@spear-ai/spectral 1.15.5 → 1.15.6

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 (265) hide show
  1. package/dist/Accordion.d.ts.map +1 -1
  2. package/dist/Accordion.js +1 -1
  3. package/dist/Accordion.js.map +1 -1
  4. package/dist/Alert/AlertBase.d.ts.map +1 -1
  5. package/dist/Alert/AlertBase.js.map +1 -1
  6. package/dist/Alert.js.map +1 -1
  7. package/dist/Avatar.js.map +1 -1
  8. package/dist/Badge.d.ts.map +1 -1
  9. package/dist/Badge.js.map +1 -1
  10. package/dist/Button.d.ts.map +1 -1
  11. package/dist/Button.js +6 -6
  12. package/dist/Button.js.map +1 -1
  13. package/dist/ButtonGroup/ButtonGroupButton.js.map +1 -1
  14. package/dist/ButtonGroup.d.ts.map +1 -1
  15. package/dist/ButtonGroup.js +1 -1
  16. package/dist/ButtonGroup.js.map +1 -1
  17. package/dist/ButtonIcon.js +3 -3
  18. package/dist/ButtonIcon.js.map +1 -1
  19. package/dist/ButtonIconSlideout.js +5 -5
  20. package/dist/ButtonIconSlideout.js.map +1 -1
  21. package/dist/Checkbox/CheckboxBase.js.map +1 -1
  22. package/dist/Checkbox.js.map +1 -1
  23. package/dist/Combobox.js.map +1 -1
  24. package/dist/ControlGroup/ControlGroupSelect.js.map +1 -1
  25. package/dist/ControlGroup.d.ts.map +1 -1
  26. package/dist/ControlGroup.js +1 -1
  27. package/dist/ControlGroup.js.map +1 -1
  28. package/dist/DataCard/Card.d.ts.map +1 -1
  29. package/dist/DataCard/Card.js.map +1 -1
  30. package/dist/DataCard.js.map +1 -1
  31. package/dist/DateTimePicker/Calendar.js.map +1 -1
  32. package/dist/DateTimePicker/DateTimeDisplayInput.js.map +1 -1
  33. package/dist/DateTimePicker/TimePeriodSelect.js.map +1 -1
  34. package/dist/DateTimePicker/TimePicker.js.map +1 -1
  35. package/dist/DateTimePicker.js.map +1 -1
  36. package/dist/Dialog.d.ts.map +1 -1
  37. package/dist/Dialog.js +2 -2
  38. package/dist/Dialog.js.map +1 -1
  39. package/dist/Drawer.js +3 -3
  40. package/dist/Drawer.js.map +1 -1
  41. package/dist/DropdownMenu.js.map +1 -1
  42. package/dist/FormFieldMessage.d.ts.map +1 -1
  43. package/dist/FormFieldMessage.js.map +1 -1
  44. package/dist/HoverCard.d.ts.map +1 -1
  45. package/dist/HoverCard.js.map +1 -1
  46. package/dist/Icons/AdjustmentsIcon.d.ts.map +1 -1
  47. package/dist/Icons/AdjustmentsIcon.js.map +1 -1
  48. package/dist/Icons/AnalyzeIcon.d.ts.map +1 -1
  49. package/dist/Icons/AnalyzeIcon.js.map +1 -1
  50. package/dist/Icons/AnnotationsIcon.d.ts.map +1 -1
  51. package/dist/Icons/AnnotationsIcon.js.map +1 -1
  52. package/dist/Icons/ApprovedIcon.d.ts.map +1 -1
  53. package/dist/Icons/ApprovedIcon.js.map +1 -1
  54. package/dist/Icons/ArrowDownIcon.d.ts.map +1 -1
  55. package/dist/Icons/ArrowDownIcon.js.map +1 -1
  56. package/dist/Icons/ArrowUpIcon.d.ts.map +1 -1
  57. package/dist/Icons/ArrowUpIcon.js.map +1 -1
  58. package/dist/Icons/BoxToolIcon.d.ts.map +1 -1
  59. package/dist/Icons/BoxToolIcon.js.map +1 -1
  60. package/dist/Icons/CalendarIcon.d.ts.map +1 -1
  61. package/dist/Icons/CalendarIcon.js.map +1 -1
  62. package/dist/Icons/CheckCircleIcon.d.ts.map +1 -1
  63. package/dist/Icons/CheckCircleIcon.js.map +1 -1
  64. package/dist/Icons/CheckSquareIcon.d.ts.map +1 -1
  65. package/dist/Icons/CheckSquareIcon.js.map +1 -1
  66. package/dist/Icons/CheckmarkIcon.d.ts.map +1 -1
  67. package/dist/Icons/CheckmarkIcon.js.map +1 -1
  68. package/dist/Icons/ChevronDownIcon.d.ts.map +1 -1
  69. package/dist/Icons/ChevronDownIcon.js.map +1 -1
  70. package/dist/Icons/ChevronUpIcon.d.ts.map +1 -1
  71. package/dist/Icons/ChevronUpIcon.js.map +1 -1
  72. package/dist/Icons/ClockIcon.d.ts.map +1 -1
  73. package/dist/Icons/ClockIcon.js.map +1 -1
  74. package/dist/Icons/CloseCircleIcon.d.ts.map +1 -1
  75. package/dist/Icons/CloseCircleIcon.js.map +1 -1
  76. package/dist/Icons/CloseIcon.d.ts.map +1 -1
  77. package/dist/Icons/CloseIcon.js.map +1 -1
  78. package/dist/Icons/Crosshairs2Icon.d.ts.map +1 -1
  79. package/dist/Icons/Crosshairs2Icon.js.map +1 -1
  80. package/dist/Icons/CrosshairsIcon.d.ts.map +1 -1
  81. package/dist/Icons/CrosshairsIcon.js.map +1 -1
  82. package/dist/Icons/DashboardIcon.d.ts.map +1 -1
  83. package/dist/Icons/DashboardIcon.js.map +1 -1
  84. package/dist/Icons/DatabaseIcon.d.ts.map +1 -1
  85. package/dist/Icons/DatabaseIcon.js.map +1 -1
  86. package/dist/Icons/DeleteIcon.d.ts.map +1 -1
  87. package/dist/Icons/DeleteIcon.js.map +1 -1
  88. package/dist/Icons/DurationIcon.d.ts.map +1 -1
  89. package/dist/Icons/DurationIcon.js.map +1 -1
  90. package/dist/Icons/EditIcon.d.ts.map +1 -1
  91. package/dist/Icons/EditIcon.js.map +1 -1
  92. package/dist/Icons/EmailIcon.d.ts.map +1 -1
  93. package/dist/Icons/EmailIcon.js.map +1 -1
  94. package/dist/Icons/EraserIcon.d.ts.map +1 -1
  95. package/dist/Icons/EraserIcon.js.map +1 -1
  96. package/dist/Icons/ErrorIcon.d.ts.map +1 -1
  97. package/dist/Icons/ErrorIcon.js.map +1 -1
  98. package/dist/Icons/EyeClosedIcon.d.ts.map +1 -1
  99. package/dist/Icons/EyeClosedIcon.js.map +1 -1
  100. package/dist/Icons/EyeClosedIcon2.d.ts.map +1 -1
  101. package/dist/Icons/EyeClosedIcon2.js.map +1 -1
  102. package/dist/Icons/EyeOpenIcon.d.ts.map +1 -1
  103. package/dist/Icons/EyeOpenIcon.js.map +1 -1
  104. package/dist/Icons/FileDownloadIcon.d.ts.map +1 -1
  105. package/dist/Icons/FileDownloadIcon.js.map +1 -1
  106. package/dist/Icons/GoToFirstIcon.d.ts.map +1 -1
  107. package/dist/Icons/GoToFirstIcon.js.map +1 -1
  108. package/dist/Icons/GoToLastIcon.d.ts.map +1 -1
  109. package/dist/Icons/GoToLastIcon.js.map +1 -1
  110. package/dist/Icons/HarmonicCursorsIcon.d.ts.map +1 -1
  111. package/dist/Icons/HarmonicCursorsIcon.js.map +1 -1
  112. package/dist/Icons/InfoIcon.d.ts.map +1 -1
  113. package/dist/Icons/InfoIcon.js.map +1 -1
  114. package/dist/Icons/KeyboardIcon.d.ts.map +1 -1
  115. package/dist/Icons/KeyboardIcon.js.map +1 -1
  116. package/dist/Icons/LabelIcon.d.ts.map +1 -1
  117. package/dist/Icons/LabelIcon.js.map +1 -1
  118. package/dist/Icons/LassoIcon.d.ts.map +1 -1
  119. package/dist/Icons/LassoIcon.js.map +1 -1
  120. package/dist/Icons/LineToolIcon.d.ts.map +1 -1
  121. package/dist/Icons/LineToolIcon.js.map +1 -1
  122. package/dist/Icons/LiveViewIcon.d.ts.map +1 -1
  123. package/dist/Icons/LiveViewIcon.js.map +1 -1
  124. package/dist/Icons/LoaderIcon.d.ts.map +1 -1
  125. package/dist/Icons/LoaderIcon.js.map +1 -1
  126. package/dist/Icons/LocationIcon.d.ts.map +1 -1
  127. package/dist/Icons/LocationIcon.js.map +1 -1
  128. package/dist/Icons/LogoutIcon.d.ts.map +1 -1
  129. package/dist/Icons/LogoutIcon.js.map +1 -1
  130. package/dist/Icons/MaximizeIcon.d.ts.map +1 -1
  131. package/dist/Icons/MaximizeIcon.js.map +1 -1
  132. package/dist/Icons/MeasureIcon.d.ts.map +1 -1
  133. package/dist/Icons/MeasureIcon.js.map +1 -1
  134. package/dist/Icons/MenuDotsIcon.d.ts.map +1 -1
  135. package/dist/Icons/MenuDotsIcon.js.map +1 -1
  136. package/dist/Icons/MenuIcon.d.ts.map +1 -1
  137. package/dist/Icons/MenuIcon.js.map +1 -1
  138. package/dist/Icons/MessagesIcon.d.ts.map +1 -1
  139. package/dist/Icons/MessagesIcon.js.map +1 -1
  140. package/dist/Icons/MetadataIcon.d.ts.map +1 -1
  141. package/dist/Icons/MetadataIcon.js.map +1 -1
  142. package/dist/Icons/MinimizeIcon.d.ts.map +1 -1
  143. package/dist/Icons/MinimizeIcon.js.map +1 -1
  144. package/dist/Icons/MinusIcon.d.ts.map +1 -1
  145. package/dist/Icons/MinusIcon.js.map +1 -1
  146. package/dist/Icons/OntologyIcon.d.ts.map +1 -1
  147. package/dist/Icons/OntologyIcon.js.map +1 -1
  148. package/dist/Icons/PanelIconClose.d.ts.map +1 -1
  149. package/dist/Icons/PanelIconClose.js.map +1 -1
  150. package/dist/Icons/PanelIconOpen.d.ts.map +1 -1
  151. package/dist/Icons/PanelIconOpen.js.map +1 -1
  152. package/dist/Icons/PauseIcon.d.ts.map +1 -1
  153. package/dist/Icons/PauseIcon.js.map +1 -1
  154. package/dist/Icons/PlayIcon.d.ts.map +1 -1
  155. package/dist/Icons/PlayIcon.js.map +1 -1
  156. package/dist/Icons/PlusIcon.d.ts.map +1 -1
  157. package/dist/Icons/PlusIcon.js.map +1 -1
  158. package/dist/Icons/PolygonIcon.d.ts.map +1 -1
  159. package/dist/Icons/PolygonIcon.js.map +1 -1
  160. package/dist/Icons/PrinterIcon.d.ts.map +1 -1
  161. package/dist/Icons/PrinterIcon.js.map +1 -1
  162. package/dist/Icons/ProgressCheckIcon.d.ts.map +1 -1
  163. package/dist/Icons/ProgressCheckIcon.js.map +1 -1
  164. package/dist/Icons/ResetIcon.d.ts.map +1 -1
  165. package/dist/Icons/ResetIcon.js.map +1 -1
  166. package/dist/Icons/ReviewedIcon.d.ts.map +1 -1
  167. package/dist/Icons/ReviewedIcon.js.map +1 -1
  168. package/dist/Icons/ScissorsIcon.d.ts.map +1 -1
  169. package/dist/Icons/ScissorsIcon.js.map +1 -1
  170. package/dist/Icons/SearchIcon.d.ts.map +1 -1
  171. package/dist/Icons/SearchIcon.js.map +1 -1
  172. package/dist/Icons/SettingsIcon.d.ts.map +1 -1
  173. package/dist/Icons/SettingsIcon.js.map +1 -1
  174. package/dist/Icons/SortAscendingIcon.d.ts.map +1 -1
  175. package/dist/Icons/SortAscendingIcon.js.map +1 -1
  176. package/dist/Icons/SortAtoZIcon.d.ts.map +1 -1
  177. package/dist/Icons/SortAtoZIcon.js.map +1 -1
  178. package/dist/Icons/SortDescendingIcon.d.ts.map +1 -1
  179. package/dist/Icons/SortDescendingIcon.js.map +1 -1
  180. package/dist/Icons/SortZtoAIcon.d.ts.map +1 -1
  181. package/dist/Icons/SortZtoAIcon.js.map +1 -1
  182. package/dist/Icons/SparklesIcon.d.ts.map +1 -1
  183. package/dist/Icons/SparklesIcon.js.map +1 -1
  184. package/dist/Icons/StackIcon.d.ts.map +1 -1
  185. package/dist/Icons/StackIcon.js.map +1 -1
  186. package/dist/Icons/StarIcon.d.ts.map +1 -1
  187. package/dist/Icons/StarIcon.js.map +1 -1
  188. package/dist/Icons/SyncIcon.d.ts.map +1 -1
  189. package/dist/Icons/SyncIcon.js.map +1 -1
  190. package/dist/Icons/SyncOffIcon.d.ts.map +1 -1
  191. package/dist/Icons/SyncOffIcon.js.map +1 -1
  192. package/dist/Icons/TrashIcon.d.ts.map +1 -1
  193. package/dist/Icons/TrashIcon.js.map +1 -1
  194. package/dist/Icons/UndoIcon.d.ts.map +1 -1
  195. package/dist/Icons/UndoIcon.js.map +1 -1
  196. package/dist/Icons/UploadIcon.d.ts.map +1 -1
  197. package/dist/Icons/UploadIcon.js.map +1 -1
  198. package/dist/Icons/User2Icon.d.ts.map +1 -1
  199. package/dist/Icons/User2Icon.js.map +1 -1
  200. package/dist/Icons/UserIcon.d.ts.map +1 -1
  201. package/dist/Icons/UserIcon.js.map +1 -1
  202. package/dist/Icons/WarningIcon.d.ts.map +1 -1
  203. package/dist/Icons/WarningIcon.js.map +1 -1
  204. package/dist/Icons/ZoomAllIcon.d.ts.map +1 -1
  205. package/dist/Icons/ZoomAllIcon.js.map +1 -1
  206. package/dist/Icons/ZoomXIcon.d.ts.map +1 -1
  207. package/dist/Icons/ZoomXIcon.js.map +1 -1
  208. package/dist/Icons/ZoomYIcon.d.ts.map +1 -1
  209. package/dist/Icons/ZoomYIcon.js.map +1 -1
  210. package/dist/IconsAnimated/PanelLeftCloseIcon.js.map +1 -1
  211. package/dist/IconsAnimated/PanelLeftOpenIcon.js.map +1 -1
  212. package/dist/Input.js +1 -1
  213. package/dist/Input.js.map +1 -1
  214. package/dist/InputNumeric.d.ts.map +1 -1
  215. package/dist/InputNumeric.js.map +1 -1
  216. package/dist/InputOTP.d.ts.map +1 -1
  217. package/dist/InputOTP.js.map +1 -1
  218. package/dist/Kbd.d.ts.map +1 -1
  219. package/dist/Kbd.js.map +1 -1
  220. package/dist/Label.js.map +1 -1
  221. package/dist/MultiSelect/MultiSelectBase.js.map +1 -1
  222. package/dist/MultiSelect.js.map +1 -1
  223. package/dist/Popover.d.ts.map +1 -1
  224. package/dist/Popover.js.map +1 -1
  225. package/dist/RadioButton.js +1 -4
  226. package/dist/RadioButton.js.map +1 -1
  227. package/dist/RadioButtonGroup/RadioButtonGroupBase.d.ts.map +1 -1
  228. package/dist/RadioButtonGroup/RadioButtonGroupBase.js +2 -7
  229. package/dist/RadioButtonGroup/RadioButtonGroupBase.js.map +1 -1
  230. package/dist/RadioButtonGroup.d.ts.map +1 -1
  231. package/dist/RadioButtonGroup.js.map +1 -1
  232. package/dist/RadioGroup.d.ts.map +1 -1
  233. package/dist/RadioGroup.js +1 -1
  234. package/dist/RadioGroup.js.map +1 -1
  235. package/dist/Select.js.map +1 -1
  236. package/dist/Skeleton.js.map +1 -1
  237. package/dist/Slider.js.map +1 -1
  238. package/dist/Switch/SwitchBase.d.ts.map +1 -1
  239. package/dist/Switch/SwitchBase.js.map +1 -1
  240. package/dist/Switch.js.map +1 -1
  241. package/dist/Tabs/TabsBase.d.ts.map +1 -1
  242. package/dist/Tabs/TabsBase.js.map +1 -1
  243. package/dist/Tabs.d.ts.map +1 -1
  244. package/dist/Tabs.js.map +1 -1
  245. package/dist/Textarea.js.map +1 -1
  246. package/dist/Toast.d.ts.map +1 -1
  247. package/dist/Toast.js.map +1 -1
  248. package/dist/Toggle/ToggleBase.js.map +1 -1
  249. package/dist/Toggle.d.ts.map +1 -1
  250. package/dist/Toggle.js +2 -6
  251. package/dist/Toggle.js.map +1 -1
  252. package/dist/ToggleGroup/ToggleGroupBase.d.ts.map +1 -1
  253. package/dist/ToggleGroup/ToggleGroupBase.js.map +1 -1
  254. package/dist/ToggleGroup/ToggleGroupItem.js +1 -1
  255. package/dist/ToggleGroup/ToggleGroupItem.js.map +1 -1
  256. package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js +1 -1
  257. package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js.map +1 -1
  258. package/dist/ToggleGroup.js +1 -9
  259. package/dist/ToggleGroup.js.map +1 -1
  260. package/dist/Tooltip.d.ts.map +1 -1
  261. package/dist/Tooltip.js.map +1 -1
  262. package/dist/Tray.d.ts.map +1 -1
  263. package/dist/Tray.js +1 -1
  264. package/dist/Tray.js.map +1 -1
  265. package/package.json +1 -1
