@fanvue/ui 1.16.1 → 1.16.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cjs/components/Alert/Alert.cjs +4 -4
- package/dist/cjs/components/Alert/Alert.cjs.map +1 -1
- package/dist/cjs/components/Chip/Chip.cjs +24 -8
- package/dist/cjs/components/Chip/Chip.cjs.map +1 -1
- package/dist/cjs/components/Icons/CloseIcon.cjs +1 -1
- package/dist/cjs/components/Icons/CloseIcon.cjs.map +1 -1
- package/dist/cjs/components/Icons/DoubleTickIcon.cjs +1 -11
- package/dist/cjs/components/Icons/DoubleTickIcon.cjs.map +1 -1
- package/dist/cjs/components/Icons/TickIcon.cjs +5 -2
- package/dist/cjs/components/Icons/TickIcon.cjs.map +1 -1
- package/dist/cjs/components/Tooltip/Tooltip.cjs +5 -1
- package/dist/cjs/components/Tooltip/Tooltip.cjs.map +1 -1
- package/dist/components/Alert/Alert.mjs +4 -4
- package/dist/components/Alert/Alert.mjs.map +1 -1
- package/dist/components/Chip/Chip.mjs +25 -9
- package/dist/components/Chip/Chip.mjs.map +1 -1
- package/dist/components/Icons/CloseIcon.mjs +1 -1
- package/dist/components/Icons/CloseIcon.mjs.map +1 -1
- package/dist/components/Icons/DoubleTickIcon.mjs +2 -12
- package/dist/components/Icons/DoubleTickIcon.mjs.map +1 -1
- package/dist/components/Icons/TickIcon.mjs +5 -2
- package/dist/components/Icons/TickIcon.mjs.map +1 -1
- package/dist/components/Tooltip/Tooltip.mjs +5 -1
- package/dist/components/Tooltip/Tooltip.mjs.map +1 -1
- package/dist/styles/theme.css +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
React component library built with Tailwind CSS for the Fanvue ecosystem.
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
[](https://github.com/fanvue/fanv-ui/actions/workflows/ci.yml)
|
|
6
7
|
[](https://github.com/fanvue/fanv-ui/actions/workflows/chromatic.yml)
|
|
7
8
|
[](https://www.npmjs.com/package/@fanvue/ui)
|
|
@@ -34,10 +34,10 @@ const DEFAULT_ICONS = {
|
|
|
34
34
|
error: /* @__PURE__ */ jsxRuntime.jsx(ErrorCircleIcon.ErrorCircleIcon, {})
|
|
35
35
|
};
|
|
36
36
|
const CLOSE_BUTTON_CLASSES = {
|
|
37
|
-
info: "hover:bg-info-default active:bg-info-default text-info-default motion-safe:transition-colors motion-safe:duration-150",
|
|
38
|
-
success: "hover:bg-success-default active:bg-success-default text-success-default motion-safe:transition-colors motion-safe:duration-150",
|
|
39
|
-
warning: "hover:bg-warning-default active:bg-warning-default text-warning-default motion-safe:transition-colors motion-safe:duration-150",
|
|
40
|
-
error: "hover:bg-error-default active:bg-error-default text-error-default motion-safe:transition-colors motion-safe:duration-150"
|
|
37
|
+
info: "hover:bg-info-default/10 active:bg-info-default/20 text-info-default motion-safe:transition-colors motion-safe:duration-150",
|
|
38
|
+
success: "hover:bg-success-default/10 active:bg-success-default/20 text-success-default motion-safe:transition-colors motion-safe:duration-150",
|
|
39
|
+
warning: "hover:bg-warning-default/10 active:bg-warning-default/20 text-warning-default motion-safe:transition-colors motion-safe:duration-150",
|
|
40
|
+
error: "hover:bg-error-default/10 active:bg-error-default/20 text-error-default motion-safe:transition-colors motion-safe:duration-150"
|
|
41
41
|
};
|
|
42
42
|
const Alert = React__namespace.forwardRef(
|
|
43
43
|
({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert.cjs","sources":["../../../../src/components/Alert/Alert.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\nimport { CheckCircleIcon } from \"../Icons/CheckCircleIcon\";\nimport { CrossIcon } from \"../Icons/CrossIcon\";\nimport { ErrorCircleIcon } from \"../Icons/ErrorCircleIcon\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { WarningTriangleIcon } from \"../Icons/WarningTriangleIcon\";\n\n/** Visual style variant of the alert. */\nexport type AlertVariant = \"info\" | \"success\" | \"warning\" | \"error\";\n\nconst DEFAULT_ICONS: Record<AlertVariant, React.ReactNode> = {\n info: <InfoCircleIcon />,\n success: <CheckCircleIcon />,\n warning: <WarningTriangleIcon />,\n error: <ErrorCircleIcon />,\n};\n\nexport interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Visual style variant of the alert. @default \"info\" */\n variant?: AlertVariant;\n /** Optional title text displayed in bold above the description. */\n title?: string;\n /** Custom icon override. Pass `null` to hide the icon entirely. Each variant shows a default icon when left `undefined`. */\n icon?: React.ReactNode | null;\n /** Whether to show the close button. @default false */\n closable?: boolean;\n /** Callback fired when the close button is clicked. */\n onClose?: () => void;\n /** Accessible label for the close button. @default \"Close alert\" */\n closeLabel?: string;\n}\n\nconst CLOSE_BUTTON_CLASSES: Record<AlertVariant, string> = {\n info: \"hover:bg-info-default active:bg-info-default text-info-default motion-safe:transition-colors motion-safe:duration-150\",\n success:\n \"hover:bg-success-default active:bg-success-default text-success-default motion-safe:transition-colors motion-safe:duration-150\",\n warning:\n \"hover:bg-warning-default active:bg-warning-default text-warning-default motion-safe:transition-colors motion-safe:duration-150\",\n error:\n \"hover:bg-error-default active:bg-error-default text-error-default motion-safe:transition-colors motion-safe:duration-150\",\n};\n\n/**\n * Displays a contextual feedback message to the user.\n *\n * Supports `info`, `success`, `warning`, and `error` variants with a default\n * icon per variant, optional title, description, and dismiss button.\n *\n * Each variant renders a default icon automatically. Pass a custom `icon` to\n * override, or `icon={null}` to hide the icon entirely.\n *\n * @example\n * ```tsx\n * <Alert variant=\"success\" title=\"Saved\" closable onClose={handleClose}>\n * Your changes have been saved.\n * </Alert>\n * ```\n */\nexport const Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n (\n {\n className,\n variant = \"info\",\n title,\n icon,\n closable = false,\n onClose,\n closeLabel = \"Close alert\",\n children,\n ...props\n },\n ref,\n ) => {\n const resolvedIcon = icon === null ? null : (icon ?? DEFAULT_ICONS[variant]);\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n data-testid=\"alert\"\n className={cn(\n \"grid gap-x-3 rounded-lg p-4 text-sm leading-[18px]\",\n resolvedIcon && closable && \"grid-cols-[auto_1fr_auto]\",\n resolvedIcon && !closable && \"grid-cols-[auto_1fr]\",\n !resolvedIcon && closable && \"grid-cols-[1fr_auto]\",\n !resolvedIcon && !closable && \"grid-cols-[1fr]\",\n title && children ? \"items-start\" : \"items-center\",\n variant === \"info\" && \"bg-info-background text-info-default\",\n variant === \"success\" && \"bg-success-background text-success-default\",\n variant === \"warning\" && \"bg-warning-background text-warning-default\",\n variant === \"error\" && \"bg-error-background text-error-default\",\n className,\n )}\n {...props}\n >\n {resolvedIcon && (\n <span className=\"flex shrink-0 items-start\" aria-hidden=\"true\">\n {resolvedIcon}\n </span>\n )}\n\n <div className=\"flex min-w-0 flex-col gap-2\">\n {title && (\n <div className=\"typography-semibold-body-md text-foreground-default\">{title}</div>\n )}\n <div className=\"typography-regular-body-md text-foreground-secondary\">{children}</div>\n </div>\n\n {closable && (\n <Button\n variant=\"tertiary\"\n size=\"24\"\n onClick={onClose}\n className={cn(\"self-start px-0\", CLOSE_BUTTON_CLASSES[variant])}\n aria-label={closeLabel}\n >\n <CrossIcon />\n </Button>\n )}\n </div>\n );\n },\n);\n\nAlert.displayName = \"Alert\";\n"],"names":["InfoCircleIcon","CheckCircleIcon","WarningTriangleIcon","ErrorCircleIcon","React","jsxs","cn","jsx","Button","CrossIcon"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,MAAM,gBAAuD;AAAA,EAC3D,qCAAOA,eAAAA,gBAAA,EAAe;AAAA,EACtB,wCAAUC,gBAAAA,iBAAA,EAAgB;AAAA,EAC1B,wCAAUC,oBAAAA,qBAAA,EAAoB;AAAA,EAC9B,sCAAQC,gBAAAA,iBAAA,CAAA,CAAgB;AAC1B;AAiBA,MAAM,uBAAqD;AAAA,EACzD,MAAM;AAAA,EACN,SACE;AAAA,EACF,SACE;AAAA,EACF,OACE;AACJ;AAkBO,MAAM,QAAQC,iBAAM;AAAA,EACzB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,eAAe,SAAS,OAAO,OAAQ,QAAQ,cAAc,OAAO;AAE1E,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAWC,GAAAA;AAAAA,UACT;AAAA,UACA,gBAAgB,YAAY;AAAA,UAC5B,gBAAgB,CAAC,YAAY;AAAA,UAC7B,CAAC,gBAAgB,YAAY;AAAA,UAC7B,CAAC,gBAAgB,CAAC,YAAY;AAAA,UAC9B,SAAS,WAAW,gBAAgB;AAAA,UACpC,YAAY,UAAU;AAAA,UACtB,YAAY,aAAa;AAAA,UACzB,YAAY,aAAa;AAAA,UACzB,YAAY,WAAW;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,+CACE,QAAA,EAAK,WAAU,6BAA4B,eAAY,QACrD,UAAA,cACH;AAAA,UAGFD,2BAAAA,KAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,YAAA,SACCE,2BAAAA,IAAC,OAAA,EAAI,WAAU,uDAAuD,UAAA,OAAM;AAAA,YAE9EA,2BAAAA,IAAC,OAAA,EAAI,WAAU,wDAAwD,SAAA,CAAS;AAAA,UAAA,GAClF;AAAA,UAEC,YACCA,2BAAAA;AAAAA,YAACC,OAAAA;AAAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS;AAAA,cACT,WAAWF,GAAAA,GAAG,mBAAmB,qBAAqB,OAAO,CAAC;AAAA,cAC9D,cAAY;AAAA,cAEZ,yCAACG,UAAAA,WAAA,CAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,MAAM,cAAc;;"}
|
|
1
|
+
{"version":3,"file":"Alert.cjs","sources":["../../../../src/components/Alert/Alert.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\nimport { CheckCircleIcon } from \"../Icons/CheckCircleIcon\";\nimport { CrossIcon } from \"../Icons/CrossIcon\";\nimport { ErrorCircleIcon } from \"../Icons/ErrorCircleIcon\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { WarningTriangleIcon } from \"../Icons/WarningTriangleIcon\";\n\n/** Visual style variant of the alert. */\nexport type AlertVariant = \"info\" | \"success\" | \"warning\" | \"error\";\n\nconst DEFAULT_ICONS: Record<AlertVariant, React.ReactNode> = {\n info: <InfoCircleIcon />,\n success: <CheckCircleIcon />,\n warning: <WarningTriangleIcon />,\n error: <ErrorCircleIcon />,\n};\n\nexport interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Visual style variant of the alert. @default \"info\" */\n variant?: AlertVariant;\n /** Optional title text displayed in bold above the description. */\n title?: string;\n /** Custom icon override. Pass `null` to hide the icon entirely. Each variant shows a default icon when left `undefined`. */\n icon?: React.ReactNode | null;\n /** Whether to show the close button. @default false */\n closable?: boolean;\n /** Callback fired when the close button is clicked. */\n onClose?: () => void;\n /** Accessible label for the close button. @default \"Close alert\" */\n closeLabel?: string;\n}\n\nconst CLOSE_BUTTON_CLASSES: Record<AlertVariant, string> = {\n info: \"hover:bg-info-default/10 active:bg-info-default/20 text-info-default motion-safe:transition-colors motion-safe:duration-150\",\n success:\n \"hover:bg-success-default/10 active:bg-success-default/20 text-success-default motion-safe:transition-colors motion-safe:duration-150\",\n warning:\n \"hover:bg-warning-default/10 active:bg-warning-default/20 text-warning-default motion-safe:transition-colors motion-safe:duration-150\",\n error:\n \"hover:bg-error-default/10 active:bg-error-default/20 text-error-default motion-safe:transition-colors motion-safe:duration-150\",\n};\n\n/**\n * Displays a contextual feedback message to the user.\n *\n * Supports `info`, `success`, `warning`, and `error` variants with a default\n * icon per variant, optional title, description, and dismiss button.\n *\n * Each variant renders a default icon automatically. Pass a custom `icon` to\n * override, or `icon={null}` to hide the icon entirely.\n *\n * @example\n * ```tsx\n * <Alert variant=\"success\" title=\"Saved\" closable onClose={handleClose}>\n * Your changes have been saved.\n * </Alert>\n * ```\n */\nexport const Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n (\n {\n className,\n variant = \"info\",\n title,\n icon,\n closable = false,\n onClose,\n closeLabel = \"Close alert\",\n children,\n ...props\n },\n ref,\n ) => {\n const resolvedIcon = icon === null ? null : (icon ?? DEFAULT_ICONS[variant]);\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n data-testid=\"alert\"\n className={cn(\n \"grid gap-x-3 rounded-lg p-4 text-sm leading-[18px]\",\n resolvedIcon && closable && \"grid-cols-[auto_1fr_auto]\",\n resolvedIcon && !closable && \"grid-cols-[auto_1fr]\",\n !resolvedIcon && closable && \"grid-cols-[1fr_auto]\",\n !resolvedIcon && !closable && \"grid-cols-[1fr]\",\n title && children ? \"items-start\" : \"items-center\",\n variant === \"info\" && \"bg-info-background text-info-default\",\n variant === \"success\" && \"bg-success-background text-success-default\",\n variant === \"warning\" && \"bg-warning-background text-warning-default\",\n variant === \"error\" && \"bg-error-background text-error-default\",\n className,\n )}\n {...props}\n >\n {resolvedIcon && (\n <span className=\"flex shrink-0 items-start\" aria-hidden=\"true\">\n {resolvedIcon}\n </span>\n )}\n\n <div className=\"flex min-w-0 flex-col gap-2\">\n {title && (\n <div className=\"typography-semibold-body-md text-foreground-default\">{title}</div>\n )}\n <div className=\"typography-regular-body-md text-foreground-secondary\">{children}</div>\n </div>\n\n {closable && (\n <Button\n variant=\"tertiary\"\n size=\"24\"\n onClick={onClose}\n className={cn(\"self-start px-0\", CLOSE_BUTTON_CLASSES[variant])}\n aria-label={closeLabel}\n >\n <CrossIcon />\n </Button>\n )}\n </div>\n );\n },\n);\n\nAlert.displayName = \"Alert\";\n"],"names":["InfoCircleIcon","CheckCircleIcon","WarningTriangleIcon","ErrorCircleIcon","React","jsxs","cn","jsx","Button","CrossIcon"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,MAAM,gBAAuD;AAAA,EAC3D,qCAAOA,eAAAA,gBAAA,EAAe;AAAA,EACtB,wCAAUC,gBAAAA,iBAAA,EAAgB;AAAA,EAC1B,wCAAUC,oBAAAA,qBAAA,EAAoB;AAAA,EAC9B,sCAAQC,gBAAAA,iBAAA,CAAA,CAAgB;AAC1B;AAiBA,MAAM,uBAAqD;AAAA,EACzD,MAAM;AAAA,EACN,SACE;AAAA,EACF,SACE;AAAA,EACF,OACE;AACJ;AAkBO,MAAM,QAAQC,iBAAM;AAAA,EACzB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,eAAe,SAAS,OAAO,OAAQ,QAAQ,cAAc,OAAO;AAE1E,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAWC,GAAAA;AAAAA,UACT;AAAA,UACA,gBAAgB,YAAY;AAAA,UAC5B,gBAAgB,CAAC,YAAY;AAAA,UAC7B,CAAC,gBAAgB,YAAY;AAAA,UAC7B,CAAC,gBAAgB,CAAC,YAAY;AAAA,UAC9B,SAAS,WAAW,gBAAgB;AAAA,UACpC,YAAY,UAAU;AAAA,UACtB,YAAY,aAAa;AAAA,UACzB,YAAY,aAAa;AAAA,UACzB,YAAY,WAAW;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,+CACE,QAAA,EAAK,WAAU,6BAA4B,eAAY,QACrD,UAAA,cACH;AAAA,UAGFD,2BAAAA,KAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,YAAA,SACCE,2BAAAA,IAAC,OAAA,EAAI,WAAU,uDAAuD,UAAA,OAAM;AAAA,YAE9EA,2BAAAA,IAAC,OAAA,EAAI,WAAU,wDAAwD,SAAA,CAAS;AAAA,UAAA,GAClF;AAAA,UAEC,YACCA,2BAAAA;AAAAA,YAACC,OAAAA;AAAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS;AAAA,cACT,WAAWF,GAAAA,GAAG,mBAAmB,qBAAqB,OAAO,CAAC;AAAA,cAC9D,cAAY;AAAA,cAEZ,yCAACG,UAAAA,WAAA,CAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,MAAM,cAAc;;"}
|
|
@@ -41,13 +41,13 @@ const Chip = React__namespace.forwardRef(
|
|
|
41
41
|
const isInteractive = !!onClick && !asChild;
|
|
42
42
|
const Comp = asChild ? reactSlot.Slot : isInteractive ? "button" : "span";
|
|
43
43
|
const isDark = variant === "dark";
|
|
44
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
44
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
45
45
|
Comp,
|
|
46
46
|
{
|
|
47
47
|
ref,
|
|
48
48
|
"data-testid": "chip",
|
|
49
49
|
className: cn.cn(
|
|
50
|
-
"typography-semibold-body-sm relative inline-flex min-w-0 items-center justify-center
|
|
50
|
+
"typography-semibold-body-sm relative inline-flex min-w-0 items-center justify-center whitespace-nowrap motion-safe:transition-colors motion-safe:duration-150",
|
|
51
51
|
// Shape
|
|
52
52
|
variant === "square" ? "rounded-lg" : "rounded-full",
|
|
53
53
|
// Size
|
|
@@ -76,13 +76,29 @@ const Chip = React__namespace.forwardRef(
|
|
|
76
76
|
...!isInteractive && disabled && { "aria-disabled": true },
|
|
77
77
|
...selected && { "data-selected": "" },
|
|
78
78
|
...props,
|
|
79
|
-
children: [
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
children: asChild ? /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slottable, { children }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
80
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 items-center gap-0.5 overflow-hidden px-3", children: [
|
|
81
|
+
leftDot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-2 shrink-0 rounded-full bg-current", "aria-hidden": "true" }),
|
|
82
|
+
leftIcon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
83
|
+
"span",
|
|
84
|
+
{
|
|
85
|
+
className: "flex size-5 shrink-0 items-center justify-center",
|
|
86
|
+
"aria-hidden": "true",
|
|
87
|
+
children: leftIcon
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children }),
|
|
91
|
+
rightIcon && /* @__PURE__ */ jsxRuntime.jsx(
|
|
92
|
+
"span",
|
|
93
|
+
{
|
|
94
|
+
className: "flex size-5 shrink-0 items-center justify-center",
|
|
95
|
+
"aria-hidden": "true",
|
|
96
|
+
children: rightIcon
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
] }),
|
|
84
100
|
notificationLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-semibold-body-sm absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-foreground-default px-1 text-foreground-inverse", children: notificationLabel })
|
|
85
|
-
]
|
|
101
|
+
] })
|
|
86
102
|
}
|
|
87
103
|
);
|
|
88
104
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chip.cjs","sources":["../../../../src/components/Chip/Chip.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Visual variant of the chip. */\nexport type ChipVariant = \"rounded\" | \"square\" | \"dark\";\n/** Height of the chip in pixels. */\nexport type ChipSize = \"32\" | \"40\";\n\nexport interface ChipProps extends React.HTMLAttributes<HTMLElement> {\n /** Visual variant of the chip. @default \"rounded\" */\n variant?: ChipVariant;\n /** Height of the chip in pixels. @default \"32\" */\n size?: ChipSize;\n /** Whether the chip is in a selected (pressed) state. @default false */\n selected?: boolean;\n /** Whether the chip is disabled. @default false */\n disabled?: boolean;\n /** Whether to show a coloured status dot at the leading edge. @default false */\n leftDot?: boolean;\n /** Icon element displayed before the label. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed after the label. */\n rightIcon?: React.ReactNode;\n /** Notification badge content (e.g. `\"99+\"`). Passed as a string for i18n support. */\n notificationLabel?: string;\n /** Click handler — when provided, the chip renders as a `<button>` for accessibility. */\n onClick?: React.MouseEventHandler<HTMLElement>;\n /** Merge props onto a child element instead of rendering a wrapper. @default false */\n asChild?: boolean;\n}\n\n/**\n * A compact element for filters, tags, or toggleable actions. When an `onClick`\n * handler is provided, the chip renders as an interactive `<button>` with\n * `aria-pressed` support.\n *\n * @example\n * ```tsx\n * <Chip selected onClick={toggle}>Music</Chip>\n * ```\n */\nexport const Chip = React.forwardRef<HTMLButtonElement, ChipProps>(\n (\n {\n className,\n variant = \"rounded\",\n size = \"32\",\n selected = false,\n disabled = false,\n leftDot = false,\n leftIcon,\n rightIcon,\n notificationLabel,\n onClick,\n asChild = false,\n children,\n ...props\n },\n ref,\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Variant-heavy UI component\n ) => {\n const isInteractive = !!onClick && !asChild;\n const Comp = asChild ? Slot : isInteractive ? \"button\" : \"span\";\n const isDark = variant === \"dark\";\n\n return (\n <Comp\n ref={ref}\n data-testid=\"chip\"\n className={cn(\n \"typography-semibold-body-sm relative inline-flex min-w-0 items-center justify-center
|
|
1
|
+
{"version":3,"file":"Chip.cjs","sources":["../../../../src/components/Chip/Chip.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Visual variant of the chip. */\nexport type ChipVariant = \"rounded\" | \"square\" | \"dark\";\n/** Height of the chip in pixels. */\nexport type ChipSize = \"32\" | \"40\";\n\nexport interface ChipProps extends React.HTMLAttributes<HTMLElement> {\n /** Visual variant of the chip. @default \"rounded\" */\n variant?: ChipVariant;\n /** Height of the chip in pixels. @default \"32\" */\n size?: ChipSize;\n /** Whether the chip is in a selected (pressed) state. @default false */\n selected?: boolean;\n /** Whether the chip is disabled. @default false */\n disabled?: boolean;\n /** Whether to show a coloured status dot at the leading edge. @default false */\n leftDot?: boolean;\n /** Icon element displayed before the label. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed after the label. */\n rightIcon?: React.ReactNode;\n /** Notification badge content (e.g. `\"99+\"`). Passed as a string for i18n support. */\n notificationLabel?: string;\n /** Click handler — when provided, the chip renders as a `<button>` for accessibility. */\n onClick?: React.MouseEventHandler<HTMLElement>;\n /** Merge props onto a child element instead of rendering a wrapper. @default false */\n asChild?: boolean;\n}\n\n/**\n * A compact element for filters, tags, or toggleable actions. When an `onClick`\n * handler is provided, the chip renders as an interactive `<button>` with\n * `aria-pressed` support.\n *\n * @example\n * ```tsx\n * <Chip selected onClick={toggle}>Music</Chip>\n * ```\n */\nexport const Chip = React.forwardRef<HTMLButtonElement, ChipProps>(\n (\n {\n className,\n variant = \"rounded\",\n size = \"32\",\n selected = false,\n disabled = false,\n leftDot = false,\n leftIcon,\n rightIcon,\n notificationLabel,\n onClick,\n asChild = false,\n children,\n ...props\n },\n ref,\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Variant-heavy UI component\n ) => {\n const isInteractive = !!onClick && !asChild;\n const Comp = asChild ? Slot : isInteractive ? \"button\" : \"span\";\n const isDark = variant === \"dark\";\n\n return (\n <Comp\n ref={ref}\n data-testid=\"chip\"\n className={cn(\n \"typography-semibold-body-sm relative inline-flex min-w-0 items-center justify-center whitespace-nowrap motion-safe:transition-colors motion-safe:duration-150\",\n // Shape\n variant === \"square\" ? \"rounded-lg\" : \"rounded-full\",\n // Size\n size === \"32\" && \"h-8 py-1\",\n size === \"40\" && \"h-10 py-2.5\",\n // Variant colors\n isDark && \"bg-neutral-50 text-foreground-onaccentinverse\",\n !isDark && selected && \"bg-brand-accent-muted text-neutral-400\",\n !isDark && !selected && \"bg-neutral-100 text-neutral-400\",\n // Interactive\n isInteractive && !disabled && \"cursor-pointer\",\n isInteractive &&\n !disabled &&\n !isDark &&\n !selected &&\n \"hover:bg-brand-accent-muted active:bg-brand-accent-muted\",\n // Focus\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n // Disabled\n disabled && isDark && \"pointer-events-none opacity-50\",\n disabled && !isDark && \"pointer-events-none text-neutral-300\",\n className,\n )}\n {...(isInteractive && {\n type: \"button\" as const,\n disabled,\n \"aria-pressed\": selected,\n onClick,\n })}\n {...(!isInteractive && disabled && { \"aria-disabled\": true })}\n {...(selected && { \"data-selected\": \"\" })}\n {...props}\n >\n {asChild ? (\n <Slottable>{children}</Slottable>\n ) : (\n <>\n <span className=\"flex min-w-0 items-center gap-0.5 overflow-hidden px-3\">\n {leftDot && (\n <span className=\"size-2 shrink-0 rounded-full bg-current\" aria-hidden=\"true\" />\n )}\n {leftIcon && (\n <span\n className=\"flex size-5 shrink-0 items-center justify-center\"\n aria-hidden=\"true\"\n >\n {leftIcon}\n </span>\n )}\n <span className=\"min-w-0 truncate\">{children}</span>\n {rightIcon && (\n <span\n className=\"flex size-5 shrink-0 items-center justify-center\"\n aria-hidden=\"true\"\n >\n {rightIcon}\n </span>\n )}\n </span>\n {notificationLabel && (\n <span className=\"typography-semibold-body-sm absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-foreground-default px-1 text-foreground-inverse\">\n {notificationLabel}\n </span>\n )}\n </>\n )}\n </Comp>\n );\n },\n);\n\nChip.displayName = \"Chip\";\n"],"names":["React","Slot","jsx","cn","Slottable","jsxs","Fragment"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0CO,MAAM,OAAOA,iBAAM;AAAA,EACxB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QAEG;AACH,UAAM,gBAAgB,CAAC,CAAC,WAAW,CAAC;AACpC,UAAM,OAAO,UAAUC,UAAAA,OAAO,gBAAgB,WAAW;AACzD,UAAM,SAAS,YAAY;AAE3B,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAY;AAAA,QACZ,WAAWC,GAAAA;AAAAA,UACT;AAAA;AAAA,UAEA,YAAY,WAAW,eAAe;AAAA;AAAA,UAEtC,SAAS,QAAQ;AAAA,UACjB,SAAS,QAAQ;AAAA;AAAA,UAEjB,UAAU;AAAA,UACV,CAAC,UAAU,YAAY;AAAA,UACvB,CAAC,UAAU,CAAC,YAAY;AAAA;AAAA,UAExB,iBAAiB,CAAC,YAAY;AAAA,UAC9B,iBACE,CAAC,YACD,CAAC,UACD,CAAC,YACD;AAAA;AAAA,UAEF;AAAA;AAAA,UAEA,YAAY,UAAU;AAAA,UACtB,YAAY,CAAC,UAAU;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAI,iBAAiB;AAAA,UACpB,MAAM;AAAA,UACN;AAAA,UACA,gBAAgB;AAAA,UAChB;AAAA,QAAA;AAAA,QAED,GAAI,CAAC,iBAAiB,YAAY,EAAE,iBAAiB,KAAA;AAAA,QACrD,GAAI,YAAY,EAAE,iBAAiB,GAAA;AAAA,QACnC,GAAG;AAAA,QAEH,UAAA,UACCD,2BAAAA,IAACE,qBAAA,EAAW,SAAA,CAAS,IAErBC,2BAAAA,KAAAC,qBAAA,EACE,UAAA;AAAA,UAAAD,2BAAAA,KAAC,QAAA,EAAK,WAAU,0DACb,UAAA;AAAA,YAAA,WACCH,2BAAAA,IAAC,QAAA,EAAK,WAAU,2CAA0C,eAAY,QAAO;AAAA,YAE9E,YACCA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,eAAY;AAAA,gBAEX,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGLA,2BAAAA,IAAC,QAAA,EAAK,WAAU,oBAAoB,SAAA,CAAS;AAAA,YAC5C,aACCA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,eAAY;AAAA,gBAEX,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACH,GAEJ;AAAA,UACC,qBACCA,2BAAAA,IAAC,QAAA,EAAK,WAAU,qKACb,UAAA,kBAAA,CACH;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,KAAK,cAAc;;"}
|
|
@@ -32,7 +32,7 @@ const CloseIcon = React__namespace.forwardRef(
|
|
|
32
32
|
"aria-hidden": "true",
|
|
33
33
|
className: cn.cn("size-6", className),
|
|
34
34
|
...props,
|
|
35
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("g", { stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "
|
|
35
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("g", { stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7.003 7.006 17 17.003M17 6.996l-9.997 9.998" }) })
|
|
36
36
|
}
|
|
37
37
|
);
|
|
38
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloseIcon.cjs","sources":["../../../../src/components/Icons/CloseIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const CloseIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <g stroke=\"currentColor\" strokeLinecap=\"round\" strokeWidth=\"1.5\">\n <path d=\"
|
|
1
|
+
{"version":3,"file":"CloseIcon.cjs","sources":["../../../../src/components/Icons/CloseIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const CloseIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <g stroke=\"currentColor\" strokeLinecap=\"round\" strokeWidth=\"1.5\">\n <path d=\"M7.003 7.006 17 17.003M17 6.996l-9.997 9.998\" />\n </g>\n </svg>\n );\n },\n);\n\nCloseIcon.displayName = \"CloseIcon\";\n"],"names":["React","jsx","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAIO,MAAM,YAAYA,iBAAM;AAAA,EAC7B,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAAQ;AAChC,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAWC,GAAAA,GAAG,UAAU,SAAS;AAAA,QAChC,GAAG;AAAA,QAEJ,UAAAD,2BAAAA,IAAC,KAAA,EAAE,QAAO,gBAAe,eAAc,SAAQ,aAAY,OACzD,UAAAA,+BAAC,QAAA,EAAK,GAAE,+CAAA,CAA+C,EAAA,CACzD;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,UAAU,cAAc;;"}
|
|
@@ -32,17 +32,7 @@ const DoubleTickIcon = React__namespace.forwardRef(
|
|
|
32
32
|
"aria-hidden": "true",
|
|
33
33
|
className: cn.cn("size-6", className),
|
|
34
34
|
...props,
|
|
35
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
36
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
37
|
-
"path",
|
|
38
|
-
{
|
|
39
|
-
fillRule: "evenodd",
|
|
40
|
-
d: "M5.22 11.47c.29-.29.77-.29 1.06 0l2.3 2.3.594-.596 1.06 1.06L9.11 15.36a.75.75 0 0 1-1.06 0l-2.83-2.83a.755.755 0 0 1 0-1.06m8.5-2.84c.29-.29.77-.29 1.06 0s.29.77 0 1.06l-2.796 2.795-1.06-1.06z",
|
|
41
|
-
clipRule: "evenodd"
|
|
42
|
-
}
|
|
43
|
-
),
|
|
44
|
-
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12.58 15.58a.75.75 0 0 1-.53-.22l-2.83-2.83a.754.754 0 0 1 0-1.06c.29-.29.77-.29 1.06 0l2.3 2.3 5.14-5.14c.29-.29.77-.29 1.06 0s.29.77 0 1.06l-5.67 5.67a.75.75 0 0 1-.53.22" })
|
|
45
|
-
] })
|
|
35
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("g", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m8 11.5 5 5L22.5 7M2 11.5l5 5L8.5 15m8-8-4.75 4.75" }) })
|
|
46
36
|
}
|
|
47
37
|
);
|
|
48
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoubleTickIcon.cjs","sources":["../../../../src/components/Icons/DoubleTickIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const DoubleTickIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <g
|
|
1
|
+
{"version":3,"file":"DoubleTickIcon.cjs","sources":["../../../../src/components/Icons/DoubleTickIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const DoubleTickIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <g stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"1.5\">\n <path d=\"m8 11.5 5 5L22.5 7M2 11.5l5 5L8.5 15m8-8-4.75 4.75\" />\n </g>\n </svg>\n );\n },\n);\n\nDoubleTickIcon.displayName = \"DoubleTickIcon\";\n"],"names":["React","jsx","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAIO,MAAM,iBAAiBA,iBAAM;AAAA,EAClC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAAQ;AAChC,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAWC,GAAAA,GAAG,UAAU,SAAS;AAAA,QAChC,GAAG;AAAA,QAEJ,UAAAD,2BAAAA,IAAC,KAAA,EAAE,QAAO,gBAAe,eAAc,SAAQ,gBAAe,SAAQ,aAAY,OAChF,UAAAA,2BAAAA,IAAC,QAAA,EAAK,GAAE,sDAAqD,EAAA,CAC/D;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,eAAe,cAAc;;"}
|
|
@@ -35,8 +35,11 @@ const TickIcon = React__namespace.forwardRef(
|
|
|
35
35
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
36
36
|
"path",
|
|
37
37
|
{
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
stroke: "currentColor",
|
|
39
|
+
strokeLinecap: "round",
|
|
40
|
+
strokeLinejoin: "round",
|
|
41
|
+
strokeWidth: "1.5",
|
|
42
|
+
d: "m5 12 5 5 9.5-9.5"
|
|
40
43
|
}
|
|
41
44
|
)
|
|
42
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TickIcon.cjs","sources":["../../../../src/components/Icons/TickIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const TickIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <path\n
|
|
1
|
+
{"version":3,"file":"TickIcon.cjs","sources":["../../../../src/components/Icons/TickIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const TickIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <path\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n d=\"m5 12 5 5 9.5-9.5\"\n />\n </svg>\n );\n },\n);\n\nTickIcon.displayName = \"TickIcon\";\n"],"names":["React","jsx","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAIO,MAAM,WAAWA,iBAAM;AAAA,EAC5B,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAAQ;AAChC,WACEC,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAWC,GAAAA,GAAG,UAAU,SAAS;AAAA,QAChC,GAAG;AAAA,QAEJ,UAAAD,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,QAAO;AAAA,YACP,eAAc;AAAA,YACd,gBAAe;AAAA,YACf,aAAY;AAAA,YACZ,GAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MACJ;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,SAAS,cAAc;;"}
|
|
@@ -27,10 +27,14 @@ const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
|
27
27
|
const TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
28
28
|
const Tooltip = TooltipPrimitive__namespace.Root;
|
|
29
29
|
const TooltipTrigger = TooltipPrimitive__namespace.Trigger;
|
|
30
|
+
const TOOLTIP_ACTION_CLASSES = {
|
|
31
|
+
brand: "hover:bg-brand-accent-default/80 hover:text-foreground-onaccent",
|
|
32
|
+
tertiary: "text-foreground-inverse hover:text-foreground-inverse hover:bg-foreground-inverse/10"
|
|
33
|
+
};
|
|
30
34
|
const ActionButton = ({
|
|
31
35
|
action,
|
|
32
36
|
variant
|
|
33
|
-
}) => action.element ? action.element : /* @__PURE__ */ jsxRuntime.jsx(Button.Button, { variant,
|
|
37
|
+
}) => action.element ? action.element : /* @__PURE__ */ jsxRuntime.jsx(Button.Button, { variant, onClick: action.onClick, className: TOOLTIP_ACTION_CLASSES[variant], children: action.label });
|
|
34
38
|
const InfoboxContent = ({
|
|
35
39
|
icon,
|
|
36
40
|
heading,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.cjs","sources":["../../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\n\n/** Props for the {@link TooltipProvider}. Wraps Radix `Tooltip.Provider`. */\nexport type TooltipProviderProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>;\n\n/** Provides tooltip delay and skip-delay context. Wrap your app or a subtree. */\nexport const TooltipProvider = TooltipPrimitive.Provider;\n\n/** Props for the {@link Tooltip} root component. */\nexport interface TooltipProps extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root> {\n /**\n * Controlled open state. When provided, the component is in controlled mode\n * and you must also supply `onOpenChange` to update the value.\n */\n open?: boolean;\n /** Called when the open state changes. Required when `open` is controlled. */\n onOpenChange?: (open: boolean) => void;\n /** The open state of the tooltip when it is initially rendered (uncontrolled). */\n defaultOpen?: boolean;\n}\n\n/** Root component that manages open/close state for a single tooltip. */\nexport const Tooltip = TooltipPrimitive.Root;\n\n/** Props for the {@link TooltipTrigger} component. */\nexport type TooltipTriggerProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>;\n\n/** The element that triggers the tooltip on hover/focus. */\nexport const TooltipTrigger = TooltipPrimitive.Trigger;\n\n/**\n * Visual style variant of the tooltip content.\n *\n * - `\"tooltip\"` — simple text bubble, no border.\n * - `\"infobox\"` — richer card with a visible border, structured header, body text, and optional actions.\n */\nexport type TooltipContentVariant = \"tooltip\" | \"infobox\";\n\n/** Action button configuration for the infobox variant of {@link TooltipContent}. */\nexport interface TooltipAction {\n /** Button label. */\n label: string;\n /** Click handler. */\n onClick?: () => void;\n /**\n * Optional custom React node to be rendered for the action instead of the default button.\n * Only used in the infobox variant.\n */\n element?: React.ReactNode;\n}\n\nexport interface TooltipContentProps\n extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> {\n /**\n * Visual style variant.\n *\n * `\"tooltip\"` is a lightweight text bubble. `\"infobox\"` renders a structured card\n * with optional heading, icon, pill, body text, and action buttons.\n *\n * @default \"tooltip\"\n */\n variant?: TooltipContentVariant;\n /** Whether to show the directional arrow pointer. @default true */\n showArrow?: boolean;\n /**\n * Heading text rendered in subtitle style at the top of the infobox.\n * Infobox variant only.\n */\n heading?: React.ReactNode;\n /**\n * Icon element displayed to the left of the heading.\n * Infobox variant only.\n */\n icon?: React.ReactNode;\n /**\n * Pill or badge element displayed to the right of the heading.\n * Infobox variant only.\n */\n pill?: React.ReactNode;\n /**\n * Primary action button (brand green). Rendered below the body text.\n * Infobox variant only.\n */\n primaryAction?: TooltipAction;\n /**\n * Secondary action button (ghost). Rendered next to the primary action.\n * Infobox variant only.\n */\n secondaryAction?: TooltipAction;\n}\n\nconst ActionButton = ({\n action,\n variant,\n}: {\n action: TooltipAction;\n variant: \"brand\" | \"tertiary\";\n}) =>\n action.element ? (\n action.element\n ) : (\n <Button variant={variant} size=\"32\" onClick={action.onClick}>\n {action.label}\n </Button>\n );\n\nconst InfoboxContent = ({\n icon,\n heading,\n pill,\n children,\n primaryAction,\n secondaryAction,\n hasHeader,\n hasActions,\n}: {\n icon?: React.ReactNode;\n heading?: React.ReactNode;\n pill?: React.ReactNode;\n children?: React.ReactNode;\n primaryAction?: TooltipAction;\n secondaryAction?: TooltipAction;\n hasHeader: boolean;\n hasActions: boolean;\n}) => (\n <div className=\"flex flex-col gap-3\">\n {hasHeader && (\n <div className=\"flex items-center gap-3\">\n {icon && <div className=\"size-5 shrink-0\">{icon}</div>}\n {heading && (\n <p className=\"typography-semibold-body-lg min-w-0 flex-1 text-foreground-inverse\">\n {heading}\n </p>\n )}\n {pill && <div className=\"shrink-0\">{pill}</div>}\n </div>\n )}\n {children && (\n <div className=\"typography-regular-body-md text-foreground-inverse\">{children}</div>\n )}\n {hasActions && (\n <div className=\"flex items-center gap-1\">\n {primaryAction && <ActionButton action={primaryAction} variant=\"brand\" />}\n {secondaryAction && <ActionButton action={secondaryAction} variant=\"tertiary\" />}\n </div>\n )}\n </div>\n);\n\n/**\n * The popup content of the tooltip. Renders inside a portal.\n *\n * Arrow direction is controlled via the `side` and `align` props (Radix passthrough).\n *\n * @example\n * ```tsx\n * // Simple tooltip\n * <TooltipContent>Info text</TooltipContent>\n *\n * // Infobox with structured content\n * <TooltipContent\n * variant=\"infobox\"\n * heading=\"Title\"\n * icon={<InfoCircleIcon className=\"size-5\" />}\n * primaryAction={{ label: \"OK\", onClick: () => {} }}\n * secondaryAction={{ label: \"Dismiss\" }}\n * >\n * Info text\n * </TooltipContent>\n * ```\n */\nexport const TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n TooltipContentProps\n>(\n (\n {\n className,\n variant = \"tooltip\",\n showArrow = true,\n sideOffset = 8,\n heading,\n icon,\n pill,\n primaryAction,\n secondaryAction,\n children,\n side,\n style,\n ...props\n },\n ref,\n ) => {\n const isInfobox = variant === \"infobox\";\n const hasHeader =\n isInfobox && (icon !== undefined || heading !== undefined || pill !== undefined);\n const hasActions = isInfobox && (primaryAction !== undefined || secondaryAction !== undefined);\n\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n collisionPadding={8}\n style={{ zIndex: \"var(--fanvue-ui-portal-z-index, 50)\", ...style }}\n className={cn(\n \"typography-regular-body-md max-h-[var(--radix-tooltip-content-available-height)] max-w-[320px] overflow-hidden rounded-3xl bg-surface-pageinverse p-4 text-foreground-inverse shadow-[0px_2px_4px_0px_rgba(17,24,39,0.08)]\",\n isInfobox && \"border border-neutral-200\",\n className,\n )}\n align=\"center\"\n arrowPadding={12}\n side={side}\n {...props}\n >\n {isInfobox ? (\n <InfoboxContent\n icon={icon}\n heading={heading}\n pill={pill}\n primaryAction={primaryAction}\n secondaryAction={secondaryAction}\n hasHeader={hasHeader}\n hasActions={hasActions}\n >\n {children}\n </InfoboxContent>\n ) : (\n children\n )}\n {showArrow && (\n <TooltipPrimitive.Arrow\n className={\n \"-translate-y-px! fill-surface-pageinverse stroke-2 stroke-surface-pageinverse\"\n }\n width={12}\n height={6}\n />\n )}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n },\n);\nTooltipContent.displayName = \"TooltipContent\";\n"],"names":["TooltipPrimitive","jsx","Button","jsxs","React","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AASO,MAAM,kBAAkBA,4BAAiB;AAgBzC,MAAM,UAAUA,4BAAiB;AAMjC,MAAM,iBAAiBA,4BAAiB;AA+D/C,MAAM,eAAe,CAAC;AAAA,EACpB;AAAA,EACA;AACF,MAIE,OAAO,UACL,OAAO,UAEPC,2BAAAA,IAACC,OAAAA,QAAA,EAAO,SAAkB,MAAK,MAAK,SAAS,OAAO,SACjD,iBAAO,OACV;AAGJ,MAAM,iBAAiB,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAUEC,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACZ,UAAA;AAAA,EAAA,aACCA,2BAAAA,KAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,QAAQF,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,MAAK;AAAA,IAC/C,WACCA,2BAAAA,IAAC,KAAA,EAAE,WAAU,sEACV,UAAA,SACH;AAAA,IAED,QAAQA,2BAAAA,IAAC,OAAA,EAAI,WAAU,YAAY,UAAA,KAAA,CAAK;AAAA,EAAA,GAC3C;AAAA,EAED,YACCA,2BAAAA,IAAC,OAAA,EAAI,WAAU,sDAAsD,UAAS;AAAA,EAE/E,cACCE,2BAAAA,KAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,iBAAiBF,2BAAAA,IAAC,cAAA,EAAa,QAAQ,eAAe,SAAQ,SAAQ;AAAA,IACtE,mBAAmBA,2BAAAA,IAAC,cAAA,EAAa,QAAQ,iBAAiB,SAAQ,WAAA,CAAW;AAAA,EAAA,EAAA,CAChF;AAAA,GAEJ;AAyBK,MAAM,iBAAiBG,iBAAM;AAAA,EAIlC,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,YAAY,YAAY;AAC9B,UAAM,YACJ,cAAc,SAAS,UAAa,YAAY,UAAa,SAAS;AACxE,UAAM,aAAa,cAAc,kBAAkB,UAAa,oBAAoB;AAEpF,WACEH,2BAAAA,IAACD,4BAAiB,QAAjB,EACC,UAAAG,2BAAAA;AAAAA,MAACH,4BAAiB;AAAA,MAAjB;AAAA,QACC;AAAA,QACA;AAAA,QACA,kBAAkB;AAAA,QAClB,OAAO,EAAE,QAAQ,uCAAuC,GAAG,MAAA;AAAA,QAC3D,WAAWK,GAAAA;AAAAA,UACT;AAAA,UACA,aAAa;AAAA,UACb;AAAA,QAAA;AAAA,QAEF,OAAM;AAAA,QACN,cAAc;AAAA,QACd;AAAA,QACC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,YACCJ,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cAEC;AAAA,YAAA;AAAA,UAAA,IAGH;AAAA,UAED,aACCA,2BAAAA;AAAAA,YAACD,4BAAiB;AAAA,YAAjB;AAAA,cACC,WACE;AAAA,cAEF,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,QACV;AAAA,MAAA;AAAA,IAAA,GAGN;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;;;;;"}
|
|
1
|
+
{"version":3,"file":"Tooltip.cjs","sources":["../../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\n\n/** Props for the {@link TooltipProvider}. Wraps Radix `Tooltip.Provider`. */\nexport type TooltipProviderProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>;\n\n/** Provides tooltip delay and skip-delay context. Wrap your app or a subtree. */\nexport const TooltipProvider = TooltipPrimitive.Provider;\n\n/** Props for the {@link Tooltip} root component. */\nexport interface TooltipProps extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root> {\n /**\n * Controlled open state. When provided, the component is in controlled mode\n * and you must also supply `onOpenChange` to update the value.\n */\n open?: boolean;\n /** Called when the open state changes. Required when `open` is controlled. */\n onOpenChange?: (open: boolean) => void;\n /** The open state of the tooltip when it is initially rendered (uncontrolled). */\n defaultOpen?: boolean;\n}\n\n/** Root component that manages open/close state for a single tooltip. */\nexport const Tooltip = TooltipPrimitive.Root;\n\n/** Props for the {@link TooltipTrigger} component. */\nexport type TooltipTriggerProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>;\n\n/** The element that triggers the tooltip on hover/focus. */\nexport const TooltipTrigger = TooltipPrimitive.Trigger;\n\n/**\n * Visual style variant of the tooltip content.\n *\n * - `\"tooltip\"` — simple text bubble, no border.\n * - `\"infobox\"` — richer card with a visible border, structured header, body text, and optional actions.\n */\nexport type TooltipContentVariant = \"tooltip\" | \"infobox\";\n\n/** Action button configuration for the infobox variant of {@link TooltipContent}. */\nexport interface TooltipAction {\n /** Button label. */\n label: string;\n /** Click handler. */\n onClick?: () => void;\n /**\n * Optional custom React node to be rendered for the action instead of the default button.\n * Only used in the infobox variant.\n */\n element?: React.ReactNode;\n}\n\nexport interface TooltipContentProps\n extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> {\n /**\n * Visual style variant.\n *\n * `\"tooltip\"` is a lightweight text bubble. `\"infobox\"` renders a structured card\n * with optional heading, icon, pill, body text, and action buttons.\n *\n * @default \"tooltip\"\n */\n variant?: TooltipContentVariant;\n /** Whether to show the directional arrow pointer. @default true */\n showArrow?: boolean;\n /**\n * Heading text rendered in subtitle style at the top of the infobox.\n * Infobox variant only.\n */\n heading?: React.ReactNode;\n /**\n * Icon element displayed to the left of the heading.\n * Infobox variant only.\n */\n icon?: React.ReactNode;\n /**\n * Pill or badge element displayed to the right of the heading.\n * Infobox variant only.\n */\n pill?: React.ReactNode;\n /**\n * Primary action button (brand green). Rendered below the body text.\n * Infobox variant only.\n */\n primaryAction?: TooltipAction;\n /**\n * Secondary action button (ghost). Rendered next to the primary action.\n * Infobox variant only.\n */\n secondaryAction?: TooltipAction;\n}\n\n/** Class overrides so CTA buttons render correctly on the tooltip's inverted background. */\nconst TOOLTIP_ACTION_CLASSES: Record<\"brand\" | \"tertiary\", string> = {\n brand: \"hover:bg-brand-accent-default/80 hover:text-foreground-onaccent\",\n tertiary: \"text-foreground-inverse hover:text-foreground-inverse hover:bg-foreground-inverse/10\",\n};\n\nconst ActionButton = ({\n action,\n variant,\n}: {\n action: TooltipAction;\n variant: \"brand\" | \"tertiary\";\n}) =>\n action.element ? (\n action.element\n ) : (\n <Button variant={variant} onClick={action.onClick} className={TOOLTIP_ACTION_CLASSES[variant]}>\n {action.label}\n </Button>\n );\n\nconst InfoboxContent = ({\n icon,\n heading,\n pill,\n children,\n primaryAction,\n secondaryAction,\n hasHeader,\n hasActions,\n}: {\n icon?: React.ReactNode;\n heading?: React.ReactNode;\n pill?: React.ReactNode;\n children?: React.ReactNode;\n primaryAction?: TooltipAction;\n secondaryAction?: TooltipAction;\n hasHeader: boolean;\n hasActions: boolean;\n}) => (\n <div className=\"flex flex-col gap-3\">\n {hasHeader && (\n <div className=\"flex items-center gap-3\">\n {icon && <div className=\"size-5 shrink-0\">{icon}</div>}\n {heading && (\n <p className=\"typography-semibold-body-lg min-w-0 flex-1 text-foreground-inverse\">\n {heading}\n </p>\n )}\n {pill && <div className=\"shrink-0\">{pill}</div>}\n </div>\n )}\n {children && (\n <div className=\"typography-regular-body-md text-foreground-inverse\">{children}</div>\n )}\n {hasActions && (\n <div className=\"flex items-center gap-1\">\n {primaryAction && <ActionButton action={primaryAction} variant=\"brand\" />}\n {secondaryAction && <ActionButton action={secondaryAction} variant=\"tertiary\" />}\n </div>\n )}\n </div>\n);\n\n/**\n * The popup content of the tooltip. Renders inside a portal.\n *\n * Arrow direction is controlled via the `side` and `align` props (Radix passthrough).\n *\n * @example\n * ```tsx\n * // Simple tooltip\n * <TooltipContent>Info text</TooltipContent>\n *\n * // Infobox with structured content\n * <TooltipContent\n * variant=\"infobox\"\n * heading=\"Title\"\n * icon={<InfoCircleIcon className=\"size-5\" />}\n * primaryAction={{ label: \"OK\", onClick: () => {} }}\n * secondaryAction={{ label: \"Dismiss\" }}\n * >\n * Info text\n * </TooltipContent>\n * ```\n */\nexport const TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n TooltipContentProps\n>(\n (\n {\n className,\n variant = \"tooltip\",\n showArrow = true,\n sideOffset = 8,\n heading,\n icon,\n pill,\n primaryAction,\n secondaryAction,\n children,\n side,\n style,\n ...props\n },\n ref,\n ) => {\n const isInfobox = variant === \"infobox\";\n const hasHeader =\n isInfobox && (icon !== undefined || heading !== undefined || pill !== undefined);\n const hasActions = isInfobox && (primaryAction !== undefined || secondaryAction !== undefined);\n\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n collisionPadding={8}\n style={{ zIndex: \"var(--fanvue-ui-portal-z-index, 50)\", ...style }}\n className={cn(\n \"typography-regular-body-md max-h-[var(--radix-tooltip-content-available-height)] max-w-[320px] overflow-hidden rounded-3xl bg-surface-pageinverse p-4 text-foreground-inverse shadow-[0px_2px_4px_0px_rgba(17,24,39,0.08)]\",\n isInfobox && \"border border-neutral-200\",\n className,\n )}\n align=\"center\"\n arrowPadding={12}\n side={side}\n {...props}\n >\n {isInfobox ? (\n <InfoboxContent\n icon={icon}\n heading={heading}\n pill={pill}\n primaryAction={primaryAction}\n secondaryAction={secondaryAction}\n hasHeader={hasHeader}\n hasActions={hasActions}\n >\n {children}\n </InfoboxContent>\n ) : (\n children\n )}\n {showArrow && (\n <TooltipPrimitive.Arrow\n className={\n \"-translate-y-px! fill-surface-pageinverse stroke-2 stroke-surface-pageinverse\"\n }\n width={12}\n height={6}\n />\n )}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n },\n);\nTooltipContent.displayName = \"TooltipContent\";\n"],"names":["TooltipPrimitive","Button","jsxs","jsx","React","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AASO,MAAM,kBAAkBA,4BAAiB;AAgBzC,MAAM,UAAUA,4BAAiB;AAMjC,MAAM,iBAAiBA,4BAAiB;AAgE/C,MAAM,yBAA+D;AAAA,EACnE,OAAO;AAAA,EACP,UAAU;AACZ;AAEA,MAAM,eAAe,CAAC;AAAA,EACpB;AAAA,EACA;AACF,MAIE,OAAO,UACL,OAAO,yCAENC,OAAAA,QAAA,EAAO,SAAkB,SAAS,OAAO,SAAS,WAAW,uBAAuB,OAAO,GACzF,iBAAO,OACV;AAGJ,MAAM,iBAAiB,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAUEC,2BAAAA,KAAC,OAAA,EAAI,WAAU,uBACZ,UAAA;AAAA,EAAA,aACCA,2BAAAA,KAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,QAAQC,2BAAAA,IAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,MAAK;AAAA,IAC/C,WACCA,2BAAAA,IAAC,KAAA,EAAE,WAAU,sEACV,UAAA,SACH;AAAA,IAED,QAAQA,2BAAAA,IAAC,OAAA,EAAI,WAAU,YAAY,UAAA,KAAA,CAAK;AAAA,EAAA,GAC3C;AAAA,EAED,YACCA,2BAAAA,IAAC,OAAA,EAAI,WAAU,sDAAsD,UAAS;AAAA,EAE/E,cACCD,2BAAAA,KAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,iBAAiBC,2BAAAA,IAAC,cAAA,EAAa,QAAQ,eAAe,SAAQ,SAAQ;AAAA,IACtE,mBAAmBA,2BAAAA,IAAC,cAAA,EAAa,QAAQ,iBAAiB,SAAQ,WAAA,CAAW;AAAA,EAAA,EAAA,CAChF;AAAA,GAEJ;AAyBK,MAAM,iBAAiBC,iBAAM;AAAA,EAIlC,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,YAAY,YAAY;AAC9B,UAAM,YACJ,cAAc,SAAS,UAAa,YAAY,UAAa,SAAS;AACxE,UAAM,aAAa,cAAc,kBAAkB,UAAa,oBAAoB;AAEpF,WACED,2BAAAA,IAACH,4BAAiB,QAAjB,EACC,UAAAE,2BAAAA;AAAAA,MAACF,4BAAiB;AAAA,MAAjB;AAAA,QACC;AAAA,QACA;AAAA,QACA,kBAAkB;AAAA,QAClB,OAAO,EAAE,QAAQ,uCAAuC,GAAG,MAAA;AAAA,QAC3D,WAAWK,GAAAA;AAAAA,UACT;AAAA,UACA,aAAa;AAAA,UACb;AAAA,QAAA;AAAA,QAEF,OAAM;AAAA,QACN,cAAc;AAAA,QACd;AAAA,QACC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,YACCF,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cAEC;AAAA,YAAA;AAAA,UAAA,IAGH;AAAA,UAED,aACCA,2BAAAA;AAAAA,YAACH,4BAAiB;AAAA,YAAjB;AAAA,cACC,WACE;AAAA,cAEF,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,QACV;AAAA,MAAA;AAAA,IAAA,GAGN;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;;;;;"}
|
|
@@ -15,10 +15,10 @@ const DEFAULT_ICONS = {
|
|
|
15
15
|
error: /* @__PURE__ */ jsx(ErrorCircleIcon, {})
|
|
16
16
|
};
|
|
17
17
|
const CLOSE_BUTTON_CLASSES = {
|
|
18
|
-
info: "hover:bg-info-default active:bg-info-default text-info-default motion-safe:transition-colors motion-safe:duration-150",
|
|
19
|
-
success: "hover:bg-success-default active:bg-success-default text-success-default motion-safe:transition-colors motion-safe:duration-150",
|
|
20
|
-
warning: "hover:bg-warning-default active:bg-warning-default text-warning-default motion-safe:transition-colors motion-safe:duration-150",
|
|
21
|
-
error: "hover:bg-error-default active:bg-error-default text-error-default motion-safe:transition-colors motion-safe:duration-150"
|
|
18
|
+
info: "hover:bg-info-default/10 active:bg-info-default/20 text-info-default motion-safe:transition-colors motion-safe:duration-150",
|
|
19
|
+
success: "hover:bg-success-default/10 active:bg-success-default/20 text-success-default motion-safe:transition-colors motion-safe:duration-150",
|
|
20
|
+
warning: "hover:bg-warning-default/10 active:bg-warning-default/20 text-warning-default motion-safe:transition-colors motion-safe:duration-150",
|
|
21
|
+
error: "hover:bg-error-default/10 active:bg-error-default/20 text-error-default motion-safe:transition-colors motion-safe:duration-150"
|
|
22
22
|
};
|
|
23
23
|
const Alert = React.forwardRef(
|
|
24
24
|
({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert.mjs","sources":["../../../src/components/Alert/Alert.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\nimport { CheckCircleIcon } from \"../Icons/CheckCircleIcon\";\nimport { CrossIcon } from \"../Icons/CrossIcon\";\nimport { ErrorCircleIcon } from \"../Icons/ErrorCircleIcon\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { WarningTriangleIcon } from \"../Icons/WarningTriangleIcon\";\n\n/** Visual style variant of the alert. */\nexport type AlertVariant = \"info\" | \"success\" | \"warning\" | \"error\";\n\nconst DEFAULT_ICONS: Record<AlertVariant, React.ReactNode> = {\n info: <InfoCircleIcon />,\n success: <CheckCircleIcon />,\n warning: <WarningTriangleIcon />,\n error: <ErrorCircleIcon />,\n};\n\nexport interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Visual style variant of the alert. @default \"info\" */\n variant?: AlertVariant;\n /** Optional title text displayed in bold above the description. */\n title?: string;\n /** Custom icon override. Pass `null` to hide the icon entirely. Each variant shows a default icon when left `undefined`. */\n icon?: React.ReactNode | null;\n /** Whether to show the close button. @default false */\n closable?: boolean;\n /** Callback fired when the close button is clicked. */\n onClose?: () => void;\n /** Accessible label for the close button. @default \"Close alert\" */\n closeLabel?: string;\n}\n\nconst CLOSE_BUTTON_CLASSES: Record<AlertVariant, string> = {\n info: \"hover:bg-info-default active:bg-info-default text-info-default motion-safe:transition-colors motion-safe:duration-150\",\n success:\n \"hover:bg-success-default active:bg-success-default text-success-default motion-safe:transition-colors motion-safe:duration-150\",\n warning:\n \"hover:bg-warning-default active:bg-warning-default text-warning-default motion-safe:transition-colors motion-safe:duration-150\",\n error:\n \"hover:bg-error-default active:bg-error-default text-error-default motion-safe:transition-colors motion-safe:duration-150\",\n};\n\n/**\n * Displays a contextual feedback message to the user.\n *\n * Supports `info`, `success`, `warning`, and `error` variants with a default\n * icon per variant, optional title, description, and dismiss button.\n *\n * Each variant renders a default icon automatically. Pass a custom `icon` to\n * override, or `icon={null}` to hide the icon entirely.\n *\n * @example\n * ```tsx\n * <Alert variant=\"success\" title=\"Saved\" closable onClose={handleClose}>\n * Your changes have been saved.\n * </Alert>\n * ```\n */\nexport const Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n (\n {\n className,\n variant = \"info\",\n title,\n icon,\n closable = false,\n onClose,\n closeLabel = \"Close alert\",\n children,\n ...props\n },\n ref,\n ) => {\n const resolvedIcon = icon === null ? null : (icon ?? DEFAULT_ICONS[variant]);\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n data-testid=\"alert\"\n className={cn(\n \"grid gap-x-3 rounded-lg p-4 text-sm leading-[18px]\",\n resolvedIcon && closable && \"grid-cols-[auto_1fr_auto]\",\n resolvedIcon && !closable && \"grid-cols-[auto_1fr]\",\n !resolvedIcon && closable && \"grid-cols-[1fr_auto]\",\n !resolvedIcon && !closable && \"grid-cols-[1fr]\",\n title && children ? \"items-start\" : \"items-center\",\n variant === \"info\" && \"bg-info-background text-info-default\",\n variant === \"success\" && \"bg-success-background text-success-default\",\n variant === \"warning\" && \"bg-warning-background text-warning-default\",\n variant === \"error\" && \"bg-error-background text-error-default\",\n className,\n )}\n {...props}\n >\n {resolvedIcon && (\n <span className=\"flex shrink-0 items-start\" aria-hidden=\"true\">\n {resolvedIcon}\n </span>\n )}\n\n <div className=\"flex min-w-0 flex-col gap-2\">\n {title && (\n <div className=\"typography-semibold-body-md text-foreground-default\">{title}</div>\n )}\n <div className=\"typography-regular-body-md text-foreground-secondary\">{children}</div>\n </div>\n\n {closable && (\n <Button\n variant=\"tertiary\"\n size=\"24\"\n onClick={onClose}\n className={cn(\"self-start px-0\", CLOSE_BUTTON_CLASSES[variant])}\n aria-label={closeLabel}\n >\n <CrossIcon />\n </Button>\n )}\n </div>\n );\n },\n);\n\nAlert.displayName = \"Alert\";\n"],"names":[],"mappings":";;;;;;;;;;AAYA,MAAM,gBAAuD;AAAA,EAC3D,0BAAO,gBAAA,EAAe;AAAA,EACtB,6BAAU,iBAAA,EAAgB;AAAA,EAC1B,6BAAU,qBAAA,EAAoB;AAAA,EAC9B,2BAAQ,iBAAA,CAAA,CAAgB;AAC1B;AAiBA,MAAM,uBAAqD;AAAA,EACzD,MAAM;AAAA,EACN,SACE;AAAA,EACF,SACE;AAAA,EACF,OACE;AACJ;AAkBO,MAAM,QAAQ,MAAM;AAAA,EACzB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,eAAe,SAAS,OAAO,OAAQ,QAAQ,cAAc,OAAO;AAE1E,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA,gBAAgB,YAAY;AAAA,UAC5B,gBAAgB,CAAC,YAAY;AAAA,UAC7B,CAAC,gBAAgB,YAAY;AAAA,UAC7B,CAAC,gBAAgB,CAAC,YAAY;AAAA,UAC9B,SAAS,WAAW,gBAAgB;AAAA,UACpC,YAAY,UAAU;AAAA,UACtB,YAAY,aAAa;AAAA,UACzB,YAAY,aAAa;AAAA,UACzB,YAAY,WAAW;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,oCACE,QAAA,EAAK,WAAU,6BAA4B,eAAY,QACrD,UAAA,cACH;AAAA,UAGF,qBAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,YAAA,SACC,oBAAC,OAAA,EAAI,WAAU,uDAAuD,UAAA,OAAM;AAAA,YAE9E,oBAAC,OAAA,EAAI,WAAU,wDAAwD,SAAA,CAAS;AAAA,UAAA,GAClF;AAAA,UAEC,YACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS;AAAA,cACT,WAAW,GAAG,mBAAmB,qBAAqB,OAAO,CAAC;AAAA,cAC9D,cAAY;AAAA,cAEZ,8BAAC,WAAA,CAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,MAAM,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Alert.mjs","sources":["../../../src/components/Alert/Alert.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\nimport { CheckCircleIcon } from \"../Icons/CheckCircleIcon\";\nimport { CrossIcon } from \"../Icons/CrossIcon\";\nimport { ErrorCircleIcon } from \"../Icons/ErrorCircleIcon\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { WarningTriangleIcon } from \"../Icons/WarningTriangleIcon\";\n\n/** Visual style variant of the alert. */\nexport type AlertVariant = \"info\" | \"success\" | \"warning\" | \"error\";\n\nconst DEFAULT_ICONS: Record<AlertVariant, React.ReactNode> = {\n info: <InfoCircleIcon />,\n success: <CheckCircleIcon />,\n warning: <WarningTriangleIcon />,\n error: <ErrorCircleIcon />,\n};\n\nexport interface AlertProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Visual style variant of the alert. @default \"info\" */\n variant?: AlertVariant;\n /** Optional title text displayed in bold above the description. */\n title?: string;\n /** Custom icon override. Pass `null` to hide the icon entirely. Each variant shows a default icon when left `undefined`. */\n icon?: React.ReactNode | null;\n /** Whether to show the close button. @default false */\n closable?: boolean;\n /** Callback fired when the close button is clicked. */\n onClose?: () => void;\n /** Accessible label for the close button. @default \"Close alert\" */\n closeLabel?: string;\n}\n\nconst CLOSE_BUTTON_CLASSES: Record<AlertVariant, string> = {\n info: \"hover:bg-info-default/10 active:bg-info-default/20 text-info-default motion-safe:transition-colors motion-safe:duration-150\",\n success:\n \"hover:bg-success-default/10 active:bg-success-default/20 text-success-default motion-safe:transition-colors motion-safe:duration-150\",\n warning:\n \"hover:bg-warning-default/10 active:bg-warning-default/20 text-warning-default motion-safe:transition-colors motion-safe:duration-150\",\n error:\n \"hover:bg-error-default/10 active:bg-error-default/20 text-error-default motion-safe:transition-colors motion-safe:duration-150\",\n};\n\n/**\n * Displays a contextual feedback message to the user.\n *\n * Supports `info`, `success`, `warning`, and `error` variants with a default\n * icon per variant, optional title, description, and dismiss button.\n *\n * Each variant renders a default icon automatically. Pass a custom `icon` to\n * override, or `icon={null}` to hide the icon entirely.\n *\n * @example\n * ```tsx\n * <Alert variant=\"success\" title=\"Saved\" closable onClose={handleClose}>\n * Your changes have been saved.\n * </Alert>\n * ```\n */\nexport const Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n (\n {\n className,\n variant = \"info\",\n title,\n icon,\n closable = false,\n onClose,\n closeLabel = \"Close alert\",\n children,\n ...props\n },\n ref,\n ) => {\n const resolvedIcon = icon === null ? null : (icon ?? DEFAULT_ICONS[variant]);\n\n return (\n <div\n ref={ref}\n role=\"alert\"\n data-testid=\"alert\"\n className={cn(\n \"grid gap-x-3 rounded-lg p-4 text-sm leading-[18px]\",\n resolvedIcon && closable && \"grid-cols-[auto_1fr_auto]\",\n resolvedIcon && !closable && \"grid-cols-[auto_1fr]\",\n !resolvedIcon && closable && \"grid-cols-[1fr_auto]\",\n !resolvedIcon && !closable && \"grid-cols-[1fr]\",\n title && children ? \"items-start\" : \"items-center\",\n variant === \"info\" && \"bg-info-background text-info-default\",\n variant === \"success\" && \"bg-success-background text-success-default\",\n variant === \"warning\" && \"bg-warning-background text-warning-default\",\n variant === \"error\" && \"bg-error-background text-error-default\",\n className,\n )}\n {...props}\n >\n {resolvedIcon && (\n <span className=\"flex shrink-0 items-start\" aria-hidden=\"true\">\n {resolvedIcon}\n </span>\n )}\n\n <div className=\"flex min-w-0 flex-col gap-2\">\n {title && (\n <div className=\"typography-semibold-body-md text-foreground-default\">{title}</div>\n )}\n <div className=\"typography-regular-body-md text-foreground-secondary\">{children}</div>\n </div>\n\n {closable && (\n <Button\n variant=\"tertiary\"\n size=\"24\"\n onClick={onClose}\n className={cn(\"self-start px-0\", CLOSE_BUTTON_CLASSES[variant])}\n aria-label={closeLabel}\n >\n <CrossIcon />\n </Button>\n )}\n </div>\n );\n },\n);\n\nAlert.displayName = \"Alert\";\n"],"names":[],"mappings":";;;;;;;;;;AAYA,MAAM,gBAAuD;AAAA,EAC3D,0BAAO,gBAAA,EAAe;AAAA,EACtB,6BAAU,iBAAA,EAAgB;AAAA,EAC1B,6BAAU,qBAAA,EAAoB;AAAA,EAC9B,2BAAQ,iBAAA,CAAA,CAAgB;AAC1B;AAiBA,MAAM,uBAAqD;AAAA,EACzD,MAAM;AAAA,EACN,SACE;AAAA,EACF,SACE;AAAA,EACF,OACE;AACJ;AAkBO,MAAM,QAAQ,MAAM;AAAA,EACzB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,eAAe,SAAS,OAAO,OAAQ,QAAQ,cAAc,OAAO;AAE1E,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA,gBAAgB,YAAY;AAAA,UAC5B,gBAAgB,CAAC,YAAY;AAAA,UAC7B,CAAC,gBAAgB,YAAY;AAAA,UAC7B,CAAC,gBAAgB,CAAC,YAAY;AAAA,UAC9B,SAAS,WAAW,gBAAgB;AAAA,UACpC,YAAY,UAAU;AAAA,UACtB,YAAY,aAAa;AAAA,UACzB,YAAY,aAAa;AAAA,UACzB,YAAY,WAAW;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,oCACE,QAAA,EAAK,WAAU,6BAA4B,eAAY,QACrD,UAAA,cACH;AAAA,UAGF,qBAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,YAAA,SACC,oBAAC,OAAA,EAAI,WAAU,uDAAuD,UAAA,OAAM;AAAA,YAE9E,oBAAC,OAAA,EAAI,WAAU,wDAAwD,SAAA,CAAS;AAAA,UAAA,GAClF;AAAA,UAEC,YACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS;AAAA,cACT,WAAW,GAAG,mBAAmB,qBAAqB,OAAO,CAAC;AAAA,cAC9D,cAAY;AAAA,cAEZ,8BAAC,WAAA,CAAA,CAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,MAAM,cAAc;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs,
|
|
2
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { Slot, Slottable } from "@radix-ui/react-slot";
|
|
4
4
|
import * as React from "react";
|
|
5
5
|
import { cn } from "../../utils/cn.mjs";
|
|
@@ -22,13 +22,13 @@ const Chip = React.forwardRef(
|
|
|
22
22
|
const isInteractive = !!onClick && !asChild;
|
|
23
23
|
const Comp = asChild ? Slot : isInteractive ? "button" : "span";
|
|
24
24
|
const isDark = variant === "dark";
|
|
25
|
-
return /* @__PURE__ */
|
|
25
|
+
return /* @__PURE__ */ jsx(
|
|
26
26
|
Comp,
|
|
27
27
|
{
|
|
28
28
|
ref,
|
|
29
29
|
"data-testid": "chip",
|
|
30
30
|
className: cn(
|
|
31
|
-
"typography-semibold-body-sm relative inline-flex min-w-0 items-center justify-center
|
|
31
|
+
"typography-semibold-body-sm relative inline-flex min-w-0 items-center justify-center whitespace-nowrap motion-safe:transition-colors motion-safe:duration-150",
|
|
32
32
|
// Shape
|
|
33
33
|
variant === "square" ? "rounded-lg" : "rounded-full",
|
|
34
34
|
// Size
|
|
@@ -57,13 +57,29 @@ const Chip = React.forwardRef(
|
|
|
57
57
|
...!isInteractive && disabled && { "aria-disabled": true },
|
|
58
58
|
...selected && { "data-selected": "" },
|
|
59
59
|
...props,
|
|
60
|
-
children: [
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
children: asChild ? /* @__PURE__ */ jsx(Slottable, { children }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
61
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-0.5 overflow-hidden px-3", children: [
|
|
62
|
+
leftDot && /* @__PURE__ */ jsx("span", { className: "size-2 shrink-0 rounded-full bg-current", "aria-hidden": "true" }),
|
|
63
|
+
leftIcon && /* @__PURE__ */ jsx(
|
|
64
|
+
"span",
|
|
65
|
+
{
|
|
66
|
+
className: "flex size-5 shrink-0 items-center justify-center",
|
|
67
|
+
"aria-hidden": "true",
|
|
68
|
+
children: leftIcon
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children }),
|
|
72
|
+
rightIcon && /* @__PURE__ */ jsx(
|
|
73
|
+
"span",
|
|
74
|
+
{
|
|
75
|
+
className: "flex size-5 shrink-0 items-center justify-center",
|
|
76
|
+
"aria-hidden": "true",
|
|
77
|
+
children: rightIcon
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
] }),
|
|
65
81
|
notificationLabel && /* @__PURE__ */ jsx("span", { className: "typography-semibold-body-sm absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-foreground-default px-1 text-foreground-inverse", children: notificationLabel })
|
|
66
|
-
]
|
|
82
|
+
] })
|
|
67
83
|
}
|
|
68
84
|
);
|
|
69
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chip.mjs","sources":["../../../src/components/Chip/Chip.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Visual variant of the chip. */\nexport type ChipVariant = \"rounded\" | \"square\" | \"dark\";\n/** Height of the chip in pixels. */\nexport type ChipSize = \"32\" | \"40\";\n\nexport interface ChipProps extends React.HTMLAttributes<HTMLElement> {\n /** Visual variant of the chip. @default \"rounded\" */\n variant?: ChipVariant;\n /** Height of the chip in pixels. @default \"32\" */\n size?: ChipSize;\n /** Whether the chip is in a selected (pressed) state. @default false */\n selected?: boolean;\n /** Whether the chip is disabled. @default false */\n disabled?: boolean;\n /** Whether to show a coloured status dot at the leading edge. @default false */\n leftDot?: boolean;\n /** Icon element displayed before the label. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed after the label. */\n rightIcon?: React.ReactNode;\n /** Notification badge content (e.g. `\"99+\"`). Passed as a string for i18n support. */\n notificationLabel?: string;\n /** Click handler — when provided, the chip renders as a `<button>` for accessibility. */\n onClick?: React.MouseEventHandler<HTMLElement>;\n /** Merge props onto a child element instead of rendering a wrapper. @default false */\n asChild?: boolean;\n}\n\n/**\n * A compact element for filters, tags, or toggleable actions. When an `onClick`\n * handler is provided, the chip renders as an interactive `<button>` with\n * `aria-pressed` support.\n *\n * @example\n * ```tsx\n * <Chip selected onClick={toggle}>Music</Chip>\n * ```\n */\nexport const Chip = React.forwardRef<HTMLButtonElement, ChipProps>(\n (\n {\n className,\n variant = \"rounded\",\n size = \"32\",\n selected = false,\n disabled = false,\n leftDot = false,\n leftIcon,\n rightIcon,\n notificationLabel,\n onClick,\n asChild = false,\n children,\n ...props\n },\n ref,\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Variant-heavy UI component\n ) => {\n const isInteractive = !!onClick && !asChild;\n const Comp = asChild ? Slot : isInteractive ? \"button\" : \"span\";\n const isDark = variant === \"dark\";\n\n return (\n <Comp\n ref={ref}\n data-testid=\"chip\"\n className={cn(\n \"typography-semibold-body-sm relative inline-flex min-w-0 items-center justify-center
|
|
1
|
+
{"version":3,"file":"Chip.mjs","sources":["../../../src/components/Chip/Chip.tsx"],"sourcesContent":["import { Slot, Slottable } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Visual variant of the chip. */\nexport type ChipVariant = \"rounded\" | \"square\" | \"dark\";\n/** Height of the chip in pixels. */\nexport type ChipSize = \"32\" | \"40\";\n\nexport interface ChipProps extends React.HTMLAttributes<HTMLElement> {\n /** Visual variant of the chip. @default \"rounded\" */\n variant?: ChipVariant;\n /** Height of the chip in pixels. @default \"32\" */\n size?: ChipSize;\n /** Whether the chip is in a selected (pressed) state. @default false */\n selected?: boolean;\n /** Whether the chip is disabled. @default false */\n disabled?: boolean;\n /** Whether to show a coloured status dot at the leading edge. @default false */\n leftDot?: boolean;\n /** Icon element displayed before the label. */\n leftIcon?: React.ReactNode;\n /** Icon element displayed after the label. */\n rightIcon?: React.ReactNode;\n /** Notification badge content (e.g. `\"99+\"`). Passed as a string for i18n support. */\n notificationLabel?: string;\n /** Click handler — when provided, the chip renders as a `<button>` for accessibility. */\n onClick?: React.MouseEventHandler<HTMLElement>;\n /** Merge props onto a child element instead of rendering a wrapper. @default false */\n asChild?: boolean;\n}\n\n/**\n * A compact element for filters, tags, or toggleable actions. When an `onClick`\n * handler is provided, the chip renders as an interactive `<button>` with\n * `aria-pressed` support.\n *\n * @example\n * ```tsx\n * <Chip selected onClick={toggle}>Music</Chip>\n * ```\n */\nexport const Chip = React.forwardRef<HTMLButtonElement, ChipProps>(\n (\n {\n className,\n variant = \"rounded\",\n size = \"32\",\n selected = false,\n disabled = false,\n leftDot = false,\n leftIcon,\n rightIcon,\n notificationLabel,\n onClick,\n asChild = false,\n children,\n ...props\n },\n ref,\n // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Variant-heavy UI component\n ) => {\n const isInteractive = !!onClick && !asChild;\n const Comp = asChild ? Slot : isInteractive ? \"button\" : \"span\";\n const isDark = variant === \"dark\";\n\n return (\n <Comp\n ref={ref}\n data-testid=\"chip\"\n className={cn(\n \"typography-semibold-body-sm relative inline-flex min-w-0 items-center justify-center whitespace-nowrap motion-safe:transition-colors motion-safe:duration-150\",\n // Shape\n variant === \"square\" ? \"rounded-lg\" : \"rounded-full\",\n // Size\n size === \"32\" && \"h-8 py-1\",\n size === \"40\" && \"h-10 py-2.5\",\n // Variant colors\n isDark && \"bg-neutral-50 text-foreground-onaccentinverse\",\n !isDark && selected && \"bg-brand-accent-muted text-neutral-400\",\n !isDark && !selected && \"bg-neutral-100 text-neutral-400\",\n // Interactive\n isInteractive && !disabled && \"cursor-pointer\",\n isInteractive &&\n !disabled &&\n !isDark &&\n !selected &&\n \"hover:bg-brand-accent-muted active:bg-brand-accent-muted\",\n // Focus\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n // Disabled\n disabled && isDark && \"pointer-events-none opacity-50\",\n disabled && !isDark && \"pointer-events-none text-neutral-300\",\n className,\n )}\n {...(isInteractive && {\n type: \"button\" as const,\n disabled,\n \"aria-pressed\": selected,\n onClick,\n })}\n {...(!isInteractive && disabled && { \"aria-disabled\": true })}\n {...(selected && { \"data-selected\": \"\" })}\n {...props}\n >\n {asChild ? (\n <Slottable>{children}</Slottable>\n ) : (\n <>\n <span className=\"flex min-w-0 items-center gap-0.5 overflow-hidden px-3\">\n {leftDot && (\n <span className=\"size-2 shrink-0 rounded-full bg-current\" aria-hidden=\"true\" />\n )}\n {leftIcon && (\n <span\n className=\"flex size-5 shrink-0 items-center justify-center\"\n aria-hidden=\"true\"\n >\n {leftIcon}\n </span>\n )}\n <span className=\"min-w-0 truncate\">{children}</span>\n {rightIcon && (\n <span\n className=\"flex size-5 shrink-0 items-center justify-center\"\n aria-hidden=\"true\"\n >\n {rightIcon}\n </span>\n )}\n </span>\n {notificationLabel && (\n <span className=\"typography-semibold-body-sm absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-foreground-default px-1 text-foreground-inverse\">\n {notificationLabel}\n </span>\n )}\n </>\n )}\n </Comp>\n );\n },\n);\n\nChip.displayName = \"Chip\";\n"],"names":[],"mappings":";;;;;AA0CO,MAAM,OAAO,MAAM;AAAA,EACxB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,OAAO;AAAA,IACP,WAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QAEG;AACH,UAAM,gBAAgB,CAAC,CAAC,WAAW,CAAC;AACpC,UAAM,OAAO,UAAU,OAAO,gBAAgB,WAAW;AACzD,UAAM,SAAS,YAAY;AAE3B,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA;AAAA,UAEA,YAAY,WAAW,eAAe;AAAA;AAAA,UAEtC,SAAS,QAAQ;AAAA,UACjB,SAAS,QAAQ;AAAA;AAAA,UAEjB,UAAU;AAAA,UACV,CAAC,UAAU,YAAY;AAAA,UACvB,CAAC,UAAU,CAAC,YAAY;AAAA;AAAA,UAExB,iBAAiB,CAAC,YAAY;AAAA,UAC9B,iBACE,CAAC,YACD,CAAC,UACD,CAAC,YACD;AAAA;AAAA,UAEF;AAAA;AAAA,UAEA,YAAY,UAAU;AAAA,UACtB,YAAY,CAAC,UAAU;AAAA,UACvB;AAAA,QAAA;AAAA,QAED,GAAI,iBAAiB;AAAA,UACpB,MAAM;AAAA,UACN;AAAA,UACA,gBAAgB;AAAA,UAChB;AAAA,QAAA;AAAA,QAED,GAAI,CAAC,iBAAiB,YAAY,EAAE,iBAAiB,KAAA;AAAA,QACrD,GAAI,YAAY,EAAE,iBAAiB,GAAA;AAAA,QACnC,GAAG;AAAA,QAEH,UAAA,UACC,oBAAC,WAAA,EAAW,SAAA,CAAS,IAErB,qBAAA,UAAA,EACE,UAAA;AAAA,UAAA,qBAAC,QAAA,EAAK,WAAU,0DACb,UAAA;AAAA,YAAA,WACC,oBAAC,QAAA,EAAK,WAAU,2CAA0C,eAAY,QAAO;AAAA,YAE9E,YACC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,eAAY;AAAA,gBAEX,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGL,oBAAC,QAAA,EAAK,WAAU,oBAAoB,SAAA,CAAS;AAAA,YAC5C,aACC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,eAAY;AAAA,gBAEX,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,UACH,GAEJ;AAAA,UACC,qBACC,oBAAC,QAAA,EAAK,WAAU,qKACb,UAAA,kBAAA,CACH;AAAA,QAAA,EAAA,CAEJ;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEA,KAAK,cAAc;"}
|
|
@@ -13,7 +13,7 @@ const CloseIcon = React.forwardRef(
|
|
|
13
13
|
"aria-hidden": "true",
|
|
14
14
|
className: cn("size-6", className),
|
|
15
15
|
...props,
|
|
16
|
-
children: /* @__PURE__ */ jsx("g", { stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.5", children: /* @__PURE__ */ jsx("path", { d: "
|
|
16
|
+
children: /* @__PURE__ */ jsx("g", { stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.5", children: /* @__PURE__ */ jsx("path", { d: "M7.003 7.006 17 17.003M17 6.996l-9.997 9.998" }) })
|
|
17
17
|
}
|
|
18
18
|
);
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloseIcon.mjs","sources":["../../../src/components/Icons/CloseIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const CloseIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <g stroke=\"currentColor\" strokeLinecap=\"round\" strokeWidth=\"1.5\">\n <path d=\"
|
|
1
|
+
{"version":3,"file":"CloseIcon.mjs","sources":["../../../src/components/Icons/CloseIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const CloseIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <g stroke=\"currentColor\" strokeLinecap=\"round\" strokeWidth=\"1.5\">\n <path d=\"M7.003 7.006 17 17.003M17 6.996l-9.997 9.998\" />\n </g>\n </svg>\n );\n },\n);\n\nCloseIcon.displayName = \"CloseIcon\";\n"],"names":[],"mappings":";;;;AAIO,MAAM,YAAY,MAAM;AAAA,EAC7B,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAAQ;AAChC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAW,GAAG,UAAU,SAAS;AAAA,QAChC,GAAG;AAAA,QAEJ,UAAA,oBAAC,KAAA,EAAE,QAAO,gBAAe,eAAc,SAAQ,aAAY,OACzD,UAAA,oBAAC,QAAA,EAAK,GAAE,+CAAA,CAA+C,EAAA,CACzD;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,UAAU,cAAc;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { cn } from "../../utils/cn.mjs";
|
|
5
5
|
const DoubleTickIcon = React.forwardRef(
|
|
@@ -13,17 +13,7 @@ const DoubleTickIcon = React.forwardRef(
|
|
|
13
13
|
"aria-hidden": "true",
|
|
14
14
|
className: cn("size-6", className),
|
|
15
15
|
...props,
|
|
16
|
-
children: /* @__PURE__ */
|
|
17
|
-
/* @__PURE__ */ jsx(
|
|
18
|
-
"path",
|
|
19
|
-
{
|
|
20
|
-
fillRule: "evenodd",
|
|
21
|
-
d: "M5.22 11.47c.29-.29.77-.29 1.06 0l2.3 2.3.594-.596 1.06 1.06L9.11 15.36a.75.75 0 0 1-1.06 0l-2.83-2.83a.755.755 0 0 1 0-1.06m8.5-2.84c.29-.29.77-.29 1.06 0s.29.77 0 1.06l-2.796 2.795-1.06-1.06z",
|
|
22
|
-
clipRule: "evenodd"
|
|
23
|
-
}
|
|
24
|
-
),
|
|
25
|
-
/* @__PURE__ */ jsx("path", { d: "M12.58 15.58a.75.75 0 0 1-.53-.22l-2.83-2.83a.754.754 0 0 1 0-1.06c.29-.29.77-.29 1.06 0l2.3 2.3 5.14-5.14c.29-.29.77-.29 1.06 0s.29.77 0 1.06l-5.67 5.67a.75.75 0 0 1-.53.22" })
|
|
26
|
-
] })
|
|
16
|
+
children: /* @__PURE__ */ jsx("g", { stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5", children: /* @__PURE__ */ jsx("path", { d: "m8 11.5 5 5L22.5 7M2 11.5l5 5L8.5 15m8-8-4.75 4.75" }) })
|
|
27
17
|
}
|
|
28
18
|
);
|
|
29
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoubleTickIcon.mjs","sources":["../../../src/components/Icons/DoubleTickIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const DoubleTickIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <g
|
|
1
|
+
{"version":3,"file":"DoubleTickIcon.mjs","sources":["../../../src/components/Icons/DoubleTickIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const DoubleTickIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <g stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"1.5\">\n <path d=\"m8 11.5 5 5L22.5 7M2 11.5l5 5L8.5 15m8-8-4.75 4.75\" />\n </g>\n </svg>\n );\n },\n);\n\nDoubleTickIcon.displayName = \"DoubleTickIcon\";\n"],"names":[],"mappings":";;;;AAIO,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAAQ;AAChC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAW,GAAG,UAAU,SAAS;AAAA,QAChC,GAAG;AAAA,QAEJ,UAAA,oBAAC,KAAA,EAAE,QAAO,gBAAe,eAAc,SAAQ,gBAAe,SAAQ,aAAY,OAChF,UAAA,oBAAC,QAAA,EAAK,GAAE,sDAAqD,EAAA,CAC/D;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,eAAe,cAAc;"}
|
|
@@ -16,8 +16,11 @@ const TickIcon = React.forwardRef(
|
|
|
16
16
|
children: /* @__PURE__ */ jsx(
|
|
17
17
|
"path",
|
|
18
18
|
{
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
stroke: "currentColor",
|
|
20
|
+
strokeLinecap: "round",
|
|
21
|
+
strokeLinejoin: "round",
|
|
22
|
+
strokeWidth: "1.5",
|
|
23
|
+
d: "m5 12 5 5 9.5-9.5"
|
|
21
24
|
}
|
|
22
25
|
)
|
|
23
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TickIcon.mjs","sources":["../../../src/components/Icons/TickIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const TickIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <path\n
|
|
1
|
+
{"version":3,"file":"TickIcon.mjs","sources":["../../../src/components/Icons/TickIcon.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport type { IconProps } from \"./types\";\n\nexport const TickIcon = React.forwardRef<SVGSVGElement, IconProps>(\n ({ className, ...props }, ref) => {\n return (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n className={cn(\"size-6\", className)}\n {...props}\n >\n <path\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n d=\"m5 12 5 5 9.5-9.5\"\n />\n </svg>\n );\n },\n);\n\nTickIcon.displayName = \"TickIcon\";\n"],"names":[],"mappings":";;;;AAIO,MAAM,WAAW,MAAM;AAAA,EAC5B,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAAQ;AAChC,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,eAAY;AAAA,QACZ,WAAW,GAAG,UAAU,SAAS;AAAA,QAChC,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,QAAO;AAAA,YACP,eAAc;AAAA,YACd,gBAAe;AAAA,YACf,aAAY;AAAA,YACZ,GAAE;AAAA,UAAA;AAAA,QAAA;AAAA,MACJ;AAAA,IAAA;AAAA,EAGN;AACF;AAEA,SAAS,cAAc;"}
|
|
@@ -7,10 +7,14 @@ import { Button } from "../Button/Button.mjs";
|
|
|
7
7
|
const TooltipProvider = TooltipPrimitive.Provider;
|
|
8
8
|
const Tooltip = TooltipPrimitive.Root;
|
|
9
9
|
const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
10
|
+
const TOOLTIP_ACTION_CLASSES = {
|
|
11
|
+
brand: "hover:bg-brand-accent-default/80 hover:text-foreground-onaccent",
|
|
12
|
+
tertiary: "text-foreground-inverse hover:text-foreground-inverse hover:bg-foreground-inverse/10"
|
|
13
|
+
};
|
|
10
14
|
const ActionButton = ({
|
|
11
15
|
action,
|
|
12
16
|
variant
|
|
13
|
-
}) => action.element ? action.element : /* @__PURE__ */ jsx(Button, { variant,
|
|
17
|
+
}) => action.element ? action.element : /* @__PURE__ */ jsx(Button, { variant, onClick: action.onClick, className: TOOLTIP_ACTION_CLASSES[variant], children: action.label });
|
|
14
18
|
const InfoboxContent = ({
|
|
15
19
|
icon,
|
|
16
20
|
heading,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.mjs","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\n\n/** Props for the {@link TooltipProvider}. Wraps Radix `Tooltip.Provider`. */\nexport type TooltipProviderProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>;\n\n/** Provides tooltip delay and skip-delay context. Wrap your app or a subtree. */\nexport const TooltipProvider = TooltipPrimitive.Provider;\n\n/** Props for the {@link Tooltip} root component. */\nexport interface TooltipProps extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root> {\n /**\n * Controlled open state. When provided, the component is in controlled mode\n * and you must also supply `onOpenChange` to update the value.\n */\n open?: boolean;\n /** Called when the open state changes. Required when `open` is controlled. */\n onOpenChange?: (open: boolean) => void;\n /** The open state of the tooltip when it is initially rendered (uncontrolled). */\n defaultOpen?: boolean;\n}\n\n/** Root component that manages open/close state for a single tooltip. */\nexport const Tooltip = TooltipPrimitive.Root;\n\n/** Props for the {@link TooltipTrigger} component. */\nexport type TooltipTriggerProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>;\n\n/** The element that triggers the tooltip on hover/focus. */\nexport const TooltipTrigger = TooltipPrimitive.Trigger;\n\n/**\n * Visual style variant of the tooltip content.\n *\n * - `\"tooltip\"` — simple text bubble, no border.\n * - `\"infobox\"` — richer card with a visible border, structured header, body text, and optional actions.\n */\nexport type TooltipContentVariant = \"tooltip\" | \"infobox\";\n\n/** Action button configuration for the infobox variant of {@link TooltipContent}. */\nexport interface TooltipAction {\n /** Button label. */\n label: string;\n /** Click handler. */\n onClick?: () => void;\n /**\n * Optional custom React node to be rendered for the action instead of the default button.\n * Only used in the infobox variant.\n */\n element?: React.ReactNode;\n}\n\nexport interface TooltipContentProps\n extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> {\n /**\n * Visual style variant.\n *\n * `\"tooltip\"` is a lightweight text bubble. `\"infobox\"` renders a structured card\n * with optional heading, icon, pill, body text, and action buttons.\n *\n * @default \"tooltip\"\n */\n variant?: TooltipContentVariant;\n /** Whether to show the directional arrow pointer. @default true */\n showArrow?: boolean;\n /**\n * Heading text rendered in subtitle style at the top of the infobox.\n * Infobox variant only.\n */\n heading?: React.ReactNode;\n /**\n * Icon element displayed to the left of the heading.\n * Infobox variant only.\n */\n icon?: React.ReactNode;\n /**\n * Pill or badge element displayed to the right of the heading.\n * Infobox variant only.\n */\n pill?: React.ReactNode;\n /**\n * Primary action button (brand green). Rendered below the body text.\n * Infobox variant only.\n */\n primaryAction?: TooltipAction;\n /**\n * Secondary action button (ghost). Rendered next to the primary action.\n * Infobox variant only.\n */\n secondaryAction?: TooltipAction;\n}\n\nconst ActionButton = ({\n action,\n variant,\n}: {\n action: TooltipAction;\n variant: \"brand\" | \"tertiary\";\n}) =>\n action.element ? (\n action.element\n ) : (\n <Button variant={variant} size=\"32\" onClick={action.onClick}>\n {action.label}\n </Button>\n );\n\nconst InfoboxContent = ({\n icon,\n heading,\n pill,\n children,\n primaryAction,\n secondaryAction,\n hasHeader,\n hasActions,\n}: {\n icon?: React.ReactNode;\n heading?: React.ReactNode;\n pill?: React.ReactNode;\n children?: React.ReactNode;\n primaryAction?: TooltipAction;\n secondaryAction?: TooltipAction;\n hasHeader: boolean;\n hasActions: boolean;\n}) => (\n <div className=\"flex flex-col gap-3\">\n {hasHeader && (\n <div className=\"flex items-center gap-3\">\n {icon && <div className=\"size-5 shrink-0\">{icon}</div>}\n {heading && (\n <p className=\"typography-semibold-body-lg min-w-0 flex-1 text-foreground-inverse\">\n {heading}\n </p>\n )}\n {pill && <div className=\"shrink-0\">{pill}</div>}\n </div>\n )}\n {children && (\n <div className=\"typography-regular-body-md text-foreground-inverse\">{children}</div>\n )}\n {hasActions && (\n <div className=\"flex items-center gap-1\">\n {primaryAction && <ActionButton action={primaryAction} variant=\"brand\" />}\n {secondaryAction && <ActionButton action={secondaryAction} variant=\"tertiary\" />}\n </div>\n )}\n </div>\n);\n\n/**\n * The popup content of the tooltip. Renders inside a portal.\n *\n * Arrow direction is controlled via the `side` and `align` props (Radix passthrough).\n *\n * @example\n * ```tsx\n * // Simple tooltip\n * <TooltipContent>Info text</TooltipContent>\n *\n * // Infobox with structured content\n * <TooltipContent\n * variant=\"infobox\"\n * heading=\"Title\"\n * icon={<InfoCircleIcon className=\"size-5\" />}\n * primaryAction={{ label: \"OK\", onClick: () => {} }}\n * secondaryAction={{ label: \"Dismiss\" }}\n * >\n * Info text\n * </TooltipContent>\n * ```\n */\nexport const TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n TooltipContentProps\n>(\n (\n {\n className,\n variant = \"tooltip\",\n showArrow = true,\n sideOffset = 8,\n heading,\n icon,\n pill,\n primaryAction,\n secondaryAction,\n children,\n side,\n style,\n ...props\n },\n ref,\n ) => {\n const isInfobox = variant === \"infobox\";\n const hasHeader =\n isInfobox && (icon !== undefined || heading !== undefined || pill !== undefined);\n const hasActions = isInfobox && (primaryAction !== undefined || secondaryAction !== undefined);\n\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n collisionPadding={8}\n style={{ zIndex: \"var(--fanvue-ui-portal-z-index, 50)\", ...style }}\n className={cn(\n \"typography-regular-body-md max-h-[var(--radix-tooltip-content-available-height)] max-w-[320px] overflow-hidden rounded-3xl bg-surface-pageinverse p-4 text-foreground-inverse shadow-[0px_2px_4px_0px_rgba(17,24,39,0.08)]\",\n isInfobox && \"border border-neutral-200\",\n className,\n )}\n align=\"center\"\n arrowPadding={12}\n side={side}\n {...props}\n >\n {isInfobox ? (\n <InfoboxContent\n icon={icon}\n heading={heading}\n pill={pill}\n primaryAction={primaryAction}\n secondaryAction={secondaryAction}\n hasHeader={hasHeader}\n hasActions={hasActions}\n >\n {children}\n </InfoboxContent>\n ) : (\n children\n )}\n {showArrow && (\n <TooltipPrimitive.Arrow\n className={\n \"-translate-y-px! fill-surface-pageinverse stroke-2 stroke-surface-pageinverse\"\n }\n width={12}\n height={6}\n />\n )}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n },\n);\nTooltipContent.displayName = \"TooltipContent\";\n"],"names":[],"mappings":";;;;;;AASO,MAAM,kBAAkB,iBAAiB;AAgBzC,MAAM,UAAU,iBAAiB;AAMjC,MAAM,iBAAiB,iBAAiB;AA+D/C,MAAM,eAAe,CAAC;AAAA,EACpB;AAAA,EACA;AACF,MAIE,OAAO,UACL,OAAO,UAEP,oBAAC,QAAA,EAAO,SAAkB,MAAK,MAAK,SAAS,OAAO,SACjD,iBAAO,OACV;AAGJ,MAAM,iBAAiB,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAUE,qBAAC,OAAA,EAAI,WAAU,uBACZ,UAAA;AAAA,EAAA,aACC,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,QAAQ,oBAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,MAAK;AAAA,IAC/C,WACC,oBAAC,KAAA,EAAE,WAAU,sEACV,UAAA,SACH;AAAA,IAED,QAAQ,oBAAC,OAAA,EAAI,WAAU,YAAY,UAAA,KAAA,CAAK;AAAA,EAAA,GAC3C;AAAA,EAED,YACC,oBAAC,OAAA,EAAI,WAAU,sDAAsD,UAAS;AAAA,EAE/E,cACC,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,iBAAiB,oBAAC,cAAA,EAAa,QAAQ,eAAe,SAAQ,SAAQ;AAAA,IACtE,mBAAmB,oBAAC,cAAA,EAAa,QAAQ,iBAAiB,SAAQ,WAAA,CAAW;AAAA,EAAA,EAAA,CAChF;AAAA,GAEJ;AAyBK,MAAM,iBAAiB,MAAM;AAAA,EAIlC,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,YAAY,YAAY;AAC9B,UAAM,YACJ,cAAc,SAAS,UAAa,YAAY,UAAa,SAAS;AACxE,UAAM,aAAa,cAAc,kBAAkB,UAAa,oBAAoB;AAEpF,WACE,oBAAC,iBAAiB,QAAjB,EACC,UAAA;AAAA,MAAC,iBAAiB;AAAA,MAAjB;AAAA,QACC;AAAA,QACA;AAAA,QACA,kBAAkB;AAAA,QAClB,OAAO,EAAE,QAAQ,uCAAuC,GAAG,MAAA;AAAA,QAC3D,WAAW;AAAA,UACT;AAAA,UACA,aAAa;AAAA,UACb;AAAA,QAAA;AAAA,QAEF,OAAM;AAAA,QACN,cAAc;AAAA,QACd;AAAA,QACC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,YACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cAEC;AAAA,YAAA;AAAA,UAAA,IAGH;AAAA,UAED,aACC;AAAA,YAAC,iBAAiB;AAAA,YAAjB;AAAA,cACC,WACE;AAAA,cAEF,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,QACV;AAAA,MAAA;AAAA,IAAA,GAGN;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Tooltip.mjs","sources":["../../../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\n\n/** Props for the {@link TooltipProvider}. Wraps Radix `Tooltip.Provider`. */\nexport type TooltipProviderProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider>;\n\n/** Provides tooltip delay and skip-delay context. Wrap your app or a subtree. */\nexport const TooltipProvider = TooltipPrimitive.Provider;\n\n/** Props for the {@link Tooltip} root component. */\nexport interface TooltipProps extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root> {\n /**\n * Controlled open state. When provided, the component is in controlled mode\n * and you must also supply `onOpenChange` to update the value.\n */\n open?: boolean;\n /** Called when the open state changes. Required when `open` is controlled. */\n onOpenChange?: (open: boolean) => void;\n /** The open state of the tooltip when it is initially rendered (uncontrolled). */\n defaultOpen?: boolean;\n}\n\n/** Root component that manages open/close state for a single tooltip. */\nexport const Tooltip = TooltipPrimitive.Root;\n\n/** Props for the {@link TooltipTrigger} component. */\nexport type TooltipTriggerProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>;\n\n/** The element that triggers the tooltip on hover/focus. */\nexport const TooltipTrigger = TooltipPrimitive.Trigger;\n\n/**\n * Visual style variant of the tooltip content.\n *\n * - `\"tooltip\"` — simple text bubble, no border.\n * - `\"infobox\"` — richer card with a visible border, structured header, body text, and optional actions.\n */\nexport type TooltipContentVariant = \"tooltip\" | \"infobox\";\n\n/** Action button configuration for the infobox variant of {@link TooltipContent}. */\nexport interface TooltipAction {\n /** Button label. */\n label: string;\n /** Click handler. */\n onClick?: () => void;\n /**\n * Optional custom React node to be rendered for the action instead of the default button.\n * Only used in the infobox variant.\n */\n element?: React.ReactNode;\n}\n\nexport interface TooltipContentProps\n extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> {\n /**\n * Visual style variant.\n *\n * `\"tooltip\"` is a lightweight text bubble. `\"infobox\"` renders a structured card\n * with optional heading, icon, pill, body text, and action buttons.\n *\n * @default \"tooltip\"\n */\n variant?: TooltipContentVariant;\n /** Whether to show the directional arrow pointer. @default true */\n showArrow?: boolean;\n /**\n * Heading text rendered in subtitle style at the top of the infobox.\n * Infobox variant only.\n */\n heading?: React.ReactNode;\n /**\n * Icon element displayed to the left of the heading.\n * Infobox variant only.\n */\n icon?: React.ReactNode;\n /**\n * Pill or badge element displayed to the right of the heading.\n * Infobox variant only.\n */\n pill?: React.ReactNode;\n /**\n * Primary action button (brand green). Rendered below the body text.\n * Infobox variant only.\n */\n primaryAction?: TooltipAction;\n /**\n * Secondary action button (ghost). Rendered next to the primary action.\n * Infobox variant only.\n */\n secondaryAction?: TooltipAction;\n}\n\n/** Class overrides so CTA buttons render correctly on the tooltip's inverted background. */\nconst TOOLTIP_ACTION_CLASSES: Record<\"brand\" | \"tertiary\", string> = {\n brand: \"hover:bg-brand-accent-default/80 hover:text-foreground-onaccent\",\n tertiary: \"text-foreground-inverse hover:text-foreground-inverse hover:bg-foreground-inverse/10\",\n};\n\nconst ActionButton = ({\n action,\n variant,\n}: {\n action: TooltipAction;\n variant: \"brand\" | \"tertiary\";\n}) =>\n action.element ? (\n action.element\n ) : (\n <Button variant={variant} onClick={action.onClick} className={TOOLTIP_ACTION_CLASSES[variant]}>\n {action.label}\n </Button>\n );\n\nconst InfoboxContent = ({\n icon,\n heading,\n pill,\n children,\n primaryAction,\n secondaryAction,\n hasHeader,\n hasActions,\n}: {\n icon?: React.ReactNode;\n heading?: React.ReactNode;\n pill?: React.ReactNode;\n children?: React.ReactNode;\n primaryAction?: TooltipAction;\n secondaryAction?: TooltipAction;\n hasHeader: boolean;\n hasActions: boolean;\n}) => (\n <div className=\"flex flex-col gap-3\">\n {hasHeader && (\n <div className=\"flex items-center gap-3\">\n {icon && <div className=\"size-5 shrink-0\">{icon}</div>}\n {heading && (\n <p className=\"typography-semibold-body-lg min-w-0 flex-1 text-foreground-inverse\">\n {heading}\n </p>\n )}\n {pill && <div className=\"shrink-0\">{pill}</div>}\n </div>\n )}\n {children && (\n <div className=\"typography-regular-body-md text-foreground-inverse\">{children}</div>\n )}\n {hasActions && (\n <div className=\"flex items-center gap-1\">\n {primaryAction && <ActionButton action={primaryAction} variant=\"brand\" />}\n {secondaryAction && <ActionButton action={secondaryAction} variant=\"tertiary\" />}\n </div>\n )}\n </div>\n);\n\n/**\n * The popup content of the tooltip. Renders inside a portal.\n *\n * Arrow direction is controlled via the `side` and `align` props (Radix passthrough).\n *\n * @example\n * ```tsx\n * // Simple tooltip\n * <TooltipContent>Info text</TooltipContent>\n *\n * // Infobox with structured content\n * <TooltipContent\n * variant=\"infobox\"\n * heading=\"Title\"\n * icon={<InfoCircleIcon className=\"size-5\" />}\n * primaryAction={{ label: \"OK\", onClick: () => {} }}\n * secondaryAction={{ label: \"Dismiss\" }}\n * >\n * Info text\n * </TooltipContent>\n * ```\n */\nexport const TooltipContent = React.forwardRef<\n React.ComponentRef<typeof TooltipPrimitive.Content>,\n TooltipContentProps\n>(\n (\n {\n className,\n variant = \"tooltip\",\n showArrow = true,\n sideOffset = 8,\n heading,\n icon,\n pill,\n primaryAction,\n secondaryAction,\n children,\n side,\n style,\n ...props\n },\n ref,\n ) => {\n const isInfobox = variant === \"infobox\";\n const hasHeader =\n isInfobox && (icon !== undefined || heading !== undefined || pill !== undefined);\n const hasActions = isInfobox && (primaryAction !== undefined || secondaryAction !== undefined);\n\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n collisionPadding={8}\n style={{ zIndex: \"var(--fanvue-ui-portal-z-index, 50)\", ...style }}\n className={cn(\n \"typography-regular-body-md max-h-[var(--radix-tooltip-content-available-height)] max-w-[320px] overflow-hidden rounded-3xl bg-surface-pageinverse p-4 text-foreground-inverse shadow-[0px_2px_4px_0px_rgba(17,24,39,0.08)]\",\n isInfobox && \"border border-neutral-200\",\n className,\n )}\n align=\"center\"\n arrowPadding={12}\n side={side}\n {...props}\n >\n {isInfobox ? (\n <InfoboxContent\n icon={icon}\n heading={heading}\n pill={pill}\n primaryAction={primaryAction}\n secondaryAction={secondaryAction}\n hasHeader={hasHeader}\n hasActions={hasActions}\n >\n {children}\n </InfoboxContent>\n ) : (\n children\n )}\n {showArrow && (\n <TooltipPrimitive.Arrow\n className={\n \"-translate-y-px! fill-surface-pageinverse stroke-2 stroke-surface-pageinverse\"\n }\n width={12}\n height={6}\n />\n )}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n },\n);\nTooltipContent.displayName = \"TooltipContent\";\n"],"names":[],"mappings":";;;;;;AASO,MAAM,kBAAkB,iBAAiB;AAgBzC,MAAM,UAAU,iBAAiB;AAMjC,MAAM,iBAAiB,iBAAiB;AAgE/C,MAAM,yBAA+D;AAAA,EACnE,OAAO;AAAA,EACP,UAAU;AACZ;AAEA,MAAM,eAAe,CAAC;AAAA,EACpB;AAAA,EACA;AACF,MAIE,OAAO,UACL,OAAO,8BAEN,QAAA,EAAO,SAAkB,SAAS,OAAO,SAAS,WAAW,uBAAuB,OAAO,GACzF,iBAAO,OACV;AAGJ,MAAM,iBAAiB,CAAC;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAUE,qBAAC,OAAA,EAAI,WAAU,uBACZ,UAAA;AAAA,EAAA,aACC,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,QAAQ,oBAAC,OAAA,EAAI,WAAU,mBAAmB,UAAA,MAAK;AAAA,IAC/C,WACC,oBAAC,KAAA,EAAE,WAAU,sEACV,UAAA,SACH;AAAA,IAED,QAAQ,oBAAC,OAAA,EAAI,WAAU,YAAY,UAAA,KAAA,CAAK;AAAA,EAAA,GAC3C;AAAA,EAED,YACC,oBAAC,OAAA,EAAI,WAAU,sDAAsD,UAAS;AAAA,EAE/E,cACC,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,IAAA,iBAAiB,oBAAC,cAAA,EAAa,QAAQ,eAAe,SAAQ,SAAQ;AAAA,IACtE,mBAAmB,oBAAC,cAAA,EAAa,QAAQ,iBAAiB,SAAQ,WAAA,CAAW;AAAA,EAAA,EAAA,CAChF;AAAA,GAEJ;AAyBK,MAAM,iBAAiB,MAAM;AAAA,EAIlC,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,YAAY,YAAY;AAC9B,UAAM,YACJ,cAAc,SAAS,UAAa,YAAY,UAAa,SAAS;AACxE,UAAM,aAAa,cAAc,kBAAkB,UAAa,oBAAoB;AAEpF,WACE,oBAAC,iBAAiB,QAAjB,EACC,UAAA;AAAA,MAAC,iBAAiB;AAAA,MAAjB;AAAA,QACC;AAAA,QACA;AAAA,QACA,kBAAkB;AAAA,QAClB,OAAO,EAAE,QAAQ,uCAAuC,GAAG,MAAA;AAAA,QAC3D,WAAW;AAAA,UACT;AAAA,UACA,aAAa;AAAA,UACb;AAAA,QAAA;AAAA,QAEF,OAAM;AAAA,QACN,cAAc;AAAA,QACd;AAAA,QACC,GAAG;AAAA,QAEH,UAAA;AAAA,UAAA,YACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cAEC;AAAA,YAAA;AAAA,UAAA,IAGH;AAAA,UAED,aACC;AAAA,YAAC,iBAAiB;AAAA,YAAjB;AAAA,cACC,WACE;AAAA,cAEF,OAAO;AAAA,cACP,QAAQ;AAAA,YAAA;AAAA,UAAA;AAAA,QACV;AAAA,MAAA;AAAA,IAAA,GAGN;AAAA,EAEJ;AACF;AACA,eAAe,cAAc;"}
|
package/dist/styles/theme.css
CHANGED