analytica-frontend-lib 1.0.83 → 1.0.85

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 (143) hide show
  1. package/dist/Accordation/index.js +163 -74
  2. package/dist/Accordation/index.js.map +1 -1
  3. package/dist/Accordation/index.mjs +163 -74
  4. package/dist/Accordation/index.mjs.map +1 -1
  5. package/dist/Alert/index.js +32 -32
  6. package/dist/Alert/index.js.map +1 -1
  7. package/dist/Alert/index.mjs +32 -32
  8. package/dist/Alert/index.mjs.map +1 -1
  9. package/dist/AlertDialog/index.js +13 -2
  10. package/dist/AlertDialog/index.js.map +1 -1
  11. package/dist/AlertDialog/index.mjs +13 -2
  12. package/dist/AlertDialog/index.mjs.map +1 -1
  13. package/dist/Alternative/index.js +86 -25
  14. package/dist/Alternative/index.js.map +1 -1
  15. package/dist/Alternative/index.mjs +86 -25
  16. package/dist/Alternative/index.mjs.map +1 -1
  17. package/dist/Badge/index.js +13 -4
  18. package/dist/Badge/index.js.map +1 -1
  19. package/dist/Badge/index.mjs +13 -4
  20. package/dist/Badge/index.mjs.map +1 -1
  21. package/dist/Button/index.js +10 -1
  22. package/dist/Button/index.js.map +1 -1
  23. package/dist/Button/index.mjs +8 -1
  24. package/dist/Button/index.mjs.map +1 -1
  25. package/dist/Calendar/index.js +11 -2
  26. package/dist/Calendar/index.js.map +1 -1
  27. package/dist/Calendar/index.mjs +11 -2
  28. package/dist/Calendar/index.mjs.map +1 -1
  29. package/dist/Card/index.js +154 -71
  30. package/dist/Card/index.js.map +1 -1
  31. package/dist/Card/index.mjs +154 -71
  32. package/dist/Card/index.mjs.map +1 -1
  33. package/dist/CheckBox/index.js +28 -5
  34. package/dist/CheckBox/index.js.map +1 -1
  35. package/dist/CheckBox/index.mjs +28 -5
  36. package/dist/CheckBox/index.mjs.map +1 -1
  37. package/dist/Chips/index.js +10 -1
  38. package/dist/Chips/index.js.map +1 -1
  39. package/dist/Chips/index.mjs +10 -1
  40. package/dist/Chips/index.mjs.map +1 -1
  41. package/dist/Divider/index.js +10 -1
  42. package/dist/Divider/index.js.map +1 -1
  43. package/dist/Divider/index.mjs +8 -1
  44. package/dist/Divider/index.mjs.map +1 -1
  45. package/dist/DropdownMenu/index.js +18 -22
  46. package/dist/DropdownMenu/index.js.map +1 -1
  47. package/dist/DropdownMenu/index.mjs +18 -22
  48. package/dist/DropdownMenu/index.mjs.map +1 -1
  49. package/dist/IconButton/index.js +10 -1
  50. package/dist/IconButton/index.js.map +1 -1
  51. package/dist/IconButton/index.mjs +10 -1
  52. package/dist/IconButton/index.mjs.map +1 -1
  53. package/dist/IconRoundedButton/index.js +10 -1
  54. package/dist/IconRoundedButton/index.js.map +1 -1
  55. package/dist/IconRoundedButton/index.mjs +8 -1
  56. package/dist/IconRoundedButton/index.mjs.map +1 -1
  57. package/dist/Menu/index.js +22 -10
  58. package/dist/Menu/index.js.map +1 -1
  59. package/dist/Menu/index.mjs +22 -10
  60. package/dist/Menu/index.mjs.map +1 -1
  61. package/dist/Modal/index.js +15 -1
  62. package/dist/Modal/index.js.map +1 -1
  63. package/dist/Modal/index.mjs +15 -1
  64. package/dist/Modal/index.mjs.map +1 -1
  65. package/dist/NavButton/index.js +10 -1
  66. package/dist/NavButton/index.js.map +1 -1
  67. package/dist/NavButton/index.mjs +10 -1
  68. package/dist/NavButton/index.mjs.map +1 -1
  69. package/dist/NotFound/index.js +13 -3
  70. package/dist/NotFound/index.js.map +1 -1
  71. package/dist/NotFound/index.mjs +13 -3
  72. package/dist/NotFound/index.mjs.map +1 -1
  73. package/dist/ProgressBar/index.js +63 -15
  74. package/dist/ProgressBar/index.js.map +1 -1
  75. package/dist/ProgressBar/index.mjs +63 -15
  76. package/dist/ProgressBar/index.mjs.map +1 -1
  77. package/dist/ProgressCircle/index.js +34 -7
  78. package/dist/ProgressCircle/index.js.map +1 -1
  79. package/dist/ProgressCircle/index.mjs +34 -7
  80. package/dist/ProgressCircle/index.mjs.map +1 -1
  81. package/dist/Quiz/index.d.mts +25 -2
  82. package/dist/Quiz/index.d.ts +25 -2
  83. package/dist/Quiz/index.js +972 -260
  84. package/dist/Quiz/index.js.map +1 -1
  85. package/dist/Quiz/index.mjs +968 -261
  86. package/dist/Quiz/index.mjs.map +1 -1
  87. package/dist/Quiz/useQuizStore/index.d.mts +44 -12
  88. package/dist/Quiz/useQuizStore/index.d.ts +44 -12
  89. package/dist/Quiz/useQuizStore/index.js +206 -85
  90. package/dist/Quiz/useQuizStore/index.js.map +1 -1
  91. package/dist/Quiz/useQuizStore/index.mjs +203 -85
  92. package/dist/Quiz/useQuizStore/index.mjs.map +1 -1
  93. package/dist/Radio/index.js +36 -6
  94. package/dist/Radio/index.js.map +1 -1
  95. package/dist/Radio/index.mjs +36 -6
  96. package/dist/Radio/index.mjs.map +1 -1
  97. package/dist/Select/index.js +20 -4
  98. package/dist/Select/index.js.map +1 -1
  99. package/dist/Select/index.mjs +20 -4
  100. package/dist/Select/index.mjs.map +1 -1
  101. package/dist/SelectionButton/index.js +10 -1
  102. package/dist/SelectionButton/index.js.map +1 -1
  103. package/dist/SelectionButton/index.mjs +10 -1
  104. package/dist/SelectionButton/index.mjs.map +1 -1
  105. package/dist/Skeleton/index.js +18 -6
  106. package/dist/Skeleton/index.js.map +1 -1
  107. package/dist/Skeleton/index.mjs +18 -6
  108. package/dist/Skeleton/index.mjs.map +1 -1
  109. package/dist/Stepper/index.js +27 -18
  110. package/dist/Stepper/index.js.map +1 -1
  111. package/dist/Stepper/index.mjs +27 -18
  112. package/dist/Stepper/index.mjs.map +1 -1
  113. package/dist/Table/index.js +37 -13
  114. package/dist/Table/index.js.map +1 -1
  115. package/dist/Table/index.mjs +37 -13
  116. package/dist/Table/index.mjs.map +1 -1
  117. package/dist/Text/index.js +10 -1
  118. package/dist/Text/index.js.map +1 -1
  119. package/dist/Text/index.mjs +8 -1
  120. package/dist/Text/index.mjs.map +1 -1
  121. package/dist/TextArea/index.js +17 -3
  122. package/dist/TextArea/index.js.map +1 -1
  123. package/dist/TextArea/index.mjs +17 -3
  124. package/dist/TextArea/index.mjs.map +1 -1
  125. package/dist/Toast/Toaster/index.js +15 -1
  126. package/dist/Toast/Toaster/index.js.map +1 -1
  127. package/dist/Toast/Toaster/index.mjs +15 -1
  128. package/dist/Toast/Toaster/index.mjs.map +1 -1
  129. package/dist/Toast/index.js +15 -1
  130. package/dist/Toast/index.js.map +1 -1
  131. package/dist/Toast/index.mjs +15 -1
  132. package/dist/Toast/index.mjs.map +1 -1
  133. package/dist/index.css +8 -9
  134. package/dist/index.css.map +1 -1
  135. package/dist/index.d.mts +1 -1
  136. package/dist/index.d.ts +1 -1
  137. package/dist/index.js +903 -325
  138. package/dist/index.js.map +1 -1
  139. package/dist/index.mjs +901 -326
  140. package/dist/index.mjs.map +1 -1
  141. package/dist/styles.css +8 -9
  142. package/dist/styles.css.map +1 -1
  143. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Select/Select.tsx"],"sourcesContent":["import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\n\nconst VARIANT_CLASSES = {\n outlined: 'border rounded-lg focus:border-primary-950',\n underlined: 'border-b focus:border-primary-950',\n rounded: 'border rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className=\"w-full\">\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={`block font-bold text-text-900 mb-1.5 ${sizeClasses}`}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={`relative ${sizeClasses}`} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={`\n flex min-w-[220px] w-full items-center justify-between border-border-300\n ${heightClasses} ${paddingClasses}\n ${invalid && `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${!invalid && !disabled ? 'text-text-700' : ''}\n ${variantClasses}\n ${className}\n `}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={`h-[1em] w-[1em] opacity-50 transition-transform ${open ? 'rotate-180' : ''}`}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={`bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md border-border-100 ${getPositionClasses()} ${className}`}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n"],"mappings":"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","names":["children","label"]}
1
+ {"version":3,"sources":["../../src/components/Select/Select.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nconst VARIANT_CLASSES = {\n outlined: 'border rounded-lg focus:border-primary-950',\n underlined: 'border-b focus:border-primary-950',\n rounded: 'border rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className=\"w-full\">\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={cn('block font-bold text-text-900 mb-1.5', sizeClasses)}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={cn('relative', sizeClasses)} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={`\n flex min-w-[220px] w-full items-center justify-between border-border-300\n ${heightClasses} ${paddingClasses}\n ${invalid && `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${!invalid && !disabled ? 'text-text-700' : ''}\n ${variantClasses}\n ${className}\n `}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={cn(\n 'h-[1em] w-[1em] opacity-50 transition-transform',\n open ? 'rotate-180' : ''\n )}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={cn(\n 'bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md border-border-100',\n getPositionClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"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","names":["children","label"]}
@@ -10,6 +10,15 @@ import {
10
10
  useId
11
11
  } from "react";
12
12
  import { CaretDown, Check, WarningCircle } from "phosphor-react";
13
+
14
+ // src/utils/utils.ts
15
+ import { clsx } from "clsx";
16
+ import { twMerge } from "tailwind-merge";
17
+ function cn(...inputs) {
18
+ return twMerge(clsx(inputs));
19
+ }
20
+
21
+ // src/components/Select/Select.tsx
13
22
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
23
  var VARIANT_CLASSES = {
15
24
  outlined: "border rounded-lg focus:border-primary-950",
@@ -185,11 +194,11 @@ var Select = ({
185
194
  "label",
186
195
  {
187
196
  htmlFor: selectId,
188
- className: `block font-bold text-text-900 mb-1.5 ${sizeClasses}`,
197
+ className: cn("block font-bold text-text-900 mb-1.5", sizeClasses),
189
198
  children: label
190
199
  }
191
200
  ),
192
- /* @__PURE__ */ jsx("div", { className: `relative ${sizeClasses}`, ref: selectRef, children: injectStore(children, store, size, selectId) }),
201
+ /* @__PURE__ */ jsx("div", { className: cn("relative", sizeClasses), ref: selectRef, children: injectStore(children, store, size, selectId) }),
193
202
  /* @__PURE__ */ jsxs("div", { className: "mt-1.5 gap-1.5", children: [
194
203
  helperText && /* @__PURE__ */ jsx("p", { className: "text-sm text-text-500", children: helperText }),
195
204
  errorMessage && /* @__PURE__ */ jsxs("p", { className: "flex gap-1 items-center text-sm text-indicator-error", children: [
@@ -250,7 +259,10 @@ var SelectTrigger = forwardRef(
250
259
  /* @__PURE__ */ jsx(
251
260
  CaretDown,
252
261
  {
253
- className: `h-[1em] w-[1em] opacity-50 transition-transform ${open ? "rotate-180" : ""}`
262
+ className: cn(
263
+ "h-[1em] w-[1em] opacity-50 transition-transform",
264
+ open ? "rotate-180" : ""
265
+ )
254
266
  }
255
267
  )
256
268
  ]
@@ -277,7 +289,11 @@ var SelectContent = forwardRef(
277
289
  {
278
290
  role: "menu",
279
291
  ref,
280
- className: `bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md border-border-100 ${getPositionClasses()} ${className}`,
292
+ className: cn(
293
+ "bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md border-border-100",
294
+ getPositionClasses(),
295
+ className
296
+ ),
281
297
  ...props,
282
298
  children
283
299
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Select/Select.tsx"],"sourcesContent":["import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\n\nconst VARIANT_CLASSES = {\n outlined: 'border rounded-lg focus:border-primary-950',\n underlined: 'border-b focus:border-primary-950',\n rounded: 'border rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className=\"w-full\">\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={`block font-bold text-text-900 mb-1.5 ${sizeClasses}`}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={`relative ${sizeClasses}`} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={`\n flex min-w-[220px] w-full items-center justify-between border-border-300\n ${heightClasses} ${paddingClasses}\n ${invalid && `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${!invalid && !disabled ? 'text-text-700' : ''}\n ${variantClasses}\n ${className}\n `}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={`h-[1em] w-[1em] opacity-50 transition-transform ${open ? 'rotate-180' : ''}`}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={`bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md border-border-100 ${getPositionClasses()} ${className}`}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n"],"mappings":";AAAA,SAAS,QAAkB,gBAAgB;AAC3C;AAAA,EAEE;AAAA,EACA;AAAA,EAEA;AAAA,EAKA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW,OAAO,qBAAqB;AAqFvC,wBAkMC,YAlMD;AAnFT,IAAM,kBAAkB;AAAA,EACtB,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,SAAS;AACX;AAEA,IAAM,eAAe;AAAA,EACnB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,eAAe;AACjB;AAEA,IAAM,iBAAiB;AAAA,EACrB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,eAAe;AACjB;AAEA,IAAM,kBAAkB;AAAA,EACtB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,eAAe;AACjB;AAEA,IAAM,eAAe;AAAA,EACnB,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AACR;AACA,IAAM,gBAAgB;AAAA,EACpB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,KAAK;AACP;AAcO,SAAS,kBACd,eACgB;AAChB,SAAO,OAAoB,CAAC,SAAS;AAAA,IACnC,MAAM;AAAA,IACN,SAAS,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC;AAAA,IAC/B,OAAO;AAAA,IACP,UAAU,CAAC,UAAU,IAAI,EAAE,MAAM,CAAC;AAAA,IAClC,eAAe;AAAA,IACf,kBAAkB,CAAC,UAAU,IAAI,EAAE,eAAe,MAAM,CAAC;AAAA,IACzD;AAAA,EACF,EAAE;AACJ;AAEO,IAAM,iBAAiB,CAAC,kBAAmC;AAChE,MAAI,CAAC,eAAe;AAClB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,eAAe,UAAgC;AAC7D,MAAI,OAAO,aAAa,YAAY,OAAO,aAAa,UAAU;AAChE,WAAO;AAAA,EACT;AACA,QAAM,YAAY,SAAS,QAAQ,QAAQ;AAE3C,MAAI,UAAU,WAAW,EAAG,QAAO,UAAU,CAAC;AAE9C,SAAO,gCAAG,qBAAU;AACtB;AAcA,IAAM,cAAc,CAClB,UACA,OACA,MACA,aACc;AACd,SAAO,SAAS,IAAI,UAAU,CAAC,UAAU;AACvC,QAAI,eAAe,KAAK,GAAG;AACzB,YAAM,aAAa;AAOnB,YAAM,WAKD;AAAA,QACH;AAAA,MACF;AAGA,UAAI,WAAW,SAAS,eAAe;AACrC,iBAAS,OAAO;AAChB,iBAAS,WAAW;AAAA,MACtB;AAEA,UAAI,WAAW,MAAM,UAAU;AAC7B,iBAAS,WAAW;AAAA,UAClB,WAAW,MAAM;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,aAAO,aAAa,YAAY,QAAQ;AAAA,IAC1C;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,IAAM,SAAS,CAAC;AAAA,EACd;AAAA,EACA,eAAe;AAAA,EACf,OAAO;AAAA,EACP;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAmB;AACjB,QAAM,WAAW,OAA8B,IAAI;AACnD,WAAS,YAAY,kBAAkB,aAAa;AACpD,QAAM,QAAQ,SAAS;AAEvB,QAAM,YAAY,OAAuB,IAAI;AAC7C,QAAM,EAAE,MAAM,SAAS,UAAU,cAAc,IAAI,SAAS,OAAO,CAAC,MAAM,CAAC;AAG3E,QAAM,cAAc,MAAM;AAC1B,QAAM,WAAW,MAAM,UAAU,WAAW;AAE5C,QAAM,oBAAoB,CACxBA,WACA,gBACkB;AAClB,QAAI,QAAuB;AAC3B,UAAM,SAAS,CAAC,UAAqB;AACnC,eAAS,QAAQ,OAAO,CAAC,UAAU;AACjC,YAAI,CAAC,eAAe,KAAK,EAAG;AAC5B,cAAM,aAAa;AAInB,YACE,WAAW,SAAS,cACpB,WAAW,MAAM,UAAU,aAC3B;AACA,cAAI,OAAO,WAAW,MAAM,aAAa;AACvC,oBAAQ,WAAW,MAAM;AAAA,QAC7B;AACA,YAAI,WAAW,MAAM,YAAY,CAAC;AAChC,iBAAO,WAAW,MAAM,QAAQ;AAAA,MACpC,CAAC;AAAA,IACH;AACA,WAAOA,SAAQ;AACf,WAAO;AAAA,EACT;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,iBAAiB,cAAc;AAClC,YAAMC,SAAQ,kBAAkB,UAAU,YAAY;AACtD,UAAIA,OAAO,OAAM,SAAS,EAAE,eAAeA,OAAM,CAAC;AAAA,IACpD;AAAA,EACF,GAAG,CAAC,UAAU,cAAc,aAAa,CAAC;AAE1C,YAAU,MAAM;AACd,UAAM,qBAAqB,CAAC,UAAiC;AAC3D,UACE,UAAU,WACV,CAAC,UAAU,QAAQ,SAAS,MAAM,MAAc,GAChD;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF;AAEA,UAAM,kBAAkB,CAAC,UAAoC;AAC3D,YAAM,gBAAgB,UAAU,SAAS,cAAc,eAAe;AACtE,UAAI,eAAe;AACjB,cAAM,eAAe;AACrB,cAAM,QAAQ,MAAM;AAAA,UAClB,cAAc;AAAA,YACZ;AAAA,UACF;AAAA,QACF,EAAE,OAAO,CAAC,OAA0B,cAAc,WAAW;AAE7D,cAAM,UAAU,SAAS;AACzB,cAAM,eAAe,MAAM,UAAU,CAAC,SAAS,SAAS,OAAO;AAE/D,YAAI,YAAY;AAChB,YAAI,MAAM,QAAQ,aAAa;AAC7B,sBACE,iBAAiB,KAAK,KAAK,eAAe,KAAK,MAAM;AAAA,QACzD,OAAO;AACL,sBACE,iBAAiB,KACb,MAAM,SAAS,KACd,eAAe,IAAI,MAAM,UAAU,MAAM;AAAA,QAClD;AACA,cAAM,SAAS,GAAG,MAAM;AAAA,MAC1B;AAAA,IACF;AAEA,QAAI,MAAM;AACR,eAAS,iBAAiB,aAAa,kBAAkB;AACzD,eAAS,iBAAiB,WAAW,eAAe;AAAA,IACtD;AACA,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,kBAAkB;AAC5D,eAAS,oBAAoB,WAAW,eAAe;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,YAAU,MAAM;AACd,QAAI,WAAW;AACb,eAAS,SAAS;AAClB,YAAMA,SAAQ,kBAAkB,UAAU,SAAS;AACnD,UAAIA,OAAO,OAAM,SAAS,EAAE,eAAeA,OAAM,CAAC;AAAA,IACpD;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,cAAc,aAAa,IAAI;AAErC,SACE,qBAAC,SAAI,WAAU,UAEZ;AAAA,aACC;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,WAAW,wCAAwC,WAAW;AAAA,QAE7D;AAAA;AAAA,IACH;AAAA,IAIF,oBAAC,SAAI,WAAW,YAAY,WAAW,IAAI,KAAK,WAC7C,sBAAY,UAAU,OAAO,MAAM,QAAQ,GAC9C;AAAA,IAGA,qBAAC,SAAI,WAAU,kBACZ;AAAA,oBAAc,oBAAC,OAAE,WAAU,yBAAyB,sBAAW;AAAA,MAC/D,gBACC,qBAAC,OAAE,WAAU,wDACX;AAAA,4BAAC,iBAAc,MAAM,IAAI;AAAA,QAAE;AAAA,QAAE;AAAA,SAC/B;AAAA,OAEJ;AAAA,KACF;AAEJ;AAEA,IAAM,cAAc,CAAC;AAAA,EACnB;AAAA,EACA,OAAO;AACT,MAGM;AACJ,QAAM,QAAQ,eAAe,aAAa;AAE1C,QAAM,gBAAgB,SAAS,OAAO,CAAC,MAAM,EAAE,aAAa;AAC5D,QAAM,QAAQ,SAAS,OAAO,CAAC,MAAM,EAAE,KAAK;AAC5C,SACE,oBAAC,UAAK,WAAU,gBACb,2BAAiB,eAAe,OACnC;AAEJ;AAWA,IAAM,gBAAgB;AAAA,EACpB,CACE;AAAA,IACE;AAAA,IACA,UAAU;AAAA,IACV,UAAU;AAAA,IACV,OAAO;AAAA,IACP;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,QAAQ,eAAe,aAAa;AAC1C,UAAM,OAAO,SAAS,OAAO,CAAC,MAAM,EAAE,IAAI;AAC1C,UAAM,aAAa,MAAM,MAAM,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC;AAEvD,UAAM,iBAAiB,gBAAgB,OAAO;AAC9C,UAAM,gBAAgB,eAAe,IAAI;AACzC,UAAM,iBAAiB,gBAAgB,IAAI;AAE3C,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,IAAI;AAAA,QACJ,WAAW;AAAA;AAAA,UAET,aAAa,IAAI,cAAc;AAAA,UAC/B,WAAW,GAAG,WAAW,eAAe,eAAe,UAAU,uCAAuC;AAAA,UAExG,WACI,oEACA,iIACN;AAAA,UACE,CAAC,WAAW,CAAC,WAAW,kBAAkB,EAAE;AAAA,UAC5C,cAAc;AAAA,UACd,SAAS;AAAA;AAAA,QAEX,SAAS;AAAA,QACT,iBAAe;AAAA,QACf,iBAAc;AAAA,QACd,iBAAe,OAAO,mBAAmB;AAAA,QACxC,GAAG;AAAA,QAEH;AAAA,gBAAM;AAAA,UACP;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,mDAAmD,OAAO,eAAe,EAAE;AAAA;AAAA,UACxF;AAAA;AAAA;AAAA,IACF;AAAA,EAEJ;AACF;AACA,cAAc,cAAc;AAS5B,IAAM,gBAAgB;AAAA,EACpB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,OAAO;AAAA,IACP,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,QAAQ,eAAe,aAAa;AAE1C,UAAM,OAAO,SAAS,OAAO,CAAC,MAAM,EAAE,IAAI;AAC1C,QAAI,CAAC,KAAM,QAAO;AAElB,UAAM,qBAAqB,MACzB,8BAA8B,aAAa,IAAI,CAAC,IAAI,cAAc,KAAK,CAAC;AAE1E,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA,WAAW,yIAAyI,mBAAmB,CAAC,IAAI,SAAS;AAAA,QACpL,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AACA,cAAc,cAAc;AAQ5B,IAAM,aAAa;AAAA,EACjB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,OAAO;AAAA,IACP,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,QAAQ,eAAe,aAAa;AAC1C,UAAM;AAAA,MACJ,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,SAAS,OAAO,CAAC,MAAM,CAAC;AAE5B,UAAM,cAAc,CAClB,MACG;AACH,YAAM,YAAY,eAAe,QAAQ;AACzC,UAAI,CAAC,UAAU;AACb,iBAAS,KAAK;AACd,yBAAiB,SAAS;AAC1B,gBAAQ,KAAK;AACb,wBAAgB,KAAK;AAAA,MACvB;AACA,YAAM,UAAU,CAA+B;AAAA,IACjD;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,iBAAe;AAAA,QACf;AAAA,QACA,WAAW;AAAA;AAAA;AAAA,YAGP,SAAS;AAAA,YAET,WACI,oEACA,+IACN;AAAA,YACE,kBAAkB,SAAS,kBAAkB;AAAA;AAAA,QAEjD,SAAS;AAAA,QACT,WAAW,CAAC,MAAM;AAChB,cAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,IAAK,aAAY,CAAC;AAAA,QACvD;AAAA,QACA,UAAU,WAAW,KAAK;AAAA,QACzB,GAAG;AAAA,QAEJ;AAAA,8BAAC,UAAK,WAAU,iEACb,4BAAkB,SAAS,oBAAC,SAAM,WAAU,IAAG,GAClD;AAAA,UACC;AAAA;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;AAEzB,IAAO,iBAAQ;","names":["children","label"]}
1
+ {"version":3,"sources":["../../src/components/Select/Select.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { create, StoreApi, useStore } from 'zustand';\nimport {\n ReactNode,\n useEffect,\n useRef,\n ButtonHTMLAttributes,\n forwardRef,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactElement,\n isValidElement,\n Children,\n cloneElement,\n useId,\n} from 'react';\nimport { CaretDown, Check, WarningCircle } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\nconst VARIANT_CLASSES = {\n outlined: 'border rounded-lg focus:border-primary-950',\n underlined: 'border-b focus:border-primary-950',\n rounded: 'border rounded-full focus:border-primary-950',\n} as const;\n\nconst SIZE_CLASSES = {\n small: 'text-sm',\n medium: 'text-md',\n large: 'text-lg',\n 'extra-large': 'text-lg',\n} as const;\n\nconst HEIGHT_CLASSES = {\n small: 'h-8',\n medium: 'h-9',\n large: 'h-10',\n 'extra-large': 'h-12',\n} as const;\n\nconst PADDING_CLASSES = {\n small: 'px-2 py-1',\n medium: 'px-3 py-2',\n large: 'px-4 py-3',\n 'extra-large': 'px-5 py-4',\n} as const;\n\nconst SIDE_CLASSES = {\n top: 'bottom-full -translate-y-1',\n right: 'top-full translate-y-1',\n bottom: 'top-full translate-y-1',\n left: 'top-full translate-y-1',\n};\nconst ALIGN_CLASSES = {\n start: 'left-0',\n center: 'left-1/2 -translate-x-1/2',\n end: 'right-0',\n};\n\ninterface SelectStore {\n open: boolean;\n setOpen: (open: boolean) => void;\n value: string;\n setValue: (value: string) => void;\n selectedLabel: ReactNode;\n setSelectedLabel: (label: ReactNode) => void;\n onValueChange?: (value: string) => void;\n}\n\ntype SelectStoreApi = StoreApi<SelectStore>;\n\nexport function createSelectStore(\n onValueChange?: (value: string) => void\n): SelectStoreApi {\n return create<SelectStore>((set) => ({\n open: false,\n setOpen: (open) => set({ open }),\n value: '',\n setValue: (value) => set({ value }),\n selectedLabel: '',\n setSelectedLabel: (label) => set({ selectedLabel: label }),\n onValueChange,\n }));\n}\n\nexport const useSelectStore = (externalStore?: SelectStoreApi) => {\n if (!externalStore) {\n throw new Error(\n 'Component must be used within a Select (store is missing)'\n );\n }\n\n return externalStore;\n};\n\nexport function getLabelAsNode(children: ReactNode): ReactNode {\n if (typeof children === 'string' || typeof children === 'number') {\n return children;\n }\n const flattened = Children.toArray(children);\n\n if (flattened.length === 1) return flattened[0];\n\n return <>{flattened}</>;\n}\n\ninterface SelectProps {\n children: ReactNode;\n defaultValue?: string;\n value?: string;\n onValueChange?: (value: string) => void;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n label?: string;\n helperText?: string;\n errorMessage?: string;\n id?: string;\n}\n\nconst injectStore = (\n children: ReactNode,\n store: SelectStoreApi,\n size: string,\n selectId: string\n): ReactNode => {\n return Children.map(children, (child) => {\n if (isValidElement(child)) {\n const typedChild = child as ReactElement<{\n store?: SelectStoreApi;\n children?: ReactNode;\n size?: string;\n selectId?: string;\n }>;\n\n const newProps: Partial<{\n store: SelectStoreApi;\n children: ReactNode;\n size: string;\n selectId: string;\n }> = {\n store,\n };\n\n // Only pass size and selectId to SelectTrigger\n if (typedChild.type === SelectTrigger) {\n newProps.size = size;\n newProps.selectId = selectId;\n }\n\n if (typedChild.props.children) {\n newProps.children = injectStore(\n typedChild.props.children,\n store,\n size,\n selectId\n );\n }\n\n return cloneElement(typedChild, newProps);\n }\n return child;\n });\n};\n\nconst Select = ({\n children,\n defaultValue = '',\n value: propValue,\n onValueChange,\n size = 'small',\n label,\n helperText,\n errorMessage,\n id,\n}: SelectProps) => {\n const storeRef = useRef<SelectStoreApi | null>(null);\n storeRef.current ??= createSelectStore(onValueChange);\n const store = storeRef.current;\n\n const selectRef = useRef<HTMLDivElement>(null);\n const { open, setOpen, setValue, selectedLabel } = useStore(store, (s) => s);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const selectId = id ?? `select-${generatedId}`;\n\n const findLabelForValue = (\n children: ReactNode,\n targetValue: string\n ): string | null => {\n let found: string | null = null;\n const search = (nodes: ReactNode) => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const typedChild = child as ReactElement<{\n value?: string;\n children?: ReactNode;\n }>;\n if (\n typedChild.type === SelectItem &&\n typedChild.props.value === targetValue\n ) {\n if (typeof typedChild.props.children === 'string')\n found = typedChild.props.children;\n }\n if (typedChild.props.children && !found)\n search(typedChild.props.children);\n });\n };\n search(children);\n return found;\n };\n\n useEffect(() => {\n if (!selectedLabel && defaultValue) {\n const label = findLabelForValue(children, defaultValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [children, defaultValue, selectedLabel]);\n\n useEffect(() => {\n const handleClickOutside = (event: globalThis.MouseEvent) => {\n if (\n selectRef.current &&\n !selectRef.current.contains(event.target as Node)\n ) {\n setOpen(false);\n }\n };\n\n const handleArrowKeys = (event: globalThis.KeyboardEvent) => {\n const selectContent = selectRef.current?.querySelector('[role=\"menu\"]');\n if (selectContent) {\n event.preventDefault();\n const items = Array.from(\n selectContent.querySelectorAll(\n '[role=\"menuitem\"]:not([aria-disabled=\"true\"])'\n )\n ).filter((el): el is HTMLElement => el instanceof HTMLElement);\n\n const focused = document.activeElement as HTMLElement;\n const currentIndex = items.findIndex((item) => item === focused);\n\n let nextIndex = 0;\n if (event.key === 'ArrowDown') {\n nextIndex =\n currentIndex === -1 ? 0 : (currentIndex + 1) % items.length;\n } else {\n nextIndex =\n currentIndex === -1\n ? items.length - 1\n : (currentIndex - 1 + items.length) % items.length;\n }\n items[nextIndex]?.focus();\n }\n };\n\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleArrowKeys);\n }\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleArrowKeys);\n };\n }, [open]);\n\n useEffect(() => {\n if (propValue) {\n setValue(propValue);\n const label = findLabelForValue(children, propValue);\n if (label) store.setState({ selectedLabel: label });\n }\n }, [propValue]);\n\n const sizeClasses = SIZE_CLASSES[size];\n\n return (\n <div className=\"w-full\">\n {/* Label */}\n {label && (\n <label\n htmlFor={selectId}\n className={cn('block font-bold text-text-900 mb-1.5', sizeClasses)}\n >\n {label}\n </label>\n )}\n\n {/* Select Container */}\n <div className={cn('relative', sizeClasses)} ref={selectRef}>\n {injectStore(children, store, size, selectId)}\n </div>\n\n {/* Helper Text or Error Message */}\n <div className=\"mt-1.5 gap-1.5\">\n {helperText && <p className=\"text-sm text-text-500\">{helperText}</p>}\n {errorMessage && (\n <p className=\"flex gap-1 items-center text-sm text-indicator-error\">\n <WarningCircle size={16} /> {errorMessage}\n </p>\n )}\n </div>\n </div>\n );\n};\n\nconst SelectValue = ({\n placeholder,\n store: externalStore,\n}: {\n placeholder?: string;\n store?: SelectStoreApi;\n}) => {\n const store = useSelectStore(externalStore);\n\n const selectedLabel = useStore(store, (s) => s.selectedLabel);\n const value = useStore(store, (s) => s.value);\n return (\n <span className=\"text-inherit\">\n {selectedLabel || placeholder || value}\n </span>\n );\n};\n\ninterface SelectTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n invalid?: boolean;\n variant?: 'outlined' | 'underlined' | 'rounded';\n store?: SelectStoreApi;\n size?: 'small' | 'medium' | 'large' | 'extra-large';\n selectId?: string;\n}\n\nconst SelectTrigger = forwardRef<HTMLButtonElement, SelectTriggerProps>(\n (\n {\n className,\n invalid = false,\n variant = 'outlined',\n store: externalStore,\n disabled,\n size = 'medium',\n selectId,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const open = useStore(store, (s) => s.open);\n const toggleOpen = () => store.setState({ open: !open });\n\n const variantClasses = VARIANT_CLASSES[variant];\n const heightClasses = HEIGHT_CLASSES[size];\n const paddingClasses = PADDING_CLASSES[size];\n\n return (\n <button\n ref={ref}\n id={selectId}\n className={`\n flex min-w-[220px] w-full items-center justify-between border-border-300\n ${heightClasses} ${paddingClasses}\n ${invalid && `${variant == 'underlined' ? 'border-b-2' : 'border-2'} border-indicator-error text-text-600`}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${!invalid && !disabled ? 'text-text-700' : ''}\n ${variantClasses}\n ${className}\n `}\n onClick={toggleOpen}\n aria-expanded={open}\n aria-haspopup=\"listbox\"\n aria-controls={open ? 'select-content' : undefined}\n {...props}\n >\n {props.children}\n <CaretDown\n className={cn(\n 'h-[1em] w-[1em] opacity-50 transition-transform',\n open ? 'rotate-180' : ''\n )}\n />\n </button>\n );\n }\n);\nSelectTrigger.displayName = 'SelectTrigger';\n\ninterface SelectContentProps extends HTMLAttributes<HTMLDivElement> {\n className?: string;\n align?: 'start' | 'center' | 'end';\n side?: 'top' | 'right' | 'bottom' | 'left';\n store?: SelectStoreApi;\n}\n\nconst SelectContent = forwardRef<HTMLDivElement, SelectContentProps>(\n (\n {\n children,\n className,\n align = 'start',\n side = 'bottom',\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n\n const open = useStore(store, (s) => s.open);\n if (!open) return null;\n\n const getPositionClasses = () =>\n `w-full min-w-full absolute ${SIDE_CLASSES[side]} ${ALIGN_CLASSES[align]}`;\n\n return (\n <div\n role=\"menu\"\n ref={ref}\n className={cn(\n 'bg-background z-50 min-w-[210px] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md border-border-100',\n getPositionClasses(),\n className\n )}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\nSelectContent.displayName = 'SelectContent';\n\ninterface SelectItemProps extends HTMLAttributes<HTMLDivElement> {\n value: string;\n disabled?: boolean;\n store?: SelectStoreApi;\n}\n\nconst SelectItem = forwardRef<HTMLDivElement, SelectItemProps>(\n (\n {\n className,\n children,\n value,\n disabled = false,\n store: externalStore,\n ...props\n },\n ref\n ) => {\n const store = useSelectStore(externalStore);\n const {\n value: selectedValue,\n setValue,\n setOpen,\n setSelectedLabel,\n onValueChange,\n } = useStore(store, (s) => s);\n\n const handleClick = (\n e: MouseEvent<HTMLDivElement> | KeyboardEvent<HTMLDivElement>\n ) => {\n const labelNode = getLabelAsNode(children);\n if (!disabled) {\n setValue(value);\n setSelectedLabel(labelNode);\n setOpen(false);\n onValueChange?.(value);\n }\n props.onClick?.(e as MouseEvent<HTMLDivElement>);\n };\n\n return (\n <div\n role=\"menuitem\"\n aria-disabled={disabled}\n ref={ref}\n className={`\n focus-visible:bg-background-50\n relative flex select-none items-center gap-2 rounded-sm p-3 outline-none transition-colors [&>svg]:size-4 [&>svg]:shrink-0\n ${className}\n ${\n disabled\n ? 'cursor-not-allowed text-text-400 pointer-events-none opacity-50'\n : 'cursor-pointer hover:bg-background-50 text-text-700 focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground'\n }\n ${selectedValue === value && 'bg-background-50'}\n `}\n onClick={handleClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') handleClick(e);\n }}\n tabIndex={disabled ? -1 : 0}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n {selectedValue === value && <Check className=\"\" />}\n </span>\n {children}\n </div>\n );\n }\n);\n\nSelectItem.displayName = 'SelectItem';\n\nexport default Select;\nexport { SelectTrigger, SelectContent, SelectItem, SelectValue };\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"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","names":["children","label"]}
@@ -24,6 +24,15 @@ __export(SelectionButton_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(SelectionButton_exports);
26
26
  var import_react = require("react");
27
+
28
+ // src/utils/utils.ts
29
+ var import_clsx = require("clsx");
30
+ var import_tailwind_merge = require("tailwind-merge");
31
+ function cn(...inputs) {
32
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
33
+ }
34
+
35
+ // src/components/SelectionButton/SelectionButton.tsx
27
36
  var import_jsx_runtime = require("react/jsx-runtime");
28
37
  var SelectionButton = (0, import_react.forwardRef)(
29
38
  ({ icon, label, selected = false, className = "", disabled, ...props }, ref) => {
@@ -62,7 +71,7 @@ var SelectionButton = (0, import_react.forwardRef)(
62
71
  {
63
72
  ref,
64
73
  type: "button",
65
- className: `${allClasses} ${className}`,
74
+ className: cn(allClasses, className),
66
75
  disabled,
67
76
  "aria-pressed": selected,
68
77
  ...props,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/SelectionButton/SelectionButton.tsx"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\n\n/**\n * SelectionButton component props interface\n */\ntype SelectionButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * SelectionButton component for Analytica Ensino platforms\n *\n * Um botão com ícone e texto para ações e navegação com estado de seleção.\n * Ideal para filtros, tags, categorias, seleção de tipos, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado\n *\n * @example\n * ```tsx\n * <SelectionButton\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={false}\n * onClick={() => handleSelection()}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <SelectionButton\n * ref={buttonRef}\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={isSelected}\n * onClick={() => setSelected(!isSelected)}\n * />\n * ```\n */\nconst SelectionButton = forwardRef<HTMLButtonElement, SelectionButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'inline-flex',\n 'items-center',\n 'justify-start',\n 'gap-2',\n 'p-4',\n 'rounded-xl',\n 'cursor-pointer',\n 'border',\n 'border-border-50',\n 'bg-background',\n 'text-sm',\n 'text-text-700',\n 'font-bold',\n 'shadow-soft-shadow-1',\n 'hover:bg-background-100',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-indicator-info',\n 'focus-visible:ring-offset-0',\n 'focus-visible:shadow-none',\n 'active:ring-2',\n 'active:ring-primary-950',\n 'active:ring-offset-0',\n 'active:shadow-none',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n ];\n\n const stateClasses = selected\n ? ['ring-primary-950', 'ring-2', 'ring-offset-0', 'shadow-none']\n : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={`${allClasses} ${className}`}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-6 h-6\">{icon}</span>\n <span>{label}</span>\n </button>\n );\n }\n);\n\nSelectionButton.displayName = 'SelectionButton';\n\nexport default SelectionButton;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4D;AAoGtD;AA1CN,IAAM,sBAAkB;AAAA,EACtB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WACjB,CAAC,oBAAoB,UAAU,iBAAiB,aAAa,IAC7D,CAAC;AAEL,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,UAAU,IAAI,SAAS;AAAA,QACrC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,sDAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,4CAAC,UAAM,iBAAM;AAAA;AAAA;AAAA,IACf;AAAA,EAEJ;AACF;AAEA,gBAAgB,cAAc;AAE9B,IAAO,0BAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/SelectionButton/SelectionButton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * SelectionButton component props interface\n */\ntype SelectionButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * SelectionButton component for Analytica Ensino platforms\n *\n * Um botão com ícone e texto para ações e navegação com estado de seleção.\n * Ideal para filtros, tags, categorias, seleção de tipos, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado\n *\n * @example\n * ```tsx\n * <SelectionButton\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={false}\n * onClick={() => handleSelection()}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <SelectionButton\n * ref={buttonRef}\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={isSelected}\n * onClick={() => setSelected(!isSelected)}\n * />\n * ```\n */\nconst SelectionButton = forwardRef<HTMLButtonElement, SelectionButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'inline-flex',\n 'items-center',\n 'justify-start',\n 'gap-2',\n 'p-4',\n 'rounded-xl',\n 'cursor-pointer',\n 'border',\n 'border-border-50',\n 'bg-background',\n 'text-sm',\n 'text-text-700',\n 'font-bold',\n 'shadow-soft-shadow-1',\n 'hover:bg-background-100',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-indicator-info',\n 'focus-visible:ring-offset-0',\n 'focus-visible:shadow-none',\n 'active:ring-2',\n 'active:ring-primary-950',\n 'active:ring-offset-0',\n 'active:shadow-none',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n ];\n\n const stateClasses = selected\n ? ['ring-primary-950', 'ring-2', 'ring-offset-0', 'shadow-none']\n : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(allClasses, className)}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-6 h-6\">{icon}</span>\n <span>{label}</span>\n </button>\n );\n }\n);\n\nSelectionButton.displayName = 'SelectionButton';\n\nexport default SelectionButton;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4D;;;ACA5D,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ADgGM;AA1CN,IAAM,sBAAkB;AAAA,EACtB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WACjB,CAAC,oBAAoB,UAAU,iBAAiB,aAAa,IAC7D,CAAC;AAEL,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,YAAY,SAAS;AAAA,QACnC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,sDAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,4CAAC,UAAM,iBAAM;AAAA;AAAA;AAAA,IACf;AAAA,EAEJ;AACF;AAEA,gBAAgB,cAAc;AAE9B,IAAO,0BAAQ;","names":[]}
@@ -1,5 +1,14 @@
1
1
  // src/components/SelectionButton/SelectionButton.tsx
2
2
  import { forwardRef } from "react";
3
+
4
+ // src/utils/utils.ts
5
+ import { clsx } from "clsx";
6
+ import { twMerge } from "tailwind-merge";
7
+ function cn(...inputs) {
8
+ return twMerge(clsx(inputs));
9
+ }
10
+
11
+ // src/components/SelectionButton/SelectionButton.tsx
3
12
  import { jsx, jsxs } from "react/jsx-runtime";
4
13
  var SelectionButton = forwardRef(
5
14
  ({ icon, label, selected = false, className = "", disabled, ...props }, ref) => {
@@ -38,7 +47,7 @@ var SelectionButton = forwardRef(
38
47
  {
39
48
  ref,
40
49
  type: "button",
41
- className: `${allClasses} ${className}`,
50
+ className: cn(allClasses, className),
42
51
  disabled,
43
52
  "aria-pressed": selected,
44
53
  ...props,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/SelectionButton/SelectionButton.tsx"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\n\n/**\n * SelectionButton component props interface\n */\ntype SelectionButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * SelectionButton component for Analytica Ensino platforms\n *\n * Um botão com ícone e texto para ações e navegação com estado de seleção.\n * Ideal para filtros, tags, categorias, seleção de tipos, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado\n *\n * @example\n * ```tsx\n * <SelectionButton\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={false}\n * onClick={() => handleSelection()}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <SelectionButton\n * ref={buttonRef}\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={isSelected}\n * onClick={() => setSelected(!isSelected)}\n * />\n * ```\n */\nconst SelectionButton = forwardRef<HTMLButtonElement, SelectionButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'inline-flex',\n 'items-center',\n 'justify-start',\n 'gap-2',\n 'p-4',\n 'rounded-xl',\n 'cursor-pointer',\n 'border',\n 'border-border-50',\n 'bg-background',\n 'text-sm',\n 'text-text-700',\n 'font-bold',\n 'shadow-soft-shadow-1',\n 'hover:bg-background-100',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-indicator-info',\n 'focus-visible:ring-offset-0',\n 'focus-visible:shadow-none',\n 'active:ring-2',\n 'active:ring-primary-950',\n 'active:ring-offset-0',\n 'active:shadow-none',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n ];\n\n const stateClasses = selected\n ? ['ring-primary-950', 'ring-2', 'ring-offset-0', 'shadow-none']\n : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={`${allClasses} ${className}`}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-6 h-6\">{icon}</span>\n <span>{label}</span>\n </button>\n );\n }\n);\n\nSelectionButton.displayName = 'SelectionButton';\n\nexport default SelectionButton;\n"],"mappings":";AAAA,SAA0C,kBAAkB;AAoGtD,SAQE,KARF;AA1CN,IAAM,kBAAkB;AAAA,EACtB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WACjB,CAAC,oBAAoB,UAAU,iBAAiB,aAAa,IAC7D,CAAC;AAEL,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,UAAU,IAAI,SAAS;AAAA,QACrC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,8BAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,oBAAC,UAAM,iBAAM;AAAA;AAAA;AAAA,IACf;AAAA,EAEJ;AACF;AAEA,gBAAgB,cAAc;AAE9B,IAAO,0BAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/SelectionButton/SelectionButton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { ButtonHTMLAttributes, ReactNode, forwardRef } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * SelectionButton component props interface\n */\ntype SelectionButtonProps = {\n /** Ícone a ser exibido no botão */\n icon: ReactNode;\n /** Texto/label a ser exibido ao lado do ícone */\n label: string;\n /** Estado de seleção do botão */\n selected?: boolean;\n /** Additional CSS classes to apply */\n className?: string;\n} & ButtonHTMLAttributes<HTMLButtonElement>;\n\n/**\n * SelectionButton component for Analytica Ensino platforms\n *\n * Um botão com ícone e texto para ações e navegação com estado de seleção.\n * Ideal para filtros, tags, categorias, seleção de tipos, etc.\n * Suporta forwardRef para acesso programático ao elemento DOM.\n *\n * @param icon - O ícone a ser exibido no botão\n * @param label - O texto/label a ser exibido\n * @param selected - Estado de seleção do botão\n * @param className - Classes CSS adicionais\n * @param props - Todos os outros atributos HTML padrão de button\n * @returns Um elemento button estilizado\n *\n * @example\n * ```tsx\n * <SelectionButton\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={false}\n * onClick={() => handleSelection()}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Usando ref para foco programático\n * const buttonRef = useRef<HTMLButtonElement>(null);\n *\n * const handleFocus = () => {\n * buttonRef.current?.focus();\n * };\n *\n * <SelectionButton\n * ref={buttonRef}\n * icon={<TagIcon />}\n * label=\"Categoria\"\n * selected={isSelected}\n * onClick={() => setSelected(!isSelected)}\n * />\n * ```\n */\nconst SelectionButton = forwardRef<HTMLButtonElement, SelectionButtonProps>(\n (\n { icon, label, selected = false, className = '', disabled, ...props },\n ref\n ) => {\n // Classes base para todos os estados\n const baseClasses = [\n 'inline-flex',\n 'items-center',\n 'justify-start',\n 'gap-2',\n 'p-4',\n 'rounded-xl',\n 'cursor-pointer',\n 'border',\n 'border-border-50',\n 'bg-background',\n 'text-sm',\n 'text-text-700',\n 'font-bold',\n 'shadow-soft-shadow-1',\n 'hover:bg-background-100',\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-indicator-info',\n 'focus-visible:ring-offset-0',\n 'focus-visible:shadow-none',\n 'active:ring-2',\n 'active:ring-primary-950',\n 'active:ring-offset-0',\n 'active:shadow-none',\n 'disabled:opacity-50',\n 'disabled:cursor-not-allowed',\n ];\n\n const stateClasses = selected\n ? ['ring-primary-950', 'ring-2', 'ring-offset-0', 'shadow-none']\n : [];\n\n const allClasses = [...baseClasses, ...stateClasses].join(' ');\n\n return (\n <button\n ref={ref}\n type=\"button\"\n className={cn(allClasses, className)}\n disabled={disabled}\n aria-pressed={selected}\n {...props}\n >\n <span className=\"flex items-center justify-center w-6 h-6\">{icon}</span>\n <span>{label}</span>\n </button>\n );\n }\n);\n\nSelectionButton.displayName = 'SelectionButton';\n\nexport default SelectionButton;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAA0C,kBAAkB;;;ACA5D,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ADgGM,SAQE,KARF;AA1CN,IAAM,kBAAkB;AAAA,EACtB,CACE,EAAE,MAAM,OAAO,WAAW,OAAO,YAAY,IAAI,UAAU,GAAG,MAAM,GACpE,QACG;AAEH,UAAM,cAAc;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,eAAe,WACjB,CAAC,oBAAoB,UAAU,iBAAiB,aAAa,IAC7D,CAAC;AAEL,UAAM,aAAa,CAAC,GAAG,aAAa,GAAG,YAAY,EAAE,KAAK,GAAG;AAE7D,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,MAAK;AAAA,QACL,WAAW,GAAG,YAAY,SAAS;AAAA,QACnC;AAAA,QACA,gBAAc;AAAA,QACb,GAAG;AAAA,QAEJ;AAAA,8BAAC,UAAK,WAAU,4CAA4C,gBAAK;AAAA,UACjE,oBAAC,UAAM,iBAAM;AAAA;AAAA;AAAA,IACf;AAAA,EAEJ;AACF;AAEA,gBAAgB,cAAc;AAE9B,IAAO,0BAAQ;","names":[]}
@@ -31,6 +31,15 @@ __export(Skeleton_exports, {
31
31
  });
32
32
  module.exports = __toCommonJS(Skeleton_exports);
33
33
  var import_react = require("react");
34
+
35
+ // src/utils/utils.ts
36
+ var import_clsx = require("clsx");
37
+ var import_tailwind_merge = require("tailwind-merge");
38
+ function cn(...inputs) {
39
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
40
+ }
41
+
42
+ // src/components/Skeleton/Skeleton.tsx
34
43
  var import_jsx_runtime = require("react/jsx-runtime");
35
44
  var SKELETON_ANIMATION_CLASSES = {
36
45
  pulse: "animate-pulse",
@@ -72,12 +81,12 @@ var Skeleton = (0, import_react.forwardRef)(
72
81
  "div",
73
82
  {
74
83
  ref,
75
- className: `flex flex-col ${spacingClass} ${className}`,
84
+ className: cn("flex flex-col", spacingClass, className),
76
85
  ...props,
77
86
  children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
87
  "div",
79
88
  {
80
- className: `${variantClass} ${animationClass}`,
89
+ className: cn(variantClass, animationClass),
81
90
  style: index === lines - 1 ? { width: "60%" } : void 0
82
91
  },
83
92
  index
@@ -89,7 +98,7 @@ var Skeleton = (0, import_react.forwardRef)(
89
98
  "div",
90
99
  {
91
100
  ref,
92
- className: `${variantClass} ${animationClass} ${className}`,
101
+ className: cn(variantClass, animationClass, className),
93
102
  style,
94
103
  ...props,
95
104
  children
@@ -117,7 +126,10 @@ var SkeletonCard = (0, import_react.forwardRef)(
117
126
  "div",
118
127
  {
119
128
  ref,
120
- className: `w-full p-4 bg-background border border-border-200 rounded-lg ${className}`,
129
+ className: cn(
130
+ "w-full p-4 bg-background border border-border-200 rounded-lg",
131
+ className
132
+ ),
121
133
  ...props,
122
134
  children: [
123
135
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start space-x-3", children: [
@@ -146,7 +158,7 @@ var SkeletonList = (0, import_react.forwardRef)(
146
158
  className = "",
147
159
  ...props
148
160
  }, ref) => {
149
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref, className: `space-y-3 ${className}`, ...props, children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start space-x-3 p-3", children: [
161
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref, className: cn("space-y-3", className), ...props, children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start space-x-3 p-3", children: [
150
162
  showAvatar && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonCircle, { width: 32, height: 32 }),
151
163
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex-1 space-y-2", children: [
152
164
  showTitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SkeletonText, { width: "40%", height: 16 }),
@@ -157,7 +169,7 @@ var SkeletonList = (0, import_react.forwardRef)(
157
169
  );
158
170
  var SkeletonTable = (0, import_react.forwardRef)(
159
171
  ({ rows = 5, columns = 4, showHeader = true, className = "", ...props }, ref) => {
160
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref, className: `w-full ${className}`, ...props, children: [
172
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref, className: cn("w-full", className), ...props, children: [
161
173
  showHeader && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex space-x-2 mb-3", children: Array.from({ length: columns }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
162
174
  SkeletonText,
163
175
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Skeleton/Skeleton.tsx"],"sourcesContent":["import { forwardRef, HTMLAttributes, CSSProperties } from 'react';\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded';\n width?: string | number;\n height?: string | number;\n animation?: 'pulse' | 'none';\n lines?: number;\n spacing?: 'none' | 'small' | 'medium' | 'large';\n}\n\nconst SKELETON_ANIMATION_CLASSES = {\n pulse: 'animate-pulse',\n none: '',\n};\n\nconst SKELETON_VARIANT_CLASSES = {\n text: 'h-4 bg-background-200 rounded',\n circular: 'bg-background-200 rounded-full',\n rectangular: 'bg-background-200',\n rounded: 'bg-background-200 rounded-lg',\n};\n\nconst SPACING_CLASSES = {\n none: '',\n small: 'space-y-1',\n medium: 'space-y-2',\n large: 'space-y-3',\n};\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(\n (\n {\n variant = 'text',\n width,\n height,\n animation = 'pulse',\n lines = 1,\n spacing = 'none',\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n const animationClass = SKELETON_ANIMATION_CLASSES[animation];\n const variantClass = SKELETON_VARIANT_CLASSES[variant];\n const spacingClass = SPACING_CLASSES[spacing];\n\n const style: CSSProperties = {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n };\n\n // Se for múltiplas linhas de texto\n if (variant === 'text' && lines > 1) {\n return (\n <div\n ref={ref}\n className={`flex flex-col ${spacingClass} ${className}`}\n {...props}\n >\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={`${variantClass} ${animationClass}`}\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </div>\n );\n }\n\n // Se for um único elemento\n return (\n <div\n ref={ref}\n className={`${variantClass} ${animationClass} ${className}`}\n style={style}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\n// Componentes específicos para casos comuns\nconst SkeletonText = forwardRef<HTMLDivElement, Omit<SkeletonProps, 'variant'>>(\n (props, ref) => <Skeleton ref={ref} variant=\"text\" {...props} />\n);\n\nconst SkeletonCircle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"circular\" {...props} />);\n\nconst SkeletonRectangle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rectangular\" {...props} />);\n\nconst SkeletonRounded = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rounded\" {...props} />);\n\n// Componente para card skeleton\ninterface SkeletonCardProps extends HTMLAttributes<HTMLDivElement> {\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n showActions?: boolean;\n lines?: number;\n}\n\nconst SkeletonCard = forwardRef<HTMLDivElement, SkeletonCardProps>(\n (\n {\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n showActions = true,\n lines = 2,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={`w-full p-4 bg-background border border-border-200 rounded-lg ${className}`}\n {...props}\n >\n <div className=\"flex items-start space-x-3\">\n {showAvatar && <SkeletonCircle width={40} height={40} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"60%\" height={20} />}\n\n {showDescription && <SkeletonText lines={lines} spacing=\"small\" />}\n </div>\n </div>\n\n {showActions && (\n <div className=\"flex justify-end space-x-2 mt-4\">\n <SkeletonRectangle width={80} height={32} />\n <SkeletonRectangle width={80} height={32} />\n </div>\n )}\n </div>\n );\n }\n);\n\n// Componente para lista skeleton\ninterface SkeletonListProps extends HTMLAttributes<HTMLDivElement> {\n items?: number;\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n lines?: number;\n}\n\nconst SkeletonList = forwardRef<HTMLDivElement, SkeletonListProps>(\n (\n {\n items = 3,\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n lines = 1,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div ref={ref} className={`space-y-3 ${className}`} {...props}>\n {Array.from({ length: items }, (_, index) => (\n <div key={index} className=\"flex items-start space-x-3 p-3\">\n {showAvatar && <SkeletonCircle width={32} height={32} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"40%\" height={16} />}\n\n {showDescription && (\n <SkeletonText lines={lines} spacing=\"small\" />\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n);\n\n// Componente para tabela skeleton\ninterface SkeletonTableProps extends HTMLAttributes<HTMLDivElement> {\n rows?: number;\n columns?: number;\n showHeader?: boolean;\n}\n\nconst SkeletonTable = forwardRef<HTMLDivElement, SkeletonTableProps>(\n (\n { rows = 5, columns = 4, showHeader = true, className = '', ...props },\n ref\n ) => {\n return (\n <div ref={ref} className={`w-full ${className}`} {...props}>\n {showHeader && (\n <div className=\"flex space-x-2 mb-3\">\n {Array.from({ length: columns }, (_, index) => (\n <SkeletonText\n key={index}\n width={`${100 / columns}%`}\n height={20}\n />\n ))}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div key={rowIndex} className=\"flex space-x-2\">\n {Array.from({ length: columns }, (_, colIndex) => (\n <SkeletonText\n key={colIndex}\n width={`${100 / columns}%`}\n height={16}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nexport {\n Skeleton,\n SkeletonText,\n SkeletonCircle,\n SkeletonRectangle,\n SkeletonRounded,\n SkeletonCard,\n SkeletonList,\n SkeletonTable,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0D;AA+D9C;AApDZ,IAAM,6BAA6B;AAAA,EACjC,OAAO;AAAA,EACP,MAAM;AACR;AAEA,IAAM,2BAA2B;AAAA,EAC/B,MAAM;AAAA,EACN,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AACX;AAEA,IAAM,kBAAkB;AAAA,EACtB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AACT;AAEA,IAAM,eAAW;AAAA,EACf,CACE;AAAA,IACE,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,YAAY;AAAA,IACZ;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,iBAAiB,2BAA2B,SAAS;AAC3D,UAAM,eAAe,yBAAyB,OAAO;AACrD,UAAM,eAAe,gBAAgB,OAAO;AAE5C,UAAM,QAAuB;AAAA,MAC3B,OAAO,OAAO,UAAU,WAAW,GAAG,KAAK,OAAO;AAAA,MAClD,QAAQ,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAAA,IACvD;AAGA,QAAI,YAAY,UAAU,QAAQ,GAAG;AACnC,aACE;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAW,iBAAiB,YAAY,IAAI,SAAS;AAAA,UACpD,GAAG;AAAA,UAEH,gBAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UACjC;AAAA,YAAC;AAAA;AAAA,cAEC,WAAW,GAAG,YAAY,IAAI,cAAc;AAAA,cAC5C,OAAO,UAAU,QAAQ,IAAI,EAAE,OAAO,MAAM,IAAI;AAAA;AAAA,YAF3C;AAAA,UAGP,CACD;AAAA;AAAA,MACH;AAAA,IAEJ;AAGA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,GAAG,YAAY,IAAI,cAAc,IAAI,SAAS;AAAA,QACzD;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAGA,IAAM,mBAAe;AAAA,EACnB,CAAC,OAAO,QAAQ,4CAAC,YAAS,KAAU,SAAQ,QAAQ,GAAG,OAAO;AAChE;AAEA,IAAM,qBAAiB,yBAGrB,CAAC,OAAO,QAAQ,4CAAC,YAAS,KAAU,SAAQ,YAAY,GAAG,OAAO,CAAE;AAEtE,IAAM,wBAAoB,yBAGxB,CAAC,OAAO,QAAQ,4CAAC,YAAS,KAAU,SAAQ,eAAe,GAAG,OAAO,CAAE;AAEzE,IAAM,sBAAkB,yBAGtB,CAAC,OAAO,QAAQ,4CAAC,YAAS,KAAU,SAAQ,WAAW,GAAG,OAAO,CAAE;AAWrE,IAAM,mBAAe;AAAA,EACnB,CACE;AAAA,IACE,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,cAAc;AAAA,IACd,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,gEAAgE,SAAS;AAAA,QACnF,GAAG;AAAA,QAEJ;AAAA,uDAAC,SAAI,WAAU,8BACZ;AAAA,0BAAc,4CAAC,kBAAe,OAAO,IAAI,QAAQ,IAAI;AAAA,YAEtD,6CAAC,SAAI,WAAU,oBACZ;AAAA,2BAAa,4CAAC,gBAAa,OAAM,OAAM,QAAQ,IAAI;AAAA,cAEnD,mBAAmB,4CAAC,gBAAa,OAAc,SAAQ,SAAQ;AAAA,eAClE;AAAA,aACF;AAAA,UAEC,eACC,6CAAC,SAAI,WAAU,mCACb;AAAA,wDAAC,qBAAkB,OAAO,IAAI,QAAQ,IAAI;AAAA,YAC1C,4CAAC,qBAAkB,OAAO,IAAI,QAAQ,IAAI;AAAA,aAC5C;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAWA,IAAM,mBAAe;AAAA,EACnB,CACE;AAAA,IACE,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,GACA,QACG;AACH,WACE,4CAAC,SAAI,KAAU,WAAW,aAAa,SAAS,IAAK,GAAG,OACrD,gBAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,UACjC,6CAAC,SAAgB,WAAU,kCACxB;AAAA,oBAAc,4CAAC,kBAAe,OAAO,IAAI,QAAQ,IAAI;AAAA,MAEtD,6CAAC,SAAI,WAAU,oBACZ;AAAA,qBAAa,4CAAC,gBAAa,OAAM,OAAM,QAAQ,IAAI;AAAA,QAEnD,mBACC,4CAAC,gBAAa,OAAc,SAAQ,SAAQ;AAAA,SAEhD;AAAA,SATQ,KAUV,CACD,GACH;AAAA,EAEJ;AACF;AASA,IAAM,oBAAgB;AAAA,EACpB,CACE,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,MAAM,YAAY,IAAI,GAAG,MAAM,GACrE,QACG;AACH,WACE,6CAAC,SAAI,KAAU,WAAW,UAAU,SAAS,IAAK,GAAG,OAClD;AAAA,oBACC,4CAAC,SAAI,WAAU,uBACZ,gBAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAAC,GAAG,UACnC;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,GAAG,MAAM,OAAO;AAAA,UACvB,QAAQ;AAAA;AAAA,QAFH;AAAA,MAGP,CACD,GACH;AAAA,MAGF,4CAAC,SAAI,WAAU,aACZ,gBAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,aAChC,4CAAC,SAAmB,WAAU,kBAC3B,gBAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG,CAACA,IAAG,aACnC;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,GAAG,MAAM,OAAO;AAAA,UACvB,QAAQ;AAAA;AAAA,QAFH;AAAA,MAGP,CACD,KAPO,QAQV,CACD,GACH;AAAA,OACF;AAAA,EAEJ;AACF;","names":["_"]}
1
+ {"version":3,"sources":["../../src/components/Skeleton/Skeleton.tsx","../../src/utils/utils.ts"],"sourcesContent":["import { forwardRef, HTMLAttributes, CSSProperties } from 'react';\nimport { cn } from '../../utils/utils';\n\ninterface SkeletonProps extends HTMLAttributes<HTMLDivElement> {\n variant?: 'text' | 'circular' | 'rectangular' | 'rounded';\n width?: string | number;\n height?: string | number;\n animation?: 'pulse' | 'none';\n lines?: number;\n spacing?: 'none' | 'small' | 'medium' | 'large';\n}\n\nconst SKELETON_ANIMATION_CLASSES = {\n pulse: 'animate-pulse',\n none: '',\n};\n\nconst SKELETON_VARIANT_CLASSES = {\n text: 'h-4 bg-background-200 rounded',\n circular: 'bg-background-200 rounded-full',\n rectangular: 'bg-background-200',\n rounded: 'bg-background-200 rounded-lg',\n};\n\nconst SPACING_CLASSES = {\n none: '',\n small: 'space-y-1',\n medium: 'space-y-2',\n large: 'space-y-3',\n};\n\nconst Skeleton = forwardRef<HTMLDivElement, SkeletonProps>(\n (\n {\n variant = 'text',\n width,\n height,\n animation = 'pulse',\n lines = 1,\n spacing = 'none',\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n const animationClass = SKELETON_ANIMATION_CLASSES[animation];\n const variantClass = SKELETON_VARIANT_CLASSES[variant];\n const spacingClass = SPACING_CLASSES[spacing];\n\n const style: CSSProperties = {\n width: typeof width === 'number' ? `${width}px` : width,\n height: typeof height === 'number' ? `${height}px` : height,\n };\n\n // Se for múltiplas linhas de texto\n if (variant === 'text' && lines > 1) {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col', spacingClass, className)}\n {...props}\n >\n {Array.from({ length: lines }, (_, index) => (\n <div\n key={index}\n className={cn(variantClass, animationClass)}\n style={index === lines - 1 ? { width: '60%' } : undefined}\n />\n ))}\n </div>\n );\n }\n\n // Se for um único elemento\n return (\n <div\n ref={ref}\n className={cn(variantClass, animationClass, className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\n// Componentes específicos para casos comuns\nconst SkeletonText = forwardRef<HTMLDivElement, Omit<SkeletonProps, 'variant'>>(\n (props, ref) => <Skeleton ref={ref} variant=\"text\" {...props} />\n);\n\nconst SkeletonCircle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"circular\" {...props} />);\n\nconst SkeletonRectangle = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rectangular\" {...props} />);\n\nconst SkeletonRounded = forwardRef<\n HTMLDivElement,\n Omit<SkeletonProps, 'variant'>\n>((props, ref) => <Skeleton ref={ref} variant=\"rounded\" {...props} />);\n\n// Componente para card skeleton\ninterface SkeletonCardProps extends HTMLAttributes<HTMLDivElement> {\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n showActions?: boolean;\n lines?: number;\n}\n\nconst SkeletonCard = forwardRef<HTMLDivElement, SkeletonCardProps>(\n (\n {\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n showActions = true,\n lines = 2,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'w-full p-4 bg-background border border-border-200 rounded-lg',\n className\n )}\n {...props}\n >\n <div className=\"flex items-start space-x-3\">\n {showAvatar && <SkeletonCircle width={40} height={40} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"60%\" height={20} />}\n\n {showDescription && <SkeletonText lines={lines} spacing=\"small\" />}\n </div>\n </div>\n\n {showActions && (\n <div className=\"flex justify-end space-x-2 mt-4\">\n <SkeletonRectangle width={80} height={32} />\n <SkeletonRectangle width={80} height={32} />\n </div>\n )}\n </div>\n );\n }\n);\n\n// Componente para lista skeleton\ninterface SkeletonListProps extends HTMLAttributes<HTMLDivElement> {\n items?: number;\n showAvatar?: boolean;\n showTitle?: boolean;\n showDescription?: boolean;\n lines?: number;\n}\n\nconst SkeletonList = forwardRef<HTMLDivElement, SkeletonListProps>(\n (\n {\n items = 3,\n showAvatar = true,\n showTitle = true,\n showDescription = true,\n lines = 1,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('space-y-3', className)} {...props}>\n {Array.from({ length: items }, (_, index) => (\n <div key={index} className=\"flex items-start space-x-3 p-3\">\n {showAvatar && <SkeletonCircle width={32} height={32} />}\n\n <div className=\"flex-1 space-y-2\">\n {showTitle && <SkeletonText width=\"40%\" height={16} />}\n\n {showDescription && (\n <SkeletonText lines={lines} spacing=\"small\" />\n )}\n </div>\n </div>\n ))}\n </div>\n );\n }\n);\n\n// Componente para tabela skeleton\ninterface SkeletonTableProps extends HTMLAttributes<HTMLDivElement> {\n rows?: number;\n columns?: number;\n showHeader?: boolean;\n}\n\nconst SkeletonTable = forwardRef<HTMLDivElement, SkeletonTableProps>(\n (\n { rows = 5, columns = 4, showHeader = true, className = '', ...props },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('w-full', className)} {...props}>\n {showHeader && (\n <div className=\"flex space-x-2 mb-3\">\n {Array.from({ length: columns }, (_, index) => (\n <SkeletonText\n key={index}\n width={`${100 / columns}%`}\n height={20}\n />\n ))}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {Array.from({ length: rows }, (_, rowIndex) => (\n <div key={rowIndex} className=\"flex space-x-2\">\n {Array.from({ length: columns }, (_, colIndex) => (\n <SkeletonText\n key={colIndex}\n width={`${100 / columns}%`}\n height={16}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nexport {\n Skeleton,\n SkeletonText,\n SkeletonCircle,\n SkeletonRectangle,\n SkeletonRounded,\n SkeletonCard,\n SkeletonList,\n SkeletonTable,\n};\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"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","names":["_"]}
@@ -1,5 +1,14 @@
1
1
  // src/components/Skeleton/Skeleton.tsx
2
2
  import { forwardRef } from "react";
3
+
4
+ // src/utils/utils.ts
5
+ import { clsx } from "clsx";
6
+ import { twMerge } from "tailwind-merge";
7
+ function cn(...inputs) {
8
+ return twMerge(clsx(inputs));
9
+ }
10
+
11
+ // src/components/Skeleton/Skeleton.tsx
3
12
  import { jsx, jsxs } from "react/jsx-runtime";
4
13
  var SKELETON_ANIMATION_CLASSES = {
5
14
  pulse: "animate-pulse",
@@ -41,12 +50,12 @@ var Skeleton = forwardRef(
41
50
  "div",
42
51
  {
43
52
  ref,
44
- className: `flex flex-col ${spacingClass} ${className}`,
53
+ className: cn("flex flex-col", spacingClass, className),
45
54
  ...props,
46
55
  children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ jsx(
47
56
  "div",
48
57
  {
49
- className: `${variantClass} ${animationClass}`,
58
+ className: cn(variantClass, animationClass),
50
59
  style: index === lines - 1 ? { width: "60%" } : void 0
51
60
  },
52
61
  index
@@ -58,7 +67,7 @@ var Skeleton = forwardRef(
58
67
  "div",
59
68
  {
60
69
  ref,
61
- className: `${variantClass} ${animationClass} ${className}`,
70
+ className: cn(variantClass, animationClass, className),
62
71
  style,
63
72
  ...props,
64
73
  children
@@ -86,7 +95,10 @@ var SkeletonCard = forwardRef(
86
95
  "div",
87
96
  {
88
97
  ref,
89
- className: `w-full p-4 bg-background border border-border-200 rounded-lg ${className}`,
98
+ className: cn(
99
+ "w-full p-4 bg-background border border-border-200 rounded-lg",
100
+ className
101
+ ),
90
102
  ...props,
91
103
  children: [
92
104
  /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3", children: [
@@ -115,7 +127,7 @@ var SkeletonList = forwardRef(
115
127
  className = "",
116
128
  ...props
117
129
  }, ref) => {
118
- return /* @__PURE__ */ jsx("div", { ref, className: `space-y-3 ${className}`, ...props, children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 p-3", children: [
130
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("space-y-3", className), ...props, children: Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 p-3", children: [
119
131
  showAvatar && /* @__PURE__ */ jsx(SkeletonCircle, { width: 32, height: 32 }),
120
132
  /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
121
133
  showTitle && /* @__PURE__ */ jsx(SkeletonText, { width: "40%", height: 16 }),
@@ -126,7 +138,7 @@ var SkeletonList = forwardRef(
126
138
  );
127
139
  var SkeletonTable = forwardRef(
128
140
  ({ rows = 5, columns = 4, showHeader = true, className = "", ...props }, ref) => {
129
- return /* @__PURE__ */ jsxs("div", { ref, className: `w-full ${className}`, ...props, children: [
141
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("w-full", className), ...props, children: [
130
142
  showHeader && /* @__PURE__ */ jsx("div", { className: "flex space-x-2 mb-3", children: Array.from({ length: columns }, (_, index) => /* @__PURE__ */ jsx(
131
143
  SkeletonText,
132
144
  {