package/dist/Kbd.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Kbd.js","names":[],"sources":["../src/components/Kbd/Kbd.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ComponentProps } from 'react'\n\nexport type KbdSymbol = 'arrowLeft' | 'arrowRight' | 'arrowUp' | 'arrowDown' | 'command' | 'option' | 'shift' | 'control' | 'return' | 'delete'\n\nexport interface KbdProps {\n className?: string\n symbol?: KbdSymbol\n symbolPosition?: 'start' | 'end'\n}\n\nexport interface KbdGroupProps {\n className?: string\n}\n\nconst symbolMap = {\n arrowLeft: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path d='M10 5.75L3.75 12L10 18.25M4.5 12H20.25' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round' />\n </svg>\n ),\n arrowRight: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path d='M14 5.75L20.25 12L14 18.25M19.5 12H3.75' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round' />\n </svg>\n ),\n arrowUp: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path d='M5.75 10L12 3.75L18.25 10M12 20.25V4.5' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round' />\n </svg>\n ),\n arrowDown: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path d='M18 14L12 20L6 14M12 19V4' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round' />\n </svg>\n ),\n command: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M9.25 9.25V6.5C9.25 4.98122 8.01878 3.75 6.5 3.75C4.98122 3.75 3.75 4.98122 3.75 6.5C3.75 8.01878 4.98122 9.25 6.5 9.25H9.25ZM9.25 9.25H14.75M9.25 9.25V14.75M14.75 9.25V6.5C14.75 4.98122 15.9812 3.75 17.5 3.75C19.0188 3.75 20.25 4.98122 20.25 6.5C20.25 8.01878 19.0188 9.25 17.5 9.25H14.75ZM14.75 9.25V14.75M14.75 14.75H9.25M14.75 14.75V17.5C14.75 19.0188 15.9812 20.25 17.5 20.25C19.0188 20.25 20.25 19.0188 20.25 17.5C20.25 15.9812 19.0188 14.75 17.5 14.75H14.75ZM9.25 14.75V17.5C9.25 19.0188 8.01878 20.25 6.5 20.25C4.98122 20.25 3.75 19.0188 3.75 17.5C3.75 15.9812 4.98122 14.75 6.5 14.75H9.25Z'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='square'\n />\n </svg>\n ),\n option: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path d='M3.75 4.75H7.40962C7.77384 4.75 8.10925 4.94802 8.2852 5.26692L15.7148 18.7331C15.8907 19.052 16.2262 19.25 16.5904 19.25H20.25M15.75 4.75H20.25' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round' />\n </svg>\n ),\n shift: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M2.91032 11.5511L11.2848 2.98182C11.6771 2.5804 12.3229 2.5804 12.7152 2.98182L21.0897 11.5511C21.7085 12.1843 21.2599 13.25 20.3745 13.25H17.1316V19.25C17.1316 19.8023 16.6839 20.25 16.1316 20.25H7.86842C7.31614 20.25 6.86842 19.8023 6.86842 19.25V13.25H3.62551C2.74013 13.25 2.2915 12.1843 2.91032 11.5511Z'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='square'\n strokeLinejoin='round'\n />\n </svg>\n ),\n control: (\n <svg className='-translate-y-0.5' width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path d='M8 13.9999L11.6464 10.3535C11.8417 10.1582 12.1583 10.1582 12.3536 10.3535L16 13.9999' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round' />\n </svg>\n ),\n return: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n fillRule='evenodd'\n clipRule='evenodd'\n d='M20.25 4C19.8358 4 19.5 4.33579 19.5 4.75V14.25C19.5 14.3881 19.3881 14.5 19.25 14.5H5.56066L8.28033 11.7803C8.57322 11.4874 8.57322 11.0126 8.28033 10.7197C7.98744 10.4268 7.51256 10.4268 7.21967 10.7197L3.21967 14.7197C2.92678 15.0126 2.92678 15.4874 3.21967 15.7803L7.21967 19.7803C7.51256 20.0732 7.98744 20.0732 8.28033 19.7803C8.57322 19.4874 8.57322 19.0126 8.28033 18.7197L5.56066 16H19.25C20.2165 16 21 15.2165 21 14.25V4.75C21 4.33579 20.6642 4 20.25 4Z'\n fill='currentColor'\n />\n </svg>\n ),\n delete: (\n <svg width='14' height='14' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M14.9988 9.75L12.7488 12M12.7488 12L10.4988 14.25M12.7488 12L10.4988 9.75M12.7488 12L14.9988 14.25M6.55509 4.75H20.2488C20.8011 4.75 21.2488 5.19772 21.2488 5.75V18.25C21.2488 18.8023 20.8011 19.25 20.2488 19.25H6.55509C6.2092 19.25 5.88786 19.0712 5.70545 18.7774L1.82614 12.5274C1.62566 12.2044 1.62566 11.7956 1.82614 11.4726L5.70545 5.22264C5.88786 4.92875 6.2092 4.75 6.55509 4.75Z'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n />\n </svg>\n ),\n} as const\n\nconst symbolLabelMap: Record<KbdSymbol, string> = {\n arrowLeft: 'Left Arrow',\n arrowRight: 'Right Arrow',\n arrowUp: 'Up Arrow',\n arrowDown: 'Down Arrow',\n command: 'Command',\n option: 'Option',\n shift: 'Shift',\n control: 'Control',\n return: 'Return',\n delete: 'Delete',\n}\n\nexport const Kbd = ({ className, symbol, symbolPosition = 'start', children, ...props }: KbdProps & ComponentProps<'kbd'>) => {\n const hasChildren = children !== undefined && children !== null && children !== ''\n const symbolElement = symbol && <span aria-hidden='true'>{symbolMap[symbol]}</span>\n\n // Derive aria-label from symbol when no children are provided, unless explicitly overridden\n const derivedAriaLabel = !hasChildren && symbol ? symbolLabelMap[symbol] : undefined\n const ariaLabel = props['aria-label'] ?? derivedAriaLabel\n\n return (\n <kbd\n className={cn(\n 'h-5 min-w-5 gap-1 rounded-sm px-1 text-xs font-medium pointer-events-none inline-flex w-fit items-center justify-center bg-kbd-bg font-mono! text-kbd-text select-none',\n `[&_svg:not([class*='size-'])]:size-3 in-data-[slot=tooltip-content]:bg-level-three`,\n className,\n )}\n data-slot='kbd'\n data-testid='spectral-kbd'\n {...props}\n aria-label={ariaLabel}\n >\n {symbolPosition === 'start' && symbolElement}\n {children}\n {symbolPosition === 'end' && symbolElement}\n </kbd>\n )\n}\nKbd.displayName = 'Kbd'\n\nexport const KbdGroup = ({ className, ...props }: KbdGroupProps & ComponentProps<'kbd'>) => {\n return <kbd className={cn('gap-1 inline-flex items-center', className)} data-slot='kbd-group' data-testid='spectral-kbd-group' {...props} />\n}\nKbdGroup.displayName = 'KbdGroup'\n"],"mappings":"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"}
1
+ {"version":3,"file":"Kbd.js","names":[],"sources":["../src/components/Kbd/Kbd.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ComponentProps } from 'react'\n\nexport type KbdSymbol = 'arrowLeft' | 'arrowRight' | 'arrowUp' | 'arrowDown' | 'command' | 'option' | 'shift' | 'control' | 'return' | 'delete'\n\nexport interface KbdProps {\n className?: string\n symbol?: KbdSymbol\n symbolPosition?: 'start' | 'end'\n}\n\nexport interface KbdGroupProps {\n className?: string\n}\n\nconst symbolMap = {\n arrowLeft: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M10 5.75L3.75 12L10 18.25M4.5 12H20.25'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n />\n </svg>\n ),\n arrowRight: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M14 5.75L20.25 12L14 18.25M19.5 12H3.75'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n />\n </svg>\n ),\n arrowUp: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M5.75 10L12 3.75L18.25 10M12 20.25V4.5'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n />\n </svg>\n ),\n arrowDown: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M18 14L12 20L6 14M12 19V4'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n />\n </svg>\n ),\n command: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M9.25 9.25V6.5C9.25 4.98122 8.01878 3.75 6.5 3.75C4.98122 3.75 3.75 4.98122 3.75 6.5C3.75 8.01878 4.98122 9.25 6.5 9.25H9.25ZM9.25 9.25H14.75M9.25 9.25V14.75M14.75 9.25V6.5C14.75 4.98122 15.9812 3.75 17.5 3.75C19.0188 3.75 20.25 4.98122 20.25 6.5C20.25 8.01878 19.0188 9.25 17.5 9.25H14.75ZM14.75 9.25V14.75M14.75 14.75H9.25M14.75 14.75V17.5C14.75 19.0188 15.9812 20.25 17.5 20.25C19.0188 20.25 20.25 19.0188 20.25 17.5C20.25 15.9812 19.0188 14.75 17.5 14.75H14.75ZM9.25 14.75V17.5C9.25 19.0188 8.01878 20.25 6.5 20.25C4.98122 20.25 3.75 19.0188 3.75 17.5C3.75 15.9812 4.98122 14.75 6.5 14.75H9.25Z'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='square'\n />\n </svg>\n ),\n option: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M3.75 4.75H7.40962C7.77384 4.75 8.10925 4.94802 8.2852 5.26692L15.7148 18.7331C15.8907 19.052 16.2262 19.25 16.5904 19.25H20.25M15.75 4.75H20.25'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n />\n </svg>\n ),\n shift: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M2.91032 11.5511L11.2848 2.98182C11.6771 2.5804 12.3229 2.5804 12.7152 2.98182L21.0897 11.5511C21.7085 12.1843 21.2599 13.25 20.3745 13.25H17.1316V19.25C17.1316 19.8023 16.6839 20.25 16.1316 20.25H7.86842C7.31614 20.25 6.86842 19.8023 6.86842 19.25V13.25H3.62551C2.74013 13.25 2.2915 12.1843 2.91032 11.5511Z'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='square'\n strokeLinejoin='round'\n />\n </svg>\n ),\n control: (\n <svg\n className='-translate-y-0.5'\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M8 13.9999L11.6464 10.3535C11.8417 10.1582 12.1583 10.1582 12.3536 10.3535L16 13.9999'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n />\n </svg>\n ),\n return: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n fillRule='evenodd'\n clipRule='evenodd'\n d='M20.25 4C19.8358 4 19.5 4.33579 19.5 4.75V14.25C19.5 14.3881 19.3881 14.5 19.25 14.5H5.56066L8.28033 11.7803C8.57322 11.4874 8.57322 11.0126 8.28033 10.7197C7.98744 10.4268 7.51256 10.4268 7.21967 10.7197L3.21967 14.7197C2.92678 15.0126 2.92678 15.4874 3.21967 15.7803L7.21967 19.7803C7.51256 20.0732 7.98744 20.0732 8.28033 19.7803C8.57322 19.4874 8.57322 19.0126 8.28033 18.7197L5.56066 16H19.25C20.2165 16 21 15.2165 21 14.25V4.75C21 4.33579 20.6642 4 20.25 4Z'\n fill='currentColor'\n />\n </svg>\n ),\n delete: (\n <svg\n width='14'\n height='14'\n viewBox='0 0 24 24'\n fill='none'\n xmlns='http://www.w3.org/2000/svg'\n >\n <path\n d='M14.9988 9.75L12.7488 12M12.7488 12L10.4988 14.25M12.7488 12L10.4988 9.75M12.7488 12L14.9988 14.25M6.55509 4.75H20.2488C20.8011 4.75 21.2488 5.19772 21.2488 5.75V18.25C21.2488 18.8023 20.8011 19.25 20.2488 19.25H6.55509C6.2092 19.25 5.88786 19.0712 5.70545 18.7774L1.82614 12.5274C1.62566 12.2044 1.62566 11.7956 1.82614 11.4726L5.70545 5.22264C5.88786 4.92875 6.2092 4.75 6.55509 4.75Z'\n stroke='currentColor'\n strokeWidth='1.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n />\n </svg>\n ),\n} as const\n\nconst symbolLabelMap: Record<KbdSymbol, string> = {\n arrowLeft: 'Left Arrow',\n arrowRight: 'Right Arrow',\n arrowUp: 'Up Arrow',\n arrowDown: 'Down Arrow',\n command: 'Command',\n option: 'Option',\n shift: 'Shift',\n control: 'Control',\n return: 'Return',\n delete: 'Delete',\n}\n\nexport const Kbd = ({ className, symbol, symbolPosition = 'start', children, ...props }: KbdProps & ComponentProps<'kbd'>) => {\n const hasChildren = children !== undefined && children !== null && children !== ''\n const symbolElement = symbol && <span aria-hidden='true'>{symbolMap[symbol]}</span>\n\n // Derive aria-label from symbol when no children are provided, unless explicitly overridden\n const derivedAriaLabel = !hasChildren && symbol ? symbolLabelMap[symbol] : undefined\n const ariaLabel = props['aria-label'] ?? derivedAriaLabel\n\n return (\n <kbd\n className={cn(\n 'h-5 min-w-5 gap-1 rounded-sm px-1 text-xs font-medium pointer-events-none inline-flex w-fit items-center justify-center bg-kbd-bg font-mono! text-kbd-text select-none',\n `[&_svg:not([class*='size-'])]:size-3 in-data-[slot=tooltip-content]:bg-level-three`,\n className,\n )}\n data-slot='kbd'\n data-testid='spectral-kbd'\n {...props}\n aria-label={ariaLabel}\n >\n {symbolPosition === 'start' && symbolElement}\n {children}\n {symbolPosition === 'end' && symbolElement}\n </kbd>\n )\n}\nKbd.displayName = 'Kbd'\n\nexport const KbdGroup = ({ className, ...props }: KbdGroupProps & ComponentProps<'kbd'>) => {\n return (\n <kbd\n className={cn('gap-1 inline-flex items-center', className)}\n data-slot='kbd-group'\n data-testid='spectral-kbd-group'\n {...props}\n />\n )\n}\nKbdGroup.displayName = 'KbdGroup'\n"],"mappings":"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"}
package/dist/Label.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Label.js","names":[],"sources":["../src/components/Label/Label.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type Ref } from 'react'\n\nexport interface LabelProps extends ComponentPropsWithoutRef<'label'> {\n ref?: Ref<HTMLLabelElement>\n}\n\nexport const Label = ({\n className,\n ref,\n ...props\n}: LabelProps & {\n ref?: Ref<HTMLLabelElement>\n}) => {\n return (\n // eslint-disable-next-line jsx-a11y/label-has-associated-control\n <label className={cn('text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', className)} data-slot='label' ref={ref} {...props} />\n )\n}\nLabel.displayName = 'Label'\n"],"mappings":";;;;;;AAOA,MAAa,SAAS,EACpB,WACA,KACA,GAAG,YAGC;AACJ,QAEE,oBAAC,SAAD;EAAO,WAAW,GAAG,8FAA8F,UAAU;EAAE,aAAU;EAAa;EAAK,GAAI;EAAS;;AAG5K,MAAM,cAAc"}
1
+ {"version":3,"file":"Label.js","names":[],"sources":["../src/components/Label/Label.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type Ref } from 'react'\n\nexport interface LabelProps extends ComponentPropsWithoutRef<'label'> {\n ref?: Ref<HTMLLabelElement>\n}\n\nexport const Label = ({\n className,\n ref,\n ...props\n}: LabelProps & {\n ref?: Ref<HTMLLabelElement>\n}) => {\n return (\n // eslint-disable-next-line jsx-a11y/label-has-associated-control\n <label\n className={cn('text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', className)}\n data-slot='label'\n ref={ref}\n {...props}\n />\n )\n}\nLabel.displayName = 'Label'\n"],"mappings":";;;;;;AAOA,MAAa,SAAS,EACpB,WACA,KACA,GAAG,YAGC;AACJ,QAEE,oBAAC,SAAD;EACE,WAAW,GAAG,8FAA8F,UAAU;EACtH,aAAU;EACL;EACL,GAAI;EACJ;;AAGN,MAAM,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"MultiSelectBase.js","names":[],"sources":["../../src/components/MultiSelect/MultiSelectBase.tsx"],"sourcesContent":["import { CheckmarkIcon, ChevronDownIcon, CloseIcon, SearchIcon } from '@components/Icons'\nimport { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport * as Popover from '@radix-ui/react-popover'\nimport { useAutoDropdownHorizontalShift } from '@utils/dropdownPositioning'\nimport { EmptyState, ErrorMessage, getAriaProps, getDropdownSurfaceClasses, getDropdownWidthStyles, getErrorMessageId, getTriggerClasses, LoadingState, WarningMessage, useFormFieldId, type BaseFormFieldProps, type DropdownWidth, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useCallback, useEffect, useId, useMemo, useRef, useState, type ButtonHTMLAttributes, type ChangeEvent, type CSSProperties, type KeyboardEvent, type Ref } from 'react'\n\nexport type MultiSelectState = Exclude<FormFieldState, 'disabled'>\n\nexport interface MultiSelectOption {\n disabled?: boolean\n group?: string\n label: string\n value: string\n}\n\nexport interface MultiSelectBaseProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'onChange'> {\n clearAllLabel?: string\n closeOnSelect?: boolean\n dropdownWidth?: DropdownWidth\n emptyMessage?: string\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string\n label?: string\n loadingMessage?: string\n maxCount?: number\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n defaultValue?: string[]\n onChange?: (value: string[]) => void\n options: MultiSelectOption[]\n placeholder?: string\n required?: boolean\n searchPlaceholder?: string\n showClearAll?: boolean\n showSearch?: boolean\n showSelectAll?: boolean\n selectAllLabel?: string\n sortAlphabetically?: boolean\n state?: MultiSelectState\n value?: string[]\n warningMessage?: BaseFormFieldProps['errorMessage']\n 'aria-label'?: string\n 'aria-describedby'?: string\n}\n\nconst ICON_SIZE = 'h-4 w-4'\n\nconst getDropdownClasses = (): string => {\n return cn(\n 'max-h-80 z-50 overflow-hidden',\n getDropdownSurfaceClasses(),\n 'motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=open]:animate-in',\n 'motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=open]:fade-in-0',\n 'motion-safe:data-[state=closed]:zoom-out-95 motion-safe:data-[state=open]:zoom-in-95',\n 'motion-safe:data-[side=bottom]:slide-in-from-top-2',\n 'motion-safe:data-[side=top]:slide-in-from-bottom-2',\n 'origin-(--radix-popover-content-transform-origin)',\n )\n}\n\ntype FocusableItem = { type: 'search' } | { type: 'select-all' } | { type: 'option'; index: number; value: string } | { type: 'clear-all' }\n\nconst useKeyboardNavigation = (\n options: MultiSelectOption[],\n onClearAll: () => void,\n onClose: () => void,\n onSelect: (value: string) => void,\n onSelectAll: () => void,\n searchInputRef: React.RefObject<HTMLInputElement | null>,\n showSearch: boolean,\n showSelectAll: boolean,\n showClearAll: boolean,\n) => {\n const [focusedIndex, setFocusedIndex] = useState(-1)\n\n // Build a flat list of all focusable items\n const focusableItems = useMemo((): FocusableItem[] => {\n const items: FocusableItem[] = []\n\n if (showSearch) {\n items.push({ type: 'search' })\n }\n\n if (showSelectAll) {\n items.push({ type: 'select-all' })\n }\n\n options.forEach((option, index) => {\n if (!option.disabled) {\n items.push({ type: 'option', index, value: option.value })\n }\n })\n\n if (showClearAll) {\n items.push({ type: 'clear-all' })\n }\n\n return items\n }, [options, showSearch, showSelectAll, showClearAll])\n\n // Focus the appropriate element when focusedIndex changes\n const focusCurrentItem = useCallback(\n (index: number) => {\n if (index < 0 || index >= focusableItems.length) return\n const item = focusableItems[index]\n if (item.type === 'search') {\n searchInputRef.current?.focus()\n }\n },\n [focusableItems, searchInputRef],\n )\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n const currentItem = focusedIndex >= 0 && focusedIndex < focusableItems.length ? focusableItems[focusedIndex] : null\n\n // Don't prevent default for space in search input (allow typing spaces)\n if (event.key === ' ' && currentItem?.type === 'search') {\n return\n }\n\n // Don't prevent default for Enter in search input (allow form submission behavior)\n if (event.key === 'Enter' && currentItem?.type === 'search') {\n return\n }\n\n const keyHandlers: Record<string, () => void> = {\n ArrowDown: () => {\n event.preventDefault()\n const newIndex = Math.min(focusedIndex + 1, focusableItems.length - 1)\n setFocusedIndex(newIndex)\n focusCurrentItem(newIndex)\n },\n ArrowUp: () => {\n event.preventDefault()\n const newIndex = Math.max(focusedIndex - 1, 0)\n setFocusedIndex(newIndex)\n focusCurrentItem(newIndex)\n },\n Tab: () => {\n // Allow Tab to cycle through focusable items\n if (event.shiftKey) {\n if (focusedIndex <= 0) {\n // At start, close dropdown and return to trigger\n onClose()\n } else {\n event.preventDefault()\n const newIndex = focusedIndex - 1\n setFocusedIndex(newIndex)\n focusCurrentItem(newIndex)\n }\n } else {\n if (focusedIndex >= focusableItems.length - 1) {\n // At end, close dropdown and move to next element\n onClose()\n } else {\n event.preventDefault()\n const newIndex = focusedIndex + 1\n setFocusedIndex(newIndex)\n focusCurrentItem(newIndex)\n }\n }\n },\n Enter: () => {\n event.preventDefault()\n if (focusedIndex >= 0 && focusedIndex < focusableItems.length) {\n const item = focusableItems[focusedIndex]\n if (item.type === 'select-all') {\n onSelectAll()\n } else if (item.type === 'clear-all') {\n onClearAll()\n } else if (item.type === 'option') {\n onSelect(item.value)\n }\n }\n },\n ' ': () => {\n event.preventDefault()\n if (focusedIndex >= 0 && focusedIndex < focusableItems.length) {\n const item = focusableItems[focusedIndex]\n if (item.type === 'select-all') {\n onSelectAll()\n } else if (item.type === 'clear-all') {\n onClearAll()\n } else if (item.type === 'option') {\n onSelect(item.value)\n }\n }\n },\n Escape: () => {\n event.preventDefault()\n onClose()\n },\n }\n\n const handler = keyHandlers[event.key]\n if (handler) {\n handler()\n }\n },\n [focusableItems, focusedIndex, onSelect, onSelectAll, onClearAll, onClose, focusCurrentItem],\n )\n\n // Get the option index for visual focus styling (accounting for select-all offset)\n const getOptionFocusIndex = useCallback(\n (optionIndex: number): boolean => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return false\n const item = focusableItems[focusedIndex]\n return item.type === 'option' && item.index === optionIndex\n },\n [focusedIndex, focusableItems],\n )\n\n const isSearchFocused = useMemo(() => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return false\n return focusableItems[focusedIndex].type === 'search'\n }, [focusedIndex, focusableItems])\n\n const isSelectAllFocused = useMemo(() => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return false\n return focusableItems[focusedIndex].type === 'select-all'\n }, [focusedIndex, focusableItems])\n\n const isClearAllFocused = useMemo(() => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return false\n return focusableItems[focusedIndex].type === 'clear-all'\n }, [focusedIndex, focusableItems])\n\n const focusedOptionValue = useMemo(() => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return null\n const item = focusableItems[focusedIndex]\n return item.type === 'option' ? item.value : null\n }, [focusedIndex, focusableItems])\n\n return {\n focusedIndex,\n setFocusedIndex,\n handleKeyDown,\n getOptionFocusIndex,\n isSearchFocused,\n isSelectAllFocused,\n isClearAllFocused,\n focusedOptionValue,\n }\n}\n\nexport const MultiSelectBase = ({\n className,\n clearAllLabel = 'Clear all',\n closeOnSelect = false,\n dropdownWidth = 'trigger',\n emptyMessage = 'No options found',\n errorMessage,\n defaultValue = [],\n disabled,\n id,\n label,\n loadingMessage = 'Loading options…',\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxCount = 3,\n name,\n onChange,\n options = [],\n placeholder = 'Select options',\n ref,\n searchPlaceholder = 'Search options…',\n selectAllLabel = 'Select all',\n showClearAll = true,\n showSearch = true,\n showSelectAll = true,\n sortAlphabetically = false,\n state = 'default',\n value: valueProp,\n warningMessage,\n 'aria-label': ariaLabel,\n 'aria-describedby': ariaDescribedBy,\n ...props\n}: MultiSelectBaseProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const generatedId = useId()\n const fallbackName = name ?? `multiselect-${generatedId}`\n const multiSelectId = useFormFieldId(id, fallbackName)\n const listboxId = `${multiSelectId}-listbox`\n const errorMessageId = getErrorMessageId(multiSelectId)\n const warningMessageId = `${multiSelectId}-warning`\n const messageId = state === 'error' ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n\n const [isOpen, setIsOpen] = useState(false)\n const { dropdownShiftStyle, setDropdownElement } = useAutoDropdownHorizontalShift(isOpen)\n const [searchValue, setSearchValue] = useState('')\n const [value, setValue] = useUncontrolledState<string[]>({\n value: valueProp,\n defaultValue,\n onChange,\n })\n\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n const isDisabled = Boolean(disabled)\n const isLoading = state === 'loading'\n const ariaProps = getAriaProps(state, ariaDescribedBy, props.required, messageId)\n const { dropdownOverflowStyle, dropdownWidthMode, resolvedDropdownWidth } = getDropdownWidthStyles({\n dropdownWidth,\n triggerWidth: 'var(--radix-popover-trigger-width)',\n })\n\n const filteredOptions = useMemo(() => {\n let filtered = options.filter((option) => option.label.toLowerCase().includes(searchValue.toLowerCase()))\n\n if (sortAlphabetically) {\n filtered = [...filtered].sort((a, b) => a.label.localeCompare(b.label))\n }\n\n return filtered\n }, [options, searchValue, sortAlphabetically])\n\n const groupedOptions = useMemo(() => {\n const groups: Record<string, MultiSelectOption[]> = {}\n const ungrouped: MultiSelectOption[] = []\n\n filteredOptions.forEach((option) => {\n if (option.group) {\n if (!groups[option.group]) {\n groups[option.group] = []\n }\n groups[option.group].push(option)\n } else {\n ungrouped.push(option)\n }\n })\n\n return { groups, ungrouped, hasGroups: Object.keys(groups).length > 0 }\n }, [filteredOptions])\n\n const toggleOption = useCallback(\n (optionValue: string) => {\n const option = options.find((o) => o.value === optionValue)\n if (option?.disabled) return\n\n const newValue = value.includes(optionValue) ? value.filter((v) => v !== optionValue) : [...value, optionValue]\n\n setValue(newValue)\n\n if (closeOnSelect) {\n setIsOpen(false)\n }\n },\n [closeOnSelect, options, setValue, value],\n )\n\n const handleSelectAll = useCallback(() => {\n const allValues = options.filter((o) => !o.disabled).map((o) => o.value)\n const isAllSelected = allValues.every((v) => value.includes(v))\n\n if (isAllSelected) {\n setValue([])\n } else {\n setValue(allValues)\n }\n }, [options, setValue, value])\n\n const handleClearAll = useCallback(() => {\n setValue([])\n }, [setValue])\n\n // Check if all non-disabled options are selected\n const allSelectableValues = useMemo(() => options.filter((o) => !o.disabled).map((o) => o.value), [options])\n const isAllSelected = allSelectableValues.length > 0 && allSelectableValues.every((v) => value.includes(v))\n\n const { focusedOptionValue, getOptionFocusIndex, handleKeyDown, isSelectAllFocused, setFocusedIndex } = useKeyboardNavigation(\n filteredOptions,\n handleClearAll,\n () => setIsOpen(false),\n toggleOption,\n handleSelectAll,\n searchInputRef,\n showSearch,\n showSelectAll,\n false, // No separate clear-all button in dropdown\n )\n\n // Set initial focus index when dropdown opens/closes\n useEffect(() => {\n if (isOpen) {\n setFocusedIndex(0)\n } else {\n setFocusedIndex(-1)\n }\n }, [isOpen, setFocusedIndex])\n\n const handleSearchChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setSearchValue(e.target.value)\n }, [])\n\n const renderSelectedItems = () => {\n if (value.length === 0) {\n return <span className='min-h-8 flex items-center text-input-text-placeholder'>{placeholder}</span>\n }\n\n const displayedValues = value.slice(0, maxCount)\n const remainingCount = value.length - maxCount\n\n return (\n <div className='gap-1 flex flex-wrap items-center overflow-hidden'>\n {displayedValues.map((val) => {\n const option = options.find((o) => o.value === val)\n if (!option) return null\n\n return (\n <span className='gap-1 px-2 py-1 rounded-md text-xs max-w-48 inline-flex items-center bg-input-bg--selected text-input-text' key={val}>\n <span className='truncate'>{option.label}</span>\n <button\n aria-label={`Remove ${option.label}`}\n className='hover:text-danger rounded-sm cursor-pointer'\n data-testid='spectral-multiselect-remove-item-button'\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n toggleOption(val)\n }}\n onPointerDown={(e) => {\n e.stopPropagation()\n }}\n type='button'\n >\n <CloseIcon size={12} />\n </button>\n </span>\n )\n })}\n {remainingCount > 0 && <span className='text-input-text-secondary text-xs py-1 flex items-center tabular-nums'>+{remainingCount} more</span>}\n </div>\n )\n }\n\n const renderOption = (option: MultiSelectOption, index: number) => {\n const isSelected = value.includes(option.value)\n const isFocused = getOptionFocusIndex(index)\n const optionId = `${listboxId}-option-${option.value}`\n\n return (\n <button\n aria-selected={isSelected}\n className={cn(\n 'my-0.5 first:mt-0 last:mb-0 gap-3 rounded-sm px-3 py-2 text-sm flex w-full items-center text-left hover:bg-input-bg--hover focus-visible:bg-input-bg--hover focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n isFocused && 'bg-input-bg--hover',\n isSelected && 'font-medium text-input-text',\n )}\n disabled={option.disabled}\n id={optionId}\n key={option.value}\n onClick={() => toggleOption(option.value)}\n role='option'\n type='button'\n >\n <div data-testid='spectral-multiselect-selected-indicator' className={cn('w-4 h-4 rounded flex items-center justify-center border border-input-border', isSelected && 'bg-primary border-primary')}>\n {isSelected && <CheckmarkIcon size={12} />}\n </div>\n <span>{option.label}</span>\n </button>\n )\n }\n\n const getCSSCustomProperties = () => ({\n '--multiselect-border-radius': '0.5rem',\n '--multiselect-trigger-height': '3rem',\n '--multiselect-dropdown-max-height': '20rem',\n })\n\n return (\n <div className='w-full' data-testid='spectral-multiselect-root'>\n {label && (\n <Label className={cn('mb-2 block text-text-primary', isDisabled && 'text-text-secondary')} data-testid='spectral-multiselect-label' htmlFor={multiSelectId}>\n {label}\n </Label>\n )}\n <Popover.Root open={isOpen} onOpenChange={setIsOpen}>\n <div className='relative' data-testid='spectral-multiselect-wrapper' onKeyDown={isOpen ? handleKeyDown : undefined} role='none'>\n <Popover.Trigger asChild>\n <button\n aria-activedescendant={isOpen && focusedOptionValue ? `${listboxId}-option-${focusedOptionValue}` : undefined}\n aria-controls={isOpen ? listboxId : undefined}\n aria-expanded={isOpen}\n aria-label={ariaLabel ?? label}\n className={cn(getTriggerClasses(isOpen, state, className), 'max-h-22 py-2 text-sm')}\n data-state={state}\n data-testid='spectral-multiselect-trigger'\n disabled={isDisabled}\n id={multiSelectId}\n name={name}\n ref={ref}\n role='combobox' // oxlint-disable-line jsx-a11y/prefer-tag-over-role -- trigger uses button-based combobox semantics for listbox popup\n style={getCSSCustomProperties() as CSSProperties}\n type='button'\n {...ariaProps}\n {...props}\n >\n <div className='min-w-0 flex-1 overflow-hidden' data-testid='spectral-multiselect-selected-items'>\n {renderSelectedItems()}\n </div>\n <div className='gap-2 ml-2 flex shrink-0 items-center'>\n <ChevronDownIcon className={cn('text-input-icon transition-transform duration-200', isOpen && 'rotate-180')} size={20} />\n </div>\n </button>\n </Popover.Trigger>\n {showClearAll && value.length > 0 && (\n <button\n aria-label='Clear all selections'\n className='right-10 text-input-icon hover:text-input-icon--hover rounded-sm absolute top-1/2 z-10 -translate-y-1/2 cursor-pointer focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 disabled:pointer-events-none disabled:opacity-50'\n data-testid='spectral-multiselect-clear-all-button'\n disabled={isDisabled}\n onClick={(e) => {\n e.stopPropagation()\n handleClearAll()\n document.getElementById(multiSelectId)?.focus()\n }}\n type='button'\n >\n <CloseIcon size={12} />\n </button>\n )}\n\n <Popover.Portal>\n <Popover.Content\n align='start'\n avoidCollisions\n className={getDropdownClasses()}\n collisionPadding={10}\n data-dropdown-width-mode={dropdownWidthMode}\n data-dropdown-width-value={dropdownWidthMode === 'custom' ? dropdownWidth : undefined}\n data-testid='spectral-multiselect-dropdown'\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n if (showSearch) {\n searchInputRef.current?.focus()\n }\n }}\n side='bottom'\n sideOffset={4}\n ref={setDropdownElement}\n style={{\n width: resolvedDropdownWidth,\n ...(dropdownWidth === 'trigger' ? {} : dropdownOverflowStyle),\n ...dropdownShiftStyle,\n }}\n >\n <div className='p-1'>\n {showSearch && (\n <div className='mb-2 relative'>\n <SearchIcon className={cn(ICON_SIZE, 'left-3 text-input-icon absolute top-1/2 -translate-y-1/2')} />\n <input\n aria-label='Search options'\n className='pl-9 pr-3 py-2 text-sm rounded-md focus-visible:ring-black w-full border border-input-border bg-input-bg focus-visible:border-input-border--focus focus-visible:ring-1 focus-visible:outline-none'\n data-testid='spectral-multiselect-search-input'\n onChange={handleSearchChange}\n placeholder={searchPlaceholder}\n ref={searchInputRef}\n type='text'\n value={searchValue}\n />\n </div>\n )}\n <div aria-multiselectable='true' className='max-h-64 overflow-y-auto' id={listboxId} role='listbox' // oxlint-disable-line jsx-a11y/prefer-tag-over-role -- custom multi-select uses ARIA listbox semantics with option children\n >\n {isLoading ? (\n <LoadingState className='text-sm' message={loadingMessage} data-testid='spectral-multiselect-loading' />\n ) : filteredOptions.length === 0 ? (\n <EmptyState className='text-sm' data-testid='spectral-multiselect-empty-message' message={emptyMessage} />\n ) : (\n <>\n {showSelectAll && (\n <div className='mb-1'>\n <button\n className={cn(\n 'my-0.5 first:mt-0 last:mb-0 gap-3 rounded-sm px-3 py-2 text-sm font-medium text-input-text-secondary flex w-full items-center hover:bg-input-bg--hover focus-visible:bg-input-bg--hover focus-visible:outline-none',\n isSelectAllFocused && 'bg-input-bg--hover',\n )}\n data-testid='spectral-multiselect-select-all-button'\n onClick={handleSelectAll}\n type='button'\n >\n {isAllSelected ? clearAllLabel : selectAllLabel}\n </button>\n <div className='mx-3 my-1 h-px bg-input-border' />\n </div>\n )}\n\n {groupedOptions.ungrouped.length > 0 && <div className='mb-1'>{groupedOptions.ungrouped.map((option, index) => renderOption(option, index))}</div>}\n\n {Object.entries(groupedOptions.groups).map(([groupName, groupOptions]) => (\n <div key={groupName} className='mb-1' data-testid='spectral-multiselect-group'>\n {(groupedOptions.ungrouped.length > 0 || Object.keys(groupedOptions.groups).indexOf(groupName) > 0) && <div className='mx-3 my-1 h-px bg-input-border' />}\n <div data-testid='spectral-multiselect-group-name' className='px-3 py-1 text-xs font-semibold text-input-text-secondary tracking-wide uppercase'>\n {groupName}\n </div>\n {groupOptions.map((option, _index) => renderOption(option, filteredOptions.indexOf(option)))}\n </div>\n ))}\n </>\n )}\n </div>\n </div>\n </Popover.Content>\n </Popover.Portal>\n </div>\n </Popover.Root>\n\n <ErrorMessage\n dataTestId='spectral-multiselect-error-message'\n id={errorMessageId}\n message={state === 'error' ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-multiselect-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\nMultiSelectBase.displayName = 'MultiSelectBase'\n"],"mappings":"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"}
1
+ {"version":3,"file":"MultiSelectBase.js","names":[],"sources":["../../src/components/MultiSelect/MultiSelectBase.tsx"],"sourcesContent":["import { CheckmarkIcon, ChevronDownIcon, CloseIcon, SearchIcon } from '@components/Icons'\nimport { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport * as Popover from '@radix-ui/react-popover'\nimport { useAutoDropdownHorizontalShift } from '@utils/dropdownPositioning'\nimport { EmptyState, ErrorMessage, getAriaProps, getDropdownSurfaceClasses, getDropdownWidthStyles, getErrorMessageId, getTriggerClasses, LoadingState, WarningMessage, useFormFieldId, type BaseFormFieldProps, type DropdownWidth, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useCallback, useEffect, useId, useMemo, useRef, useState, type ButtonHTMLAttributes, type ChangeEvent, type CSSProperties, type KeyboardEvent, type Ref } from 'react'\n\nexport type MultiSelectState = Exclude<FormFieldState, 'disabled'>\n\nexport interface MultiSelectOption {\n disabled?: boolean\n group?: string\n label: string\n value: string\n}\n\nexport interface MultiSelectBaseProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'onChange'> {\n clearAllLabel?: string\n closeOnSelect?: boolean\n dropdownWidth?: DropdownWidth\n emptyMessage?: string\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string\n label?: string\n loadingMessage?: string\n maxCount?: number\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n defaultValue?: string[]\n onChange?: (value: string[]) => void\n options: MultiSelectOption[]\n placeholder?: string\n required?: boolean\n searchPlaceholder?: string\n showClearAll?: boolean\n showSearch?: boolean\n showSelectAll?: boolean\n selectAllLabel?: string\n sortAlphabetically?: boolean\n state?: MultiSelectState\n value?: string[]\n warningMessage?: BaseFormFieldProps['errorMessage']\n 'aria-label'?: string\n 'aria-describedby'?: string\n}\n\nconst ICON_SIZE = 'h-4 w-4'\n\nconst getDropdownClasses = (): string => {\n return cn(\n 'max-h-80 z-50 overflow-hidden',\n getDropdownSurfaceClasses(),\n 'motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=open]:animate-in',\n 'motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=open]:fade-in-0',\n 'motion-safe:data-[state=closed]:zoom-out-95 motion-safe:data-[state=open]:zoom-in-95',\n 'motion-safe:data-[side=bottom]:slide-in-from-top-2',\n 'motion-safe:data-[side=top]:slide-in-from-bottom-2',\n 'origin-(--radix-popover-content-transform-origin)',\n )\n}\n\ntype FocusableItem = { type: 'search' } | { type: 'select-all' } | { type: 'option'; index: number; value: string } | { type: 'clear-all' }\n\nconst useKeyboardNavigation = (\n options: MultiSelectOption[],\n onClearAll: () => void,\n onClose: () => void,\n onSelect: (value: string) => void,\n onSelectAll: () => void,\n searchInputRef: React.RefObject<HTMLInputElement | null>,\n showSearch: boolean,\n showSelectAll: boolean,\n showClearAll: boolean,\n) => {\n const [focusedIndex, setFocusedIndex] = useState(-1)\n\n // Build a flat list of all focusable items\n const focusableItems = useMemo((): FocusableItem[] => {\n const items: FocusableItem[] = []\n\n if (showSearch) {\n items.push({ type: 'search' })\n }\n\n if (showSelectAll) {\n items.push({ type: 'select-all' })\n }\n\n options.forEach((option, index) => {\n if (!option.disabled) {\n items.push({ type: 'option', index, value: option.value })\n }\n })\n\n if (showClearAll) {\n items.push({ type: 'clear-all' })\n }\n\n return items\n }, [options, showSearch, showSelectAll, showClearAll])\n\n // Focus the appropriate element when focusedIndex changes\n const focusCurrentItem = useCallback(\n (index: number) => {\n if (index < 0 || index >= focusableItems.length) return\n const item = focusableItems[index]\n if (item.type === 'search') {\n searchInputRef.current?.focus()\n }\n },\n [focusableItems, searchInputRef],\n )\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLDivElement>) => {\n const currentItem = focusedIndex >= 0 && focusedIndex < focusableItems.length ? focusableItems[focusedIndex] : null\n\n // Don't prevent default for space in search input (allow typing spaces)\n if (event.key === ' ' && currentItem?.type === 'search') {\n return\n }\n\n // Don't prevent default for Enter in search input (allow form submission behavior)\n if (event.key === 'Enter' && currentItem?.type === 'search') {\n return\n }\n\n const keyHandlers: Record<string, () => void> = {\n ArrowDown: () => {\n event.preventDefault()\n const newIndex = Math.min(focusedIndex + 1, focusableItems.length - 1)\n setFocusedIndex(newIndex)\n focusCurrentItem(newIndex)\n },\n ArrowUp: () => {\n event.preventDefault()\n const newIndex = Math.max(focusedIndex - 1, 0)\n setFocusedIndex(newIndex)\n focusCurrentItem(newIndex)\n },\n Tab: () => {\n // Allow Tab to cycle through focusable items\n if (event.shiftKey) {\n if (focusedIndex <= 0) {\n // At start, close dropdown and return to trigger\n onClose()\n } else {\n event.preventDefault()\n const newIndex = focusedIndex - 1\n setFocusedIndex(newIndex)\n focusCurrentItem(newIndex)\n }\n } else {\n if (focusedIndex >= focusableItems.length - 1) {\n // At end, close dropdown and move to next element\n onClose()\n } else {\n event.preventDefault()\n const newIndex = focusedIndex + 1\n setFocusedIndex(newIndex)\n focusCurrentItem(newIndex)\n }\n }\n },\n Enter: () => {\n event.preventDefault()\n if (focusedIndex >= 0 && focusedIndex < focusableItems.length) {\n const item = focusableItems[focusedIndex]\n if (item.type === 'select-all') {\n onSelectAll()\n } else if (item.type === 'clear-all') {\n onClearAll()\n } else if (item.type === 'option') {\n onSelect(item.value)\n }\n }\n },\n ' ': () => {\n event.preventDefault()\n if (focusedIndex >= 0 && focusedIndex < focusableItems.length) {\n const item = focusableItems[focusedIndex]\n if (item.type === 'select-all') {\n onSelectAll()\n } else if (item.type === 'clear-all') {\n onClearAll()\n } else if (item.type === 'option') {\n onSelect(item.value)\n }\n }\n },\n Escape: () => {\n event.preventDefault()\n onClose()\n },\n }\n\n const handler = keyHandlers[event.key]\n if (handler) {\n handler()\n }\n },\n [focusableItems, focusedIndex, onSelect, onSelectAll, onClearAll, onClose, focusCurrentItem],\n )\n\n // Get the option index for visual focus styling (accounting for select-all offset)\n const getOptionFocusIndex = useCallback(\n (optionIndex: number): boolean => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return false\n const item = focusableItems[focusedIndex]\n return item.type === 'option' && item.index === optionIndex\n },\n [focusedIndex, focusableItems],\n )\n\n const isSearchFocused = useMemo(() => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return false\n return focusableItems[focusedIndex].type === 'search'\n }, [focusedIndex, focusableItems])\n\n const isSelectAllFocused = useMemo(() => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return false\n return focusableItems[focusedIndex].type === 'select-all'\n }, [focusedIndex, focusableItems])\n\n const isClearAllFocused = useMemo(() => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return false\n return focusableItems[focusedIndex].type === 'clear-all'\n }, [focusedIndex, focusableItems])\n\n const focusedOptionValue = useMemo(() => {\n if (focusedIndex < 0 || focusedIndex >= focusableItems.length) return null\n const item = focusableItems[focusedIndex]\n return item.type === 'option' ? item.value : null\n }, [focusedIndex, focusableItems])\n\n return {\n focusedIndex,\n setFocusedIndex,\n handleKeyDown,\n getOptionFocusIndex,\n isSearchFocused,\n isSelectAllFocused,\n isClearAllFocused,\n focusedOptionValue,\n }\n}\n\nexport const MultiSelectBase = ({\n className,\n clearAllLabel = 'Clear all',\n closeOnSelect = false,\n dropdownWidth = 'trigger',\n emptyMessage = 'No options found',\n errorMessage,\n defaultValue = [],\n disabled,\n id,\n label,\n loadingMessage = 'Loading options…',\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxCount = 3,\n name,\n onChange,\n options = [],\n placeholder = 'Select options',\n ref,\n searchPlaceholder = 'Search options…',\n selectAllLabel = 'Select all',\n showClearAll = true,\n showSearch = true,\n showSelectAll = true,\n sortAlphabetically = false,\n state = 'default',\n value: valueProp,\n warningMessage,\n 'aria-label': ariaLabel,\n 'aria-describedby': ariaDescribedBy,\n ...props\n}: MultiSelectBaseProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const generatedId = useId()\n const fallbackName = name ?? `multiselect-${generatedId}`\n const multiSelectId = useFormFieldId(id, fallbackName)\n const listboxId = `${multiSelectId}-listbox`\n const errorMessageId = getErrorMessageId(multiSelectId)\n const warningMessageId = `${multiSelectId}-warning`\n const messageId = state === 'error' ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n\n const [isOpen, setIsOpen] = useState(false)\n const { dropdownShiftStyle, setDropdownElement } = useAutoDropdownHorizontalShift(isOpen)\n const [searchValue, setSearchValue] = useState('')\n const [value, setValue] = useUncontrolledState<string[]>({\n value: valueProp,\n defaultValue,\n onChange,\n })\n\n const searchInputRef = useRef<HTMLInputElement>(null)\n\n const isDisabled = Boolean(disabled)\n const isLoading = state === 'loading'\n const ariaProps = getAriaProps(state, ariaDescribedBy, props.required, messageId)\n const { dropdownOverflowStyle, dropdownWidthMode, resolvedDropdownWidth } = getDropdownWidthStyles({\n dropdownWidth,\n triggerWidth: 'var(--radix-popover-trigger-width)',\n })\n\n const filteredOptions = useMemo(() => {\n let filtered = options.filter((option) => option.label.toLowerCase().includes(searchValue.toLowerCase()))\n\n if (sortAlphabetically) {\n filtered = [...filtered].sort((a, b) => a.label.localeCompare(b.label))\n }\n\n return filtered\n }, [options, searchValue, sortAlphabetically])\n\n const groupedOptions = useMemo(() => {\n const groups: Record<string, MultiSelectOption[]> = {}\n const ungrouped: MultiSelectOption[] = []\n\n filteredOptions.forEach((option) => {\n if (option.group) {\n if (!groups[option.group]) {\n groups[option.group] = []\n }\n groups[option.group].push(option)\n } else {\n ungrouped.push(option)\n }\n })\n\n return { groups, ungrouped, hasGroups: Object.keys(groups).length > 0 }\n }, [filteredOptions])\n\n const toggleOption = useCallback(\n (optionValue: string) => {\n const option = options.find((o) => o.value === optionValue)\n if (option?.disabled) return\n\n const newValue = value.includes(optionValue) ? value.filter((v) => v !== optionValue) : [...value, optionValue]\n\n setValue(newValue)\n\n if (closeOnSelect) {\n setIsOpen(false)\n }\n },\n [closeOnSelect, options, setValue, value],\n )\n\n const handleSelectAll = useCallback(() => {\n const allValues = options.filter((o) => !o.disabled).map((o) => o.value)\n const isAllSelected = allValues.every((v) => value.includes(v))\n\n if (isAllSelected) {\n setValue([])\n } else {\n setValue(allValues)\n }\n }, [options, setValue, value])\n\n const handleClearAll = useCallback(() => {\n setValue([])\n }, [setValue])\n\n // Check if all non-disabled options are selected\n const allSelectableValues = useMemo(() => options.filter((o) => !o.disabled).map((o) => o.value), [options])\n const isAllSelected = allSelectableValues.length > 0 && allSelectableValues.every((v) => value.includes(v))\n\n const { focusedOptionValue, getOptionFocusIndex, handleKeyDown, isSelectAllFocused, setFocusedIndex } = useKeyboardNavigation(\n filteredOptions,\n handleClearAll,\n () => setIsOpen(false),\n toggleOption,\n handleSelectAll,\n searchInputRef,\n showSearch,\n showSelectAll,\n false, // No separate clear-all button in dropdown\n )\n\n // Set initial focus index when dropdown opens/closes\n useEffect(() => {\n if (isOpen) {\n setFocusedIndex(0)\n } else {\n setFocusedIndex(-1)\n }\n }, [isOpen, setFocusedIndex])\n\n const handleSearchChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {\n setSearchValue(e.target.value)\n }, [])\n\n const renderSelectedItems = () => {\n if (value.length === 0) {\n return <span className='min-h-8 flex items-center text-input-text-placeholder'>{placeholder}</span>\n }\n\n const displayedValues = value.slice(0, maxCount)\n const remainingCount = value.length - maxCount\n\n return (\n <div className='gap-1 flex flex-wrap items-center overflow-hidden'>\n {displayedValues.map((val) => {\n const option = options.find((o) => o.value === val)\n if (!option) return null\n\n return (\n <span\n className='gap-1 px-2 py-1 rounded-md text-xs max-w-48 inline-flex items-center bg-input-bg--selected text-input-text'\n key={val}\n >\n <span className='truncate'>{option.label}</span>\n <button\n aria-label={`Remove ${option.label}`}\n className='hover:text-danger rounded-sm cursor-pointer'\n data-testid='spectral-multiselect-remove-item-button'\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n toggleOption(val)\n }}\n onPointerDown={(e) => {\n e.stopPropagation()\n }}\n type='button'\n >\n <CloseIcon size={12} />\n </button>\n </span>\n )\n })}\n {remainingCount > 0 && <span className='text-input-text-secondary text-xs py-1 flex items-center tabular-nums'>+{remainingCount} more</span>}\n </div>\n )\n }\n\n const renderOption = (option: MultiSelectOption, index: number) => {\n const isSelected = value.includes(option.value)\n const isFocused = getOptionFocusIndex(index)\n const optionId = `${listboxId}-option-${option.value}`\n\n return (\n <button\n aria-selected={isSelected}\n className={cn(\n 'my-0.5 first:mt-0 last:mb-0 gap-3 rounded-sm px-3 py-2 text-sm flex w-full items-center text-left hover:bg-input-bg--hover focus-visible:bg-input-bg--hover focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n isFocused && 'bg-input-bg--hover',\n isSelected && 'font-medium text-input-text',\n )}\n disabled={option.disabled}\n id={optionId}\n key={option.value}\n onClick={() => toggleOption(option.value)}\n role='option'\n type='button'\n >\n <div\n data-testid='spectral-multiselect-selected-indicator'\n className={cn('w-4 h-4 rounded flex items-center justify-center border border-input-border', isSelected && 'bg-primary border-primary')}\n >\n {isSelected && <CheckmarkIcon size={12} />}\n </div>\n <span>{option.label}</span>\n </button>\n )\n }\n\n const getCSSCustomProperties = () => ({\n '--multiselect-border-radius': '0.5rem',\n '--multiselect-trigger-height': '3rem',\n '--multiselect-dropdown-max-height': '20rem',\n })\n\n return (\n <div\n className='w-full'\n data-testid='spectral-multiselect-root'\n >\n {label && (\n <Label\n className={cn('mb-2 block text-text-primary', isDisabled && 'text-text-secondary')}\n data-testid='spectral-multiselect-label'\n htmlFor={multiSelectId}\n >\n {label}\n </Label>\n )}\n <Popover.Root\n open={isOpen}\n onOpenChange={setIsOpen}\n >\n <div\n className='relative'\n data-testid='spectral-multiselect-wrapper'\n onKeyDown={isOpen ? handleKeyDown : undefined}\n role='none'\n >\n <Popover.Trigger asChild>\n <button\n aria-activedescendant={isOpen && focusedOptionValue ? `${listboxId}-option-${focusedOptionValue}` : undefined}\n aria-controls={isOpen ? listboxId : undefined}\n aria-expanded={isOpen}\n aria-label={ariaLabel ?? label}\n className={cn(getTriggerClasses(isOpen, state, className), 'max-h-22 py-2 text-sm')}\n data-state={state}\n data-testid='spectral-multiselect-trigger'\n disabled={isDisabled}\n id={multiSelectId}\n name={name}\n ref={ref}\n role='combobox' // oxlint-disable-line jsx-a11y/prefer-tag-over-role -- trigger uses button-based combobox semantics for listbox popup\n style={getCSSCustomProperties() as CSSProperties}\n type='button'\n {...ariaProps}\n {...props}\n >\n <div\n className='min-w-0 flex-1 overflow-hidden'\n data-testid='spectral-multiselect-selected-items'\n >\n {renderSelectedItems()}\n </div>\n <div className='gap-2 ml-2 flex shrink-0 items-center'>\n <ChevronDownIcon\n className={cn('text-input-icon transition-transform duration-200', isOpen && 'rotate-180')}\n size={20}\n />\n </div>\n </button>\n </Popover.Trigger>\n {showClearAll && value.length > 0 && (\n <button\n aria-label='Clear all selections'\n className='right-10 text-input-icon hover:text-input-icon--hover rounded-sm absolute top-1/2 z-10 -translate-y-1/2 cursor-pointer focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-1 disabled:pointer-events-none disabled:opacity-50'\n data-testid='spectral-multiselect-clear-all-button'\n disabled={isDisabled}\n onClick={(e) => {\n e.stopPropagation()\n handleClearAll()\n document.getElementById(multiSelectId)?.focus()\n }}\n type='button'\n >\n <CloseIcon size={12} />\n </button>\n )}\n\n <Popover.Portal>\n <Popover.Content\n align='start'\n avoidCollisions\n className={getDropdownClasses()}\n collisionPadding={10}\n data-dropdown-width-mode={dropdownWidthMode}\n data-dropdown-width-value={dropdownWidthMode === 'custom' ? dropdownWidth : undefined}\n data-testid='spectral-multiselect-dropdown'\n onOpenAutoFocus={(e) => {\n e.preventDefault()\n if (showSearch) {\n searchInputRef.current?.focus()\n }\n }}\n side='bottom'\n sideOffset={4}\n ref={setDropdownElement}\n style={{\n width: resolvedDropdownWidth,\n ...(dropdownWidth === 'trigger' ? {} : dropdownOverflowStyle),\n ...dropdownShiftStyle,\n }}\n >\n <div className='p-1'>\n {showSearch && (\n <div className='mb-2 relative'>\n <SearchIcon className={cn(ICON_SIZE, 'left-3 text-input-icon absolute top-1/2 -translate-y-1/2')} />\n <input\n aria-label='Search options'\n className='pl-9 pr-3 py-2 text-sm rounded-md focus-visible:ring-black w-full border border-input-border bg-input-bg focus-visible:border-input-border--focus focus-visible:ring-1 focus-visible:outline-none'\n data-testid='spectral-multiselect-search-input'\n onChange={handleSearchChange}\n placeholder={searchPlaceholder}\n ref={searchInputRef}\n type='text'\n value={searchValue}\n />\n </div>\n )}\n <div\n aria-multiselectable='true'\n className='max-h-64 overflow-y-auto'\n id={listboxId}\n role='listbox' // oxlint-disable-line jsx-a11y/prefer-tag-over-role -- custom multi-select uses ARIA listbox semantics with option children\n >\n {isLoading ? (\n <LoadingState\n className='text-sm'\n message={loadingMessage}\n data-testid='spectral-multiselect-loading'\n />\n ) : filteredOptions.length === 0 ? (\n <EmptyState\n className='text-sm'\n data-testid='spectral-multiselect-empty-message'\n message={emptyMessage}\n />\n ) : (\n <>\n {showSelectAll && (\n <div className='mb-1'>\n <button\n className={cn(\n 'my-0.5 first:mt-0 last:mb-0 gap-3 rounded-sm px-3 py-2 text-sm font-medium text-input-text-secondary flex w-full items-center hover:bg-input-bg--hover focus-visible:bg-input-bg--hover focus-visible:outline-none',\n isSelectAllFocused && 'bg-input-bg--hover',\n )}\n data-testid='spectral-multiselect-select-all-button'\n onClick={handleSelectAll}\n type='button'\n >\n {isAllSelected ? clearAllLabel : selectAllLabel}\n </button>\n <div className='mx-3 my-1 h-px bg-input-border' />\n </div>\n )}\n\n {groupedOptions.ungrouped.length > 0 && <div className='mb-1'>{groupedOptions.ungrouped.map((option, index) => renderOption(option, index))}</div>}\n\n {Object.entries(groupedOptions.groups).map(([groupName, groupOptions]) => (\n <div\n key={groupName}\n className='mb-1'\n data-testid='spectral-multiselect-group'\n >\n {(groupedOptions.ungrouped.length > 0 || Object.keys(groupedOptions.groups).indexOf(groupName) > 0) && <div className='mx-3 my-1 h-px bg-input-border' />}\n <div\n data-testid='spectral-multiselect-group-name'\n className='px-3 py-1 text-xs font-semibold text-input-text-secondary tracking-wide uppercase'\n >\n {groupName}\n </div>\n {groupOptions.map((option, _index) => renderOption(option, filteredOptions.indexOf(option)))}\n </div>\n ))}\n </>\n )}\n </div>\n </div>\n </Popover.Content>\n </Popover.Portal>\n </div>\n </Popover.Root>\n\n <ErrorMessage\n dataTestId='spectral-multiselect-error-message'\n id={errorMessageId}\n message={state === 'error' ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-multiselect-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\nMultiSelectBase.displayName = 'MultiSelectBase'\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MultiSelect.js","names":[],"sources":["../src/components/MultiSelect/MultiSelect.tsx"],"sourcesContent":["import { type Ref } from 'react'\nimport { MultiSelectBase, type MultiSelectBaseProps, type MultiSelectOption } from './MultiSelectBase'\n\nexport interface MultiSelectProps extends Omit<MultiSelectBaseProps, 'defaultValue' | 'onChange' | 'options' | 'value'> {\n defaultValue?: string[]\n emptyText?: string\n loading?: boolean\n onChange?: (value: string[]) => void\n onSearchChange?: (search: string) => void\n onValueChange?: (value: string[]) => void\n options: {\n disabled?: boolean\n group?: string\n label: string\n value: string\n }[]\n sortAlphabetically?: boolean\n value?: string[]\n}\n\nexport const MultiSelect = ({\n emptyText = 'No matches found.',\n loading = false,\n onChange,\n onValueChange,\n options,\n defaultValue,\n ref,\n state,\n value,\n ...props\n}: MultiSelectProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const baseOptions: MultiSelectOption[] = options.map((option) => ({\n disabled: option.disabled ?? false,\n group: option.group,\n label: option.label,\n value: option.value,\n }))\n\n const derivedState = loading ? 'loading' : state\n\n const handleChange = (nextValue: string[]) => {\n onValueChange?.(nextValue)\n onChange?.(nextValue)\n }\n\n return <MultiSelectBase data-disabled={props.disabled} defaultValue={defaultValue} disabled={props.disabled} emptyMessage={emptyText} onChange={handleChange} options={baseOptions} ref={ref} state={derivedState} value={value} {...props} />\n}\nMultiSelect.displayName = 'MultiSelect'\n"],"mappings":";;;;;;AAoBA,MAAa,eAAe,EAC1B,YAAY,qBACZ,UAAU,OACV,UACA,eACA,SACA,cACA,KACA,OACA,OACA,GAAG,YAGC;CACJ,MAAM,cAAmC,QAAQ,KAAK,YAAY;EAChE,UAAU,OAAO,YAAY;EAC7B,OAAO,OAAO;EACd,OAAO,OAAO;EACd,OAAO,OAAO;EACf,EAAE;CAEH,MAAM,eAAe,UAAU,YAAY;CAE3C,MAAM,gBAAgB,cAAwB;AAC5C,kBAAgB,UAAU;AAC1B,aAAW,UAAU;;AAGvB,QAAO,oBAAC,iBAAD;EAAiB,iBAAe,MAAM;EAAwB;EAAc,UAAU,MAAM;EAAU,cAAc;EAAW,UAAU;EAAc,SAAS;EAAkB;EAAK,OAAO;EAAqB;EAAO,GAAI;EAAS;;AAEhP,YAAY,cAAc"}
1
+ {"version":3,"file":"MultiSelect.js","names":[],"sources":["../src/components/MultiSelect/MultiSelect.tsx"],"sourcesContent":["import { type Ref } from 'react'\nimport { MultiSelectBase, type MultiSelectBaseProps, type MultiSelectOption } from './MultiSelectBase'\n\nexport interface MultiSelectProps extends Omit<MultiSelectBaseProps, 'defaultValue' | 'onChange' | 'options' | 'value'> {\n defaultValue?: string[]\n emptyText?: string\n loading?: boolean\n onChange?: (value: string[]) => void\n onSearchChange?: (search: string) => void\n onValueChange?: (value: string[]) => void\n options: {\n disabled?: boolean\n group?: string\n label: string\n value: string\n }[]\n sortAlphabetically?: boolean\n value?: string[]\n}\n\nexport const MultiSelect = ({\n emptyText = 'No matches found.',\n loading = false,\n onChange,\n onValueChange,\n options,\n defaultValue,\n ref,\n state,\n value,\n ...props\n}: MultiSelectProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const baseOptions: MultiSelectOption[] = options.map((option) => ({\n disabled: option.disabled ?? false,\n group: option.group,\n label: option.label,\n value: option.value,\n }))\n\n const derivedState = loading ? 'loading' : state\n\n const handleChange = (nextValue: string[]) => {\n onValueChange?.(nextValue)\n onChange?.(nextValue)\n }\n\n return (\n <MultiSelectBase\n data-disabled={props.disabled}\n defaultValue={defaultValue}\n disabled={props.disabled}\n emptyMessage={emptyText}\n onChange={handleChange}\n options={baseOptions}\n ref={ref}\n state={derivedState}\n value={value}\n {...props}\n />\n )\n}\nMultiSelect.displayName = 'MultiSelect'\n"],"mappings":";;;;;;AAoBA,MAAa,eAAe,EAC1B,YAAY,qBACZ,UAAU,OACV,UACA,eACA,SACA,cACA,KACA,OACA,OACA,GAAG,YAGC;CACJ,MAAM,cAAmC,QAAQ,KAAK,YAAY;EAChE,UAAU,OAAO,YAAY;EAC7B,OAAO,OAAO;EACd,OAAO,OAAO;EACd,OAAO,OAAO;EACf,EAAE;CAEH,MAAM,eAAe,UAAU,YAAY;CAE3C,MAAM,gBAAgB,cAAwB;AAC5C,kBAAgB,UAAU;AAC1B,aAAW,UAAU;;AAGvB,QACE,oBAAC,iBAAD;EACE,iBAAe,MAAM;EACP;EACd,UAAU,MAAM;EAChB,cAAc;EACd,UAAU;EACV,SAAS;EACJ;EACL,OAAO;EACA;EACP,GAAI;EACJ;;AAGN,YAAY,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.d.ts","names":[],"sources":["../src/components/Popover/Popover.tsx"],"mappings":";;;;;;KAIY,mBAAA,GAAsB,wBAAA,QAAgC,gBAAA,CAAiB,OAAA;EACjF,KAAA;AAAA;AAAA,cAGW,OAAA;EAAA,GAAO;AAAA,GAAkB,wBAAA,QAAgC,gBAAA,CAAiB,IAAA,MAAK,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAI/E,cAAA;EAAA,GAAc;AAAA,GAAkB,wBAAA,QAAgC,gBAAA,CAAiB,OAAA,MAAQ,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAIzF,cAAA;EAAc,KAAA;EAAA,SAAA;EAAA,gBAAA;EAAA,IAAA;EAAA,UAAA;EAAA,KAAA;EAAA,GAAA;AAAA,GAAuH,mBAAA,KAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cA6BxJ,aAAA;EAAA,GAAa;AAAA,GAAkB,wBAAA,QAAgC,gBAAA,CAAiB,MAAA,MAAO,oBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"Popover.d.ts","names":[],"sources":["../src/components/Popover/Popover.tsx"],"mappings":";;;;;;KAIY,mBAAA,GAAsB,wBAAA,QAAgC,gBAAA,CAAiB,OAAA;EACjF,KAAA;AAAA;AAAA,cAGW,OAAA;EAAA,GAAO;AAAA,GAAkB,wBAAA,QAAgC,gBAAA,CAAiB,IAAA,MAAK,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAU/E,cAAA;EAAA,GAAc;AAAA,GAAkB,wBAAA,QAAgC,gBAAA,CAAiB,OAAA,MAAQ,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAUzF,cAAA;EAAc,KAAA;EAAA,SAAA;EAAA,gBAAA;EAAA,IAAA;EAAA,UAAA;EAAA,KAAA;EAAA,GAAA;AAAA,GAAuH,mBAAA,KAAmB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cA6BxJ,aAAA;EAAA,GAAa;AAAA,GAAkB,wBAAA,QAAgC,gBAAA,CAAiB,MAAA,MAAO,oBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.js","names":[],"sources":["../src/components/Popover/Popover.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type CSSProperties } from 'react'\n\nexport type PopoverContentProps = ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & {\n width?: number | string\n}\n\nexport const Popover = ({ ...props }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>) => {\n return <PopoverPrimitive.Root data-slot='popover' data-testid='spectral-popover' {...props} />\n}\n\nexport const PopoverTrigger = ({ ...props }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Trigger>) => {\n return <PopoverPrimitive.Trigger data-slot='popover-trigger' data-testid='spectral-popover-trigger' {...props} />\n}\n\nexport const PopoverContent = ({ align = 'center', className, collisionPadding = 8, side = 'bottom', sideOffset = 4, width = 'w-fit', ...props }: PopoverContentProps) => {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n align={align}\n collisionPadding={collisionPadding}\n data-slot='popover-content'\n data-testid='spectral-popover-content'\n side={side}\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover-bg text-popover-text motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=open]:animate-in',\n 'motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[state=closed]:zoom-out-95 motion-safe:data-[state=open]:fade-in-0 motion-safe:data-[state=open]:zoom-in-95',\n 'z-50 h-fit motion-safe:data-[side=left]:slide-in-from-right-2 motion-safe:data-[side=right]:slide-in-from-left-2 motion-safe:data-[side=top]:slide-in-from-bottom-2',\n 'rounded-lg p-4 max-h-(--radix-popover-content-available-height) origin-[--radix-popover-content-transform-origin] border-none',\n 'shadow-md w-(--popover-width) overflow-x-hidden overflow-y-auto outline-none',\n className,\n )}\n style={\n {\n '--popover-width': typeof width === 'number' ? `${width}px` : width === 'w-fit' ? '320px' : width,\n } as CSSProperties\n }\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nexport const PopoverAnchor = ({ ...props }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Anchor>) => {\n return <PopoverPrimitive.Anchor data-slot='popover-anchor' {...props} />\n}\n"],"mappings":";;;;;;;AAQA,MAAa,WAAW,EAAE,GAAG,YAAoE;AAC/F,QAAO,oBAAC,iBAAiB,MAAlB;EAAuB,aAAU;EAAU,eAAY;EAAmB,GAAI;EAAS;;AAGhG,MAAa,kBAAkB,EAAE,GAAG,YAAuE;AACzG,QAAO,oBAAC,iBAAiB,SAAlB;EAA0B,aAAU;EAAkB,eAAY;EAA2B,GAAI;EAAS;;AAGnH,MAAa,kBAAkB,EAAE,QAAQ,UAAU,WAAW,mBAAmB,GAAG,OAAO,UAAU,aAAa,GAAG,QAAQ,SAAS,GAAG,YAAiC;AACxK,QACE,oBAAC,iBAAiB,QAAlB,YACE,oBAAC,iBAAiB,SAAlB;EACS;EACW;EAClB,aAAU;EACV,eAAY;EACN;EACM;EACZ,WAAW,GACT,mKACA,mLACA,uKACA,iIACA,gFACA,UACD;EACD,OACE,EACE,mBAAmB,OAAO,UAAU,WAAW,GAAG,MAAM,MAAM,UAAU,UAAU,UAAU,OAC7F;EAEH,GAAI;EACJ,GACsB;;AAI9B,MAAa,iBAAiB,EAAE,GAAG,YAAsE;AACvG,QAAO,oBAAC,iBAAiB,QAAlB;EAAyB,aAAU;EAAiB,GAAI;EAAS"}
1
+ {"version":3,"file":"Popover.js","names":[],"sources":["../src/components/Popover/Popover.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type CSSProperties } from 'react'\n\nexport type PopoverContentProps = ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & {\n width?: number | string\n}\n\nexport const Popover = ({ ...props }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Root>) => {\n return (\n <PopoverPrimitive.Root\n data-slot='popover'\n data-testid='spectral-popover'\n {...props}\n />\n )\n}\n\nexport const PopoverTrigger = ({ ...props }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Trigger>) => {\n return (\n <PopoverPrimitive.Trigger\n data-slot='popover-trigger'\n data-testid='spectral-popover-trigger'\n {...props}\n />\n )\n}\n\nexport const PopoverContent = ({ align = 'center', className, collisionPadding = 8, side = 'bottom', sideOffset = 4, width = 'w-fit', ...props }: PopoverContentProps) => {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n align={align}\n collisionPadding={collisionPadding}\n data-slot='popover-content'\n data-testid='spectral-popover-content'\n side={side}\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover-bg text-popover-text motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=open]:animate-in',\n 'motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[state=closed]:zoom-out-95 motion-safe:data-[state=open]:fade-in-0 motion-safe:data-[state=open]:zoom-in-95',\n 'z-50 h-fit motion-safe:data-[side=left]:slide-in-from-right-2 motion-safe:data-[side=right]:slide-in-from-left-2 motion-safe:data-[side=top]:slide-in-from-bottom-2',\n 'rounded-lg p-4 max-h-(--radix-popover-content-available-height) origin-[--radix-popover-content-transform-origin] border-none',\n 'shadow-md w-(--popover-width) overflow-x-hidden overflow-y-auto outline-none',\n className,\n )}\n style={\n {\n '--popover-width': typeof width === 'number' ? `${width}px` : width === 'w-fit' ? '320px' : width,\n } as CSSProperties\n }\n {...props}\n />\n </PopoverPrimitive.Portal>\n )\n}\n\nexport const PopoverAnchor = ({ ...props }: ComponentPropsWithoutRef<typeof PopoverPrimitive.Anchor>) => {\n return (\n <PopoverPrimitive.Anchor\n data-slot='popover-anchor'\n {...props}\n />\n )\n}\n"],"mappings":";;;;;;;AAQA,MAAa,WAAW,EAAE,GAAG,YAAoE;AAC/F,QACE,oBAAC,iBAAiB,MAAlB;EACE,aAAU;EACV,eAAY;EACZ,GAAI;EACJ;;AAIN,MAAa,kBAAkB,EAAE,GAAG,YAAuE;AACzG,QACE,oBAAC,iBAAiB,SAAlB;EACE,aAAU;EACV,eAAY;EACZ,GAAI;EACJ;;AAIN,MAAa,kBAAkB,EAAE,QAAQ,UAAU,WAAW,mBAAmB,GAAG,OAAO,UAAU,aAAa,GAAG,QAAQ,SAAS,GAAG,YAAiC;AACxK,QACE,oBAAC,iBAAiB,QAAlB,YACE,oBAAC,iBAAiB,SAAlB;EACS;EACW;EAClB,aAAU;EACV,eAAY;EACN;EACM;EACZ,WAAW,GACT,mKACA,mLACA,uKACA,iIACA,gFACA,UACD;EACD,OACE,EACE,mBAAmB,OAAO,UAAU,WAAW,GAAG,MAAM,MAAM,UAAU,UAAU,UAAU,OAC7F;EAEH,GAAI;EACJ,GACsB;;AAI9B,MAAa,iBAAiB,EAAE,GAAG,YAAsE;AACvG,QACE,oBAAC,iBAAiB,QAAlB;EACE,aAAU;EACV,GAAI;EACJ"}
@@ -15,10 +15,7 @@ const RadioButton = ({ asChild = false, activeColor = "default", activeTextColor
15
15
  };
16
16
  const baseProps = {
17
17
  ...rest,
18
- className: cn(`gap-2 rounded-md text-sm font-medium h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4 inline-flex items-center justify-center border border-toggle-border
19
- bg-toggle-bg text-toggle-text shadow-none transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:z-10
20
- focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:border-toggle-border--active active:bg-toggle-bg--active active:text-toggle-text--active
21
- disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 data-[variant=outline]:[--color-toggle-border:var(--color-toggle-outline-border)`, expanded && "w-full", isKeptActive && "data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active", className),
18
+ className: cn(`gap-2 rounded-md text-sm font-medium h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4 data-[variant=outline]:[--color-toggle-border:var(--color-toggle-outline-border) inline-flex items-center justify-center border border-toggle-border bg-toggle-bg text-toggle-text shadow-none transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:border-toggle-border--active active:bg-toggle-bg--active active:text-toggle-text--active disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`, expanded && "w-full", isKeptActive && "data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active", className),
22
19
  style: {
23
20
  ...getActiveColorStyle(activeColor, activeTextColor),
24
21
  ...style
@@ -1 +1 @@
1
- {"version":3,"file":"RadioButton.js","names":[],"sources":["../src/components/RadioButton/RadioButton.tsx"],"sourcesContent":["import { Slot, type AsChildProp } from '@primitives/slot'\nimport { getActiveColorStyle, type ActiveColor, type ActiveTextColor } from '@utils/activeColorStyle'\nimport { cn } from '@utils/twUtils'\nimport { type ButtonHTMLAttributes, type MouseEvent, type ReactNode, type Ref } from 'react'\n\nexport interface RadioButtonProps extends AsChildProp, Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onSelect' | 'type'> {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n checked?: boolean\n children: ReactNode\n expanded?: boolean\n isKeptActive?: boolean\n onCheckedChange?: (checked: boolean) => void\n onSelect?: (checked: boolean) => void\n variant?: 'default' | 'outline'\n}\n\nexport const RadioButton = ({\n asChild = false,\n activeColor = 'default',\n activeTextColor,\n checked = false,\n children,\n className,\n disabled = false,\n expanded = false,\n isKeptActive = false,\n onCheckedChange,\n onClick,\n onSelect,\n ref,\n variant = 'default',\n style,\n ...rest\n}: RadioButtonProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented || disabled) return\n\n onCheckedChange?.(true)\n onSelect?.(true)\n }\n\n const baseProps = {\n ...rest,\n className: cn(\n `gap-2 rounded-md text-sm font-medium h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4 inline-flex items-center justify-center border border-toggle-border\n bg-toggle-bg text-toggle-text shadow-none transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:z-10\n focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:border-toggle-border--active active:bg-toggle-bg--active active:text-toggle-text--active\n disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 data-[variant=outline]:[--color-toggle-border:var(--color-toggle-outline-border)`,\n expanded && 'w-full',\n isKeptActive && 'data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active',\n className,\n ),\n style: { ...getActiveColorStyle(activeColor, activeTextColor), ...style },\n disabled,\n onClick: handleClick,\n role: 'radio',\n 'aria-checked': checked,\n 'data-state': checked ? 'on' : 'off',\n 'data-testid': 'spectral-radio-button',\n 'data-variant': variant,\n }\n\n if (asChild) {\n return (\n <Slot ref={ref as Ref<HTMLElement>} {...baseProps}>\n {children}\n </Slot>\n )\n }\n\n return (\n <button ref={ref} {...baseProps} type='button'>\n {children}\n </button>\n )\n}\n\nRadioButton.displayName = 'RadioButton'\n"],"mappings":";;;;;;;;AAiBA,MAAa,eAAe,EAC1B,UAAU,OACV,cAAc,WACd,iBACA,UAAU,OACV,UACA,WACA,WAAW,OACX,WAAW,OACX,eAAe,OACf,iBACA,SACA,UACA,KACA,UAAU,WACV,OACA,GAAG,WAGC;CACJ,MAAM,eAAe,UAAyC;AAC5D,YAAU,MAAM;AAChB,MAAI,MAAM,oBAAoB,SAAU;AAExC,oBAAkB,KAAK;AACvB,aAAW,KAAK;;CAGlB,MAAM,YAAY;EAChB,GAAG;EACH,WAAW,GACT;;;mNAIA,YAAY,UACZ,gBAAgB,8HAChB,UACD;EACD,OAAO;GAAE,GAAG,oBAAoB,aAAa,gBAAgB;GAAE,GAAG;GAAO;EACzE;EACA,SAAS;EACT,MAAM;EACN,gBAAgB;EAChB,cAAc,UAAU,OAAO;EAC/B,eAAe;EACf,gBAAgB;EACjB;AAED,KAAI,QACF,QACE,oBAAC,MAAD;EAAW;EAAyB,GAAI;EACrC;EACI;AAIX,QACE,oBAAC,UAAD;EAAa;EAAK,GAAI;EAAW,MAAK;EACnC;EACM;;AAIb,YAAY,cAAc"}
1
+ {"version":3,"file":"RadioButton.js","names":[],"sources":["../src/components/RadioButton/RadioButton.tsx"],"sourcesContent":["import { Slot, type AsChildProp } from '@primitives/slot'\nimport { getActiveColorStyle, type ActiveColor, type ActiveTextColor } from '@utils/activeColorStyle'\nimport { cn } from '@utils/twUtils'\nimport { type ButtonHTMLAttributes, type MouseEvent, type ReactNode, type Ref } from 'react'\n\nexport interface RadioButtonProps extends AsChildProp, Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onSelect' | 'type'> {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n checked?: boolean\n children: ReactNode\n expanded?: boolean\n isKeptActive?: boolean\n onCheckedChange?: (checked: boolean) => void\n onSelect?: (checked: boolean) => void\n variant?: 'default' | 'outline'\n}\n\nexport const RadioButton = ({\n asChild = false,\n activeColor = 'default',\n activeTextColor,\n checked = false,\n children,\n className,\n disabled = false,\n expanded = false,\n isKeptActive = false,\n onCheckedChange,\n onClick,\n onSelect,\n ref,\n variant = 'default',\n style,\n ...rest\n}: RadioButtonProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (event.defaultPrevented || disabled) return\n\n onCheckedChange?.(true)\n onSelect?.(true)\n }\n\n const baseProps = {\n ...rest,\n className: cn(\n `gap-2 rounded-md text-sm font-medium h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4 data-[variant=outline]:[--color-toggle-border:var(--color-toggle-outline-border) inline-flex items-center justify-center border border-toggle-border bg-toggle-bg text-toggle-text shadow-none transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:border-toggle-border--active active:bg-toggle-bg--active active:text-toggle-text--active disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n expanded && 'w-full',\n isKeptActive && 'data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active',\n className,\n ),\n style: { ...getActiveColorStyle(activeColor, activeTextColor), ...style },\n disabled,\n onClick: handleClick,\n role: 'radio',\n 'aria-checked': checked,\n 'data-state': checked ? 'on' : 'off',\n 'data-testid': 'spectral-radio-button',\n 'data-variant': variant,\n }\n\n if (asChild) {\n return (\n <Slot\n ref={ref as Ref<HTMLElement>}\n {...baseProps}\n >\n {children}\n </Slot>\n )\n }\n\n return (\n <button\n ref={ref}\n {...baseProps}\n type='button'\n >\n {children}\n </button>\n )\n}\n\nRadioButton.displayName = 'RadioButton'\n"],"mappings":";;;;;;;;AAiBA,MAAa,eAAe,EAC1B,UAAU,OACV,cAAc,WACd,iBACA,UAAU,OACV,UACA,WACA,WAAW,OACX,WAAW,OACX,eAAe,OACf,iBACA,SACA,UACA,KACA,UAAU,WACV,OACA,GAAG,WAGC;CACJ,MAAM,eAAe,UAAyC;AAC5D,YAAU,MAAM;AAChB,MAAI,MAAM,oBAAoB,SAAU;AAExC,oBAAkB,KAAK;AACvB,aAAW,KAAK;;CAGlB,MAAM,YAAY;EAChB,GAAG;EACH,WAAW,GACT,0vBACA,YAAY,UACZ,gBAAgB,8HAChB,UACD;EACD,OAAO;GAAE,GAAG,oBAAoB,aAAa,gBAAgB;GAAE,GAAG;GAAO;EACzE;EACA,SAAS;EACT,MAAM;EACN,gBAAgB;EAChB,cAAc,UAAU,OAAO;EAC/B,eAAe;EACf,gBAAgB;EACjB;AAED,KAAI,QACF,QACE,oBAAC,MAAD;EACO;EACL,GAAI;EAEH;EACI;AAIX,QACE,oBAAC,UAAD;EACO;EACL,GAAI;EACJ,MAAK;EAEJ;EACM;;AAIb,YAAY,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"RadioButtonGroupBase.d.ts","names":[],"sources":["../../src/components/RadioButtonGroup/RadioButtonGroupBase.tsx"],"mappings":";;;;;;;UAuCiB,qBAAA;EACf,WAAA,GAAc,WAAA;EACd,eAAA,GAAkB,eAAA;EAClB,OAAA;EACA,QAAA,EAAU,SAAA;EACV,SAAA;EACA,QAAA;EACA,YAAA;EACA,IAAA;EACA,aAAA,IAAiB,KAAA;EACjB,WAAA;EACA,KAAA;EACA,OAAA;EACA,YAAA;EACA,iBAAA;AAAA;AAAA,UAGe,yBAAA,SAAkC,WAAA,EAAa,IAAA,CAAK,oBAAA,CAAqB,iBAAA;EACxF,WAAA,GAAc,WAAA;EACd,eAAA,GAAkB,eAAA;EAClB,QAAA,EAAU,SAAA;EACV,QAAA,IAAY,KAAA;EACZ,KAAA;AAAA;AAAA,cASW,oBAAA;EAAA,cAAoB,SAAA;EAAA,mBAAA,cAAA;EAAA,WAAA;EAAA,eAAA;EAAA,QAAA;EAAA,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,IAAA;EAAA,aAAA;EAAA,WAAA;EAAA,KAAA;EAAA;AAAA,GAA+P,qBAAA,KAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA;EAgHnT,OAAA;EACA,WAAA;EACA,eAAA;EACA,QAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA;EACA,QAAA;EACA,GAAA;EACA,KAAA;EACA,KAAA;EAAA,GACG;AAAA,GACF,yBAAA;EACD,GAAA,GAAM,GAAA,CAAI,iBAAA;AAAA,IACX,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
1
+ {"version":3,"file":"RadioButtonGroupBase.d.ts","names":[],"sources":["../../src/components/RadioButtonGroup/RadioButtonGroupBase.tsx"],"mappings":";;;;;;;UAyBiB,qBAAA;EACf,WAAA,GAAc,WAAA;EACd,eAAA,GAAkB,eAAA;EAClB,OAAA;EACA,QAAA,EAAU,SAAA;EACV,SAAA;EACA,QAAA;EACA,YAAA;EACA,IAAA;EACA,aAAA,IAAiB,KAAA;EACjB,WAAA;EACA,KAAA;EACA,OAAA;EACA,YAAA;EACA,iBAAA;AAAA;AAAA,UAGe,yBAAA,SAAkC,WAAA,EAAa,IAAA,CAAK,oBAAA,CAAqB,iBAAA;EACxF,WAAA,GAAc,WAAA;EACd,eAAA,GAAkB,eAAA;EAClB,QAAA,EAAU,SAAA;EACV,QAAA,IAAY,KAAA;EACZ,KAAA;AAAA;AAAA,cASW,oBAAA;EAAA,cAAoB,SAAA;EAAA,mBAAA,cAAA;EAAA,WAAA;EAAA,eAAA;EAAA,QAAA;EAAA,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,IAAA;EAAA,aAAA;EAAA,WAAA;EAAA,KAAA;EAAA;AAAA,GAc9B,qBAAA,KAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA;EA4GtB,OAAA;EACA,WAAA;EACA,eAAA;EACA,QAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA;EACA,QAAA;EACA,GAAA;EACA,KAAA;EACA,KAAA;EAAA,GACG;AAAA,GACF,yBAAA;EACD,GAAA,GAAM,GAAA,CAAI,iBAAA;AAAA,IACX,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
@@ -94,9 +94,7 @@ const RadioButtonGroupBase = ({ "aria-label": ariaLabel, "aria-labelledby": aria
94
94
  children: /* @__PURE__ */ jsx("div", {
95
95
  "aria-label": ariaLabel,
96
96
  "aria-labelledby": ariaLabelledby,
97
- className: cn("rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md flex h-fit w-fit items-center", "data-[expanded=true]:w-full", `data-[variant=outline]:gap-0 data-[variant=outline]:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant=outline]:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)]
98
- data-[variant=divided]:gap-0 data-[variant=divided]:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant=divided]:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)]
99
- data-[variant=divided]:[&_button]:border-y-0 data-[variant=divided]:[&_button:first-of-type]:border-l-0 data-[variant=divided]:[&_button:last-of-type]:border-r-0`, className),
97
+ className: cn("rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md flex h-fit w-fit items-center", "data-[expanded=true]:w-full", `data-[variant=outline]:gap-0 data-[variant=divided]:gap-0 data-[variant=divided]:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant=outline]:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant=divided]:[&_button]:border-y-0 data-[variant=divided]:[&_button:first-of-type]:border-l-0 data-[variant=divided]:[&_button:last-of-type]:border-r-0 data-[variant=divided]:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)] data-[variant=outline]:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)]`, className),
100
98
  "data-expanded": expanded,
101
99
  "data-orientation": orientation,
102
100
  "data-testid": "spectral-radio-button-group",
@@ -189,10 +187,7 @@ const RadioButtonGroupItem = ({ asChild = false, activeColor, activeTextColor, c
189
187
  const tabIndex = isSelected || selectedIndex === -1 && firstEnabledIndex !== -1 && currentIndex === firstEnabledIndex ? 0 : -1;
190
188
  const baseProps = {
191
189
  ...rest,
192
- className: cn(`gap-2 text-sm font-medium h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4 inline-flex items-center justify-center rounded-none border border-toggle-border
193
- bg-toggle-bg text-toggle-text shadow-none transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:z-10
194
- focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:border-toggle-border--active active:bg-toggle-bg--active active:text-toggle-text--active
195
- disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&:not(:first-child)]:border-l-0`, expanded && "w-full", isKeptActive && "data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active", className),
190
+ className: cn(`gap-2 text-sm font-medium h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4 inline-flex items-center justify-center rounded-none border border-toggle-border bg-toggle-bg text-toggle-text shadow-none transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:border-toggle-border--active active:bg-toggle-bg--active active:text-toggle-text--active disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&:not(:first-child)]:border-l-0`, expanded && "w-full", isKeptActive && "data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active", className),
196
191
  style: {
197
192
  ...getActiveColorStyle(resolvedActiveColor, resolvedActiveTextColor),
198
193
  ...style
@@ -1 +1 @@
1
- {"version":3,"file":"RadioButtonGroupBase.js","names":[],"sources":["../../src/components/RadioButtonGroup/RadioButtonGroupBase.tsx"],"sourcesContent":["import { Slot, type AsChildProp } from '@primitives/slot'\nimport { getActiveColorStyle, type ActiveColor, type ActiveTextColor } from '@utils/activeColorStyle'\nimport { cn } from '@utils/twUtils'\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref }\n from 'react'\n\ninterface RadioButtonGroupContextValue {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n focusItemByIndex: (index: number) => void\n getIndexByValue: (value: string) => number\n isDisabledAtIndex: (index: number) => boolean\n itemCount: () => number\n loop: boolean\n orientation: 'horizontal' | 'vertical'\n selectByIndex: (index: number) => void\n onValueChange?: (value: string) => void\n value?: string\n isKeptActive?: boolean\n expanded?: boolean\n variant?: 'default' | 'outline' | 'divided'\n register: (value: string, element: HTMLButtonElement | null, disabled: boolean) => () => void\n}\n\nconst RadioButtonGroupContext = createContext<RadioButtonGroupContextValue | null>(null)\n\nexport interface RadioButtonGroupProps {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n asChild?: boolean\n children: ReactNode\n className?: string\n expanded?: boolean\n isKeptActive?: boolean\n loop?: boolean\n onValueChange?: (value: string) => void\n orientation?: 'horizontal' | 'vertical'\n value?: string\n variant?: 'default' | 'outline' | 'divided'\n 'aria-label'?: string\n 'aria-labelledby'?: string\n}\n\nexport interface RadioButtonGroupItemProps extends AsChildProp, Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'onSelect' | 'type'> {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n children: ReactNode\n onSelect?: (value: string) => void\n value: string\n}\n\ninterface RadioButtonRegistryItem {\n value: string\n element: HTMLButtonElement | null\n disabled: boolean\n}\n\nexport const RadioButtonGroupBase = ({ 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledby, activeColor = 'default', activeTextColor, children, className, expanded = false, isKeptActive = false, loop = true, onValueChange, orientation = 'horizontal', value, variant = 'default' }: RadioButtonGroupProps) => {\n const [registry, setRegistry] = useState<RadioButtonRegistryItem[]>([])\n\n const register = useCallback((nextValue: string, element: HTMLButtonElement | null, disabled: boolean) => {\n setRegistry((previousRegistry) => {\n const existingIndex = previousRegistry.findIndex((item) => item.value === nextValue)\n\n if (existingIndex !== -1) {\n const existingItem = previousRegistry[existingIndex]\n if (existingItem?.element === element && existingItem.disabled === disabled) return previousRegistry\n\n return previousRegistry.map((item, index) =>\n index === existingIndex ? { value: nextValue, element, disabled } : item,\n )\n }\n\n return [...previousRegistry, { value: nextValue, element, disabled }]\n })\n\n return () => {\n setRegistry((previousRegistry) => previousRegistry.filter((item) => item.value !== nextValue))\n }\n }, [])\n\n const getIndexByValue = useCallback((itemValue: string) => registry.findIndex((item) => item.value === itemValue), [registry])\n const itemCount = useCallback(() => registry.length, [registry])\n const isDisabledAtIndex = useCallback((index: number) => registry[index]?.disabled ?? false, [registry])\n\n const getNextEnabledIndex = useCallback(\n (startIndex: number, direction: 1 | -1) => {\n const items = registry\n if (items.length === 0) return -1\n\n let currentIndex = startIndex\n for (let attempt = 0; attempt < items.length; attempt += 1) {\n if (!loop && (currentIndex < 0 || currentIndex >= items.length)) return -1\n const boundedIndex = loop ? (currentIndex + items.length) % items.length : currentIndex\n if (!items[boundedIndex]?.disabled) return boundedIndex\n currentIndex += direction\n }\n\n return -1\n },\n [loop, registry],\n )\n\n const focusItemByIndex = useCallback(\n (index: number) => {\n const targetIndex = getNextEnabledIndex(index, 1)\n if (targetIndex === -1) return\n registry[targetIndex]?.element?.focus()\n },\n [getNextEnabledIndex, registry],\n )\n\n const selectByIndex = useCallback(\n (index: number) => {\n const target = registry[index]\n if (!target || target.disabled) return\n onValueChange?.(target.value)\n },\n [onValueChange, registry],\n )\n\n const contextValue = useMemo(\n () => ({\n activeColor,\n activeTextColor,\n focusItemByIndex,\n getIndexByValue,\n isDisabledAtIndex,\n itemCount,\n loop,\n onValueChange,\n orientation,\n selectByIndex,\n value,\n isKeptActive,\n expanded,\n variant,\n register,\n }),\n [activeColor, activeTextColor, expanded, focusItemByIndex, getIndexByValue, isDisabledAtIndex, isKeptActive, itemCount, loop, onValueChange, orientation, register, selectByIndex, value, variant],\n )\n\n return (\n <RadioButtonGroupContext.Provider value={contextValue}>\n <div\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n className={cn(\n 'rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md flex h-fit w-fit items-center',\n 'data-[expanded=true]:w-full',\n `data-[variant=outline]:gap-0 data-[variant=outline]:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant=outline]:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)]\n data-[variant=divided]:gap-0 data-[variant=divided]:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant=divided]:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)]\n data-[variant=divided]:[&_button]:border-y-0 data-[variant=divided]:[&_button:first-of-type]:border-l-0 data-[variant=divided]:[&_button:last-of-type]:border-r-0`,\n className,\n )}\n data-expanded={expanded}\n data-orientation={orientation}\n data-testid='spectral-radio-button-group'\n data-variant={variant}\n aria-orientation={orientation}\n role='radiogroup'\n >\n {children}\n </div>\n </RadioButtonGroupContext.Provider>\n )\n}\n\nexport const RadioButtonGroupItem = ({\n asChild = false,\n activeColor,\n activeTextColor,\n children,\n className,\n disabled = false,\n onClick,\n onSelect,\n ref,\n style,\n value,\n ...rest\n}: RadioButtonGroupItemProps & {\n ref?: Ref<HTMLButtonElement | null>\n}) => {\n const context = useContext(RadioButtonGroupContext)\n\n if (!context) {\n throw new Error('RadioButtonGroupItem must be used within a RadioButtonGroup')\n }\n\n const { activeColor: contextActiveColor, activeTextColor: contextActiveTextColor, value: selectedValue, onValueChange, isKeptActive, expanded, variant, orientation, register, getIndexByValue, isDisabledAtIndex, focusItemByIndex, itemCount, loop, selectByIndex } = context\n const isSelected = selectedValue === value\n const resolvedActiveColor = activeColor ?? contextActiveColor\n const resolvedActiveTextColor = activeTextColor ?? contextActiveTextColor\n const itemRef = useRef<HTMLButtonElement | null>(null)\n\n useImperativeHandle<HTMLButtonElement | null, HTMLButtonElement | null>(ref, () => itemRef.current)\n\n useEffect(() => register(value, itemRef.current, disabled), [disabled, register, value])\n\n const setItemRef = (node: HTMLButtonElement | null) => {\n itemRef.current = node\n if (!ref) return\n if (typeof ref === 'function') {\n ref(node)\n return\n }\n ref.current = node\n }\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (onClick) onClick(event)\n if (event.defaultPrevented) return\n if (!disabled) {\n if (onValueChange) {\n onValueChange(value)\n }\n if (onSelect) {\n onSelect(value)\n }\n }\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (rest.onKeyDown) rest.onKeyDown(event)\n if (event.defaultPrevented) return\n\n const currentIndex = getIndexByValue(value)\n if (currentIndex === -1) return\n\n const key = event.key\n const isHorizontal = orientation === 'horizontal'\n const moveNext = (isHorizontal && key === 'ArrowRight') || (!isHorizontal && key === 'ArrowDown')\n const movePrev = (isHorizontal && key === 'ArrowLeft') || (!isHorizontal && key === 'ArrowUp')\n\n if (key === 'Home') {\n event.preventDefault()\n for (let index = 0; index < itemCount(); index += 1) {\n if (!isDisabledAtIndex(index)) {\n selectByIndex(index)\n focusItemByIndex(index)\n return\n }\n }\n return\n }\n\n if (key === 'End') {\n event.preventDefault()\n for (let index = itemCount() - 1; index >= 0; index -= 1) {\n if (!isDisabledAtIndex(index)) {\n selectByIndex(index)\n focusItemByIndex(index)\n return\n }\n }\n return\n }\n\n if (!moveNext && !movePrev) return\n event.preventDefault()\n\n const direction = moveNext ? 1 : -1\n let nextIndex = currentIndex + direction\n for (let attempt = 0; attempt < itemCount(); attempt += 1) {\n if (!loop && (nextIndex < 0 || nextIndex >= itemCount())) return\n const boundedIndex = loop ? (nextIndex + itemCount()) % itemCount() : nextIndex\n if (!isDisabledAtIndex(boundedIndex)) {\n selectByIndex(boundedIndex)\n focusItemByIndex(boundedIndex)\n return\n }\n nextIndex += direction\n }\n }\n\n const selectedIndex = selectedValue ? getIndexByValue(selectedValue) : -1\n const firstEnabledIndex = (() => {\n for (let index = 0; index < itemCount(); index += 1) {\n if (!isDisabledAtIndex(index)) return index\n }\n return -1\n })()\n const currentIndex = getIndexByValue(value)\n const tabIndex = isSelected || (selectedIndex === -1 && firstEnabledIndex !== -1 && currentIndex === firstEnabledIndex) ? 0 : -1\n\n const baseProps = {\n ...rest,\n className: cn(\n `gap-2 text-sm font-medium h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4 inline-flex items-center justify-center rounded-none border border-toggle-border\n bg-toggle-bg text-toggle-text shadow-none transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:z-10\n focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:border-toggle-border--active active:bg-toggle-bg--active active:text-toggle-text--active\n disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&:not(:first-child)]:border-l-0`,\n expanded && 'w-full',\n isKeptActive && 'data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active',\n className,\n ),\n style: { ...getActiveColorStyle(resolvedActiveColor, resolvedActiveTextColor), ...style },\n disabled,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n role: 'radio',\n 'aria-checked': isSelected,\n 'data-state': isSelected ? 'on' : 'off',\n 'data-testid': 'spectral-radio-button-group-item',\n 'data-variant': variant,\n tabIndex: disabled ? -1 : tabIndex,\n }\n\n if (asChild) {\n return (\n <Slot ref={setItemRef as Ref<HTMLElement>} {...baseProps}>\n {children}\n </Slot>\n )\n }\n\n return (\n <button ref={setItemRef} {...baseProps} type='button'>\n {children}\n </button>\n )\n}\n\nRadioButtonGroupItem.displayName = 'RadioButtonGroupItem'\n"],"mappings":"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"}
1
+ {"version":3,"file":"RadioButtonGroupBase.js","names":[],"sources":["../../src/components/RadioButtonGroup/RadioButtonGroupBase.tsx"],"sourcesContent":["import { Slot, type AsChildProp } from '@primitives/slot'\nimport { getActiveColorStyle, type ActiveColor, type ActiveTextColor } from '@utils/activeColorStyle'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState, type ButtonHTMLAttributes, type KeyboardEvent, type MouseEvent, type ReactNode, type Ref } from 'react'\n\ninterface RadioButtonGroupContextValue {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n focusItemByIndex: (index: number) => void\n getIndexByValue: (value: string) => number\n isDisabledAtIndex: (index: number) => boolean\n itemCount: () => number\n loop: boolean\n orientation: 'horizontal' | 'vertical'\n selectByIndex: (index: number) => void\n onValueChange?: (value: string) => void\n value?: string\n isKeptActive?: boolean\n expanded?: boolean\n variant?: 'default' | 'outline' | 'divided'\n register: (value: string, element: HTMLButtonElement | null, disabled: boolean) => () => void\n}\n\nconst RadioButtonGroupContext = createContext<RadioButtonGroupContextValue | null>(null)\n\nexport interface RadioButtonGroupProps {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n asChild?: boolean\n children: ReactNode\n className?: string\n expanded?: boolean\n isKeptActive?: boolean\n loop?: boolean\n onValueChange?: (value: string) => void\n orientation?: 'horizontal' | 'vertical'\n value?: string\n variant?: 'default' | 'outline' | 'divided'\n 'aria-label'?: string\n 'aria-labelledby'?: string\n}\n\nexport interface RadioButtonGroupItemProps extends AsChildProp, Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'onSelect' | 'type'> {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n children: ReactNode\n onSelect?: (value: string) => void\n value: string\n}\n\ninterface RadioButtonRegistryItem {\n value: string\n element: HTMLButtonElement | null\n disabled: boolean\n}\n\nexport const RadioButtonGroupBase = ({\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n activeColor = 'default',\n activeTextColor,\n children,\n className,\n expanded = false,\n isKeptActive = false,\n loop = true,\n onValueChange,\n orientation = 'horizontal',\n value,\n variant = 'default',\n}: RadioButtonGroupProps) => {\n const [registry, setRegistry] = useState<RadioButtonRegistryItem[]>([])\n\n const register = useCallback((nextValue: string, element: HTMLButtonElement | null, disabled: boolean) => {\n setRegistry((previousRegistry) => {\n const existingIndex = previousRegistry.findIndex((item) => item.value === nextValue)\n\n if (existingIndex !== -1) {\n const existingItem = previousRegistry[existingIndex]\n if (existingItem?.element === element && existingItem.disabled === disabled) return previousRegistry\n\n return previousRegistry.map((item, index) => (index === existingIndex ? { value: nextValue, element, disabled } : item))\n }\n\n return [...previousRegistry, { value: nextValue, element, disabled }]\n })\n\n return () => {\n setRegistry((previousRegistry) => previousRegistry.filter((item) => item.value !== nextValue))\n }\n }, [])\n\n const getIndexByValue = useCallback((itemValue: string) => registry.findIndex((item) => item.value === itemValue), [registry])\n const itemCount = useCallback(() => registry.length, [registry])\n const isDisabledAtIndex = useCallback((index: number) => registry[index]?.disabled ?? false, [registry])\n\n const getNextEnabledIndex = useCallback(\n (startIndex: number, direction: 1 | -1) => {\n const items = registry\n if (items.length === 0) return -1\n\n let currentIndex = startIndex\n for (let attempt = 0; attempt < items.length; attempt += 1) {\n if (!loop && (currentIndex < 0 || currentIndex >= items.length)) return -1\n const boundedIndex = loop ? (currentIndex + items.length) % items.length : currentIndex\n if (!items[boundedIndex]?.disabled) return boundedIndex\n currentIndex += direction\n }\n\n return -1\n },\n [loop, registry],\n )\n\n const focusItemByIndex = useCallback(\n (index: number) => {\n const targetIndex = getNextEnabledIndex(index, 1)\n if (targetIndex === -1) return\n registry[targetIndex]?.element?.focus()\n },\n [getNextEnabledIndex, registry],\n )\n\n const selectByIndex = useCallback(\n (index: number) => {\n const target = registry[index]\n if (!target || target.disabled) return\n onValueChange?.(target.value)\n },\n [onValueChange, registry],\n )\n\n const contextValue = useMemo(\n () => ({\n activeColor,\n activeTextColor,\n focusItemByIndex,\n getIndexByValue,\n isDisabledAtIndex,\n itemCount,\n loop,\n onValueChange,\n orientation,\n selectByIndex,\n value,\n isKeptActive,\n expanded,\n variant,\n register,\n }),\n [activeColor, activeTextColor, expanded, focusItemByIndex, getIndexByValue, isDisabledAtIndex, isKeptActive, itemCount, loop, onValueChange, orientation, register, selectByIndex, value, variant],\n )\n\n return (\n <RadioButtonGroupContext.Provider value={contextValue}>\n <div\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n className={cn(\n 'rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md flex h-fit w-fit items-center',\n 'data-[expanded=true]:w-full',\n `data-[variant=outline]:gap-0 data-[variant=divided]:gap-0 data-[variant=divided]:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant=outline]:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant=divided]:[&_button]:border-y-0 data-[variant=divided]:[&_button:first-of-type]:border-l-0 data-[variant=divided]:[&_button:last-of-type]:border-r-0 data-[variant=divided]:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)] data-[variant=outline]:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)]`,\n className,\n )}\n data-expanded={expanded}\n data-orientation={orientation}\n data-testid='spectral-radio-button-group'\n data-variant={variant}\n aria-orientation={orientation}\n role='radiogroup'\n >\n {children}\n </div>\n </RadioButtonGroupContext.Provider>\n )\n}\n\nexport const RadioButtonGroupItem = ({\n asChild = false,\n activeColor,\n activeTextColor,\n children,\n className,\n disabled = false,\n onClick,\n onSelect,\n ref,\n style,\n value,\n ...rest\n}: RadioButtonGroupItemProps & {\n ref?: Ref<HTMLButtonElement | null>\n}) => {\n const context = useContext(RadioButtonGroupContext)\n\n if (!context) {\n throw new Error('RadioButtonGroupItem must be used within a RadioButtonGroup')\n }\n\n const { activeColor: contextActiveColor, activeTextColor: contextActiveTextColor, value: selectedValue, onValueChange, isKeptActive, expanded, variant, orientation, register, getIndexByValue, isDisabledAtIndex, focusItemByIndex, itemCount, loop, selectByIndex } = context\n const isSelected = selectedValue === value\n const resolvedActiveColor = activeColor ?? contextActiveColor\n const resolvedActiveTextColor = activeTextColor ?? contextActiveTextColor\n const itemRef = useRef<HTMLButtonElement | null>(null)\n\n useImperativeHandle<HTMLButtonElement | null, HTMLButtonElement | null>(ref, () => itemRef.current)\n\n useEffect(() => register(value, itemRef.current, disabled), [disabled, register, value])\n\n const setItemRef = (node: HTMLButtonElement | null) => {\n itemRef.current = node\n if (!ref) return\n if (typeof ref === 'function') {\n ref(node)\n return\n }\n ref.current = node\n }\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n if (onClick) onClick(event)\n if (event.defaultPrevented) return\n if (!disabled) {\n if (onValueChange) {\n onValueChange(value)\n }\n if (onSelect) {\n onSelect(value)\n }\n }\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (rest.onKeyDown) rest.onKeyDown(event)\n if (event.defaultPrevented) return\n\n const currentIndex = getIndexByValue(value)\n if (currentIndex === -1) return\n\n const key = event.key\n const isHorizontal = orientation === 'horizontal'\n const moveNext = (isHorizontal && key === 'ArrowRight') || (!isHorizontal && key === 'ArrowDown')\n const movePrev = (isHorizontal && key === 'ArrowLeft') || (!isHorizontal && key === 'ArrowUp')\n\n if (key === 'Home') {\n event.preventDefault()\n for (let index = 0; index < itemCount(); index += 1) {\n if (!isDisabledAtIndex(index)) {\n selectByIndex(index)\n focusItemByIndex(index)\n return\n }\n }\n return\n }\n\n if (key === 'End') {\n event.preventDefault()\n for (let index = itemCount() - 1; index >= 0; index -= 1) {\n if (!isDisabledAtIndex(index)) {\n selectByIndex(index)\n focusItemByIndex(index)\n return\n }\n }\n return\n }\n\n if (!moveNext && !movePrev) return\n event.preventDefault()\n\n const direction = moveNext ? 1 : -1\n let nextIndex = currentIndex + direction\n for (let attempt = 0; attempt < itemCount(); attempt += 1) {\n if (!loop && (nextIndex < 0 || nextIndex >= itemCount())) return\n const boundedIndex = loop ? (nextIndex + itemCount()) % itemCount() : nextIndex\n if (!isDisabledAtIndex(boundedIndex)) {\n selectByIndex(boundedIndex)\n focusItemByIndex(boundedIndex)\n return\n }\n nextIndex += direction\n }\n }\n\n const selectedIndex = selectedValue ? getIndexByValue(selectedValue) : -1\n const firstEnabledIndex = (() => {\n for (let index = 0; index < itemCount(); index += 1) {\n if (!isDisabledAtIndex(index)) return index\n }\n return -1\n })()\n const currentIndex = getIndexByValue(value)\n const tabIndex = isSelected || (selectedIndex === -1 && firstEnabledIndex !== -1 && currentIndex === firstEnabledIndex) ? 0 : -1\n\n const baseProps = {\n ...rest,\n className: cn(\n `gap-2 text-sm font-medium h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4 inline-flex items-center justify-center rounded-none border border-toggle-border bg-toggle-bg text-toggle-text shadow-none transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:border-toggle-border--active active:bg-toggle-bg--active active:text-toggle-text--active disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&:not(:first-child)]:border-l-0`,\n expanded && 'w-full',\n isKeptActive && 'data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active',\n className,\n ),\n style: { ...getActiveColorStyle(resolvedActiveColor, resolvedActiveTextColor), ...style },\n disabled,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n role: 'radio',\n 'aria-checked': isSelected,\n 'data-state': isSelected ? 'on' : 'off',\n 'data-testid': 'spectral-radio-button-group-item',\n 'data-variant': variant,\n tabIndex: disabled ? -1 : tabIndex,\n }\n\n if (asChild) {\n return (\n <Slot\n ref={setItemRef as Ref<HTMLElement>}\n {...baseProps}\n >\n {children}\n </Slot>\n )\n }\n\n return (\n <button\n ref={setItemRef}\n {...baseProps}\n type='button'\n >\n {children}\n </button>\n )\n}\n\nRadioButtonGroupItem.displayName = 'RadioButtonGroupItem'\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RadioButtonGroup.d.ts","names":[],"sources":["../src/components/RadioButtonGroup/RadioButtonGroup.tsx"],"mappings":";;;;;;;KAIY,qBAAA,GAAwB,cAAA,QAAsB,oBAAA;AAAA,KAC9C,yBAAA,GAA4B,2BAAA;AAAA,cAE3B,gBAAA;EAAgB,SAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GAAuC,qBAAA,KAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAO5E,oBAAA;EAAA"}
1
+ {"version":3,"file":"RadioButtonGroup.d.ts","names":[],"sources":["../src/components/RadioButtonGroup/RadioButtonGroup.tsx"],"mappings":";;;;;;;KAIY,qBAAA,GAAwB,cAAA,QAAsB,oBAAA;AAAA,KAC9C,yBAAA,GAA4B,2BAAA;AAAA,cAE3B,gBAAA;EAAgB,SAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GAAuC,qBAAA,KAAqB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAU5E,oBAAA;EAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RadioButtonGroup.js","names":["RadioButtonGroupItemBase"],"sources":["../src/components/RadioButtonGroup/RadioButtonGroup.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ComponentProps } from 'react'\nimport { RadioButtonGroupBase, RadioButtonGroupItem as RadioButtonGroupItemBase, type RadioButtonGroupItemProps as RadioButtonGroupItemPropsBase } from './RadioButtonGroupBase'\n\nexport type RadioButtonGroupProps = ComponentProps<typeof RadioButtonGroupBase>\nexport type RadioButtonGroupItemProps = RadioButtonGroupItemPropsBase\n\nexport const RadioButtonGroup = ({ className, children, ...props }: RadioButtonGroupProps) => {\n return (\n <RadioButtonGroupBase className={cn('rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md flex h-fit w-fit items-center whitespace-nowrap', className)} {...props}>\n {children}\n </RadioButtonGroupBase>\n )\n}\nexport const RadioButtonGroupItem = RadioButtonGroupItemBase\n"],"mappings":";;;;;;;AAOA,MAAa,oBAAoB,EAAE,WAAW,UAAU,GAAG,YAAmC;AAC5F,QACE,oBAAC,sBAAD;EAAsB,WAAW,GAAG,yIAAyI,UAAU;EAAE,GAAI;EAC1L;EACoB;;AAG3B,MAAa,uBAAuBA"}
1
+ {"version":3,"file":"RadioButtonGroup.js","names":["RadioButtonGroupItemBase"],"sources":["../src/components/RadioButtonGroup/RadioButtonGroup.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ComponentProps } from 'react'\nimport { RadioButtonGroupBase, RadioButtonGroupItem as RadioButtonGroupItemBase, type RadioButtonGroupItemProps as RadioButtonGroupItemPropsBase } from './RadioButtonGroupBase'\n\nexport type RadioButtonGroupProps = ComponentProps<typeof RadioButtonGroupBase>\nexport type RadioButtonGroupItemProps = RadioButtonGroupItemPropsBase\n\nexport const RadioButtonGroup = ({ className, children, ...props }: RadioButtonGroupProps) => {\n return (\n <RadioButtonGroupBase\n className={cn('rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md flex h-fit w-fit items-center whitespace-nowrap', className)}\n {...props}\n >\n {children}\n </RadioButtonGroupBase>\n )\n}\nexport const RadioButtonGroupItem = RadioButtonGroupItemBase\n"],"mappings":";;;;;;;AAOA,MAAa,oBAAoB,EAAE,WAAW,UAAU,GAAG,YAAmC;AAC5F,QACE,oBAAC,sBAAD;EACE,WAAW,GAAG,yIAAyI,UAAU;EACjK,GAAI;EAEH;EACoB;;AAG3B,MAAa,uBAAuBA"}
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.d.ts","names":[],"sources":["../src/components/RadioGroup/RadioGroup.tsx"],"mappings":";;;;;;;KAOK,iBAAA;AAAA,UAEY,eAAA,SAAwB,IAAA,CAAK,cAAA,QAAsB,mBAAA,CAAoB,IAAA;EACtF,kBAAA;EACA,YAAA;EACA,SAAA;EACA,QAAA;EACA,YAAA,GAAe,kBAAA;EACf,aAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,QAAA,IAAY,QAAA;EACZ,aAAA,GAAgB,QAAA;EAChB,WAAA;EACA,QAAA;EACA,QAAA;EACA,KAAA,GAAQ,cAAA;EACR,OAAA,GAAU,iBAAA;EACV,cAAA,GAAiB,kBAAA;AAAA;AAAA,UAGF,mBAAA,SAA4B,cAAA,QAAsB,mBAAA,CAAoB,IAAA;EACrF,SAAA;EACA,QAAA,GAAW,SAAA;EACX,WAAA,YAAuB,SAAA;EACvB,EAAA;EACA,KAAA;AAAA;AAAA,iBACD,UAAA,CAqBC,QAAA,EAAU,eAAA;EACR,GAAA,GAAM,GAAA,CAAI,YAAA,QAAoB,mBAAA,CAAoB,IAAA;AAAA,IAEnD,YAAA;AAAA,kBAAY,UAAA;EAAA;;;EAqJb,QAAA;EACA,SAAA;EACA,QAAA;EACA,GAAA;EACA,KAAA;EAAA,GACG;AAAA,GACF,mBAAA;EACD,GAAA,GAAM,GAAA,CAAI,YAAA,QAAoB,mBAAA,CAAoB,IAAA;AAAA,IAChD,YAAA;AAAA,kBAAY,cAAA;EAAA;;;EAgCd,GAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,cAAA,QAAsB,KAAA;EACvB,GAAA,GAAM,GAAA,CAAI,YAAA,QAAoB,KAAA;AAAA,IAC5B,YAAA;AAAA,kBAAY,eAAA;EAAA"}
1
+ {"version":3,"file":"RadioGroup.d.ts","names":[],"sources":["../src/components/RadioGroup/RadioGroup.tsx"],"mappings":";;;;;;;KAOK,iBAAA;AAAA,UAEY,eAAA,SAAwB,IAAA,CAAK,cAAA,QAAsB,mBAAA,CAAoB,IAAA;EACtF,kBAAA;EACA,YAAA;EACA,SAAA;EACA,QAAA;EACA,YAAA,GAAe,kBAAA;EACf,aAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,QAAA,IAAY,QAAA;EACZ,aAAA,GAAgB,QAAA;EAChB,WAAA;EACA,QAAA;EACA,QAAA;EACA,KAAA,GAAQ,cAAA;EACR,OAAA,GAAU,iBAAA;EACV,cAAA,GAAiB,kBAAA;AAAA;AAAA,UAGF,mBAAA,SAA4B,cAAA,QAAsB,mBAAA,CAAoB,IAAA;EACrF,SAAA;EACA,QAAA,GAAW,SAAA;EACX,WAAA,YAAuB,SAAA;EACvB,EAAA;EACA,KAAA;AAAA;AAAA,iBACD,UAAA,CAqBC,QAAA,EAAU,eAAA;EACR,GAAA,GAAM,GAAA,CAAI,YAAA,QAAoB,mBAAA,CAAoB,IAAA;AAAA,IAEnD,YAAA;AAAA,kBAAY,UAAA;EAAA;;;EAqKb,QAAA;EACA,SAAA;EACA,QAAA;EACA,GAAA;EACA,KAAA;EAAA,GACG;AAAA,GACF,mBAAA;EACD,GAAA,GAAM,GAAA,CAAI,YAAA,QAAoB,mBAAA,CAAoB,IAAA;AAAA,IAChD,YAAA;AAAA,kBAAY,cAAA;EAAA;;;EAqDd,GAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,cAAA,QAAsB,KAAA;EACvB,GAAA,GAAM,GAAA,CAAI,YAAA,QAAoB,KAAA;AAAA,IAC5B,YAAA;AAAA,kBAAY,eAAA;EAAA"}
@@ -46,7 +46,7 @@ const RadioGroup = (allProps) => {
46
46
  value: contextValue,
47
47
  children: /* @__PURE__ */ jsxs("div", {
48
48
  "data-slot": "radio-group-field",
49
- className: "flex w-full flex-col gap-1.5",
49
+ className: "gap-1.5 flex w-full flex-col",
50
50
  children: [
51
51
  /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, {
52
52
  className: cn("flex w-full text-text-primary", orientation === "vertical" ? "gap-4 flex-col" : "gap-5 flex-row", variant === "unstyled" && "gap-2.5 w-fit", className),
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroup.js","names":[],"sources":["../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { ErrorMessage, WarningMessage, useFormFieldId, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { AnimatePresence, motion, useReducedMotion, type Transition } from 'motion/react'\nimport { createContext, memo, useContext, useId, useMemo, type ComponentProps, type ComponentRef, type ReactElement, type ReactNode, type Ref } from 'react'\n\ntype RadioGroupVariant = 'default' | 'unstyled'\n\nexport interface RadioGroupProps extends Omit<ComponentProps<typeof RadioGroupPrimitive.Root>, 'onChange' | 'disabled'> {\n 'aria-describedby'?: string\n 'aria-label'?: string\n className?: string\n disabled?: boolean | string[]\n errorMessage?: BaseFormFieldProps['errorMessage']\n itemClassName?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name: string\n onChange?: (selected: string) => void\n onValueChange: (selected: string) => void\n orientation?: 'horizontal' | 'vertical'\n required?: boolean\n selected?: string\n state?: FormFieldState\n variant?: RadioGroupVariant\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport interface RadioGroupItemProps extends ComponentProps<typeof RadioGroupPrimitive.Item> {\n className?: string\n children?: ReactNode\n description?: string | ReactNode\n id?: string\n value: string\n}\n\ninterface RadioGroupContextType {\n disabledValues: string[]\n groupDisabled: boolean\n itemClassName?: string\n orientation: 'horizontal' | 'vertical'\n selected?: string\n variant: RadioGroupVariant\n}\n\nconst RadioGroupContext = createContext<RadioGroupContextType>({\n disabledValues: [],\n groupDisabled: false,\n orientation: 'vertical',\n variant: 'default',\n})\n\nconst DISABLED_STYLES = 'pointer-events-none opacity-60'\n\nconst RadioGroup = (\n allProps: RadioGroupProps & {\n ref?: Ref<ComponentRef<typeof RadioGroupPrimitive.Root>>\n },\n): ReactElement => {\n const isControlled = 'selected' in allProps\n const {\n className,\n disabled,\n errorMessage,\n itemClassName,\n messageReserveLines = 1,\n messageReserveSpace = false,\n name,\n onChange,\n onValueChange,\n orientation = 'vertical',\n ref,\n selected: selectedProp,\n state = 'default',\n variant = 'default',\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n ...props\n } = allProps\n const selected = isControlled ? (selectedProp ?? '') : selectedProp\n const groupId = useFormFieldId(props.id, name)\n const errorMessageId = `${groupId}-error`\n const warningMessageId = `${groupId}-warning`\n const messageId = state === 'error' && errorMessage ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const handleValueChange = (nextValue: string) => {\n onValueChange(nextValue)\n onChange?.(nextValue)\n }\n\n const contextValue = useMemo(\n () => ({\n disabledValues: Array.isArray(disabled) ? disabled : [],\n groupDisabled: typeof disabled === 'boolean' ? disabled : false,\n itemClassName,\n orientation,\n selected,\n variant,\n }),\n [orientation, variant, disabled, itemClassName, selected],\n )\n\n return (\n <RadioGroupContext.Provider value={contextValue}>\n <div data-slot='radio-group-field' className='flex w-full flex-col gap-1.5'>\n <RadioGroupPrimitive.Root\n className={cn('flex w-full text-text-primary', orientation === 'vertical' ? 'gap-4 flex-col' : 'gap-5 flex-row', variant === 'unstyled' && 'gap-2.5 w-fit', className)}\n data-state={state}\n data-testid='spectral-radio-group'\n id={groupId}\n aria-invalid={state === 'error' ? true : undefined}\n aria-describedby={[messageId, ariaDescribedBy].filter(Boolean).join(' ') || undefined}\n disabled={contextValue.groupDisabled}\n name={name}\n onValueChange={handleValueChange}\n ref={ref}\n value={selected}\n {...props}\n />\n <ErrorMessage\n dataTestId='spectral-radio-group-error-message'\n id={errorMessageId}\n message={state === 'error' ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-radio-group-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n </RadioGroupContext.Provider>\n )\n}\nRadioGroup.displayName = 'RadioGroup'\n\nconst DEFAULT_TRANSITION: Transition = { type: 'spring', stiffness: 200, damping: 16 }\n\nconst RadioButton = memo(\n ({\n className,\n id,\n isDisabled,\n ref,\n transition = DEFAULT_TRANSITION,\n value,\n ...props\n }: Omit<ComponentProps<typeof RadioGroupPrimitive.Item>, 'asChild'> & {\n isDisabled?: boolean\n ref?: Ref<HTMLButtonElement>\n transition?: Transition\n }) => {\n const prefersReducedMotion = useReducedMotion()\n\n // When reduced motion is preferred, fall back to original non-animated behavior\n if (prefersReducedMotion) {\n return (\n <RadioGroupPrimitive.Item\n className={cn(\n 'h-4.5 w-4.5 border-border-subtle ring-black relative aspect-square cursor-pointer rounded-full border-2 bg-radio-bg transition-colors',\n 'hover:border-radio-border--hover focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-accent',\n 'data-[state=checked]:border-radio-border--selected data-[state=checked]:bg-radio-bg',\n isDisabled && DISABLED_STYLES,\n className,\n )}\n data-testid='spectral-radio-group-item'\n disabled={isDisabled}\n id={id}\n ref={ref as Ref<ComponentRef<typeof RadioGroupPrimitive.Item>>}\n value={value}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className={cn(`after:inset-0 after:h-2.5 after:w-2.5 after:absolute after:m-auto after:rounded-full after:bg-radio-bg--selected after:content-['']`, isDisabled && DISABLED_STYLES)} />\n </RadioGroupPrimitive.Item>\n )\n }\n\n return (\n <RadioGroupPrimitive.Item value={value} id={id} disabled={isDisabled} asChild {...props}>\n <motion.button\n className={cn(\n 'h-4.5 w-4.5 border-border-subtle ring-black relative aspect-square cursor-pointer rounded-full border-2 bg-radio-bg transition-colors',\n 'hover:border-radio-border--hover focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-accent',\n 'data-[state=checked]:border-radio-border--selected data-[state=checked]:bg-radio-bg',\n isDisabled && DISABLED_STYLES,\n className,\n )}\n data-testid='spectral-radio-group-item'\n ref={ref}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n >\n <RadioGroupPrimitive.Indicator className='relative flex items-center justify-center'>\n <AnimatePresence>\n <motion.div animate={{ opacity: 1, scale: 1 }} className='h-2.5 w-2.5 absolute rounded-full bg-radio-bg--selected' exit={{ opacity: 0, scale: 0 }} initial={{ opacity: 0, scale: 0 }} key='radio-indicator' transition={transition} />\n </AnimatePresence>\n </RadioGroupPrimitive.Indicator>\n </motion.button>\n </RadioGroupPrimitive.Item>\n )\n },\n)\nRadioButton.displayName = 'RadioButton'\n\nconst RadioGroupItem = ({\n children,\n className,\n disabled,\n ref,\n value,\n ...props\n}: RadioGroupItemProps & {\n ref?: Ref<ComponentRef<typeof RadioGroupPrimitive.Item>>\n}): ReactElement => {\n const { disabledValues, groupDisabled, itemClassName, variant, orientation } = useContext(RadioGroupContext)\n const generatedId = useId()\n\n const stringValue = value.toString()\n const id = props.id?.toString() ?? `${stringValue}-${generatedId}`\n const isDisabled = groupDisabled || disabledValues.includes(stringValue) || Boolean(disabled)\n\n if (variant === 'unstyled') {\n return (\n <RadioGroupPrimitive.Item asChild data-testid='spectral-radio-group-item' disabled={isDisabled} id={id} ref={ref} value={stringValue} {...props}>\n <Label className={cn('rounded flex h-fit w-fit border-2 border-transparent data-[state=checked]:border-radio-border--selected', isDisabled && DISABLED_STYLES, itemClassName, className)} data-testid='spectral-radio-group-item-label' htmlFor={id}>\n {children}\n </Label>\n </RadioGroupPrimitive.Item>\n )\n }\n\n return (\n <div className={cn('flex items-center', isDisabled && DISABLED_STYLES, itemClassName, className, orientation)}>\n <RadioButton ref={ref} value={stringValue} id={id} isDisabled={isDisabled} {...props} />\n {children && (\n <Label className={cn('text-md font-normal cursor-pointer', orientation === 'vertical' ? 'ml-2' : 'ml-1')} htmlFor={id}>\n {children}\n </Label>\n )}\n </div>\n )\n}\nRadioGroupItem.displayName = 'RadioGroup.Item'\n\nconst RadioGroupLabel = ({\n ref,\n className,\n ...props\n}: ComponentProps<typeof Label> & {\n ref?: Ref<ComponentRef<typeof Label>>\n}): ReactElement => {\n return <Label ref={ref} data-testid='spectral-radio-group-label' className={cn('text-md font-medium block', className)} {...props} />\n}\nRadioGroupLabel.displayName = 'RadioGroup.Label'\n\nexport { RadioGroup, RadioGroupItem, RadioGroupLabel }\n"],"mappings":"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"}
1
+ {"version":3,"file":"RadioGroup.js","names":[],"sources":["../src/components/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { ErrorMessage, WarningMessage, useFormFieldId, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { AnimatePresence, motion, useReducedMotion, type Transition } from 'motion/react'\nimport { createContext, memo, useContext, useId, useMemo, type ComponentProps, type ComponentRef, type ReactElement, type ReactNode, type Ref } from 'react'\n\ntype RadioGroupVariant = 'default' | 'unstyled'\n\nexport interface RadioGroupProps extends Omit<ComponentProps<typeof RadioGroupPrimitive.Root>, 'onChange' | 'disabled'> {\n 'aria-describedby'?: string\n 'aria-label'?: string\n className?: string\n disabled?: boolean | string[]\n errorMessage?: BaseFormFieldProps['errorMessage']\n itemClassName?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name: string\n onChange?: (selected: string) => void\n onValueChange: (selected: string) => void\n orientation?: 'horizontal' | 'vertical'\n required?: boolean\n selected?: string\n state?: FormFieldState\n variant?: RadioGroupVariant\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport interface RadioGroupItemProps extends ComponentProps<typeof RadioGroupPrimitive.Item> {\n className?: string\n children?: ReactNode\n description?: string | ReactNode\n id?: string\n value: string\n}\n\ninterface RadioGroupContextType {\n disabledValues: string[]\n groupDisabled: boolean\n itemClassName?: string\n orientation: 'horizontal' | 'vertical'\n selected?: string\n variant: RadioGroupVariant\n}\n\nconst RadioGroupContext = createContext<RadioGroupContextType>({\n disabledValues: [],\n groupDisabled: false,\n orientation: 'vertical',\n variant: 'default',\n})\n\nconst DISABLED_STYLES = 'pointer-events-none opacity-60'\n\nconst RadioGroup = (\n allProps: RadioGroupProps & {\n ref?: Ref<ComponentRef<typeof RadioGroupPrimitive.Root>>\n },\n): ReactElement => {\n const isControlled = 'selected' in allProps\n const {\n className,\n disabled,\n errorMessage,\n itemClassName,\n messageReserveLines = 1,\n messageReserveSpace = false,\n name,\n onChange,\n onValueChange,\n orientation = 'vertical',\n ref,\n selected: selectedProp,\n state = 'default',\n variant = 'default',\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n ...props\n } = allProps\n const selected = isControlled ? (selectedProp ?? '') : selectedProp\n const groupId = useFormFieldId(props.id, name)\n const errorMessageId = `${groupId}-error`\n const warningMessageId = `${groupId}-warning`\n const messageId = state === 'error' && errorMessage ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const handleValueChange = (nextValue: string) => {\n onValueChange(nextValue)\n onChange?.(nextValue)\n }\n\n const contextValue = useMemo(\n () => ({\n disabledValues: Array.isArray(disabled) ? disabled : [],\n groupDisabled: typeof disabled === 'boolean' ? disabled : false,\n itemClassName,\n orientation,\n selected,\n variant,\n }),\n [orientation, variant, disabled, itemClassName, selected],\n )\n\n return (\n <RadioGroupContext.Provider value={contextValue}>\n <div\n data-slot='radio-group-field'\n className='gap-1.5 flex w-full flex-col'\n >\n <RadioGroupPrimitive.Root\n className={cn('flex w-full text-text-primary', orientation === 'vertical' ? 'gap-4 flex-col' : 'gap-5 flex-row', variant === 'unstyled' && 'gap-2.5 w-fit', className)}\n data-state={state}\n data-testid='spectral-radio-group'\n id={groupId}\n aria-invalid={state === 'error' ? true : undefined}\n aria-describedby={[messageId, ariaDescribedBy].filter(Boolean).join(' ') || undefined}\n disabled={contextValue.groupDisabled}\n name={name}\n onValueChange={handleValueChange}\n ref={ref}\n value={selected}\n {...props}\n />\n <ErrorMessage\n dataTestId='spectral-radio-group-error-message'\n id={errorMessageId}\n message={state === 'error' ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-radio-group-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n </RadioGroupContext.Provider>\n )\n}\nRadioGroup.displayName = 'RadioGroup'\n\nconst DEFAULT_TRANSITION: Transition = { type: 'spring', stiffness: 200, damping: 16 }\n\nconst RadioButton = memo(\n ({\n className,\n id,\n isDisabled,\n ref,\n transition = DEFAULT_TRANSITION,\n value,\n ...props\n }: Omit<ComponentProps<typeof RadioGroupPrimitive.Item>, 'asChild'> & {\n isDisabled?: boolean\n ref?: Ref<HTMLButtonElement>\n transition?: Transition\n }) => {\n const prefersReducedMotion = useReducedMotion()\n\n // When reduced motion is preferred, fall back to original non-animated behavior\n if (prefersReducedMotion) {\n return (\n <RadioGroupPrimitive.Item\n className={cn(\n 'h-4.5 w-4.5 border-border-subtle ring-black relative aspect-square cursor-pointer rounded-full border-2 bg-radio-bg transition-colors',\n 'hover:border-radio-border--hover focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-accent',\n 'data-[state=checked]:border-radio-border--selected data-[state=checked]:bg-radio-bg',\n isDisabled && DISABLED_STYLES,\n className,\n )}\n data-testid='spectral-radio-group-item'\n disabled={isDisabled}\n id={id}\n ref={ref as Ref<ComponentRef<typeof RadioGroupPrimitive.Item>>}\n value={value}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className={cn(`after:inset-0 after:h-2.5 after:w-2.5 after:absolute after:m-auto after:rounded-full after:bg-radio-bg--selected after:content-['']`, isDisabled && DISABLED_STYLES)} />\n </RadioGroupPrimitive.Item>\n )\n }\n\n return (\n <RadioGroupPrimitive.Item\n value={value}\n id={id}\n disabled={isDisabled}\n asChild\n {...props}\n >\n <motion.button\n className={cn(\n 'h-4.5 w-4.5 border-border-subtle ring-black relative aspect-square cursor-pointer rounded-full border-2 bg-radio-bg transition-colors',\n 'hover:border-radio-border--hover focus-visible:outline-1 focus-visible:outline-offset-2 focus-visible:outline-accent',\n 'data-[state=checked]:border-radio-border--selected data-[state=checked]:bg-radio-bg',\n isDisabled && DISABLED_STYLES,\n className,\n )}\n data-testid='spectral-radio-group-item'\n ref={ref}\n whileHover={{ scale: 1.05 }}\n whileTap={{ scale: 0.95 }}\n >\n <RadioGroupPrimitive.Indicator className='relative flex items-center justify-center'>\n <AnimatePresence>\n <motion.div\n animate={{ opacity: 1, scale: 1 }}\n className='h-2.5 w-2.5 absolute rounded-full bg-radio-bg--selected'\n exit={{ opacity: 0, scale: 0 }}\n initial={{ opacity: 0, scale: 0 }}\n key='radio-indicator'\n transition={transition}\n />\n </AnimatePresence>\n </RadioGroupPrimitive.Indicator>\n </motion.button>\n </RadioGroupPrimitive.Item>\n )\n },\n)\nRadioButton.displayName = 'RadioButton'\n\nconst RadioGroupItem = ({\n children,\n className,\n disabled,\n ref,\n value,\n ...props\n}: RadioGroupItemProps & {\n ref?: Ref<ComponentRef<typeof RadioGroupPrimitive.Item>>\n}): ReactElement => {\n const { disabledValues, groupDisabled, itemClassName, variant, orientation } = useContext(RadioGroupContext)\n const generatedId = useId()\n\n const stringValue = value.toString()\n const id = props.id?.toString() ?? `${stringValue}-${generatedId}`\n const isDisabled = groupDisabled || disabledValues.includes(stringValue) || Boolean(disabled)\n\n if (variant === 'unstyled') {\n return (\n <RadioGroupPrimitive.Item\n asChild\n data-testid='spectral-radio-group-item'\n disabled={isDisabled}\n id={id}\n ref={ref}\n value={stringValue}\n {...props}\n >\n <Label\n className={cn('rounded flex h-fit w-fit border-2 border-transparent data-[state=checked]:border-radio-border--selected', isDisabled && DISABLED_STYLES, itemClassName, className)}\n data-testid='spectral-radio-group-item-label'\n htmlFor={id}\n >\n {children}\n </Label>\n </RadioGroupPrimitive.Item>\n )\n }\n\n return (\n <div className={cn('flex items-center', isDisabled && DISABLED_STYLES, itemClassName, className, orientation)}>\n <RadioButton\n ref={ref}\n value={stringValue}\n id={id}\n isDisabled={isDisabled}\n {...props}\n />\n {children && (\n <Label\n className={cn('text-md font-normal cursor-pointer', orientation === 'vertical' ? 'ml-2' : 'ml-1')}\n htmlFor={id}\n >\n {children}\n </Label>\n )}\n </div>\n )\n}\nRadioGroupItem.displayName = 'RadioGroup.Item'\n\nconst RadioGroupLabel = ({\n ref,\n className,\n ...props\n}: ComponentProps<typeof Label> & {\n ref?: Ref<ComponentRef<typeof Label>>\n}): ReactElement => {\n return (\n <Label\n ref={ref}\n data-testid='spectral-radio-group-label'\n className={cn('text-md font-medium block', className)}\n {...props}\n />\n )\n}\nRadioGroupLabel.displayName = 'RadioGroup.Label'\n\nexport { RadioGroup, RadioGroupItem, RadioGroupLabel }\n"],"mappings":"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"}