@intlayer/design-system 7.4.0 → 7.5.0-canary.1

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 (162) hide show
  1. package/dist/esm/components/Avatar/index.mjs +11 -28
  2. package/dist/esm/components/Avatar/index.mjs.map +1 -1
  3. package/dist/esm/components/Badge/index.mjs +1 -1
  4. package/dist/esm/components/Badge/index.mjs.map +1 -1
  5. package/dist/esm/components/Breadcrumb/index.mjs +1 -0
  6. package/dist/esm/components/Breadcrumb/index.mjs.map +1 -1
  7. package/dist/esm/components/Button/Button.mjs +20 -15
  8. package/dist/esm/components/Button/Button.mjs.map +1 -1
  9. package/dist/esm/components/Container/index.mjs +7 -4
  10. package/dist/esm/components/Container/index.mjs.map +1 -1
  11. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +2 -4
  12. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs.map +1 -1
  13. package/dist/esm/components/DropDown/index.mjs +6 -2
  14. package/dist/esm/components/DropDown/index.mjs.map +1 -1
  15. package/dist/esm/components/Form/elements/CheckboxElement.mjs +8 -4
  16. package/dist/esm/components/Form/elements/CheckboxElement.mjs.map +1 -1
  17. package/dist/esm/components/Form/elements/OTPElement.mjs +1 -5
  18. package/dist/esm/components/Form/elements/OTPElement.mjs.map +1 -1
  19. package/dist/esm/components/IDE/CodeBlockClient.mjs +1 -1
  20. package/dist/esm/components/IDE/CodeBlockClient.mjs.map +1 -1
  21. package/dist/esm/components/IDE/CodeBlockShiki.mjs +1 -0
  22. package/dist/esm/components/IDE/CodeBlockShiki.mjs.map +1 -1
  23. package/dist/esm/components/Input/Input.mjs.map +1 -1
  24. package/dist/esm/components/Input/OTPInput.mjs +1 -2
  25. package/dist/esm/components/Input/OTPInput.mjs.map +1 -1
  26. package/dist/esm/components/KeyboardShortcut/KeyboardShortcut.mjs +225 -0
  27. package/dist/esm/components/KeyboardShortcut/KeyboardShortcut.mjs.map +1 -0
  28. package/dist/esm/components/KeyboardShortcut/index.mjs +3 -0
  29. package/dist/esm/components/Link/Link.mjs +123 -93
  30. package/dist/esm/components/Link/Link.mjs.map +1 -1
  31. package/dist/esm/components/Link/index.mjs +2 -2
  32. package/dist/esm/components/Navbar/DesktopNavbar.mjs +1 -1
  33. package/dist/esm/components/Navbar/DesktopNavbar.mjs.map +1 -1
  34. package/dist/esm/components/Pagination/Pagination.mjs +83 -43
  35. package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
  36. package/dist/esm/components/Popover/static.mjs +3 -6
  37. package/dist/esm/components/Popover/static.mjs.map +1 -1
  38. package/dist/esm/components/SwitchSelector/index.mjs +2 -2
  39. package/dist/esm/components/SwitchSelector/index.mjs.map +1 -1
  40. package/dist/esm/components/Tag/index.mjs +2 -2
  41. package/dist/esm/components/Tag/index.mjs.map +1 -1
  42. package/dist/esm/components/Terminal/Terminal.mjs +4 -1
  43. package/dist/esm/components/Terminal/Terminal.mjs.map +1 -1
  44. package/dist/esm/components/Terminal/terminal.content.mjs +51 -0
  45. package/dist/esm/components/Terminal/terminal.content.mjs.map +1 -0
  46. package/dist/esm/components/index.mjs +3 -2
  47. package/dist/esm/hooks/index.mjs +2 -2
  48. package/dist/esm/hooks/reactQuery.mjs +8 -1
  49. package/dist/esm/hooks/reactQuery.mjs.map +1 -1
  50. package/dist/esm/hooks/useItemSelector.mjs +51 -28
  51. package/dist/esm/hooks/useItemSelector.mjs.map +1 -1
  52. package/dist/esm/libs/auth.mjs +9 -3
  53. package/dist/esm/libs/auth.mjs.map +1 -1
  54. package/dist/types/components/Avatar/index.d.ts.map +1 -1
  55. package/dist/types/components/Badge/index.d.ts.map +1 -1
  56. package/dist/types/components/Breadcrumb/breadcrumb.content.d.ts +3 -3
  57. package/dist/types/components/Breadcrumb/breadcrumb.content.d.ts.map +1 -1
  58. package/dist/types/components/Breadcrumb/index.d.ts.map +1 -1
  59. package/dist/types/components/Button/Button.d.ts +1 -1
  60. package/dist/types/components/Button/Button.d.ts.map +1 -1
  61. package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +2 -2
  62. package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts.map +1 -1
  63. package/dist/types/components/Command/index.d.ts +17 -17
  64. package/dist/types/components/Command/index.d.ts.map +1 -1
  65. package/dist/types/components/Container/index.d.ts +10 -8
  66. package/dist/types/components/Container/index.d.ts.map +1 -1
  67. package/dist/types/components/CopyButton/CopyButton.content.d.ts +3 -3
  68. package/dist/types/components/CopyButton/CopyButton.content.d.ts.map +1 -1
  69. package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/dictionaryCreationForm.content.d.ts +25 -25
  70. package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/useDictionaryFormSchema.content.d.ts +9 -9
  71. package/dist/types/components/DictionaryFieldEditor/DictionaryDetails/dictionaryDetails.content.d.ts +33 -33
  72. package/dist/types/components/DictionaryFieldEditor/DictionaryDetails/useDictionaryDetailsSchema.content.d.ts +25 -25
  73. package/dist/types/components/DictionaryFieldEditor/DictionaryFieldEditor.d.ts.map +1 -1
  74. package/dist/types/components/DictionaryFieldEditor/NavigationView/navigationViewNode.content.d.ts +25 -25
  75. package/dist/types/components/DictionaryFieldEditor/SaveForm/saveForm.content.d.ts +33 -33
  76. package/dist/types/components/DictionaryFieldEditor/StructureView/structureView.content.d.ts +9 -9
  77. package/dist/types/components/DictionaryFieldEditor/VersionSwitcherDropDown/versionSwitcherDropDown.content.d.ts +7 -7
  78. package/dist/types/components/DictionaryFieldEditor/VersionSwitcherDropDown/versionSwitcherDropDown.content.d.ts.map +1 -1
  79. package/dist/types/components/DictionaryFieldEditor/dictionaryFieldEditor.content.d.ts +5 -5
  80. package/dist/types/components/DictionaryFieldEditor/nodeTypeSelector.content.d.ts +31 -31
  81. package/dist/types/components/DictionaryFieldEditor/nodeTypeSelector.content.d.ts.map +1 -1
  82. package/dist/types/components/ExpandCollapse/expandCollapse.content.d.ts +3 -3
  83. package/dist/types/components/Form/FormBase.d.ts +2 -2
  84. package/dist/types/components/Form/FormField.d.ts +2 -2
  85. package/dist/types/components/Form/FormItem.d.ts +2 -2
  86. package/dist/types/components/Form/FormItem.d.ts.map +1 -1
  87. package/dist/types/components/Form/elements/CheckboxElement.d.ts.map +1 -1
  88. package/dist/types/components/Form/elements/EditableFieldInputElement.d.ts +2 -2
  89. package/dist/types/components/Form/elements/EditableFieldTextAreaElement.d.ts +2 -2
  90. package/dist/types/components/Form/elements/FormElement.d.ts +2 -2
  91. package/dist/types/components/Form/elements/MultiselectElement.d.ts +2 -2
  92. package/dist/types/components/Form/elements/OTPElement.d.ts.map +1 -1
  93. package/dist/types/components/Form/elements/SelectElement.d.ts +2 -2
  94. package/dist/types/components/Form/elements/SwitchSelectorElement.d.ts +2 -2
  95. package/dist/types/components/IDE/CodeBlockShiki.d.ts.map +1 -1
  96. package/dist/types/components/IDE/CodeContext.d.ts +2 -2
  97. package/dist/types/components/IDE/FileTree.d.ts.map +1 -1
  98. package/dist/types/components/IDE/code.content.d.ts +5 -5
  99. package/dist/types/components/IDE/code.content.d.ts.map +1 -1
  100. package/dist/types/components/IDE/copyCode.content.d.ts +5 -5
  101. package/dist/types/components/IDE/copyCode.content.d.ts.map +1 -1
  102. package/dist/types/components/Input/Checkbox.d.ts +3 -3
  103. package/dist/types/components/Input/Checkbox.d.ts.map +1 -1
  104. package/dist/types/components/Input/Input.d.ts +3 -3
  105. package/dist/types/components/Input/Input.d.ts.map +1 -1
  106. package/dist/types/components/Input/OTPInput.d.ts +7 -9
  107. package/dist/types/components/Input/OTPInput.d.ts.map +1 -1
  108. package/dist/types/components/Input/SearchInput.d.ts +2 -2
  109. package/dist/types/components/KeyboardShortcut/KeyboardShortcut.d.ts +90 -0
  110. package/dist/types/components/KeyboardShortcut/KeyboardShortcut.d.ts.map +1 -0
  111. package/dist/types/components/KeyboardShortcut/index.d.ts +2 -0
  112. package/dist/types/components/Link/Link.d.ts +25 -88
  113. package/dist/types/components/Link/Link.d.ts.map +1 -1
  114. package/dist/types/components/Link/index.d.ts +2 -2
  115. package/dist/types/components/Loader/index.content.d.ts +3 -3
  116. package/dist/types/components/Loader/index.content.d.ts.map +1 -1
  117. package/dist/types/components/Loader/spinner.d.ts +2 -2
  118. package/dist/types/components/Loader/spinner.d.ts.map +1 -1
  119. package/dist/types/components/LocaleSwitcherContentDropDown/localeSwitcher.content.d.ts +17 -17
  120. package/dist/types/components/LocaleSwitcherContentDropDown/localeSwitcher.content.d.ts.map +1 -1
  121. package/dist/types/components/LocaleSwitcherDropDown/localeSwitcher.content.d.ts +13 -13
  122. package/dist/types/components/LocaleSwitcherDropDown/localeSwitcher.content.d.ts.map +1 -1
  123. package/dist/types/components/MaxWidthSmoother/index.d.ts +2 -2
  124. package/dist/types/components/MaxWidthSmoother/index.d.ts.map +1 -1
  125. package/dist/types/components/Navbar/Burger.d.ts +2 -2
  126. package/dist/types/components/Navbar/Burger.d.ts.map +1 -1
  127. package/dist/types/components/Navbar/DesktopNavbar.d.ts +2 -2
  128. package/dist/types/components/Navbar/MobileNavbar.d.ts +2 -2
  129. package/dist/types/components/Navbar/MobileNavbar.d.ts.map +1 -1
  130. package/dist/types/components/Navbar/index.d.ts +2 -2
  131. package/dist/types/components/Navbar/index.d.ts.map +1 -1
  132. package/dist/types/components/Pagination/Pagination.d.ts +3 -3
  133. package/dist/types/components/Pagination/Pagination.d.ts.map +1 -1
  134. package/dist/types/components/Pagination/pagination.content.d.ts +11 -11
  135. package/dist/types/components/Popover/static.d.ts +1 -17
  136. package/dist/types/components/Popover/static.d.ts.map +1 -1
  137. package/dist/types/components/Select/Select.d.ts +3 -3
  138. package/dist/types/components/SocialNetworks/index.d.ts +2 -2
  139. package/dist/types/components/SocialNetworks/index.d.ts.map +1 -1
  140. package/dist/types/components/SwitchSelector/index.d.ts +5 -5
  141. package/dist/types/components/SwitchSelector/index.d.ts.map +1 -1
  142. package/dist/types/components/Tab/Tab.d.ts +6 -6
  143. package/dist/types/components/Tab/Tab.d.ts.map +1 -1
  144. package/dist/types/components/Tab/TabContext.d.ts +2 -2
  145. package/dist/types/components/TabSelector/TabSelector.d.ts +4 -4
  146. package/dist/types/components/Table/table.content.d.ts +3 -3
  147. package/dist/types/components/Tag/index.d.ts +2 -2
  148. package/dist/types/components/Tag/index.d.ts.map +1 -1
  149. package/dist/types/components/Terminal/Terminal.d.ts.map +1 -1
  150. package/dist/types/components/Terminal/terminal.content.d.ts +93 -0
  151. package/dist/types/components/Terminal/terminal.content.d.ts.map +1 -0
  152. package/dist/types/components/Toaster/Toast.d.ts +2 -2
  153. package/dist/types/components/Toaster/Toast.d.ts.map +1 -1
  154. package/dist/types/components/Toaster/Toaster.d.ts +2 -2
  155. package/dist/types/components/Toaster/Toaster.d.ts.map +1 -1
  156. package/dist/types/components/index.d.ts +4 -2
  157. package/dist/types/hooks/index.d.ts +2 -2
  158. package/dist/types/hooks/reactQuery.d.ts +2 -1
  159. package/dist/types/hooks/reactQuery.d.ts.map +1 -1
  160. package/dist/types/libs/auth.d.ts +1 -0
  161. package/dist/types/libs/auth.d.ts.map +1 -1
  162. package/package.json +40 -34
@@ -1,20 +1,11 @@
1
1
  import { cn } from "../../utils/cn.mjs";
2
2
  import { Loader } from "../Loader/index.mjs";
3
3
  import { User } from "lucide-react";
4
- import { forwardRef, useMemo } from "react";
4
+ import { useMemo } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
 
7
7
  //#region src/components/Avatar/index.tsx
8
8
  /**
9
- * Size variants for the avatar
10
- */
11
- const sizeVariants = {
12
- sm: "size-6",
13
- md: "size-9",
14
- lg: "size-12",
15
- xl: "size-16"
16
- };
17
- /**
18
9
  * @description Gets the capital letters from a name.
19
10
  * @param name - The name to extract capitals from.
20
11
  * @param separator - The separator to split the name (default is an empty string, which splits by each character).
@@ -27,20 +18,17 @@ const getCapitals = (name, separator = " ") => {
27
18
  /**
28
19
  * Container component that renders either a button or div based on interactivity
29
20
  */
30
- const Container = forwardRef(({ isClickable, onClick, ...props }, ref) => {
21
+ const Container = ({ isClickable, onClick, ...props }) => {
31
22
  if (isClickable && onClick) return /* @__PURE__ */ jsx("button", {
32
23
  ...props,
33
- ref,
34
24
  onClick,
35
25
  type: "button"
36
26
  });
37
27
  return /* @__PURE__ */ jsx("div", {
38
28
  ...props,
39
- ref,
40
29
  role: props.tabIndex !== void 0 || props["aria-label"] ? "img" : void 0
41
30
  });
42
- });
43
- Container.displayName = "AvatarContainer";
31
+ };
44
32
  /**
45
33
  * Avatar component that displays user profile images, initials, or a default user icon.
46
34
  * Supports loading states, authentication states, and accessibility features.
@@ -72,7 +60,6 @@ const Avatar = ({ fullname, className, isLoading = false, isLoggedIn = true, src
72
60
  const displayInitials = isLoggedIn && !displayLoader && !displayAvatar && isNameDefined;
73
61
  const displayUserIcon = isLoggedIn && !displayLoader && !displayAvatar && !displayInitials;
74
62
  const isClickable = onClick !== void 0;
75
- const sizeClass = sizeVariants[size];
76
63
  const accessibilityProps = useMemo(() => {
77
64
  const baseProps = {};
78
65
  if (displayAvatar && alt) baseProps["aria-label"] = alt;
@@ -96,13 +83,13 @@ const Avatar = ({ fullname, className, isLoading = false, isLoggedIn = true, src
96
83
  isClickable,
97
84
  focusable
98
85
  ]);
99
- return /* @__PURE__ */ jsxs(Container, {
86
+ return /* @__PURE__ */ jsx(Container, {
100
87
  isClickable,
101
- className: cn(`rounded-full border-[1.5px] border-text p-[1.5px]`, sizeClass, isClickable && `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`, !isClickable && focusable && `focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`, displayLoader && "animate-pulse", className),
88
+ className: cn(`rounded-full border-[1.3px] border-text p-[1.5px]`, size === "sm" && "size-7 border-[1px] p-[1px]", size === "md" && "size-9", size === "lg" && "size-12", size === "xl" && "size-16", isClickable && `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`, !isClickable && focusable && `focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`, displayLoader && "animate-pulse", className),
102
89
  onClick,
103
90
  ...accessibilityProps,
104
91
  ...props,
105
- children: [/* @__PURE__ */ jsx("div", {
92
+ children: /* @__PURE__ */ jsx("div", {
106
93
  className: "relative flex size-full flex-row items-center justify-center",
107
94
  children: /* @__PURE__ */ jsxs("div", {
108
95
  className: "absolute top-0 left-0 flex size-full flex-col items-center justify-center rounded-full bg-text text-text-opposite",
@@ -115,27 +102,23 @@ const Avatar = ({ fullname, className, isLoading = false, isLoggedIn = true, src
115
102
  className: "size-full rounded-full object-cover",
116
103
  src,
117
104
  srcSet: src,
118
- alt: alt || `Avatar of ${fullname}`,
105
+ alt: alt ?? `Avatar of ${fullname}`,
119
106
  width: 59,
120
107
  height: 59,
121
- loading: "lazy"
108
+ loading: "lazy",
109
+ draggable: false
122
110
  }),
123
111
  displayInitials && /* @__PURE__ */ jsx("div", {
124
112
  className: "flex size-full items-center justify-center gap-[0.1rem] font-bold text-sm max-md:py-1",
125
- "aria-label": `Initials for ${fullname}`,
126
113
  children: capitals?.map((capital, index) => /* @__PURE__ */ jsx("span", { children: capital }, `${capital}-${index}`))
127
114
  }),
128
115
  displayUserIcon && /* @__PURE__ */ jsx(User, {
129
- size: size === "sm" ? 14 : size === "md" ? 25 : size === "lg" ? 30 : 40,
116
+ size: cn(size === "sm" && 14, size === "md" && 25, size === "lg" && 30, size === "xl" && 40),
130
117
  "aria-label": "Default user icon"
131
118
  })
132
119
  ]
133
120
  })
134
- }), isClickable && /* @__PURE__ */ jsx("span", {
135
- id: "avatar-description",
136
- className: "sr-only",
137
- children: "Click to view profile"
138
- })]
121
+ })
139
122
  });
140
123
  };
