@fabio.caffarello/react-design-system 3.13.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/dist/granular/ui/components/Autocomplete/Autocomplete.js +103 -86
  2. package/dist/granular/ui/components/Autocomplete/Autocomplete.js.map +1 -1
  3. package/dist/granular/ui/components/Autocomplete/AutocompleteList.js +57 -47
  4. package/dist/granular/ui/components/Autocomplete/AutocompleteList.js.map +1 -1
  5. package/dist/granular/ui/components/Autocomplete/AutocompleteOption.js +21 -20
  6. package/dist/granular/ui/components/Autocomplete/AutocompleteOption.js.map +1 -1
  7. package/dist/granular/ui/components/Breadcrumb/Breadcrumb.js.map +1 -1
  8. package/dist/granular/ui/components/ColorPicker/ColorPicker.js.map +1 -1
  9. package/dist/granular/ui/components/CommandPalette/CommandPalette.js +187 -149
  10. package/dist/granular/ui/components/CommandPalette/CommandPalette.js.map +1 -1
  11. package/dist/granular/ui/components/DataGrid/DataGrid.js +92 -92
  12. package/dist/granular/ui/components/DataGrid/DataGrid.js.map +1 -1
  13. package/dist/granular/ui/components/DatePicker/DatePickerCalendar.js +154 -139
  14. package/dist/granular/ui/components/DatePicker/DatePickerCalendar.js.map +1 -1
  15. package/dist/granular/ui/components/Dialog/AlertDialog.js +73 -40
  16. package/dist/granular/ui/components/Dialog/AlertDialog.js.map +1 -1
  17. package/dist/granular/ui/components/Dialog/DialogContent.js +54 -48
  18. package/dist/granular/ui/components/Dialog/DialogContent.js.map +1 -1
  19. package/dist/granular/ui/components/Dialog/DialogDescription.js +31 -31
  20. package/dist/granular/ui/components/Dialog/DialogDescription.js.map +1 -1
  21. package/dist/granular/ui/components/Dialog/DialogTitle.js +30 -30
  22. package/dist/granular/ui/components/Dialog/DialogTitle.js.map +1 -1
  23. package/dist/granular/ui/components/Drawer/Drawer.js.map +1 -1
  24. package/dist/granular/ui/components/Dropdown/Dropdown.js.map +1 -1
  25. package/dist/granular/ui/components/EmptyState/EmptyState.js.map +1 -1
  26. package/dist/granular/ui/components/FileUpload/FileUpload.js.map +1 -1
  27. package/dist/granular/ui/components/Form/Form.js +38 -37
  28. package/dist/granular/ui/components/Form/Form.js.map +1 -1
  29. package/dist/granular/ui/components/Form/FormField.js +28 -26
  30. package/dist/granular/ui/components/Form/FormField.js.map +1 -1
  31. package/dist/granular/ui/components/Header/Header.js.map +1 -1
  32. package/dist/granular/ui/components/Header/components/HeaderActions.js.map +1 -1
  33. package/dist/granular/ui/components/Header/components/HeaderHamburger.js.map +1 -1
  34. package/dist/granular/ui/components/Header/components/HeaderLogo.js.map +1 -1
  35. package/dist/granular/ui/components/Header/components/HeaderMobileMenu.js.map +1 -1
  36. package/dist/granular/ui/components/Header/components/HeaderNavigation.js.map +1 -1
  37. package/dist/granular/ui/components/Header/contexts/HeaderContext.js.map +1 -1
  38. package/dist/granular/ui/components/Menu/Menu.js.map +1 -1
  39. package/dist/granular/ui/components/Modal/Modal.js +98 -86
  40. package/dist/granular/ui/components/Modal/Modal.js.map +1 -1
  41. package/dist/granular/ui/components/MultiSelect/MultiSelect.js +122 -106
  42. package/dist/granular/ui/components/MultiSelect/MultiSelect.js.map +1 -1
  43. package/dist/granular/ui/components/Navigation/Navigation.js.map +1 -1
  44. package/dist/granular/ui/components/PageHeader/PageHeader.js.map +1 -1
  45. package/dist/granular/ui/components/Pagination/Pagination.js.map +1 -1
  46. package/dist/granular/ui/components/Popover/Popover.js.map +1 -1
  47. package/dist/granular/ui/components/Rating/Rating.js.map +1 -1
  48. package/dist/granular/ui/components/SearchInput/SearchInput.js.map +1 -1
  49. package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarGroup.js +82 -64
  50. package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarGroup.js.map +1 -1
  51. package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarItem.js +30 -29
  52. package/dist/granular/ui/components/SideNavbar/components/Navbar/NavbarItem.js.map +1 -1
  53. package/dist/granular/ui/components/SideNavbar/components/SideNavbarResizeHandle.js +37 -35
  54. package/dist/granular/ui/components/SideNavbar/components/SideNavbarResizeHandle.js.map +1 -1
  55. package/dist/granular/ui/components/SideNavbar/providers/SideNavbarStateProvider.js +57 -57
  56. package/dist/granular/ui/components/SideNavbar/providers/SideNavbarStateProvider.js.map +1 -1
  57. package/dist/granular/ui/components/Stepper/Stepper.js +102 -94
  58. package/dist/granular/ui/components/Stepper/Stepper.js.map +1 -1
  59. package/dist/granular/ui/components/Table/Table.js +41 -35
  60. package/dist/granular/ui/components/Table/Table.js.map +1 -1
  61. package/dist/granular/ui/components/Table/TableActions/TableActions.js.map +1 -1
  62. package/dist/granular/ui/components/Table/TableFilters/TableFilters.js +49 -46
  63. package/dist/granular/ui/components/Table/TableFilters/TableFilters.js.map +1 -1
  64. package/dist/granular/ui/components/Table/TablePagination/TablePagination.js.map +1 -1
  65. package/dist/granular/ui/components/Table/TableProvider.js +82 -80
  66. package/dist/granular/ui/components/Table/TableProvider.js.map +1 -1
  67. package/dist/granular/ui/components/Table/TableRow.js +57 -53
  68. package/dist/granular/ui/components/Table/TableRow.js.map +1 -1
  69. package/dist/granular/ui/components/Table/useColumnResizing.js +53 -53
  70. package/dist/granular/ui/components/Table/useColumnResizing.js.map +1 -1
  71. package/dist/granular/ui/components/TimePicker/TimePicker.js +149 -103
  72. package/dist/granular/ui/components/TimePicker/TimePicker.js.map +1 -1
  73. package/dist/granular/ui/components/Timeline/Timeline.js.map +1 -1
  74. package/dist/granular/ui/hooks/useFocusRestore.js +14 -15
  75. package/dist/granular/ui/hooks/useFocusRestore.js.map +1 -1
  76. package/dist/granular/ui/primitives/Badge/Badge.js.map +1 -1
  77. package/dist/granular/ui/primitives/Checkbox/Checkbox.js.map +1 -1
  78. package/dist/granular/ui/primitives/Chip/Chip.js +91 -71
  79. package/dist/granular/ui/primitives/Chip/Chip.js.map +1 -1
  80. package/dist/granular/ui/primitives/ErrorMessage/ErrorMessage.js.map +1 -1
  81. package/dist/granular/ui/primitives/Input/Input.js.map +1 -1
  82. package/dist/granular/ui/primitives/Label/Label.js.map +1 -1
  83. package/dist/granular/ui/primitives/NavLink/NavLink.js.map +1 -1
  84. package/dist/granular/ui/primitives/Radio/Radio.js.map +1 -1
  85. package/dist/granular/ui/primitives/Select/Select.js.map +1 -1
  86. package/dist/granular/ui/primitives/Separator/Separator.js.map +1 -1
  87. package/dist/granular/ui/primitives/Skeleton/Skeleton.js.map +1 -1
  88. package/dist/granular/ui/primitives/Slider/Slider.js.map +1 -1
  89. package/dist/granular/ui/primitives/Spinner/Spinner.js.map +1 -1
  90. package/dist/granular/ui/primitives/Switch/Switch.js.map +1 -1
  91. package/dist/granular/ui/primitives/Tooltip/Tooltip.js.map +1 -1
  92. package/dist/granular/ui/providers/DialogContext.js.map +1 -1
  93. package/dist/granular/ui/providers/DialogProvider.js +24 -20
  94. package/dist/granular/ui/providers/DialogProvider.js.map +1 -1
  95. package/dist/index.cjs +144 -144
  96. package/dist/index.cjs.map +1 -1
  97. package/dist/index.js +5780 -5486
  98. package/dist/index.js.map +1 -1
  99. package/dist/react-design-system.css +1 -1
  100. package/dist/server/index.cjs +7 -7
  101. package/dist/server/index.cjs.map +1 -1
  102. package/dist/server/index.js +404 -384
  103. package/dist/server/index.js.map +1 -1
  104. package/dist/ui/components/Autocomplete/AutocompleteList.d.ts +4 -0
  105. package/dist/ui/components/Autocomplete/AutocompleteOption.d.ts +8 -0
  106. package/dist/ui/components/Breadcrumb/Breadcrumb.d.ts +0 -1
  107. package/dist/ui/components/ColorPicker/ColorPicker.d.ts +0 -1
  108. package/dist/ui/components/CommandPalette/CommandPalette.d.ts +0 -1
  109. package/dist/ui/components/DataGrid/DataGrid.d.ts +0 -1
  110. package/dist/ui/components/Dialog/DialogContent.d.ts +20 -1
  111. package/dist/ui/components/Drawer/Drawer.d.ts +0 -1
  112. package/dist/ui/components/Dropdown/Dropdown.d.ts +0 -1
  113. package/dist/ui/components/EmptyState/EmptyState.d.ts +0 -1
  114. package/dist/ui/components/FileUpload/FileUpload.d.ts +0 -1
  115. package/dist/ui/components/Form/FormField.d.ts +7 -0
  116. package/dist/ui/components/Header/Header.d.ts +1 -1
  117. package/dist/ui/components/Header/components/HeaderActions.d.ts +1 -1
  118. package/dist/ui/components/Header/components/HeaderHamburger.d.ts +1 -1
  119. package/dist/ui/components/Header/components/HeaderLogo.d.ts +1 -1
  120. package/dist/ui/components/Header/components/HeaderMobileMenu.d.ts +1 -1
  121. package/dist/ui/components/Header/components/HeaderNavigation.d.ts +1 -1
  122. package/dist/ui/components/Header/contexts/HeaderContext.d.ts +1 -1
  123. package/dist/ui/components/Menu/Menu.d.ts +0 -1
  124. package/dist/ui/components/Modal/Modal.d.ts +1 -2
  125. package/dist/ui/components/Navigation/Navigation.d.ts +1 -1
  126. package/dist/ui/components/PageHeader/PageHeader.d.ts +1 -1
  127. package/dist/ui/components/Pagination/Pagination.d.ts +0 -1
  128. package/dist/ui/components/Popover/Popover.d.ts +0 -1
  129. package/dist/ui/components/Rating/Rating.d.ts +0 -1
  130. package/dist/ui/components/SearchInput/SearchInput.d.ts +0 -1
  131. package/dist/ui/components/Stepper/Stepper.d.ts +0 -1
  132. package/dist/ui/components/Table/TableActions/TableActions.d.ts +0 -1
  133. package/dist/ui/components/Table/TableFilters/TableFilters.d.ts +0 -1
  134. package/dist/ui/components/Table/TablePagination/TablePagination.d.ts +0 -1
  135. package/dist/ui/components/TimePicker/TimePicker.d.ts +0 -1
  136. package/dist/ui/components/Timeline/Timeline.d.ts +0 -1
  137. package/dist/ui/primitives/Checkbox/Checkbox.d.ts +0 -1
  138. package/dist/ui/primitives/Chip/Chip.d.ts +21 -0
  139. package/dist/ui/primitives/ErrorMessage/ErrorMessage.d.ts +0 -1
  140. package/dist/ui/primitives/Input/Input.d.ts +0 -1
  141. package/dist/ui/primitives/Label/Label.d.ts +0 -1
  142. package/dist/ui/primitives/NavLink/NavLink.d.ts +1 -1
  143. package/dist/ui/primitives/Radio/Radio.d.ts +0 -1
  144. package/dist/ui/primitives/Select/Select.d.ts +0 -1
  145. package/dist/ui/primitives/Skeleton/Skeleton.d.ts +0 -1
  146. package/dist/ui/primitives/Slider/Slider.d.ts +0 -1
  147. package/dist/ui/primitives/Switch/Switch.d.ts +0 -1
  148. package/dist/ui/primitives/Tooltip/Tooltip.d.ts +0 -1
  149. package/dist/ui/providers/DialogContext.d.ts +8 -0
  150. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../../../src/ui/primitives/Input/Input.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useState, memo, useId, useMemo, useCallback } from \"react\";\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\nimport {\n getTypographyClasses,\n getTypographySize,\n} from \"../../tokens/typography\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn, cva } from \"../../utils\";\nimport { X, Eye, EyeOff } from \"lucide-react\";\nimport Button from \"../Button/Button\";\n\n/**\n * Helper Text Component\n * Memoized component for helper/error text\n */\nconst HelperText = memo(function HelperText({\n error,\n success,\n helperText,\n errorId,\n helperId,\n}: {\n error: boolean;\n success: boolean;\n helperText?: string;\n errorId?: string;\n helperId?: string;\n}) {\n const helperClasses = useMemo(\n () =>\n cn(\n getSpacingClass(\"xs\", \"mt\"),\n getTypographyClasses(\"caption\"),\n error && \"text-fg-error\",\n success && \"text-fg-success\",\n !error && !success && \"text-fg-secondary\",\n ),\n [error, success],\n );\n\n const text = useMemo(\n () => helperText || (error ? \"Error\" : success ? \"Success\" : \"\"),\n [helperText, error, success],\n );\n\n return (\n <div\n id={errorId || helperId}\n className={helperClasses}\n role={error || success ? \"alert\" : undefined}\n >\n {text}\n </div>\n );\n});\n\nexport type InputSize = \"sm\" | \"md\" | \"lg\";\nexport type InputVariant = \"default\" | \"outlined\" | \"filled\";\nexport type InputState = \"default\" | \"error\" | \"success\";\n\nexport interface InputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> {\n label?: ReactNode;\n error?: boolean;\n success?: boolean;\n helperText?: string;\n size?: InputSize;\n variant?: InputVariant;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n showClearButton?: boolean;\n onClear?: () => void;\n}\n\n/**\n * Input Component\n *\n * A styled text input component with label, error/success states, icons, and clear button.\n * Follows Atomic Design principles as an Atom component.\n * Uses Composite Pattern when combined with Label and ErrorMessage.\n *\n * @example\n * ```tsx\n * <Input\n * id=\"email\"\n * label=\"Email\"\n * type=\"email\"\n * placeholder=\"Enter your email\"\n * error={hasError}\n * helperText={errorMessage}\n * leftIcon={<MailIcon />}\n * />\n * ```\n */\nconst Input = memo(\n forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n id,\n label,\n error = false,\n success = false,\n helperText,\n size = \"md\",\n variant = \"outlined\",\n leftIcon,\n rightIcon,\n showClearButton = false,\n onClear,\n className = \"\",\n disabled = false,\n type = \"text\",\n value,\n onChange,\n ...props\n },\n ref,\n ) {\n // Stable fallback id when the consumer doesn't provide one. useId\n // is SSR-safe and stable across renders, replacing the deprecated\n // Math.random().substr() pattern.\n const reactId = useId();\n const inputId = id || `input-${reactId}`;\n\n // Memoize error and helper IDs\n const errorId = useMemo(\n () => (error ? `${inputId}-error` : undefined),\n [error, inputId],\n );\n\n const helperId = useMemo(\n () => (helperText ? `${inputId}-helper` : undefined),\n [helperText, inputId],\n );\n\n // Password toggle state\n const [showPassword, setShowPassword] = useState(false);\n\n // Memoize password-related values\n const isPassword = useMemo(() => type === \"password\", [type]);\n const inputType = useMemo(\n () => (isPassword && showPassword ? \"text\" : type),\n [isPassword, showPassword, type],\n );\n\n // Memoize state\n const state = useMemo<InputState>(\n () => (error ? \"error\" : success ? \"success\" : \"default\"),\n [error, success],\n );\n\n // Memoize clear button visibility\n const hasValue = useMemo(\n () => value !== undefined && value !== null && value !== \"\",\n [value],\n );\n\n const shouldShowClear = useMemo(\n () => showClearButton && hasValue && !disabled,\n [showClearButton, hasValue, disabled],\n );\n\n // Memoize focus ring colors\n const primaryFocusRing = useMemo(() => \"focus:border-line-focus\", []);\n\n const errorFocusRing = useMemo(() => \"focus:border-error\", []);\n\n const successFocusRing = useMemo(() => \"focus:border-success\", []);\n\n const getFocusRingColor = useMemo(\n () => primaryFocusRing.replace(\"focus:border-\", \"focus:ring-\"),\n [primaryFocusRing],\n );\n\n const getStateFocusRingColor = useCallback(\n (stateType: \"error\" | \"success\"): string => {\n return stateType === \"error\"\n ? errorFocusRing.replace(\"focus:border-\", \"focus:ring-\")\n : successFocusRing.replace(\"focus:border-\", \"focus:ring-\");\n },\n [errorFocusRing, successFocusRing],\n );\n\n // Input variants using CVA — memoize so the function reference is\n // stable across renders. inputClasses below depends on this; without\n // memoization a fresh cva() each render would invalidate that memo\n // on every render (defeating its purpose).\n const inputVariants = useMemo(\n () =>\n cva(\n // Base classes\n cn(\n \"w-full\",\n getRadiusClass(\"md\"),\n \"transition-colors\",\n \"focus:outline-none\",\n \"focus:ring-2\",\n \"focus:ring-offset-2\",\n \"disabled:opacity-50\",\n \"disabled:cursor-not-allowed\",\n ),\n {\n variants: {\n variant: {\n default: cn(\n \"border-0\",\n \"border-b-2\",\n \"border-line-default\",\n \"focus:border-line-focus\",\n ),\n outlined: cn(\n \"border\",\n \"border-line-default\",\n \"focus:border-line-focus\",\n ),\n filled: cn(\n \"bg-surface-muted\",\n \"border-0\",\n \"focus:bg-surface-base\",\n \"focus:ring-2\",\n getFocusRingColor,\n ),\n },\n size: {\n sm: cn(\n \"h-8\",\n getTypographySize(\"bodySmall\"),\n getSpacingClass(\"md\", \"px\"),\n ),\n md: cn(\n \"h-10\",\n getTypographySize(\"body\"),\n getSpacingClass(\"base\", \"px\"),\n ),\n lg: cn(\n \"h-12\",\n getTypographySize(\"bodyLarge\"),\n getSpacingClass(\"lg\", \"px\"),\n ),\n },\n state: {\n default: \"\",\n error: cn(\n \"border-error\",\n \"focus:border-error\",\n getStateFocusRingColor(\"error\"),\n ),\n success: cn(\n \"border-success\",\n \"focus:border-success\",\n getStateFocusRingColor(\"success\"),\n ),\n },\n },\n defaultVariants: {\n variant: \"outlined\",\n size: \"md\",\n state: \"default\",\n },\n },\n ),\n [getFocusRingColor, getStateFocusRingColor],\n );\n\n // Memoize input classes\n const inputClasses = useMemo(\n () =>\n cn(\n inputVariants({ variant, size, state }),\n // Icon padding - specific values for icon positioning.\n // `pl-9` / `pr-9` aren't on the spacing scale (no semantic\n // key for 36px); they stay raw until a future PR either\n // extends the scale or refactors the icon-padding contract.\n leftIcon &&\n (size === \"sm\"\n ? \"pl-9\"\n : size === \"lg\"\n ? getSpacingClass(\"3xl\", \"pl\")\n : getSpacingClass(\"2xl\", \"pl\")),\n (rightIcon || shouldShowClear || isPassword) &&\n (size === \"sm\"\n ? \"pr-9\"\n : size === \"lg\"\n ? getSpacingClass(\"3xl\", \"pr\")\n : getSpacingClass(\"2xl\", \"pr\")),\n className,\n ),\n [\n inputVariants,\n variant,\n size,\n state,\n leftIcon,\n rightIcon,\n shouldShowClear,\n isPassword,\n className,\n ],\n );\n\n // Memoize label classes\n const labelClasses = useMemo(\n () =>\n cn(\n \"block\",\n getTypographyClasses(\"label\"),\n getSpacingClass(\"xs\", \"mb\"),\n disabled && \"opacity-50\",\n ),\n [disabled],\n );\n\n // Memoize icon size and position\n const iconSize = useMemo(\n () => (size === \"sm\" ? \"h-4 w-4\" : size === \"lg\" ? \"h-5 w-5\" : \"h-4 w-4\"),\n [size],\n );\n\n const iconPosition = useMemo(\n () => (size === \"sm\" ? \"top-2\" : size === \"lg\" ? \"top-3.5\" : \"top-2.5\"),\n [size],\n );\n\n // Memoize clear handler\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n if (onClear) {\n onClear();\n } else if (onChange) {\n // Create synthetic event to clear input\n const inputElement = e.currentTarget\n .closest(\".relative\")\n ?.querySelector(\"input\") as HTMLInputElement;\n if (inputElement) {\n const syntheticEvent = {\n target: inputElement,\n currentTarget: inputElement,\n bubbles: true,\n cancelable: true,\n defaultPrevented: false,\n eventPhase: 2,\n isTrusted: false,\n nativeEvent: new Event(\"change\"),\n preventDefault: () => {},\n stopPropagation: () => {},\n persist: () => {},\n timeStamp: Date.now(),\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n Object.defineProperty(syntheticEvent.target, \"value\", {\n value: \"\",\n writable: true,\n });\n Object.defineProperty(syntheticEvent.currentTarget, \"value\", {\n value: \"\",\n writable: true,\n });\n onChange(syntheticEvent);\n }\n }\n },\n [onClear, onChange],\n );\n\n // Memoize password toggle handler\n const handleTogglePassword = useCallback(() => {\n setShowPassword((prev) => !prev);\n }, []);\n\n return (\n <div className=\"w-full\">\n {label && (\n <label htmlFor={inputId} className={labelClasses}>\n {label}\n </label>\n )}\n <div className=\"relative\">\n {leftIcon && (\n <div\n className={`absolute left-3 ${iconPosition} text-fg-secondary opacity-60 pointer-events-none`}\n >\n <div className={iconSize}>{leftIcon}</div>\n </div>\n )}\n <input\n id={inputId}\n ref={ref}\n type={inputType}\n className={inputClasses}\n disabled={disabled}\n value={value}\n onChange={onChange}\n aria-invalid={error}\n aria-required={props.required}\n aria-describedby={errorId || helperId}\n suppressHydrationWarning\n {...props}\n />\n <div\n className={`absolute right-3 top-0 bottom-0 flex items-center ${getSpacingClass(\"xs\", \"gap\")}`}\n >\n {shouldShowClear && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleClear}\n className={`h-auto ${getSpacingClass(\"xs\", \"p\")}`}\n aria-label=\"Clear input\"\n >\n <X className={iconSize} />\n </Button>\n )}\n {isPassword && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleTogglePassword}\n className={`h-auto ${getSpacingClass(\"xs\", \"p\")}`}\n aria-label={showPassword ? \"Hide password\" : \"Show password\"}\n >\n {showPassword ? (\n <EyeOff className={iconSize} />\n ) : (\n <Eye className={iconSize} />\n )}\n </Button>\n )}\n {rightIcon && !shouldShowClear && !isPassword && (\n <div\n className={`text-fg-secondary opacity-60 pointer-events-none ${iconSize}`}\n >\n {rightIcon}\n </div>\n )}\n </div>\n </div>\n {(error || success || helperText) && (\n <HelperText\n error={error}\n success={success}\n helperText={helperText}\n errorId={errorId}\n helperId={helperId}\n />\n )}\n </div>\n );\n }),\n);\n\nInput.displayName = \"Input\";\n\nexport default Input;\n"],"names":["HelperText","memo","error","success","helperText","errorId","helperId","helperClasses","useMemo","cn","getSpacingClass","getTypographyClasses","text","jsx","Input","forwardRef","_a","ref","_b","id","label","size","variant","leftIcon","rightIcon","showClearButton","onClear","className","disabled","type","value","onChange","props","__objRest","reactId","useId","inputId","showPassword","setShowPassword","useState","isPassword","inputType","state","hasValue","shouldShowClear","primaryFocusRing","errorFocusRing","successFocusRing","getFocusRingColor","getStateFocusRingColor","useCallback","stateType","inputVariants","cva","getRadiusClass","getTypographySize","inputClasses","labelClasses","iconSize","iconPosition","handleClear","e","inputElement","syntheticEvent","handleTogglePassword","prev","jsxs","__spreadValues","Button","X","EyeOff","Eye"],"mappings":"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"}
