@intlayer/design-system 9.4.4 → 9.5.0

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.
Files changed (80) hide show
  1. package/README.md +0 -2
  2. package/dist/esm/api/index.mjs +2 -2
  3. package/dist/esm/api/useAuth/useOAuth2.mjs +1 -1
  4. package/dist/esm/api/useAuth/useSession.mjs +2 -2
  5. package/dist/esm/api/useUser/index.mjs +1 -1
  6. package/dist/esm/components/Badge/index.mjs +2 -4
  7. package/dist/esm/components/Badge/index.mjs.map +1 -1
  8. package/dist/esm/components/Breadcrumb/index.mjs +0 -4
  9. package/dist/esm/components/Breadcrumb/index.mjs.map +1 -1
  10. package/dist/esm/components/Button/Button.mjs +2 -7
  11. package/dist/esm/components/Button/Button.mjs.map +1 -1
  12. package/dist/esm/components/Container/index.mjs +0 -2
  13. package/dist/esm/components/Container/index.mjs.map +1 -1
  14. package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs +1 -1
  15. package/dist/esm/components/CopyButton/index.mjs +1 -1
  16. package/dist/esm/components/CopyButton/index.mjs.map +1 -1
  17. package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +2 -2
  18. package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs +1 -1
  19. package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs +6 -6
  20. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +1 -1
  21. package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +1 -1
  22. package/dist/esm/components/DictionaryFieldEditor/NodeEditor.mjs +2 -2
  23. package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +2 -2
  24. package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs +1 -1
  25. package/dist/esm/components/Input/Checkbox.mjs +0 -2
  26. package/dist/esm/components/Input/Checkbox.mjs.map +1 -1
  27. package/dist/esm/components/Input/Radio.mjs +0 -2
  28. package/dist/esm/components/Input/Radio.mjs.map +1 -1
  29. package/dist/esm/components/Link/Link.mjs +4 -28
  30. package/dist/esm/components/Link/Link.mjs.map +1 -1
  31. package/dist/esm/components/Navbar/DesktopNavbar.mjs +1 -1
  32. package/dist/esm/components/Navbar/DesktopNavbar.mjs.map +1 -1
  33. package/dist/esm/components/Pagination/Pagination.mjs +0 -2
  34. package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
  35. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs +1 -5
  36. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs.map +1 -1
  37. package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs +2 -6
  38. package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs.map +1 -1
  39. package/dist/esm/components/TabSelector/TabSelector.mjs +2 -6
  40. package/dist/esm/components/TabSelector/TabSelector.mjs.map +1 -1
  41. package/dist/esm/components/Table/Table.mjs +1 -1
  42. package/dist/esm/components/Table/Table.mjs.map +1 -1
  43. package/dist/esm/components/Tag/index.mjs +0 -1
  44. package/dist/esm/components/Tag/index.mjs.map +1 -1
  45. package/dist/esm/hooks/index.mjs +2 -1
  46. package/dist/esm/hooks/useListKeyboardNavigation.mjs +73 -0
  47. package/dist/esm/hooks/useListKeyboardNavigation.mjs.map +1 -0
  48. package/dist/esm/routes.mjs +123 -122
  49. package/dist/esm/routes.mjs.map +1 -1
  50. package/dist/types/components/Badge/index.d.ts +2 -2
  51. package/dist/types/components/Badge/index.d.ts.map +1 -1
  52. package/dist/types/components/Breadcrumb/index.d.ts.map +1 -1
  53. package/dist/types/components/Button/Button.d.ts +2 -2
  54. package/dist/types/components/Button/Button.d.ts.map +1 -1
  55. package/dist/types/components/Container/index.d.ts +2 -2
  56. package/dist/types/components/Container/index.d.ts.map +1 -1
  57. package/dist/types/components/CopyButton/index.d.ts +1 -1
  58. package/dist/types/components/Input/Checkbox.d.ts +2 -2
  59. package/dist/types/components/Input/Checkbox.d.ts.map +1 -1
  60. package/dist/types/components/Input/Radio.d.ts +2 -2
  61. package/dist/types/components/Input/Radio.d.ts.map +1 -1
  62. package/dist/types/components/Link/Link.d.ts +2 -2
  63. package/dist/types/components/Link/Link.d.ts.map +1 -1
  64. package/dist/types/components/Pagination/Pagination.d.ts +1 -1
  65. package/dist/types/components/Pagination/Pagination.d.ts.map +1 -1
  66. package/dist/types/components/SwitchSelector/SwitchSelector.d.ts +3 -3
  67. package/dist/types/components/SwitchSelector/SwitchSelector.d.ts.map +1 -1
  68. package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts +1 -1
  69. package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts.map +1 -1
  70. package/dist/types/components/TabSelector/TabSelector.d.ts +2 -2
  71. package/dist/types/components/TabSelector/TabSelector.d.ts.map +1 -1
  72. package/dist/types/components/Tag/index.d.ts +2 -2
  73. package/dist/types/components/Tag/index.d.ts.map +1 -1
  74. package/dist/types/hooks/index.d.ts +2 -1
  75. package/dist/types/hooks/useListKeyboardNavigation.d.ts +31 -0
  76. package/dist/types/hooks/useListKeyboardNavigation.d.ts.map +1 -0
  77. package/dist/types/routes.d.ts +5 -4
  78. package/dist/types/routes.d.ts.map +1 -1
  79. package/package.json +41 -41
  80. package/styles/globals.css +11 -3
@@ -6,8 +6,8 @@ import { EditableFieldInput } from "../../EditableField/EditableFieldInput.mjs";
6
6
  import { NodeTypeSelector } from "../NodeTypeSelector.mjs";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
8
  import { Plus, Trash } from "lucide-react";
9
- import { useConfiguration, useEditedContentActions, useFocusUnmergedDictionary } from "@intlayer/editor-react";
10
9
  import { useIntlayer } from "react-intlayer";
10
+ import { useConfiguration, useEditedContentActions, useFocusUnmergedDictionary } from "@intlayer/editor-react";
11
11
  import { getDefaultNode, getNodeChildren, getNodeType } from "@intlayer/core/dictionaryManipulator";
12
12
  import * as NodeTypes from "@intlayer/types/nodeType";
13
13
  import { isSameKeyPath } from "@intlayer/core/utils";