141
124
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["Avatar: FC<AvatarProps>","baseProps: Record<string, any>"],"sources":["../../../../src/components/Avatar/index.tsx"],"sourcesContent":["import { User } from 'lucide-react';\nimport type { ComponentProps, FC, HTMLAttributes } from 'react';\nimport { forwardRef, useMemo } from 'react';\nimport { cn } from '../../utils/cn';\nimport { Loader } from '../Loader';\n\n/**\n * Props for the Avatar component\n */\nexport interface AvatarProps extends Omit<ComponentProps<'button'>, 'onClick'> {\n /** Image source URL for the avatar */\n src?: string;\n /** Full name used to generate initials and alt text */\n fullname?: string;\n /** Displays a loading spinner when true */\n isLoading?: boolean;\n /** Whether the user is authenticated */\n isLoggedIn?: boolean;\n /** Size variant of the avatar */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /** Click handler - when provided, makes the avatar clickable */\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n /** Alternative text for accessibility */\n alt?: string;\n /** Whether the avatar should be focusable when not clickable */\n focusable?: boolean;\n}\n\n/**\n * Size variants for the avatar\n */\nconst sizeVariants = {\n sm: 'size-6',\n md: 'size-9',\n lg: 'size-12',\n xl: 'size-16',\n} as const;\n\n/**\n * @description Gets the capital letters from a name.\n * @param name - The name to extract capitals from.\n * @param separator - The separator to split the name (default is an empty string, which splits by each character).\n * @returns {string[]} An array of capital letters from the name.\n */\nexport const getCapitals = (name: string, separator = ' '): string[] => {\n if (!name) return [];\n\n const parts =\n separator === ' '\n ? name\n .trim()\n .split(/\\s+/) // handle multiple spaces\n : name.split(separator);\n\n return parts.filter(Boolean).map((word) => word.charAt(0).toUpperCase());\n};\n\n/**\n * Container component that renders either a button or div based on interactivity\n */\nconst Container = forwardRef<\n HTMLElement,\n HTMLAttributes<HTMLElement> & {\n isClickable: boolean;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n }\n>(({ isClickable, onClick, ...props }, ref) => {\n if (isClickable && onClick) {\n return (\n <button\n {...(props as ComponentProps<'button'>)}\n ref={ref as React.Ref<HTMLButtonElement>}\n onClick={onClick}\n type=\"button\"\n />\n );\n }\n\n return (\n <div\n {...(props as ComponentProps<'div'>)}\n ref={ref as React.Ref<HTMLDivElement>}\n role={\n props.tabIndex !== undefined || props['aria-label'] ? 'img' : undefined\n }\n />\n );\n});\n\nContainer.displayName = 'AvatarContainer';\n\n/**\n * Avatar component that displays user profile images, initials, or a default user icon.\n * Supports loading states, authentication states, and accessibility features.\n *\n * @example\n * ```tsx\n * // With image\n * <Avatar src=\"https://example.com/avatar.jpg\" fullname=\"John Doe\" />\n *\n * // With initials\n * <Avatar fullname=\"John Doe\" />\n *\n * // Clickable avatar\n * <Avatar\n * fullname=\"John Doe\"\n * onClick={(e) => console.log('Avatar clicked')}\n * />\n *\n * // Loading state\n * <Avatar isLoading fullname=\"John Doe\" />\n * ```\n */\nexport const Avatar: FC<AvatarProps> = ({\n fullname,\n className,\n isLoading = false,\n isLoggedIn = true,\n src,\n onClick,\n size = 'md',\n alt,\n focusable = false,\n ...props\n}) => {\n const isImageDefined = Boolean(src);\n const isNameDefined = Boolean((fullname ?? '').length > 0);\n const capitals = fullname ? getCapitals(fullname) : undefined;\n\n // Display logic\n const displayLoader = isLoading;\n const displayAvatar = isLoggedIn && !displayLoader && isImageDefined;\n const displayInitials =\n isLoggedIn && !displayLoader && !displayAvatar && isNameDefined;\n const displayUserIcon =\n isLoggedIn && !displayLoader && !displayAvatar && !displayInitials;\n\n const isClickable = onClick !== undefined;\n const sizeClass = sizeVariants[size];\n\n // Accessibility attributes\n const accessibilityProps = useMemo(() => {\n const baseProps: Record<string, any> = {};\n\n if (displayAvatar && alt) {\n baseProps['aria-label'] = alt;\n } else if (displayAvatar && fullname) {\n baseProps['aria-label'] = `Avatar of ${fullname}`;\n } else if (displayInitials && fullname) {\n baseProps['aria-label'] = `Avatar initials for ${fullname}`;\n } else if (displayUserIcon) {\n baseProps['aria-label'] = 'Default user avatar';\n } else if (displayLoader) {\n baseProps['aria-label'] = 'Loading avatar';\n baseProps['aria-busy'] = true;\n }\n\n if (!isClickable && focusable) {\n baseProps.tabIndex = 0;\n }\n\n if (isClickable) {\n baseProps['aria-describedby'] = 'avatar-description';\n }\n\n return baseProps;\n }, [\n displayAvatar,\n displayInitials,\n displayUserIcon,\n displayLoader,\n alt,\n fullname,\n isClickable,\n focusable,\n ]);\n\n return (\n <Container\n isClickable={isClickable}\n className={cn(\n `rounded-full border-[1.5px] border-text p-[1.5px]`,\n sizeClass,\n isClickable &&\n `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`,\n !isClickable &&\n focusable &&\n `focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`,\n displayLoader && 'animate-pulse',\n className\n )}\n onClick={onClick}\n {...accessibilityProps}\n {...props}\n >\n <div className=\"relative flex size-full flex-row items-center justify-center\">\n <div className=\"absolute top-0 left-0 flex size-full flex-col items-center justify-center rounded-full bg-text text-text-opposite\">\n {displayLoader && (\n <Loader className=\"w-3/4\" aria-label=\"Loading user avatar\" />\n )}\n\n {displayAvatar && (\n <img\n className=\"size-full rounded-full object-cover\"\n src={src}\n srcSet={src}\n alt={alt || `Avatar of ${fullname}`}\n width={59}\n height={59}\n loading=\"lazy\"\n />\n )}\n\n {displayInitials && (\n <div\n className=\"flex size-full items-center justify-center gap-[0.1rem] font-bold text-sm max-md:py-1\"\n aria-label={`Initials for ${fullname}`}\n >\n {capitals?.map((capital, index) => (\n <span key={`${capital}-${index}`}>{capital}</span>\n ))}\n </div>\n )}\n\n {displayUserIcon && (\n <User\n size={\n size === 'sm'\n ? 14\n : size === 'md'\n ? 25\n : size === 'lg'\n ? 30\n : 40\n }\n aria-label=\"Default user icon\"\n />\n )}\n </div>\n </div>\n\n {isClickable && (\n <span id=\"avatar-description\" className=\"sr-only\">\n Click to view profile\n </span>\n )}\n </Container>\n );\n};\n"],"mappings":";;;;;;;;;;AA+BA,MAAM,eAAe;CACnB,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;;;;;;;AAQD,MAAa,eAAe,MAAc,YAAY,QAAkB;AACtE,KAAI,CAAC,KAAM,QAAO,EAAE;AASpB,SANE,cAAc,MACV,KACG,MAAM,CACN,MAAM,MAAM,GACf,KAAK,MAAM,UAAU,EAEd,OAAO,QAAQ,CAAC,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,CAAC;;;;;AAM1E,MAAM,YAAY,YAMf,EAAE,aAAa,SAAS,GAAG,SAAS,QAAQ;AAC7C,KAAI,eAAe,QACjB,QACE,oBAAC;EACC,GAAK;EACA;EACI;EACT,MAAK;GACL;AAIN,QACE,oBAAC;EACC,GAAK;EACA;EACL,MACE,MAAM,aAAa,UAAa,MAAM,gBAAgB,QAAQ;GAEhE;EAEJ;AAEF,UAAU,cAAc;;;;;;;;;;;;;;;;;;;;;;;AAwBxB,MAAaA,UAA2B,EACtC,UACA,WACA,YAAY,OACZ,aAAa,MACb,KACA,SACA,OAAO,MACP,KACA,YAAY,OACZ,GAAG,YACC;CACJ,MAAM,iBAAiB,QAAQ,IAAI;CACnC,MAAM,gBAAgB,SAAS,YAAY,IAAI,SAAS,EAAE;CAC1D,MAAM,WAAW,WAAW,YAAY,SAAS,GAAG;CAGpD,MAAM,gBAAgB;CACtB,MAAM,gBAAgB,cAAc,CAAC,iBAAiB;CACtD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB;CACpD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;CAErD,MAAM,cAAc,YAAY;CAChC,MAAM,YAAY,aAAa;CAG/B,MAAM,qBAAqB,cAAc;EACvC,MAAMC,YAAiC,EAAE;AAEzC,MAAI,iBAAiB,IACnB,WAAU,gBAAgB;WACjB,iBAAiB,SAC1B,WAAU,gBAAgB,aAAa;WAC9B,mBAAmB,SAC5B,WAAU,gBAAgB,uBAAuB;WACxC,gBACT,WAAU,gBAAgB;WACjB,eAAe;AACxB,aAAU,gBAAgB;AAC1B,aAAU,eAAe;;AAG3B,MAAI,CAAC,eAAe,UAClB,WAAU,WAAW;AAGvB,MAAI,YACF,WAAU,sBAAsB;AAGlC,SAAO;IACN;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,QACE,qBAAC;EACc;EACb,WAAW,GACT,qDACA,WACA,eACE,2GACF,CAAC,eACC,aACA,2EACF,iBAAiB,iBACjB,UACD;EACQ;EACT,GAAI;EACJ,GAAI;aAEJ,oBAAC;GAAI,WAAU;aACb,qBAAC;IAAI,WAAU;;KACZ,iBACC,oBAAC;MAAO,WAAU;MAAQ,cAAW;OAAwB;KAG9D,iBACC,oBAAC;MACC,WAAU;MACL;MACL,QAAQ;MACR,KAAK,OAAO,aAAa;MACzB,OAAO;MACP,QAAQ;MACR,SAAQ;OACR;KAGH,mBACC,oBAAC;MACC,WAAU;MACV,cAAY,gBAAgB;gBAE3B,UAAU,KAAK,SAAS,UACvB,oBAAC,oBAAkC,WAAxB,GAAG,QAAQ,GAAG,QAAyB,CAClD;OACE;KAGP,mBACC,oBAAC;MACC,MACE,SAAS,OACL,KACA,SAAS,OACP,KACA,SAAS,OACP,KACA;MAEV,cAAW;OACX;;KAEA;IACF,EAEL,eACC,oBAAC;GAAK,IAAG;GAAqB,WAAU;aAAU;IAE3C;GAEC"}
1
+ {"version":3,"file":"index.mjs","names":["Container: FC<\n HTMLAttributes<HTMLElement> & {\n isClickable: boolean;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n }\n>","Avatar: FC<AvatarProps>","baseProps: Record<string, any>"],"sources":["../../../../src/components/Avatar/index.tsx"],"sourcesContent":["import { User } from 'lucide-react';\nimport type { ComponentProps, FC, HTMLAttributes } from 'react';\nimport { useMemo } from 'react';\nimport { cn } from '../../utils/cn';\nimport { Loader } from '../Loader';\n\n/**\n * Props for the Avatar component\n */\nexport interface AvatarProps extends Omit<ComponentProps<'button'>, 'onClick'> {\n /** Image source URL for the avatar */\n src?: string;\n /** Full name used to generate initials and alt text */\n fullname?: string;\n /** Displays a loading spinner when true */\n isLoading?: boolean;\n /** Whether the user is authenticated */\n isLoggedIn?: boolean;\n /** Size variant of the avatar */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /** Click handler - when provided, makes the avatar clickable */\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n /** Alternative text for accessibility */\n alt?: string;\n /** Whether the avatar should be focusable when not clickable */\n focusable?: boolean;\n}\n\n/**\n * @description Gets the capital letters from a name.\n * @param name - The name to extract capitals from.\n * @param separator - The separator to split the name (default is an empty string, which splits by each character).\n * @returns {string[]} An array of capital letters from the name.\n */\nexport const getCapitals = (name: string, separator = ' '): string[] => {\n if (!name) return [];\n\n const parts =\n separator === ' '\n ? name\n .trim()\n .split(/\\s+/) // handle multiple spaces\n : name.split(separator);\n\n return parts.filter(Boolean).map((word) => word.charAt(0).toUpperCase());\n};\n\n/**\n * Container component that renders either a button or div based on interactivity\n */\nconst Container: FC<\n HTMLAttributes<HTMLElement> & {\n isClickable: boolean;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n }\n> = ({ isClickable, onClick, ...props }) => {\n if (isClickable && onClick) {\n return (\n <button\n {...(props as ComponentProps<'button'>)}\n onClick={onClick}\n type=\"button\"\n />\n );\n }\n\n return (\n <div\n {...(props as ComponentProps<'div'>)}\n role={\n props.tabIndex !== undefined || props['aria-label'] ? 'img' : undefined\n }\n />\n );\n};\n\n/**\n * Avatar component that displays user profile images, initials, or a default user icon.\n * Supports loading states, authentication states, and accessibility features.\n *\n * @example\n * ```tsx\n * // With image\n * <Avatar src=\"https://example.com/avatar.jpg\" fullname=\"John Doe\" />\n *\n * // With initials\n * <Avatar fullname=\"John Doe\" />\n *\n * // Clickable avatar\n * <Avatar\n * fullname=\"John Doe\"\n * onClick={(e) => console.log('Avatar clicked')}\n * />\n *\n * // Loading state\n * <Avatar isLoading fullname=\"John Doe\" />\n * ```\n */\nexport const Avatar: FC<AvatarProps> = ({\n fullname,\n className,\n isLoading = false,\n isLoggedIn = true,\n src,\n onClick,\n size = 'md',\n alt,\n focusable = false,\n ...props\n}) => {\n const isImageDefined = Boolean(src);\n const isNameDefined = Boolean((fullname ?? '').length > 0);\n const capitals = fullname ? getCapitals(fullname) : undefined;\n\n // Display logic\n const displayLoader = isLoading;\n const displayAvatar = isLoggedIn && !displayLoader && isImageDefined;\n const displayInitials =\n isLoggedIn && !displayLoader && !displayAvatar && isNameDefined;\n const displayUserIcon =\n isLoggedIn && !displayLoader && !displayAvatar && !displayInitials;\n\n const isClickable = onClick !== undefined;\n\n // Accessibility attributes\n const accessibilityProps = useMemo(() => {\n const baseProps: Record<string, any> = {};\n\n if (displayAvatar && alt) {\n baseProps['aria-label'] = alt;\n } else if (displayAvatar && fullname) {\n baseProps['aria-label'] = `Avatar of ${fullname}`;\n } else if (displayInitials && fullname) {\n baseProps['aria-label'] = `Avatar initials for ${fullname}`;\n } else if (displayUserIcon) {\n baseProps['aria-label'] = 'Default user avatar';\n } else if (displayLoader) {\n baseProps['aria-label'] = 'Loading avatar';\n baseProps['aria-busy'] = true;\n }\n\n if (!isClickable && focusable) {\n baseProps.tabIndex = 0;\n }\n\n if (isClickable) {\n baseProps['aria-describedby'] = 'avatar-description';\n }\n\n return baseProps;\n }, [\n displayAvatar,\n displayInitials,\n displayUserIcon,\n displayLoader,\n alt,\n fullname,\n isClickable,\n focusable,\n ]);\n\n return (\n <Container\n isClickable={isClickable}\n className={cn(\n `rounded-full border-[1.3px] border-text p-[1.5px]`,\n size === 'sm' && 'size-7 border-[1px] p-[1px]',\n size === 'md' && 'size-9',\n size === 'lg' && 'size-12',\n size === 'xl' && 'size-16',\n isClickable &&\n `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`,\n !isClickable &&\n focusable &&\n `focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`,\n displayLoader && 'animate-pulse',\n className\n )}\n onClick={onClick}\n {...accessibilityProps}\n {...props}\n >\n <div className=\"relative flex size-full flex-row items-center justify-center\">\n <div className=\"absolute top-0 left-0 flex size-full flex-col items-center justify-center rounded-full bg-text text-text-opposite\">\n {displayLoader && (\n <Loader className=\"w-3/4\" aria-label=\"Loading user avatar\" />\n )}\n\n {displayAvatar && (\n <img\n className=\"size-full rounded-full object-cover\"\n src={src}\n srcSet={src}\n alt={alt ?? `Avatar of ${fullname}`}\n width={59}\n height={59}\n loading=\"lazy\"\n draggable={false}\n />\n )}\n\n {displayInitials && (\n <div className=\"flex size-full items-center justify-center gap-[0.1rem] font-bold text-sm max-md:py-1\">\n {capitals?.map((capital, index) => (\n <span key={`${capital}-${index}`}>{capital}</span>\n ))}\n </div>\n )}\n\n {displayUserIcon && (\n <User\n size={cn(\n size === 'sm' && 14,\n size === 'md' && 25,\n size === 'lg' && 30,\n size === 'xl' && 40\n )}\n aria-label=\"Default user icon\"\n />\n )}\n </div>\n </div>\n </Container>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAkCA,MAAa,eAAe,MAAc,YAAY,QAAkB;AACtE,KAAI,CAAC,KAAM,QAAO,EAAE;AASpB,SANE,cAAc,MACV,KACG,MAAM,CACN,MAAM,MAAM,GACf,KAAK,MAAM,UAAU,EAEd,OAAO,QAAQ,CAAC,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,CAAC;;;;;AAM1E,MAAMA,aAKD,EAAE,aAAa,SAAS,GAAG,YAAY;AAC1C,KAAI,eAAe,QACjB,QACE,oBAAC;EACC,GAAK;EACI;EACT,MAAK;GACL;AAIN,QACE,oBAAC;EACC,GAAK;EACL,MACE,MAAM,aAAa,UAAa,MAAM,gBAAgB,QAAQ;GAEhE;;;;;;;;;;;;;;;;;;;;;;;;AA0BN,MAAaC,UAA2B,EACtC,UACA,WACA,YAAY,OACZ,aAAa,MACb,KACA,SACA,OAAO,MACP,KACA,YAAY,OACZ,GAAG,YACC;CACJ,MAAM,iBAAiB,QAAQ,IAAI;CACnC,MAAM,gBAAgB,SAAS,YAAY,IAAI,SAAS,EAAE;CAC1D,MAAM,WAAW,WAAW,YAAY,SAAS,GAAG;CAGpD,MAAM,gBAAgB;CACtB,MAAM,gBAAgB,cAAc,CAAC,iBAAiB;CACtD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB;CACpD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;CAErD,MAAM,cAAc,YAAY;CAGhC,MAAM,qBAAqB,cAAc;EACvC,MAAMC,YAAiC,EAAE;AAEzC,MAAI,iBAAiB,IACnB,WAAU,gBAAgB;WACjB,iBAAiB,SAC1B,WAAU,gBAAgB,aAAa;WAC9B,mBAAmB,SAC5B,WAAU,gBAAgB,uBAAuB;WACxC,gBACT,WAAU,gBAAgB;WACjB,eAAe;AACxB,aAAU,gBAAgB;AAC1B,aAAU,eAAe;;AAG3B,MAAI,CAAC,eAAe,UAClB,WAAU,WAAW;AAGvB,MAAI,YACF,WAAU,sBAAsB;AAGlC,SAAO;IACN;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,QACE,oBAAC;EACc;EACb,WAAW,GACT,qDACA,SAAS,QAAQ,+BACjB,SAAS,QAAQ,UACjB,SAAS,QAAQ,WACjB,SAAS,QAAQ,WACjB,eACE,2GACF,CAAC,eACC,aACA,2EACF,iBAAiB,iBACjB,UACD;EACQ;EACT,GAAI;EACJ,GAAI;YAEJ,oBAAC;GAAI,WAAU;aACb,qBAAC;IAAI,WAAU;;KACZ,iBACC,oBAAC;MAAO,WAAU;MAAQ,cAAW;OAAwB;KAG9D,iBACC,oBAAC;MACC,WAAU;MACL;MACL,QAAQ;MACR,KAAK,OAAO,aAAa;MACzB,OAAO;MACP,QAAQ;MACR,SAAQ;MACR,WAAW;OACX;KAGH,mBACC,oBAAC;MAAI,WAAU;gBACZ,UAAU,KAAK,SAAS,UACvB,oBAAC,oBAAkC,WAAxB,GAAG,QAAQ,GAAG,QAAyB,CAClD;OACE;KAGP,mBACC,oBAAC;MACC,MAAM,GACJ,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,GAClB;MACD,cAAW;OACX;;KAEA;IACF;GACI"}
@@ -62,7 +62,7 @@ const badgeVariants = cva("inline-flex items-center rounded-md border px-2.5 py-
62
62
  variant: {
63
63
  [BadgeVariant.DEFAULT]: "rounded-lg text-text-opposite",
64
64
  [BadgeVariant.NONE]: "border-none bg-opacity-0 text-inherit hover:bg-opacity-0",
65
- [BadgeVariant.OUTLINE]: "rounded-lg border-[1.5px] bg-opacity-0 hover:bg-opacity-30",
65
+ [BadgeVariant.OUTLINE]: "rounded-lg border-[1.3px] bg-opacity-0 hover:bg-opacity-30",
66
66
  [BadgeVariant.HOVERABLE]: "rounded-lg border-none bg-opacity-0 transition hover:bg-opacity-10"
67
67
  },
68
68
  size: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["Badge: React.FC<BadgeProps>"],"sources":["../../../../src/components/Badge/index.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes } from 'react';\nimport { cn } from '../../utils/cn';\n\n/**\n * Badge color variants enum\n * @description Defines the available color themes for the badge component\n */\nexport enum BadgeColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n SUCCESS = 'success',\n ERROR = 'error',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n CUSTOM = 'custom',\n}\n\n/**\n * Badge visual variants enum\n * @description Defines the available visual styles for the badge component\n */\nexport enum BadgeVariant {\n DEFAULT = 'default',\n NONE = 'none',\n OUTLINE = 'outline',\n HOVERABLE = 'hoverable',\n}\n\n/**\n * Badge size variants enum\n * @description Defines the available sizes for the badge component\n */\nexport enum BadgeSize {\n SMALL = 'sm',\n MEDIUM = 'md',\n LARGE = 'lg',\n}\n\n/**\n * Badge component variants using class-variance-authority\n * @description Defines the styling variants for different badge combinations\n */\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2',\n {\n variants: {\n color: {\n [BadgeColor.PRIMARY]:\n 'border-primary bg-primary text-primary hover:bg-primary-500',\n [BadgeColor.SECONDARY]:\n 'border-secondary bg-secondary text-secondary hover:bg-secondary-300',\n [BadgeColor.DESTRUCTIVE]:\n 'border-destructive bg-destructive text-destructive hover:bg-destructive-500',\n [BadgeColor.SUCCESS]:\n 'border-success bg-success text-success hover:bg-success-500',\n [BadgeColor.ERROR]:\n 'border-error bg-error text-error hover:bg-error-500',\n [BadgeColor.NEUTRAL]:\n 'border-neutral bg-neutral text-neutral hover:bg-neutral-600',\n [BadgeColor.LIGHT]:\n 'border-white bg-white text-white hover:bg-neutral-500',\n [BadgeColor.DARK]:\n 'border-neutral-800 bg-neutral-800 text-neutral-800 hover:bg-neutral-900',\n [BadgeColor.TEXT]: 'border-text bg-text text-text hover:opacity-80',\n [BadgeColor.CUSTOM]: '',\n },\n variant: {\n [BadgeVariant.DEFAULT]: 'rounded-lg text-text-opposite',\n [BadgeVariant.NONE]:\n 'border-none bg-opacity-0 text-inherit hover:bg-opacity-0',\n [BadgeVariant.OUTLINE]:\n 'rounded-lg border-[1.5px] bg-opacity-0 hover:bg-opacity-30',\n [BadgeVariant.HOVERABLE]:\n 'rounded-lg border-none bg-opacity-0 transition hover:bg-opacity-10',\n },\n size: {\n [BadgeSize.SMALL]: 'px-2 py-0.5 text-xs',\n [BadgeSize.MEDIUM]: 'px-2.5 py-0.5 text-xs',\n [BadgeSize.LARGE]: 'px-3 py-1 text-sm',\n },\n },\n defaultVariants: {\n variant: BadgeVariant.DEFAULT,\n color: BadgeColor.PRIMARY,\n size: BadgeSize.MEDIUM,\n },\n }\n);\n\n/**\n * Badge component props interface\n * @description Comprehensive props for the Badge component with accessibility and interactive features\n */\nexport interface BadgeProps extends HTMLAttributes<HTMLElement> {\n /** The content to display inside the badge */\n children?: React.ReactNode;\n /** Color theme variant */\n color?: BadgeColor;\n /** Visual style variant */\n variant?: BadgeVariant;\n /** Size of the badge */\n size?: BadgeSize;\n /** Whether the badge is clickable */\n clickable?: boolean;\n /** Whether the badge is dismissible (shows close button) */\n dismissible?: boolean;\n /** Click handler for the badge */\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Click handler for the dismiss button */\n onDismiss?: () => void;\n /** ARIA label for accessibility */\n 'aria-label'?: string;\n /** Badge role for accessibility (default: 'status') */\n role?: 'status' | 'button' | 'generic';\n /** Whether badge should be focusable */\n tabIndex?: number;\n}\n\n/**\n * Utility type for badge variant props\n */\nexport type BadgeVariantProps = VariantProps<typeof badgeVariants>;\n\n/**\n * Badge component for displaying status indicators, labels, and notifications\n *\n * @description A flexible badge component that supports multiple visual styles, colors, and interactive features.\n * It maintains accessibility standards and provides comprehensive customization options.\n *\n * @example\n * ```tsx\n * // Basic badge\n * <Badge>New</Badge>\n *\n * // Colored badge\n * <Badge color={BadgeColor.DESTRUCTIVE}>Error</Badge>\n *\n * // Clickable badge\n * <Badge clickable onClick={() => console.log('clicked')}>\n * Clickable\n * </Badge>\n *\n * // Dismissible badge\n * <Badge dismissible onDismiss={() => console.log('dismissed')}>\n * Dismissible\n * </Badge>\n * ```\n */\nexport const Badge: React.FC<BadgeProps> = ({\n className,\n variant = BadgeVariant.DEFAULT,\n color = BadgeColor.PRIMARY,\n size = BadgeSize.MEDIUM,\n children,\n clickable = false,\n dismissible = false,\n onClick,\n onDismiss,\n role,\n tabIndex,\n 'aria-label': ariaLabel,\n ...props\n}) => {\n const Component = clickable ? 'button' : 'span';\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (clickable && onClick && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n onClick(event as any);\n }\n };\n\n const handleDismiss = (event: React.MouseEvent) => {\n event.stopPropagation();\n onDismiss?.();\n };\n\n return (\n <Component\n className={cn(\n badgeVariants({ variant, color, size }),\n clickable &&\n 'cursor-pointer hover:opacity-80 focus-visible:ring-2 focus-visible:ring-offset-2',\n dismissible && 'pr-1',\n className\n )}\n onClick={clickable ? onClick : undefined}\n onKeyDown={clickable ? handleKeyDown : undefined}\n role={role || (clickable ? 'button' : 'status')}\n tabIndex={clickable ? (tabIndex ?? 0) : tabIndex}\n aria-label={ariaLabel || (clickable ? `${children} button` : undefined)}\n {...props}\n >\n {children}\n {dismissible && (\n <button\n type=\"button\"\n className=\"ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full hover:bg-black/10 focus:outline-none focus:ring-1 focus:ring-offset-1\"\n onClick={handleDismiss}\n aria-label={`Remove ${children} badge`}\n >\n <svg\n className=\"size-3\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-label=\"Remove badge\"\n >\n <title>Remove badge</title>\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n )}\n </Component>\n );\n};\n"],"mappings":";;;;;;;;;AAQA,IAAY,oDAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOF,IAAY,wDAAL;AACL;AACA;AACA;AACA;;;;;;;AAOF,IAAY,kDAAL;AACL;AACA;AACA;;;;;;;AAOF,MAAa,gBAAgB,IAC3B,0KACA;CACE,UAAU;EACR,OAAO;IACJ,WAAW,UACV;IACD,WAAW,YACV;IACD,WAAW,cACV;IACD,WAAW,UACV;IACD,WAAW,QACV;IACD,WAAW,UACV;IACD,WAAW,QACV;IACD,WAAW,OACV;IACD,WAAW,OAAO;IAClB,WAAW,SAAS;GACtB;EACD,SAAS;IACN,aAAa,UAAU;IACvB,aAAa,OACZ;IACD,aAAa,UACZ;IACD,aAAa,YACZ;GACH;EACD,MAAM;IACH,UAAU,QAAQ;IAClB,UAAU,SAAS;IACnB,UAAU,QAAQ;GACpB;EACF;CACD,iBAAiB;EACf,SAAS,aAAa;EACtB,OAAO,WAAW;EAClB,MAAM,UAAU;EACjB;CACF,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DD,MAAaA,SAA+B,EAC1C,WACA,UAAU,aAAa,SACvB,QAAQ,WAAW,SACnB,OAAO,UAAU,QACjB,UACA,YAAY,OACZ,cAAc,OACd,SACA,WACA,MACA,UACA,cAAc,WACd,GAAG,YACC;CACJ,MAAM,YAAY,YAAY,WAAW;CAEzC,MAAM,iBAAiB,UAA4C;AACjE,MAAI,aAAa,YAAY,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;AACxE,SAAM,gBAAgB;AACtB,WAAQ,MAAa;;;CAIzB,MAAM,iBAAiB,UAA4B;AACjD,QAAM,iBAAiB;AACvB,eAAa;;AAGf,QACE,qBAAC;EACC,WAAW,GACT,cAAc;GAAE;GAAS;GAAO;GAAM,CAAC,EACvC,aACE,oFACF,eAAe,QACf,UACD;EACD,SAAS,YAAY,UAAU;EAC/B,WAAW,YAAY,gBAAgB;EACvC,MAAM,SAAS,YAAY,WAAW;EACtC,UAAU,YAAa,YAAY,IAAK;EACxC,cAAY,cAAc,YAAY,GAAG,SAAS,WAAW;EAC7D,GAAI;aAEH,UACA,eACC,oBAAC;GACC,MAAK;GACL,WAAU;GACV,SAAS;GACT,cAAY,UAAU,SAAS;aAE/B,qBAAC;IACC,WAAU;IACV,SAAQ;IACR,MAAK;IACL,cAAW;eAEX,oBAAC,qBAAM,iBAAoB,EAC3B,oBAAC;KACC,UAAS;KACT,GAAE;KACF,UAAS;MACT;KACE;IACC;GAED"}
1
+ {"version":3,"file":"index.mjs","names":["Badge: React.FC<BadgeProps>"],"sources":["../../../../src/components/Badge/index.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes } from 'react';\nimport { cn } from '../../utils/cn';\n\n/**\n * Badge color variants enum\n * @description Defines the available color themes for the badge component\n */\nexport enum BadgeColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n SUCCESS = 'success',\n ERROR = 'error',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n CUSTOM = 'custom',\n}\n\n/**\n * Badge visual variants enum\n * @description Defines the available visual styles for the badge component\n */\nexport enum BadgeVariant {\n DEFAULT = 'default',\n NONE = 'none',\n OUTLINE = 'outline',\n HOVERABLE = 'hoverable',\n}\n\n/**\n * Badge size variants enum\n * @description Defines the available sizes for the badge component\n */\nexport enum BadgeSize {\n SMALL = 'sm',\n MEDIUM = 'md',\n LARGE = 'lg',\n}\n\n/**\n * Badge component variants using class-variance-authority\n * @description Defines the styling variants for different badge combinations\n */\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2',\n {\n variants: {\n color: {\n [BadgeColor.PRIMARY]:\n 'border-primary bg-primary text-primary hover:bg-primary-500',\n [BadgeColor.SECONDARY]:\n 'border-secondary bg-secondary text-secondary hover:bg-secondary-300',\n [BadgeColor.DESTRUCTIVE]:\n 'border-destructive bg-destructive text-destructive hover:bg-destructive-500',\n [BadgeColor.SUCCESS]:\n 'border-success bg-success text-success hover:bg-success-500',\n [BadgeColor.ERROR]:\n 'border-error bg-error text-error hover:bg-error-500',\n [BadgeColor.NEUTRAL]:\n 'border-neutral bg-neutral text-neutral hover:bg-neutral-600',\n [BadgeColor.LIGHT]:\n 'border-white bg-white text-white hover:bg-neutral-500',\n [BadgeColor.DARK]:\n 'border-neutral-800 bg-neutral-800 text-neutral-800 hover:bg-neutral-900',\n [BadgeColor.TEXT]: 'border-text bg-text text-text hover:opacity-80',\n [BadgeColor.CUSTOM]: '',\n },\n variant: {\n [BadgeVariant.DEFAULT]: 'rounded-lg text-text-opposite',\n [BadgeVariant.NONE]:\n 'border-none bg-opacity-0 text-inherit hover:bg-opacity-0',\n [BadgeVariant.OUTLINE]:\n 'rounded-lg border-[1.3px] bg-opacity-0 hover:bg-opacity-30',\n [BadgeVariant.HOVERABLE]:\n 'rounded-lg border-none bg-opacity-0 transition hover:bg-opacity-10',\n },\n size: {\n [BadgeSize.SMALL]: 'px-2 py-0.5 text-xs',\n [BadgeSize.MEDIUM]: 'px-2.5 py-0.5 text-xs',\n [BadgeSize.LARGE]: 'px-3 py-1 text-sm',\n },\n },\n defaultVariants: {\n variant: BadgeVariant.DEFAULT,\n color: BadgeColor.PRIMARY,\n size: BadgeSize.MEDIUM,\n },\n }\n);\n\n/**\n * Badge component props interface\n * @description Comprehensive props for the Badge component with accessibility and interactive features\n */\nexport interface BadgeProps extends HTMLAttributes<HTMLElement> {\n /** The content to display inside the badge */\n children?: React.ReactNode;\n /** Color theme variant */\n color?: BadgeColor;\n /** Visual style variant */\n variant?: BadgeVariant;\n /** Size of the badge */\n size?: BadgeSize;\n /** Whether the badge is clickable */\n clickable?: boolean;\n /** Whether the badge is dismissible (shows close button) */\n dismissible?: boolean;\n /** Click handler for the badge */\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Click handler for the dismiss button */\n onDismiss?: () => void;\n /** ARIA label for accessibility */\n 'aria-label'?: string;\n /** Badge role for accessibility (default: 'status') */\n role?: 'status' | 'button' | 'generic';\n /** Whether badge should be focusable */\n tabIndex?: number;\n}\n\n/**\n * Utility type for badge variant props\n */\nexport type BadgeVariantProps = VariantProps<typeof badgeVariants>;\n\n/**\n * Badge component for displaying status indicators, labels, and notifications\n *\n * @description A flexible badge component that supports multiple visual styles, colors, and interactive features.\n * It maintains accessibility standards and provides comprehensive customization options.\n *\n * @example\n * ```tsx\n * // Basic badge\n * <Badge>New</Badge>\n *\n * // Colored badge\n * <Badge color={BadgeColor.DESTRUCTIVE}>Error</Badge>\n *\n * // Clickable badge\n * <Badge clickable onClick={() => console.log('clicked')}>\n * Clickable\n * </Badge>\n *\n * // Dismissible badge\n * <Badge dismissible onDismiss={() => console.log('dismissed')}>\n * Dismissible\n * </Badge>\n * ```\n */\nexport const Badge: React.FC<BadgeProps> = ({\n className,\n variant = BadgeVariant.DEFAULT,\n color = BadgeColor.PRIMARY,\n size = BadgeSize.MEDIUM,\n children,\n clickable = false,\n dismissible = false,\n onClick,\n onDismiss,\n role,\n tabIndex,\n 'aria-label': ariaLabel,\n ...props\n}) => {\n const Component = clickable ? 'button' : 'span';\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (clickable && onClick && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n onClick(event as any);\n }\n };\n\n const handleDismiss = (event: React.MouseEvent) => {\n event.stopPropagation();\n onDismiss?.();\n };\n\n return (\n <Component\n className={cn(\n badgeVariants({ variant, color, size }),\n clickable &&\n 'cursor-pointer hover:opacity-80 focus-visible:ring-2 focus-visible:ring-offset-2',\n dismissible && 'pr-1',\n className\n )}\n onClick={clickable ? onClick : undefined}\n onKeyDown={clickable ? handleKeyDown : undefined}\n role={role || (clickable ? 'button' : 'status')}\n tabIndex={clickable ? (tabIndex ?? 0) : tabIndex}\n aria-label={ariaLabel || (clickable ? `${children} button` : undefined)}\n {...props}\n >\n {children}\n {dismissible && (\n <button\n type=\"button\"\n className=\"ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full hover:bg-black/10 focus:outline-none focus:ring-1 focus:ring-offset-1\"\n onClick={handleDismiss}\n aria-label={`Remove ${children} badge`}\n >\n <svg\n className=\"size-3\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-label=\"Remove badge\"\n >\n <title>Remove badge</title>\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n )}\n </Component>\n );\n};\n"],"mappings":";;;;;;;;;AAQA,IAAY,oDAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOF,IAAY,wDAAL;AACL;AACA;AACA;AACA;;;;;;;AAOF,IAAY,kDAAL;AACL;AACA;AACA;;;;;;;AAOF,MAAa,gBAAgB,IAC3B,0KACA;CACE,UAAU;EACR,OAAO;IACJ,WAAW,UACV;IACD,WAAW,YACV;IACD,WAAW,cACV;IACD,WAAW,UACV;IACD,WAAW,QACV;IACD,WAAW,UACV;IACD,WAAW,QACV;IACD,WAAW,OACV;IACD,WAAW,OAAO;IAClB,WAAW,SAAS;GACtB;EACD,SAAS;IACN,aAAa,UAAU;IACvB,aAAa,OACZ;IACD,aAAa,UACZ;IACD,aAAa,YACZ;GACH;EACD,MAAM;IACH,UAAU,QAAQ;IAClB,UAAU,SAAS;IACnB,UAAU,QAAQ;GACpB;EACF;CACD,iBAAiB;EACf,SAAS,aAAa;EACtB,OAAO,WAAW;EAClB,MAAM,UAAU;EACjB;CACF,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;AA6DD,MAAaA,SAA+B,EAC1C,WACA,UAAU,aAAa,SACvB,QAAQ,WAAW,SACnB,OAAO,UAAU,QACjB,UACA,YAAY,OACZ,cAAc,OACd,SACA,WACA,MACA,UACA,cAAc,WACd,GAAG,YACC;CACJ,MAAM,YAAY,YAAY,WAAW;CAEzC,MAAM,iBAAiB,UAA4C;AACjE,MAAI,aAAa,YAAY,MAAM,QAAQ,WAAW,MAAM,QAAQ,MAAM;AACxE,SAAM,gBAAgB;AACtB,WAAQ,MAAa;;;CAIzB,MAAM,iBAAiB,UAA4B;AACjD,QAAM,iBAAiB;AACvB,eAAa;;AAGf,QACE,qBAAC;EACC,WAAW,GACT,cAAc;GAAE;GAAS;GAAO;GAAM,CAAC,EACvC,aACE,oFACF,eAAe,QACf,UACD;EACD,SAAS,YAAY,UAAU;EAC/B,WAAW,YAAY,gBAAgB;EACvC,MAAM,SAAS,YAAY,WAAW;EACtC,UAAU,YAAa,YAAY,IAAK;EACxC,cAAY,cAAc,YAAY,GAAG,SAAS,WAAW;EAC7D,GAAI;aAEH,UACA,eACC,oBAAC;GACC,MAAK;GACL,WAAU;GACV,SAAS;GACT,cAAY,UAAU,SAAS;aAE/B,qBAAC;IACC,WAAU;IACV,SAAQ;IACR,MAAK;IACL,cAAW;eAEX,oBAAC,qBAAM,iBAAoB,EAC3B,oBAAC;KACC,UAAS;KACT,GAAE;KACF,UAAS;MACT;KACE;IACC;GAED"}
@@ -49,6 +49,7 @@ const LinkLink = ({ href, lang, children, onClick, color, position, locale, clas
49
49
  ...props,
50
50
  label: `${linkLabel} ${children}`,
51
51
  itemID: href,
52
+ size: "sm",
52
53
  children: /* @__PURE__ */ jsx("span", {
53
54
  itemProp: "name",
54
55
  children
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["LinkLink: FC<LinkLinkProps>","ButtonLink: FC<ButtonButtonProps>","Span: FC<SpanProps>","Breadcrumb: FC<BreadcrumbProps>"],"sources":["../../../../src/components/Breadcrumb/index.tsx"],"sourcesContent":["'use client';\n\nimport { getIntlayer } from '@intlayer/core';\nimport type { LocalesValues } from '@intlayer/types';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { __DictionaryRegistry } from 'intlayer';\nimport { ChevronRightIcon } from 'lucide-react';\nimport { type FC, Fragment, type HTMLAttributes, type ReactNode } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { cn } from '../../utils/cn';\nimport { Button, type ButtonProps, ButtonVariant } from '../Button';\nimport { Link, LinkColor } from '../Link';\n\n/**\n * Props for LinkLink sub-component that renders breadcrumb items as links\n */\ntype LinkLinkProps = {\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n /**\n * Locale for internationalization\n */\n locale?: LocalesValues;\n /**\n * URL to navigate to\n */\n href?: string;\n /**\n * Link color\n */\n color?: LinkColor | `${LinkColor}`;\n /**\n * Click handler\n */\n onClick?: () => void;\n /**\n * Children content\n */\n children?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n} & Omit<\n HTMLAttributes<HTMLAnchorElement>,\n 'href' | 'onClick' | 'color' | 'children' | 'className'\n>;\n\n/**\n * Breadcrumb variant styles using class-variance-authority\n */\nconst breadcrumbVariants = cva('flex flex-row flex-wrap items-center text-sm', {\n variants: {\n size: {\n small: 'gap-1 text-xs',\n medium: 'gap-2 text-sm',\n large: 'gap-3 text-base',\n },\n spacing: {\n compact: 'gap-1',\n normal: 'gap-2',\n loose: 'gap-4',\n },\n },\n defaultVariants: {\n size: 'medium',\n spacing: 'normal',\n },\n});\n\n/**\n * LinkLink sub-component for breadcrumb items that navigate to other pages\n */\nconst LinkLink: FC<LinkLinkProps> = ({\n href,\n lang,\n children,\n onClick,\n color,\n position,\n locale,\n className,\n ...props\n}) => {\n const content = getIntlayer('breadcrumb');\n const linkLabel = content.linkLabel;\n\n return (\n <>\n <Link\n href={href}\n locale={locale}\n color={color}\n onClick={onClick}\n itemProp=\"item\"\n isExternalLink={false}\n itemScope\n itemType=\"https://schema.org/WebPage\"\n {...props}\n label={`${linkLabel} ${children}`}\n itemID={href}\n >\n <span itemProp=\"name\">{children}</span>\n </Link>\n <meta itemProp=\"position\" content={position.toString()} />\n </>\n );\n};\n\n/**\n * Props for ButtonLink sub-component that renders breadcrumb items as interactive buttons\n */\ntype ButtonButtonProps = {\n /**\n * Text content for the breadcrumb button\n */\n children: string;\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n} & Omit<ButtonProps, 'children' | 'label'>;\n\n/**\n * ButtonLink sub-component for breadcrumb items with click handlers\n */\nconst ButtonLink: FC<ButtonButtonProps> = ({\n children: text,\n onClick,\n color,\n position,\n className,\n ...props\n}) => {\n const { linkLabel } = useIntlayer('breadcrumb');\n\n return (\n <>\n <Button\n onClick={onClick}\n variant={ButtonVariant.LINK}\n label={`${linkLabel} ${text}`}\n color={color}\n itemProp=\"item\"\n {...props}\n >\n <span itemProp=\"name\">{text}</span>\n </Button>\n <meta itemProp=\"position\" content={position.toString()} />\n </>\n );\n};\n\n/**\n * Props for Span sub-component that renders static breadcrumb text\n */\ntype SpanProps = {\n /**\n * Text content for the static breadcrumb item\n */\n children: string;\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n} & HTMLAttributes<HTMLSpanElement>;\n\n/**\n * Span sub-component for static breadcrumb text items\n */\nconst Span: FC<SpanProps> = ({ children, position, className, ...props }) => (\n <span\n itemProp=\"item\"\n className={cn(\n 'inline-flex items-center',\n 'font-medium text-neutral-700',\n 'transition-colors duration-200',\n className\n )}\n >\n <span itemProp=\"name\" {...props}>\n {children}\n </span>\n <meta itemProp=\"position\" content={position.toString()} />\n </span>\n);\n\n/**\n * Detailed breadcrumb link configuration with optional href or onClick\n */\ntype DetailedBreadcrumbLink = {\n /**\n * URL to navigate to when the breadcrumb item is clicked\n */\n href?: string;\n /**\n * Text content to display for this breadcrumb item\n */\n text: string;\n /**\n * Custom click handler function for interactive breadcrumb items\n */\n onClick?: () => void;\n};\n\n/**\n * Union type representing different breadcrumb item configurations:\n * - string: Simple text breadcrumb item\n * - DetailedBreadcrumbLink: Object with href, text, and/or onClick properties\n */\nexport type BreadcrumbLink = string | DetailedBreadcrumbLink;\n\nexport type BreadcrumbProps = {\n /**\n * Array of breadcrumb items\n */\n links: BreadcrumbLink[];\n /**\n * Color scheme for breadcrumb links\n * @default LinkColor.TEXT\n */\n color?: LinkColor | `${LinkColor}`;\n /**\n * Locale for internationalization\n */\n locale?: LocalesValues;\n /**\n * Element type for ARIA current attribute\n * @default 'page'\n */\n elementType?: 'page' | 'location';\n /**\n * Custom separator between breadcrumb items\n * @default ChevronRightIcon\n */\n separator?: ReactNode;\n /**\n * ARIA label for breadcrumb navigation\n * @default 'breadcrumb'\n */\n ariaLabel?: string;\n /**\n * Whether to include structured data markup\n * @default true\n */\n includeStructuredData?: boolean;\n /**\n * Maximum number of breadcrumb items to show before truncation\n */\n maxItems?: number;\n} & VariantProps<typeof breadcrumbVariants> &\n HTMLAttributes<HTMLOListElement>;\n\n/**\n * Breadcrumb component providing navigational context with accessibility features\n *\n * Features:\n * - Supports links, buttons, and static text elements\n * - Full keyboard navigation support\n * - ARIA attributes for screen readers\n * - Schema.org structured data for SEO\n * - Customizable separators and styling\n * - Internationalization support\n * - Responsive design variants\n *\n * @example\n * ```tsx\n * <Breadcrumb\n * links={[\n * 'Home',\n * { href: '/products', text: 'Products' },\n * { onClick: handleCategory, text: 'Electronics' },\n * 'Smartphones'\n * ]}\n * size=\"medium\"\n * ariaLabel=\"Product navigation\"\n * />\n * ```\n */\nexport const Breadcrumb: FC<BreadcrumbProps> = ({\n links,\n className,\n color = LinkColor.TEXT,\n locale,\n elementType = 'page',\n separator = <ChevronRightIcon size={10} />,\n ariaLabel = 'breadcrumb',\n includeStructuredData = true,\n maxItems,\n size,\n spacing,\n ...props\n}) => {\n const displayLinks =\n maxItems && links.length > maxItems\n ? [...links.slice(0, 1), '...', ...links.slice(-(maxItems - 2))]\n : links;\n\n return (\n <nav aria-label={ariaLabel}>\n <ol\n className={cn(breadcrumbVariants({ size, spacing }), className)}\n {...(includeStructuredData && {\n itemScope: true,\n itemType: 'http://schema.org/BreadcrumbList',\n })}\n {...props}\n >\n {displayLinks.map((link, index) => {\n const isLastLink = index === displayLinks.length - 1;\n const isLink =\n typeof link === 'object' && typeof link.href === 'string';\n const isButton =\n typeof link === 'object' && typeof link.onClick === 'function';\n const isActive = index === displayLinks.length - 1;\n const ariaCurrent = isActive ? elementType : undefined;\n const isTruncated = link === '...';\n\n const text = (link as DetailedBreadcrumbLink).text ?? link;\n\n if (isTruncated) {\n return (\n <Fragment key={`truncated-${text}`}>\n <li className=\"flex items-center\" aria-hidden=\"true\">\n <span className=\"text-neutral-500\">…</span>\n </li>\n {!isLastLink && (\n <li aria-hidden=\"true\" className=\"flex items-center\">\n {separator}\n </li>\n )}\n </Fragment>\n );\n }\n\n let section = (\n <Span\n key={text}\n position={index + 1}\n aria-current={ariaCurrent}\n className={cn(\n 'transition-colors duration-200',\n isActive && 'text-neutral-900'\n )}\n >\n {text}\n </Span>\n );\n\n if (isLink) {\n section = (\n <LinkLink\n key={text}\n href={link.href!}\n color={color}\n position={index + 1}\n locale={locale}\n aria-current={ariaCurrent}\n className={cn(isActive && 'cursor-default text-neutral-900')}\n >\n {text}\n </LinkLink>\n );\n } else if (isButton) {\n section = (\n <ButtonLink\n key={text}\n onClick={link.onClick!}\n color={color}\n position={index + 1}\n aria-current={ariaCurrent}\n className={cn(isActive && 'cursor-default text-neutral-900')}\n >\n {text}\n </ButtonLink>\n );\n }\n\n const listElement = (\n <li\n {...(includeStructuredData && {\n itemProp: 'itemListElement',\n itemScope: true,\n itemType: 'https://schema.org/ListItem',\n })}\n key={text}\n className=\"flex items-center\"\n >\n {section}\n </li>\n );\n\n if (isLastLink) {\n return listElement;\n }\n\n return (\n <Fragment key={text}>\n {listElement}\n <li aria-hidden=\"true\" className=\"flex items-center\">\n {separator}\n </li>\n </Fragment>\n );\n })}\n </ol>\n </nav>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAqDA,MAAM,qBAAqB,IAAI,gDAAgD;CAC7E,UAAU;EACR,MAAM;GACJ,OAAO;GACP,QAAQ;GACR,OAAO;GACR;EACD,SAAS;GACP,SAAS;GACT,QAAQ;GACR,OAAO;GACR;EACF;CACD,iBAAiB;EACf,MAAM;EACN,SAAS;EACV;CACF,CAAC;;;;AAKF,MAAMA,YAA+B,EACnC,MACA,MACA,UACA,SACA,OACA,UACA,QACA,WACA,GAAG,YACC;CAEJ,MAAM,YADU,YAAY,aAAa,CACf;AAE1B,QACE,8CACE,oBAAC;EACO;EACE;EACD;EACE;EACT,UAAS;EACT,gBAAgB;EAChB;EACA,UAAS;EACT,GAAI;EACJ,OAAO,GAAG,UAAU,GAAG;EACvB,QAAQ;YAER,oBAAC;GAAK,UAAS;GAAQ;IAAgB;GAClC,EACP,oBAAC;EAAK,UAAS;EAAW,SAAS,SAAS,UAAU;GAAI,IACzD;;;;;AAqBP,MAAMC,cAAqC,EACzC,UAAU,MACV,SACA,OACA,UACA,WACA,GAAG,YACC;CACJ,MAAM,EAAE,cAAc,YAAY,aAAa;AAE/C,QACE,8CACE,oBAAC;EACU;EACT,SAAS,cAAc;EACvB,OAAO,GAAG,UAAU,GAAG;EAChB;EACP,UAAS;EACT,GAAI;YAEJ,oBAAC;GAAK,UAAS;aAAQ;IAAY;GAC5B,EACT,oBAAC;EAAK,UAAS;EAAW,SAAS,SAAS,UAAU;GAAI,IACzD;;;;;AAqBP,MAAMC,QAAuB,EAAE,UAAU,UAAU,WAAW,GAAG,YAC/D,qBAAC;CACC,UAAS;CACT,WAAW,GACT,4BACA,gCACA,kCACA,UACD;YAED,oBAAC;EAAK,UAAS;EAAO,GAAI;EACvB;GACI,EACP,oBAAC;EAAK,UAAS;EAAW,SAAS,SAAS,UAAU;GAAI;EACrD;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+FT,MAAaC,cAAmC,EAC9C,OACA,WACA,QAAQ,UAAU,MAClB,QACA,cAAc,QACd,YAAY,oBAAC,oBAAiB,MAAM,KAAM,EAC1C,YAAY,cACZ,wBAAwB,MACxB,UACA,MACA,SACA,GAAG,YACC;CACJ,MAAM,eACJ,YAAY,MAAM,SAAS,WACvB;EAAC,GAAG,MAAM,MAAM,GAAG,EAAE;EAAE;EAAO,GAAG,MAAM,MAAM,EAAE,WAAW,GAAG;EAAC,GAC9D;AAEN,QACE,oBAAC;EAAI,cAAY;YACf,oBAAC;GACC,WAAW,GAAG,mBAAmB;IAAE;IAAM;IAAS,CAAC,EAAE,UAAU;GAC/D,GAAK,yBAAyB;IAC5B,WAAW;IACX,UAAU;IACX;GACD,GAAI;aAEH,aAAa,KAAK,MAAM,UAAU;IACjC,MAAM,aAAa,UAAU,aAAa,SAAS;IACnD,MAAM,SACJ,OAAO,SAAS,YAAY,OAAO,KAAK,SAAS;IACnD,MAAM,WACJ,OAAO,SAAS,YAAY,OAAO,KAAK,YAAY;IACtD,MAAM,WAAW,UAAU,aAAa,SAAS;IACjD,MAAM,cAAc,WAAW,cAAc;IAC7C,MAAM,cAAc,SAAS;IAE7B,MAAM,OAAQ,KAAgC,QAAQ;AAEtD,QAAI,YACF,QACE,qBAAC,uBACC,oBAAC;KAAG,WAAU;KAAoB,eAAY;eAC5C,oBAAC;MAAK,WAAU;gBAAmB;OAAQ;MACxC,EACJ,CAAC,cACA,oBAAC;KAAG,eAAY;KAAO,WAAU;eAC9B;MACE,KAPM,aAAa,OASjB;IAIf,IAAI,UACF,oBAAC;KAEC,UAAU,QAAQ;KAClB,gBAAc;KACd,WAAW,GACT,kCACA,YAAY,mBACb;eAEA;OARI,KASA;AAGT,QAAI,OACF,WACE,oBAAC;KAEC,MAAM,KAAK;KACJ;KACP,UAAU,QAAQ;KACV;KACR,gBAAc;KACd,WAAW,GAAG,YAAY,kCAAkC;eAE3D;OARI,KASI;aAEJ,SACT,WACE,oBAAC;KAEC,SAAS,KAAK;KACP;KACP,UAAU,QAAQ;KAClB,gBAAc;KACd,WAAW,GAAG,YAAY,kCAAkC;eAE3D;OAPI,KAQM;IAIjB,MAAM,cACJ,8BAAC;KACC,GAAK,yBAAyB;MAC5B,UAAU;MACV,WAAW;MACX,UAAU;MACX;KACD,KAAK;KACL,WAAU;OAET,QACE;AAGP,QAAI,WACF,QAAO;AAGT,WACE,qBAAC,uBACE,aACD,oBAAC;KAAG,eAAY;KAAO,WAAU;eAC9B;MACE,KAJQ,KAKJ;KAEb;IACC;GACD"}
1
+ {"version":3,"file":"index.mjs","names":["LinkLink: FC<LinkLinkProps>","ButtonLink: FC<ButtonButtonProps>","Span: FC<SpanProps>","Breadcrumb: FC<BreadcrumbProps>"],"sources":["../../../../src/components/Breadcrumb/index.tsx"],"sourcesContent":["'use client';\n\nimport { getIntlayer } from '@intlayer/core';\nimport type { LocalesValues } from '@intlayer/types';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronRightIcon } from 'lucide-react';\nimport { type FC, Fragment, type HTMLAttributes, type ReactNode } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { cn } from '../../utils/cn';\nimport { Button, type ButtonProps, ButtonVariant } from '../Button';\nimport { Link, LinkColor } from '../Link';\n\n/**\n * Props for LinkLink sub-component that renders breadcrumb items as links\n */\ntype LinkLinkProps = {\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n /**\n * Locale for internationalization\n */\n locale?: LocalesValues;\n /**\n * URL to navigate to\n */\n href?: string;\n /**\n * Link color\n */\n color?: LinkColor | `${LinkColor}`;\n /**\n * Click handler\n */\n onClick?: () => void;\n /**\n * Children content\n */\n children?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n} & Omit<\n HTMLAttributes<HTMLAnchorElement>,\n 'href' | 'onClick' | 'color' | 'children' | 'className'\n>;\n\n/**\n * Breadcrumb variant styles using class-variance-authority\n */\nconst breadcrumbVariants = cva('flex flex-row flex-wrap items-center text-sm', {\n variants: {\n size: {\n small: 'gap-1 text-xs',\n medium: 'gap-2 text-sm',\n large: 'gap-3 text-base',\n },\n spacing: {\n compact: 'gap-1',\n normal: 'gap-2',\n loose: 'gap-4',\n },\n },\n defaultVariants: {\n size: 'medium',\n spacing: 'normal',\n },\n});\n\n/**\n * LinkLink sub-component for breadcrumb items that navigate to other pages\n */\nconst LinkLink: FC<LinkLinkProps> = ({\n href,\n lang,\n children,\n onClick,\n color,\n position,\n locale,\n className,\n ...props\n}) => {\n const content = getIntlayer('breadcrumb');\n const linkLabel = content.linkLabel;\n\n return (\n <>\n <Link\n href={href}\n locale={locale}\n color={color}\n onClick={onClick}\n itemProp=\"item\"\n isExternalLink={false}\n itemScope\n itemType=\"https://schema.org/WebPage\"\n {...props}\n label={`${linkLabel} ${children}`}\n itemID={href}\n size=\"sm\"\n >\n <span itemProp=\"name\">{children}</span>\n </Link>\n <meta itemProp=\"position\" content={position.toString()} />\n </>\n );\n};\n\n/**\n * Props for ButtonLink sub-component that renders breadcrumb items as interactive buttons\n */\ntype ButtonButtonProps = {\n /**\n * Text content for the breadcrumb button\n */\n children: string;\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n} & Omit<ButtonProps, 'children' | 'label'>;\n\n/**\n * ButtonLink sub-component for breadcrumb items with click handlers\n */\nconst ButtonLink: FC<ButtonButtonProps> = ({\n children: text,\n onClick,\n color,\n position,\n className,\n ...props\n}) => {\n const { linkLabel } = useIntlayer('breadcrumb');\n\n return (\n <>\n <Button\n onClick={onClick}\n variant={ButtonVariant.LINK}\n label={`${linkLabel} ${text}`}\n color={color}\n itemProp=\"item\"\n {...props}\n >\n <span itemProp=\"name\">{text}</span>\n </Button>\n <meta itemProp=\"position\" content={position.toString()} />\n </>\n );\n};\n\n/**\n * Props for Span sub-component that renders static breadcrumb text\n */\ntype SpanProps = {\n /**\n * Text content for the static breadcrumb item\n */\n children: string;\n /**\n * Position of the breadcrumb item in the list (1-based index)\n */\n position: number;\n} & HTMLAttributes<HTMLSpanElement>;\n\n/**\n * Span sub-component for static breadcrumb text items\n */\nconst Span: FC<SpanProps> = ({ children, position, className, ...props }) => (\n <span\n itemProp=\"item\"\n className={cn(\n 'inline-flex items-center',\n 'font-medium text-neutral-700',\n 'transition-colors duration-200',\n className\n )}\n >\n <span itemProp=\"name\" {...props}>\n {children}\n </span>\n <meta itemProp=\"position\" content={position.toString()} />\n </span>\n);\n\n/**\n * Detailed breadcrumb link configuration with optional href or onClick\n */\ntype DetailedBreadcrumbLink = {\n /**\n * URL to navigate to when the breadcrumb item is clicked\n */\n href?: string;\n /**\n * Text content to display for this breadcrumb item\n */\n text: string;\n /**\n * Custom click handler function for interactive breadcrumb items\n */\n onClick?: () => void;\n};\n\n/**\n * Union type representing different breadcrumb item configurations:\n * - string: Simple text breadcrumb item\n * - DetailedBreadcrumbLink: Object with href, text, and/or onClick properties\n */\nexport type BreadcrumbLink = string | DetailedBreadcrumbLink;\n\nexport type BreadcrumbProps = {\n /**\n * Array of breadcrumb items\n */\n links: BreadcrumbLink[];\n /**\n * Color scheme for breadcrumb links\n * @default LinkColor.TEXT\n */\n color?: LinkColor | `${LinkColor}`;\n /**\n * Locale for internationalization\n */\n locale?: LocalesValues;\n /**\n * Element type for ARIA current attribute\n * @default 'page'\n */\n elementType?: 'page' | 'location';\n /**\n * Custom separator between breadcrumb items\n * @default ChevronRightIcon\n */\n separator?: ReactNode;\n /**\n * ARIA label for breadcrumb navigation\n * @default 'breadcrumb'\n */\n ariaLabel?: string;\n /**\n * Whether to include structured data markup\n * @default true\n */\n includeStructuredData?: boolean;\n /**\n * Maximum number of breadcrumb items to show before truncation\n */\n maxItems?: number;\n} & VariantProps<typeof breadcrumbVariants> &\n HTMLAttributes<HTMLOListElement>;\n\n/**\n * Breadcrumb component providing navigational context with accessibility features\n *\n * Features:\n * - Supports links, buttons, and static text elements\n * - Full keyboard navigation support\n * - ARIA attributes for screen readers\n * - Schema.org structured data for SEO\n * - Customizable separators and styling\n * - Internationalization support\n * - Responsive design variants\n *\n * @example\n * ```tsx\n * <Breadcrumb\n * links={[\n * 'Home',\n * { href: '/products', text: 'Products' },\n * { onClick: handleCategory, text: 'Electronics' },\n * 'Smartphones'\n * ]}\n * size=\"medium\"\n * ariaLabel=\"Product navigation\"\n * />\n * ```\n */\nexport const Breadcrumb: FC<BreadcrumbProps> = ({\n links,\n className,\n color = LinkColor.TEXT,\n locale,\n elementType = 'page',\n separator = <ChevronRightIcon size={10} />,\n ariaLabel = 'breadcrumb',\n includeStructuredData = true,\n maxItems,\n size,\n spacing,\n ...props\n}) => {\n const displayLinks =\n maxItems && links.length > maxItems\n ? [...links.slice(0, 1), '...', ...links.slice(-(maxItems - 2))]\n : links;\n\n return (\n <nav aria-label={ariaLabel}>\n <ol\n className={cn(breadcrumbVariants({ size, spacing }), className)}\n {...(includeStructuredData && {\n itemScope: true,\n itemType: 'http://schema.org/BreadcrumbList',\n })}\n {...props}\n >\n {displayLinks.map((link, index) => {\n const isLastLink = index === displayLinks.length - 1;\n const isLink =\n typeof link === 'object' && typeof link.href === 'string';\n const isButton =\n typeof link === 'object' && typeof link.onClick === 'function';\n const isActive = index === displayLinks.length - 1;\n const ariaCurrent = isActive ? elementType : undefined;\n const isTruncated = link === '...';\n\n const text = (link as DetailedBreadcrumbLink).text ?? link;\n\n if (isTruncated) {\n return (\n <Fragment key={`truncated-${text}`}>\n <li className=\"flex items-center\" aria-hidden=\"true\">\n <span className=\"text-neutral-500\">…</span>\n </li>\n {!isLastLink && (\n <li aria-hidden=\"true\" className=\"flex items-center\">\n {separator}\n </li>\n )}\n </Fragment>\n );\n }\n\n let section = (\n <Span\n key={text}\n position={index + 1}\n aria-current={ariaCurrent}\n className={cn(\n 'transition-colors duration-200',\n isActive && 'text-neutral-900'\n )}\n >\n {text}\n </Span>\n );\n\n if (isLink) {\n section = (\n <LinkLink\n key={text}\n href={link.href!}\n color={color}\n position={index + 1}\n locale={locale}\n aria-current={ariaCurrent}\n className={cn(isActive && 'cursor-default text-neutral-900')}\n >\n {text}\n </LinkLink>\n );\n } else if (isButton) {\n section = (\n <ButtonLink\n key={text}\n onClick={link.onClick!}\n color={color}\n position={index + 1}\n aria-current={ariaCurrent}\n className={cn(isActive && 'cursor-default text-neutral-900')}\n >\n {text}\n </ButtonLink>\n );\n }\n\n const listElement = (\n <li\n {...(includeStructuredData && {\n itemProp: 'itemListElement',\n itemScope: true,\n itemType: 'https://schema.org/ListItem',\n })}\n key={text}\n className=\"flex items-center\"\n >\n {section}\n </li>\n );\n\n if (isLastLink) {\n return listElement;\n }\n\n return (\n <Fragment key={text}>\n {listElement}\n <li aria-hidden=\"true\" className=\"flex items-center\">\n {separator}\n </li>\n </Fragment>\n );\n })}\n </ol>\n </nav>\n );\n};\n"],"mappings":"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"}
@@ -93,13 +93,13 @@ const buttonVariants = cva("relative inline-flex cursor-pointer items-center jus
93
93
  [`${ButtonColor.PRIMARY}`]: "hover-primary-500/20 text-primary ring-primary-500/20 *:text-text-light",
94
94
  [`${ButtonColor.SECONDARY}`]: "hover-secondary-500/20 text-secondary ring-secondary-500/20 *:text-text-light",
95
95
  [`${ButtonColor.DESTRUCTIVE}`]: "hover-destructive-500/20 text-destructive ring-destructive-500/20 *:text-text-light",
96
- [`${ButtonColor.NEUTRAL}`]: "hover-neutral-500/20 text-neutral ring-neutral-500/20 *:text-text-light",
96
+ [`${ButtonColor.NEUTRAL}`]: "text-neutral ring-neutral-500/20 *:text-text-light",
97
97
  [`${ButtonColor.CARD}`]: "hover-card-500/20 text-card ring-card-500/20 *:text-text-light",
98
98
  [`${ButtonColor.LIGHT}`]: "hover-white-500/20 text-white ring-white/20 *:text-text-light",
99
- [`${ButtonColor.DARK}`]: "hover-neutral-500/20 text-neutral-800 ring-neutral-800/50 *:text-text-light",
100
- [`${ButtonColor.TEXT}`]: "hover-neutral-500/20 text-text ring-neutral-500/20 *:text-text-opposite",
101
- [`${ButtonColor.CURRENT}`]: "hover-current-500/20 text-current ring-current/20 *:text-text-light",
102
- [`${ButtonColor.TEXT_INVERSE}`]: "hover-neutral-500/20 text-text-opposite ring-neutral-500/20 *:text-text",
99
+ [`${ButtonColor.DARK}`]: "text-neutral-800 ring-text-light/50 *:text-text-light",
100
+ [`${ButtonColor.TEXT}`]: "text-text ring-text/20 *:text-text-opposite",
101
+ [`${ButtonColor.CURRENT}`]: "hover-current-500/10 text-current ring-current/10 *:text-text-light",
102
+ [`${ButtonColor.TEXT_INVERSE}`]: "text-text-opposite ring-text-opposite/20 *:text-text",
103
103
  [`${ButtonColor.ERROR}`]: "hover-error-500/20 text-error ring-error/20 *:text-text-light",
104
104
  [`${ButtonColor.SUCCESS}`]: "hover-success-500/20 text-success ring-success/20 *:text-text-light",
105
105
  [`${ButtonColor.CUSTOM}`]: ""
@@ -109,26 +109,31 @@ const buttonVariants = cva("relative inline-flex cursor-pointer items-center jus
109
109
  [`${ContainerRoundedSize.SM}`]: "rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl",
110
110
  [`${ContainerRoundedSize.MD}`]: "rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl",
111
111
  [`${ContainerRoundedSize.LG}`]: "rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl",
112
- [`${ContainerRoundedSize.XL}`]: "rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl"
112
+ [`${ContainerRoundedSize.XL}`]: "rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl",
113
+ [`${ContainerRoundedSize["2xl"]}`]: "rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]",
114
+ [`${ContainerRoundedSize["3xl"]}`]: "rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]",
115
+ [`${ContainerRoundedSize["4xl"]}`]: "rounded-[3rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[4rem]",
116
+ [`${ContainerRoundedSize["5xl"]}`]: "rounded-[4rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[5rem]",
117
+ [`${ContainerRoundedSize.FULL}`]: "rounded-full"
113
118
  },
114
119
  variant: {
115
120
  [`${ButtonVariant.DEFAULT}`]: [
116
121
  "bg-current",
117
122
  "hover:bg-current/90",
118
- "hover:ring-6",
119
- "aria-selected:ring-6"
123
+ "hover:ring-5",
124
+ "aria-selected:ring-5"
120
125
  ],
121
126
  [`${ButtonVariant.OUTLINE}`]: [
122
- "rounded-2xl border-[1.5px] border-current bg-current/0 *:text-current!",
123
- "hover:bg-current/10",
124
- "hover:ring-6",
125
- "aria-selected:ring-6"
127
+ "rounded-2xl border-[1.3px] border-current bg-current/0 *:text-current!",
128
+ "hover:bg-current/20 focus-visible:bg-current/20",
129
+ "hover:ring-5 focus-visible:ring-5",
130
+ "aria-selected:ring-5"
126
131
  ],
127
132
  [`${ButtonVariant.NONE}`]: "border-none bg-current/0 text-inherit hover:bg-current/0",
128
133
  [`${ButtonVariant.LINK}`]: "h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent hover:underline",
129
134
  [`${ButtonVariant.INVISIBLE_LINK}`]: "h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent",
130
- [`${ButtonVariant.HOVERABLE}`]: "rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5",
131
- [`${ButtonVariant.FADE}`]: "rounded-lg border-none bg-current/10 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5",
135
+ [`${ButtonVariant.HOVERABLE}`]: "rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5",
136
+ [`${ButtonVariant.FADE}`]: "rounded-lg border-none bg-current/20 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5",
132
137
  [`${ButtonVariant.INPUT}`]: [
133
138
  "text-text",
134
139
  "w-full select-text resize-none rounded-2xl text-base shadow-none outline-none supports-[corner-shape:squircle]:rounded-4xl",
@@ -204,7 +209,7 @@ const buttonVariants = cva("relative inline-flex cursor-pointer items-center jus
204
209
  * </Button>
205
210
  * ```
206
211
  */
207
- const Button = ({ variant, size, color, children, Icon, IconRight, iconClassName, isLoading = false, isActive = false, isSelected = false, isFullWidth = false, roundedSize, textAlign, disabled, label, className, type = "button", "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-haspopup": ariaHasPopup, "aria-pressed": ariaPressed, ...props }) => {
212
+ const Button = ({ variant, size, color, children, Icon, IconRight, iconClassName, isLoading = false, isActive, isSelected, isFullWidth, roundedSize, textAlign, disabled, label, className, type = "button", "aria-describedby": ariaDescribedBy, "aria-expanded": ariaExpanded, "aria-haspopup": ariaHasPopup, "aria-pressed": ariaPressed, ...props }) => {
208
213
  const isLink = variant === `${ButtonVariant.LINK}` || variant === `${ButtonVariant.INVISIBLE_LINK}`;
209
214
  const isIconOnly = !children && (Icon || IconRight);
210
215
  const accessibilityProps = {
@@ -1 +1 @@
1
- {"version":3,"file":"Button.mjs","names":["Button: FC<ButtonProps>"],"sources":["../../../../src/components/Button/Button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { LucideIcon } from 'lucide-react';\nimport type { ButtonHTMLAttributes, DetailedHTMLProps, FC } from 'react';\nimport { cn } from '../../utils/cn';\nimport { ContainerRoundedSize } from '../Container';\nimport { Loader } from '../Loader';\n\n/**\n * Button size variants for different use cases\n */\nexport enum ButtonSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n ICON_SM = 'icon-sm',\n ICON_MD = 'icon-md',\n ICON_LG = 'icon-lg',\n ICON_XL = 'icon-xl',\n}\n\nconst buttonIconVariants = cva('flex-none shrink-0', {\n variants: {\n size: {\n [`${ButtonSize.SM}`]: 'size-3',\n [`${ButtonSize.MD}`]: 'size-4',\n [`${ButtonSize.LG}`]: 'size-5',\n [`${ButtonSize.XL}`]: 'size-6',\n [`${ButtonSize.ICON_SM}`]: 'size-3',\n [`${ButtonSize.ICON_MD}`]: 'size-4',\n [`${ButtonSize.ICON_LG}`]: 'size-4',\n [`${ButtonSize.ICON_XL}`]: 'size-5',\n },\n },\n defaultVariants: {\n size: ButtonSize.MD,\n },\n});\n\n/**\n * Button visual style variants\n */\nexport enum ButtonVariant {\n DEFAULT = 'default',\n NONE = 'none',\n OUTLINE = 'outline',\n LINK = 'link',\n INVISIBLE_LINK = 'invisible-link',\n HOVERABLE = 'hoverable',\n FADE = 'fade',\n INPUT = 'input',\n}\n\n/**\n * Button color themes that work with the design system\n */\nexport enum ButtonColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n CARD = 'card',\n TEXT_INVERSE = 'text-inverse',\n CURRENT = 'current',\n ERROR = 'error',\n SUCCESS = 'success',\n CUSTOM = 'custom',\n}\n\n/**\n * Text alignment options for button content\n */\nexport enum ButtonTextAlign {\n LEFT = 'left',\n CENTER = 'center',\n RIGHT = 'right',\n}\n\n/**\n * Enhanced button variants with improved accessibility and focus states\n */\nexport const buttonVariants = cva(\n 'relative inline-flex cursor-pointer items-center justify-center font-medium ring-0 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n size: {\n [`${ButtonSize.SM}`]: 'min-h-7 px-3 text-xs max-md:py-1',\n [`${ButtonSize.MD}`]: 'min-h-8 px-6 text-sm max-md:py-2',\n [`${ButtonSize.LG}`]: 'min-h-10 px-8 text-lg max-md:py-3',\n [`${ButtonSize.XL}`]: 'min-h-11 px-10 text-xl max-md:py-4',\n [`${ButtonSize.ICON_SM}`]: 'p-1.5',\n [`${ButtonSize.ICON_MD}`]: 'p-1.5',\n [`${ButtonSize.ICON_LG}`]: 'p-2',\n [`${ButtonSize.ICON_XL}`]: 'p-3',\n },\n color: {\n [`${ButtonColor.PRIMARY}`]:\n 'hover-primary-500/20 text-primary ring-primary-500/20 *:text-text-light',\n [`${ButtonColor.SECONDARY}`]:\n 'hover-secondary-500/20 text-secondary ring-secondary-500/20 *:text-text-light',\n [`${ButtonColor.DESTRUCTIVE}`]:\n 'hover-destructive-500/20 text-destructive ring-destructive-500/20 *:text-text-light',\n [`${ButtonColor.NEUTRAL}`]:\n 'hover-neutral-500/20 text-neutral ring-neutral-500/20 *:text-text-light',\n [`${ButtonColor.CARD}`]:\n 'hover-card-500/20 text-card ring-card-500/20 *:text-text-light',\n [`${ButtonColor.LIGHT}`]:\n 'hover-white-500/20 text-white ring-white/20 *:text-text-light',\n [`${ButtonColor.DARK}`]:\n 'hover-neutral-500/20 text-neutral-800 ring-neutral-800/50 *:text-text-light',\n [`${ButtonColor.TEXT}`]:\n 'hover-neutral-500/20 text-text ring-neutral-500/20 *:text-text-opposite',\n [`${ButtonColor.CURRENT}`]:\n 'hover-current-500/20 text-current ring-current/20 *:text-text-light',\n [`${ButtonColor.TEXT_INVERSE}`]:\n 'hover-neutral-500/20 text-text-opposite ring-neutral-500/20 *:text-text',\n [`${ButtonColor.ERROR}`]:\n 'hover-error-500/20 text-error ring-error/20 *:text-text-light',\n [`${ButtonColor.SUCCESS}`]:\n 'hover-success-500/20 text-success ring-success/20 *:text-text-light',\n [`${ButtonColor.CUSTOM}`]: '',\n },\n roundedSize: {\n [`${ContainerRoundedSize.NONE}`]: 'rounded-none',\n [`${ContainerRoundedSize.SM}`]:\n 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n [`${ContainerRoundedSize.MD}`]:\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n [`${ContainerRoundedSize.LG}`]:\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n [`${ContainerRoundedSize.XL}`]:\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n },\n variant: {\n [`${ButtonVariant.DEFAULT}`]: [\n 'bg-current',\n 'hover:bg-current/90',\n\n // Hover ring (similar spirit to your input)\n 'hover:ring-6', // width\n 'aria-selected:ring-6',\n ],\n\n [`${ButtonVariant.OUTLINE}`]: [\n 'rounded-2xl border-[1.5px] border-current bg-current/0 *:text-current!',\n 'hover:bg-current/10',\n\n // Same hover ring behavior as DEFAULT for coherence\n 'hover:ring-6',\n 'aria-selected:ring-6',\n ],\n\n [`${ButtonVariant.NONE}`]:\n 'border-none bg-current/0 text-inherit hover:bg-current/0',\n\n [`${ButtonVariant.LINK}`]:\n 'h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent hover:underline',\n\n [`${ButtonVariant.INVISIBLE_LINK}`]:\n 'h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent',\n\n [`${ButtonVariant.HOVERABLE}`]:\n 'rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5',\n\n [`${ButtonVariant.FADE}`]:\n 'rounded-lg border-none bg-current/10 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5',\n\n [`${ButtonVariant.INPUT}`]: [\n // base styles\n 'text-text',\n 'w-full select-text resize-none rounded-2xl text-base shadow-none outline-none supports-[corner-shape:squircle]:rounded-4xl',\n 'transition-shadow duration-100 md:text-sm',\n 'ring-0', // base ring\n 'disabled:opacity-50',\n\n 'text-text',\n 'bg-neutral-50 dark:bg-neutral-950',\n 'ring-neutral-100 dark:ring-neutral-700',\n\n // Hover ring (similar spirit to your input)\n 'hover:ring-3', // width\n 'aria-selected:ring-4',\n 'focus-visible:ring-3',\n 'disabled:ring-0',\n\n // Focus ring + animation\n 'focus-visible:outline-none',\n\n // Remove any weird box-shadow\n '[box-shadow:none] focus:[box-shadow:none]',\n\n // aria-invalid border color\n 'aria-invalid:border-error',\n ],\n },\n\n textAlign: {\n [`${ButtonTextAlign.LEFT}`]: 'justify-start text-left',\n [`${ButtonTextAlign.CENTER}`]: 'justify-center text-center',\n [`${ButtonTextAlign.RIGHT}`]: 'justify-end text-right',\n },\n\n isFullWidth: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: `${ButtonVariant.DEFAULT}`,\n size: `${ButtonSize.MD}`,\n color: `${ButtonColor.CUSTOM}`,\n roundedSize: `${ContainerRoundedSize.MD}`,\n textAlign: `${ButtonTextAlign.CENTER}`,\n isFullWidth: false,\n },\n }\n);\n\n/**\n * Enhanced Button component props with comprehensive type safety and accessibility features\n */\nexport type ButtonProps = DetailedHTMLProps<\n ButtonHTMLAttributes<HTMLButtonElement>,\n HTMLButtonElement\n> &\n VariantProps<typeof buttonVariants> & {\n /**\n * Accessible label for screen readers and assistive technologies.\n * This is required for accessibility compliance.\n */\n label: string | null;\n\n /**\n * Optional icon to display on the left side of the button\n */\n Icon?: FC | LucideIcon;\n\n /**\n * Optional icon to display on the right side of the button\n */\n IconRight?: FC | LucideIcon;\n\n /**\n * Additional CSS classes for icon styling\n */\n iconClassName?: string;\n\n /**\n * Shows loading spinner and disables button interaction when true\n */\n isLoading?: boolean;\n\n /**\n * Marks the button as active (useful for navigation or toggle states)\n */\n isActive?: boolean;\n\n /**\n * Marks the button as selected\n */\n isSelected?: boolean;\n\n /**\n * Makes the button span the full width of its container\n */\n isFullWidth?: boolean;\n\n /**\n * Additional description for complex buttons (optional)\n */\n 'aria-describedby'?: string;\n\n /**\n * Expanded state for collapsible sections (optional)\n */\n 'aria-expanded'?: boolean;\n\n /**\n * Controls whether the button has popup/menu (optional)\n */\n 'aria-haspopup'?:\n | boolean\n | 'true'\n | 'false'\n | 'menu'\n | 'listbox'\n | 'tree'\n | 'grid'\n | 'dialog';\n\n /**\n * Indicates if button controls are currently pressed (for toggle buttons)\n */\n 'aria-pressed'?: boolean;\n };\n\n/**\n * Button Component - A comprehensive, accessible button component\n *\n * Features:\n * - Full accessibility compliance with ARIA attributes\n * - Multiple variants and sizes for different use cases\n * - Icon support (left and right positioning)\n * - Loading states with spinner\n * - Keyboard navigation support\n * - Focus management with visible indicators\n * - Responsive design adaptations\n *\n * @example\n * ```tsx\n * // Basic button\n * <Button label=\"Click me\">Click me</Button>\n *\n * // Button with icon and loading state\n * <Button\n * label=\"Save document\"\n * Icon={SaveIcon}\n * isLoading={saving}\n * disabled={!hasChanges}\n * >\n * Save\n * </Button>\n *\n * // Destructive action button\n * <Button\n * variant={`${ButtonVariant.OUTLINE}`}\n * color={ButtonColor.DESTRUCTIVE}\n * label=\"Delete item permanently\"\n * aria-describedby=\"delete-warning\"\n * >\n * Delete\n * </Button>\n * ```\n */\nexport const Button: FC<ButtonProps> = ({\n variant,\n size,\n color,\n children,\n Icon,\n IconRight,\n iconClassName,\n isLoading = false,\n isActive = false,\n isSelected = false,\n isFullWidth = false,\n roundedSize,\n textAlign,\n disabled,\n label,\n className,\n type = 'button',\n 'aria-describedby': ariaDescribedBy,\n 'aria-expanded': ariaExpanded,\n 'aria-haspopup': ariaHasPopup,\n 'aria-pressed': ariaPressed,\n ...props\n}) => {\n const isLink =\n variant === `${ButtonVariant.LINK}` ||\n variant === `${ButtonVariant.INVISIBLE_LINK}`;\n const isIconOnly = !children && (Icon || IconRight);\n\n const accessibilityProps = {\n 'aria-label': isIconOnly ? (label ?? undefined) : undefined,\n 'aria-labelledby': !isIconOnly ? undefined : undefined,\n 'aria-describedby': ariaDescribedBy,\n 'aria-expanded': ariaExpanded,\n 'aria-haspopup': ariaHasPopup,\n 'aria-pressed': isActive !== undefined ? isActive : ariaPressed,\n 'aria-busy': isLoading,\n 'aria-current': (isActive ? 'page' : undefined) as 'page' | undefined,\n 'aria-disabled': disabled || isLoading,\n 'aria-selected': isSelected,\n };\n\n const isSquareButton =\n size === ButtonSize.ICON_SM ||\n size === ButtonSize.ICON_MD ||\n size === ButtonSize.ICON_LG ||\n size === ButtonSize.ICON_XL;\n\n return (\n <button\n disabled={isLoading || disabled}\n role={isLink ? 'link' : 'button'}\n type={type}\n className={buttonVariants({\n variant,\n size,\n color,\n isFullWidth,\n roundedSize,\n textAlign:\n textAlign ??\n (IconRight ? ButtonTextAlign.LEFT : ButtonTextAlign.CENTER),\n className,\n })}\n {...accessibilityProps}\n {...props}\n >\n {Icon && !isLoading && (\n <Icon\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'mr-3', iconClassName),\n })}\n aria-hidden=\"true\"\n />\n )}\n\n <div\n className={cn(\n 'flex w-0 items-center justify-center transition-[width] duration-300',\n isLoading && size === ButtonSize.SM && 'w-3',\n isLoading && size === ButtonSize.MD && 'w-4',\n isLoading && size === ButtonSize.LG && 'w-5',\n isLoading && size === ButtonSize.XL && 'w-6'\n )}\n >\n <Loader\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'mr-3', iconClassName),\n })}\n isLoading={isLoading}\n aria-hidden=\"true\"\n data-testid=\"loader\"\n />\n </div>\n\n {children && (\n <span className=\"flex-1 truncate whitespace-nowrap\">{children}</span>\n )}\n\n {!children && isIconOnly && <span className=\"sr-only\">{label}</span>}\n\n {IconRight && (\n <IconRight\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'ml-3', iconClassName),\n })}\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Button.mjs","names":["ButtonRoundedSize","Button: FC<ButtonProps>"],"sources":["../../../../src/components/Button/Button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { LucideIcon } from 'lucide-react';\nimport type { ButtonHTMLAttributes, DetailedHTMLProps, FC } from 'react';\nimport { cn } from '../../utils/cn';\nimport { ContainerRoundedSize as ButtonRoundedSize } from '../Container';\nimport { Loader } from '../Loader';\n\n/**\n * Button size variants for different use cases\n */\nexport enum ButtonSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n ICON_SM = 'icon-sm',\n ICON_MD = 'icon-md',\n ICON_LG = 'icon-lg',\n ICON_XL = 'icon-xl',\n}\n\nconst buttonIconVariants = cva('flex-none shrink-0', {\n variants: {\n size: {\n [`${ButtonSize.SM}`]: 'size-3',\n [`${ButtonSize.MD}`]: 'size-4',\n [`${ButtonSize.LG}`]: 'size-5',\n [`${ButtonSize.XL}`]: 'size-6',\n [`${ButtonSize.ICON_SM}`]: 'size-3',\n [`${ButtonSize.ICON_MD}`]: 'size-4',\n [`${ButtonSize.ICON_LG}`]: 'size-4',\n [`${ButtonSize.ICON_XL}`]: 'size-5',\n },\n },\n defaultVariants: {\n size: ButtonSize.MD,\n },\n});\n\n/**\n * Button visual style variants\n */\nexport enum ButtonVariant {\n DEFAULT = 'default',\n NONE = 'none',\n OUTLINE = 'outline',\n LINK = 'link',\n INVISIBLE_LINK = 'invisible-link',\n HOVERABLE = 'hoverable',\n FADE = 'fade',\n INPUT = 'input',\n}\n\n/**\n * Button color themes that work with the design system\n */\nexport enum ButtonColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n CARD = 'card',\n TEXT_INVERSE = 'text-inverse',\n CURRENT = 'current',\n ERROR = 'error',\n SUCCESS = 'success',\n CUSTOM = 'custom',\n}\n\n/**\n * Text alignment options for button content\n */\nexport enum ButtonTextAlign {\n LEFT = 'left',\n CENTER = 'center',\n RIGHT = 'right',\n}\n\n/**\n * Enhanced button variants with improved accessibility and focus states\n */\nexport const buttonVariants = cva(\n 'relative inline-flex cursor-pointer items-center justify-center font-medium ring-0 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n size: {\n [`${ButtonSize.SM}`]: 'min-h-7 px-3 text-xs max-md:py-1',\n [`${ButtonSize.MD}`]: 'min-h-8 px-6 text-sm max-md:py-2',\n [`${ButtonSize.LG}`]: 'min-h-10 px-8 text-lg max-md:py-3',\n [`${ButtonSize.XL}`]: 'min-h-11 px-10 text-xl max-md:py-4',\n [`${ButtonSize.ICON_SM}`]: 'p-1.5',\n [`${ButtonSize.ICON_MD}`]: 'p-1.5',\n [`${ButtonSize.ICON_LG}`]: 'p-2',\n [`${ButtonSize.ICON_XL}`]: 'p-3',\n },\n color: {\n [`${ButtonColor.PRIMARY}`]:\n 'hover-primary-500/20 text-primary ring-primary-500/20 *:text-text-light',\n [`${ButtonColor.SECONDARY}`]:\n 'hover-secondary-500/20 text-secondary ring-secondary-500/20 *:text-text-light',\n [`${ButtonColor.DESTRUCTIVE}`]:\n 'hover-destructive-500/20 text-destructive ring-destructive-500/20 *:text-text-light',\n [`${ButtonColor.NEUTRAL}`]:\n 'text-neutral ring-neutral-500/20 *:text-text-light',\n [`${ButtonColor.CARD}`]:\n 'hover-card-500/20 text-card ring-card-500/20 *:text-text-light',\n [`${ButtonColor.LIGHT}`]:\n 'hover-white-500/20 text-white ring-white/20 *:text-text-light',\n [`${ButtonColor.DARK}`]:\n 'text-neutral-800 ring-text-light/50 *:text-text-light',\n [`${ButtonColor.TEXT}`]: 'text-text ring-text/20 *:text-text-opposite',\n [`${ButtonColor.CURRENT}`]:\n 'hover-current-500/10 text-current ring-current/10 *:text-text-light',\n [`${ButtonColor.TEXT_INVERSE}`]:\n 'text-text-opposite ring-text-opposite/20 *:text-text',\n [`${ButtonColor.ERROR}`]:\n 'hover-error-500/20 text-error ring-error/20 *:text-text-light',\n [`${ButtonColor.SUCCESS}`]:\n 'hover-success-500/20 text-success ring-success/20 *:text-text-light',\n [`${ButtonColor.CUSTOM}`]: '',\n },\n roundedSize: {\n [`${ButtonRoundedSize.NONE}`]: 'rounded-none',\n [`${ButtonRoundedSize.SM}`]:\n 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n [`${ButtonRoundedSize.MD}`]:\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n [`${ButtonRoundedSize.LG}`]:\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n [`${ButtonRoundedSize.XL}`]:\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n [`${ButtonRoundedSize['2xl']}`]:\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n [`${ButtonRoundedSize['3xl']}`]:\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n [`${ButtonRoundedSize['4xl']}`]:\n 'rounded-[3rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[4rem]',\n [`${ButtonRoundedSize['5xl']}`]:\n 'rounded-[4rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[5rem]',\n [`${ButtonRoundedSize.FULL}`]: 'rounded-full',\n },\n variant: {\n [`${ButtonVariant.DEFAULT}`]: [\n 'bg-current',\n 'hover:bg-current/90',\n 'hover:ring-5',\n 'aria-selected:ring-5',\n ],\n\n [`${ButtonVariant.OUTLINE}`]: [\n 'rounded-2xl border-[1.3px] border-current bg-current/0 *:text-current!',\n 'hover:bg-current/20 focus-visible:bg-current/20',\n 'hover:ring-5 focus-visible:ring-5',\n 'aria-selected:ring-5',\n ],\n\n [`${ButtonVariant.NONE}`]:\n 'border-none bg-current/0 text-inherit hover:bg-current/0',\n\n [`${ButtonVariant.LINK}`]:\n 'h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent hover:underline',\n\n [`${ButtonVariant.INVISIBLE_LINK}`]:\n 'h-auto justify-start border-inherit bg-transparent px-1 underline-offset-4 *:text-current! hover:bg-transparent',\n\n [`${ButtonVariant.HOVERABLE}`]:\n 'rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5',\n\n [`${ButtonVariant.FADE}`]:\n 'rounded-lg border-none bg-current/20 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5',\n\n [`${ButtonVariant.INPUT}`]: [\n // base styles\n 'text-text',\n 'w-full select-text resize-none rounded-2xl text-base shadow-none outline-none supports-[corner-shape:squircle]:rounded-4xl',\n 'transition-shadow duration-100 md:text-sm',\n 'ring-0', // base ring\n 'disabled:opacity-50',\n\n 'text-text',\n 'bg-neutral-50 dark:bg-neutral-950',\n 'ring-neutral-100 dark:ring-neutral-700',\n\n // Hover ring (similar spirit to your input)\n 'hover:ring-3', // width\n 'aria-selected:ring-4',\n 'focus-visible:ring-3',\n 'disabled:ring-0',\n\n // Focus ring + animation\n 'focus-visible:outline-none',\n\n // Remove any weird box-shadow\n '[box-shadow:none] focus:[box-shadow:none]',\n\n // aria-invalid border color\n 'aria-invalid:border-error',\n ],\n },\n\n textAlign: {\n [`${ButtonTextAlign.LEFT}`]: 'justify-start text-left',\n [`${ButtonTextAlign.CENTER}`]: 'justify-center text-center',\n [`${ButtonTextAlign.RIGHT}`]: 'justify-end text-right',\n },\n\n isFullWidth: {\n true: 'w-full',\n false: '',\n },\n },\n defaultVariants: {\n variant: `${ButtonVariant.DEFAULT}`,\n size: `${ButtonSize.MD}`,\n color: `${ButtonColor.CUSTOM}`,\n roundedSize: `${ButtonRoundedSize.MD}`,\n textAlign: `${ButtonTextAlign.CENTER}`,\n isFullWidth: false,\n },\n }\n);\n\n/**\n * Enhanced Button component props with comprehensive type safety and accessibility features\n */\nexport type ButtonProps = DetailedHTMLProps<\n ButtonHTMLAttributes<HTMLButtonElement>,\n HTMLButtonElement\n> &\n VariantProps<typeof buttonVariants> & {\n /**\n * Accessible label for screen readers and assistive technologies.\n * This is required for accessibility compliance.\n */\n label: string | null;\n\n /**\n * Optional icon to display on the left side of the button\n */\n Icon?: FC | LucideIcon;\n\n /**\n * Optional icon to display on the right side of the button\n */\n IconRight?: FC | LucideIcon;\n\n /**\n * Additional CSS classes for icon styling\n */\n iconClassName?: string;\n\n /**\n * Shows loading spinner and disables button interaction when true\n */\n isLoading?: boolean;\n\n /**\n * Marks the button as active (useful for navigation or toggle states)\n */\n isActive?: boolean;\n\n /**\n * Marks the button as selected\n */\n isSelected?: boolean;\n\n /**\n * Makes the button span the full width of its container\n */\n isFullWidth?: boolean;\n\n /**\n * Additional description for complex buttons (optional)\n */\n 'aria-describedby'?: string;\n\n /**\n * Expanded state for collapsible sections (optional)\n */\n 'aria-expanded'?: boolean;\n\n /**\n * Controls whether the button has popup/menu (optional)\n */\n 'aria-haspopup'?:\n | boolean\n | 'true'\n | 'false'\n | 'menu'\n | 'listbox'\n | 'tree'\n | 'grid'\n | 'dialog';\n\n /**\n * Indicates if button controls are currently pressed (for toggle buttons)\n */\n 'aria-pressed'?: boolean;\n };\n\n/**\n * Button Component - A comprehensive, accessible button component\n *\n * Features:\n * - Full accessibility compliance with ARIA attributes\n * - Multiple variants and sizes for different use cases\n * - Icon support (left and right positioning)\n * - Loading states with spinner\n * - Keyboard navigation support\n * - Focus management with visible indicators\n * - Responsive design adaptations\n *\n * @example\n * ```tsx\n * // Basic button\n * <Button label=\"Click me\">Click me</Button>\n *\n * // Button with icon and loading state\n * <Button\n * label=\"Save document\"\n * Icon={SaveIcon}\n * isLoading={saving}\n * disabled={!hasChanges}\n * >\n * Save\n * </Button>\n *\n * // Destructive action button\n * <Button\n * variant={`${ButtonVariant.OUTLINE}`}\n * color={ButtonColor.DESTRUCTIVE}\n * label=\"Delete item permanently\"\n * aria-describedby=\"delete-warning\"\n * >\n * Delete\n * </Button>\n * ```\n */\nexport const Button: FC<ButtonProps> = ({\n variant,\n size,\n color,\n children,\n Icon,\n IconRight,\n iconClassName,\n isLoading = false,\n isActive,\n isSelected,\n isFullWidth,\n roundedSize,\n textAlign,\n disabled,\n label,\n className,\n type = 'button',\n 'aria-describedby': ariaDescribedBy,\n 'aria-expanded': ariaExpanded,\n 'aria-haspopup': ariaHasPopup,\n 'aria-pressed': ariaPressed,\n ...props\n}) => {\n const isLink =\n variant === `${ButtonVariant.LINK}` ||\n variant === `${ButtonVariant.INVISIBLE_LINK}`;\n const isIconOnly = !children && (Icon || IconRight);\n\n const accessibilityProps = {\n 'aria-label': isIconOnly ? (label ?? undefined) : undefined,\n 'aria-labelledby': !isIconOnly ? undefined : undefined,\n 'aria-describedby': ariaDescribedBy,\n 'aria-expanded': ariaExpanded,\n 'aria-haspopup': ariaHasPopup,\n 'aria-pressed': isActive !== undefined ? isActive : ariaPressed,\n 'aria-busy': isLoading,\n 'aria-current': (isActive ? 'page' : undefined) as 'page' | undefined,\n 'aria-disabled': disabled || isLoading,\n 'aria-selected': isSelected,\n };\n\n const isSquareButton =\n size === ButtonSize.ICON_SM ||\n size === ButtonSize.ICON_MD ||\n size === ButtonSize.ICON_LG ||\n size === ButtonSize.ICON_XL;\n\n return (\n <button\n disabled={isLoading || disabled}\n role={isLink ? 'link' : 'button'}\n type={type}\n className={buttonVariants({\n variant,\n size,\n color,\n isFullWidth,\n roundedSize,\n textAlign:\n textAlign ??\n (IconRight ? ButtonTextAlign.LEFT : ButtonTextAlign.CENTER),\n className,\n })}\n {...accessibilityProps}\n {...props}\n >\n {Icon && !isLoading && (\n <Icon\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'mr-3', iconClassName),\n })}\n aria-hidden=\"true\"\n />\n )}\n\n <div\n className={cn(\n 'flex w-0 items-center justify-center transition-[width] duration-300',\n isLoading && size === ButtonSize.SM && 'w-3',\n isLoading && size === ButtonSize.MD && 'w-4',\n isLoading && size === ButtonSize.LG && 'w-5',\n isLoading && size === ButtonSize.XL && 'w-6'\n )}\n >\n <Loader\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'mr-3', iconClassName),\n })}\n isLoading={isLoading}\n aria-hidden=\"true\"\n data-testid=\"loader\"\n />\n </div>\n\n {children && (\n <span className=\"flex-1 truncate whitespace-nowrap\">{children}</span>\n )}\n\n {!children && isIconOnly && <span className=\"sr-only\">{label}</span>}\n\n {IconRight && (\n <IconRight\n className={buttonIconVariants({\n size,\n className: cn(!isSquareButton && 'ml-3', iconClassName),\n })}\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n};\n"],"mappings":"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"}
@@ -17,6 +17,7 @@ const containerVariants = cva("flex flex-col text-text backdrop-blur", {
17
17
  xl: "rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl",
18
18
  "2xl": "rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl",
19
19
  "3xl": "rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl",
20
+ "4xl": "rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]",
20
21
  full: "rounded-full [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-full"
21
22
  },
22
23
  transparency: {
@@ -43,7 +44,7 @@ const containerVariants = cva("flex flex-col text-text backdrop-blur", {
43
44
  },
44
45
  border: {
45
46
  none: "",
46
- with: "border-[1.5px]"
47
+ with: "border-[1.3px]"
47
48
  },
48
49
  borderColor: {
49
50
  primary: "border-primary",
@@ -85,8 +86,10 @@ let ContainerRoundedSize = /* @__PURE__ */ function(ContainerRoundedSize$1) {
85
86
  ContainerRoundedSize$1["MD"] = "md";
86
87
  ContainerRoundedSize$1["LG"] = "lg";
87
88
  ContainerRoundedSize$1["XL"] = "xl";
88
- ContainerRoundedSize$1["TWO_XL"] = "2xl";
89
- ContainerRoundedSize$1["THREE_XL"] = "3xl";
89
+ ContainerRoundedSize$1["2xl"] = "2xl";
90
+ ContainerRoundedSize$1["3xl"] = "3xl";
91
+ ContainerRoundedSize$1["4xl"] = "4xl";
92
+ ContainerRoundedSize$1["5xl"] = "5xl";
90
93
  ContainerRoundedSize$1["FULL"] = "full";
91
94
  return ContainerRoundedSize$1;
92
95
  }({});
@@ -142,7 +145,7 @@ let ContainerGap = /* @__PURE__ */ function(ContainerGap$1) {
142
145
  ContainerGap$1["MD"] = "md";
143
146
  ContainerGap$1["LG"] = "lg";
144
147
  ContainerGap$1["XL"] = "xl";
145
- ContainerGap$1["TWO_XL"] = "2xl";
148
+ ContainerGap$1["2xl"] = "2xl";
146
149
  return ContainerGap$1;
147
150
  }({});
148
151
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["Container: FC<ContainerProps>"],"sources":["../../../../src/components/Container/index.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n HTMLAttributes,\n PropsWithChildren,\n} from 'react';\nimport { cn } from '../../utils/cn';\n\n/**\n * Container component variants using class-variance-authority\n * Provides flexible styling options for background, padding, borders, and layout\n */\nexport const containerVariants = cva('flex flex-col text-text backdrop-blur', {\n variants: {\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-sm [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-md',\n md: 'rounded-md [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-lg',\n lg: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n xl: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n '2xl':\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n '3xl':\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n full: 'rounded-full [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-full',\n },\n transparency: {\n none: 'bg-card',\n sm: 'bg-card/95',\n md: 'bg-card/70',\n lg: 'bg-card/40',\n xl: 'bg-card/20',\n full: '',\n },\n padding: {\n none: 'p-0',\n sm: 'px-2 py-4',\n md: 'px-4 py-6',\n lg: 'px-6 py-8',\n xl: 'px-8 py-10',\n '2xl': 'px-10 py-12',\n },\n separator: {\n without: '',\n x: 'divide-x divide-dashed divide-text/20',\n y: 'divide-y divide-dashed divide-text/20',\n both: 'divide-x divide-y divide-dashed divide-text/20',\n },\n border: {\n none: '',\n with: 'border-[1.5px]',\n },\n borderColor: {\n primary: 'border-primary',\n secondary: 'border-secondary',\n neutral: 'border-neutral',\n text: 'border-text',\n error: 'border-error',\n warning: 'border-warning',\n success: 'border-success',\n },\n background: {\n none: 'bg-inherit',\n hoverable:\n 'bg-opacity-5! backdrop-blur-0 hover:bg-opacity-10! hover:backdrop-blur focus:bg-opacity-10! focus:backdrop-blur aria-selected:bg-opacity-15! aria-selected:backdrop-blur',\n with: '',\n },\n gap: {\n none: 'gap-0',\n sm: 'gap-1',\n md: 'gap-3',\n lg: 'gap-5',\n xl: 'gap-8',\n '2xl': 'gap-10',\n },\n },\n defaultVariants: {\n roundedSize: 'lg',\n border: 'none',\n borderColor: 'text',\n transparency: 'md',\n padding: 'none',\n separator: 'without',\n gap: 'none',\n },\n});\n\n/** Available rounded corner sizes for the container */\nexport enum ContainerRoundedSize {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n TWO_XL = '2xl',\n THREE_XL = '3xl',\n FULL = 'full',\n}\n\n/** Background transparency levels for the container */\nexport enum ContainerTransparency {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n FULL = 'full',\n}\n\n/** Padding sizes for container content */\nexport enum ContainerPadding {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n}\n\n/** Separator options for dividing container children */\nexport enum ContainerSeparator {\n WITHOUT = 'without',\n X = 'x',\n Y = 'y',\n BOTH = 'both',\n}\n\n/** Border color options for the container */\nexport enum ContainerBorderColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n NEUTRAL = 'neutral',\n TEXT = 'text',\n ERROR = 'error',\n WARNING = 'warning',\n SUCCESS = 'success',\n}\n\n/** Background interaction states for the container */\nexport enum ContainerBackground {\n NONE = 'none',\n HOVERABLE = 'hoverable',\n WITH = 'with',\n}\n\n/** Gap sizes between container children */\nexport enum ContainerGap {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n TWO_XL = '2xl',\n}\n\n/** Container component props extending HTML div attributes */\nexport type ContainerProps = PropsWithChildren<\n Omit<VariantProps<typeof containerVariants>, 'border'>\n> &\n DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {\n /** Whether to show a border around the container */\n border?: boolean;\n };\n\n/**\n * Container Component\n *\n * A flexible container component for organizing content with customizable styling options.\n * Supports various visual states, layouts, and accessibility features.\n *\n * ## Features\n * - **Flexible Layout**: Supports different padding, gap, and separator options\n * - **Visual Variants**: Multiple background transparency levels and border styles\n * - **Responsive Design**: Configurable rounded corners and spacing\n * - **Semantic HTML**: Proper div element with extensible attributes\n *\n * ## Accessibility\n * - Inherits all standard div accessibility features\n * - Supports ARIA attributes through spread props\n * - Maintains proper semantic structure for screen readers\n *\n * @param children - The content to display inside the container\n * @param roundedSize - Border radius size (default: 'md')\n * @param transparency - Background transparency level (default: 'md')\n * @param padding - Internal padding size (default: 'none')\n * @param separator - Divider lines between children (default: 'without')\n * @param border - Whether to show border (default: false)\n * @param borderColor - Color of the border (default: 'text')\n * @param background - Background interaction behavior (default: 'none')\n * @param gap - Space between child elements (default: 'none')\n * @param className - Additional CSS classes\n * @param props - Additional HTML div attributes including ARIA attributes\n */\nexport const Container: FC<ContainerProps> = ({\n children,\n roundedSize,\n padding,\n transparency,\n separator,\n className,\n border,\n borderColor,\n background,\n gap,\n ...props\n}) => (\n <div\n className={cn(\n containerVariants({\n roundedSize,\n transparency,\n padding,\n separator,\n border:\n typeof border === 'boolean' ? (border ? 'with' : 'none') : undefined,\n background,\n borderColor,\n gap,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n"],"mappings":";;;;;;;;;AAaA,MAAa,oBAAoB,IAAI,yCAAyC;CAC5E,UAAU;EACR,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OACE;GACF,OACE;GACF,MAAM;GACP;EACD,cAAc;GACZ,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GACP;EACD,SAAS;GACP,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACD,WAAW;GACT,SAAS;GACT,GAAG;GACH,GAAG;GACH,MAAM;GACP;EACD,QAAQ;GACN,MAAM;GACN,MAAM;GACP;EACD,aAAa;GACX,SAAS;GACT,WAAW;GACX,SAAS;GACT,MAAM;GACN,OAAO;GACP,SAAS;GACT,SAAS;GACV;EACD,YAAY;GACV,MAAM;GACN,WACE;GACF,MAAM;GACP;EACD,KAAK;GACH,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACF;CACD,iBAAiB;EACf,aAAa;EACb,QAAQ;EACR,aAAa;EACb,cAAc;EACd,SAAS;EACT,WAAW;EACX,KAAK;EACN;CACF,CAAC;;AAGF,IAAY,wEAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIF,IAAY,0EAAL;AACL;AACA;AACA;AACA;AACA;AACA;;;;AAIF,IAAY,gEAAL;AACL;AACA;AACA;AACA;AACA;;;;AAIF,IAAY,oEAAL;AACL;AACA;AACA;AACA;;;;AAIF,IAAY,wEAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIF,IAAY,sEAAL;AACL;AACA;AACA;;;;AAIF,IAAY,wDAAL;AACL;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCF,MAAaA,aAAiC,EAC5C,UACA,aACA,SACA,cACA,WACA,WACA,QACA,aACA,YACA,KACA,GAAG,YAEH,oBAAC;CACC,WAAW,GACT,kBAAkB;EAChB;EACA;EACA;EACA;EACA,QACE,OAAO,WAAW,YAAa,SAAS,SAAS,SAAU;EAC7D;EACA;EACA;EACD,CAAC,EACF,UACD;CACD,GAAI;CAEH;EACG"}
1
+ {"version":3,"file":"index.mjs","names":["Container: FC<ContainerProps>"],"sources":["../../../../src/components/Container/index.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n HTMLAttributes,\n PropsWithChildren,\n} from 'react';\nimport { cn } from '../../utils/cn';\n\n/**\n * Container component variants using class-variance-authority\n * Provides flexible styling options for background, padding, borders, and layout\n */\nexport const containerVariants = cva('flex flex-col text-text backdrop-blur', {\n variants: {\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-sm [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-md',\n md: 'rounded-md [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-lg',\n lg: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n xl: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n '2xl':\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n '3xl':\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '4xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n full: 'rounded-full [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-full',\n },\n transparency: {\n none: 'bg-card',\n sm: 'bg-card/95',\n md: 'bg-card/70',\n lg: 'bg-card/40',\n xl: 'bg-card/20',\n full: '',\n },\n padding: {\n none: 'p-0',\n sm: 'px-2 py-4',\n md: 'px-4 py-6',\n lg: 'px-6 py-8',\n xl: 'px-8 py-10',\n '2xl': 'px-10 py-12',\n },\n separator: {\n without: '',\n x: 'divide-x divide-dashed divide-text/20',\n y: 'divide-y divide-dashed divide-text/20',\n both: 'divide-x divide-y divide-dashed divide-text/20',\n },\n border: {\n none: '',\n with: 'border-[1.3px]',\n },\n borderColor: {\n primary: 'border-primary',\n secondary: 'border-secondary',\n neutral: 'border-neutral',\n text: 'border-text',\n error: 'border-error',\n warning: 'border-warning',\n success: 'border-success',\n },\n background: {\n none: 'bg-inherit',\n hoverable:\n 'bg-opacity-5! backdrop-blur-0 hover:bg-opacity-10! hover:backdrop-blur focus:bg-opacity-10! focus:backdrop-blur aria-selected:bg-opacity-15! aria-selected:backdrop-blur',\n with: '',\n },\n gap: {\n none: 'gap-0',\n sm: 'gap-1',\n md: 'gap-3',\n lg: 'gap-5',\n xl: 'gap-8',\n '2xl': 'gap-10',\n },\n },\n defaultVariants: {\n roundedSize: 'lg',\n border: 'none',\n borderColor: 'text',\n transparency: 'md',\n padding: 'none',\n separator: 'without',\n gap: 'none',\n },\n});\n\n/** Available rounded corner sizes for the container */\nexport enum ContainerRoundedSize {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n '2xl' = '2xl',\n '3xl' = '3xl',\n '4xl' = '4xl',\n '5xl' = '5xl',\n FULL = 'full',\n}\n\n/** Background transparency levels for the container */\nexport enum ContainerTransparency {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n FULL = 'full',\n}\n\n/** Padding sizes for container content */\nexport enum ContainerPadding {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n}\n\n/** Separator options for dividing container children */\nexport enum ContainerSeparator {\n WITHOUT = 'without',\n X = 'x',\n Y = 'y',\n BOTH = 'both',\n}\n\n/** Border color options for the container */\nexport enum ContainerBorderColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n NEUTRAL = 'neutral',\n TEXT = 'text',\n ERROR = 'error',\n WARNING = 'warning',\n SUCCESS = 'success',\n}\n\n/** Background interaction states for the container */\nexport enum ContainerBackground {\n NONE = 'none',\n HOVERABLE = 'hoverable',\n WITH = 'with',\n}\n\n/** Gap sizes between container children */\nexport enum ContainerGap {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n '2xl' = '2xl',\n}\n\n/** Container component props extending HTML div attributes */\nexport type ContainerProps = PropsWithChildren<\n Omit<VariantProps<typeof containerVariants>, 'border'>\n> &\n DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {\n /** Whether to show a border around the container */\n border?: boolean;\n };\n\n/**\n * Container Component\n *\n * A flexible container component for organizing content with customizable styling options.\n * Supports various visual states, layouts, and accessibility features.\n *\n * ## Features\n * - **Flexible Layout**: Supports different padding, gap, and separator options\n * - **Visual Variants**: Multiple background transparency levels and border styles\n * - **Responsive Design**: Configurable rounded corners and spacing\n * - **Semantic HTML**: Proper div element with extensible attributes\n *\n * ## Accessibility\n * - Inherits all standard div accessibility features\n * - Supports ARIA attributes through spread props\n * - Maintains proper semantic structure for screen readers\n *\n * @param children - The content to display inside the container\n * @param roundedSize - Border radius size (default: 'md')\n * @param transparency - Background transparency level (default: 'md')\n * @param padding - Internal padding size (default: 'none')\n * @param separator - Divider lines between children (default: 'without')\n * @param border - Whether to show border (default: false)\n * @param borderColor - Color of the border (default: 'text')\n * @param background - Background interaction behavior (default: 'none')\n * @param gap - Space between child elements (default: 'none')\n * @param className - Additional CSS classes\n * @param props - Additional HTML div attributes including ARIA attributes\n */\nexport const Container: FC<ContainerProps> = ({\n children,\n roundedSize,\n padding,\n transparency,\n separator,\n className,\n border,\n borderColor,\n background,\n gap,\n ...props\n}) => (\n <div\n className={cn(\n containerVariants({\n roundedSize,\n transparency,\n padding,\n separator,\n border:\n typeof border === 'boolean' ? (border ? 'with' : 'none') : undefined,\n background,\n borderColor,\n gap,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n"],"mappings":";;;;;;;;;AAaA,MAAa,oBAAoB,IAAI,yCAAyC;CAC5E,UAAU;EACR,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OACE;GACF,OACE;GACF,OACE;GACF,MAAM;GACP;EACD,cAAc;GACZ,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GACP;EACD,SAAS;GACP,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACD,WAAW;GACT,SAAS;GACT,GAAG;GACH,GAAG;GACH,MAAM;GACP;EACD,QAAQ;GACN,MAAM;GACN,MAAM;GACP;EACD,aAAa;GACX,SAAS;GACT,WAAW;GACX,SAAS;GACT,MAAM;GACN,OAAO;GACP,SAAS;GACT,SAAS;GACV;EACD,YAAY;GACV,MAAM;GACN,WACE;GACF,MAAM;GACP;EACD,KAAK;GACH,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACF;CACD,iBAAiB;EACf,aAAa;EACb,QAAQ;EACR,aAAa;EACb,cAAc;EACd,SAAS;EACT,WAAW;EACX,KAAK;EACN;CACF,CAAC;;AAGF,IAAY,wEAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIF,IAAY,0EAAL;AACL;AACA;AACA;AACA;AACA;AACA;;;;AAIF,IAAY,gEAAL;AACL;AACA;AACA;AACA;AACA;;;;AAIF,IAAY,oEAAL;AACL;AACA;AACA;AACA;;;;AAIF,IAAY,wEAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIF,IAAY,sEAAL;AACL;AACA;AACA;;;;AAIF,IAAY,wDAAL;AACL;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCF,MAAaA,aAAiC,EAC5C,UACA,aACA,SACA,cACA,WACA,WACA,QACA,aACA,YACA,KACA,GAAG,YAEH,oBAAC;CACC,WAAW,GACT,kBAAkB;EAChB;EACA;EACA;EACA;EACA,QACE,OAAO,WAAW,YAAa,SAAS,SAAS,SAAU;EAC7D;EACA;EACA;EACD,CAAC,EACF,UACD;CACD,GAAI;CAEH;EACG"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Button, ButtonColor, ButtonVariant } from "../Button/Button.mjs";
4
- import { SwitchSelector, SwitchSelectorColor, SwitchSelectorSize } from "../SwitchSelector/index.mjs";
4
+ import { SwitchSelector } from "../SwitchSelector/index.mjs";
5
5
  import { SaveForm } from "./SaveForm/SaveForm.mjs";
6
6
  import { LocaleSwitcherContentProvider } from "../LocaleSwitcherContentDropDown/LocaleSwitcherContentContext.mjs";
7
7
  import { ContentEditor } from "./ContentEditor.mjs";
@@ -56,9 +56,7 @@ const DictionaryFieldEditor = ({ dictionary, onClickDictionaryList, isDarkMode,
56
56
  /* @__PURE__ */ jsx(SwitchSelector, {
57
57
  defaultValue: editorView,
58
58
  onChange: (value) => setEditorView(value),
59
- color: SwitchSelectorColor.TEXT,
60
- size: SwitchSelectorSize.SM,
61
- className: "m-auto w-full max-w-xl",
59
+ color: "text",
62
60
  choices: [
63
61
  {
64
62
  content: "Details",
@@ -1 +1 @@
1
- {"version":3,"file":"DictionaryFieldEditor.mjs","names":["DictionaryFieldEditor: FC<DictionaryFieldEditorProps>"],"sources":["../../../../src/components/DictionaryFieldEditor/DictionaryFieldEditor.tsx"],"sourcesContent":["'use client';\n\nimport {\n useConfiguration,\n useDictionariesRecordActions,\n useFocusUnmergedDictionary,\n} from '@intlayer/editor-react';\nimport type { Dictionary } from '@intlayer/types';\nimport { ArrowLeft } from 'lucide-react';\nimport { type FC, useEffect, useState } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button, ButtonColor, ButtonVariant } from '../Button';\nimport { LocaleSwitcherContentProvider } from '../LocaleSwitcherContentDropDown';\nimport {\n SwitchSelector,\n SwitchSelectorColor,\n SwitchSelectorSize,\n} from '../SwitchSelector';\nimport { ContentEditor } from './ContentEditor';\nimport { DictionaryDetailsForm } from './DictionaryDetails/DictionaryDetailsForm';\nimport { JSONEditor } from './JSONEditor';\nimport { SaveForm } from './SaveForm/SaveForm';\nimport { StructureEditor } from './StructureEditor';\n\ntype DictionaryFieldEditorProps = {\n dictionary: Dictionary;\n onClickDictionaryList?: () => void;\n onDelete?: () => void;\n onSave?: () => void;\n isDarkMode?: boolean;\n mode: ('local' | 'remote')[];\n};\n\nenum EditorViewType {\n DetailsEditor,\n ContentEditor,\n StructureEditor,\n JSONEditor,\n}\n\nexport const DictionaryFieldEditor: FC<DictionaryFieldEditorProps> = ({\n dictionary,\n onClickDictionaryList,\n isDarkMode,\n mode,\n onDelete,\n onSave,\n}) => {\n const config = useConfiguration();\n const [editorView, setEditorView] = useState<EditorViewType>(\n EditorViewType.ContentEditor\n );\n const { returnToDictionaryList } = useIntlayer('dictionary-field-editor');\n const { setFocusedContent } = useFocusUnmergedDictionary();\n const { setLocaleDictionaries } = useDictionariesRecordActions();\n\n useEffect(() => {\n // Focus the dictionary if not focused\n setFocusedContent((prev) => ({\n ...(prev ?? {}),\n dictionaryKey: dictionary.key,\n dictionaryLocalId: dictionary.localId,\n }));\n setLocaleDictionaries((prev) => ({\n ...prev,\n [dictionary.localId!]: dictionary,\n }));\n }, []);\n\n return (\n <LocaleSwitcherContentProvider\n availableLocales={config?.internationalization.locales ?? []}\n >\n <div className=\"flex size-full flex-col gap-6 px-2\">\n <Button\n onClick={onClickDictionaryList}\n variant={ButtonVariant.HOVERABLE}\n className=\"z-10 mr-auto ml-5\"\n color={ButtonColor.TEXT}\n Icon={ArrowLeft}\n label={returnToDictionaryList.label.value}\n >\n {returnToDictionaryList.text}\n </Button>\n\n <SwitchSelector\n defaultValue={editorView}\n onChange={(value) => setEditorView(value)}\n color={SwitchSelectorColor.TEXT}\n size={SwitchSelectorSize.SM}\n className=\"m-auto w-full max-w-xl\"\n choices={[\n {\n content: 'Details',\n value: EditorViewType.DetailsEditor,\n },\n {\n content: 'Structure',\n value: EditorViewType.StructureEditor,\n },\n {\n content: 'Content',\n value: EditorViewType.ContentEditor,\n },\n {\n content: 'JSON',\n value: EditorViewType.JSONEditor,\n },\n ].filter(\n ({ value }) =>\n !(\n !mode.includes('remote') &&\n value === EditorViewType.DetailsEditor\n )\n )}\n />\n\n {editorView === EditorViewType.DetailsEditor && (\n <DictionaryDetailsForm dictionary={dictionary} />\n )}\n {editorView === EditorViewType.StructureEditor && (\n <StructureEditor dictionary={dictionary} />\n )}\n {editorView === EditorViewType.ContentEditor && (\n <ContentEditor dictionary={dictionary} isDarkMode={isDarkMode} />\n )}\n {editorView === EditorViewType.JSONEditor && (\n <JSONEditor dictionary={dictionary} isDarkMode={isDarkMode} />\n )}\n\n <SaveForm\n dictionary={dictionary}\n mode={mode}\n onDelete={() => {\n setFocusedContent(null);\n onDelete?.();\n }}\n onSave={onSave}\n />\n </div>\n </LocaleSwitcherContentProvider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAiCA,IAAK,4DAAL;AACE;AACA;AACA;AACA;;EAJG;AAOL,MAAaA,yBAAyD,EACpE,YACA,uBACA,YACA,MACA,UACA,aACI;CACJ,MAAM,SAAS,kBAAkB;CACjC,MAAM,CAAC,YAAY,iBAAiB,SAClC,eAAe,cAChB;CACD,MAAM,EAAE,2BAA2B,YAAY,0BAA0B;CACzE,MAAM,EAAE,sBAAsB,4BAA4B;CAC1D,MAAM,EAAE,0BAA0B,8BAA8B;AAEhE,iBAAgB;AAEd,qBAAmB,UAAU;GAC3B,GAAI,QAAQ,EAAE;GACd,eAAe,WAAW;GAC1B,mBAAmB,WAAW;GAC/B,EAAE;AACH,yBAAuB,UAAU;GAC/B,GAAG;IACF,WAAW,UAAW;GACxB,EAAE;IACF,EAAE,CAAC;AAEN,QACE,oBAAC;EACC,kBAAkB,QAAQ,qBAAqB,WAAW,EAAE;YAE5D,qBAAC;GAAI,WAAU;;IACb,oBAAC;KACC,SAAS;KACT,SAAS,cAAc;KACvB,WAAU;KACV,OAAO,YAAY;KACnB,MAAM;KACN,OAAO,uBAAuB,MAAM;eAEnC,uBAAuB;MACjB;IAET,oBAAC;KACC,cAAc;KACd,WAAW,UAAU,cAAc,MAAM;KACzC,OAAO,oBAAoB;KAC3B,MAAM,mBAAmB;KACzB,WAAU;KACV,SAAS;MACP;OACE,SAAS;OACT,OAAO,eAAe;OACvB;MACD;OACE,SAAS;OACT,OAAO,eAAe;OACvB;MACD;OACE,SAAS;OACT,OAAO,eAAe;OACvB;MACD;OACE,SAAS;OACT,OAAO,eAAe;OACvB;MACF,CAAC,QACC,EAAE,YACD,EACE,CAAC,KAAK,SAAS,SAAS,IACxB,UAAU,eAAe,eAE9B;MACD;IAED,eAAe,eAAe,iBAC7B,oBAAC,yBAAkC,aAAc;IAElD,eAAe,eAAe,mBAC7B,oBAAC,mBAA4B,aAAc;IAE5C,eAAe,eAAe,iBAC7B,oBAAC;KAA0B;KAAwB;MAAc;IAElE,eAAe,eAAe,cAC7B,oBAAC;KAAuB;KAAwB;MAAc;IAGhE,oBAAC;KACa;KACN;KACN,gBAAgB;AACd,wBAAkB,KAAK;AACvB,kBAAY;;KAEN;MACR;;IACE;GACwB"}
1
+ {"version":3,"file":"DictionaryFieldEditor.mjs","names":["DictionaryFieldEditor: FC<DictionaryFieldEditorProps>"],"sources":["../../../../src/components/DictionaryFieldEditor/DictionaryFieldEditor.tsx"],"sourcesContent":["'use client';\n\nimport {\n useConfiguration,\n useDictionariesRecordActions,\n useFocusUnmergedDictionary,\n} from '@intlayer/editor-react';\nimport type { Dictionary } from '@intlayer/types';\nimport { ArrowLeft } from 'lucide-react';\nimport { type FC, useEffect, useState } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button, ButtonColor, ButtonVariant } from '../Button';\nimport { LocaleSwitcherContentProvider } from '../LocaleSwitcherContentDropDown';\nimport { SwitchSelector } from '../SwitchSelector';\nimport { ContentEditor } from './ContentEditor';\nimport { DictionaryDetailsForm } from './DictionaryDetails/DictionaryDetailsForm';\nimport { JSONEditor } from './JSONEditor';\nimport { SaveForm } from './SaveForm/SaveForm';\nimport { StructureEditor } from './StructureEditor';\n\ntype DictionaryFieldEditorProps = {\n dictionary: Dictionary;\n onClickDictionaryList?: () => void;\n onDelete?: () => void;\n onSave?: () => void;\n isDarkMode?: boolean;\n mode: ('local' | 'remote')[];\n};\n\nenum EditorViewType {\n DetailsEditor,\n ContentEditor,\n StructureEditor,\n JSONEditor,\n}\n\nexport const DictionaryFieldEditor: FC<DictionaryFieldEditorProps> = ({\n dictionary,\n onClickDictionaryList,\n isDarkMode,\n mode,\n onDelete,\n onSave,\n}) => {\n const config = useConfiguration();\n const [editorView, setEditorView] = useState<EditorViewType>(\n EditorViewType.ContentEditor\n );\n const { returnToDictionaryList } = useIntlayer('dictionary-field-editor');\n const { setFocusedContent } = useFocusUnmergedDictionary();\n const { setLocaleDictionaries } = useDictionariesRecordActions();\n\n useEffect(() => {\n // Focus the dictionary if not focused\n setFocusedContent((prev) => ({\n ...(prev ?? {}),\n dictionaryKey: dictionary.key,\n dictionaryLocalId: dictionary.localId,\n }));\n setLocaleDictionaries((prev) => ({\n ...prev,\n [dictionary.localId!]: dictionary,\n }));\n }, []);\n\n return (\n <LocaleSwitcherContentProvider\n availableLocales={config?.internationalization.locales ?? []}\n >\n <div className=\"flex size-full flex-col gap-6 px-2\">\n <Button\n onClick={onClickDictionaryList}\n variant={ButtonVariant.HOVERABLE}\n className=\"z-10 mr-auto ml-5\"\n color={ButtonColor.TEXT}\n Icon={ArrowLeft}\n label={returnToDictionaryList.label.value}\n >\n {returnToDictionaryList.text}\n </Button>\n\n <SwitchSelector\n defaultValue={editorView}\n onChange={(value) => setEditorView(value)}\n color=\"text\"\n choices={[\n {\n content: 'Details',\n value: EditorViewType.DetailsEditor,\n },\n {\n content: 'Structure',\n value: EditorViewType.StructureEditor,\n },\n {\n content: 'Content',\n value: EditorViewType.ContentEditor,\n },\n {\n content: 'JSON',\n value: EditorViewType.JSONEditor,\n },\n ].filter(\n ({ value }) =>\n !(\n !mode.includes('remote') &&\n value === EditorViewType.DetailsEditor\n )\n )}\n />\n\n {editorView === EditorViewType.DetailsEditor && (\n <DictionaryDetailsForm dictionary={dictionary} />\n )}\n {editorView === EditorViewType.StructureEditor && (\n <StructureEditor dictionary={dictionary} />\n )}\n {editorView === EditorViewType.ContentEditor && (\n <ContentEditor dictionary={dictionary} isDarkMode={isDarkMode} />\n )}\n {editorView === EditorViewType.JSONEditor && (\n <JSONEditor dictionary={dictionary} isDarkMode={isDarkMode} />\n )}\n\n <SaveForm\n dictionary={dictionary}\n mode={mode}\n onDelete={() => {\n setFocusedContent(null);\n onDelete?.();\n }}\n onSave={onSave}\n />\n </div>\n </LocaleSwitcherContentProvider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA6BA,IAAK,4DAAL;AACE;AACA;AACA;AACA;;EAJG;AAOL,MAAaA,yBAAyD,EACpE,YACA,uBACA,YACA,MACA,UACA,aACI;CACJ,MAAM,SAAS,kBAAkB;CACjC,MAAM,CAAC,YAAY,iBAAiB,SAClC,eAAe,cAChB;CACD,MAAM,EAAE,2BAA2B,YAAY,0BAA0B;CACzE,MAAM,EAAE,sBAAsB,4BAA4B;CAC1D,MAAM,EAAE,0BAA0B,8BAA8B;AAEhE,iBAAgB;AAEd,qBAAmB,UAAU;GAC3B,GAAI,QAAQ,EAAE;GACd,eAAe,WAAW;GAC1B,mBAAmB,WAAW;GAC/B,EAAE;AACH,yBAAuB,UAAU;GAC/B,GAAG;IACF,WAAW,UAAW;GACxB,EAAE;IACF,EAAE,CAAC;AAEN,QACE,oBAAC;EACC,kBAAkB,QAAQ,qBAAqB,WAAW,EAAE;YAE5D,qBAAC;GAAI,WAAU;;IACb,oBAAC;KACC,SAAS;KACT,SAAS,cAAc;KACvB,WAAU;KACV,OAAO,YAAY;KACnB,MAAM;KACN,OAAO,uBAAuB,MAAM;eAEnC,uBAAuB;MACjB;IAET,oBAAC;KACC,cAAc;KACd,WAAW,UAAU,cAAc,MAAM;KACzC,OAAM;KACN,SAAS;MACP;OACE,SAAS;OACT,OAAO,eAAe;OACvB;MACD;OACE,SAAS;OACT,OAAO,eAAe;OACvB;MACD;OACE,SAAS;OACT,OAAO,eAAe;OACvB;MACD;OACE,SAAS;OACT,OAAO,eAAe;OACvB;MACF,CAAC,QACC,EAAE,YACD,EACE,CAAC,KAAK,SAAS,SAAS,IACxB,UAAU,eAAe,eAE9B;MACD;IAED,eAAe,eAAe,iBAC7B,oBAAC,yBAAkC,aAAc;IAElD,eAAe,eAAe,mBAC7B,oBAAC,mBAA4B,aAAc;IAE5C,eAAe,eAAe,iBAC7B,oBAAC;KAA0B;KAAwB;MAAc;IAElE,eAAe,eAAe,cAC7B,oBAAC;KAAuB;KAAwB;MAAc;IAGhE,oBAAC;KACa;KACN;KACN,gBAAgB;AACd,wBAAkB,KAAK;AACvB,kBAAY;;KAEN;MACR;;IACE;GACwB"}