Skip to content

Commit 22f79ed

Browse files
refactor(ui): replace HeroUI Snippet with CodeSnippet component (#10319)
1 parent 0790619 commit 22f79ed

File tree

12 files changed

+61
-120
lines changed

12 files changed

+61
-120
lines changed

ui/components/integrations/saml/saml-config-form.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import { createSamlConfig, updateSamlConfig } from "@/actions/integrations";
1414
import { AddIcon } from "@/components/icons";
1515
import { Button, Card, CardContent, CardHeader } from "@/components/shadcn";
1616
import { useToast } from "@/components/ui";
17+
import { CodeSnippet } from "@/components/ui/code-snippet/code-snippet";
1718
import { CustomServerInput } from "@/components/ui/custom";
1819
import { CustomLink } from "@/components/ui/custom/custom-link";
19-
import { SnippetChip } from "@/components/ui/entities";
2020
import { FormButtons } from "@/components/ui/form";
2121
import { apiBaseUrl } from "@/lib";
2222

@@ -258,7 +258,11 @@ export const SamlConfigForm = ({
258258
: `${apiBaseUrl}/accounts/saml/your-domain.com/acs/`;
259259

260260
return (
261-
<form ref={formRef} action={formAction} className="flex flex-col gap-2">
261+
<form
262+
ref={formRef}
263+
action={formAction}
264+
className="flex min-w-0 flex-col gap-2"
265+
>
262266
<div className="py-1 text-xs">
263267
Need help configuring SAML SSO?{" "}
264268
<CustomLink
@@ -304,9 +308,9 @@ export const SamlConfigForm = ({
304308
<span className="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">
305309
ACS URL:
306310
</span>
307-
<SnippetChip
311+
<CodeSnippet
308312
value={acsUrl}
309-
ariaLabel="Copy ACS URL to clipboard"
313+
ariaLabel="Copy ACS URL"
310314
className="h-10 w-full"
311315
/>
312316
</div>
@@ -315,9 +319,9 @@ export const SamlConfigForm = ({
315319
<span className="mb-2 block text-sm font-medium text-gray-700 dark:text-gray-300">
316320
Audience:
317321
</span>
318-
<SnippetChip
322+
<CodeSnippet
319323
value="urn:prowler.com:sp"
320-
ariaLabel="Copy Audience to clipboard"
324+
ariaLabel="Copy Audience"
321325
className="h-10 w-full"
322326
/>
323327
</div>

ui/components/invitations/invitation-details.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"use client";
22

3-
import { Snippet } from "@heroui/snippet";
43
import Link from "next/link";
54

65
import { AddIcon } from "../icons";
76
import { Button, Card, CardContent, CardHeader } from "../shadcn";
87
import { Separator } from "../shadcn/separator/separator";
8+
import { CodeSnippet } from "../ui/code-snippet/code-snippet";
99
import { DateWithTime } from "../ui/entities";
1010

1111
interface InvitationDetailsProps {
@@ -89,20 +89,7 @@ export const InvitationDetails = ({ attributes }: InvitationDetailsProps) => {
8989
Share this link with the user:
9090
</h3>
9191

92-
<div className="flex w-full flex-col items-start justify-between overflow-hidden">
93-
<Snippet
94-
classNames={{
95-
base: "w-full max-w-full",
96-
content: "min-w-0 overflow-hidden",
97-
pre: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap",
98-
}}
99-
hideSymbol
100-
variant="bordered"
101-
className="bg-bg-neutral-secondary max-w-full overflow-hidden py-1"
102-
>
103-
<p className="min-w-0 truncate text-sm">{invitationLink}</p>
104-
</Snippet>
105-
</div>
92+
<CodeSnippet value={invitationLink} className="max-w-full" />
10693
</CardContent>
10794
</Card>
10895
<div className="flex w-full items-center justify-end">

ui/components/scans/table/scan-detail.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"use client";
22

3-
import { Snippet } from "@heroui/snippet";
4-
53
import { Card, CardContent, CardHeader, CardTitle } from "@/components/shadcn";
4+
import { CodeSnippet } from "@/components/ui/code-snippet/code-snippet";
65
import { DateWithTime, EntityInfo, InfoField } from "@/components/ui/entities";
76
import { StatusBadge } from "@/components/ui/table/status-badge";
87
import { ProviderProps, ProviderType, ScanProps, TaskDetails } from "@/types";
@@ -81,18 +80,17 @@ export const ScanDetail = ({
8180
</div>
8281

8382
<InfoField label="Scan ID" variant="simple">
84-
<Snippet hideSymbol>{scanDetails.id}</Snippet>
83+
<CodeSnippet value={scanDetails.id} />
8584
</InfoField>
8685

8786
{scan.state === "failed" && taskDetails?.attributes.result && (
8887
<>
8988
{taskDetails.attributes.result.exc_message && (
9089
<InfoField label="Error Message" variant="simple">
91-
<Snippet hideSymbol>
92-
<span className="text-xs whitespace-pre-line">
93-
{taskDetails.attributes.result.exc_message.join("\n")}
94-
</span>
95-
</Snippet>
90+
<CodeSnippet
91+
value={taskDetails.attributes.result.exc_message.join("\n")}
92+
multiline
93+
/>
9694
</InfoField>
9795
)}
9896
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">

ui/components/ui/code-snippet/code-snippet.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ interface CodeSnippetProps {
2121
icon?: ReactNode;
2222
/** Function to format the displayed text (value is still copied as-is) */
2323
formatter?: (value: string) => string;
24+
/** Enable multiline display (disables truncation, enables word wrap) */
25+
multiline?: boolean;
26+
/** Custom aria-label for the copy button */
27+
ariaLabel?: string;
2428
}
2529

2630
export const CodeSnippet = ({
@@ -30,6 +34,8 @@ export const CodeSnippet = ({
3034
hideCopyButton = false,
3135
icon,
3236
formatter,
37+
multiline = false,
38+
ariaLabel = "Copy to clipboard",
3339
}: CodeSnippetProps) => {
3440
const [copied, setCopied] = useState(false);
3541

@@ -46,7 +52,7 @@ export const CodeSnippet = ({
4652
type="button"
4753
onClick={handleCopy}
4854
className="text-text-neutral-secondary hover:text-text-neutral-primary shrink-0 cursor-pointer transition-colors"
49-
aria-label="Copy to clipboard"
55+
aria-label={ariaLabel}
5056
>
5157
{copied ? (
5258
<Check className="h-3.5 w-3.5" />
@@ -66,7 +72,7 @@ export const CodeSnippet = ({
6672
"hover:bg-bg-neutral-tertiary text-text-neutral-secondary hover:text-text-neutral-primary shrink-0 cursor-pointer rounded-md p-1 transition-colors",
6773
className,
6874
)}
69-
aria-label="Copy to clipboard"
75+
aria-label={ariaLabel}
7076
>
7177
{copied ? (
7278
<Check className="h-3.5 w-3.5" />
@@ -80,19 +86,26 @@ export const CodeSnippet = ({
8086
return (
8187
<div
8288
className={cn(
83-
"bg-bg-neutral-tertiary text-text-neutral-primary border-border-neutral-tertiary flex h-6 w-fit min-w-0 items-center gap-1.5 rounded-full border-2 px-2 py-0.5 text-xs",
89+
"bg-bg-neutral-tertiary text-text-neutral-primary border-border-neutral-tertiary flex w-fit min-w-0 items-center gap-1.5 border-2 px-2 py-0.5 text-xs",
90+
multiline ? "h-auto rounded-lg" : "h-6 rounded-full",
8491
className,
8592
)}
8693
>
8794
{icon && (
8895
<span className="text-text-neutral-secondary shrink-0">{icon}</span>
8996
)}
90-
<Tooltip>
91-
<TooltipTrigger asChild>
92-
<code className="min-w-0 flex-1 truncate">{displayValue}</code>
93-
</TooltipTrigger>
94-
<TooltipContent side="top">{value}</TooltipContent>
95-
</Tooltip>
97+
{multiline ? (
98+
<span className="min-w-0 flex-1 break-all whitespace-pre-wrap">
99+
{displayValue}
100+
</span>
101+
) : (
102+
<Tooltip>
103+
<TooltipTrigger asChild>
104+
<span className="min-w-0 flex-1 truncate">{displayValue}</span>
105+
</TooltipTrigger>
106+
<TooltipContent side="top">{value}</TooltipContent>
107+
</Tooltip>
108+
)}
96109
{!hideCopyButton && <CopyButton />}
97110
</div>
98111
);

ui/components/ui/entities/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@ export * from "./entity-info";
33
export * from "./get-provider-logo";
44
export * from "./info-field";
55
export * from "./scan-status";
6-
export * from "./snippet-chip";

ui/components/ui/entities/snippet-chip.tsx

Lines changed: 0 additions & 51 deletions
This file was deleted.

ui/components/ui/table/data-table-pagination.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ export function DataTablePagination({
191191

192192
{/* Page info and navigation */}
193193
<div className="flex items-center gap-3">
194-
<span className="text-text-neutral-secondary text-xs font-medium">
194+
<span className="text-text-neutral-secondary hidden text-xs font-medium sm:inline">
195195
Page {currentPage} of {totalPages}
196196
</span>
197197
<div className="flex items-center gap-3">

ui/components/users/profile/api-key-success-modal.tsx

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
"use client";
22

3-
import { Snippet } from "@heroui/snippet";
4-
53
import { Button } from "@/components/shadcn";
64
import { Modal } from "@/components/shadcn/modal";
75
import { Alert, AlertDescription } from "@/components/ui/alert/Alert";
6+
import { CodeSnippet } from "@/components/ui/code-snippet/code-snippet";
87

98
interface ApiKeySuccessModalProps {
109
isOpen: boolean;
@@ -36,18 +35,12 @@ export const ApiKeySuccessModal = ({
3635
<p className="text-text-neutral-primary text-sm font-medium">
3736
Your API Key
3837
</p>
39-
<Snippet
40-
hideSymbol
41-
classNames={{
42-
pre: "font-mono text-sm break-all whitespace-pre-wrap p-2 text-text-neutral-primary",
43-
}}
44-
tooltipProps={{
45-
content: "Copy API key",
46-
color: "default",
47-
}}
48-
>
49-
{apiKey}
50-
</Snippet>
38+
<CodeSnippet
39+
value={apiKey}
40+
multiline
41+
ariaLabel="Copy API key"
42+
className="w-full px-3 py-2 text-sm"
43+
/>
5144
</div>
5245
</div>
5346

ui/components/users/profile/membership-item.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ export const MembershipItem = ({
3232
setIsOpen={setIsEditOpen}
3333
/>
3434
</Modal>
35-
<Card variant="inner" className="min-w-[320px] p-2">
36-
<div className="flex w-full items-center gap-4">
35+
<Card variant="inner" className="p-2">
36+
<div className="flex w-full flex-col gap-2 sm:flex-row sm:items-center sm:gap-4">
3737
<Chip size="sm" variant="flat" color="secondary">
3838
{membership.attributes.role}
3939
</Chip>

ui/components/users/profile/revoke-api-key-modal.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"use client";
22

3-
import { Snippet } from "@heroui/snippet";
43
import { Trash2Icon } from "lucide-react";
54

65
import { revokeApiKey } from "@/actions/api-keys/api-keys";
@@ -10,6 +9,7 @@ import {
109
AlertDescription,
1110
AlertTitle,
1211
} from "@/components/ui/alert/Alert";
12+
import { CodeSnippet } from "@/components/ui/code-snippet/code-snippet";
1313
import { ModalButtons } from "@/components/ui/custom/custom-modal-buttons";
1414

1515
import { FALLBACK_VALUES } from "./api-keys/constants";
@@ -67,16 +67,12 @@ export const RevokeApiKeyModal = ({
6767
<div className="flex flex-col gap-2">
6868
<p>Are you sure you want to revoke this API key?</p>
6969

70-
<Snippet
71-
hideSymbol
72-
hideCopyButton={true}
73-
classNames={{
74-
pre: "font-mono text-sm break-all whitespace-pre-wrap",
75-
}}
76-
>
77-
<p>{apiKey?.attributes.name || FALLBACK_VALUES.UNNAMED_KEY}</p>
78-
<p className="mt-1 text-xs">Prefix: {apiKey?.attributes.prefix}</p>
79-
</Snippet>
70+
<CodeSnippet
71+
value={`${apiKey?.attributes.name || FALLBACK_VALUES.UNNAMED_KEY}\nPrefix: ${apiKey?.attributes.prefix}`}
72+
hideCopyButton
73+
multiline
74+
className="w-full px-3 py-2 text-sm"
75+
/>
8076
</div>
8177

8278
{error && (

0 commit comments

Comments
 (0)