1
+ {"version":3,"file":"Input.js","sources":["../../../../../src/ui/primitives/Input/Input.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useState, memo, useId, useMemo, useCallback } from \"react\";\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\nimport {\n getTypographyClasses,\n getTypographySize,\n} from \"../../tokens/typography\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn, cva } from \"../../utils\";\nimport { X, Eye, EyeOff } from \"lucide-react\";\nimport Button from \"../Button/Button\";\n\n/**\n * Helper Text Component\n * Memoized component for helper/error text\n */\nconst HelperText = memo(function HelperText({\n error,\n success,\n helperText,\n errorId,\n helperId,\n}: {\n error: boolean;\n success: boolean;\n helperText?: string;\n errorId?: string;\n helperId?: string;\n}) {\n const helperClasses = useMemo(\n () =>\n cn(\n getSpacingClass(\"xs\", \"mt\"),\n getTypographyClasses(\"caption\"),\n error && \"text-fg-error\",\n success && \"text-fg-success\",\n !error && !success && \"text-fg-secondary\",\n ),\n [error, success],\n );\n\n const text = useMemo(\n () => helperText || (error ? \"Error\" : success ? \"Success\" : \"\"),\n [helperText, error, success],\n );\n\n return (\n <div\n id={errorId || helperId}\n className={helperClasses}\n role={error || success ? \"alert\" : undefined}\n >\n {text}\n </div>\n );\n});\n\nexport type InputSize = \"sm\" | \"md\" | \"lg\";\nexport type InputVariant = \"default\" | \"outlined\" | \"filled\";\nexport type InputState = \"default\" | \"error\" | \"success\";\n\nexport interface InputProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> {\n label?: ReactNode;\n error?: boolean;\n success?: boolean;\n helperText?: string;\n size?: InputSize;\n variant?: InputVariant;\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n showClearButton?: boolean;\n onClear?: () => void;\n}\n\n/**\n * Input Component\n *\n * A styled text input component with label, error/success states, icons, and clear button.\n * Uses Composite Pattern when combined with Label and ErrorMessage.\n *\n * @example\n * ```tsx\n * <Input\n * id=\"email\"\n * label=\"Email\"\n * type=\"email\"\n * placeholder=\"Enter your email\"\n * error={hasError}\n * helperText={errorMessage}\n * leftIcon={<MailIcon />}\n * />\n * ```\n */\nconst Input = memo(\n forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n id,\n label,\n error = false,\n success = false,\n helperText,\n size = \"md\",\n variant = \"outlined\",\n leftIcon,\n rightIcon,\n showClearButton = false,\n onClear,\n className = \"\",\n disabled = false,\n type = \"text\",\n value,\n onChange,\n ...props\n },\n ref,\n ) {\n // Stable fallback id when the consumer doesn't provide one. useId\n // is SSR-safe and stable across renders, replacing the deprecated\n // Math.random().substr() pattern.\n const reactId = useId();\n const inputId = id || `input-${reactId}`;\n\n // Memoize error and helper IDs\n const errorId = useMemo(\n () => (error ? `${inputId}-error` : undefined),\n [error, inputId],\n );\n\n const helperId = useMemo(\n () => (helperText ? `${inputId}-helper` : undefined),\n [helperText, inputId],\n );\n\n // Password toggle state\n const [showPassword, setShowPassword] = useState(false);\n\n // Memoize password-related values\n const isPassword = useMemo(() => type === \"password\", [type]);\n const inputType = useMemo(\n () => (isPassword && showPassword ? \"text\" : type),\n [isPassword, showPassword, type],\n );\n\n // Memoize state\n const state = useMemo<InputState>(\n () => (error ? \"error\" : success ? \"success\" : \"default\"),\n [error, success],\n );\n\n // Memoize clear button visibility\n const hasValue = useMemo(\n () => value !== undefined && value !== null && value !== \"\",\n [value],\n );\n\n const shouldShowClear = useMemo(\n () => showClearButton && hasValue && !disabled,\n [showClearButton, hasValue, disabled],\n );\n\n // Memoize focus ring colors\n const primaryFocusRing = useMemo(() => \"focus:border-line-focus\", []);\n\n const errorFocusRing = useMemo(() => \"focus:border-error\", []);\n\n const successFocusRing = useMemo(() => \"focus:border-success\", []);\n\n const getFocusRingColor = useMemo(\n () => primaryFocusRing.replace(\"focus:border-\", \"focus:ring-\"),\n [primaryFocusRing],\n );\n\n const getStateFocusRingColor = useCallback(\n (stateType: \"error\" | \"success\"): string => {\n return stateType === \"error\"\n ? errorFocusRing.replace(\"focus:border-\", \"focus:ring-\")\n : successFocusRing.replace(\"focus:border-\", \"focus:ring-\");\n },\n [errorFocusRing, successFocusRing],\n );\n\n // Input variants using CVA — memoize so the function reference is\n // stable across renders. inputClasses below depends on this; without\n // memoization a fresh cva() each render would invalidate that memo\n // on every render (defeating its purpose).\n const inputVariants = useMemo(\n () =>\n cva(\n // Base classes\n cn(\n \"w-full\",\n getRadiusClass(\"md\"),\n \"transition-colors\",\n \"focus:outline-none\",\n \"focus:ring-2\",\n \"focus:ring-offset-2\",\n \"disabled:opacity-50\",\n \"disabled:cursor-not-allowed\",\n ),\n {\n variants: {\n variant: {\n default: cn(\n \"border-0\",\n \"border-b-2\",\n \"border-line-default\",\n \"focus:border-line-focus\",\n ),\n outlined: cn(\n \"border\",\n \"border-line-default\",\n \"focus:border-line-focus\",\n ),\n filled: cn(\n \"bg-surface-muted\",\n \"border-0\",\n \"focus:bg-surface-base\",\n \"focus:ring-2\",\n getFocusRingColor,\n ),\n },\n size: {\n sm: cn(\n \"h-8\",\n getTypographySize(\"bodySmall\"),\n getSpacingClass(\"md\", \"px\"),\n ),\n md: cn(\n \"h-10\",\n getTypographySize(\"body\"),\n getSpacingClass(\"base\", \"px\"),\n ),\n lg: cn(\n \"h-12\",\n getTypographySize(\"bodyLarge\"),\n getSpacingClass(\"lg\", \"px\"),\n ),\n },\n state: {\n default: \"\",\n error: cn(\n \"border-error\",\n \"focus:border-error\",\n getStateFocusRingColor(\"error\"),\n ),\n success: cn(\n \"border-success\",\n \"focus:border-success\",\n getStateFocusRingColor(\"success\"),\n ),\n },\n },\n defaultVariants: {\n variant: \"outlined\",\n size: \"md\",\n state: \"default\",\n },\n },\n ),\n [getFocusRingColor, getStateFocusRingColor],\n );\n\n // Memoize input classes\n const inputClasses = useMemo(\n () =>\n cn(\n inputVariants({ variant, size, state }),\n // Icon padding - specific values for icon positioning.\n // `pl-9` / `pr-9` aren't on the spacing scale (no semantic\n // key for 36px); they stay raw until a future PR either\n // extends the scale or refactors the icon-padding contract.\n leftIcon &&\n (size === \"sm\"\n ? \"pl-9\"\n : size === \"lg\"\n ? getSpacingClass(\"3xl\", \"pl\")\n : getSpacingClass(\"2xl\", \"pl\")),\n (rightIcon || shouldShowClear || isPassword) &&\n (size === \"sm\"\n ? \"pr-9\"\n : size === \"lg\"\n ? getSpacingClass(\"3xl\", \"pr\")\n : getSpacingClass(\"2xl\", \"pr\")),\n className,\n ),\n [\n inputVariants,\n variant,\n size,\n state,\n leftIcon,\n rightIcon,\n shouldShowClear,\n isPassword,\n className,\n ],\n );\n\n // Memoize label classes\n const labelClasses = useMemo(\n () =>\n cn(\n \"block\",\n getTypographyClasses(\"label\"),\n getSpacingClass(\"xs\", \"mb\"),\n disabled && \"opacity-50\",\n ),\n [disabled],\n );\n\n // Memoize icon size and position\n const iconSize = useMemo(\n () => (size === \"sm\" ? \"h-4 w-4\" : size === \"lg\" ? \"h-5 w-5\" : \"h-4 w-4\"),\n [size],\n );\n\n const iconPosition = useMemo(\n () => (size === \"sm\" ? \"top-2\" : size === \"lg\" ? \"top-3.5\" : \"top-2.5\"),\n [size],\n );\n\n // Memoize clear handler\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n if (onClear) {\n onClear();\n } else if (onChange) {\n // Create synthetic event to clear input\n const inputElement = e.currentTarget\n .closest(\".relative\")\n ?.querySelector(\"input\") as HTMLInputElement;\n if (inputElement) {\n const syntheticEvent = {\n target: inputElement,\n currentTarget: inputElement,\n bubbles: true,\n cancelable: true,\n defaultPrevented: false,\n eventPhase: 2,\n isTrusted: false,\n nativeEvent: new Event(\"change\"),\n preventDefault: () => {},\n stopPropagation: () => {},\n persist: () => {},\n timeStamp: Date.now(),\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n Object.defineProperty(syntheticEvent.target, \"value\", {\n value: \"\",\n writable: true,\n });\n Object.defineProperty(syntheticEvent.currentTarget, \"value\", {\n value: \"\",\n writable: true,\n });\n onChange(syntheticEvent);\n }\n }\n },\n [onClear, onChange],\n );\n\n // Memoize password toggle handler\n const handleTogglePassword = useCallback(() => {\n setShowPassword((prev) => !prev);\n }, []);\n\n return (\n <div className=\"w-full\">\n {label && (\n <label htmlFor={inputId} className={labelClasses}>\n {label}\n </label>\n )}\n <div className=\"relative\">\n {leftIcon && (\n <div\n className={`absolute left-3 ${iconPosition} text-fg-secondary opacity-60 pointer-events-none`}\n >\n <div className={iconSize}>{leftIcon}</div>\n </div>\n )}\n <input\n id={inputId}\n ref={ref}\n type={inputType}\n className={inputClasses}\n disabled={disabled}\n value={value}\n onChange={onChange}\n aria-invalid={error}\n aria-required={props.required}\n aria-describedby={errorId || helperId}\n suppressHydrationWarning\n {...props}\n />\n <div\n className={`absolute right-3 top-0 bottom-0 flex items-center ${getSpacingClass(\"xs\", \"gap\")}`}\n >\n {shouldShowClear && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleClear}\n className={`h-auto ${getSpacingClass(\"xs\", \"p\")}`}\n aria-label=\"Clear input\"\n >\n <X className={iconSize} />\n </Button>\n )}\n {isPassword && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleTogglePassword}\n className={`h-auto ${getSpacingClass(\"xs\", \"p\")}`}\n aria-label={showPassword ? \"Hide password\" : \"Show password\"}\n >\n {showPassword ? (\n <EyeOff className={iconSize} />\n ) : (\n <Eye className={iconSize} />\n )}\n </Button>\n )}\n {rightIcon && !shouldShowClear && !isPassword && (\n <div\n className={`text-fg-secondary opacity-60 pointer-events-none ${iconSize}`}\n >\n {rightIcon}\n </div>\n )}\n </div>\n </div>\n {(error || success || helperText) && (\n <HelperText\n error={error}\n success={success}\n helperText={helperText}\n errorId={errorId}\n helperId={helperId}\n />\n )}\n </div>\n );\n }),\n);\n\nInput.displayName = \"Input\";\n\nexport default Input;\n"],"names":["HelperText","memo","error","success","helperText","errorId","helperId","helperClasses","useMemo","cn","getSpacingClass","getTypographyClasses","text","jsx","Input","forwardRef","_a","ref","_b","id","label","size","variant","leftIcon","rightIcon","showClearButton","onClear","className","disabled","type","value","onChange","props","__objRest","reactId","useId","inputId","showPassword","setShowPassword","useState","isPassword","inputType","state","hasValue","shouldShowClear","primaryFocusRing","errorFocusRing","successFocusRing","getFocusRingColor","getStateFocusRingColor","useCallback","stateType","inputVariants","cva","getRadiusClass","getTypographySize","inputClasses","labelClasses","iconSize","iconPosition","handleClear","e","inputElement","syntheticEvent","handleTogglePassword","prev","jsxs","__spreadValues","Button","X","EyeOff","Eye"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Label.js","sources":["../../../../../src/ui/primitives/Label/Label.tsx"],"sourcesContent":["import type { LabelHTMLAttributes } from \"react\";\nimport { forwardRef, memo } from \"react\";\nimport {\n getTypographySize,\n getTypographyWeight,\n} from \"../../tokens/typography\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn } from \"../../utils\";\n\ninterface Props extends LabelHTMLAttributes<HTMLLabelElement> {\n variant?: \"default\" | \"required\" | \"optional\";\n children: React.ReactNode;\n}\n\nconst labelBaseClasses = cn(\n \"block\",\n getTypographySize(\"label\"),\n getTypographyWeight(\"label\"),\n \"text-fg-primary\",\n);\n\nconst labelVariantClasses: Record<NonNullable<Props[\"variant\"]>, string> = {\n default: \"\",\n required: cn(\n \"after:content-['*']\",\n `after:${getSpacingClass(\"0.5\", \"ml\")}`,\n \"after:text-fg-error\",\n ),\n optional: cn(\n \"after:content-['(optional)']\",\n `after:${getSpacingClass(\"xs\", \"ml\")}`,\n \"after:text-fg-tertiary\",\n \"after:font-normal\",\n ),\n};\n\n/**\n * Label Component\n *\n * A styled label component for form inputs.\n * Follows Atomic Design principles as an Atom component.\n *\n * @example\n * ```tsx\n * <Label htmlFor=\"email\" variant=\"required\">\n * Email Address\n * </Label>\n * ```\n */\nconst Label = memo(\n forwardRef<HTMLLabelElement, Props>(function Label(\n { variant = \"default\", className = \"\", children, ...props },\n ref,\n ) {\n const classes = cn(\n labelBaseClasses,\n labelVariantClasses[variant],\n className,\n );\n\n return (\n <label ref={ref} className={classes} {...props}>\n {children}\n </label>\n );\n }),\n);\n\nLabel.displayName = \"Label\";\n\nexport default Label;\n"],"names":["labelBaseClasses","cn","getTypographySize","getTypographyWeight","labelVariantClasses","getSpacingClass","Label","memo","forwardRef","_a","ref","_b","variant","className","children","props","__objRest","classes","__spreadProps","__spreadValues"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,MAAMA,IAAmBC;AAAA,EACvB;AAAA,EACAC,EAAkB,OAAO;AAAA,EACzBC,EAAoB,OAAO;AAAA,EAC3B;AACF,GAEMC,IAAqE;AAAA,EACzE,SAAS;AAAA,EACT,UAAUH;AAAA,IACR;AAAA,IACA,SAASI,EAAgB,OAAO,IAAI,CAAC;AAAA,IACrC;AAAA,EAAA;AAAA,EAEF,UAAUJ;AAAA,IACR;AAAA,IACA,SAASI,EAAgB,MAAM,IAAI,CAAC;AAAA,IACpC;AAAA,IACA;AAAA,EAAA;AAEJ,GAeMC,IAAQC;AAAA,EACZC,EAAoC,SAClCC,GACAC,GACA;AAFA,QAAAC,IAAAF,GAAE,WAAAG,IAAU,WAAW,WAAAC,IAAY,IAAI,UAAAC,MAAvCH,GAAoDI,IAAAC,EAApDL,GAAoD,CAAlD,WAAqB,aAAgB;AAGvC,UAAMM,IAAUhB;AAAA,MACdD;AAAA,MACAI,EAAoBQ,CAAO;AAAA,MAC3BC;AAAA,IAAA;AAGF,6BACG,SAAAK,EAAAC,EAAA,EAAM,KAAAT,GAAU,WAAWO,KAAaF,IAAxC,EACE,UAAAD,IACH;AAAA,EAEJ,CAAC;AACH;AAEAR,EAAM,cAAc;"}
1
+ {"version":3,"file":"Label.js","sources":["../../../../../src/ui/primitives/Label/Label.tsx"],"sourcesContent":["import type { LabelHTMLAttributes } from \"react\";\nimport { forwardRef, memo } from \"react\";\nimport {\n getTypographySize,\n getTypographyWeight,\n} from \"../../tokens/typography\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn } from \"../../utils\";\n\ninterface Props extends LabelHTMLAttributes<HTMLLabelElement> {\n variant?: \"default\" | \"required\" | \"optional\";\n children: React.ReactNode;\n}\n\nconst labelBaseClasses = cn(\n \"block\",\n getTypographySize(\"label\"),\n getTypographyWeight(\"label\"),\n \"text-fg-primary\",\n);\n\nconst labelVariantClasses: Record<NonNullable<Props[\"variant\"]>, string> = {\n default: \"\",\n required: cn(\n \"after:content-['*']\",\n `after:${getSpacingClass(\"0.5\", \"ml\")}`,\n \"after:text-fg-error\",\n ),\n optional: cn(\n \"after:content-['(optional)']\",\n `after:${getSpacingClass(\"xs\", \"ml\")}`,\n \"after:text-fg-tertiary\",\n \"after:font-normal\",\n ),\n};\n\n/**\n * Label Component\n *\n * A styled label component for form inputs.\n *\n * @example\n * ```tsx\n * <Label htmlFor=\"email\" variant=\"required\">\n * Email Address\n * </Label>\n * ```\n */\nconst Label = memo(\n forwardRef<HTMLLabelElement, Props>(function Label(\n { variant = \"default\", className = \"\", children, ...props },\n ref,\n ) {\n const classes = cn(\n labelBaseClasses,\n labelVariantClasses[variant],\n className,\n );\n\n return (\n <label ref={ref} className={classes} {...props}>\n {children}\n </label>\n );\n }),\n);\n\nLabel.displayName = \"Label\";\n\nexport default Label;\n"],"names":["labelBaseClasses","cn","getTypographySize","getTypographyWeight","labelVariantClasses","getSpacingClass","Label","memo","forwardRef","_a","ref","_b","variant","className","children","props","__objRest","classes","__spreadProps","__spreadValues"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,MAAMA,IAAmBC;AAAA,EACvB;AAAA,EACAC,EAAkB,OAAO;AAAA,EACzBC,EAAoB,OAAO;AAAA,EAC3B;AACF,GAEMC,IAAqE;AAAA,EACzE,SAAS;AAAA,EACT,UAAUH;AAAA,IACR;AAAA,IACA,SAASI,EAAgB,OAAO,IAAI,CAAC;AAAA,IACrC;AAAA,EAAA;AAAA,EAEF,UAAUJ;AAAA,IACR;AAAA,IACA,SAASI,EAAgB,MAAM,IAAI,CAAC;AAAA,IACpC;AAAA,IACA;AAAA,EAAA;AAEJ,GAcMC,IAAQC;AAAA,EACZC,EAAoC,SAClCC,GACAC,GACA;AAFA,QAAAC,IAAAF,GAAE,WAAAG,IAAU,WAAW,WAAAC,IAAY,IAAI,UAAAC,MAAvCH,GAAoDI,IAAAC,EAApDL,GAAoD,CAAlD,WAAqB,aAAgB;AAGvC,UAAMM,IAAUhB;AAAA,MACdD;AAAA,MACAI,EAAoBQ,CAAO;AAAA,MAC3BC;AAAA,IAAA;AAGF,6BACG,SAAAK,EAAAC,EAAA,EAAM,KAAAT,GAAU,WAAWO,KAAaF,IAAxC,EACE,UAAAD,IACH;AAAA,EAEJ,CAAC;AACH;AAEAR,EAAM,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"NavLink.js","sources":["../../../../../src/ui/primitives/NavLink/NavLink.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * NavLink Component\n *\n * Navigation link component with active state detection and Next.js integration.\n *\n * @see EPIC-001: NavLink Component (Atom)\n * @see RFC-001: NavLink Hook Strategy (APPROVED)\n * @see RFC-002: Next.js Integration Strategy (APPROVED)\n * @see ADR-001: Active State Detection (ACCEPTED)\n */\n\nimport React, { forwardRef, useMemo, useCallback } from \"react\";\nimport type { NavLinkProps } from \"./types\";\nimport { useNavLink } from \"./hooks/useNavLink\";\nimport { cn, cva } from \"../../utils\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getTypographySize } from \"../../tokens/typography\";\nimport { getRadiusClass } from \"../../tokens/radius\";\n\n/**\n * NavLink Variants using CVA\n * Type-safe variant system for NavLink component\n */\nconst navLinkVariants = cva(\n // Base classes\n cn(\n \"inline-flex\",\n \"items-center\",\n \"transition-colors\",\n \"focus:outline-none\",\n \"focus:ring-2\",\n \"focus:ring-offset-2\",\n \"disabled:opacity-50\",\n \"disabled:cursor-not-allowed\",\n \"disabled:pointer-events-none\",\n \"no-underline\",\n ),\n {\n variants: {\n variant: {\n default: cn(\n \"text-fg-primary\",\n \"hover:opacity-80\",\n \"focus-visible:opacity-100\",\n \"focus:ring-line-brand\",\n ),\n underline: cn(\n \"text-fg-primary\",\n \"hover:opacity-80\",\n \"focus-visible:opacity-100\",\n \"border-b-2\",\n \"border-transparent\",\n \"hover:border-current\",\n \"focus:ring-line-brand\",\n ),\n background: cn(\n \"text-fg-primary\",\n \"hover:bg-surface-hover\",\n getRadiusClass(\"md\"),\n \"focus:ring-line-brand\",\n ),\n },\n size: {\n sm: cn(\n getSpacingClass(\"sm\", \"px\"),\n getSpacingClass(\"xs\", \"py\"),\n getTypographySize(\"bodySmall\"),\n ),\n md: cn(\n getSpacingClass(\"base\", \"px\"),\n getSpacingClass(\"sm\", \"py\"),\n getTypographySize(\"body\"),\n ),\n lg: cn(\n getSpacingClass(\"lg\", \"px\"),\n getSpacingClass(\"md\", \"py\"),\n getTypographySize(\"bodyLarge\"),\n ),\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n },\n compoundVariants: [\n {\n variant: \"underline\",\n size: \"sm\",\n class: getSpacingClass(\"0.5\", \"pb\"),\n },\n {\n variant: \"underline\",\n size: \"md\",\n class: getSpacingClass(\"xs\", \"pb\"),\n },\n {\n variant: \"underline\",\n size: \"lg\",\n class: getSpacingClass(\"1.5\", \"pb\"),\n },\n {\n variant: \"background\",\n size: \"sm\",\n class: getSpacingClass(\"xs\", \"px\"),\n },\n {\n variant: \"background\",\n size: \"md\",\n class: getSpacingClass(\"sm\", \"px\"),\n },\n {\n variant: \"background\",\n size: \"lg\",\n class: getSpacingClass(\"base\", \"px\"),\n },\n ],\n },\n);\n\n/**\n * NavLink Component\n *\n * Navigation link with active state detection and Next.js integration.\n *\n * @example\n * ```tsx\n * <NavLink href=\"/home\">Home</NavLink>\n * <NavLink href=\"/about\" variant=\"underline\" active>About</NavLink>\n * <NavLink href=\"/contact\" variant=\"background\" size=\"lg\">Contact</NavLink>\n * ```\n *\n * Note: Auto-detection of active state via usePathname is deferred to a future enhancement\n * to avoid issues with conditional hook calls. For now, use the `active` prop manually\n * or implement pathname detection in the parent component.\n */\nexport const NavLink = forwardRef<HTMLAnchorElement, NavLinkProps>(\n function NavLink(\n {\n href,\n children,\n active,\n disabled = false,\n variant = \"default\",\n size = \"md\",\n as,\n className,\n \"aria-label\": ariaLabel,\n onClick,\n onKeyDown,\n ...props\n },\n ref,\n ) {\n // Calculate active state\n // Priority: manual active > false (ADR-001)\n // TODO: Add auto-detect via usePathname in future enhancement\n // This requires a wrapper component pattern to avoid conditional hook calls\n const calculatedActive = useMemo(() => {\n // Manual active prop has priority (ADR-001)\n if (active !== undefined) {\n return active;\n }\n\n // Default to false\n // TODO: Auto-detect using usePathname (if Next.js available)\n return false;\n }, [active]);\n\n // Use hook for Next.js Link integration\n const { NextLink } = useNavLink({ href, active: calculatedActive });\n\n // Determine Link component\n // Priority: as prop > NextLink (auto-detected) > 'a' (RFC-002)\n const LinkComponent: React.ElementType = as || NextLink || \"a\";\n\n // Active state classes\n const activeClasses = useMemo(() => {\n if (!calculatedActive) return \"\";\n\n switch (variant) {\n case \"underline\":\n return cn(\n \"border-b-2\",\n \"border-line-brand\",\n \"text-fg-brand-emphasis\",\n );\n case \"background\":\n return cn(\"bg-surface-brand-muted\", \"text-fg-brand-emphasis\");\n case \"default\":\n default:\n return cn(\"text-fg-brand-emphasis\", \"font-semibold\");\n }\n }, [calculatedActive, variant]);\n\n // Handle disabled state\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n onClick?.(e);\n },\n [disabled, onClick],\n );\n\n // Handle keyboard navigation\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLAnchorElement>) => {\n if (disabled) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n }\n return;\n }\n onKeyDown?.(e);\n },\n [disabled, onKeyDown],\n );\n\n // Prepare props for LinkComponent\n // Next.js Link has different prop structure, so we need to handle it\n const linkProps = useMemo(() => {\n const baseProps = {\n className: cn(\n navLinkVariants({ variant, size }),\n activeClasses,\n disabled && \"opacity-50 cursor-not-allowed pointer-events-none\",\n className,\n ),\n \"aria-current\": calculatedActive ? \"page\" : undefined,\n \"aria-disabled\": disabled ? true : undefined,\n \"aria-label\": ariaLabel,\n tabIndex: disabled ? -1 : undefined,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n \"data-active\": calculatedActive,\n \"data-disabled\": disabled,\n ...props,\n };\n\n // For Next.js Link, we need to pass href differently\n if (NextLink && !as) {\n return {\n ...baseProps,\n href: disabled ? undefined : href,\n };\n }\n\n // For regular anchor or custom component\n return {\n ...baseProps,\n href: disabled ? undefined : href,\n };\n }, [\n variant,\n size,\n activeClasses,\n disabled,\n className,\n calculatedActive,\n ariaLabel,\n handleClick,\n handleKeyDown,\n href,\n NextLink,\n as,\n props,\n ]);\n\n return (\n <LinkComponent ref={ref} {...linkProps}>\n {children}\n </LinkComponent>\n );\n },\n);\n\nNavLink.displayName = \"NavLink\";\n\nexport default NavLink;\n"],"names":["navLinkVariants","cva","cn","getRadiusClass","getSpacingClass","getTypographySize","NavLink","forwardRef","_a","ref","_b","href","children","active","disabled","variant","size","as","className","ariaLabel","onClick","onKeyDown","props","__objRest","calculatedActive","useMemo","NextLink","useNavLink","LinkComponent","activeClasses","handleClick","useCallback","e","handleKeyDown","linkProps","baseProps","__spreadValues","__spreadProps","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"NavLink.js","sources":["../../../../../src/ui/primitives/NavLink/NavLink.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * NavLink Component\n *\n * Navigation link component with active state detection and Next.js integration.\n *\n * @see EPIC-001: NavLink Component\n * @see RFC-001: NavLink Hook Strategy (APPROVED)\n * @see RFC-002: Next.js Integration Strategy (APPROVED)\n * @see ADR-001: Active State Detection (ACCEPTED)\n */\n\nimport React, { forwardRef, useMemo, useCallback } from \"react\";\nimport type { NavLinkProps } from \"./types\";\nimport { useNavLink } from \"./hooks/useNavLink\";\nimport { cn, cva } from \"../../utils\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getTypographySize } from \"../../tokens/typography\";\nimport { getRadiusClass } from \"../../tokens/radius\";\n\n/**\n * NavLink Variants using CVA\n * Type-safe variant system for NavLink component\n */\nconst navLinkVariants = cva(\n // Base classes\n cn(\n \"inline-flex\",\n \"items-center\",\n \"transition-colors\",\n \"focus:outline-none\",\n \"focus:ring-2\",\n \"focus:ring-offset-2\",\n \"disabled:opacity-50\",\n \"disabled:cursor-not-allowed\",\n \"disabled:pointer-events-none\",\n \"no-underline\",\n ),\n {\n variants: {\n variant: {\n default: cn(\n \"text-fg-primary\",\n \"hover:opacity-80\",\n \"focus-visible:opacity-100\",\n \"focus:ring-line-brand\",\n ),\n underline: cn(\n \"text-fg-primary\",\n \"hover:opacity-80\",\n \"focus-visible:opacity-100\",\n \"border-b-2\",\n \"border-transparent\",\n \"hover:border-current\",\n \"focus:ring-line-brand\",\n ),\n background: cn(\n \"text-fg-primary\",\n \"hover:bg-surface-hover\",\n getRadiusClass(\"md\"),\n \"focus:ring-line-brand\",\n ),\n },\n size: {\n sm: cn(\n getSpacingClass(\"sm\", \"px\"),\n getSpacingClass(\"xs\", \"py\"),\n getTypographySize(\"bodySmall\"),\n ),\n md: cn(\n getSpacingClass(\"base\", \"px\"),\n getSpacingClass(\"sm\", \"py\"),\n getTypographySize(\"body\"),\n ),\n lg: cn(\n getSpacingClass(\"lg\", \"px\"),\n getSpacingClass(\"md\", \"py\"),\n getTypographySize(\"bodyLarge\"),\n ),\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n },\n compoundVariants: [\n {\n variant: \"underline\",\n size: \"sm\",\n class: getSpacingClass(\"0.5\", \"pb\"),\n },\n {\n variant: \"underline\",\n size: \"md\",\n class: getSpacingClass(\"xs\", \"pb\"),\n },\n {\n variant: \"underline\",\n size: \"lg\",\n class: getSpacingClass(\"1.5\", \"pb\"),\n },\n {\n variant: \"background\",\n size: \"sm\",\n class: getSpacingClass(\"xs\", \"px\"),\n },\n {\n variant: \"background\",\n size: \"md\",\n class: getSpacingClass(\"sm\", \"px\"),\n },\n {\n variant: \"background\",\n size: \"lg\",\n class: getSpacingClass(\"base\", \"px\"),\n },\n ],\n },\n);\n\n/**\n * NavLink Component\n *\n * Navigation link with active state detection and Next.js integration.\n *\n * @example\n * ```tsx\n * <NavLink href=\"/home\">Home</NavLink>\n * <NavLink href=\"/about\" variant=\"underline\" active>About</NavLink>\n * <NavLink href=\"/contact\" variant=\"background\" size=\"lg\">Contact</NavLink>\n * ```\n *\n * Note: Auto-detection of active state via usePathname is deferred to a future enhancement\n * to avoid issues with conditional hook calls. For now, use the `active` prop manually\n * or implement pathname detection in the parent component.\n */\nexport const NavLink = forwardRef<HTMLAnchorElement, NavLinkProps>(\n function NavLink(\n {\n href,\n children,\n active,\n disabled = false,\n variant = \"default\",\n size = \"md\",\n as,\n className,\n \"aria-label\": ariaLabel,\n onClick,\n onKeyDown,\n ...props\n },\n ref,\n ) {\n // Calculate active state\n // Priority: manual active > false (ADR-001)\n // TODO: Add auto-detect via usePathname in future enhancement\n // This requires a wrapper component pattern to avoid conditional hook calls\n const calculatedActive = useMemo(() => {\n // Manual active prop has priority (ADR-001)\n if (active !== undefined) {\n return active;\n }\n\n // Default to false\n // TODO: Auto-detect using usePathname (if Next.js available)\n return false;\n }, [active]);\n\n // Use hook for Next.js Link integration\n const { NextLink } = useNavLink({ href, active: calculatedActive });\n\n // Determine Link component\n // Priority: as prop > NextLink (auto-detected) > 'a' (RFC-002)\n const LinkComponent: React.ElementType = as || NextLink || \"a\";\n\n // Active state classes\n const activeClasses = useMemo(() => {\n if (!calculatedActive) return \"\";\n\n switch (variant) {\n case \"underline\":\n return cn(\n \"border-b-2\",\n \"border-line-brand\",\n \"text-fg-brand-emphasis\",\n );\n case \"background\":\n return cn(\"bg-surface-brand-muted\", \"text-fg-brand-emphasis\");\n case \"default\":\n default:\n return cn(\"text-fg-brand-emphasis\", \"font-semibold\");\n }\n }, [calculatedActive, variant]);\n\n // Handle disabled state\n const handleClick = useCallback(\n (e: React.MouseEvent<HTMLAnchorElement>) => {\n if (disabled) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n onClick?.(e);\n },\n [disabled, onClick],\n );\n\n // Handle keyboard navigation\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLAnchorElement>) => {\n if (disabled) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n e.stopPropagation();\n }\n return;\n }\n onKeyDown?.(e);\n },\n [disabled, onKeyDown],\n );\n\n // Prepare props for LinkComponent\n // Next.js Link has different prop structure, so we need to handle it\n const linkProps = useMemo(() => {\n const baseProps = {\n className: cn(\n navLinkVariants({ variant, size }),\n activeClasses,\n disabled && \"opacity-50 cursor-not-allowed pointer-events-none\",\n className,\n ),\n \"aria-current\": calculatedActive ? \"page\" : undefined,\n \"aria-disabled\": disabled ? true : undefined,\n \"aria-label\": ariaLabel,\n tabIndex: disabled ? -1 : undefined,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n \"data-active\": calculatedActive,\n \"data-disabled\": disabled,\n ...props,\n };\n\n // For Next.js Link, we need to pass href differently\n if (NextLink && !as) {\n return {\n ...baseProps,\n href: disabled ? undefined : href,\n };\n }\n\n // For regular anchor or custom component\n return {\n ...baseProps,\n href: disabled ? undefined : href,\n };\n }, [\n variant,\n size,\n activeClasses,\n disabled,\n className,\n calculatedActive,\n ariaLabel,\n handleClick,\n handleKeyDown,\n href,\n NextLink,\n as,\n props,\n ]);\n\n return (\n <LinkComponent ref={ref} {...linkProps}>\n {children}\n </LinkComponent>\n );\n },\n);\n\nNavLink.displayName = \"NavLink\";\n\nexport default NavLink;\n"],"names":["navLinkVariants","cva","cn","getRadiusClass","getSpacingClass","getTypographySize","NavLink","forwardRef","_a","ref","_b","href","children","active","disabled","variant","size","as","className","ariaLabel","onClick","onKeyDown","props","__objRest","calculatedActive","useMemo","NextLink","useNavLink","LinkComponent","activeClasses","handleClick","useCallback","e","handleKeyDown","linkProps","baseProps","__spreadValues","__spreadProps","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAMA,IAAkBC;AAAA;AAAA,EAEtBC;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAASA;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,WAAWA;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,YAAYA;AAAA,UACV;AAAA,UACA;AAAA,UACAC,EAAe,IAAI;AAAA,UACnB;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,MAAM;AAAA,QACJ,IAAID;AAAA,UACFE,EAAgB,MAAM,IAAI;AAAA,UAC1BA,EAAgB,MAAM,IAAI;AAAA,UAC1BC,EAAkB,WAAW;AAAA,QAAA;AAAA,QAE/B,IAAIH;AAAA,UACFE,EAAgB,QAAQ,IAAI;AAAA,UAC5BA,EAAgB,MAAM,IAAI;AAAA,UAC1BC,EAAkB,MAAM;AAAA,QAAA;AAAA,QAE1B,IAAIH;AAAA,UACFE,EAAgB,MAAM,IAAI;AAAA,UAC1BA,EAAgB,MAAM,IAAI;AAAA,UAC1BC,EAAkB,WAAW;AAAA,QAAA;AAAA,MAC/B;AAAA,IACF;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,IAER,kBAAkB;AAAA,MAChB;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAOD,EAAgB,OAAO,IAAI;AAAA,MAAA;AAAA,MAEpC;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAOA,EAAgB,MAAM,IAAI;AAAA,MAAA;AAAA,MAEnC;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAOA,EAAgB,OAAO,IAAI;AAAA,MAAA;AAAA,MAEpC;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAOA,EAAgB,MAAM,IAAI;AAAA,MAAA;AAAA,MAEnC;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAOA,EAAgB,MAAM,IAAI;AAAA,MAAA;AAAA,MAEnC;AAAA,QACE,SAAS;AAAA,QACT,MAAM;AAAA,QACN,OAAOA,EAAgB,QAAQ,IAAI;AAAA,MAAA;AAAA,IACrC;AAAA,EACF;AAEJ,GAkBaE,IAAUC;AAAA,EACrB,SACEC,GAcAC,GACA;AAfA,QAAAC,IAAAF,GACE;AAAA,YAAAG;AAAA,MACA,UAAAC;AAAA,MACA,QAAAC;AAAA,MACA,UAAAC,IAAW;AAAA,MACX,SAAAC,IAAU;AAAA,MACV,MAAAC,IAAO;AAAA,MACP,IAAAC;AAAA,MACA,WAAAC;AAAA,MACA,cAAcC;AAAA,MACd,SAAAC;AAAA,MACA,WAAAC;AAAA,QAXFX,GAYKY,IAAAC,EAZLb,GAYK;AAAA,MAXH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AASF,UAAMc,IAAmBC,EAAQ,MAE3BZ,MAAW,SACNA,IAKF,IACN,CAACA,CAAM,CAAC,GAGL,EAAE,UAAAa,MAAaC,EAAW,EAAE,MAAAhB,GAAM,QAAQa,GAAkB,GAI5DI,IAAmCX,KAAMS,KAAY,KAGrDG,IAAgBJ,EAAQ,MAAM;AAClC,UAAI,CAACD,EAAkB,QAAO;AAE9B,cAAQT,GAAA;AAAA,QACN,KAAK;AACH,iBAAOb;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAAA,QAEJ,KAAK;AACH,iBAAOA,EAAG,0BAA0B,wBAAwB;AAAA,QAE9D;AACE,iBAAOA,EAAG,0BAA0B,eAAe;AAAA,MAAA;AAAA,IAEzD,GAAG,CAACsB,GAAkBT,CAAO,CAAC,GAGxBe,IAAcC;AAAA,MAClB,CAACC,MAA2C;AAC1C,YAAIlB,GAAU;AACZ,UAAAkB,EAAE,eAAA,GACFA,EAAE,gBAAA;AACF;AAAA,QACF;AACA,QAAAZ,KAAA,QAAAA,EAAUY;AAAA,MACZ;AAAA,MACA,CAAClB,GAAUM,CAAO;AAAA,IAAA,GAIda,IAAgBF;AAAA,MACpB,CAACC,MAA8C;AAC7C,YAAIlB,GAAU;AACZ,WAAIkB,EAAE,QAAQ,WAAWA,EAAE,QAAQ,SACjCA,EAAE,eAAA,GACFA,EAAE,gBAAA;AAEJ;AAAA,QACF;AACA,QAAAX,KAAA,QAAAA,EAAYW;AAAA,MACd;AAAA,MACA,CAAClB,GAAUO,CAAS;AAAA,IAAA,GAKhBa,IAAYT,EAAQ,MAAM;AAC9B,YAAMU,IAAYC,EAAA;AAAA,QAChB,WAAWlC;AAAA,UACTF,EAAgB,EAAE,SAAAe,GAAS,MAAAC,GAAM;AAAA,UACjCa;AAAA,UACAf,KAAY;AAAA,UACZI;AAAA,QAAA;AAAA,QAEF,gBAAgBM,IAAmB,SAAS;AAAA,QAC5C,iBAAiBV,IAAW,KAAO;AAAA,QACnC,cAAcK;AAAA,QACd,UAAUL,IAAW,KAAK;AAAA,QAC1B,SAASgB;AAAA,QACT,WAAWG;AAAA,QACX,eAAeT;AAAA,QACf,iBAAiBV;AAAA,SACdQ;AAIL,aAAII,KAAY,CAACT,IACRoB,EAAAD,EAAA,IACFD,IADE;AAAA,QAEL,MAAMrB,IAAW,SAAYH;AAAA,MAAA,KAK1B0B,EAAAD,EAAA,IACFD,IADE;AAAA,QAEL,MAAMrB,IAAW,SAAYH;AAAA,MAAA;AAAA,IAEjC,GAAG;AAAA,MACDI;AAAA,MACAC;AAAA,MACAa;AAAA,MACAf;AAAA,MACAI;AAAA,MACAM;AAAA,MACAL;AAAA,MACAW;AAAA,MACAG;AAAA,MACAtB;AAAA,MACAe;AAAA,MACAT;AAAA,MACAK;AAAA,IAAA,CACD;AAED,WACE,gBAAAgB,EAACV,GAAAS,EAAAD,EAAA,EAAc,KAAA3B,KAAcyB,IAA5B,EACE,UAAAtB,IACH;AAAA,EAEJ;AACF;AAEAN,EAAQ,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.js","sources":["../../../../../src/ui/primitives/Radio/Radio.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, memo, useId, useMemo } from \"react\";\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\nimport { getTypographyClasses } from \"../../tokens/typography\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn } from \"../../utils\";\n\nexport interface RadioProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"type\"\n> {\n label?: ReactNode;\n error?: boolean;\n /**\n * Validation success state — paints the border and (when\n * `helperText` is also set) the helper-text color green. Matches\n * the Input + Select + Checkbox + Switch + Textarea convention;\n * the three feedback flags (`error`, `success`, `helperText`)\n * cover every form primitive in the DS. Error takes precedence\n * when both `error` and `success` are set.\n */\n success?: boolean;\n helperText?: string;\n}\n\n/**\n * Radio Component\n *\n * A styled radio input component.\n * Follows Atomic Design principles as an Atom component.\n * Uses Composite Pattern when combined with Label and ErrorMessage.\n *\n * @example\n * ```tsx\n * <Radio\n * id=\"option1\"\n * name=\"options\"\n * label=\"Option 1\"\n * value=\"1\"\n * checked={selected === \"1\"}\n * onChange={handleChange}\n * />\n * ```\n */\nconst Radio = memo(\n forwardRef<HTMLInputElement, RadioProps>(function Radio(\n {\n id,\n label,\n error = false,\n success = false,\n helperText,\n className = \"\",\n disabled = false,\n ...props\n },\n ref,\n ) {\n // Stable fallback id when the consumer doesn't provide one. useId\n // is SSR-safe and stable across renders, replacing the deprecated\n // Math.random().substr() pattern.\n const reactId = useId();\n const radioId = id || `radio-${reactId}`;\n\n const errorId = useMemo(\n () => (error ? `${radioId}-error` : undefined),\n [error, radioId],\n );\n\n const helperId = useMemo(\n () => (helperText ? `${radioId}-helper` : undefined),\n [helperText, radioId],\n );\n\n // Memoize focus ring colors\n const primaryFocusRing = useMemo(() => \"focus:border-line-focus\", []);\n\n const errorFocusRing = useMemo(() => \"focus:border-error\", []);\n\n const focusRingColor = useMemo(\n () =>\n error\n ? errorFocusRing.replace(\"focus:border-\", \"focus:ring-\")\n : primaryFocusRing.replace(\"focus:border-\", \"focus:ring-\"),\n [error, errorFocusRing, primaryFocusRing],\n );\n\n // Memoize classes — error wins over success when both flags are\n // set (a field cannot be valid AND invalid; treat it as invalid).\n const radioClasses = useMemo(\n () =>\n cn(\n \"h-4\",\n \"w-4\",\n \"border\",\n \"border-line-default\",\n \"text-fg-brand\",\n \"focus:ring-2\",\n focusRingColor,\n \"focus:ring-offset-2\",\n \"disabled:opacity-50\",\n \"disabled:cursor-not-allowed\",\n \"cursor-pointer\",\n error && \"border-error\",\n !error && success && \"border-success\",\n className,\n ),\n [focusRingColor, error, success, className],\n );\n\n const labelClasses = useMemo(\n () =>\n cn(\n getTypographyClasses(\"label\"),\n getSpacingClass(\"sm\", \"ml\"),\n disabled ? \"opacity-50 cursor-not-allowed\" : \"cursor-pointer\",\n ),\n [disabled],\n );\n\n return (\n <div className={cn(\"flex\", \"flex-col\", getSpacingClass(\"sm\", \"my\"))}>\n <div className=\"flex items-center\">\n <input\n type=\"radio\"\n id={radioId}\n ref={ref}\n className={radioClasses}\n disabled={disabled}\n aria-invalid={error}\n aria-describedby={errorId || helperId || undefined}\n aria-label={!label ? \"Radio button\" : undefined}\n {...props}\n />\n {label && (\n <label htmlFor={radioId} className={labelClasses}>\n {label}\n </label>\n )}\n </div>\n {(error || success || helperText) && (\n <div\n id={errorId || helperId}\n className={cn(\n getSpacingClass(\"xs\", \"mt\"),\n getTypographyClasses(\"caption\"),\n error\n ? \"text-fg-error\"\n : success\n ? \"text-fg-success\"\n : \"text-fg-secondary\",\n )}\n role={error || success ? \"alert\" : undefined}\n >\n {error ? helperText || \"This field has an error\" : helperText}\n </div>\n )}\n </div>\n );\n }),\n);\n\nRadio.displayName = \"Radio\";\n\nexport default Radio;\n"],"names":["Radio","memo","forwardRef","_a","ref","_b","id","label","error","success","helperText","className","disabled","props","__objRest","reactId","useId","radioId","errorId","useMemo","helperId","primaryFocusRing","errorFocusRing","focusRingColor","radioClasses","cn","labelClasses","getTypographyClasses","getSpacingClass","jsxs","jsx","__spreadValues"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,MAAMA,IAAQC;AAAA,EACZC,EAAyC,SACvCC,GAUAC,GACA;AAXA,QAAAC,IAAAF,GACE;AAAA,UAAAG;AAAA,MACA,OAAAC;AAAA,MACA,OAAAC,IAAQ;AAAA,MACR,SAAAC,IAAU;AAAA,MACV,YAAAC;AAAA,MACA,WAAAC,IAAY;AAAA,MACZ,UAAAC,IAAW;AAAA,QAPbP,GAQKQ,IAAAC,EARLT,GAQK;AAAA,MAPH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAQF,UAAMU,IAAUC,EAAA,GACVC,IAAUX,KAAM,SAASS,CAAO,IAEhCG,IAAUC;AAAA,MACd,MAAOX,IAAQ,GAAGS,CAAO,WAAW;AAAA,MACpC,CAACT,GAAOS,CAAO;AAAA,IAAA,GAGXG,IAAWD;AAAA,MACf,MAAOT,IAAa,GAAGO,CAAO,YAAY;AAAA,MAC1C,CAACP,GAAYO,CAAO;AAAA,IAAA,GAIhBI,IAAmBF,EAAQ,MAAM,2BAA2B,CAAA,CAAE,GAE9DG,IAAiBH,EAAQ,MAAM,sBAAsB,CAAA,CAAE,GAEvDI,IAAiBJ;AAAA,MACrB,MACEX,IACIc,EAAe,QAAQ,iBAAiB,aAAa,IACrDD,EAAiB,QAAQ,iBAAiB,aAAa;AAAA,MAC7D,CAACb,GAAOc,GAAgBD,CAAgB;AAAA,IAAA,GAKpCG,IAAeL;AAAA,MACnB,MACEM;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAF;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAf,KAAS;AAAA,QACT,CAACA,KAASC,KAAW;AAAA,QACrBE;AAAA,MAAA;AAAA,MAEJ,CAACY,GAAgBf,GAAOC,GAASE,CAAS;AAAA,IAAA,GAGtCe,IAAeP;AAAA,MACnB,MACEM;AAAA,QACEE,EAAqB,OAAO;AAAA,QAC5BC,EAAgB,MAAM,IAAI;AAAA,QAC1BhB,IAAW,kCAAkC;AAAA,MAAA;AAAA,MAEjD,CAACA,CAAQ;AAAA,IAAA;AAGX,WACE,gBAAAiB,EAAC,OAAA,EAAI,WAAWJ,EAAG,QAAQ,YAAYG,EAAgB,MAAM,IAAI,CAAC,GAChE,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,QAAA,gBAAAC;AAAA,UAAC;AAAA,UAAAC,EAAA;AAAA,YACC,MAAK;AAAA,YACL,IAAId;AAAA,YACJ,KAAAb;AAAA,YACA,WAAWoB;AAAA,YACX,UAAAZ;AAAA,YACA,gBAAcJ;AAAA,YACd,oBAAkBU,KAAWE,KAAY;AAAA,YACzC,cAAab,IAAyB,SAAjB;AAAA,aACjBM;AAAA,QAAA;AAAA,QAELN,KACC,gBAAAuB,EAAC,SAAA,EAAM,SAASb,GAAS,WAAWS,GACjC,UAAAnB,EAAA,CACH;AAAA,MAAA,GAEJ;AAAA,OACEC,KAASC,KAAWC,MACpB,gBAAAoB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAIZ,KAAWE;AAAA,UACf,WAAWK;AAAA,YACTG,EAAgB,MAAM,IAAI;AAAA,YAC1BD,EAAqB,SAAS;AAAA,YAC9BnB,IACI,kBACAC,IACE,oBACA;AAAA,UAAA;AAAA,UAER,MAAMD,KAASC,IAAU,UAAU;AAAA,UAElC,UAAAD,IAAQE,KAAc,4BAA4BA;AAAA,QAAA;AAAA,MAAA;AAAA,IACrD,GAEJ;AAAA,EAEJ,CAAC;AACH;AAEAV,EAAM,cAAc;"}
1
+ {"version":3,"file":"Radio.js","sources":["../../../../../src/ui/primitives/Radio/Radio.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, memo, useId, useMemo } from \"react\";\nimport type { InputHTMLAttributes, ReactNode } from \"react\";\nimport { getTypographyClasses } from \"../../tokens/typography\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn } from \"../../utils\";\n\nexport interface RadioProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"type\"\n> {\n label?: ReactNode;\n error?: boolean;\n /**\n * Validation success state — paints the border and (when\n * `helperText` is also set) the helper-text color green. Matches\n * the Input + Select + Checkbox + Switch + Textarea convention;\n * the three feedback flags (`error`, `success`, `helperText`)\n * cover every form primitive in the DS. Error takes precedence\n * when both `error` and `success` are set.\n */\n success?: boolean;\n helperText?: string;\n}\n\n/**\n * Radio Component\n *\n * A styled radio input component.\n * Uses Composite Pattern when combined with Label and ErrorMessage.\n *\n * @example\n * ```tsx\n * <Radio\n * id=\"option1\"\n * name=\"options\"\n * label=\"Option 1\"\n * value=\"1\"\n * checked={selected === \"1\"}\n * onChange={handleChange}\n * />\n * ```\n */\nconst Radio = memo(\n forwardRef<HTMLInputElement, RadioProps>(function Radio(\n {\n id,\n label,\n error = false,\n success = false,\n helperText,\n className = \"\",\n disabled = false,\n ...props\n },\n ref,\n ) {\n // Stable fallback id when the consumer doesn't provide one. useId\n // is SSR-safe and stable across renders, replacing the deprecated\n // Math.random().substr() pattern.\n const reactId = useId();\n const radioId = id || `radio-${reactId}`;\n\n const errorId = useMemo(\n () => (error ? `${radioId}-error` : undefined),\n [error, radioId],\n );\n\n const helperId = useMemo(\n () => (helperText ? `${radioId}-helper` : undefined),\n [helperText, radioId],\n );\n\n // Memoize focus ring colors\n const primaryFocusRing = useMemo(() => \"focus:border-line-focus\", []);\n\n const errorFocusRing = useMemo(() => \"focus:border-error\", []);\n\n const focusRingColor = useMemo(\n () =>\n error\n ? errorFocusRing.replace(\"focus:border-\", \"focus:ring-\")\n : primaryFocusRing.replace(\"focus:border-\", \"focus:ring-\"),\n [error, errorFocusRing, primaryFocusRing],\n );\n\n // Memoize classes — error wins over success when both flags are\n // set (a field cannot be valid AND invalid; treat it as invalid).\n const radioClasses = useMemo(\n () =>\n cn(\n \"h-4\",\n \"w-4\",\n \"border\",\n \"border-line-default\",\n \"text-fg-brand\",\n \"focus:ring-2\",\n focusRingColor,\n \"focus:ring-offset-2\",\n \"disabled:opacity-50\",\n \"disabled:cursor-not-allowed\",\n \"cursor-pointer\",\n error && \"border-error\",\n !error && success && \"border-success\",\n className,\n ),\n [focusRingColor, error, success, className],\n );\n\n const labelClasses = useMemo(\n () =>\n cn(\n getTypographyClasses(\"label\"),\n getSpacingClass(\"sm\", \"ml\"),\n disabled ? \"opacity-50 cursor-not-allowed\" : \"cursor-pointer\",\n ),\n [disabled],\n );\n\n return (\n <div className={cn(\"flex\", \"flex-col\", getSpacingClass(\"sm\", \"my\"))}>\n <div className=\"flex items-center\">\n <input\n type=\"radio\"\n id={radioId}\n ref={ref}\n className={radioClasses}\n disabled={disabled}\n aria-invalid={error}\n aria-describedby={errorId || helperId || undefined}\n aria-label={!label ? \"Radio button\" : undefined}\n {...props}\n />\n {label && (\n <label htmlFor={radioId} className={labelClasses}>\n {label}\n </label>\n )}\n </div>\n {(error || success || helperText) && (\n <div\n id={errorId || helperId}\n className={cn(\n getSpacingClass(\"xs\", \"mt\"),\n getTypographyClasses(\"caption\"),\n error\n ? \"text-fg-error\"\n : success\n ? \"text-fg-success\"\n : \"text-fg-secondary\",\n )}\n role={error || success ? \"alert\" : undefined}\n >\n {error ? helperText || \"This field has an error\" : helperText}\n </div>\n )}\n </div>\n );\n }),\n);\n\nRadio.displayName = \"Radio\";\n\nexport default Radio;\n"],"names":["Radio","memo","forwardRef","_a","ref","_b","id","label","error","success","helperText","className","disabled","props","__objRest","reactId","useId","radioId","errorId","useMemo","helperId","primaryFocusRing","errorFocusRing","focusRingColor","radioClasses","cn","labelClasses","getTypographyClasses","getSpacingClass","jsxs","jsx","__spreadValues"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,MAAMA,IAAQC;AAAA,EACZC,EAAyC,SACvCC,GAUAC,GACA;AAXA,QAAAC,IAAAF,GACE;AAAA,UAAAG;AAAA,MACA,OAAAC;AAAA,MACA,OAAAC,IAAQ;AAAA,MACR,SAAAC,IAAU;AAAA,MACV,YAAAC;AAAA,MACA,WAAAC,IAAY;AAAA,MACZ,UAAAC,IAAW;AAAA,QAPbP,GAQKQ,IAAAC,EARLT,GAQK;AAAA,MAPH;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAQF,UAAMU,IAAUC,EAAA,GACVC,IAAUX,KAAM,SAASS,CAAO,IAEhCG,IAAUC;AAAA,MACd,MAAOX,IAAQ,GAAGS,CAAO,WAAW;AAAA,MACpC,CAACT,GAAOS,CAAO;AAAA,IAAA,GAGXG,IAAWD;AAAA,MACf,MAAOT,IAAa,GAAGO,CAAO,YAAY;AAAA,MAC1C,CAACP,GAAYO,CAAO;AAAA,IAAA,GAIhBI,IAAmBF,EAAQ,MAAM,2BAA2B,CAAA,CAAE,GAE9DG,IAAiBH,EAAQ,MAAM,sBAAsB,CAAA,CAAE,GAEvDI,IAAiBJ;AAAA,MACrB,MACEX,IACIc,EAAe,QAAQ,iBAAiB,aAAa,IACrDD,EAAiB,QAAQ,iBAAiB,aAAa;AAAA,MAC7D,CAACb,GAAOc,GAAgBD,CAAgB;AAAA,IAAA,GAKpCG,IAAeL;AAAA,MACnB,MACEM;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAF;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAf,KAAS;AAAA,QACT,CAACA,KAASC,KAAW;AAAA,QACrBE;AAAA,MAAA;AAAA,MAEJ,CAACY,GAAgBf,GAAOC,GAASE,CAAS;AAAA,IAAA,GAGtCe,IAAeP;AAAA,MACnB,MACEM;AAAA,QACEE,EAAqB,OAAO;AAAA,QAC5BC,EAAgB,MAAM,IAAI;AAAA,QAC1BhB,IAAW,kCAAkC;AAAA,MAAA;AAAA,MAEjD,CAACA,CAAQ;AAAA,IAAA;AAGX,WACE,gBAAAiB,EAAC,OAAA,EAAI,WAAWJ,EAAG,QAAQ,YAAYG,EAAgB,MAAM,IAAI,CAAC,GAChE,UAAA;AAAA,MAAA,gBAAAC,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA;AAAA,QAAA,gBAAAC;AAAA,UAAC;AAAA,UAAAC,EAAA;AAAA,YACC,MAAK;AAAA,YACL,IAAId;AAAA,YACJ,KAAAb;AAAA,YACA,WAAWoB;AAAA,YACX,UAAAZ;AAAA,YACA,gBAAcJ;AAAA,YACd,oBAAkBU,KAAWE,KAAY;AAAA,YACzC,cAAab,IAAyB,SAAjB;AAAA,aACjBM;AAAA,QAAA;AAAA,QAELN,KACC,gBAAAuB,EAAC,SAAA,EAAM,SAASb,GAAS,WAAWS,GACjC,UAAAnB,EAAA,CACH;AAAA,MAAA,GAEJ;AAAA,OACEC,KAASC,KAAWC,MACpB,gBAAAoB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,IAAIZ,KAAWE;AAAA,UACf,WAAWK;AAAA,YACTG,EAAgB,MAAM,IAAI;AAAA,YAC1BD,EAAqB,SAAS;AAAA,YAC9BnB,IACI,kBACAC,IACE,oBACA;AAAA,UAAA;AAAA,UAER,MAAMD,KAASC,IAAU,UAAU;AAAA,UAElC,UAAAD,IAAQE,KAAc,4BAA4BA;AAAA,QAAA;AAAA,MAAA;AAAA,IACrD,GAEJ;AAAA,EAEJ,CAAC;AACH;AAEAV,EAAM,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","sources":["../../../../../src/ui/primitives/Select/Select.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, memo, useId, useMemo, useCallback } from \"react\";\nimport type { SelectHTMLAttributes, ReactNode } from \"react\";\nimport {\n getTypographyClasses,\n getTypographySize,\n} from \"../../tokens/typography\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn, cva } from \"../../utils\";\n\n/**\n * Helper Text Component\n * Memoized component for helper/error text\n */\nconst HelperText = memo(function HelperText({\n error,\n success,\n helperText,\n errorId,\n helperId,\n}: {\n error: boolean;\n success: boolean;\n helperText?: string;\n errorId?: string;\n helperId?: string;\n}) {\n const helperClasses = useMemo(\n () =>\n cn(\n getSpacingClass(\"xs\", \"mt\"),\n getTypographyClasses(\"caption\"),\n error && \"text-fg-error\",\n success && \"text-fg-success\",\n !error && !success && \"text-fg-secondary\",\n ),\n [error, success],\n );\n\n const text = useMemo(\n () => helperText || (error ? \"Error\" : success ? \"Success\" : \"\"),\n [helperText, error, success],\n );\n\n return (\n <div\n id={errorId || helperId}\n className={helperClasses}\n role={error || success ? \"alert\" : undefined}\n >\n {text}\n </div>\n );\n});\n\nexport type SelectSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SelectOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SelectOptionGroup {\n label: string;\n options: SelectOption[];\n}\n\nexport interface SelectProps extends Omit<\n SelectHTMLAttributes<HTMLSelectElement>,\n \"children\" | \"size\"\n> {\n options: SelectOption[];\n optionGroups?: SelectOptionGroup[];\n placeholder?: string;\n label?: ReactNode;\n error?: boolean;\n success?: boolean;\n helperText?: string;\n size?: SelectSize;\n}\n\n/**\n * Select Component\n *\n * A styled select dropdown component for forms.\n * Follows Atomic Design principles as an Atom component.\n * Supports both flat options and option groups.\n *\n * @example\n * ```tsx\n * <Select\n * label=\"Choose option\"\n * options={[\n * { value: \"1\", label: \"Option 1\" },\n * { value: \"2\", label: \"Option 2\" }\n * ]}\n * placeholder=\"Select an option\"\n * />\n * ```\n */\nconst Select = memo(\n forwardRef<HTMLSelectElement, SelectProps>(function Select(\n {\n options = [],\n optionGroups,\n placeholder,\n label,\n error = false,\n success = false,\n helperText,\n size = \"md\",\n className = \"\",\n disabled = false,\n id,\n ...props\n },\n ref,\n ) {\n // Stable fallback id when the consumer doesn't provide one. useId\n // is SSR-safe and stable across renders, replacing the deprecated\n // Math.random().substr() pattern.\n const reactId = useId();\n const selectId = id || `select-${reactId}`;\n\n const errorId = useMemo(\n () => (error ? `${selectId}-error` : undefined),\n [error, selectId],\n );\n\n const helperId = useMemo(\n () => (helperText ? `${selectId}-helper` : undefined),\n [helperText, selectId],\n );\n\n // Memoize focus ring colors\n const primaryFocusRing = useMemo(() => \"focus:border-line-focus\", []);\n\n const errorFocusRing = useMemo(() => \"focus:border-error\", []);\n\n const successFocusRing = useMemo(() => \"focus:border-success\", []);\n\n // Memoize focus ring color function\n const getFocusRingColor = useCallback(\n (stateType?: \"error\" | \"success\"): string => {\n if (stateType === \"error\") {\n return errorFocusRing.replace(\"focus:border-\", \"focus:ring-\");\n }\n if (stateType === \"success\") {\n return successFocusRing.replace(\"focus:border-\", \"focus:ring-\");\n }\n return primaryFocusRing.replace(\"focus:border-\", \"focus:ring-\");\n },\n [errorFocusRing, successFocusRing, primaryFocusRing],\n );\n\n // Select variants using CVA — memoize so the function reference is\n // stable across renders. selectClasses below depends on this; without\n // memoization a fresh cva() each render would invalidate that memo\n // on every render (defeating its purpose).\n const selectVariants = useMemo(\n () =>\n cva(\n // Base classes\n cn(\n \"block\",\n \"w-full\",\n getRadiusClass(\"md\"),\n \"border\",\n \"bg-surface-base\",\n \"transition-colors\",\n \"focus:outline-none\",\n \"focus:ring-2\",\n \"focus:ring-offset-2\",\n \"disabled:opacity-50\",\n \"disabled:cursor-not-allowed\",\n ),\n {\n variants: {\n size: {\n sm: cn(\n \"h-8\",\n getTypographySize(\"bodySmall\"),\n getSpacingClass(\"md\", \"px\"),\n ),\n md: cn(\n \"h-10\",\n getTypographySize(\"body\"),\n getSpacingClass(\"base\", \"px\"),\n ),\n lg: cn(\n \"h-12\",\n getTypographySize(\"bodyLarge\"),\n getSpacingClass(\"lg\", \"px\"),\n ),\n },\n state: {\n default: cn(\"border-line-default\", getFocusRingColor()),\n error: cn(\"border-error\", getFocusRingColor(\"error\")),\n success: cn(\"border-success\", getFocusRingColor(\"success\")),\n },\n },\n defaultVariants: {\n size: \"md\",\n state: \"default\",\n },\n },\n ),\n [getFocusRingColor],\n );\n\n // Memoize state\n const selectState = useMemo(\n () => (error ? \"error\" : success ? \"success\" : \"default\"),\n [error, success],\n );\n\n // Memoize classes\n const selectClasses = useMemo(\n () => cn(selectVariants({ size, state: selectState }), className),\n [selectVariants, size, selectState, className],\n );\n\n const labelClasses = useMemo(\n () =>\n cn(\n \"block\",\n getTypographyClasses(\"label\"),\n getSpacingClass(\"xs\", \"mb\"),\n disabled && \"opacity-50\",\n ),\n [disabled],\n );\n\n return (\n <div className=\"w-full\">\n {label && (\n <label htmlFor={selectId} className={labelClasses}>\n {label}\n </label>\n )}\n <select\n id={selectId}\n ref={ref}\n className={selectClasses}\n disabled={disabled}\n aria-invalid={error}\n aria-required={props.required}\n aria-describedby={errorId || helperId}\n {...props}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {optionGroups && optionGroups.length > 0\n ? optionGroups.map((group, groupIndex) => (\n <optgroup key={groupIndex} label={group.label}>\n {(group.options || []).map((option) => (\n <option\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </optgroup>\n ))\n : (options || []).map((option) => (\n <option\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </select>\n {(error || success || helperText) && (\n <HelperText\n error={error}\n success={success}\n helperText={helperText}\n errorId={errorId}\n helperId={helperId}\n />\n )}\n </div>\n );\n }),\n);\n\nSelect.displayName = \"Select\";\n\nexport default Select;\n"],"names":["HelperText","memo","error","success","helperText","errorId","helperId","helperClasses","useMemo","cn","getSpacingClass","getTypographyClasses","text","jsx","Select","forwardRef","_a","ref","_b","options","optionGroups","placeholder","label","size","className","disabled","id","props","__objRest","reactId","useId","selectId","primaryFocusRing","errorFocusRing","successFocusRing","getFocusRingColor","useCallback","stateType","selectVariants","cva","getRadiusClass","getTypographySize","selectState","selectClasses","labelClasses","jsxs","__spreadProps","__spreadValues","group","groupIndex","option"],"mappings":"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"}
1
+ {"version":3,"file":"Select.js","sources":["../../../../../src/ui/primitives/Select/Select.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, memo, useId, useMemo, useCallback } from \"react\";\nimport type { SelectHTMLAttributes, ReactNode } from \"react\";\nimport {\n getTypographyClasses,\n getTypographySize,\n} from \"../../tokens/typography\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn, cva } from \"../../utils\";\n\n/**\n * Helper Text Component\n * Memoized component for helper/error text\n */\nconst HelperText = memo(function HelperText({\n error,\n success,\n helperText,\n errorId,\n helperId,\n}: {\n error: boolean;\n success: boolean;\n helperText?: string;\n errorId?: string;\n helperId?: string;\n}) {\n const helperClasses = useMemo(\n () =>\n cn(\n getSpacingClass(\"xs\", \"mt\"),\n getTypographyClasses(\"caption\"),\n error && \"text-fg-error\",\n success && \"text-fg-success\",\n !error && !success && \"text-fg-secondary\",\n ),\n [error, success],\n );\n\n const text = useMemo(\n () => helperText || (error ? \"Error\" : success ? \"Success\" : \"\"),\n [helperText, error, success],\n );\n\n return (\n <div\n id={errorId || helperId}\n className={helperClasses}\n role={error || success ? \"alert\" : undefined}\n >\n {text}\n </div>\n );\n});\n\nexport type SelectSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SelectOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface SelectOptionGroup {\n label: string;\n options: SelectOption[];\n}\n\nexport interface SelectProps extends Omit<\n SelectHTMLAttributes<HTMLSelectElement>,\n \"children\" | \"size\"\n> {\n options: SelectOption[];\n optionGroups?: SelectOptionGroup[];\n placeholder?: string;\n label?: ReactNode;\n error?: boolean;\n success?: boolean;\n helperText?: string;\n size?: SelectSize;\n}\n\n/**\n * Select Component\n *\n * A styled select dropdown component for forms.\n * Supports both flat options and option groups.\n *\n * @example\n * ```tsx\n * <Select\n * label=\"Choose option\"\n * options={[\n * { value: \"1\", label: \"Option 1\" },\n * { value: \"2\", label: \"Option 2\" }\n * ]}\n * placeholder=\"Select an option\"\n * />\n * ```\n */\nconst Select = memo(\n forwardRef<HTMLSelectElement, SelectProps>(function Select(\n {\n options = [],\n optionGroups,\n placeholder,\n label,\n error = false,\n success = false,\n helperText,\n size = \"md\",\n className = \"\",\n disabled = false,\n id,\n ...props\n },\n ref,\n ) {\n // Stable fallback id when the consumer doesn't provide one. useId\n // is SSR-safe and stable across renders, replacing the deprecated\n // Math.random().substr() pattern.\n const reactId = useId();\n const selectId = id || `select-${reactId}`;\n\n const errorId = useMemo(\n () => (error ? `${selectId}-error` : undefined),\n [error, selectId],\n );\n\n const helperId = useMemo(\n () => (helperText ? `${selectId}-helper` : undefined),\n [helperText, selectId],\n );\n\n // Memoize focus ring colors\n const primaryFocusRing = useMemo(() => \"focus:border-line-focus\", []);\n\n const errorFocusRing = useMemo(() => \"focus:border-error\", []);\n\n const successFocusRing = useMemo(() => \"focus:border-success\", []);\n\n // Memoize focus ring color function\n const getFocusRingColor = useCallback(\n (stateType?: \"error\" | \"success\"): string => {\n if (stateType === \"error\") {\n return errorFocusRing.replace(\"focus:border-\", \"focus:ring-\");\n }\n if (stateType === \"success\") {\n return successFocusRing.replace(\"focus:border-\", \"focus:ring-\");\n }\n return primaryFocusRing.replace(\"focus:border-\", \"focus:ring-\");\n },\n [errorFocusRing, successFocusRing, primaryFocusRing],\n );\n\n // Select variants using CVA — memoize so the function reference is\n // stable across renders. selectClasses below depends on this; without\n // memoization a fresh cva() each render would invalidate that memo\n // on every render (defeating its purpose).\n const selectVariants = useMemo(\n () =>\n cva(\n // Base classes\n cn(\n \"block\",\n \"w-full\",\n getRadiusClass(\"md\"),\n \"border\",\n \"bg-surface-base\",\n \"transition-colors\",\n \"focus:outline-none\",\n \"focus:ring-2\",\n \"focus:ring-offset-2\",\n \"disabled:opacity-50\",\n \"disabled:cursor-not-allowed\",\n ),\n {\n variants: {\n size: {\n sm: cn(\n \"h-8\",\n getTypographySize(\"bodySmall\"),\n getSpacingClass(\"md\", \"px\"),\n ),\n md: cn(\n \"h-10\",\n getTypographySize(\"body\"),\n getSpacingClass(\"base\", \"px\"),\n ),\n lg: cn(\n \"h-12\",\n getTypographySize(\"bodyLarge\"),\n getSpacingClass(\"lg\", \"px\"),\n ),\n },\n state: {\n default: cn(\"border-line-default\", getFocusRingColor()),\n error: cn(\"border-error\", getFocusRingColor(\"error\")),\n success: cn(\"border-success\", getFocusRingColor(\"success\")),\n },\n },\n defaultVariants: {\n size: \"md\",\n state: \"default\",\n },\n },\n ),\n [getFocusRingColor],\n );\n\n // Memoize state\n const selectState = useMemo(\n () => (error ? \"error\" : success ? \"success\" : \"default\"),\n [error, success],\n );\n\n // Memoize classes\n const selectClasses = useMemo(\n () => cn(selectVariants({ size, state: selectState }), className),\n [selectVariants, size, selectState, className],\n );\n\n const labelClasses = useMemo(\n () =>\n cn(\n \"block\",\n getTypographyClasses(\"label\"),\n getSpacingClass(\"xs\", \"mb\"),\n disabled && \"opacity-50\",\n ),\n [disabled],\n );\n\n return (\n <div className=\"w-full\">\n {label && (\n <label htmlFor={selectId} className={labelClasses}>\n {label}\n </label>\n )}\n <select\n id={selectId}\n ref={ref}\n className={selectClasses}\n disabled={disabled}\n aria-invalid={error}\n aria-required={props.required}\n aria-describedby={errorId || helperId}\n {...props}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {optionGroups && optionGroups.length > 0\n ? optionGroups.map((group, groupIndex) => (\n <optgroup key={groupIndex} label={group.label}>\n {(group.options || []).map((option) => (\n <option\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </optgroup>\n ))\n : (options || []).map((option) => (\n <option\n key={option.value}\n value={option.value}\n disabled={option.disabled}\n >\n {option.label}\n </option>\n ))}\n </select>\n {(error || success || helperText) && (\n <HelperText\n error={error}\n success={success}\n helperText={helperText}\n errorId={errorId}\n helperId={helperId}\n />\n )}\n </div>\n );\n }),\n);\n\nSelect.displayName = \"Select\";\n\nexport default Select;\n"],"names":["HelperText","memo","error","success","helperText","errorId","helperId","helperClasses","useMemo","cn","getSpacingClass","getTypographyClasses","text","jsx","Select","forwardRef","_a","ref","_b","options","optionGroups","placeholder","label","size","className","disabled","id","props","__objRest","reactId","useId","selectId","primaryFocusRing","errorFocusRing","successFocusRing","getFocusRingColor","useCallback","stateType","selectVariants","cva","getRadiusClass","getTypographySize","selectState","selectClasses","labelClasses","jsxs","__spreadProps","__spreadValues","group","groupIndex","option"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Separator.js","sources":["../../../../../src/ui/primitives/Separator/Separator.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport { cn } from \"../../utils\";\n\nexport type SeparatorOrientation = \"horizontal\" | \"vertical\";\nexport type SeparatorVariant = \"solid\" | \"dashed\" | \"dotted\";\n\nexport interface SeparatorProps extends HTMLAttributes<HTMLHRElement> {\n orientation?: SeparatorOrientation;\n variant?: SeparatorVariant;\n}\n\n/**\n * Separator Component\n *\n * A visual separator component for dividing content.\n * Follows Atomic Design principles as an Atom component.\n * Optimized with React.memo to prevent unnecessary re-renders.\n *\n * @example\n * ```tsx\n * <Separator />\n *\n * <Separator orientation=\"vertical\" variant=\"dashed\" />\n * ```\n */\nconst separatorOrientationClasses = {\n horizontal: \"w-full border-t\",\n vertical: \"h-full border-l self-stretch\",\n} as const;\n\nconst separatorVariantClasses = {\n solid: \"border-solid\",\n dashed: \"border-dashed\",\n dotted: \"border-dotted\",\n} as const;\n\nconst Separator = memo(function Separator({\n orientation = \"horizontal\",\n variant = \"solid\",\n className = \"\",\n ...props\n}: SeparatorProps) {\n const classes = cn(\n \"border-0\",\n \"border-line-default\",\n separatorOrientationClasses[orientation],\n separatorVariantClasses[variant],\n className,\n );\n\n if (orientation === \"vertical\") {\n return (\n <div\n className={classes}\n role=\"separator\"\n aria-orientation=\"vertical\"\n {...(props as HTMLAttributes<HTMLDivElement>)}\n />\n );\n }\n\n return (\n <hr\n className={classes}\n role=\"separator\"\n aria-orientation=\"horizontal\"\n {...props}\n />\n );\n});\n\nSeparator.displayName = \"Separator\";\n\nexport default Separator;\n"],"names":["separatorOrientationClasses","separatorVariantClasses","Separator","memo","_a","_b","orientation","variant","className","props","__objRest","classes","cn","jsx","__spreadValues"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAMA,IAA8B;AAAA,EAClC,YAAY;AAAA,EACZ,UAAU;AACZ,GAEMC,IAA0B;AAAA,EAC9B,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AACV,GAEMC,IAAYC,EAAK,SAAmBC,GAKvB;AALuB,MAAAC,IAAAD,GACxC;AAAA,iBAAAE,IAAc;AAAA,IACd,SAAAC,IAAU;AAAA,IACV,WAAAC,IAAY;AAAA,MAH4BH,GAIrCI,IAAAC,EAJqCL,GAIrC;AAAA,IAHH;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAMM,IAAUC;AAAA,IACd;AAAA,IACA;AAAA,IACAZ,EAA4BM,CAAW;AAAA,IACvCL,EAAwBM,CAAO;AAAA,IAC/BC;AAAA,EAAA;AAGF,SAAIF,MAAgB,aAEhB,gBAAAO;AAAA,IAAC;AAAA,IAAAC,EAAA;AAAA,MACC,WAAWH;AAAA,MACX,MAAK;AAAA,MACL,oBAAiB;AAAA,OACZF;AAAA,EAAA,IAMT,gBAAAI;AAAA,IAAC;AAAA,IAAAC,EAAA;AAAA,MACC,WAAWH;AAAA,MACX,MAAK;AAAA,MACL,oBAAiB;AAAA,OACbF;AAAA,EAAA;AAGV,CAAC;AAEDP,EAAU,cAAc;"}
1
+ {"version":3,"file":"Separator.js","sources":["../../../../../src/ui/primitives/Separator/Separator.tsx"],"sourcesContent":["import { memo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport { cn } from \"../../utils\";\n\nexport type SeparatorOrientation = \"horizontal\" | \"vertical\";\nexport type SeparatorVariant = \"solid\" | \"dashed\" | \"dotted\";\n\nexport interface SeparatorProps extends HTMLAttributes<HTMLHRElement> {\n orientation?: SeparatorOrientation;\n variant?: SeparatorVariant;\n}\n\n/**\n * Separator Component\n *\n * A visual separator component for dividing content.\n * Optimized with React.memo to prevent unnecessary re-renders.\n *\n * @example\n * ```tsx\n * <Separator />\n *\n * <Separator orientation=\"vertical\" variant=\"dashed\" />\n * ```\n */\nconst separatorOrientationClasses = {\n horizontal: \"w-full border-t\",\n vertical: \"h-full border-l self-stretch\",\n} as const;\n\nconst separatorVariantClasses = {\n solid: \"border-solid\",\n dashed: \"border-dashed\",\n dotted: \"border-dotted\",\n} as const;\n\nconst Separator = memo(function Separator({\n orientation = \"horizontal\",\n variant = \"solid\",\n className = \"\",\n ...props\n}: SeparatorProps) {\n const classes = cn(\n \"border-0\",\n \"border-line-default\",\n separatorOrientationClasses[orientation],\n separatorVariantClasses[variant],\n className,\n );\n\n if (orientation === \"vertical\") {\n return (\n <div\n className={classes}\n role=\"separator\"\n aria-orientation=\"vertical\"\n {...(props as HTMLAttributes<HTMLDivElement>)}\n />\n );\n }\n\n return (\n <hr\n className={classes}\n role=\"separator\"\n aria-orientation=\"horizontal\"\n {...props}\n />\n );\n});\n\nSeparator.displayName = \"Separator\";\n\nexport default Separator;\n"],"names":["separatorOrientationClasses","separatorVariantClasses","Separator","memo","_a","_b","orientation","variant","className","props","__objRest","classes","cn","jsx","__spreadValues"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAMA,IAA8B;AAAA,EAClC,YAAY;AAAA,EACZ,UAAU;AACZ,GAEMC,IAA0B;AAAA,EAC9B,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AACV,GAEMC,IAAYC,EAAK,SAAmBC,GAKvB;AALuB,MAAAC,IAAAD,GACxC;AAAA,iBAAAE,IAAc;AAAA,IACd,SAAAC,IAAU;AAAA,IACV,WAAAC,IAAY;AAAA,MAH4BH,GAIrCI,IAAAC,EAJqCL,GAIrC;AAAA,IAHH;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAMM,IAAUC;AAAA,IACd;AAAA,IACA;AAAA,IACAZ,EAA4BM,CAAW;AAAA,IACvCL,EAAwBM,CAAO;AAAA,IAC/BC;AAAA,EAAA;AAGF,SAAIF,MAAgB,aAEhB,gBAAAO;AAAA,IAAC;AAAA,IAAAC,EAAA;AAAA,MACC,WAAWH;AAAA,MACX,MAAK;AAAA,MACL,oBAAiB;AAAA,OACZF;AAAA,EAAA,IAMT,gBAAAI;AAAA,IAAC;AAAA,IAAAC,EAAA;AAAA,MACC,WAAWH;AAAA,MACX,MAAK;AAAA,MACL,oBAAiB;AAAA,OACbF;AAAA,EAAA;AAGV,CAAC;AAEDP,EAAU,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Skeleton.js","sources":["../../../../../src/ui/primitives/Skeleton/Skeleton.tsx"],"sourcesContent":["import type { HTMLAttributes } from \"react\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn } from \"../../utils\";\n\nexport interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: \"text\" | \"card\" | \"list\" | \"circle\";\n width?: string;\n height?: string;\n lines?: number;\n}\n\n/**\n * Skeleton Component\n *\n * A skeleton loader component for displaying loading states.\n * Follows Atomic Design principles as an Atom component.\n *\n * @example\n * ```tsx\n * <Skeleton variant=\"card\" />\n * <Skeleton variant=\"text\" lines={3} />\n * ```\n */\nexport default function Skeleton({\n variant = \"text\",\n width,\n height,\n lines = 1,\n className = \"\",\n \"aria-label\": ariaLabel,\n ...props\n}: SkeletonProps) {\n const baseClasses = [\n \"motion-safe:animate-pulse\",\n \"bg-surface-muted\",\n getRadiusClass(\"sm\"),\n ];\n\n const variantClasses: Record<\n NonNullable<SkeletonProps[\"variant\"]>,\n string\n > = {\n text: \"h-4\",\n card: \"h-32\",\n list: \"h-12\",\n circle: getRadiusClass(\"full\"),\n };\n\n const classes = cn(...baseClasses, variantClasses[variant], className);\n\n const style: React.CSSProperties = {};\n if (width) style.width = width;\n if (height) style.height = height;\n\n const defaultAriaLabel = ariaLabel || `Loading ${variant} content`;\n\n if (variant === \"text\" && lines > 1) {\n return (\n <div\n className={getSpacingClass(\"sm\", \"space-y\")}\n role=\"status\"\n aria-busy=\"true\"\n aria-label={defaultAriaLabel}\n {...props}\n >\n {Array.from({ length: lines }).map((_, index) => (\n <div\n key={index}\n className={classes}\n style={index === lines - 1 ? { width: \"75%\" } : style}\n aria-hidden=\"true\"\n />\n ))}\n </div>\n );\n }\n\n return (\n <div\n className={classes}\n style={style}\n role=\"status\"\n aria-busy=\"true\"\n aria-label={defaultAriaLabel}\n {...props}\n />\n );\n}\n"],"names":["Skeleton","_a","_b","variant","width","height","lines","className","ariaLabel","props","__objRest","baseClasses","getRadiusClass","variantClasses","classes","cn","style","defaultAriaLabel","jsx","__spreadProps","__spreadValues","getSpacingClass","_","index"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAwBA,EAASC,GAQf;AARe,MAAAC,IAAAD,GAC/B;AAAA,aAAAE,IAAU;AAAA,IACV,OAAAC;AAAA,IACA,QAAAC;AAAA,IACA,OAAAC,IAAQ;AAAA,IACR,WAAAC,IAAY;AAAA,IACZ,cAAcC;AAAA,MANiBN,GAO5BO,IAAAC,EAP4BR,GAO5B;AAAA,IANH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAMS,IAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACAC,EAAe,IAAI;AAAA,EAAA,GAGfC,IAGF;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQD,EAAe,MAAM;AAAA,EAAA,GAGzBE,IAAUC,EAAG,GAAGJ,GAAaE,EAAeV,CAAO,GAAGI,CAAS,GAE/DS,IAA6B,CAAA;AACnC,EAAIZ,QAAa,QAAQA,IACrBC,QAAc,SAASA;AAE3B,QAAMY,IAAmBT,KAAa,WAAWL,CAAO;AAExD,SAAIA,MAAY,UAAUG,IAAQ,IAE9B,gBAAAY;AAAA,IAAC;AAAA,IAAAC,EAAAC,EAAA;AAAA,MACC,WAAWC,EAAgB,MAAM,SAAS;AAAA,MAC1C,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAYJ;AAAA,OACRR,IALL;AAAA,MAOE,UAAA,MAAM,KAAK,EAAE,QAAQH,GAAO,EAAE,IAAI,CAACgB,GAAGC,MACrC,gBAAAL;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAWJ;AAAA,UACX,OAAOS,MAAUjB,IAAQ,IAAI,EAAE,OAAO,UAAUU;AAAA,UAChD,eAAY;AAAA,QAAA;AAAA,QAHPO;AAAA,MAAA,CAKR;AAAA,IAAA;AAAA,EAAA,IAML,gBAAAL;AAAA,IAAC;AAAA,IAAAE,EAAA;AAAA,MACC,WAAWN;AAAA,MACX,OAAAE;AAAA,MACA,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAYC;AAAA,OACRR;AAAA,EAAA;AAGV;"}
1
+ {"version":3,"file":"Skeleton.js","sources":["../../../../../src/ui/primitives/Skeleton/Skeleton.tsx"],"sourcesContent":["import type { HTMLAttributes } from \"react\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { cn } from \"../../utils\";\n\nexport interface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: \"text\" | \"card\" | \"list\" | \"circle\";\n width?: string;\n height?: string;\n lines?: number;\n}\n\n/**\n * Skeleton Component\n *\n * A skeleton loader component for displaying loading states.\n *\n * @example\n * ```tsx\n * <Skeleton variant=\"card\" />\n * <Skeleton variant=\"text\" lines={3} />\n * ```\n */\nexport default function Skeleton({\n variant = \"text\",\n width,\n height,\n lines = 1,\n className = \"\",\n \"aria-label\": ariaLabel,\n ...props\n}: SkeletonProps) {\n const baseClasses = [\n \"motion-safe:animate-pulse\",\n \"bg-surface-muted\",\n getRadiusClass(\"sm\"),\n ];\n\n const variantClasses: Record<\n NonNullable<SkeletonProps[\"variant\"]>,\n string\n > = {\n text: \"h-4\",\n card: \"h-32\",\n list: \"h-12\",\n circle: getRadiusClass(\"full\"),\n };\n\n const classes = cn(...baseClasses, variantClasses[variant], className);\n\n const style: React.CSSProperties = {};\n if (width) style.width = width;\n if (height) style.height = height;\n\n const defaultAriaLabel = ariaLabel || `Loading ${variant} content`;\n\n if (variant === \"text\" && lines > 1) {\n return (\n <div\n className={getSpacingClass(\"sm\", \"space-y\")}\n role=\"status\"\n aria-busy=\"true\"\n aria-label={defaultAriaLabel}\n {...props}\n >\n {Array.from({ length: lines }).map((_, index) => (\n <div\n key={index}\n className={classes}\n style={index === lines - 1 ? { width: \"75%\" } : style}\n aria-hidden=\"true\"\n />\n ))}\n </div>\n );\n }\n\n return (\n <div\n className={classes}\n style={style}\n role=\"status\"\n aria-busy=\"true\"\n aria-label={defaultAriaLabel}\n {...props}\n />\n );\n}\n"],"names":["Skeleton","_a","_b","variant","width","height","lines","className","ariaLabel","props","__objRest","baseClasses","getRadiusClass","variantClasses","classes","cn","style","defaultAriaLabel","jsx","__spreadProps","__spreadValues","getSpacingClass","_","index"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAwBA,EAASC,GAQf;AARe,MAAAC,IAAAD,GAC/B;AAAA,aAAAE,IAAU;AAAA,IACV,OAAAC;AAAA,IACA,QAAAC;AAAA,IACA,OAAAC,IAAQ;AAAA,IACR,WAAAC,IAAY;AAAA,IACZ,cAAcC;AAAA,MANiBN,GAO5BO,IAAAC,EAP4BR,GAO5B;AAAA,IANH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,QAAMS,IAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACAC,EAAe,IAAI;AAAA,EAAA,GAGfC,IAGF;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,QAAQD,EAAe,MAAM;AAAA,EAAA,GAGzBE,IAAUC,EAAG,GAAGJ,GAAaE,EAAeV,CAAO,GAAGI,CAAS,GAE/DS,IAA6B,CAAA;AACnC,EAAIZ,QAAa,QAAQA,IACrBC,QAAc,SAASA;AAE3B,QAAMY,IAAmBT,KAAa,WAAWL,CAAO;AAExD,SAAIA,MAAY,UAAUG,IAAQ,IAE9B,gBAAAY;AAAA,IAAC;AAAA,IAAAC,EAAAC,EAAA;AAAA,MACC,WAAWC,EAAgB,MAAM,SAAS;AAAA,MAC1C,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAYJ;AAAA,OACRR,IALL;AAAA,MAOE,UAAA,MAAM,KAAK,EAAE,QAAQH,GAAO,EAAE,IAAI,CAACgB,GAAGC,MACrC,gBAAAL;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,WAAWJ;AAAA,UACX,OAAOS,MAAUjB,IAAQ,IAAI,EAAE,OAAO,UAAUU;AAAA,UAChD,eAAY;AAAA,QAAA;AAAA,QAHPO;AAAA,MAAA,CAKR;AAAA,IAAA;AAAA,EAAA,IAML,gBAAAL;AAAA,IAAC;AAAA,IAAAE,EAAA;AAAA,MACC,WAAWN;AAAA,MACX,OAAAE;AAAA,MACA,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAYC;AAAA,OACRR;AAAA,EAAA;AAGV;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.js","sources":["../../../../../src/ui/primitives/Slider/Slider.tsx"],"sourcesContent":["\"use client\";\n\nimport { useRef, useState, useId, forwardRef } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport { getAnimationClass } from \"../../tokens/animations\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getShadowClass } from \"../../tokens/shadows\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport {\n getTypographySize,\n getTypographyWeight,\n} from \"../../tokens/typography\";\nimport { cn, cva } from \"../../utils\";\n\nexport type SliderVariant = \"single\" | \"range\";\nexport type SliderSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SliderProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onChange\" | \"defaultValue\"\n> {\n value?: number | [number, number];\n defaultValue?: number | [number, number];\n min?: number;\n max?: number;\n step?: number;\n variant?: SliderVariant;\n size?: SliderSize;\n disabled?: boolean;\n showValue?: boolean;\n marks?: number[];\n onChange?: (value: number | [number, number]) => void;\n onValueChange?: (value: number | [number, number]) => void;\n /**\n * Required label for the slider. Becomes the accessible name via\n * aria-labelledby — single variant references the rendered <label>\n * element directly; range variant references the same label plus a\n * sr-only qualifier (\"minimum\" / \"maximum\") so AT users can tell\n * which handle has focus. Make this a real domain term (\"Volume\",\n * \"Price range\"), not the element type (\"slider\").\n */\n label: string;\n}\n\n/**\n * Slider Component\n *\n * A range input component for selecting numeric values.\n * Supports single and dual thumb (range) modes.\n * Follows Atomic Design principles as an Atom component.\n *\n * @example\n * ```tsx\n * <Slider\n * value={50}\n * min={0}\n * max={100}\n * onChange={(value) => console.log(value)}\n * />\n *\n * <Slider\n * variant=\"range\"\n * value={[20, 80]}\n * min={0}\n * max={100}\n * onChange={(value) => console.log(value)}\n * />\n * ```\n */\nconst Slider = forwardRef<HTMLDivElement, SliderProps>(function Slider(\n {\n value: controlledValue,\n defaultValue,\n min = 0,\n max = 100,\n step = 1,\n variant = \"single\",\n size = \"md\",\n disabled = false,\n showValue = false,\n marks = [],\n onChange,\n onValueChange,\n label,\n className = \"\",\n ...props\n },\n ref,\n) {\n const sliderRef = useRef<HTMLDivElement>(null);\n // Stable IDs for the visible <label> and (for range) the sr-only\n // qualifier spans that distinguish min vs max handles. Range\n // accessible name = label + qualifier via aria-labelledby with two\n // ids (\"Price range minimum\" / \"Price range maximum\"), so the\n // visible label remains the single source of truth — changing\n // `label` propagates to both handles automatically.\n const labelId = useId();\n const minQualifierId = useId();\n const maxQualifierId = useId();\n const [internalValue, setInternalValue] = useState<number | [number, number]>(\n defaultValue || (variant === \"range\" ? [min, max] : min),\n );\n const [isDragging, setIsDragging] = useState(false);\n const [activeThumb, setActiveThumb] = useState<\"min\" | \"max\" | null>(null);\n\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n const getPercentage = (val: number) => ((val - min) / (max - min)) * 100;\n\n const getValueFromPosition = (clientX: number): number => {\n if (!sliderRef.current) return min;\n const rect = sliderRef.current.getBoundingClientRect();\n const percentage = Math.max(\n 0,\n Math.min(1, (clientX - rect.left) / rect.width),\n );\n const rawValue = min + percentage * (max - min);\n return Math.round(rawValue / step) * step;\n };\n\n const handleMouseDown = (\n e: React.MouseEvent,\n thumb: \"min\" | \"max\" = \"min\",\n ) => {\n if (disabled) return;\n e.preventDefault();\n setIsDragging(true);\n setActiveThumb(thumb);\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n if (!sliderRef.current) return;\n const newValue = getValueFromPosition(moveEvent.clientX);\n updateValue(newValue, thumb);\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n setActiveThumb(null);\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseup\", handleMouseUp);\n };\n\n const updateValue = (newValue: number, thumb: \"min\" | \"max\" = \"min\") => {\n const clampedValue = Math.max(min, Math.min(max, newValue));\n\n if (variant === \"range\") {\n const [minVal, maxVal] = Array.isArray(currentValue)\n ? currentValue\n : [min, max];\n let updatedValue: [number, number];\n\n if (thumb === \"min\") {\n updatedValue = [Math.min(clampedValue, maxVal), maxVal];\n } else {\n updatedValue = [minVal, Math.max(clampedValue, minVal)];\n }\n\n if (!isControlled) {\n setInternalValue(updatedValue);\n }\n onChange?.(updatedValue);\n onValueChange?.(updatedValue);\n } else {\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n onValueChange?.(clampedValue);\n }\n };\n\n const handleTrackClick = (e: React.MouseEvent) => {\n if (disabled || isDragging) return;\n const newValue = getValueFromPosition(e.clientX);\n updateValue(newValue);\n };\n\n // Get focus ring color using design system helper\n const getFocusRingColor = (): string => {\n return \"focus:ring-line-brand\" + \" ring-offset-2\";\n };\n\n // Slider variants using CVA\n const sliderTrackVariants = cva(cn(\"relative\", \"cursor-pointer\"), {\n variants: {\n size: {\n sm: \"h-1\",\n md: \"h-2\",\n lg: \"h-3\",\n },\n disabled: {\n true: \"opacity-50 cursor-not-allowed\",\n false: \"\",\n },\n },\n defaultVariants: {\n size: \"md\",\n disabled: false,\n },\n });\n\n const sliderThumbVariants = cva(\n cn(\n \"absolute\",\n \"bg-surface-brand\",\n getRadiusClass(\"full\"),\n \"border-2\",\n \"border-white\",\n getShadowClass(\"md\"),\n \"cursor-grab\",\n \"active:cursor-grabbing\",\n getAnimationClass(\"base\"),\n \"-translate-x-1/2\",\n \"-translate-y-1/2\",\n \"top-1/2\",\n ),\n {\n variants: {\n size: {\n sm: \"w-3 h-3\",\n md: \"w-4 h-4\",\n lg: \"w-5 h-5\",\n },\n active: {\n true: getFocusRingColor(),\n false: \"\",\n },\n },\n defaultVariants: {\n size: \"md\",\n active: false,\n },\n },\n );\n\n // Configuration for styling variants\n // const _config = {\n // track: sliderTrackVariants({ size, disabled }),\n // thumb: sliderThumbVariants({ size }),\n // };\n const singleValue =\n typeof currentValue === \"number\" ? currentValue : currentValue[0];\n const minValue = Array.isArray(currentValue) ? currentValue[0] : min;\n const maxValue = Array.isArray(currentValue) ? currentValue[1] : singleValue;\n\n const minPercentage = getPercentage(minValue);\n const maxPercentage = getPercentage(maxValue);\n\n return (\n <div ref={ref} className={cn(\"w-full\", className)} {...props}>\n <label\n id={labelId}\n className={cn(\n \"block\",\n getTypographySize(\"bodySmall\"),\n getTypographyWeight(\"label\"),\n \"text-fg-primary\",\n getSpacingClass(\"sm\", \"mb\"),\n )}\n >\n {label}\n {showValue && (\n <span\n className={cn(getSpacingClass(\"sm\", \"ml\"), \"text-fg-secondary\")}\n >\n {variant === \"range\" ? `${minValue} - ${maxValue}` : singleValue}\n </span>\n )}\n </label>\n {variant === \"range\" && (\n <>\n <span id={minQualifierId} className=\"sr-only\">\n minimum\n </span>\n <span id={maxQualifierId} className=\"sr-only\">\n maximum\n </span>\n </>\n )}\n <div\n ref={sliderRef}\n className={cn(\n sliderTrackVariants({ size, disabled }),\n \"bg-surface-muted\",\n getRadiusClass(\"full\"),\n )}\n onClick={handleTrackClick}\n role={variant === \"range\" ? undefined : \"slider\"}\n aria-valuemin={variant === \"range\" ? undefined : min}\n aria-valuemax={variant === \"range\" ? undefined : max}\n aria-valuenow={variant === \"range\" ? undefined : singleValue}\n aria-disabled={variant === \"range\" ? undefined : disabled}\n aria-labelledby={variant === \"range\" ? undefined : labelId}\n >\n {/* Active track */}\n <div\n className={cn(\n \"absolute\",\n sliderTrackVariants({ size }),\n \"bg-surface-brand\",\n getRadiusClass(\"full\"),\n getAnimationClass(\"base\"),\n )}\n style={{\n left: `${minPercentage}%`,\n width: `${maxPercentage - minPercentage}%`,\n }}\n />\n\n {/* Marks */}\n {marks.map((mark) => {\n const markPercentage = getPercentage(mark);\n return (\n <div\n key={mark}\n className={cn(\n \"absolute\",\n \"w-1\",\n \"h-1\",\n \"bg-line-strong\",\n getRadiusClass(\"full\"),\n \"-translate-x-1/2\",\n )}\n style={{\n left: `${markPercentage}%`,\n top: \"50%\",\n transform: \"translate(-50%, -50%)\",\n }}\n />\n );\n })}\n\n {/* Thumbs */}\n {variant === \"range\" ? (\n <>\n <div\n className={cn(\n sliderThumbVariants({ size, active: activeThumb === \"min\" }),\n )}\n style={{ left: `${minPercentage}%` }}\n onMouseDown={(e) => handleMouseDown(e, \"min\")}\n role=\"slider\"\n aria-valuemin={min}\n aria-valuemax={maxValue}\n aria-valuenow={minValue}\n aria-labelledby={`${labelId} ${minQualifierId}`}\n />\n <div\n className={cn(\n sliderThumbVariants({ size, active: activeThumb === \"max\" }),\n )}\n style={{ left: `${maxPercentage}%` }}\n onMouseDown={(e) => handleMouseDown(e, \"max\")}\n role=\"slider\"\n aria-valuemin={minValue}\n aria-valuemax={max}\n aria-valuenow={maxValue}\n aria-labelledby={`${labelId} ${maxQualifierId}`}\n />\n </>\n ) : (\n <div\n className={cn(sliderThumbVariants({ size, active: isDragging }))}\n style={{ left: `${maxPercentage}%` }}\n onMouseDown={(e) => handleMouseDown(e)}\n />\n )}\n\n {showValue && !label && (\n <div className=\"absolute -top-6 left-0 right-0 flex justify-center\">\n <span\n className={cn(\n getTypographySize(\"caption\"),\n \"text-fg-secondary\",\n \"bg-surface-overlay\",\n getSpacingClass(\"sm\", \"px\"),\n getSpacingClass(\"xs\", \"py\"),\n getRadiusClass(\"md\"),\n \"shadow\",\n )}\n >\n {variant === \"range\" ? `${minValue} - ${maxValue}` : singleValue}\n </span>\n </div>\n )}\n </div>\n </div>\n );\n});\n\nSlider.displayName = \"Slider\";\n\nexport default Slider;\n"],"names":["Slider","forwardRef","_a","ref","_b","controlledValue","defaultValue","min","max","step","variant","size","disabled","showValue","marks","onChange","onValueChange","label","className","props","__objRest","sliderRef","useRef","labelId","useId","minQualifierId","maxQualifierId","internalValue","setInternalValue","useState","isDragging","setIsDragging","activeThumb","setActiveThumb","isControlled","currentValue","getPercentage","val","getValueFromPosition","clientX","rect","percentage","rawValue","handleMouseDown","e","thumb","handleMouseMove","moveEvent","newValue","updateValue","handleMouseUp","clampedValue","minVal","maxVal","updatedValue","handleTrackClick","getFocusRingColor","sliderTrackVariants","cva","cn","sliderThumbVariants","getRadiusClass","getShadowClass","getAnimationClass","singleValue","minValue","maxValue","minPercentage","maxPercentage","jsxs","getTypographySize","getTypographyWeight","getSpacingClass","jsx","Fragment","mark","markPercentage"],"mappings":"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"}
1
+ {"version":3,"file":"Slider.js","sources":["../../../../../src/ui/primitives/Slider/Slider.tsx"],"sourcesContent":["\"use client\";\n\nimport { useRef, useState, useId, forwardRef } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport { getAnimationClass } from \"../../tokens/animations\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getShadowClass } from \"../../tokens/shadows\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport {\n getTypographySize,\n getTypographyWeight,\n} from \"../../tokens/typography\";\nimport { cn, cva } from \"../../utils\";\n\nexport type SliderVariant = \"single\" | \"range\";\nexport type SliderSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SliderProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n \"onChange\" | \"defaultValue\"\n> {\n value?: number | [number, number];\n defaultValue?: number | [number, number];\n min?: number;\n max?: number;\n step?: number;\n variant?: SliderVariant;\n size?: SliderSize;\n disabled?: boolean;\n showValue?: boolean;\n marks?: number[];\n onChange?: (value: number | [number, number]) => void;\n onValueChange?: (value: number | [number, number]) => void;\n /**\n * Required label for the slider. Becomes the accessible name via\n * aria-labelledby — single variant references the rendered <label>\n * element directly; range variant references the same label plus a\n * sr-only qualifier (\"minimum\" / \"maximum\") so AT users can tell\n * which handle has focus. Make this a real domain term (\"Volume\",\n * \"Price range\"), not the element type (\"slider\").\n */\n label: string;\n}\n\n/**\n * Slider Component\n *\n * A range input component for selecting numeric values.\n * Supports single and dual thumb (range) modes.\n *\n * @example\n * ```tsx\n * <Slider\n * value={50}\n * min={0}\n * max={100}\n * onChange={(value) => console.log(value)}\n * />\n *\n * <Slider\n * variant=\"range\"\n * value={[20, 80]}\n * min={0}\n * max={100}\n * onChange={(value) => console.log(value)}\n * />\n * ```\n */\nconst Slider = forwardRef<HTMLDivElement, SliderProps>(function Slider(\n {\n value: controlledValue,\n defaultValue,\n min = 0,\n max = 100,\n step = 1,\n variant = \"single\",\n size = \"md\",\n disabled = false,\n showValue = false,\n marks = [],\n onChange,\n onValueChange,\n label,\n className = \"\",\n ...props\n },\n ref,\n) {\n const sliderRef = useRef<HTMLDivElement>(null);\n // Stable IDs for the visible <label> and (for range) the sr-only\n // qualifier spans that distinguish min vs max handles. Range\n // accessible name = label + qualifier via aria-labelledby with two\n // ids (\"Price range minimum\" / \"Price range maximum\"), so the\n // visible label remains the single source of truth — changing\n // `label` propagates to both handles automatically.\n const labelId = useId();\n const minQualifierId = useId();\n const maxQualifierId = useId();\n const [internalValue, setInternalValue] = useState<number | [number, number]>(\n defaultValue || (variant === \"range\" ? [min, max] : min),\n );\n const [isDragging, setIsDragging] = useState(false);\n const [activeThumb, setActiveThumb] = useState<\"min\" | \"max\" | null>(null);\n\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n const getPercentage = (val: number) => ((val - min) / (max - min)) * 100;\n\n const getValueFromPosition = (clientX: number): number => {\n if (!sliderRef.current) return min;\n const rect = sliderRef.current.getBoundingClientRect();\n const percentage = Math.max(\n 0,\n Math.min(1, (clientX - rect.left) / rect.width),\n );\n const rawValue = min + percentage * (max - min);\n return Math.round(rawValue / step) * step;\n };\n\n const handleMouseDown = (\n e: React.MouseEvent,\n thumb: \"min\" | \"max\" = \"min\",\n ) => {\n if (disabled) return;\n e.preventDefault();\n setIsDragging(true);\n setActiveThumb(thumb);\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n if (!sliderRef.current) return;\n const newValue = getValueFromPosition(moveEvent.clientX);\n updateValue(newValue, thumb);\n };\n\n const handleMouseUp = () => {\n setIsDragging(false);\n setActiveThumb(null);\n document.removeEventListener(\"mousemove\", handleMouseMove);\n document.removeEventListener(\"mouseup\", handleMouseUp);\n };\n\n document.addEventListener(\"mousemove\", handleMouseMove);\n document.addEventListener(\"mouseup\", handleMouseUp);\n };\n\n const updateValue = (newValue: number, thumb: \"min\" | \"max\" = \"min\") => {\n const clampedValue = Math.max(min, Math.min(max, newValue));\n\n if (variant === \"range\") {\n const [minVal, maxVal] = Array.isArray(currentValue)\n ? currentValue\n : [min, max];\n let updatedValue: [number, number];\n\n if (thumb === \"min\") {\n updatedValue = [Math.min(clampedValue, maxVal), maxVal];\n } else {\n updatedValue = [minVal, Math.max(clampedValue, minVal)];\n }\n\n if (!isControlled) {\n setInternalValue(updatedValue);\n }\n onChange?.(updatedValue);\n onValueChange?.(updatedValue);\n } else {\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n onValueChange?.(clampedValue);\n }\n };\n\n const handleTrackClick = (e: React.MouseEvent) => {\n if (disabled || isDragging) return;\n const newValue = getValueFromPosition(e.clientX);\n updateValue(newValue);\n };\n\n // Get focus ring color using design system helper\n const getFocusRingColor = (): string => {\n return \"focus:ring-line-brand\" + \" ring-offset-2\";\n };\n\n // Slider variants using CVA\n const sliderTrackVariants = cva(cn(\"relative\", \"cursor-pointer\"), {\n variants: {\n size: {\n sm: \"h-1\",\n md: \"h-2\",\n lg: \"h-3\",\n },\n disabled: {\n true: \"opacity-50 cursor-not-allowed\",\n false: \"\",\n },\n },\n defaultVariants: {\n size: \"md\",\n disabled: false,\n },\n });\n\n const sliderThumbVariants = cva(\n cn(\n \"absolute\",\n \"bg-surface-brand\",\n getRadiusClass(\"full\"),\n \"border-2\",\n \"border-white\",\n getShadowClass(\"md\"),\n \"cursor-grab\",\n \"active:cursor-grabbing\",\n getAnimationClass(\"base\"),\n \"-translate-x-1/2\",\n \"-translate-y-1/2\",\n \"top-1/2\",\n ),\n {\n variants: {\n size: {\n sm: \"w-3 h-3\",\n md: \"w-4 h-4\",\n lg: \"w-5 h-5\",\n },\n active: {\n true: getFocusRingColor(),\n false: \"\",\n },\n },\n defaultVariants: {\n size: \"md\",\n active: false,\n },\n },\n );\n\n // Configuration for styling variants\n // const _config = {\n // track: sliderTrackVariants({ size, disabled }),\n // thumb: sliderThumbVariants({ size }),\n // };\n const singleValue =\n typeof currentValue === \"number\" ? currentValue : currentValue[0];\n const minValue = Array.isArray(currentValue) ? currentValue[0] : min;\n const maxValue = Array.isArray(currentValue) ? currentValue[1] : singleValue;\n\n const minPercentage = getPercentage(minValue);\n const maxPercentage = getPercentage(maxValue);\n\n return (\n <div ref={ref} className={cn(\"w-full\", className)} {...props}>\n <label\n id={labelId}\n className={cn(\n \"block\",\n getTypographySize(\"bodySmall\"),\n getTypographyWeight(\"label\"),\n \"text-fg-primary\",\n getSpacingClass(\"sm\", \"mb\"),\n )}\n >\n {label}\n {showValue && (\n <span\n className={cn(getSpacingClass(\"sm\", \"ml\"), \"text-fg-secondary\")}\n >\n {variant === \"range\" ? `${minValue} - ${maxValue}` : singleValue}\n </span>\n )}\n </label>\n {variant === \"range\" && (\n <>\n <span id={minQualifierId} className=\"sr-only\">\n minimum\n </span>\n <span id={maxQualifierId} className=\"sr-only\">\n maximum\n </span>\n </>\n )}\n <div\n ref={sliderRef}\n className={cn(\n sliderTrackVariants({ size, disabled }),\n \"bg-surface-muted\",\n getRadiusClass(\"full\"),\n )}\n onClick={handleTrackClick}\n role={variant === \"range\" ? undefined : \"slider\"}\n aria-valuemin={variant === \"range\" ? undefined : min}\n aria-valuemax={variant === \"range\" ? undefined : max}\n aria-valuenow={variant === \"range\" ? undefined : singleValue}\n aria-disabled={variant === \"range\" ? undefined : disabled}\n aria-labelledby={variant === \"range\" ? undefined : labelId}\n >\n {/* Active track */}\n <div\n className={cn(\n \"absolute\",\n sliderTrackVariants({ size }),\n \"bg-surface-brand\",\n getRadiusClass(\"full\"),\n getAnimationClass(\"base\"),\n )}\n style={{\n left: `${minPercentage}%`,\n width: `${maxPercentage - minPercentage}%`,\n }}\n />\n\n {/* Marks */}\n {marks.map((mark) => {\n const markPercentage = getPercentage(mark);\n return (\n <div\n key={mark}\n className={cn(\n \"absolute\",\n \"w-1\",\n \"h-1\",\n \"bg-line-strong\",\n getRadiusClass(\"full\"),\n \"-translate-x-1/2\",\n )}\n style={{\n left: `${markPercentage}%`,\n top: \"50%\",\n transform: \"translate(-50%, -50%)\",\n }}\n />\n );\n })}\n\n {/* Thumbs */}\n {variant === \"range\" ? (\n <>\n <div\n className={cn(\n sliderThumbVariants({ size, active: activeThumb === \"min\" }),\n )}\n style={{ left: `${minPercentage}%` }}\n onMouseDown={(e) => handleMouseDown(e, \"min\")}\n role=\"slider\"\n aria-valuemin={min}\n aria-valuemax={maxValue}\n aria-valuenow={minValue}\n aria-labelledby={`${labelId} ${minQualifierId}`}\n />\n <div\n className={cn(\n sliderThumbVariants({ size, active: activeThumb === \"max\" }),\n )}\n style={{ left: `${maxPercentage}%` }}\n onMouseDown={(e) => handleMouseDown(e, \"max\")}\n role=\"slider\"\n aria-valuemin={minValue}\n aria-valuemax={max}\n aria-valuenow={maxValue}\n aria-labelledby={`${labelId} ${maxQualifierId}`}\n />\n </>\n ) : (\n <div\n className={cn(sliderThumbVariants({ size, active: isDragging }))}\n style={{ left: `${maxPercentage}%` }}\n onMouseDown={(e) => handleMouseDown(e)}\n />\n )}\n\n {showValue && !label && (\n <div className=\"absolute -top-6 left-0 right-0 flex justify-center\">\n <span\n className={cn(\n getTypographySize(\"caption\"),\n \"text-fg-secondary\",\n \"bg-surface-overlay\",\n getSpacingClass(\"sm\", \"px\"),\n getSpacingClass(\"xs\", \"py\"),\n getRadiusClass(\"md\"),\n \"shadow\",\n )}\n >\n {variant === \"range\" ? `${minValue} - ${maxValue}` : singleValue}\n </span>\n </div>\n )}\n </div>\n </div>\n );\n});\n\nSlider.displayName = \"Slider\";\n\nexport default Slider;\n"],"names":["Slider","forwardRef","_a","ref","_b","controlledValue","defaultValue","min","max","step","variant","size","disabled","showValue","marks","onChange","onValueChange","label","className","props","__objRest","sliderRef","useRef","labelId","useId","minQualifierId","maxQualifierId","internalValue","setInternalValue","useState","isDragging","setIsDragging","activeThumb","setActiveThumb","isControlled","currentValue","getPercentage","val","getValueFromPosition","clientX","rect","percentage","rawValue","handleMouseDown","e","thumb","handleMouseMove","moveEvent","newValue","updateValue","handleMouseUp","clampedValue","minVal","maxVal","updatedValue","handleTrackClick","getFocusRingColor","sliderTrackVariants","cva","cn","sliderThumbVariants","getRadiusClass","getShadowClass","getAnimationClass","singleValue","minValue","maxValue","minPercentage","maxPercentage","jsxs","getTypographySize","getTypographyWeight","getSpacingClass","jsx","Fragment","mark","markPercentage"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Spinner.js","sources":["../../../../../src/ui/primitives/Spinner/Spinner.tsx"],"sourcesContent":["\"use client\";\n\nimport { memo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getTypographySize } from \"../../tokens/typography\";\nimport { cn, cva } from \"../../utils\";\n\nexport type SpinnerSize = \"sm\" | \"md\" | \"lg\";\nexport type SpinnerVariant = \"primary\" | \"secondary\" | \"neutral\";\n\nexport interface SpinnerProps extends HTMLAttributes<HTMLDivElement> {\n size?: SpinnerSize;\n variant?: SpinnerVariant;\n label?: string;\n}\n\n/**\n * Spinner Component\n *\n * A loading spinner component for indicating loading states.\n * Follows Atomic Design principles as an Atom component.\n * Uses Strategy Pattern for different size/variant combinations.\n *\n * @example\n * ```tsx\n * <Spinner size=\"md\" variant=\"primary\" label=\"Loading...\" />\n * ```\n */\n// Spinner variants using CVA\nconst spinnerVariants = cva(\"motion-safe:animate-spin\", {\n variants: {\n size: {\n sm: \"h-4 w-4\",\n md: \"h-5 w-5\",\n lg: \"h-8 w-8\",\n },\n variant: {\n primary: \"text-fg-brand\",\n secondary: \"text-fg-brand-secondary\",\n neutral: \"text-fg-secondary\",\n },\n },\n defaultVariants: {\n size: \"md\",\n variant: \"primary\",\n },\n});\n\nconst Spinner = memo(function Spinner({\n size = \"md\",\n variant = \"primary\",\n label,\n className = \"\",\n ...props\n}: SpinnerProps) {\n return (\n <div\n className={cn(\"inline-flex\", \"items-center\", className)}\n role=\"status\"\n aria-label={label || \"Loading\"}\n aria-live=\"polite\"\n {...props}\n >\n <Loader2\n className={cn(spinnerVariants({ size, variant }))}\n aria-hidden=\"true\"\n />\n {label && (\n <span\n className={cn(\n getSpacingClass(\"sm\", \"ml\"),\n getTypographySize(\"bodySmall\"),\n \"text-fg-secondary\",\n \"sr-only\",\n )}\n >\n {label}\n </span>\n )}\n </div>\n );\n});\n\nSpinner.displayName = \"Spinner\";\n\nexport default Spinner;\n"],"names":["spinnerVariants","cva","Spinner","memo","_a","_b","size","variant","label","className","props","__objRest","jsxs","__spreadProps","__spreadValues","cn","jsx","Loader2","getSpacingClass","getTypographySize"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,MAAMA,IAAkBC,EAAI,4BAA4B;AAAA,EACtD,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA;AAAA,IAEN,SAAS;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,SAAS;AAAA,EAAA;AAEb,CAAC,GAEKC,IAAUC,EAAK,SAAiBC,GAMrB;AANqB,MAAAC,IAAAD,GACpC;AAAA,UAAAE,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,OAAAC;AAAA,IACA,WAAAC,IAAY;AAAA,MAJwBJ,GAKjCK,IAAAC,EALiCN,GAKjC;AAAA,IAJH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,SACE,gBAAAO;AAAA,IAAC;AAAA,IAAAC,EAAAC,EAAA;AAAA,MACC,WAAWC,EAAG,eAAe,gBAAgBN,CAAS;AAAA,MACtD,MAAK;AAAA,MACL,cAAYD,KAAS;AAAA,MACrB,aAAU;AAAA,OACNE,IALL;AAAA,MAOC,UAAA;AAAA,QAAA,gBAAAM;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,WAAWF,EAAGf,EAAgB,EAAE,MAAAM,GAAM,SAAAC,EAAA,CAAS,CAAC;AAAA,YAChD,eAAY;AAAA,UAAA;AAAA,QAAA;AAAA,QAEbC,KACC,gBAAAQ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD;AAAA,cACTG,EAAgB,MAAM,IAAI;AAAA,cAC1BC,EAAkB,WAAW;AAAA,cAC7B;AAAA,cACA;AAAA,YAAA;AAAA,YAGD,UAAAX;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR,CAAC;AAEDN,EAAQ,cAAc;"}
1
+ {"version":3,"file":"Spinner.js","sources":["../../../../../src/ui/primitives/Spinner/Spinner.tsx"],"sourcesContent":["\"use client\";\n\nimport { memo } from \"react\";\nimport type { HTMLAttributes } from \"react\";\nimport { Loader2 } from \"lucide-react\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getTypographySize } from \"../../tokens/typography\";\nimport { cn, cva } from \"../../utils\";\n\nexport type SpinnerSize = \"sm\" | \"md\" | \"lg\";\nexport type SpinnerVariant = \"primary\" | \"secondary\" | \"neutral\";\n\nexport interface SpinnerProps extends HTMLAttributes<HTMLDivElement> {\n size?: SpinnerSize;\n variant?: SpinnerVariant;\n label?: string;\n}\n\n/**\n * Spinner Component\n *\n * A loading spinner component for indicating loading states.\n * Uses Strategy Pattern for different size/variant combinations.\n *\n * @example\n * ```tsx\n * <Spinner size=\"md\" variant=\"primary\" label=\"Loading...\" />\n * ```\n */\n// Spinner variants using CVA\nconst spinnerVariants = cva(\"motion-safe:animate-spin\", {\n variants: {\n size: {\n sm: \"h-4 w-4\",\n md: \"h-5 w-5\",\n lg: \"h-8 w-8\",\n },\n variant: {\n primary: \"text-fg-brand\",\n secondary: \"text-fg-brand-secondary\",\n neutral: \"text-fg-secondary\",\n },\n },\n defaultVariants: {\n size: \"md\",\n variant: \"primary\",\n },\n});\n\nconst Spinner = memo(function Spinner({\n size = \"md\",\n variant = \"primary\",\n label,\n className = \"\",\n ...props\n}: SpinnerProps) {\n return (\n <div\n className={cn(\"inline-flex\", \"items-center\", className)}\n role=\"status\"\n aria-label={label || \"Loading\"}\n aria-live=\"polite\"\n {...props}\n >\n <Loader2\n className={cn(spinnerVariants({ size, variant }))}\n aria-hidden=\"true\"\n />\n {label && (\n <span\n className={cn(\n getSpacingClass(\"sm\", \"ml\"),\n getTypographySize(\"bodySmall\"),\n \"text-fg-secondary\",\n \"sr-only\",\n )}\n >\n {label}\n </span>\n )}\n </div>\n );\n});\n\nSpinner.displayName = \"Spinner\";\n\nexport default Spinner;\n"],"names":["spinnerVariants","cva","Spinner","memo","_a","_b","size","variant","label","className","props","__objRest","jsxs","__spreadProps","__spreadValues","cn","jsx","Loader2","getSpacingClass","getTypographySize"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAMA,IAAkBC,EAAI,4BAA4B;AAAA,EACtD,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA;AAAA,IAEN,SAAS;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,MACX,SAAS;AAAA,IAAA;AAAA,EACX;AAAA,EAEF,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,SAAS;AAAA,EAAA;AAEb,CAAC,GAEKC,IAAUC,EAAK,SAAiBC,GAMrB;AANqB,MAAAC,IAAAD,GACpC;AAAA,UAAAE,IAAO;AAAA,IACP,SAAAC,IAAU;AAAA,IACV,OAAAC;AAAA,IACA,WAAAC,IAAY;AAAA,MAJwBJ,GAKjCK,IAAAC,EALiCN,GAKjC;AAAA,IAJH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAGA,SACE,gBAAAO;AAAA,IAAC;AAAA,IAAAC,EAAAC,EAAA;AAAA,MACC,WAAWC,EAAG,eAAe,gBAAgBN,CAAS;AAAA,MACtD,MAAK;AAAA,MACL,cAAYD,KAAS;AAAA,MACrB,aAAU;AAAA,OACNE,IALL;AAAA,MAOC,UAAA;AAAA,QAAA,gBAAAM;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,WAAWF,EAAGf,EAAgB,EAAE,MAAAM,GAAM,SAAAC,EAAA,CAAS,CAAC;AAAA,YAChD,eAAY;AAAA,UAAA;AAAA,QAAA;AAAA,QAEbC,KACC,gBAAAQ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD;AAAA,cACTG,EAAgB,MAAM,IAAI;AAAA,cAC1BC,EAAkB,WAAW;AAAA,cAC7B;AAAA,cACA;AAAA,YAAA;AAAA,YAGD,UAAAX;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EAAA;AAIR,CAAC;AAEDN,EAAQ,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.js","sources":["../../../../../src/ui/primitives/Switch/Switch.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, memo, useId, useMemo, useCallback, useState } from \"react\";\nimport type { InputHTMLAttributes } from \"react\";\nimport { getAnimationClass } from \"../../tokens/animations\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getSwitchClasses } from \"../../tokens/switch\";\nimport {\n getTypographySize,\n getTypographyWeight,\n} from \"../../tokens/typography\";\nimport { cn } from \"../../utils\";\n\nexport type SwitchSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SwitchProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\" | \"type\"\n> {\n size?: SwitchSize;\n label?: string;\n /**\n * Secondary text rendered beneath the label, wired through\n * `aria-describedby`. Named `helperText` to match Input, Select,\n * Checkbox, and Radio — every form primitive in the DS uses the\n * same prop name for this role.\n */\n helperText?: string;\n error?: boolean;\n /**\n * Validation success state — paints the (off-state) track border\n * and (when `helperText` is also set) the helper-text color green.\n * Matches the Input + Select + Checkbox + Radio + Textarea\n * convention. Error takes precedence when both `error` and\n * `success` are set.\n */\n success?: boolean;\n}\n\n/**\n * Switch Component\n *\n * A toggle switch component for on/off states.\n * Follows Atomic Design principles as an Atom component.\n *\n * @example\n * ```tsx\n * <Switch checked={isEnabled} onChange={(e) => setIsEnabled(e.target.checked)} />\n *\n * <Switch\n * label=\"Enable notifications\"\n * helperText=\"Receive email notifications\"\n * checked={notifications}\n * onChange={(e) => setNotifications(e.target.checked)}\n * />\n * ```\n */\nconst Switch = memo(\n forwardRef<HTMLInputElement, SwitchProps>(function Switch(\n {\n size = \"md\",\n label,\n helperText,\n error = false,\n success = false,\n className = \"\",\n disabled = false,\n checked,\n defaultChecked,\n onChange,\n id,\n ...props\n },\n ref,\n ) {\n // Controlled / uncontrolled pattern.\n //\n // Previously this primitive accepted `defaultChecked` via\n // `...props` and forwarded it to the hidden `<input type=\"checkbox\">`\n // (form-integration shim), but the visible `<button role=\"switch\">`\n // bound `aria-checked={checked}` directly. With `checked` undefined\n // in uncontrolled mode, `aria-checked` was missing — axe\n // `aria-required-attr` (critical) flagged every uncontrolled Switch\n // because `role=\"switch\"` REQUIRES `aria-checked`. The visual track\n // and thumb also stuck at the off state because their classes\n // derived from the same `checked` prop.\n //\n // The fix is the standard React pattern: when `checked` is provided\n // the consumer controls state; otherwise `defaultChecked` seeds\n // internal state and the click/keydown handlers update it locally\n // AND notify `onChange`. The visible button, the hidden input, and\n // every classes() consumer all read from a single resolved\n // `currentChecked`.\n const isControlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState<boolean>(\n defaultChecked ?? false,\n );\n const currentChecked = isControlled ? !!checked : internalChecked;\n // Stable fallback id when the consumer doesn't provide one. useId\n // is SSR-safe and stable across renders, replacing the deprecated\n // Math.random().substr() pattern.\n const reactId = useId();\n const switchId = id || `switch-${reactId}`;\n\n const labelId = useMemo(\n () => (label ? `${switchId}-label` : undefined),\n [label, switchId],\n );\n\n const helperId = useMemo(\n () => (helperText ? `${switchId}-helper` : undefined),\n [helperText, switchId],\n );\n\n // Component-scoped tokens (SWITCH_TOKENS) drive track/thumb/translate.\n const config = useMemo(() => getSwitchClasses(size), [size]);\n\n // Memoize focus ring color\n const focusRingColor = useMemo(\n () => \"focus:border-line-focus\".replace(\"focus:border-\", \"focus:ring-\"),\n [],\n );\n\n // Memoize classes — all consume `currentChecked` (the resolved\n // controlled-or-uncontrolled state), not the raw `checked` prop.\n const trackClasses = useMemo(\n () =>\n cn(\n \"relative\",\n \"inline-flex\",\n \"shrink-0\",\n \"cursor-pointer\",\n getRadiusClass(\"full\"),\n \"border-2\",\n \"border-transparent\",\n getAnimationClass(\"base\"),\n \"focus:outline-none\",\n \"focus:ring-2\",\n focusRingColor,\n \"focus:ring-offset-2\",\n config.track,\n currentChecked ? \"bg-surface-brand\" : \"bg-surface-muted\",\n // Border feedback only shows in the off state — the on-state\n // brand background already saturates the track and overrides\n // any colored outline visually. Error wins over success.\n error && !currentChecked && \"border-error\",\n !error && success && !currentChecked && \"border-success\",\n disabled && \"opacity-50 cursor-not-allowed\",\n className,\n ),\n [\n focusRingColor,\n config.track,\n currentChecked,\n error,\n success,\n disabled,\n className,\n ],\n );\n\n const thumbClasses = useMemo(\n () =>\n cn(\n \"pointer-events-none\",\n \"inline-block\",\n getRadiusClass(\"full\"),\n \"bg-surface-base\",\n \"shadow\",\n \"transform\",\n getAnimationClass(\"base\"),\n config.thumb,\n currentChecked ? config.translate : \"translate-x-0\",\n ),\n [config.thumb, config.translate, currentChecked],\n );\n\n return (\n <div className={cn(\"flex\", \"items-start\", getSpacingClass(\"md\", \"gap\"))}>\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n className={trackClasses}\n role=\"switch\"\n aria-checked={currentChecked}\n aria-labelledby={labelId}\n aria-describedby={helperId}\n disabled={disabled}\n onClick={useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n if (disabled) return;\n const next = !currentChecked;\n if (!isControlled) setInternalChecked(next);\n if (onChange) {\n const syntheticEvent = {\n ...e,\n target: { ...e.target, checked: next },\n currentTarget: { ...e.currentTarget, checked: next },\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n onChange(syntheticEvent);\n }\n },\n [disabled, onChange, currentChecked, isControlled],\n )}\n onKeyDown={useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled) return;\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n e.preventDefault();\n const next = !currentChecked;\n if (!isControlled) setInternalChecked(next);\n if (onChange) {\n const syntheticEvent = {\n ...e,\n target: { ...e.target, checked: next },\n currentTarget: { ...e.currentTarget, checked: next },\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n onChange(syntheticEvent);\n }\n },\n [disabled, onChange, currentChecked, isControlled],\n )}\n >\n <span className={thumbClasses} />\n </button>\n {/* Hidden checkbox for form-data integration. Follows the\n resolved `currentChecked` so submission picks up the\n correct value in both controlled and uncontrolled modes.\n `aria-hidden` + tabIndex=-1 keep it out of AT and Tab\n order — interaction happens on the visible button above.\n The onChange is a no-op fallback (real state changes\n flow through the button's handler); React requires it\n alongside `checked` to suppress the controlled-input\n warning when the consumer doesn't supply onChange. */}\n <input\n ref={ref}\n type=\"checkbox\"\n id={switchId}\n checked={currentChecked}\n onChange={onChange ?? (() => {})}\n disabled={disabled}\n className=\"sr-only\"\n aria-hidden=\"true\"\n tabIndex={-1}\n {...props}\n />\n </div>\n {(label || helperText) && (\n <div className=\"flex-1\">\n {label && (\n <label\n id={labelId}\n htmlFor={switchId}\n className={cn(\n \"block\",\n getTypographySize(\"bodySmall\"),\n getTypographyWeight(\"label\"),\n error ? \"text-fg-error\" : \"text-fg-primary\",\n disabled ? \"opacity-50\" : \"cursor-pointer\",\n )}\n >\n {label}\n </label>\n )}\n {helperText && (\n <p\n id={helperId}\n className={cn(\n getSpacingClass(\"xs\", \"mt\"),\n getTypographySize(\"bodySmall\"),\n error\n ? \"text-fg-error\"\n : success\n ? \"text-fg-success\"\n : \"text-fg-secondary\",\n )}\n >\n {helperText}\n </p>\n )}\n </div>\n )}\n </div>\n );\n }),\n);\n\nSwitch.displayName = \"Switch\";\n\nexport default Switch;\n"],"names":["Switch","memo","forwardRef","_a","ref","_b","size","label","helperText","error","success","className","disabled","checked","defaultChecked","onChange","id","props","__objRest","isControlled","internalChecked","setInternalChecked","useState","currentChecked","reactId","useId","switchId","labelId","useMemo","helperId","config","getSwitchClasses","focusRingColor","trackClasses","cn","getRadiusClass","getAnimationClass","thumbClasses","jsxs","getSpacingClass","jsx","useCallback","e","next","syntheticEvent","__spreadProps","__spreadValues","getTypographySize","getTypographyWeight"],"mappings":"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"}
1
+ {"version":3,"file":"Switch.js","sources":["../../../../../src/ui/primitives/Switch/Switch.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, memo, useId, useMemo, useCallback, useState } from \"react\";\nimport type { InputHTMLAttributes } from \"react\";\nimport { getAnimationClass } from \"../../tokens/animations\";\nimport { getRadiusClass } from \"../../tokens/radius\";\nimport { getSpacingClass } from \"../../tokens/spacing\";\nimport { getSwitchClasses } from \"../../tokens/switch\";\nimport {\n getTypographySize,\n getTypographyWeight,\n} from \"../../tokens/typography\";\nimport { cn } from \"../../utils\";\n\nexport type SwitchSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface SwitchProps extends Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"size\" | \"type\"\n> {\n size?: SwitchSize;\n label?: string;\n /**\n * Secondary text rendered beneath the label, wired through\n * `aria-describedby`. Named `helperText` to match Input, Select,\n * Checkbox, and Radio — every form primitive in the DS uses the\n * same prop name for this role.\n */\n helperText?: string;\n error?: boolean;\n /**\n * Validation success state — paints the (off-state) track border\n * and (when `helperText` is also set) the helper-text color green.\n * Matches the Input + Select + Checkbox + Radio + Textarea\n * convention. Error takes precedence when both `error` and\n * `success` are set.\n */\n success?: boolean;\n}\n\n/**\n * Switch Component\n *\n * A toggle switch component for on/off states.\n *\n * @example\n * ```tsx\n * <Switch checked={isEnabled} onChange={(e) => setIsEnabled(e.target.checked)} />\n *\n * <Switch\n * label=\"Enable notifications\"\n * helperText=\"Receive email notifications\"\n * checked={notifications}\n * onChange={(e) => setNotifications(e.target.checked)}\n * />\n * ```\n */\nconst Switch = memo(\n forwardRef<HTMLInputElement, SwitchProps>(function Switch(\n {\n size = \"md\",\n label,\n helperText,\n error = false,\n success = false,\n className = \"\",\n disabled = false,\n checked,\n defaultChecked,\n onChange,\n id,\n ...props\n },\n ref,\n ) {\n // Controlled / uncontrolled pattern.\n //\n // Previously this primitive accepted `defaultChecked` via\n // `...props` and forwarded it to the hidden `<input type=\"checkbox\">`\n // (form-integration shim), but the visible `<button role=\"switch\">`\n // bound `aria-checked={checked}` directly. With `checked` undefined\n // in uncontrolled mode, `aria-checked` was missing — axe\n // `aria-required-attr` (critical) flagged every uncontrolled Switch\n // because `role=\"switch\"` REQUIRES `aria-checked`. The visual track\n // and thumb also stuck at the off state because their classes\n // derived from the same `checked` prop.\n //\n // The fix is the standard React pattern: when `checked` is provided\n // the consumer controls state; otherwise `defaultChecked` seeds\n // internal state and the click/keydown handlers update it locally\n // AND notify `onChange`. The visible button, the hidden input, and\n // every classes() consumer all read from a single resolved\n // `currentChecked`.\n const isControlled = checked !== undefined;\n const [internalChecked, setInternalChecked] = useState<boolean>(\n defaultChecked ?? false,\n );\n const currentChecked = isControlled ? !!checked : internalChecked;\n // Stable fallback id when the consumer doesn't provide one. useId\n // is SSR-safe and stable across renders, replacing the deprecated\n // Math.random().substr() pattern.\n const reactId = useId();\n const switchId = id || `switch-${reactId}`;\n\n const labelId = useMemo(\n () => (label ? `${switchId}-label` : undefined),\n [label, switchId],\n );\n\n const helperId = useMemo(\n () => (helperText ? `${switchId}-helper` : undefined),\n [helperText, switchId],\n );\n\n // Component-scoped tokens (SWITCH_TOKENS) drive track/thumb/translate.\n const config = useMemo(() => getSwitchClasses(size), [size]);\n\n // Memoize focus ring color\n const focusRingColor = useMemo(\n () => \"focus:border-line-focus\".replace(\"focus:border-\", \"focus:ring-\"),\n [],\n );\n\n // Memoize classes — all consume `currentChecked` (the resolved\n // controlled-or-uncontrolled state), not the raw `checked` prop.\n const trackClasses = useMemo(\n () =>\n cn(\n \"relative\",\n \"inline-flex\",\n \"shrink-0\",\n \"cursor-pointer\",\n getRadiusClass(\"full\"),\n \"border-2\",\n \"border-transparent\",\n getAnimationClass(\"base\"),\n \"focus:outline-none\",\n \"focus:ring-2\",\n focusRingColor,\n \"focus:ring-offset-2\",\n config.track,\n currentChecked ? \"bg-surface-brand\" : \"bg-surface-muted\",\n // Border feedback only shows in the off state — the on-state\n // brand background already saturates the track and overrides\n // any colored outline visually. Error wins over success.\n error && !currentChecked && \"border-error\",\n !error && success && !currentChecked && \"border-success\",\n disabled && \"opacity-50 cursor-not-allowed\",\n className,\n ),\n [\n focusRingColor,\n config.track,\n currentChecked,\n error,\n success,\n disabled,\n className,\n ],\n );\n\n const thumbClasses = useMemo(\n () =>\n cn(\n \"pointer-events-none\",\n \"inline-block\",\n getRadiusClass(\"full\"),\n \"bg-surface-base\",\n \"shadow\",\n \"transform\",\n getAnimationClass(\"base\"),\n config.thumb,\n currentChecked ? config.translate : \"translate-x-0\",\n ),\n [config.thumb, config.translate, currentChecked],\n );\n\n return (\n <div className={cn(\"flex\", \"items-start\", getSpacingClass(\"md\", \"gap\"))}>\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n className={trackClasses}\n role=\"switch\"\n aria-checked={currentChecked}\n aria-labelledby={labelId}\n aria-describedby={helperId}\n disabled={disabled}\n onClick={useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n if (disabled) return;\n const next = !currentChecked;\n if (!isControlled) setInternalChecked(next);\n if (onChange) {\n const syntheticEvent = {\n ...e,\n target: { ...e.target, checked: next },\n currentTarget: { ...e.currentTarget, checked: next },\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n onChange(syntheticEvent);\n }\n },\n [disabled, onChange, currentChecked, isControlled],\n )}\n onKeyDown={useCallback(\n (e: React.KeyboardEvent<HTMLButtonElement>) => {\n if (disabled) return;\n if (e.key !== \"Enter\" && e.key !== \" \") return;\n e.preventDefault();\n const next = !currentChecked;\n if (!isControlled) setInternalChecked(next);\n if (onChange) {\n const syntheticEvent = {\n ...e,\n target: { ...e.target, checked: next },\n currentTarget: { ...e.currentTarget, checked: next },\n } as unknown as React.ChangeEvent<HTMLInputElement>;\n onChange(syntheticEvent);\n }\n },\n [disabled, onChange, currentChecked, isControlled],\n )}\n >\n <span className={thumbClasses} />\n </button>\n {/* Hidden checkbox for form-data integration. Follows the\n resolved `currentChecked` so submission picks up the\n correct value in both controlled and uncontrolled modes.\n `aria-hidden` + tabIndex=-1 keep it out of AT and Tab\n order — interaction happens on the visible button above.\n The onChange is a no-op fallback (real state changes\n flow through the button's handler); React requires it\n alongside `checked` to suppress the controlled-input\n warning when the consumer doesn't supply onChange. */}\n <input\n ref={ref}\n type=\"checkbox\"\n id={switchId}\n checked={currentChecked}\n onChange={onChange ?? (() => {})}\n disabled={disabled}\n className=\"sr-only\"\n aria-hidden=\"true\"\n tabIndex={-1}\n {...props}\n />\n </div>\n {(label || helperText) && (\n <div className=\"flex-1\">\n {label && (\n <label\n id={labelId}\n htmlFor={switchId}\n className={cn(\n \"block\",\n getTypographySize(\"bodySmall\"),\n getTypographyWeight(\"label\"),\n error ? \"text-fg-error\" : \"text-fg-primary\",\n disabled ? \"opacity-50\" : \"cursor-pointer\",\n )}\n >\n {label}\n </label>\n )}\n {helperText && (\n <p\n id={helperId}\n className={cn(\n getSpacingClass(\"xs\", \"mt\"),\n getTypographySize(\"bodySmall\"),\n error\n ? \"text-fg-error\"\n : success\n ? \"text-fg-success\"\n : \"text-fg-secondary\",\n )}\n >\n {helperText}\n </p>\n )}\n </div>\n )}\n </div>\n );\n }),\n);\n\nSwitch.displayName = \"Switch\";\n\nexport default Switch;\n"],"names":["Switch","memo","forwardRef","_a","ref","_b","size","label","helperText","error","success","className","disabled","checked","defaultChecked","onChange","id","props","__objRest","isControlled","internalChecked","setInternalChecked","useState","currentChecked","reactId","useId","switchId","labelId","useMemo","helperId","config","getSwitchClasses","focusRingColor","trackClasses","cn","getRadiusClass","getAnimationClass","thumbClasses","jsxs","getSpacingClass","jsx","useCallback","e","next","syntheticEvent","__spreadProps","__spreadValues","getTypographySize","getTypographyWeight"],"mappings":"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"}