@@ -27,8 +27,6 @@ const checkboxVariants = cva([
27
27
  lg: "size-6 rounded-xl"
28
28
  },
29
29
  color: {
30
- primary: "border-primary/30 text-primary ring-primary/20 checked:border-primary checked:bg-primary",
31
- secondary: "border-secondary/30 text-secondary ring-secondary/20 checked:border-secondary checked:bg-secondary",
32
30
  neutral: "border-neutral/30 text-muted-foreground ring-neutral/20 checked:border-neutral checked:bg-neutral",
33
31
  light: "border-white/30 text-white ring-white/20 checked:border-white checked:bg-white",
34
32
  text: "border-text/30 text-foreground ring-text/20 checked:border-text checked:bg-text",
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.mjs","names":[],"sources":["../../../../src/components/Input/Checkbox.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n InputHTMLAttributes,\n ReactNode,\n} from 'react';\n\nexport const checkboxVariants = cva(\n [\n 'appearance-none',\n 'relative cursor-pointer border-2',\n 'focus:outline-0',\n 'checked:hover:opacity-80',\n 'ring-offset-background',\n 'hover:bg-neutral-500/10',\n 'disabled:opacity-50',\n\n // Ring + animation\n 'ring-0 transition-all duration-300 ease-in-out hover:ring-4 focus-visible:ring-6',\n\n // centered custom checkmark with text-opposite color\n \"checked:before:absolute checked:before:inset-0 checked:before:content-['✓']\",\n 'checked:before:flex checked:before:items-center checked:before:justify-center',\n 'checked:before:text-foreground-opposite/80',\n\n // Corner shape\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n\n \"after:absolute after:-inset-2 after:content-['']\",\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n },\n size: {\n xs: 'size-3 rounded-sm',\n sm: 'size-4 rounded-md',\n md: 'size-5 rounded-lg',\n lg: 'size-6 rounded-xl',\n },\n color: {\n primary:\n 'border-primary/30 text-primary ring-primary/20 checked:border-primary checked:bg-primary',\n secondary:\n 'border-secondary/30 text-secondary ring-secondary/20 checked:border-secondary checked:bg-secondary',\n neutral:\n 'border-neutral/30 text-muted-foreground ring-neutral/20 checked:border-neutral checked:bg-neutral',\n light:\n 'border-white/30 text-white ring-white/20 checked:border-white checked:bg-white',\n text: 'border-text/30 text-foreground ring-text/20 checked:border-text checked:bg-text',\n 'text-inverse':\n 'border-text-inverse/30 text-foreground-inverse ring-text-inverse/20 checked:border-text-inverse checked:bg-text-inverse',\n dark: 'border-neutral-800/30 text-neutral-800 ring-neutral-800/20 checked:border-neutral-800 checked:bg-neutral-800',\n error:\n 'border-error/30 text-error ring-error/20 checked:border-error checked:bg-error',\n success:\n 'border-success/30 text-success ring-success/20 checked:border-success checked:bg-success',\n custom:\n 'border-custom/30 text-custom ring-custom/20 checked:border-custom checked:bg-custom',\n },\n validationStyleEnabled: {\n disabled: '',\n enabled: 'valid:border-success invalid:border-error',\n },\n },\n defaultVariants: {\n variant: 'default',\n color: 'text',\n validationStyleEnabled: 'disabled',\n size: 'md',\n },\n }\n);\n\nexport type CheckboxSize = 'xs' | 'sm' | 'md' | 'lg';\n\nexport type CheckboxColor =\n | 'primary'\n | 'secondary'\n | 'neutral'\n | 'light'\n | 'text'\n | 'text-inverse'\n | 'dark'\n | 'error'\n | 'success'\n | 'custom';\n\nexport type CheckboxProps = Omit<\n DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,\n 'size'\n> & {\n name: string;\n validationStyleEnabled?: boolean;\n label?: ReactNode;\n} & Omit<\n VariantProps<typeof checkboxVariants>,\n 'validationStyleEnabled' | 'size' | 'color'\n > & {\n size?: CheckboxSize | `${CheckboxSize}`;\n color?: CheckboxColor | `${CheckboxColor}`;\n labelClassName?: string;\n };\n\nconst Input: FC<CheckboxProps> = ({\n validationStyleEnabled = false,\n label,\n size,\n color,\n name,\n variant,\n className,\n labelClassName,\n ...props\n}) => (\n <input\n type=\"checkbox\"\n className={cn(\n checkboxVariants({\n variant,\n size,\n color,\n validationStyleEnabled: validationStyleEnabled ? 'enabled' : 'disabled',\n }),\n className\n )}\n {...props}\n />\n);\n\nexport const Checkbox: FC<CheckboxProps> = (props) => {\n const { label, name, id } = props;\n\n return label ? (\n <label\n htmlFor={id ?? name}\n className={cn(\n 'flex w-full cursor-pointer items-center gap-x-4 font-medium text-sm',\n props.size === 'xs' && 'text-xs',\n props.labelClassName\n )}\n >\n <Input id={id ?? name} {...props} />\n {label}\n </label>\n ) : (\n <Input id={id ?? name} {...props} />\n );\n};\n"],"mappings":";;;;;AASA,MAAa,mBAAmB,IAC9B;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CAGA;CACA;CACA;CAGA;CAEA;AACF,CAAC,CAAC,KAAK,GAAG,GACV;CACE,UAAU;EACR,SAAS,EACP,SAAS,GACX;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,OAAO;GACL,SACE;GACF,WACE;GACF,SACE;GACF,OACE;GACF,MAAM;GACN,gBACE;GACF,MAAM;GACN,OACE;GACF,SACE;GACF,QACE;EACJ;EACA,wBAAwB;GACtB,UAAU;GACV,SAAS;EACX;CACF;CACA,iBAAiB;EACf,SAAS;EACT,OAAO;EACP,wBAAwB;EACxB,MAAM;CACR;AACF,CACF;AAgCA,MAAM,SAA4B,EAChC,yBAAyB,OACzB,OACA,MACA,OACA,MACA,SACA,WACA,gBACA,GAAG,YAEH,oBAAC,SAAD;CACE,MAAK;CACL,WAAW,GACT,iBAAiB;EACf;EACA;EACA;EACA,wBAAwB,yBAAyB,YAAY;CAC/D,CAAC,GACD,SACF;CACA,GAAI;AACL;AAGH,MAAa,YAA+B,UAAU;CACpD,MAAM,EAAE,OAAO,MAAM,OAAO;CAE5B,OAAO,QACL,qBAAC,SAAD;EACE,SAAS,MAAM;EACf,WAAW,GACT,uEACA,MAAM,SAAS,QAAQ,WACvB,MAAM,cACR;YANF,CAQE,oBAAC,OAAD;GAAO,IAAI,MAAM;GAAM,GAAI;EAAQ,IAClC,KACI;MAEP,oBAAC,OAAD;EAAO,IAAI,MAAM;EAAM,GAAI;CAAQ;AAEvC"}
1
+ {"version":3,"file":"Checkbox.mjs","names":[],"sources":["../../../../src/components/Input/Checkbox.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n InputHTMLAttributes,\n ReactNode,\n} from 'react';\n\nexport const checkboxVariants = cva(\n [\n 'appearance-none',\n 'relative cursor-pointer border-2',\n 'focus:outline-0',\n 'checked:hover:opacity-80',\n 'ring-offset-background',\n 'hover:bg-neutral-500/10',\n 'disabled:opacity-50',\n\n // Ring + animation\n 'ring-0 transition-all duration-300 ease-in-out hover:ring-4 focus-visible:ring-6',\n\n // centered custom checkmark with text-opposite color\n \"checked:before:absolute checked:before:inset-0 checked:before:content-['✓']\",\n 'checked:before:flex checked:before:items-center checked:before:justify-center',\n 'checked:before:text-foreground-opposite/80',\n\n // Corner shape\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n\n \"after:absolute after:-inset-2 after:content-['']\",\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n },\n size: {\n xs: 'size-3 rounded-sm',\n sm: 'size-4 rounded-md',\n md: 'size-5 rounded-lg',\n lg: 'size-6 rounded-xl',\n },\n color: {\n neutral:\n 'border-neutral/30 text-muted-foreground ring-neutral/20 checked:border-neutral checked:bg-neutral',\n light:\n 'border-white/30 text-white ring-white/20 checked:border-white checked:bg-white',\n text: 'border-text/30 text-foreground ring-text/20 checked:border-text checked:bg-text',\n 'text-inverse':\n 'border-text-inverse/30 text-foreground-inverse ring-text-inverse/20 checked:border-text-inverse checked:bg-text-inverse',\n dark: 'border-neutral-800/30 text-neutral-800 ring-neutral-800/20 checked:border-neutral-800 checked:bg-neutral-800',\n error:\n 'border-error/30 text-error ring-error/20 checked:border-error checked:bg-error',\n success:\n 'border-success/30 text-success ring-success/20 checked:border-success checked:bg-success',\n custom:\n 'border-custom/30 text-custom ring-custom/20 checked:border-custom checked:bg-custom',\n },\n validationStyleEnabled: {\n disabled: '',\n enabled: 'valid:border-success invalid:border-error',\n },\n },\n defaultVariants: {\n variant: 'default',\n color: 'text',\n validationStyleEnabled: 'disabled',\n size: 'md',\n },\n }\n);\n\nexport type CheckboxSize = 'xs' | 'sm' | 'md' | 'lg';\n\nexport type CheckboxColor =\n | 'neutral'\n | 'light'\n | 'text'\n | 'text-inverse'\n | 'dark'\n | 'error'\n | 'success'\n | 'custom';\n\nexport type CheckboxProps = Omit<\n DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,\n 'size'\n> & {\n name: string;\n validationStyleEnabled?: boolean;\n label?: ReactNode;\n} & Omit<\n VariantProps<typeof checkboxVariants>,\n 'validationStyleEnabled' | 'size' | 'color'\n > & {\n size?: CheckboxSize | `${CheckboxSize}`;\n color?: CheckboxColor | `${CheckboxColor}`;\n labelClassName?: string;\n };\n\nconst Input: FC<CheckboxProps> = ({\n validationStyleEnabled = false,\n label,\n size,\n color,\n name,\n variant,\n className,\n labelClassName,\n ...props\n}) => (\n <input\n type=\"checkbox\"\n className={cn(\n checkboxVariants({\n variant,\n size,\n color,\n validationStyleEnabled: validationStyleEnabled ? 'enabled' : 'disabled',\n }),\n className\n )}\n {...props}\n />\n);\n\nexport const Checkbox: FC<CheckboxProps> = (props) => {\n const { label, name, id } = props;\n\n return label ? (\n <label\n htmlFor={id ?? name}\n className={cn(\n 'flex w-full cursor-pointer items-center gap-x-4 font-medium text-sm',\n props.size === 'xs' && 'text-xs',\n props.labelClassName\n )}\n >\n <Input id={id ?? name} {...props} />\n {label}\n </label>\n ) : (\n <Input id={id ?? name} {...props} />\n );\n};\n"],"mappings":";;;;;AASA,MAAa,mBAAmB,IAC9B;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CAGA;CACA;CACA;CAGA;CAEA;AACF,CAAC,CAAC,KAAK,GAAG,GACV;CACE,UAAU;EACR,SAAS,EACP,SAAS,GACX;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,OAAO;GACL,SACE;GACF,OACE;GACF,MAAM;GACN,gBACE;GACF,MAAM;GACN,OACE;GACF,SACE;GACF,QACE;EACJ;EACA,wBAAwB;GACtB,UAAU;GACV,SAAS;EACX;CACF;CACA,iBAAiB;EACf,SAAS;EACT,OAAO;EACP,wBAAwB;EACxB,MAAM;CACR;AACF,CACF;AA8BA,MAAM,SAA4B,EAChC,yBAAyB,OACzB,OACA,MACA,OACA,MACA,SACA,WACA,gBACA,GAAG,YAEH,oBAAC,SAAD;CACE,MAAK;CACL,WAAW,GACT,iBAAiB;EACf;EACA;EACA;EACA,wBAAwB,yBAAyB,YAAY;CAC/D,CAAC,GACD,SACF;CACA,GAAI;AACL;AAGH,MAAa,YAA+B,UAAU;CACpD,MAAM,EAAE,OAAO,MAAM,OAAO;CAE5B,OAAO,QACL,qBAAC,SAAD;EACE,SAAS,MAAM;EACf,WAAW,GACT,uEACA,MAAM,SAAS,QAAQ,WACvB,MAAM,cACR;YANF,CAQE,oBAAC,OAAD;GAAO,IAAI,MAAM;GAAM,GAAI;EAAQ,IAClC,KACI;MAEP,oBAAC,OAAD;EAAO,IAAI,MAAM;EAAM,GAAI;CAAQ;AAEvC"}
@@ -28,8 +28,6 @@ const radioVariants = cva([
28
28
  lg: "size-6"
29
29
  },
30
30
  color: {
31
- primary: "border-primary/30 ring-primary/20 checked:border-primary checked:bg-primary",
32
- secondary: "border-secondary/30 ring-secondary/20 checked:border-secondary checked:bg-secondary",
33
31
  neutral: "border-neutral/30 ring-neutral/20 checked:border-neutral checked:bg-neutral",
34
32
  light: "border-white/30 ring-white/20 checked:border-white checked:bg-white",
35
33
  text: "border-text/30 ring-text/20 checked:border-text checked:bg-text",
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.mjs","names":[],"sources":["../../../../src/components/Input/Radio.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n InputHTMLAttributes,\n ReactNode,\n} from 'react';\n\nexport const radioVariants = cva(\n [\n 'appearance-none',\n 'relative cursor-pointer rounded-full border-2',\n 'focus:outline-0',\n 'checked:hover:opacity-80',\n 'ring-offset-background',\n 'hover:bg-neutral-500/10',\n 'disabled:opacity-50',\n\n // Ring + animation\n 'ring-0 transition-all duration-300 ease-in-out hover:ring-4 focus-visible:ring-6',\n\n // Centered dot when checked\n 'checked:before:absolute checked:before:inset-0 checked:before:flex',\n 'checked:before:items-center checked:before:justify-center',\n \"checked:before:content-['']\",\n 'checked:before:m-auto checked:before:size-[45%]',\n 'checked:before:rounded-full checked:before:bg-text-opposite/80',\n\n \"after:absolute after:-inset-2 after:content-['']\",\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n },\n size: {\n xs: 'size-3',\n sm: 'size-4',\n md: 'size-5',\n lg: 'size-6',\n },\n color: {\n primary:\n 'border-primary/30 ring-primary/20 checked:border-primary checked:bg-primary',\n secondary:\n 'border-secondary/30 ring-secondary/20 checked:border-secondary checked:bg-secondary',\n neutral:\n 'border-neutral/30 ring-neutral/20 checked:border-neutral checked:bg-neutral',\n light:\n 'border-white/30 ring-white/20 checked:border-white checked:bg-white',\n text: 'border-text/30 ring-text/20 checked:border-text checked:bg-text',\n 'text-inverse':\n 'border-text-inverse/30 ring-text-inverse/20 checked:border-text-inverse checked:bg-text-inverse',\n dark: 'border-neutral-800/30 ring-neutral-800/20 checked:border-neutral-800 checked:bg-neutral-800',\n error:\n 'border-error/30 ring-error/20 checked:border-error checked:bg-error',\n success:\n 'border-success/30 ring-success/20 checked:border-success checked:bg-success',\n custom:\n 'border-custom/30 ring-custom/20 checked:border-custom checked:bg-custom',\n },\n validationStyleEnabled: {\n disabled: '',\n enabled: 'valid:border-success invalid:border-error',\n },\n },\n defaultVariants: {\n variant: 'default',\n color: 'text',\n validationStyleEnabled: 'disabled',\n size: 'md',\n },\n }\n);\n\nexport type RadioSize = 'xs' | 'sm' | 'md' | 'lg';\n\nexport type RadioColor =\n | 'primary'\n | 'secondary'\n | 'neutral'\n | 'light'\n | 'text'\n | 'text-inverse'\n | 'dark'\n | 'error'\n | 'success'\n | 'custom';\n\nexport type RadioProps = Omit<\n DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,\n 'size' | 'type'\n> & {\n name: string;\n validationStyleEnabled?: boolean;\n label?: ReactNode;\n} & Omit<\n VariantProps<typeof radioVariants>,\n 'validationStyleEnabled' | 'size' | 'color'\n > & {\n size?: RadioSize | `${RadioSize}`;\n color?: RadioColor | `${RadioColor}`;\n labelClassName?: string;\n };\n\nconst RadioInput: FC<RadioProps> = ({\n validationStyleEnabled = false,\n label,\n size,\n color,\n name,\n variant,\n className,\n labelClassName,\n ...props\n}) => (\n <input\n type=\"radio\"\n name={name}\n className={cn(\n radioVariants({\n variant,\n size,\n color,\n validationStyleEnabled: validationStyleEnabled ? 'enabled' : 'disabled',\n }),\n className\n )}\n {...props}\n />\n);\n\nexport const Radio: FC<RadioProps> = (props) => {\n const { label, name, id } = props;\n\n return label ? (\n <label\n htmlFor={id ?? name}\n className={cn(\n 'flex w-full cursor-pointer items-center gap-x-4 font-medium text-sm',\n props.size === 'xs' && 'text-xs',\n props.labelClassName\n )}\n >\n <RadioInput id={id ?? name} {...props} />\n {label}\n </label>\n ) : (\n <RadioInput id={id ?? name} {...props} />\n );\n};\n"],"mappings":";;;;;AASA,MAAa,gBAAgB,IAC3B;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CAGA;CACA;CACA;CACA;CACA;CAEA;AACF,CAAC,CAAC,KAAK,GAAG,GACV;CACE,UAAU;EACR,SAAS,EACP,SAAS,GACX;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,OAAO;GACL,SACE;GACF,WACE;GACF,SACE;GACF,OACE;GACF,MAAM;GACN,gBACE;GACF,MAAM;GACN,OACE;GACF,SACE;GACF,QACE;EACJ;EACA,wBAAwB;GACtB,UAAU;GACV,SAAS;EACX;CACF;CACA,iBAAiB;EACf,SAAS;EACT,OAAO;EACP,wBAAwB;EACxB,MAAM;CACR;AACF,CACF;AAgCA,MAAM,cAA8B,EAClC,yBAAyB,OACzB,OACA,MACA,OACA,MACA,SACA,WACA,gBACA,GAAG,YAEH,oBAAC,SAAD;CACE,MAAK;CACC;CACN,WAAW,GACT,cAAc;EACZ;EACA;EACA;EACA,wBAAwB,yBAAyB,YAAY;CAC/D,CAAC,GACD,SACF;CACA,GAAI;AACL;AAGH,MAAa,SAAyB,UAAU;CAC9C,MAAM,EAAE,OAAO,MAAM,OAAO;CAE5B,OAAO,QACL,qBAAC,SAAD;EACE,SAAS,MAAM;EACf,WAAW,GACT,uEACA,MAAM,SAAS,QAAQ,WACvB,MAAM,cACR;YANF,CAQE,oBAAC,YAAD;GAAY,IAAI,MAAM;GAAM,GAAI;EAAQ,IACvC,KACI;MAEP,oBAAC,YAAD;EAAY,IAAI,MAAM;EAAM,GAAI;CAAQ;AAE5C"}
1
+ {"version":3,"file":"Radio.mjs","names":[],"sources":["../../../../src/components/Input/Radio.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n InputHTMLAttributes,\n ReactNode,\n} from 'react';\n\nexport const radioVariants = cva(\n [\n 'appearance-none',\n 'relative cursor-pointer rounded-full border-2',\n 'focus:outline-0',\n 'checked:hover:opacity-80',\n 'ring-offset-background',\n 'hover:bg-neutral-500/10',\n 'disabled:opacity-50',\n\n // Ring + animation\n 'ring-0 transition-all duration-300 ease-in-out hover:ring-4 focus-visible:ring-6',\n\n // Centered dot when checked\n 'checked:before:absolute checked:before:inset-0 checked:before:flex',\n 'checked:before:items-center checked:before:justify-center',\n \"checked:before:content-['']\",\n 'checked:before:m-auto checked:before:size-[45%]',\n 'checked:before:rounded-full checked:before:bg-text-opposite/80',\n\n \"after:absolute after:-inset-2 after:content-['']\",\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n },\n size: {\n xs: 'size-3',\n sm: 'size-4',\n md: 'size-5',\n lg: 'size-6',\n },\n color: {\n neutral:\n 'border-neutral/30 ring-neutral/20 checked:border-neutral checked:bg-neutral',\n light:\n 'border-white/30 ring-white/20 checked:border-white checked:bg-white',\n text: 'border-text/30 ring-text/20 checked:border-text checked:bg-text',\n 'text-inverse':\n 'border-text-inverse/30 ring-text-inverse/20 checked:border-text-inverse checked:bg-text-inverse',\n dark: 'border-neutral-800/30 ring-neutral-800/20 checked:border-neutral-800 checked:bg-neutral-800',\n error:\n 'border-error/30 ring-error/20 checked:border-error checked:bg-error',\n success:\n 'border-success/30 ring-success/20 checked:border-success checked:bg-success',\n custom:\n 'border-custom/30 ring-custom/20 checked:border-custom checked:bg-custom',\n },\n validationStyleEnabled: {\n disabled: '',\n enabled: 'valid:border-success invalid:border-error',\n },\n },\n defaultVariants: {\n variant: 'default',\n color: 'text',\n validationStyleEnabled: 'disabled',\n size: 'md',\n },\n }\n);\n\nexport type RadioSize = 'xs' | 'sm' | 'md' | 'lg';\n\nexport type RadioColor =\n | 'neutral'\n | 'light'\n | 'text'\n | 'text-inverse'\n | 'dark'\n | 'error'\n | 'success'\n | 'custom';\n\nexport type RadioProps = Omit<\n DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,\n 'size' | 'type'\n> & {\n name: string;\n validationStyleEnabled?: boolean;\n label?: ReactNode;\n} & Omit<\n VariantProps<typeof radioVariants>,\n 'validationStyleEnabled' | 'size' | 'color'\n > & {\n size?: RadioSize | `${RadioSize}`;\n color?: RadioColor | `${RadioColor}`;\n labelClassName?: string;\n };\n\nconst RadioInput: FC<RadioProps> = ({\n validationStyleEnabled = false,\n label,\n size,\n color,\n name,\n variant,\n className,\n labelClassName,\n ...props\n}) => (\n <input\n type=\"radio\"\n name={name}\n className={cn(\n radioVariants({\n variant,\n size,\n color,\n validationStyleEnabled: validationStyleEnabled ? 'enabled' : 'disabled',\n }),\n className\n )}\n {...props}\n />\n);\n\nexport const Radio: FC<RadioProps> = (props) => {\n const { label, name, id } = props;\n\n return label ? (\n <label\n htmlFor={id ?? name}\n className={cn(\n 'flex w-full cursor-pointer items-center gap-x-4 font-medium text-sm',\n props.size === 'xs' && 'text-xs',\n props.labelClassName\n )}\n >\n <RadioInput id={id ?? name} {...props} />\n {label}\n </label>\n ) : (\n <RadioInput id={id ?? name} {...props} />\n );\n};\n"],"mappings":";;;;;AASA,MAAa,gBAAgB,IAC3B;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CAGA;CACA;CACA;CACA;CACA;CAEA;AACF,CAAC,CAAC,KAAK,GAAG,GACV;CACE,UAAU;EACR,SAAS,EACP,SAAS,GACX;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,OAAO;GACL,SACE;GACF,OACE;GACF,MAAM;GACN,gBACE;GACF,MAAM;GACN,OACE;GACF,SACE;GACF,QACE;EACJ;EACA,wBAAwB;GACtB,UAAU;GACV,SAAS;EACX;CACF;CACA,iBAAiB;EACf,SAAS;EACT,OAAO;EACP,wBAAwB;EACxB,MAAM;CACR;AACF,CACF;AA8BA,MAAM,cAA8B,EAClC,yBAAyB,OACzB,OACA,MACA,OACA,MACA,SACA,WACA,gBACA,GAAG,YAEH,oBAAC,SAAD;CACE,MAAK;CACC;CACN,WAAW,GACT,cAAc;EACZ;EACA;EACA;EACA,wBAAwB,yBAAyB,YAAY;CAC/D,CAAC,GACD,SACF;CACA,GAAI;AACL;AAGH,MAAa,SAAyB,UAAU;CAC9C,MAAM,EAAE,OAAO,MAAM,OAAO;CAE5B,OAAO,QACL,qBAAC,SAAD;EACE,SAAS,MAAM;EACf,WAAW,GACT,uEACA,MAAM,SAAS,QAAQ,WACvB,MAAM,cACR;YANF,CAQE,oBAAC,YAAD;GAAY,IAAI,MAAM;GAAM,GAAI;EAAQ,IACvC,KACI;MAEP,oBAAC,YAAD;EAAY,IAAI,MAAM;EAAM,GAAI;CAAQ;AAE5C"}
@@ -9,11 +9,11 @@ import { getLocalizedUrl } from "@intlayer/core/localization";
9
9
  const linkVariants = cva("gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50", {
10
10
  variants: {
11
11
  variant: {
12
- default: "h-auto justify-start border-inherit bg-current/0 px-1 font-medium decoration-[1.5] underline-offset-5 hover:bg-current/0 hover:text-current/80 hover:underline hover:underline-offset-6",
12
+ default: "h-auto justify-start border-inherit bg-current/0 px-1 font-medium decoration-[1.5] underline-offset-5 hover:bg-current/0 hover:underline hover:underline-offset-6 hover:opacity-80",
13
13
  "invisible-link": "h-auto justify-start border-inherit bg-current/0 px-1",
14
14
  button: "relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current px-6 text-center font-medium text-sm text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2",
15
- "button-outlined": "relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current px-6 text-center font-medium text-sm text-text ring-0 *:text-text hover:bg-current/20 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2",
16
- hoverable: "rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5"
15
+ "button-outlined": "relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current! px-6 text-center font-medium text-sm text-text ring-0 *:text-text hover:bg-current/30! hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2",
16
+ hoverable: "block rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5"
17
17
  },
18
18
  roundedSize: {
19
19
  none: "rounded-none",
@@ -26,15 +26,11 @@ const linkVariants = cva("gap-3 transition-all duration-300 focus-visible:outlin
26
26
  full: "rounded-full"
27
27
  },
28
28
  color: {
29
- primary: "text-primary",
30
- secondary: "text-secondary",
31
29
  neutral: "text-neutral",
32
- light: "text-white",
33
- dark: "text-neutral-800",
34
30
  text: "text-text",
35
- "text-inverse": "text-text-opposite",
36
31
  error: "text-error",
37
32
  success: "text-success",
33
+ "text-inverse": "text-text-opposite",
38
34
  custom: ""
39
35
  },
40
36
  size: {
@@ -81,31 +77,11 @@ const linkVariants = cva("gap-3 transition-all duration-300 focus-visible:outlin
81
77
  size: "xl",
82
78
  class: "min-h-11 px-10 text-xl max-md:py-4"
83
79
  },
84
- {
85
- variant: ["button", "button-outlined"],
86
- color: "primary",
87
- class: "ring-primary/20"
88
- },
89
- {
90
- variant: ["button", "button-outlined"],
91
- color: "secondary",
92
- class: "ring-secondary/20"
93
- },
94
80
  {
95
81
  variant: ["button", "button-outlined"],
96
82
  color: "neutral",
97
83
  class: "ring-neutral/20"
98
84
  },
99
- {
100
- variant: ["button", "button-outlined"],
101
- color: "light",
102
- class: "ring-white/20"
103
- },
104
- {
105
- variant: ["button", "button-outlined"],
106
- color: "dark",
107
- class: "ring-neutral-800/20"
108
- },
109
85
  {
110
86
  variant: ["button", "button-outlined"],
111
87
  color: "text",
@@ -1 +1 @@
1
- {"version":3,"file":"Link.mjs","names":[],"sources":["../../../../src/components/Link/Link.tsx"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, MoveRight } from 'lucide-react';\nimport {\n type AnchorHTMLAttributes,\n type DetailedHTMLProps,\n type FC,\n isValidElement,\n type ReactNode,\n} from 'react';\n\nexport type LinkVariant =\n | 'default'\n | 'invisible-link'\n | 'button'\n | 'button-outlined'\n | 'hoverable';\n\n/**\n * Color theme variants for Link component\n */\nexport type LinkColor =\n | 'primary'\n | 'secondary'\n | 'neutral'\n | 'light'\n | 'dark'\n | 'text'\n | 'text-inverse'\n | 'error'\n | 'success'\n | 'custom';\n\nexport type LinkRoundedSize =\n | 'none'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | 'full';\n\nexport type LinkSize = 'sm' | 'md' | 'lg' | 'xl' | 'custom';\n\nexport type LinkUnderlined = 'default' | 'true' | 'false';\n\nexport const linkVariants = cva(\n 'gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default:\n 'h-auto justify-start border-inherit bg-current/0 px-1 font-medium decoration-[1.5] underline-offset-5 hover:bg-current/0 hover:text-current/80 hover:underline hover:underline-offset-6',\n 'invisible-link':\n 'h-auto justify-start border-inherit bg-current/0 px-1',\n\n button:\n 'relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current px-6 text-center font-medium text-sm text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2',\n\n 'button-outlined':\n 'relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current px-6 text-center font-medium text-sm text-text ring-0 *:text-text hover:bg-current/20 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2',\n\n hoverable:\n 'rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5',\n },\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n md: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n lg: 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n xl: 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '2xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n '3xl':\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n full: 'rounded-full',\n },\n color: {\n primary: 'text-primary',\n secondary: 'text-secondary',\n neutral: 'text-neutral',\n light: 'text-white',\n dark: 'text-neutral-800',\n text: 'text-text',\n 'text-inverse': 'text-text-opposite',\n error: 'text-error',\n success: 'text-success',\n custom: '',\n },\n size: {\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n xl: 'text-xl',\n custom: '',\n },\n underlined: {\n default: '',\n true: 'underline',\n false: 'no-underline',\n },\n },\n // Compound variants handle height and padding\n compoundVariants: [\n // ---------------------------------------------------------\n // FIX START: Correctly Handle Contrast for TEXT_INVERSE\n // ---------------------------------------------------------\n {\n // Filled Button + Inverse Color (e.g., White Button):\n // We DO NOT override parent text color (it must remain 'text-opposite' so bg-current is white).\n // We ONLY override children to be 'text-text' (Dark) so they show up on white.\n variant: 'button',\n color: 'text-inverse',\n class: '*:text-text',\n },\n {\n // Outlined Button + Inverse Color (e.g., White Border):\n // Parent is 'text-opposite' (Border is white).\n // Children must also be 'text-opposite' (White text) to show on dark background.\n variant: 'button-outlined',\n color: 'text-inverse',\n class: 'text-text-opposite *:text-text-opposite',\n },\n\n // Min height and padding for button variants\n {\n variant: ['button', 'button-outlined'],\n size: 'sm',\n class: 'min-h-7 px-3 text-xs max-md:py-1',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'md',\n class: 'min-h-8 px-6 text-sm max-md:py-2',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'lg',\n class: 'min-h-10 px-8 text-lg max-md:py-3',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'xl',\n class: 'min-h-11 px-10 text-xl max-md:py-4',\n },\n // Ring color variants\n {\n variant: ['button', 'button-outlined'],\n color: 'primary',\n class: 'ring-primary/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'secondary',\n class: 'ring-secondary/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'neutral',\n class: 'ring-neutral/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'light',\n class: 'ring-white/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'dark',\n class: 'ring-neutral-800/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'text',\n class: 'ring-text/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'text-inverse',\n class: 'ring-text-opposite/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'error',\n class: 'ring-error/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'success',\n class: 'ring-success/20',\n },\n ],\n\n defaultVariants: {\n variant: 'default',\n roundedSize: 'md',\n underlined: 'default',\n size: 'custom',\n },\n }\n);\n\nexport type LinkProps = DetailedHTMLProps<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n HTMLAnchorElement\n> &\n VariantProps<typeof linkVariants> & {\n label: string;\n isExternalLink?: boolean;\n isPageSection?: boolean;\n isActive?: boolean;\n locale?: LocalesValues;\n };\n\nexport const checkIsExternalLink = (\n {\n href,\n isExternalLink: isExternalLinkProp,\n }: Pick<LinkProps, 'href' | 'isExternalLink'>,\n url?: string\n): boolean => {\n // Explicit prop override takes precedence\n if (typeof isExternalLinkProp === 'boolean') {\n return isExternalLinkProp;\n }\n\n const isValidHref = typeof href === 'string' && href.trim() !== '';\n\n if (!isValidHref) return false;\n\n // Relative URLs (e.g., '/about') are always internal\n if (!/^https?:\\/\\//.test(href)) {\n return false;\n }\n\n // Compare base domains\n if (url) {\n try {\n const hrefHost = new URL(href).hostname;\n // Ensure the reference url has a protocol so URL() can parse it correctly\n const currentHost = new URL(\n url.startsWith('http') ? url : `https://${url}`\n ).hostname;\n\n // Extract the root domain (e.g., 'app.intlayer.org' -> 'intlayer.org')\n const getBaseDomain = (host: string) =>\n host.split('.').slice(-2).join('.');\n\n return getBaseDomain(hrefHost) !== getBaseDomain(currentHost);\n } catch {\n // If URL parsing fails for any reason, default to treating it as external\n return true;\n }\n }\n\n // Absolute URL with no comparison URL provided\n return true;\n};\n\nexport const isTextChildren = (children: ReactNode): boolean => {\n if (typeof children === 'string' || typeof children === 'number') {\n return true;\n }\n if (Array.isArray(children)) {\n return children.every(isTextChildren);\n }\n if (isValidElement(children)) {\n return isTextChildren(\n (children.props as { children?: ReactNode }).children\n );\n }\n return false;\n};\n\nexport const Link: FC<LinkProps> = (props) => {\n const {\n variant = 'default',\n color = 'custom',\n roundedSize,\n children,\n label,\n className,\n isActive,\n underlined,\n locale,\n size: sizeProp,\n isExternalLink: isExternalLinkProp,\n isPageSection: isPageSectionProp,\n href: hrefProp,\n rel: relProp,\n target: targetProp,\n ...otherProps\n } = props;\n\n const isButton = variant === 'button' || variant === 'button-outlined';\n const size = sizeProp ?? (isButton ? 'md' : 'custom');\n\n const isExternalLink = isExternalLinkProp ?? checkIsExternalLink(props);\n const isPageSection = isPageSectionProp ?? hrefProp?.startsWith('#') ?? false;\n\n const isChildrenString = isTextChildren(children);\n\n /**\n * External links always carry the full safety/SEO `rel`, so a caller cannot\n * accidentally strip `nofollow`. Internal links keep whatever the caller asked for.\n */\n const rel = isExternalLink ? 'noopener noreferrer nofollow' : relProp;\n\n const target = isExternalLink ? '_blank' : (targetProp ?? '_self');\n\n const resolvedHref =\n locale && hrefProp && !isExternalLink && !isPageSection\n ? getLocalizedUrl(hrefProp, locale)\n : hrefProp;\n\n const href = resolvedHref === '' ? undefined : resolvedHref;\n\n return (\n <a\n {...otherProps}\n href={href}\n aria-label={label}\n rel={rel}\n target={target}\n aria-current={isActive ? 'page' : undefined}\n suppressHydrationWarning\n className={cn(\n linkVariants({\n variant,\n color,\n roundedSize,\n underlined,\n size,\n className,\n })\n )}\n >\n {isButton && isChildrenString ? <span>{children}</span> : children}\n\n {isExternalLink && isChildrenString && (\n <ExternalLink className=\"ml-2 inline-block size-4\" />\n )}\n {isPageSection && <MoveRight className=\"ml-2 inline-block size-4\" />}\n </a>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Link.mjs","names":[],"sources":["../../../../src/components/Link/Link.tsx"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, MoveRight } from 'lucide-react';\nimport {\n type AnchorHTMLAttributes,\n type DetailedHTMLProps,\n type FC,\n isValidElement,\n type ReactNode,\n} from 'react';\n\nexport type LinkVariant =\n | 'default'\n | 'invisible-link'\n | 'button'\n | 'button-outlined'\n | 'hoverable';\n\n/**\n * Color theme variants for Link component\n */\nexport type LinkColor =\n | 'neutral'\n | 'text'\n | 'error'\n | 'success'\n | 'custom'\n | 'text-inverse';\n\nexport type LinkRoundedSize =\n | 'none'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | 'full';\n\nexport type LinkSize = 'sm' | 'md' | 'lg' | 'xl' | 'custom';\n\nexport type LinkUnderlined = 'default' | 'true' | 'false';\n\nexport const linkVariants = cva(\n 'gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default:\n 'h-auto justify-start border-inherit bg-current/0 px-1 font-medium decoration-[1.5] underline-offset-5 hover:bg-current/0 hover:underline hover:underline-offset-6 hover:opacity-80',\n 'invisible-link':\n 'h-auto justify-start border-inherit bg-current/0 px-1',\n\n button:\n 'relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current px-6 text-center font-medium text-sm text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2',\n\n 'button-outlined':\n 'relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current! px-6 text-center font-medium text-sm text-text ring-0 *:text-text hover:bg-current/30! hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2',\n\n hoverable:\n 'block rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5',\n },\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n md: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n lg: 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n xl: 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '2xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n '3xl':\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n full: 'rounded-full',\n },\n color: {\n neutral: 'text-neutral',\n text: 'text-text',\n error: 'text-error',\n success: 'text-success',\n 'text-inverse': 'text-text-opposite',\n custom: '',\n },\n size: {\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n xl: 'text-xl',\n custom: '',\n },\n underlined: {\n default: '',\n true: 'underline',\n false: 'no-underline',\n },\n },\n // Compound variants handle height and padding\n compoundVariants: [\n // ---------------------------------------------------------\n // FIX START: Correctly Handle Contrast for TEXT_INVERSE\n // ---------------------------------------------------------\n {\n // Filled Button + Inverse Color (e.g., White Button):\n // We DO NOT override parent text color (it must remain 'text-opposite' so bg-current is white).\n // We ONLY override children to be 'text-text' (Dark) so they show up on white.\n variant: 'button',\n color: 'text-inverse',\n class: '*:text-text',\n },\n {\n // Outlined Button + Inverse Color (e.g., White Border):\n // Parent is 'text-opposite' (Border is white).\n // Children must also be 'text-opposite' (White text) to show on dark background.\n variant: 'button-outlined',\n color: 'text-inverse',\n class: 'text-text-opposite *:text-text-opposite',\n },\n // Min height and padding for button variants\n {\n variant: ['button', 'button-outlined'],\n size: 'sm',\n class: 'min-h-7 px-3 text-xs max-md:py-1',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'md',\n class: 'min-h-8 px-6 text-sm max-md:py-2',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'lg',\n class: 'min-h-10 px-8 text-lg max-md:py-3',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'xl',\n class: 'min-h-11 px-10 text-xl max-md:py-4',\n },\n // Ring color variants\n\n {\n variant: ['button', 'button-outlined'],\n color: 'neutral',\n class: 'ring-neutral/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'text',\n class: 'ring-text/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'text-inverse',\n class: 'ring-text-opposite/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'error',\n class: 'ring-error/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'success',\n class: 'ring-success/20',\n },\n ],\n\n defaultVariants: {\n variant: 'default',\n roundedSize: 'md',\n underlined: 'default',\n size: 'custom',\n },\n }\n);\n\nexport type LinkProps = DetailedHTMLProps<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n HTMLAnchorElement\n> &\n VariantProps<typeof linkVariants> & {\n label: string;\n isExternalLink?: boolean;\n isPageSection?: boolean;\n isActive?: boolean;\n locale?: LocalesValues;\n };\n\nexport const checkIsExternalLink = (\n {\n href,\n isExternalLink: isExternalLinkProp,\n }: Pick<LinkProps, 'href' | 'isExternalLink'>,\n url?: string\n): boolean => {\n // Explicit prop override takes precedence\n if (typeof isExternalLinkProp === 'boolean') {\n return isExternalLinkProp;\n }\n\n const isValidHref = typeof href === 'string' && href.trim() !== '';\n\n if (!isValidHref) return false;\n\n // Relative URLs (e.g., '/about') are always internal\n if (!/^https?:\\/\\//.test(href)) {\n return false;\n }\n\n // Compare base domains\n if (url) {\n try {\n const hrefHost = new URL(href).hostname;\n // Ensure the reference url has a protocol so URL() can parse it correctly\n const currentHost = new URL(\n url.startsWith('http') ? url : `https://${url}`\n ).hostname;\n\n // Extract the root domain (e.g., 'app.intlayer.org' -> 'intlayer.org')\n const getBaseDomain = (host: string) =>\n host.split('.').slice(-2).join('.');\n\n return getBaseDomain(hrefHost) !== getBaseDomain(currentHost);\n } catch {\n // If URL parsing fails for any reason, default to treating it as external\n return true;\n }\n }\n\n // Absolute URL with no comparison URL provided\n return true;\n};\n\nexport const isTextChildren = (children: ReactNode): boolean => {\n if (typeof children === 'string' || typeof children === 'number') {\n return true;\n }\n if (Array.isArray(children)) {\n return children.every(isTextChildren);\n }\n if (isValidElement(children)) {\n return isTextChildren(\n (children.props as { children?: ReactNode }).children\n );\n }\n return false;\n};\n\nexport const Link: FC<LinkProps> = (props) => {\n const {\n variant = 'default',\n color = 'custom',\n roundedSize,\n children,\n label,\n className,\n isActive,\n underlined,\n locale,\n size: sizeProp,\n isExternalLink: isExternalLinkProp,\n isPageSection: isPageSectionProp,\n href: hrefProp,\n rel: relProp,\n target: targetProp,\n ...otherProps\n } = props;\n\n const isButton = variant === 'button' || variant === 'button-outlined';\n const size = sizeProp ?? (isButton ? 'md' : 'custom');\n\n const isExternalLink = isExternalLinkProp ?? checkIsExternalLink(props);\n const isPageSection = isPageSectionProp ?? hrefProp?.startsWith('#') ?? false;\n\n const isChildrenString = isTextChildren(children);\n\n /**\n * External links always carry the full safety/SEO `rel`, so a caller cannot\n * accidentally strip `nofollow`. Internal links keep whatever the caller asked for.\n */\n const rel = isExternalLink ? 'noopener noreferrer nofollow' : relProp;\n\n const target = isExternalLink ? '_blank' : (targetProp ?? '_self');\n\n const resolvedHref =\n locale && hrefProp && !isExternalLink && !isPageSection\n ? getLocalizedUrl(hrefProp, locale)\n : hrefProp;\n\n const href = resolvedHref === '' ? undefined : resolvedHref;\n\n return (\n <a\n {...otherProps}\n href={href}\n aria-label={label}\n rel={rel}\n target={target}\n aria-current={isActive ? 'page' : undefined}\n suppressHydrationWarning\n className={cn(\n linkVariants({\n variant,\n color,\n roundedSize,\n underlined,\n size,\n className,\n })\n )}\n >\n {isButton && isChildrenString ? <span>{children}</span> : children}\n\n {isExternalLink && isChildrenString && (\n <ExternalLink className=\"ml-2 inline-block size-4\" />\n )}\n {isPageSection && <MoveRight className=\"ml-2 inline-block size-4\" />}\n </a>\n );\n};\n"],"mappings":"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"}
@@ -83,7 +83,7 @@ const DesktopNavbar = ({ logo, sections, rightItems, selectedChoice }) => /* @__
83
83
  className: "ml-[2vw] h-auto gap-3 overflow-x-auto text-muted-foreground tracking-wide lg:ml-[5vw] lg:gap-3 xl:ml-[10vw] xl:gap-6",
84
84
  tabs: sections,
85
85
  hoverable: true,
86
- color: "light"
86
+ color: "text"
87
87
  }),
88
88
  /* @__PURE__ */ jsx("div", {
89
89
  className: "mr-4 flex items-center justify-end gap-2 md:gap-4",
@@ -1 +1 @@
1
- {"version":3,"file":"DesktopNavbar.mjs","names":[],"sources":["../../../../src/components/Navbar/DesktopNavbar.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement, ReactNode } from 'react';\nimport { TabSelector, type TabSelectorItemProps } from '../TabSelector';\n\n/**\n * Props for the DesktopNavbar component\n * @template T - The tab props type extending TabProps\n */\ntype DesktopNavbarProps<T extends TabSelectorItemProps> = {\n /** Logo component or element displayed on the left side */\n logo: ReactNode;\n /** Array of navigation sections as tab elements */\n sections: ReactElement<T>[];\n /** Right-aligned items (e.g., user menu, search, settings) */\n rightItems?: ReactNode;\n /** Currently selected tab key for highlighting active state */\n selectedChoice: T['key'];\n};\n\n/**\n * Desktop Navigation Bar Component\n *\n * A horizontal navigation bar optimized for desktop and tablet viewports.\n * Features a sticky header with backdrop blur, left-aligned logo, center navigation tabs,\n * and right-aligned utility items.\n *\n * Features:\n * - Sticky positioning with z-index layering (z-50)\n * - Semi-transparent backdrop with blur effect for modern glass-morphism design\n * - Responsive spacing that adapts across screen sizes\n * - Horizontal scrollable tabs for overflow content\n * - Left-to-right layout: Logo → Navigation → Utility Items\n * - Integrated with TabSelector for consistent tab behavior\n *\n * Layout Structure:\n * ```\n * [Logo] -------- [Nav Tab 1] [Nav Tab 2] [Nav Tab 3] -------- [Right Items]\n * ```\n *\n * Responsive Behavior:\n * - Base: 2vw margin-left, 3-unit gap between tabs\n * - Large (≥1024px): 5vw margin-left, 3-unit gap between tabs\n * - Extra Large (≥1280px): 10vw margin-left, 6-unit gap between tabs\n * - Right items: 2-unit gap on mobile, 4-unit gap on medium screens\n *\n * Styling Features:\n * - Semi-transparent card background (`bg-card/80`)\n * - Subtle shadow with controlled blur (`shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)]`)\n * - Backdrop blur effect for content behind navbar\n * - Horizontal overflow scrolling for tab content\n *\n * @example\n * Basic usage:\n * ```tsx\n * const navigationTabs = [\n * { key: 'home', label: 'Home', href: '/' },\n * { key: 'products', label: 'Products', href: '/products' },\n * { key: 'about', label: 'About', href: '/about' }\n * ];\n *\n * <DesktopNavbar\n * logo={<CompanyLogo />}\n * sections={navigationTabs}\n * selectedChoice=\"home\"\n * rightItems={<UserProfileMenu />}\n * />\n * ```\n *\n * @example\n * With multiple right items:\n * ```tsx\n * <DesktopNavbar\n * logo={<Logo />}\n * sections={navSections}\n * selectedChoice={currentPage}\n * rightItems={\n * <>\n * <SearchButton />\n * <NotificationBell />\n * <UserMenu />\n * </>\n * }\n * />\n * ```\n *\n * @template T - Tab properties type extending TabProps for type safety\n * @param props - DesktopNavbar component props\n * @returns Horizontal desktop navigation JSX element\n */\nexport const DesktopNavbar = <T extends TabSelectorItemProps>({\n logo,\n sections,\n rightItems,\n selectedChoice,\n}: DesktopNavbarProps<T>) => (\n <nav className=\"sticky top-0 z-50 flex w-full items-center border-neutral border-b px-4 py-3 shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)] backdrop-blur-2xl\">\n {logo}\n\n <TabSelector\n selectedChoice={selectedChoice}\n className=\"ml-[2vw] h-auto gap-3 overflow-x-auto text-muted-foreground tracking-wide lg:ml-[5vw] lg:gap-3 xl:ml-[10vw] xl:gap-6\"\n tabs={sections}\n hoverable\n color=\"light\"\n />\n\n <div className=\"mr-4 flex items-center justify-end gap-2 md:gap-4\">\n {rightItems}\n </div>\n </nav>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,MAAa,iBAAiD,EAC5D,MACA,UACA,YACA,qBAEA,qBAAC,OAAD;CAAK,WAAU;WAAf;EACG;EAED,oBAAC,aAAD;GACkB;GAChB,WAAU;GACV,MAAM;GACN;GACA,OAAM;EACP;EAED,oBAAC,OAAD;GAAK,WAAU;aACZ;EACE;CACF"}
1
+ {"version":3,"file":"DesktopNavbar.mjs","names":[],"sources":["../../../../src/components/Navbar/DesktopNavbar.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement, ReactNode } from 'react';\nimport { TabSelector, type TabSelectorItemProps } from '../TabSelector';\n\n/**\n * Props for the DesktopNavbar component\n * @template T - The tab props type extending TabProps\n */\ntype DesktopNavbarProps<T extends TabSelectorItemProps> = {\n /** Logo component or element displayed on the left side */\n logo: ReactNode;\n /** Array of navigation sections as tab elements */\n sections: ReactElement<T>[];\n /** Right-aligned items (e.g., user menu, search, settings) */\n rightItems?: ReactNode;\n /** Currently selected tab key for highlighting active state */\n selectedChoice: T['key'];\n};\n\n/**\n * Desktop Navigation Bar Component\n *\n * A horizontal navigation bar optimized for desktop and tablet viewports.\n * Features a sticky header with backdrop blur, left-aligned logo, center navigation tabs,\n * and right-aligned utility items.\n *\n * Features:\n * - Sticky positioning with z-index layering (z-50)\n * - Semi-transparent backdrop with blur effect for modern glass-morphism design\n * - Responsive spacing that adapts across screen sizes\n * - Horizontal scrollable tabs for overflow content\n * - Left-to-right layout: Logo → Navigation → Utility Items\n * - Integrated with TabSelector for consistent tab behavior\n *\n * Layout Structure:\n * ```\n * [Logo] -------- [Nav Tab 1] [Nav Tab 2] [Nav Tab 3] -------- [Right Items]\n * ```\n *\n * Responsive Behavior:\n * - Base: 2vw margin-left, 3-unit gap between tabs\n * - Large (≥1024px): 5vw margin-left, 3-unit gap between tabs\n * - Extra Large (≥1280px): 10vw margin-left, 6-unit gap between tabs\n * - Right items: 2-unit gap on mobile, 4-unit gap on medium screens\n *\n * Styling Features:\n * - Semi-transparent card background (`bg-card/80`)\n * - Subtle shadow with controlled blur (`shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)]`)\n * - Backdrop blur effect for content behind navbar\n * - Horizontal overflow scrolling for tab content\n *\n * @example\n * Basic usage:\n * ```tsx\n * const navigationTabs = [\n * { key: 'home', label: 'Home', href: '/' },\n * { key: 'products', label: 'Products', href: '/products' },\n * { key: 'about', label: 'About', href: '/about' }\n * ];\n *\n * <DesktopNavbar\n * logo={<CompanyLogo />}\n * sections={navigationTabs}\n * selectedChoice=\"home\"\n * rightItems={<UserProfileMenu />}\n * />\n * ```\n *\n * @example\n * With multiple right items:\n * ```tsx\n * <DesktopNavbar\n * logo={<Logo />}\n * sections={navSections}\n * selectedChoice={currentPage}\n * rightItems={\n * <>\n * <SearchButton />\n * <NotificationBell />\n * <UserMenu />\n * </>\n * }\n * />\n * ```\n *\n * @template T - Tab properties type extending TabProps for type safety\n * @param props - DesktopNavbar component props\n * @returns Horizontal desktop navigation JSX element\n */\nexport const DesktopNavbar = <T extends TabSelectorItemProps>({\n logo,\n sections,\n rightItems,\n selectedChoice,\n}: DesktopNavbarProps<T>) => (\n <nav className=\"sticky top-0 z-50 flex w-full items-center border-neutral border-b px-4 py-3 shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)] backdrop-blur-2xl\">\n {logo}\n\n <TabSelector\n selectedChoice={selectedChoice}\n className=\"ml-[2vw] h-auto gap-3 overflow-x-auto text-muted-foreground tracking-wide lg:ml-[5vw] lg:gap-3 xl:ml-[10vw] xl:gap-6\"\n tabs={sections}\n hoverable\n color=\"text\"\n />\n\n <div className=\"mr-4 flex items-center justify-end gap-2 md:gap-4\">\n {rightItems}\n </div>\n </nav>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,MAAa,iBAAiD,EAC5D,MACA,UACA,YACA,qBAEA,qBAAC,OAAD;CAAK,WAAU;WAAf;EACG;EAED,oBAAC,aAAD;GACkB;GAChB,WAAU;GACV,MAAM;GACN;GACA,OAAM;EACP;EAED,oBAAC,OAAD;GAAK,WAAU;aACZ;EACE;CACF"}
@@ -19,8 +19,6 @@ const paginationVariants = cva("flex items-center justify-center gap-1", {
19
19
  },
20
20
  color: {
21
21
  text: "background-text",
22
- primary: "background-primary",
23
- secondary: "background-secondary",
24
22
  neutral: "background-neutral"
25
23
  },
26
24
  variant: {
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.mjs","names":[],"sources":["../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["'use client';\n\nimport { useItemSelector } from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';\nimport {\n type ComponentProps,\n type FC,\n type HTMLAttributes,\n useEffect,\n useRef,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button } from '../Button';\n\nexport const paginationVariants = cva(\n 'flex items-center justify-center gap-1',\n {\n variants: {\n size: {\n sm: 'gap-1',\n md: 'gap-2',\n lg: 'gap-3',\n },\n color: {\n text: 'background-text',\n primary: 'background-primary',\n secondary: 'background-secondary',\n neutral: 'background-neutral',\n },\n variant: {\n default: '',\n bordered: 'rounded-lg border border-border p-2',\n ghost: 'bg-transparent',\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n }\n);\n\nexport type PaginationSize = 'sm' | 'md' | 'lg';\n\nexport type PaginationVariant = 'default' | 'bordered' | 'ghost';\n\nexport type PaginationProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof paginationVariants> & {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n showFirstLast?: boolean;\n showPrevNext?: boolean;\n maxVisiblePages?: number;\n disabled?: boolean;\n };\n\nconst generatePageNumbers = (\n currentPage: number,\n totalPages: number,\n maxVisiblePages: number\n): (number | 'ellipsis')[] => {\n if (totalPages <= maxVisiblePages) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages: (number | 'ellipsis')[] = [];\n const halfVisible = Math.floor(maxVisiblePages / 2);\n\n pages.push(1);\n\n if (currentPage <= halfVisible + 2) {\n for (let i = 2; i <= Math.min(maxVisiblePages - 1, totalPages - 1); i++) {\n pages.push(i);\n }\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n if (totalPages > 1) {\n pages.push(totalPages);\n }\n } else if (currentPage >= totalPages - halfVisible - 1) {\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n for (\n let i = Math.max(2, totalPages - maxVisiblePages + 2);\n i <= totalPages;\n i++\n ) {\n pages.push(i);\n }\n } else {\n pages.push('ellipsis');\n const start = currentPage - halfVisible;\n const end = currentPage + halfVisible;\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n pages.push('ellipsis');\n pages.push(totalPages);\n }\n\n return pages;\n};\n\nconst selector = (option: HTMLElement) =>\n option?.getAttribute('aria-current') === 'true';\n\nconst getButtonSize = (size?: PaginationSize | `${PaginationSize}` | null) => {\n if (size === 'sm') {\n return 'icon-sm';\n } else if (size === 'lg') {\n return 'icon-lg';\n } else {\n return 'icon-md';\n }\n};\n\nconst InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/10 transition-[left,width] duration-300 ease-in-out [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl motion-reduce:transition-none\"\n {...props}\n />\n);\n\nexport const Pagination: FC<PaginationProps> = ({\n currentPage,\n totalPages,\n onPageChange,\n showFirstLast = false,\n showPrevNext = true,\n maxVisiblePages = 5,\n disabled = false,\n size = 'md',\n variant = 'default',\n color = 'text',\n className,\n ...props\n}) => {\n const { goToNextPage, goToPreviousPage } = useIntlayer('pagination');\n\n const pageNumbers = generatePageNumbers(\n currentPage,\n totalPages,\n maxVisiblePages\n );\n\n const buttonSize = getButtonSize(size);\n const isFirstPage = currentPage === 1;\n const isLastPage = currentPage === totalPages;\n\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, scheduleMeasurement } = useItemSelector(\n optionsRefs,\n {\n selector,\n isHoverable: true,\n }\n );\n\n useEffect(() => {\n const timer = setTimeout(() => {\n scheduleMeasurement();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [currentPage, scheduleMeasurement]);\n\n if (totalPages <= 1) return null;\n\n const handlePageChange = (page: number) => {\n if (!disabled && page >= 1 && page <= totalPages && page !== currentPage) {\n onPageChange(page);\n }\n };\n\n return (\n <div\n className={cn(paginationVariants({ size, variant }), className)}\n {...props}\n >\n <div className=\"relative flex items-center gap-1\">\n {choiceIndicatorPosition && (\n <InputIndicator style={choiceIndicatorPosition} ref={indicatorRef} />\n )}\n\n {showPrevNext && (\n <Button\n variant=\"outline\"\n size={buttonSize}\n color=\"text\"\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={disabled || isFirstPage}\n label={goToPreviousPage.value}\n Icon={ChevronLeft}\n ref={(el) => {\n if (el) optionsRefs.current[0] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n\n <div className=\"flex items-center gap-1 max-md:gap-0.5\">\n {pageNumbers.map((page, index) => {\n if (page === 'ellipsis') {\n const isFirstEllipsis = index === pageNumbers.indexOf('ellipsis');\n const ellipsisKey = isFirstEllipsis\n ? 'ellipsis-start'\n : 'ellipsis-end';\n return (\n <div\n key={ellipsisKey}\n className=\"flex h-8 min-w-8 items-center justify-center px-1\"\n >\n <MoreHorizontal className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n );\n }\n\n const isActive = page === currentPage;\n // Calculate ref index: offset by 1 if showPrevNext, then count only non-ellipsis items\n const refIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.slice(0, index).filter((p) => p !== 'ellipsis')\n .length;\n\n return (\n <Button\n key={page}\n variant={isActive ? 'default' : 'outline'}\n size={buttonSize}\n color=\"text\"\n onClick={() => handlePageChange(page)}\n disabled={disabled}\n label={`Go to page ${page}`}\n aria-current={isActive ? 'true' : 'false'}\n ref={(el) => {\n if (el) optionsRefs.current[refIndex] = el;\n }}\n className={cn(\n 'flex aspect-square h-8 w-8 min-w-0 items-center justify-center p-0 text-sm',\n size === 'sm' && 'h-6 w-6 text-xs',\n size === 'lg' && 'size-10 text-base',\n isActive && 'font-semibold'\n )}\n >\n {page}\n </Button>\n );\n })}\n </div>\n\n {showPrevNext && (\n <Button\n variant=\"outline\"\n size={buttonSize}\n color=\"text\"\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={disabled || isLastPage}\n label={goToNextPage.value}\n Icon={ChevronRight}\n ref={(el) => {\n const lastRefIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.filter((p) => p !== 'ellipsis').length;\n if (el) optionsRefs.current[lastRefIndex] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Pagination.mjs","names":[],"sources":["../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["'use client';\n\nimport { useItemSelector } from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';\nimport {\n type ComponentProps,\n type FC,\n type HTMLAttributes,\n useEffect,\n useRef,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button } from '../Button';\n\nexport const paginationVariants = cva(\n 'flex items-center justify-center gap-1',\n {\n variants: {\n size: {\n sm: 'gap-1',\n md: 'gap-2',\n lg: 'gap-3',\n },\n color: {\n text: 'background-text',\n neutral: 'background-neutral',\n },\n variant: {\n default: '',\n bordered: 'rounded-lg border border-border p-2',\n ghost: 'bg-transparent',\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n }\n);\n\nexport type PaginationSize = 'sm' | 'md' | 'lg';\n\nexport type PaginationVariant = 'default' | 'bordered' | 'ghost';\n\nexport type PaginationProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof paginationVariants> & {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n showFirstLast?: boolean;\n showPrevNext?: boolean;\n maxVisiblePages?: number;\n disabled?: boolean;\n };\n\nconst generatePageNumbers = (\n currentPage: number,\n totalPages: number,\n maxVisiblePages: number\n): (number | 'ellipsis')[] => {\n if (totalPages <= maxVisiblePages) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages: (number | 'ellipsis')[] = [];\n const halfVisible = Math.floor(maxVisiblePages / 2);\n\n pages.push(1);\n\n if (currentPage <= halfVisible + 2) {\n for (let i = 2; i <= Math.min(maxVisiblePages - 1, totalPages - 1); i++) {\n pages.push(i);\n }\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n if (totalPages > 1) {\n pages.push(totalPages);\n }\n } else if (currentPage >= totalPages - halfVisible - 1) {\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n for (\n let i = Math.max(2, totalPages - maxVisiblePages + 2);\n i <= totalPages;\n i++\n ) {\n pages.push(i);\n }\n } else {\n pages.push('ellipsis');\n const start = currentPage - halfVisible;\n const end = currentPage + halfVisible;\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n pages.push('ellipsis');\n pages.push(totalPages);\n }\n\n return pages;\n};\n\nconst selector = (option: HTMLElement) =>\n option?.getAttribute('aria-current') === 'true';\n\nconst getButtonSize = (size?: PaginationSize | `${PaginationSize}` | null) => {\n if (size === 'sm') {\n return 'icon-sm';\n } else if (size === 'lg') {\n return 'icon-lg';\n } else {\n return 'icon-md';\n }\n};\n\nconst InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/10 transition-[left,width] duration-300 ease-in-out [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl motion-reduce:transition-none\"\n {...props}\n />\n);\n\nexport const Pagination: FC<PaginationProps> = ({\n currentPage,\n totalPages,\n onPageChange,\n showFirstLast = false,\n showPrevNext = true,\n maxVisiblePages = 5,\n disabled = false,\n size = 'md',\n variant = 'default',\n color = 'text',\n className,\n ...props\n}) => {\n const { goToNextPage, goToPreviousPage } = useIntlayer('pagination');\n\n const pageNumbers = generatePageNumbers(\n currentPage,\n totalPages,\n maxVisiblePages\n );\n\n const buttonSize = getButtonSize(size);\n const isFirstPage = currentPage === 1;\n const isLastPage = currentPage === totalPages;\n\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, scheduleMeasurement } = useItemSelector(\n optionsRefs,\n {\n selector,\n isHoverable: true,\n }\n );\n\n useEffect(() => {\n const timer = setTimeout(() => {\n scheduleMeasurement();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [currentPage, scheduleMeasurement]);\n\n if (totalPages <= 1) return null;\n\n const handlePageChange = (page: number) => {\n if (!disabled && page >= 1 && page <= totalPages && page !== currentPage) {\n onPageChange(page);\n }\n };\n\n return (\n <div\n className={cn(paginationVariants({ size, variant }), className)}\n {...props}\n >\n <div className=\"relative flex items-center gap-1\">\n {choiceIndicatorPosition && (\n <InputIndicator style={choiceIndicatorPosition} ref={indicatorRef} />\n )}\n\n {showPrevNext && (\n <Button\n variant=\"outline\"\n size={buttonSize}\n color=\"text\"\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={disabled || isFirstPage}\n label={goToPreviousPage.value}\n Icon={ChevronLeft}\n ref={(el) => {\n if (el) optionsRefs.current[0] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n\n <div className=\"flex items-center gap-1 max-md:gap-0.5\">\n {pageNumbers.map((page, index) => {\n if (page === 'ellipsis') {\n const isFirstEllipsis = index === pageNumbers.indexOf('ellipsis');\n const ellipsisKey = isFirstEllipsis\n ? 'ellipsis-start'\n : 'ellipsis-end';\n return (\n <div\n key={ellipsisKey}\n className=\"flex h-8 min-w-8 items-center justify-center px-1\"\n >\n <MoreHorizontal className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n );\n }\n\n const isActive = page === currentPage;\n // Calculate ref index: offset by 1 if showPrevNext, then count only non-ellipsis items\n const refIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.slice(0, index).filter((p) => p !== 'ellipsis')\n .length;\n\n return (\n <Button\n key={page}\n variant={isActive ? 'default' : 'outline'}\n size={buttonSize}\n color=\"text\"\n onClick={() => handlePageChange(page)}\n disabled={disabled}\n label={`Go to page ${page}`}\n aria-current={isActive ? 'true' : 'false'}\n ref={(el) => {\n if (el) optionsRefs.current[refIndex] = el;\n }}\n className={cn(\n 'flex aspect-square h-8 w-8 min-w-0 items-center justify-center p-0 text-sm',\n size === 'sm' && 'h-6 w-6 text-xs',\n size === 'lg' && 'size-10 text-base',\n isActive && 'font-semibold'\n )}\n >\n {page}\n </Button>\n );\n })}\n </div>\n\n {showPrevNext && (\n <Button\n variant=\"outline\"\n size={buttonSize}\n color=\"text\"\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={disabled || isLastPage}\n label={goToNextPage.value}\n Icon={ChevronRight}\n ref={(el) => {\n const lastRefIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.filter((p) => p !== 'ellipsis').length;\n if (el) optionsRefs.current[lastRefIndex] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -17,8 +17,6 @@ const defaultChoices = [{
17
17
  const switchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-row gap-2 rounded-full border-[1.3px] p-0.38", {
18
18
  variants: {
19
19
  color: {
20
- primary: "border-primary text-primary",
21
- secondary: "border-secondary text-secondary",
22
20
  neutral: "border-neutral text-neutral",
23
21
  white: "border-white text-white",
24
22
  black: "border-black text-black",
@@ -45,8 +43,6 @@ const choiceVariant = cva("z-1 flex-1 cursor-pointer font-medium text-sm transit
45
43
  defaultVariants: { size: "md" }
46
44
  });
47
45
  const indicatorVariant = cva("absolute top-0 z-0 h-full w-auto rounded-full transition-all duration-300 ease-in-out motion-reduce:transition-none", { variants: { color: {
48
- primary: "bg-primary data-[indicator=true]:text-primary-foreground",
49
- secondary: "bg-secondary data-[indicator=true]:text-secondary-foreground",
50
46
  neutral: "bg-neutral data-[indicator=true]:text-white",
51
47
  white: "bg-white data-[indicator=true]:text-black",
52
48
  black: "bg-black data-[indicator=true]:text-white",
@@ -58,7 +54,7 @@ const indicatorVariant = cva("absolute top-0 z-0 h-full w-auto rounded-full tran
58
54
  * This component is horizontal.
59
55
  */
60
56
  const SwitchSelector = (props) => {
61
- const { choices = defaultChoices, color = "primary", size = "md", className, itemClassName } = props;
57
+ const { choices = defaultChoices, color = "text", size = "md", className, itemClassName } = props;
62
58
  const { selectedIndex, indicatorIndex, handleChange, optionsRefs, indicatorRef, choiceIndicatorPosition, setHoveredIndex, disabled } = useSwitchSelector({
63
59
  choices,
64
60
  value: props.value,
@@ -1 +1 @@
1
- {"version":3,"file":"SwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/SwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nexport type SwitchSelectorChoice<T = boolean> = {\n content: ReactNode;\n value: T;\n} & HTMLAttributes<HTMLButtonElement>;\nexport type SwitchSelectorChoices<T> = SwitchSelectorChoice<T>[];\n\nexport const defaultChoices: SwitchSelectorChoices<boolean> = [\n { content: 'Off', value: false },\n { content: 'On', value: true },\n];\n\nexport type SwitchSelectorColor =\n | 'primary'\n | 'secondary'\n | 'neutral'\n | 'white'\n | 'black'\n | 'text'\n | 'error';\n\nexport type SwitchSelectorSize = 'xs' | 'sm' | 'md' | 'lg';\n\nexport type SwitchSelectorBaseProps<T = boolean> = {\n choices?: SwitchSelectorChoices<T>;\n value?: T;\n defaultValue?: T;\n onChange?: (choice: T) => void;\n className?: string;\n itemClassName?: string;\n hoverable?: boolean;\n disabled?: boolean;\n [key: string]: any;\n};\n\nexport type SwitchSelectorProps<T = boolean> = SwitchSelectorBaseProps<T> &\n VariantProps<typeof switchSelectorVariant> &\n VariantProps<typeof choiceVariant>;\n\nexport const switchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-row gap-2 rounded-full border-[1.3px] p-0.38',\n {\n variants: {\n color: {\n primary: 'border-primary text-primary',\n secondary: 'border-secondary text-secondary',\n neutral: 'border-neutral text-neutral',\n white: 'border-white text-white',\n black: 'border-black text-black',\n text: 'border-foreground text-foreground',\n error: 'border-error text-error',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: 'text',\n disabled: false,\n },\n }\n);\n\nexport const choiceVariant = cva(\n 'z-1 flex-1 cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-background motion-reduce:transition-none',\n {\n variants: {\n size: {\n xs: 'px-2 py-0.5 text-xs',\n sm: 'px-2 py-1 text-xs',\n md: 'p-2 text-sm',\n lg: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n }\n);\n\nexport const indicatorVariant = cva(\n 'absolute top-0 z-0 h-full w-auto rounded-full transition-all duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n primary: 'bg-primary data-[indicator=true]:text-primary-foreground',\n secondary:\n 'bg-secondary data-[indicator=true]:text-secondary-foreground',\n neutral: 'bg-neutral data-[indicator=true]:text-white',\n white: 'bg-white data-[indicator=true]:text-black',\n black: 'bg-black data-[indicator=true]:text-white',\n text: 'bg-foreground data-[indicator=true]:text-background',\n error: 'bg-error data-[indicator=true]:text-white',\n },\n },\n }\n);\n/**\n * Component that allows the user to select one of the provided choices.\n * This component is horizontal.\n */\nexport const SwitchSelector = <T,>(props: SwitchSelectorProps<T>) => {\n const {\n choices = defaultChoices as SwitchSelectorChoices<T>,\n color = 'primary',\n size = 'md',\n className,\n itemClassName,\n } = props;\n\n const {\n selectedIndex,\n indicatorIndex,\n handleChange,\n optionsRefs,\n indicatorRef,\n choiceIndicatorPosition,\n setHoveredIndex,\n disabled,\n } = useSwitchSelector(\n {\n choices,\n value: props.value,\n defaultValue: props.defaultValue,\n onChange: props.onChange,\n hoverable: props.hoverable,\n disabled: props.disabled,\n },\n 'horizontal'\n );\n\n return (\n <div\n className={switchSelectorVariant({\n color,\n disabled,\n className,\n })}\n role=\"tablist\"\n aria-disabled={disabled ? 'true' : undefined}\n >\n <div className=\"relative flex size-full flex-row items-center justify-center\">\n {choices.map((choice, index) => {\n const { content, value, ...buttonProps } = choice;\n\n const isKeyOfKey =\n typeof value === 'string' || typeof value === 'number';\n\n const isSelected = index === selectedIndex;\n const isIndicatorOwner = index === indicatorIndex;\n\n return (\n <button\n {...buttonProps}\n type=\"button\"\n className={cn(\n choiceVariant({\n size,\n }),\n disabled && 'cursor-not-allowed',\n itemClassName\n )}\n key={isKeyOfKey ? value : index}\n role=\"tab\"\n onClick={() => handleChange(value)}\n aria-selected={isSelected ? 'true' : undefined}\n data-indicator={isIndicatorOwner ? 'true' : undefined}\n disabled={disabled}\n tabIndex={isSelected ? 0 : -1}\n ref={(el) => {\n optionsRefs.current[index] = el!;\n }}\n onMouseEnter={() => !disabled && setHoveredIndex(index)}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {content}\n </button>\n );\n })}\n\n {choiceIndicatorPosition && (\n <div\n className={cn(\n indicatorVariant({\n color,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;AAaA,MAAa,iBAAiD,CAC5D;CAAE,SAAS;CAAO,OAAO;AAAM,GAC/B;CAAE,SAAS;CAAM,OAAO;AAAK,CAC/B;AA6BA,MAAa,wBAAwB,IACnC,qFACA;CACE,UAAU;EACR,OAAO;GACL,SAAS;GACT,WAAW;GACX,SAAS;GACT,OAAO;GACP,OAAO;GACP,MAAM;GACN,OAAO;EACT;EACA,UAAU;GACR,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,OAAO;EACP,UAAU;CACZ;AACF,CACF;AAEA,MAAa,gBAAgB,IAC3B,0LACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AAEA,MAAa,mBAAmB,IAC9B,uHACA,EACE,UAAU,EACR,OAAO;CACL,SAAS;CACT,WACE;CACF,SAAS;CACT,OAAO;CACP,OAAO;CACP,MAAM;CACN,OAAO;AACT,EACF,EACF,CACF;;;;;AAKA,MAAa,kBAAsB,UAAkC;CACnE,MAAM,EACJ,UAAU,gBACV,QAAQ,WACR,OAAO,MACP,WACA,kBACE;CAEJ,MAAM,EACJ,eACA,gBACA,cACA,aACA,cACA,yBACA,iBACA,aACE,kBACF;EACE;EACA,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,UAAU,MAAM;CAClB,GACA,YACF;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,sBAAsB;GAC/B;GACA;GACA;EACF,CAAC;EACD,MAAK;EACL,iBAAe,WAAW,SAAS;YAEnC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,EAAE,SAAS,OAAO,GAAG,gBAAgB;IAE3C,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,UAAU;IAEhD,MAAM,aAAa,UAAU;IAC7B,MAAM,mBAAmB,UAAU;IAEnC,OACE,8BAAC,UAAD;KACE,GAAI;KACJ,MAAK;KACL,WAAW,GACT,cAAc,EACZ,KACF,CAAC,GACD,YAAY,sBACZ,aACF;KACA,KAAK,aAAa,QAAQ;KAC1B,MAAK;KACL,eAAe,aAAa,KAAK;KACjC,iBAAe,aAAa,SAAS;KACrC,kBAAgB,mBAAmB,SAAS;KAClC;KACV,UAAU,aAAa,IAAI;KAC3B,MAAM,OAAO;MACX,YAAY,QAAQ,SAAS;KAC/B;KACA,oBAAoB,CAAC,YAAY,gBAAgB,KAAK;KACtD,oBAAoB,CAAC,YAAY,gBAAgB,IAAI;IAG/C,GADL,OACK;GAEZ,CAAC,GAEA,2BACC,oBAAC,OAAD;IACE,WAAW,GACT,iBAAiB,EACf,MACF,CAAC,CACH;IACA,OAAO;IACP,KAAK;GACN,EAEA;;CACF;AAET"}
1
+ {"version":3,"file":"SwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/SwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nexport type SwitchSelectorChoice<T = boolean> = {\n content: ReactNode;\n value: T;\n} & HTMLAttributes<HTMLButtonElement>;\nexport type SwitchSelectorChoices<T> = SwitchSelectorChoice<T>[];\n\nexport const defaultChoices: SwitchSelectorChoices<boolean> = [\n { content: 'Off', value: false },\n { content: 'On', value: true },\n];\n\nexport type SwitchSelectorColor =\n | 'neutral'\n | 'white'\n | 'black'\n | 'text'\n | 'error';\n\nexport type SwitchSelectorSize = 'xs' | 'sm' | 'md' | 'lg';\n\nexport type SwitchSelectorBaseProps<T = boolean> = {\n choices?: SwitchSelectorChoices<T>;\n value?: T;\n defaultValue?: T;\n onChange?: (choice: T) => void;\n className?: string;\n itemClassName?: string;\n hoverable?: boolean;\n disabled?: boolean;\n [key: string]: any;\n};\n\nexport type SwitchSelectorProps<T = boolean> = SwitchSelectorBaseProps<T> &\n VariantProps<typeof switchSelectorVariant> &\n VariantProps<typeof choiceVariant>;\n\nexport const switchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-row gap-2 rounded-full border-[1.3px] p-0.38',\n {\n variants: {\n color: {\n neutral: 'border-neutral text-neutral',\n white: 'border-white text-white',\n black: 'border-black text-black',\n text: 'border-foreground text-foreground',\n error: 'border-error text-error',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: 'text',\n disabled: false,\n },\n }\n);\n\nexport const choiceVariant = cva(\n 'z-1 flex-1 cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-background motion-reduce:transition-none',\n {\n variants: {\n size: {\n xs: 'px-2 py-0.5 text-xs',\n sm: 'px-2 py-1 text-xs',\n md: 'p-2 text-sm',\n lg: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n }\n);\n\nexport const indicatorVariant = cva(\n 'absolute top-0 z-0 h-full w-auto rounded-full transition-all duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n neutral: 'bg-neutral data-[indicator=true]:text-white',\n white: 'bg-white data-[indicator=true]:text-black',\n black: 'bg-black data-[indicator=true]:text-white',\n text: 'bg-foreground data-[indicator=true]:text-background',\n error: 'bg-error data-[indicator=true]:text-white',\n },\n },\n }\n);\n/**\n * Component that allows the user to select one of the provided choices.\n * This component is horizontal.\n */\nexport const SwitchSelector = <T,>(props: SwitchSelectorProps<T>) => {\n const {\n choices = defaultChoices as SwitchSelectorChoices<T>,\n color = 'text',\n size = 'md',\n className,\n itemClassName,\n } = props;\n\n const {\n selectedIndex,\n indicatorIndex,\n handleChange,\n optionsRefs,\n indicatorRef,\n choiceIndicatorPosition,\n setHoveredIndex,\n disabled,\n } = useSwitchSelector(\n {\n choices,\n value: props.value,\n defaultValue: props.defaultValue,\n onChange: props.onChange,\n hoverable: props.hoverable,\n disabled: props.disabled,\n },\n 'horizontal'\n );\n\n return (\n <div\n className={switchSelectorVariant({\n color,\n disabled,\n className,\n })}\n role=\"tablist\"\n aria-disabled={disabled ? 'true' : undefined}\n >\n <div className=\"relative flex size-full flex-row items-center justify-center\">\n {choices.map((choice, index) => {\n const { content, value, ...buttonProps } = choice;\n\n const isKeyOfKey =\n typeof value === 'string' || typeof value === 'number';\n\n const isSelected = index === selectedIndex;\n const isIndicatorOwner = index === indicatorIndex;\n\n return (\n <button\n {...buttonProps}\n type=\"button\"\n className={cn(\n choiceVariant({\n size,\n }),\n disabled && 'cursor-not-allowed',\n itemClassName\n )}\n key={isKeyOfKey ? value : index}\n role=\"tab\"\n onClick={() => handleChange(value)}\n aria-selected={isSelected ? 'true' : undefined}\n data-indicator={isIndicatorOwner ? 'true' : undefined}\n disabled={disabled}\n tabIndex={isSelected ? 0 : -1}\n ref={(el) => {\n optionsRefs.current[index] = el!;\n }}\n onMouseEnter={() => !disabled && setHoveredIndex(index)}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {content}\n </button>\n );\n })}\n\n {choiceIndicatorPosition && (\n <div\n className={cn(\n indicatorVariant({\n color,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;AAaA,MAAa,iBAAiD,CAC5D;CAAE,SAAS;CAAO,OAAO;AAAM,GAC/B;CAAE,SAAS;CAAM,OAAO;AAAK,CAC/B;AA2BA,MAAa,wBAAwB,IACnC,qFACA;CACE,UAAU;EACR,OAAO;GACL,SAAS;GACT,OAAO;GACP,OAAO;GACP,MAAM;GACN,OAAO;EACT;EACA,UAAU;GACR,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,OAAO;EACP,UAAU;CACZ;AACF,CACF;AAEA,MAAa,gBAAgB,IAC3B,0LACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AAEA,MAAa,mBAAmB,IAC9B,uHACA,EACE,UAAU,EACR,OAAO;CACL,SAAS;CACT,OAAO;CACP,OAAO;CACP,MAAM;CACN,OAAO;AACT,EACF,EACF,CACF;;;;;AAKA,MAAa,kBAAsB,UAAkC;CACnE,MAAM,EACJ,UAAU,gBACV,QAAQ,QACR,OAAO,MACP,WACA,kBACE;CAEJ,MAAM,EACJ,eACA,gBACA,cACA,aACA,cACA,yBACA,iBACA,aACE,kBACF;EACE;EACA,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,UAAU,MAAM;CAClB,GACA,YACF;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,sBAAsB;GAC/B;GACA;GACA;EACF,CAAC;EACD,MAAK;EACL,iBAAe,WAAW,SAAS;YAEnC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,EAAE,SAAS,OAAO,GAAG,gBAAgB;IAE3C,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,UAAU;IAEhD,MAAM,aAAa,UAAU;IAC7B,MAAM,mBAAmB,UAAU;IAEnC,OACE,8BAAC,UAAD;KACE,GAAI;KACJ,MAAK;KACL,WAAW,GACT,cAAc,EACZ,KACF,CAAC,GACD,YAAY,sBACZ,aACF;KACA,KAAK,aAAa,QAAQ;KAC1B,MAAK;KACL,eAAe,aAAa,KAAK;KACjC,iBAAe,aAAa,SAAS;KACrC,kBAAgB,mBAAmB,SAAS;KAClC;KACV,UAAU,aAAa,IAAI;KAC3B,MAAM,OAAO;MACX,YAAY,QAAQ,SAAS;KAC/B;KACA,oBAAoB,CAAC,YAAY,gBAAgB,KAAK;KACtD,oBAAoB,CAAC,YAAY,gBAAgB,IAAI;IAG/C,GADL,OACK;GAEZ,CAAC,GAEA,2BACC,oBAAC,OAAD;IACE,WAAW,GACT,iBAAiB,EACf,MACF,CAAC,CACH;IACA,OAAO;IACP,KAAK;GACN,EAEA;;CACF;AAET"}
@@ -11,8 +11,6 @@ import { cva } from "class-variance-authority";
11
11
  const verticalSwitchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-col gap-2 rounded-2xl border-[1.3px] p-1", {
12
12
  variants: {
13
13
  color: {
14
- primary: "border-primary text-primary",
15
- secondary: "border-secondary text-secondary",
16
14
  [`error`]: "border-error bg-error text-error",
17
15
  neutral: "border-neutral text-neutral",
18
16
  light: "border-white text-white",
@@ -25,7 +23,7 @@ const verticalSwitchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-
25
23
  }
26
24
  },
27
25
  defaultVariants: {
28
- color: `primary`,
26
+ color: `text`,
29
27
  disabled: false
30
28
  }
31
29
  });
@@ -38,8 +36,6 @@ const verticalChoiceVariant = cva("z-1 w-full cursor-pointer font-medium text-sm
38
36
  defaultVariants: { size: `md` }
39
37
  });
40
38
  const verticalIndicatorVariant = cva("absolute left-0 z-0 h-auto w-full rounded-xl transition-all duration-300 ease-in-out motion-reduce:transition-none", { variants: { color: {
41
- primary: "bg-primary data-[indicator=true]:text-foreground",
42
- secondary: "bg-secondary data-[indicator=true]:text-foreground",
43
39
  [`error`]: "bg-error data-[indicator=true]:text-foreground",
44
40
  neutral: "bg-neutral data-[indicator=true]:text-white",
45
41
  light: "bg-white data-[indicator=true]:text-black",
@@ -51,7 +47,7 @@ const verticalIndicatorVariant = cva("absolute left-0 z-0 h-auto w-full rounded-
51
47
  * This component is vertical.
52
48
  */
53
49
  const VerticalSwitchSelector = (props) => {
54
- const { choices = defaultChoices, color = "primary", size = "md", className, itemClassName } = props;
50
+ const { choices = defaultChoices, color = "text", size = "md", className, itemClassName } = props;
55
51
  const { selectedIndex, indicatorIndex, handleChange, optionsRefs, indicatorRef, choiceIndicatorPosition, setHoveredIndex, disabled } = useSwitchSelector({
56
52
  choices,
57
53
  value: props.value,
@@ -1 +1 @@
1
- {"version":3,"file":"VerticalSwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/VerticalSwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n defaultChoices,\n type SwitchSelectorBaseProps,\n type SwitchSelectorChoices,\n} from './SwitchSelector';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nconst verticalSwitchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-col gap-2 rounded-2xl border-[1.3px] p-1',\n {\n variants: {\n color: {\n primary: 'border-primary text-primary',\n secondary: 'border-secondary text-secondary',\n [`${'error'}`]: 'border-error bg-error text-error',\n neutral: 'border-neutral text-neutral',\n light: 'border-white text-white',\n dark: 'border-neutral-800 text-neutral-800',\n text: 'border-text text-foreground',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: `${'primary'}`,\n disabled: false,\n },\n }\n);\n\nconst verticalChoiceVariant = cva(\n 'z-1 w-full cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-foreground-opposite motion-reduce:transition-none',\n {\n variants: {\n size: {\n sm: 'px-2 py-1 text-xs',\n md: 'p-2 text-sm',\n lg: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: `${'md'}`,\n },\n }\n);\n\nconst verticalIndicatorVariant = cva(\n 'absolute left-0 z-0 h-auto w-full rounded-xl transition-all duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n primary: 'bg-primary data-[indicator=true]:text-foreground',\n secondary: 'bg-secondary data-[indicator=true]:text-foreground',\n [`${'error'}`]: 'bg-error data-[indicator=true]:text-foreground',\n neutral: 'bg-neutral data-[indicator=true]:text-white',\n light: 'bg-white data-[indicator=true]:text-black',\n dark: 'bg-neutral-800 data-[indicator=true]:text-white',\n text: 'bg-text data-[indicator=true]:text-foreground-opposite',\n },\n },\n }\n);\n\nexport type VerticalSwitchSelectorProps<T = boolean> =\n SwitchSelectorBaseProps<T> &\n VariantProps<typeof verticalSwitchSelectorVariant> &\n VariantProps<typeof verticalChoiceVariant>;\n\n/**\n * Component that allows the user to select one of the provided choices.\n * This component is vertical.\n */\nexport const VerticalSwitchSelector = <T,>(\n props: VerticalSwitchSelectorProps<T>\n) => {\n const {\n choices = defaultChoices as SwitchSelectorChoices<T>,\n color = 'primary',\n size = 'md',\n className,\n itemClassName,\n } = props;\n\n const {\n selectedIndex,\n indicatorIndex,\n handleChange,\n optionsRefs,\n indicatorRef,\n choiceIndicatorPosition,\n setHoveredIndex,\n disabled,\n } = useSwitchSelector(\n {\n choices,\n value: props.value,\n defaultValue: props.defaultValue,\n onChange: props.onChange,\n hoverable: props.hoverable,\n disabled: props.disabled,\n },\n 'vertical'\n );\n\n return (\n <div\n className={verticalSwitchSelectorVariant({\n color,\n disabled,\n className,\n })}\n role=\"tablist\"\n aria-disabled={disabled ? 'true' : undefined}\n >\n <div className=\"relative flex h-fit w-full flex-col items-center justify-center\">\n {choices.map((choice, index) => {\n const { content, value, ...buttonProps } = choice;\n\n const isKeyOfKey =\n typeof value === 'string' || typeof value === 'number';\n\n const isSelected = index === selectedIndex;\n const isIndicatorOwner = index === indicatorIndex;\n\n return (\n <button\n {...buttonProps}\n className={cn(\n verticalChoiceVariant({\n size,\n }),\n disabled && 'cursor-not-allowed',\n itemClassName\n )}\n key={isKeyOfKey ? value : index}\n role=\"tab\"\n onClick={() => handleChange(value)}\n aria-selected={isSelected ? 'true' : undefined}\n data-indicator={isIndicatorOwner ? 'true' : undefined}\n disabled={disabled || isSelected}\n tabIndex={isSelected ? 0 : -1}\n ref={(el) => {\n optionsRefs.current[index] = el!;\n }}\n onMouseEnter={() => !disabled && setHoveredIndex(index)}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {content}\n </button>\n );\n })}\n\n {choiceIndicatorPosition && (\n <div\n className={cn(\n verticalIndicatorVariant({\n color,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAWA,MAAM,gCAAgC,IACpC,iFACA;CACE,UAAU;EACR,OAAO;GACL,SAAS;GACT,WAAW;IACV,UAAe;GAChB,SAAS;GACT,OAAO;GACP,MAAM;GACN,MAAM;EACR;EACA,UAAU;GACR,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,OAAO;EACP,UAAU;CACZ;AACF,CACF;AAEA,MAAM,wBAAwB,IAC5B,mMACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AAEA,MAAM,2BAA2B,IAC/B,sHACA,EACE,UAAU,EACR,OAAO;CACL,SAAS;CACT,WAAW;EACV,UAAe;CAChB,SAAS;CACT,OAAO;CACP,MAAM;CACN,MAAM;AACR,EACF,EACF,CACF;;;;;AAWA,MAAa,0BACX,UACG;CACH,MAAM,EACJ,UAAU,gBACV,QAAQ,WACR,OAAO,MACP,WACA,kBACE;CAEJ,MAAM,EACJ,eACA,gBACA,cACA,aACA,cACA,yBACA,iBACA,aACE,kBACF;EACE;EACA,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,UAAU,MAAM;CAClB,GACA,UACF;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,8BAA8B;GACvC;GACA;GACA;EACF,CAAC;EACD,MAAK;EACL,iBAAe,WAAW,SAAS;YAEnC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,EAAE,SAAS,OAAO,GAAG,gBAAgB;IAE3C,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,UAAU;IAEhD,MAAM,aAAa,UAAU;IAC7B,MAAM,mBAAmB,UAAU;IAEnC,OACE,8BAAC,UAAD;KACE,GAAI;KACJ,WAAW,GACT,sBAAsB,EACpB,KACF,CAAC,GACD,YAAY,sBACZ,aACF;KACA,KAAK,aAAa,QAAQ;KAC1B,MAAK;KACL,eAAe,aAAa,KAAK;KACjC,iBAAe,aAAa,SAAS;KACrC,kBAAgB,mBAAmB,SAAS;KAC5C,UAAU,YAAY;KACtB,UAAU,aAAa,IAAI;KAC3B,MAAM,OAAO;MACX,YAAY,QAAQ,SAAS;KAC/B;KACA,oBAAoB,CAAC,YAAY,gBAAgB,KAAK;KACtD,oBAAoB,CAAC,YAAY,gBAAgB,IAAI;IAG/C,GADL,OACK;GAEZ,CAAC,GAEA,2BACC,oBAAC,OAAD;IACE,WAAW,GACT,yBAAyB,EACvB,MACF,CAAC,CACH;IACA,OAAO;IACP,KAAK;GACN,EAEA;;CACF;AAET"}
1
+ {"version":3,"file":"VerticalSwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/VerticalSwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n defaultChoices,\n type SwitchSelectorBaseProps,\n type SwitchSelectorChoices,\n} from './SwitchSelector';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nconst verticalSwitchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-col gap-2 rounded-2xl border-[1.3px] p-1',\n {\n variants: {\n color: {\n [`${'error'}`]: 'border-error bg-error text-error',\n neutral: 'border-neutral text-neutral',\n light: 'border-white text-white',\n dark: 'border-neutral-800 text-neutral-800',\n text: 'border-text text-foreground',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: `${'text'}`,\n disabled: false,\n },\n }\n);\n\nconst verticalChoiceVariant = cva(\n 'z-1 w-full cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-foreground-opposite motion-reduce:transition-none',\n {\n variants: {\n size: {\n sm: 'px-2 py-1 text-xs',\n md: 'p-2 text-sm',\n lg: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: `${'md'}`,\n },\n }\n);\n\nconst verticalIndicatorVariant = cva(\n 'absolute left-0 z-0 h-auto w-full rounded-xl transition-all duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n [`${'error'}`]: 'bg-error data-[indicator=true]:text-foreground',\n neutral: 'bg-neutral data-[indicator=true]:text-white',\n light: 'bg-white data-[indicator=true]:text-black',\n dark: 'bg-neutral-800 data-[indicator=true]:text-white',\n text: 'bg-text data-[indicator=true]:text-foreground-opposite',\n },\n },\n }\n);\n\nexport type VerticalSwitchSelectorProps<T = boolean> =\n SwitchSelectorBaseProps<T> &\n VariantProps<typeof verticalSwitchSelectorVariant> &\n VariantProps<typeof verticalChoiceVariant>;\n\n/**\n * Component that allows the user to select one of the provided choices.\n * This component is vertical.\n */\nexport const VerticalSwitchSelector = <T,>(\n props: VerticalSwitchSelectorProps<T>\n) => {\n const {\n choices = defaultChoices as SwitchSelectorChoices<T>,\n color = 'text',\n size = 'md',\n className,\n itemClassName,\n } = props;\n\n const {\n selectedIndex,\n indicatorIndex,\n handleChange,\n optionsRefs,\n indicatorRef,\n choiceIndicatorPosition,\n setHoveredIndex,\n disabled,\n } = useSwitchSelector(\n {\n choices,\n value: props.value,\n defaultValue: props.defaultValue,\n onChange: props.onChange,\n hoverable: props.hoverable,\n disabled: props.disabled,\n },\n 'vertical'\n );\n\n return (\n <div\n className={verticalSwitchSelectorVariant({\n color,\n disabled,\n className,\n })}\n role=\"tablist\"\n aria-disabled={disabled ? 'true' : undefined}\n >\n <div className=\"relative flex h-fit w-full flex-col items-center justify-center\">\n {choices.map((choice, index) => {\n const { content, value, ...buttonProps } = choice;\n\n const isKeyOfKey =\n typeof value === 'string' || typeof value === 'number';\n\n const isSelected = index === selectedIndex;\n const isIndicatorOwner = index === indicatorIndex;\n\n return (\n <button\n {...buttonProps}\n className={cn(\n verticalChoiceVariant({\n size,\n }),\n disabled && 'cursor-not-allowed',\n itemClassName\n )}\n key={isKeyOfKey ? value : index}\n role=\"tab\"\n onClick={() => handleChange(value)}\n aria-selected={isSelected ? 'true' : undefined}\n data-indicator={isIndicatorOwner ? 'true' : undefined}\n disabled={disabled || isSelected}\n tabIndex={isSelected ? 0 : -1}\n ref={(el) => {\n optionsRefs.current[index] = el!;\n }}\n onMouseEnter={() => !disabled && setHoveredIndex(index)}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {content}\n </button>\n );\n })}\n\n {choiceIndicatorPosition && (\n <div\n className={cn(\n verticalIndicatorVariant({\n color,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAWA,MAAM,gCAAgC,IACpC,iFACA;CACE,UAAU;EACR,OAAO;IACJ,UAAe;GAChB,SAAS;GACT,OAAO;GACP,MAAM;GACN,MAAM;EACR;EACA,UAAU;GACR,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,OAAO;EACP,UAAU;CACZ;AACF,CACF;AAEA,MAAM,wBAAwB,IAC5B,mMACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AAEA,MAAM,2BAA2B,IAC/B,sHACA,EACE,UAAU,EACR,OAAO;EACJ,UAAe;CAChB,SAAS;CACT,OAAO;CACP,MAAM;CACN,MAAM;AACR,EACF,EACF,CACF;;;;;AAWA,MAAa,0BACX,UACG;CACH,MAAM,EACJ,UAAU,gBACV,QAAQ,QACR,OAAO,MACP,WACA,kBACE;CAEJ,MAAM,EACJ,eACA,gBACA,cACA,aACA,cACA,yBACA,iBACA,aACE,kBACF;EACE;EACA,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,UAAU,MAAM;CAClB,GACA,UACF;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,8BAA8B;GACvC;GACA;GACA;EACF,CAAC;EACD,MAAK;EACL,iBAAe,WAAW,SAAS;YAEnC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,EAAE,SAAS,OAAO,GAAG,gBAAgB;IAE3C,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,UAAU;IAEhD,MAAM,aAAa,UAAU;IAC7B,MAAM,mBAAmB,UAAU;IAEnC,OACE,8BAAC,UAAD;KACE,GAAI;KACJ,WAAW,GACT,sBAAsB,EACpB,KACF,CAAC,GACD,YAAY,sBACZ,aACF;KACA,KAAK,aAAa,QAAQ;KAC1B,MAAK;KACL,eAAe,aAAa,KAAK;KACjC,iBAAe,aAAa,SAAS;KACrC,kBAAgB,mBAAmB,SAAS;KAC5C,UAAU,YAAY;KACtB,UAAU,aAAa,IAAI;KAC3B,MAAM,OAAO;MACX,YAAY,QAAQ,SAAS;KAC/B;KACA,oBAAoB,CAAC,YAAY,gBAAgB,KAAK;KACtD,oBAAoB,CAAC,YAAY,gBAAgB,IAAI;IAG/C,GADL,OACK;GAEZ,CAAC,GAEA,2BACC,oBAAC,OAAD;IACE,WAAW,GACT,yBAAyB,EACvB,MACF,CAAC,CACH;IACA,OAAO;IACP,KAAK;GACN,EAEA;;CACF;AAET"}
@@ -9,21 +9,17 @@ import { cva } from "class-variance-authority";
9
9
  //#region src/components/TabSelector/TabSelector.tsx
10
10
  const tabSelectorVariant = cva("relative z-0 flex size-full flex-row items-center gap-2", {
11
11
  variants: { color: {
12
- primary: "border-primary text-primary",
13
- secondary: "border-secondary text-secondary",
14
12
  error: "border-error bg-error text-error",
15
13
  neutral: "border-neutral text-neutral",
16
14
  light: "border-white text-white",
17
15
  dark: "border-neutral-800 text-neutral-800",
18
16
  text: "border-text text-foreground"
19
17
  } },
20
- defaultVariants: { color: "primary" }
18
+ defaultVariants: { color: "text" }
21
19
  });
22
20
  const indicatorVariant = cva("absolute -z-1 rounded-lg duration-300 ease-in-out motion-reduce:transition-none", {
23
21
  variants: {
24
22
  color: {
25
- primary: "bg-primary/10 aria-selected:text-foreground",
26
- secondary: "bg-secondary/10 aria-selected:text-foreground",
27
23
  error: "bg-error/10 aria-selected:text-foreground",
28
24
  neutral: "bg-neutral/10 aria-selected:text-white/10",
29
25
  light: "bg-white/10 aria-selected:text-black",
@@ -54,7 +50,7 @@ const indicatorVariant = cva("absolute -z-1 rounded-lg duration-300 ease-in-out
54
50
  * </TabSelector>
55
51
  * ```
56
52
  */
57
- const TabSelector = ({ tabs, selectedChoice, onTabClick, color = "primary", hoverable = false, orientation = "horizontal", className }) => {
53
+ const TabSelector = ({ tabs, selectedChoice, onTabClick, color = "text", hoverable = false, orientation = "horizontal", className }) => {
58
54
  const optionsRefs = useRef([]);
59
55
  const indicatorRef = useRef(null);
60
56
  const { choiceIndicatorPosition, scheduleMeasurement } = useItemSelector(optionsRefs, {
@@ -1 +1 @@
1
- {"version":3,"file":"TabSelector.mjs","names":[],"sources":["../../../../src/components/TabSelector/TabSelector.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ItemSelectorOrientation,\n useItemSelector,\n} from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n cloneElement,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n useEffect,\n useRef,\n} from 'react';\n\nexport type TabSelectorColor =\n | 'primary'\n | 'secondary'\n | 'error'\n | 'neutral'\n | 'light'\n | 'dark'\n | 'text';\n\nconst tabSelectorVariant = cva(\n 'relative z-0 flex size-full flex-row items-center gap-2',\n {\n variants: {\n color: {\n primary: 'border-primary text-primary',\n secondary: 'border-secondary text-secondary',\n error: 'border-error bg-error text-error',\n neutral: 'border-neutral text-neutral',\n light: 'border-white text-white',\n dark: 'border-neutral-800 text-neutral-800',\n text: 'border-text text-foreground',\n },\n },\n defaultVariants: {\n color: 'primary',\n },\n }\n);\n\nconst indicatorVariant = cva(\n 'absolute -z-1 rounded-lg duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n primary: 'bg-primary/10 aria-selected:text-foreground',\n secondary: 'bg-secondary/10 aria-selected:text-foreground',\n error: 'bg-error/10 aria-selected:text-foreground',\n neutral: 'bg-neutral/10 aria-selected:text-white/10',\n light: 'bg-white/10 aria-selected:text-black',\n dark: 'bg-neutral-800/10 aria-selected:text-white',\n text: 'bg-text/10 aria-selected:text-foreground-opposite',\n },\n orientation: {\n horizontal: 'top-0 h-full w-auto transition-[left,width]',\n vertical: 'left-0 h-auto w-full transition-[top,height]',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\nexport type TabSelectorItemProps = HTMLAttributes<HTMLElement> & {\n key: string | number;\n};\n\nexport type TabSelectorProps<T extends TabSelectorItemProps> = {\n tabs: ReactElement<T>[];\n selectedChoice: T['key'];\n onTabClick?: (choice: T['key']) => void;\n hoverable?: boolean;\n orientation?: ItemSelectorOrientation;\n} & HTMLAttributes<HTMLElement> &\n Omit<VariantProps<typeof tabSelectorVariant>, 'color'> & {\n color?: TabSelectorColor | `${TabSelectorColor}`;\n };\n\n/**\n *\n * Component that allows the user to select one of the provided choices.\n *\n * Example:\n * ```jsx\n * <TabSelector\n * selectedChoice=\"option1\"\n * onTabClick={(choice) => console.log(choice)}\n * hoverable={true}\n * >\n * <Button key=\"option1\"/>\n * <Button key=\"option2\"/>\n * <Button key=\"option3\"/>\n * </TabSelector>\n * ```\n */\nexport const TabSelector = <T extends TabSelectorItemProps>({\n tabs,\n selectedChoice,\n onTabClick,\n color = 'primary',\n hoverable = false,\n orientation = 'horizontal',\n className,\n}: TabSelectorProps<T>) => {\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, scheduleMeasurement } = useItemSelector(\n optionsRefs,\n { isHoverable: hoverable, orientation }\n );\n\n useEffect(() => {\n scheduleMeasurement();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedChoice]);\n\n return (\n <div\n className={cn(\n tabSelectorVariant({\n color,\n }),\n className\n )}\n aria-orientation={orientation}\n aria-multiselectable=\"false\"\n role=\"tablist\"\n >\n {tabs.map((Tab, index) => {\n const key = Tab.key!;\n\n const isSelected = selectedChoice === key;\n\n return cloneElement(Tab, {\n key: key ?? index,\n role: 'tab',\n onClick: (e: MouseEvent<HTMLElement>) => {\n Tab.props?.onClick?.(e);\n onTabClick?.(key);\n },\n 'aria-selected': isSelected,\n 'data-active': isSelected as unknown as string,\n tabIndex: isSelected ? 0 : -1,\n ref: (el: HTMLElement) => {\n optionsRefs.current[index] = el!;\n },\n } as unknown as T);\n })}\n {choiceIndicatorPosition && (\n <div\n className={cn(\n indicatorVariant({\n color,\n orientation,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n key={`${selectedChoice}${JSON.stringify(tabs.map((tab) => tab.key))}`}\n />\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;AA0BA,MAAM,qBAAqB,IACzB,2DACA;CACE,UAAU,EACR,OAAO;EACL,SAAS;EACT,WAAW;EACX,OAAO;EACP,SAAS;EACT,OAAO;EACP,MAAM;EACN,MAAM;CACR,EACF;CACA,iBAAiB,EACf,OAAO,UACT;AACF,CACF;AAEA,MAAM,mBAAmB,IACvB,mFACA;CACE,UAAU;EACR,OAAO;GACL,SAAS;GACT,WAAW;GACX,OAAO;GACP,SAAS;GACT,OAAO;GACP,MAAM;GACN,MAAM;EACR;EACA,aAAa;GACX,YAAY;GACZ,UAAU;EACZ;CACF;CACA,iBAAiB,EACf,aAAa,aACf;AACF,CACF;;;;;;;;;;;;;;;;;;AAkCA,MAAa,eAA+C,EAC1D,MACA,gBACA,YACA,QAAQ,WACR,YAAY,OACZ,cAAc,cACd,gBACyB;CACzB,MAAM,cAAc,OAAsB,CAAC,CAAC;CAC5C,MAAM,eAAe,OAA8B,IAAI;CACvD,MAAM,EAAE,yBAAyB,wBAAwB,gBACvD,aACA;EAAE,aAAa;EAAW;CAAY,CACxC;CAEA,gBAAgB;EACd,oBAAoB;CAEtB,GAAG,CAAC,cAAc,CAAC;CAEnB,OACE,qBAAC,OAAD;EACE,WAAW,GACT,mBAAmB,EACjB,MACF,CAAC,GACD,SACF;EACA,oBAAkB;EAClB,wBAAqB;EACrB,MAAK;YATP,CAWG,KAAK,KAAK,KAAK,UAAU;GACxB,MAAM,MAAM,IAAI;GAEhB,MAAM,aAAa,mBAAmB;GAEtC,OAAO,aAAa,KAAK;IACvB,KAAK,OAAO;IACZ,MAAM;IACN,UAAU,MAA+B;KACvC,IAAI,OAAO,UAAU,CAAC;KACtB,aAAa,GAAG;IAClB;IACA,iBAAiB;IACjB,eAAe;IACf,UAAU,aAAa,IAAI;IAC3B,MAAM,OAAoB;KACxB,YAAY,QAAQ,SAAS;IAC/B;GACF,CAAiB;EACnB,CAAC,GACA,2BACC,oBAAC,OAAD;GACE,WAAW,GACT,iBAAiB;IACf;IACA;GACF,CAAC,CACH;GACA,OAAO;GACP,KAAK;EAEN,GADM,GAAG,iBAAiB,KAAK,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,GACnE,CAEA;;AAET"}
1
+ {"version":3,"file":"TabSelector.mjs","names":[],"sources":["../../../../src/components/TabSelector/TabSelector.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ItemSelectorOrientation,\n useItemSelector,\n} from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n cloneElement,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n useEffect,\n useRef,\n} from 'react';\n\nexport type TabSelectorColor = 'error' | 'neutral' | 'light' | 'dark' | 'text';\n\nconst tabSelectorVariant = cva(\n 'relative z-0 flex size-full flex-row items-center gap-2',\n {\n variants: {\n color: {\n error: 'border-error bg-error text-error',\n neutral: 'border-neutral text-neutral',\n light: 'border-white text-white',\n dark: 'border-neutral-800 text-neutral-800',\n text: 'border-text text-foreground',\n },\n },\n defaultVariants: {\n color: 'text',\n },\n }\n);\n\nconst indicatorVariant = cva(\n 'absolute -z-1 rounded-lg duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n error: 'bg-error/10 aria-selected:text-foreground',\n neutral: 'bg-neutral/10 aria-selected:text-white/10',\n light: 'bg-white/10 aria-selected:text-black',\n dark: 'bg-neutral-800/10 aria-selected:text-white',\n text: 'bg-text/10 aria-selected:text-foreground-opposite',\n },\n orientation: {\n horizontal: 'top-0 h-full w-auto transition-[left,width]',\n vertical: 'left-0 h-auto w-full transition-[top,height]',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\nexport type TabSelectorItemProps = HTMLAttributes<HTMLElement> & {\n key: string | number;\n};\n\nexport type TabSelectorProps<T extends TabSelectorItemProps> = {\n tabs: ReactElement<T>[];\n selectedChoice: T['key'];\n onTabClick?: (choice: T['key']) => void;\n hoverable?: boolean;\n orientation?: ItemSelectorOrientation;\n} & HTMLAttributes<HTMLElement> &\n Omit<VariantProps<typeof tabSelectorVariant>, 'color'> & {\n color?: TabSelectorColor | `${TabSelectorColor}`;\n };\n\n/**\n *\n * Component that allows the user to select one of the provided choices.\n *\n * Example:\n * ```jsx\n * <TabSelector\n * selectedChoice=\"option1\"\n * onTabClick={(choice) => console.log(choice)}\n * hoverable={true}\n * >\n * <Button key=\"option1\"/>\n * <Button key=\"option2\"/>\n * <Button key=\"option3\"/>\n * </TabSelector>\n * ```\n */\nexport const TabSelector = <T extends TabSelectorItemProps>({\n tabs,\n selectedChoice,\n onTabClick,\n color = 'text',\n hoverable = false,\n orientation = 'horizontal',\n className,\n}: TabSelectorProps<T>) => {\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, scheduleMeasurement } = useItemSelector(\n optionsRefs,\n { isHoverable: hoverable, orientation }\n );\n\n useEffect(() => {\n scheduleMeasurement();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedChoice]);\n\n return (\n <div\n className={cn(\n tabSelectorVariant({\n color,\n }),\n className\n )}\n aria-orientation={orientation}\n aria-multiselectable=\"false\"\n role=\"tablist\"\n >\n {tabs.map((Tab, index) => {\n const key = Tab.key!;\n\n const isSelected = selectedChoice === key;\n\n return cloneElement(Tab, {\n key: key ?? index,\n role: 'tab',\n onClick: (e: MouseEvent<HTMLElement>) => {\n Tab.props?.onClick?.(e);\n onTabClick?.(key);\n },\n 'aria-selected': isSelected,\n 'data-active': isSelected as unknown as string,\n tabIndex: isSelected ? 0 : -1,\n ref: (el: HTMLElement) => {\n optionsRefs.current[index] = el!;\n },\n } as unknown as T);\n })}\n {choiceIndicatorPosition && (\n <div\n className={cn(\n indicatorVariant({\n color,\n orientation,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n key={`${selectedChoice}${JSON.stringify(tabs.map((tab) => tab.key))}`}\n />\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;AAmBA,MAAM,qBAAqB,IACzB,2DACA;CACE,UAAU,EACR,OAAO;EACL,OAAO;EACP,SAAS;EACT,OAAO;EACP,MAAM;EACN,MAAM;CACR,EACF;CACA,iBAAiB,EACf,OAAO,OACT;AACF,CACF;AAEA,MAAM,mBAAmB,IACvB,mFACA;CACE,UAAU;EACR,OAAO;GACL,OAAO;GACP,SAAS;GACT,OAAO;GACP,MAAM;GACN,MAAM;EACR;EACA,aAAa;GACX,YAAY;GACZ,UAAU;EACZ;CACF;CACA,iBAAiB,EACf,aAAa,aACf;AACF,CACF;;;;;;;;;;;;;;;;;;AAkCA,MAAa,eAA+C,EAC1D,MACA,gBACA,YACA,QAAQ,QACR,YAAY,OACZ,cAAc,cACd,gBACyB;CACzB,MAAM,cAAc,OAAsB,CAAC,CAAC;CAC5C,MAAM,eAAe,OAA8B,IAAI;CACvD,MAAM,EAAE,yBAAyB,wBAAwB,gBACvD,aACA;EAAE,aAAa;EAAW;CAAY,CACxC;CAEA,gBAAgB;EACd,oBAAoB;CAEtB,GAAG,CAAC,cAAc,CAAC;CAEnB,OACE,qBAAC,OAAD;EACE,WAAW,GACT,mBAAmB,EACjB,MACF,CAAC,GACD,SACF;EACA,oBAAkB;EAClB,wBAAqB;EACrB,MAAK;YATP,CAWG,KAAK,KAAK,KAAK,UAAU;GACxB,MAAM,MAAM,IAAI;GAEhB,MAAM,aAAa,mBAAmB;GAEtC,OAAO,aAAa,KAAK;IACvB,KAAK,OAAO;IACZ,MAAM;IACN,UAAU,MAA+B;KACvC,IAAI,OAAO,UAAU,CAAC;KACtB,aAAa,GAAG;IAClB;IACA,iBAAiB;IACjB,eAAe;IACf,UAAU,aAAa,IAAI;IAC3B,MAAM,OAAoB;KACxB,YAAY,QAAQ,SAAS;IAC/B;GACF,CAAiB;EACnB,CAAC,GACA,2BACC,oBAAC,OAAD;GACE,WAAW,GACT,iBAAiB;IACf;IACA;GACF,CAAC,CACH;GACA,OAAO;GACP,KAAK;EAEN,GADM,GAAG,iBAAiB,KAAK,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,GACnE,CAEA;;AAET"}
@@ -5,7 +5,7 @@ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/Table/Table.tsx
6
6
  const Table = forwardRef(({ className, isInteractive, ...props }, ref) => /* @__PURE__ */ jsx("table", {
7
7
  ref,
8
- className: cn("w-full table-auto border-separate border-spacing-0 overflow-hidden rounded-2xl text-left text-sm", "[&_thead_tr:first-child_th:first-child]:rounded-tl-2xl", "[&_thead_tr:first-child_th:last-child]:rounded-tr-2xl", "[&_tbody_tr:last-child_td:first-child]:rounded-bl-2xl", "[&_tbody_tr:last-child_td:last-child]:rounded-br-2xl", "supports-[corner-shape:squircle]:rounded-3xl", "supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:first-child]:rounded-tl-3xl", "supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:last-child]:rounded-tr-3xl", "supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:first-child]:rounded-bl-3xl", "supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:last-child]:rounded-br-3xl", isInteractive && "[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr:hover]:dark:bg-neutral-dark/40 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:transition-colors", className),
8
+ className: cn("w-full table-auto border-separate border-spacing-0 overflow-hidden rounded-2xl text-left text-sm", "[&_thead_tr:first-child_th:first-child]:rounded-tl-2xl", "[&_thead_tr:first-child_th:last-child]:rounded-tr-2xl", "[&_tbody_tr:last-child_td:first-child]:rounded-bl-2xl", "[&_tbody_tr:last-child_td:last-child]:rounded-br-2xl", "supports-[corner-shape:squircle]:rounded-3xl", "supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:first-child]:rounded-tl-3xl", "supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:last-child]:rounded-tr-3xl", "supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:first-child]:rounded-bl-3xl", "supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:last-child]:rounded-br-3xl", isInteractive && "[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:transition-colors", className),
9
9
  ...props
10
10
  }));
11
11
 
@@ -1 +1 @@
1
- {"version":3,"file":"Table.mjs","names":[],"sources":["../../../../src/components/Table/Table.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { forwardRef, type HTMLAttributes } from 'react';\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Enables hover states and cursor changes for interactive rows */\n isInteractive?: boolean;\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(\n ({ className, isInteractive, ...props }, ref) => (\n <table\n ref={ref}\n className={cn(\n 'w-full table-auto border-separate border-spacing-0 overflow-hidden rounded-2xl text-left text-sm',\n '[&_thead_tr:first-child_th:first-child]:rounded-tl-2xl',\n '[&_thead_tr:first-child_th:last-child]:rounded-tr-2xl',\n '[&_tbody_tr:last-child_td:first-child]:rounded-bl-2xl',\n '[&_tbody_tr:last-child_td:last-child]:rounded-br-2xl',\n 'supports-[corner-shape:squircle]:rounded-3xl',\n 'supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:first-child]:rounded-tl-3xl',\n 'supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:last-child]:rounded-tr-3xl',\n 'supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:first-child]:rounded-bl-3xl',\n 'supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:last-child]:rounded-br-3xl',\n isInteractive &&\n '[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr:hover]:dark:bg-neutral-dark/40 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:transition-colors',\n className\n )}\n {...props}\n />\n )\n);\n"],"mappings":";;;;;AAQA,MAAa,QAAQ,YAClB,EAAE,WAAW,eAAe,GAAG,SAAS,QACvC,oBAAC,SAAD;CACO;CACL,WAAW,GACT,oGACA,0DACA,yDACA,yDACA,wDACA,gDACA,2FACA,0FACA,0FACA,yFACA,iBACE,0IACF,SACF;CACA,GAAI;AACL,EAEL"}
1
+ {"version":3,"file":"Table.mjs","names":[],"sources":["../../../../src/components/Table/Table.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { forwardRef, type HTMLAttributes } from 'react';\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Enables hover states and cursor changes for interactive rows */\n isInteractive?: boolean;\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(\n ({ className, isInteractive, ...props }, ref) => (\n <table\n ref={ref}\n className={cn(\n 'w-full table-auto border-separate border-spacing-0 overflow-hidden rounded-2xl text-left text-sm',\n '[&_thead_tr:first-child_th:first-child]:rounded-tl-2xl',\n '[&_thead_tr:first-child_th:last-child]:rounded-tr-2xl',\n '[&_tbody_tr:last-child_td:first-child]:rounded-bl-2xl',\n '[&_tbody_tr:last-child_td:last-child]:rounded-br-2xl',\n 'supports-[corner-shape:squircle]:rounded-3xl',\n 'supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:first-child]:rounded-tl-3xl',\n 'supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:last-child]:rounded-tr-3xl',\n 'supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:first-child]:rounded-bl-3xl',\n 'supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:last-child]:rounded-br-3xl',\n isInteractive &&\n '[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:transition-colors',\n className\n )}\n {...props}\n />\n )\n);\n"],"mappings":";;;;;AAQA,MAAa,QAAQ,YAClB,EAAE,WAAW,eAAe,GAAG,SAAS,QACvC,oBAAC,SAAD;CACO;CACL,WAAW,GACT,oGACA,0DACA,yDACA,yDACA,wDACA,gDACA,2FACA,0FACA,0FACA,yFACA,iBACE,+FACF,SACF;CACA,GAAI;AACL,EAEL"}
@@ -15,7 +15,6 @@ const containerVariants = cva("w-fit backdrop-blur", {
15
15
  full: "rounded-full"
16
16
  },
17
17
  color: {
18
- primary: "border-primary bg-primary/10 text-primary",
19
18
  success: "border-success bg-success/10 text-success",
20
19
  error: "border-error bg-error/10 text-error",
21
20
  warning: "border-warning bg-warning/10 text-warning",