@spark-ui/components 17.2.3 → 17.2.4-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/dist/DialogContent.styles-BSxCCi-u.mjs +62 -0
  2. package/dist/DialogContent.styles-BSxCCi-u.mjs.map +1 -0
  3. package/dist/DialogContent.styles-CAhJtUud.js +2 -0
  4. package/dist/DialogContent.styles-CAhJtUud.js.map +1 -0
  5. package/dist/FormFieldRequiredIndicator-CtgkvPZo.js +2 -0
  6. package/dist/FormFieldRequiredIndicator-CtgkvPZo.js.map +1 -0
  7. package/dist/FormFieldRequiredIndicator-DOGQ_HxO.mjs +14 -0
  8. package/dist/FormFieldRequiredIndicator-DOGQ_HxO.mjs.map +1 -0
  9. package/dist/accordion/index.js +2 -2
  10. package/dist/accordion/index.js.map +1 -1
  11. package/dist/accordion/index.mjs +99 -161
  12. package/dist/accordion/index.mjs.map +1 -1
  13. package/dist/alert-dialog/index.js +2 -2
  14. package/dist/alert-dialog/index.js.map +1 -1
  15. package/dist/alert-dialog/index.mjs +169 -235
  16. package/dist/alert-dialog/index.mjs.map +1 -1
  17. package/dist/avatar/index.js +2 -2
  18. package/dist/avatar/index.js.map +1 -1
  19. package/dist/avatar/index.mjs +187 -224
  20. package/dist/avatar/index.mjs.map +1 -1
  21. package/dist/badge/index.js +2 -2
  22. package/dist/badge/index.js.map +1 -1
  23. package/dist/badge/index.mjs +115 -81
  24. package/dist/badge/index.mjs.map +1 -1
  25. package/dist/breadcrumb/index.js +2 -2
  26. package/dist/breadcrumb/index.js.map +1 -1
  27. package/dist/breadcrumb/index.mjs +73 -106
  28. package/dist/breadcrumb/index.mjs.map +1 -1
  29. package/dist/button/index.js +1 -2
  30. package/dist/button/index.mjs +2 -5
  31. package/dist/button-BTDRzvpB.js +2 -0
  32. package/dist/button-BTDRzvpB.js.map +1 -0
  33. package/dist/button-_YZ_4J42.mjs +643 -0
  34. package/dist/button-_YZ_4J42.mjs.map +1 -0
  35. package/dist/card/index.js +2 -2
  36. package/dist/card/index.js.map +1 -1
  37. package/dist/card/index.mjs +327 -394
  38. package/dist/card/index.mjs.map +1 -1
  39. package/dist/carousel/index.js +2 -2
  40. package/dist/carousel/index.js.map +1 -1
  41. package/dist/carousel/index.mjs +515 -618
  42. package/dist/carousel/index.mjs.map +1 -1
  43. package/dist/checkbox/index.js +2 -2
  44. package/dist/checkbox/index.js.map +1 -1
  45. package/dist/checkbox/index.mjs +213 -246
  46. package/dist/checkbox/index.mjs.map +1 -1
  47. package/dist/chip/index.js +2 -2
  48. package/dist/chip/index.js.map +1 -1
  49. package/dist/chip/index.mjs +601 -652
  50. package/dist/chip/index.mjs.map +1 -1
  51. package/dist/chunk-C91j1N6u.js +1 -0
  52. package/dist/circular-meter/index.js +2 -2
  53. package/dist/circular-meter/index.js.map +1 -1
  54. package/dist/circular-meter/index.mjs +354 -309
  55. package/dist/circular-meter/index.mjs.map +1 -1
  56. package/dist/collapsible/index.js +2 -2
  57. package/dist/collapsible/index.js.map +1 -1
  58. package/dist/collapsible/index.mjs +53 -53
  59. package/dist/collapsible/index.mjs.map +1 -1
  60. package/dist/combobox/index.js +2 -2
  61. package/dist/combobox/index.js.map +1 -1
  62. package/dist/combobox/index.mjs +721 -876
  63. package/dist/combobox/index.mjs.map +1 -1
  64. package/dist/dialog/index.js +2 -2
  65. package/dist/dialog/index.js.map +1 -1
  66. package/dist/dialog/index.mjs +181 -206
  67. package/dist/dialog/index.mjs.map +1 -1
  68. package/dist/divider/index.js +2 -2
  69. package/dist/divider/index.js.map +1 -1
  70. package/dist/divider/index.mjs +178 -183
  71. package/dist/divider/index.mjs.map +1 -1
  72. package/dist/drawer/index.js +2 -2
  73. package/dist/drawer/index.js.map +1 -1
  74. package/dist/drawer/index.mjs +277 -309
  75. package/dist/drawer/index.mjs.map +1 -1
  76. package/dist/dropdown/index.js +2 -2
  77. package/dist/dropdown/index.js.map +1 -1
  78. package/dist/dropdown/index.mjs +429 -492
  79. package/dist/dropdown/index.mjs.map +1 -1
  80. package/dist/file-upload/index.js +2 -2
  81. package/dist/file-upload/index.js.map +1 -1
  82. package/dist/file-upload/index.mjs +540 -677
  83. package/dist/file-upload/index.mjs.map +1 -1
  84. package/dist/form-field/index.js +1 -2
  85. package/dist/form-field/index.mjs +2 -284
  86. package/dist/form-field-B8QzM655.mjs +231 -0
  87. package/dist/form-field-B8QzM655.mjs.map +1 -0
  88. package/dist/form-field-Bu_0E9tb.js +2 -0
  89. package/dist/form-field-Bu_0E9tb.js.map +1 -0
  90. package/dist/icon/index.js +1 -2
  91. package/dist/icon/index.mjs +2 -5
  92. package/dist/icon-CRPcdgYp.js +2 -0
  93. package/dist/icon-CRPcdgYp.js.map +1 -0
  94. package/dist/icon-D05Uqh8_.mjs +41 -0
  95. package/dist/icon-D05Uqh8_.mjs.map +1 -0
  96. package/dist/icon-button/index.js +1 -2
  97. package/dist/icon-button/index.mjs +2 -5
  98. package/dist/icon-button-6p3O7NIm.mjs +28 -0
  99. package/dist/icon-button-6p3O7NIm.mjs.map +1 -0
  100. package/dist/icon-button-CykysbgJ.js +2 -0
  101. package/dist/icon-button-CykysbgJ.js.map +1 -0
  102. package/dist/input/index.js +1 -2
  103. package/dist/input/index.mjs +2 -455
  104. package/dist/input-CmYeHYWQ.mjs +355 -0
  105. package/dist/input-CmYeHYWQ.mjs.map +1 -0
  106. package/dist/input-DNr40G2Z.js +2 -0
  107. package/dist/input-DNr40G2Z.js.map +1 -0
  108. package/dist/input-otp/index.js +2 -2
  109. package/dist/input-otp/index.js.map +1 -1
  110. package/dist/input-otp/index.mjs +344 -407
  111. package/dist/input-otp/index.mjs.map +1 -1
  112. package/dist/kbd/index.js +2 -2
  113. package/dist/kbd/index.js.map +1 -1
  114. package/dist/kbd/index.mjs +12 -17
  115. package/dist/kbd/index.mjs.map +1 -1
  116. package/dist/label/index.js +1 -2
  117. package/dist/label/index.mjs +2 -40
  118. package/dist/label-BqRlrca0.mjs +31 -0
  119. package/dist/label-BqRlrca0.mjs.map +1 -0
  120. package/dist/label-DU0p0d-f.js +2 -0
  121. package/dist/label-DU0p0d-f.js.map +1 -0
  122. package/dist/link-box/index.js +2 -2
  123. package/dist/link-box/index.js.map +1 -1
  124. package/dist/link-box/index.mjs +36 -34
  125. package/dist/link-box/index.mjs.map +1 -1
  126. package/dist/meter/index.js +2 -2
  127. package/dist/meter/index.js.map +1 -1
  128. package/dist/meter/index.mjs +149 -171
  129. package/dist/meter/index.mjs.map +1 -1
  130. package/dist/pagination/index.js +2 -2
  131. package/dist/pagination/index.js.map +1 -1
  132. package/dist/pagination/index.mjs +253 -214
  133. package/dist/pagination/index.mjs.map +1 -1
  134. package/dist/popover/index.js +1 -2
  135. package/dist/popover/index.mjs +2 -239
  136. package/dist/popover-CxZAQmw6.mjs +211 -0
  137. package/dist/popover-CxZAQmw6.mjs.map +1 -0
  138. package/dist/popover-GOovJ27J.js +2 -0
  139. package/dist/popover-GOovJ27J.js.map +1 -0
  140. package/dist/portal/index.js +2 -2
  141. package/dist/portal/index.js.map +1 -1
  142. package/dist/portal/index.mjs +8 -7
  143. package/dist/portal/index.mjs.map +1 -1
  144. package/dist/progress/index.js +1 -2
  145. package/dist/progress/index.mjs +2 -178
  146. package/dist/progress-cEf3tFbn.mjs +132 -0
  147. package/dist/progress-cEf3tFbn.mjs.map +1 -0
  148. package/dist/progress-rJZcPJsZ.js +2 -0
  149. package/dist/progress-rJZcPJsZ.js.map +1 -0
  150. package/dist/progress-tracker/index.js +2 -2
  151. package/dist/progress-tracker/index.js.map +1 -1
  152. package/dist/progress-tracker/index.mjs +303 -380
  153. package/dist/progress-tracker/index.mjs.map +1 -1
  154. package/dist/radio-group/index.js +2 -2
  155. package/dist/radio-group/index.js.map +1 -1
  156. package/dist/radio-group/index.mjs +204 -213
  157. package/dist/radio-group/index.mjs.map +1 -1
  158. package/dist/rating/index.js +2 -2
  159. package/dist/rating/index.js.map +1 -1
  160. package/dist/rating/index.mjs +189 -244
  161. package/dist/rating/index.mjs.map +1 -1
  162. package/dist/rating-display/index.js +2 -2
  163. package/dist/rating-display/index.js.map +1 -1
  164. package/dist/rating-display/index.mjs +165 -166
  165. package/dist/rating-display/index.mjs.map +1 -1
  166. package/dist/scrolling-list/index.js +2 -2
  167. package/dist/scrolling-list/index.js.map +1 -1
  168. package/dist/scrolling-list/index.mjs +216 -273
  169. package/dist/scrolling-list/index.mjs.map +1 -1
  170. package/dist/segmented-control/index.js +2 -2
  171. package/dist/segmented-control/index.js.map +1 -1
  172. package/dist/segmented-control/index.mjs +146 -180
  173. package/dist/segmented-control/index.mjs.map +1 -1
  174. package/dist/segmented-gauge/index.js +2 -2
  175. package/dist/segmented-gauge/index.js.map +1 -1
  176. package/dist/segmented-gauge/index.mjs +146 -195
  177. package/dist/segmented-gauge/index.mjs.map +1 -1
  178. package/dist/select/index.js +2 -2
  179. package/dist/select/index.js.map +1 -1
  180. package/dist/select/index.mjs +279 -327
  181. package/dist/select/index.mjs.map +1 -1
  182. package/dist/skeleton/index.js +2 -2
  183. package/dist/skeleton/index.js.map +1 -1
  184. package/dist/skeleton/index.mjs +92 -114
  185. package/dist/skeleton/index.mjs.map +1 -1
  186. package/dist/slider/index.js +2 -2
  187. package/dist/slider/index.js.map +1 -1
  188. package/dist/slider/index.mjs +259 -326
  189. package/dist/slider/index.mjs.map +1 -1
  190. package/dist/slot/index.js +2 -2
  191. package/dist/slot/index.js.map +1 -1
  192. package/dist/slot/index.mjs +12 -7
  193. package/dist/slot/index.mjs.map +1 -1
  194. package/dist/snackbar/index.js +2 -2
  195. package/dist/snackbar/index.js.map +1 -1
  196. package/dist/snackbar/index.mjs +404 -529
  197. package/dist/snackbar/index.mjs.map +1 -1
  198. package/dist/spinner/index.js +1 -2
  199. package/dist/spinner/index.mjs +2 -5
  200. package/dist/spinner-DFUoYvmm.js +2 -0
  201. package/dist/spinner-DFUoYvmm.js.map +1 -0
  202. package/dist/spinner-DULLiM6a.mjs +56 -0
  203. package/dist/spinner-DULLiM6a.mjs.map +1 -0
  204. package/dist/src/avatar/index.d.mts +2 -2
  205. package/dist/src/avatar/index.d.ts +2 -2
  206. package/dist/src/file-upload/index.d.mts +1 -1
  207. package/dist/src/file-upload/index.d.ts +1 -1
  208. package/dist/stepper/index.js +2 -2
  209. package/dist/stepper/index.js.map +1 -1
  210. package/dist/stepper/index.mjs +139 -176
  211. package/dist/stepper/index.mjs.map +1 -1
  212. package/dist/switch/index.js +2 -2
  213. package/dist/switch/index.js.map +1 -1
  214. package/dist/switch/index.mjs +194 -197
  215. package/dist/switch/index.mjs.map +1 -1
  216. package/dist/tabs/index.js +2 -2
  217. package/dist/tabs/index.js.map +1 -1
  218. package/dist/tabs/index.mjs +337 -389
  219. package/dist/tabs/index.mjs.map +1 -1
  220. package/dist/tag/index.js +2 -2
  221. package/dist/tag/index.js.map +1 -1
  222. package/dist/tag/index.mjs +192 -211
  223. package/dist/tag/index.mjs.map +1 -1
  224. package/dist/text-link/index.js +2 -2
  225. package/dist/text-link/index.js.map +1 -1
  226. package/dist/text-link/index.mjs +44 -5
  227. package/dist/text-link/index.mjs.map +1 -1
  228. package/dist/textarea/index.js +2 -2
  229. package/dist/textarea/index.js.map +1 -1
  230. package/dist/textarea/index.mjs +51 -50
  231. package/dist/textarea/index.mjs.map +1 -1
  232. package/dist/toast/index.js +2 -2
  233. package/dist/toast/index.js.map +1 -1
  234. package/dist/toast/index.mjs +314 -367
  235. package/dist/toast/index.mjs.map +1 -1
  236. package/dist/useRenderSlot-DP4fYerF.mjs +11 -0
  237. package/dist/useRenderSlot-DP4fYerF.mjs.map +1 -0
  238. package/dist/useRenderSlot-Xxf_s88b.js +2 -0
  239. package/dist/useRenderSlot-Xxf_s88b.js.map +1 -0
  240. package/dist/visually-hidden/index.js +2 -2
  241. package/dist/visually-hidden/index.js.map +1 -1
  242. package/dist/visually-hidden/index.mjs +25 -5
  243. package/dist/visually-hidden/index.mjs.map +1 -1
  244. package/package.json +4 -4
  245. package/dist/Button-1M9DcZl0.mjs +0 -704
  246. package/dist/Button-1M9DcZl0.mjs.map +0 -1
  247. package/dist/Button-FZceRWG2.js +0 -2
  248. package/dist/Button-FZceRWG2.js.map +0 -1
  249. package/dist/DialogContent.styles-CziMQtYr.js +0 -2
  250. package/dist/DialogContent.styles-CziMQtYr.js.map +0 -1
  251. package/dist/DialogContent.styles-Du7_Dkde.mjs +0 -60
  252. package/dist/DialogContent.styles-Du7_Dkde.mjs.map +0 -1
  253. package/dist/FormFieldRequiredIndicator-CHfcoT2y.js +0 -2
  254. package/dist/FormFieldRequiredIndicator-CHfcoT2y.js.map +0 -1
  255. package/dist/FormFieldRequiredIndicator-DTnCGiX2.mjs +0 -13
  256. package/dist/FormFieldRequiredIndicator-DTnCGiX2.mjs.map +0 -1
  257. package/dist/Icon-BO327oHU.mjs +0 -57
  258. package/dist/Icon-BO327oHU.mjs.map +0 -1
  259. package/dist/Icon-C-cNTnzd.js +0 -2
  260. package/dist/Icon-C-cNTnzd.js.map +0 -1
  261. package/dist/IconButton-BR1bJSQA.js +0 -2
  262. package/dist/IconButton-BR1bJSQA.js.map +0 -1
  263. package/dist/IconButton-DdB3Pq13.mjs +0 -43
  264. package/dist/IconButton-DdB3Pq13.mjs.map +0 -1
  265. package/dist/Slot-DLY1rJrG.mjs +0 -14
  266. package/dist/Slot-DLY1rJrG.mjs.map +0 -1
  267. package/dist/Slot-DQ8z2zsy.js +0 -2
  268. package/dist/Slot-DQ8z2zsy.js.map +0 -1
  269. package/dist/Spinner-Br4Rp9V2.js +0 -2
  270. package/dist/Spinner-Br4Rp9V2.js.map +0 -1
  271. package/dist/Spinner-Co3AjkQV.mjs +0 -68
  272. package/dist/Spinner-Co3AjkQV.mjs.map +0 -1
  273. package/dist/TextLink-5MvP0P8D.js +0 -2
  274. package/dist/TextLink-5MvP0P8D.js.map +0 -1
  275. package/dist/TextLink-Cc_LeVcx.mjs +0 -57
  276. package/dist/TextLink-Cc_LeVcx.mjs.map +0 -1
  277. package/dist/VisuallyHidden-CB6Nx76j.js +0 -2
  278. package/dist/VisuallyHidden-CB6Nx76j.js.map +0 -1
  279. package/dist/VisuallyHidden-DjlV0-CW.mjs +0 -28
  280. package/dist/VisuallyHidden-DjlV0-CW.mjs.map +0 -1
  281. package/dist/button/index.js.map +0 -1
  282. package/dist/button/index.mjs.map +0 -1
  283. package/dist/form-field/index.js.map +0 -1
  284. package/dist/form-field/index.mjs.map +0 -1
  285. package/dist/icon/index.js.map +0 -1
  286. package/dist/icon/index.mjs.map +0 -1
  287. package/dist/icon-button/index.js.map +0 -1
  288. package/dist/icon-button/index.mjs.map +0 -1
  289. package/dist/input/index.js.map +0 -1
  290. package/dist/input/index.mjs.map +0 -1
  291. package/dist/label/index.js.map +0 -1
  292. package/dist/label/index.mjs.map +0 -1
  293. package/dist/popover/index.js.map +0 -1
  294. package/dist/popover/index.mjs.map +0 -1
  295. package/dist/progress/index.js.map +0 -1
  296. package/dist/progress/index.mjs.map +0 -1
  297. package/dist/spinner/index.js.map +0 -1
  298. package/dist/spinner/index.mjs.map +0 -1
  299. package/dist/useRenderSlot-Bta2kdp4.mjs +0 -10
  300. package/dist/useRenderSlot-Bta2kdp4.mjs.map +0 -1
  301. package/dist/useRenderSlot-DATwjgpo.js +0 -2
  302. package/dist/useRenderSlot-DATwjgpo.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../src/segmented-control/SegmentedControl.styles.ts","../../src/segmented-control/SegmentedControlContext.tsx","../../src/segmented-control/SegmentedControl.tsx","../../src/segmented-control/SegmentedControlIndicator.tsx","../../src/segmented-control/SegmentedControlItem.tsx","../../src/segmented-control/index.ts"],"sourcesContent":["import { cva, VariantProps } from 'class-variance-authority'\n\nexport const rootStyles = cva([\n 'default:self-start',\n 'group inline-grid grid-flow-col auto-cols-fr',\n 'relative items-stretch min-w-max',\n 'rounded-xl p-sm',\n 'bg-surface border-sm border-outline',\n])\n\nexport const itemStyles = cva([\n 'relative z-raised min-h-sz-44 focus-visible:outline-none',\n 'flex flex-none items-center justify-center gap-md',\n 'default:px-lg default:py-md',\n 'rounded-[20px]',\n 'cursor-pointer select-none',\n 'font-medium',\n 'transition-colors duration-150',\n 'outline-none',\n 'focus-visible:u-outline',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-dim-3',\n 'data-checked:text-on-support-container',\n // Avoid layout shift: simulate \"bold\" without changing font metrics.\n // Apply only to wrapped text nodes (not arbitrary nested JSX like Tag).\n 'data-checked:[&>[data-spark-segmented-control-text]]:[text-shadow:0.35px_0_currentColor,-0.35px_0_currentColor]',\n])\n\nexport const indicatorStyles = cva([\n 'absolute z-base',\n 'rounded-[20px]',\n 'bg-support-container border-md border-support',\n 'group-has-focus-visible:border-focus',\n 'transition-[left,top,width,height] duration-200 ease-in-out',\n 'pointer-events-none',\n])\n\nexport type SegmentedControlStylesProps = VariantProps<typeof itemStyles>\n","import { createContext, RefObject, useContext } from 'react'\n\nexport interface SegmentedControlContextInterface {\n checkedValue: string | null\n containerRef: RefObject<HTMLDivElement | null>\n}\n\nexport const SegmentedControlContext = createContext<SegmentedControlContextInterface>(\n {} as SegmentedControlContextInterface\n)\n\nexport const useSegmentedControlContext = () => {\n const context = useContext(SegmentedControlContext)\n\n if (!context) {\n throw Error('useSegmentedControlContext must be used within a SegmentedControlContext Provider')\n }\n\n return context\n}\n","import { RadioGroup } from '@base-ui/react/radio-group'\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { Children, type ComponentProps, isValidElement, Ref, useRef, useState } from 'react'\n\nimport type { SegmentedControlStylesProps } from './SegmentedControl.styles'\nimport { rootStyles } from './SegmentedControl.styles'\nimport { SegmentedControlContext } from './SegmentedControlContext'\n\nexport interface SegmentedControlProps\n extends Omit<ComponentProps<typeof RadioGroup>, 'value' | 'defaultValue' | 'onValueChange'>,\n SegmentedControlStylesProps {\n /**\n * The controlled selected value.\n */\n value?: string\n /**\n * The uncontrolled default selected value.\n */\n defaultValue?: string\n /**\n * Callback fired when the selected value changes.\n */\n onValueChange?: (value: string) => void\n ref?: Ref<HTMLDivElement>\n}\n\nconst getFirstItemValue = (children: React.ReactNode): string | null => {\n let firstValue: string | null = null\n\n Children.forEach(children, child => {\n if (firstValue !== null) return\n if (isValidElement(child) && typeof (child.props as { value?: string }).value === 'string') {\n firstValue = (child.props as { value: string }).value\n }\n })\n\n return firstValue\n}\n\nexport const SegmentedControl = ({\n value,\n defaultValue,\n onValueChange,\n className,\n children,\n ref,\n ...rest\n}: SegmentedControlProps) => {\n const containerRef = useRef<HTMLDivElement | null>(null)\n const mergedRef = useMergeRefs(containerRef, ref)\n\n const firstValue = getFirstItemValue(children)\n\n const isControlled = value !== undefined\n const [internalValue, setInternalValue] = useState<string | null>(\n () => defaultValue ?? firstValue\n )\n const checkedValue = isControlled ? (value ?? null) : internalValue\n\n const handleValueChange = (newValue: unknown) => {\n const next = newValue as string\n\n if (!isControlled) {\n setInternalValue(next)\n }\n\n onValueChange?.(next)\n }\n\n const { labelId, description, isRequired, isInvalid, name } = useFormFieldControl()\n\n return (\n <SegmentedControlContext.Provider\n value={{\n checkedValue,\n containerRef,\n }}\n >\n <RadioGroup\n ref={mergedRef}\n value={isControlled ? value : undefined}\n defaultValue={!isControlled ? (defaultValue ?? firstValue ?? undefined) : undefined}\n onValueChange={handleValueChange}\n data-spark-component=\"segmented-control\"\n className={rootStyles({ className })}\n aria-labelledby={labelId}\n aria-describedby={description}\n aria-required={isRequired || undefined}\n aria-invalid={isInvalid || undefined}\n name={name}\n {...rest}\n >\n {children}\n </RadioGroup>\n </SegmentedControlContext.Provider>\n )\n}\n\nSegmentedControl.displayName = 'SegmentedControl'\n","import { type ComponentProps, type CSSProperties, Ref, useEffect, useMemo, useState } from 'react'\n\nimport { indicatorStyles } from './SegmentedControl.styles'\nimport { useSegmentedControlContext } from './SegmentedControlContext'\n\ninterface IndicatorRect {\n left: number\n top: number\n width: number\n height: number\n}\n\nexport interface SegmentedControlIndicatorProps extends ComponentProps<'span'> {\n ref?: Ref<HTMLSpanElement>\n}\n\nexport const SegmentedControlIndicator = ({\n className,\n ref,\n ...rest\n}: SegmentedControlIndicatorProps) => {\n const { checkedValue, containerRef } = useSegmentedControlContext()\n const [rect, setRect] = useState<IndicatorRect | null>(null)\n\n const selector = useMemo(\n () => (checkedValue ? `[data-value=\"${CSS.escape(checkedValue)}\"]` : null),\n [checkedValue]\n )\n\n useEffect(() => {\n const container = containerRef.current\n\n if (!container) {\n return\n }\n\n const selectedItem = selector ? container.querySelector<HTMLElement>(selector) : null\n\n const update = () => {\n const currentContainer = containerRef.current\n if (!currentContainer || !selector) {\n setRect(null)\n\n return\n }\n\n const currentSelected = currentContainer.querySelector<HTMLElement>(selector)\n if (!currentSelected) {\n setRect(null)\n\n return\n }\n\n const containerRect = currentContainer.getBoundingClientRect()\n const itemRect = currentSelected.getBoundingClientRect()\n\n // Storybook canvas \"zoom\" can be implemented via `transform: scale()`.\n // In that case, `getBoundingClientRect()` returns *scaled* values, but CSS positioning/sizing\n // expects unscaled layout pixels. We infer the scale factor from offset sizes and normalize.\n const scaleX =\n currentSelected.offsetWidth > 0 ? itemRect.width / currentSelected.offsetWidth : 1\n const scaleY =\n currentSelected.offsetHeight > 0 ? itemRect.height / currentSelected.offsetHeight : 1\n\n // `getBoundingClientRect()` is border-box; absolute positioning is relative to the padding box.\n setRect({\n left: (itemRect.left - containerRect.left) / scaleX - currentContainer.clientLeft,\n top: (itemRect.top - containerRect.top) / scaleY - currentContainer.clientTop,\n width: itemRect.width / scaleX,\n height: itemRect.height / scaleY,\n })\n }\n\n update()\n\n const ro =\n typeof ResizeObserver !== 'undefined'\n ? new ResizeObserver(() => {\n update()\n })\n : null\n\n ro?.observe(container)\n if (selectedItem) ro?.observe(selectedItem)\n\n window.addEventListener('resize', update, { passive: true })\n window.visualViewport?.addEventListener('resize', update, { passive: true })\n\n return () => {\n ro?.disconnect()\n window.removeEventListener('resize', update)\n window.visualViewport?.removeEventListener('resize', update)\n }\n }, [containerRef, selector])\n\n if (!rect) return null\n\n const style: CSSProperties = {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n }\n\n return (\n <span\n ref={ref}\n data-spark-component=\"segmented-control-indicator\"\n aria-hidden\n className={indicatorStyles({ className })}\n style={style}\n {...rest}\n />\n )\n}\n\nSegmentedControlIndicator.displayName = 'SegmentedControl.Indicator'\n","import { Radio } from '@base-ui/react/radio'\nimport { Children, type ComponentProps, Ref } from 'react'\n\nimport { itemStyles } from './SegmentedControl.styles'\n\nexport interface SegmentedControlItemProps\n extends Omit<ComponentProps<typeof Radio.Root>, 'value'> {\n /**\n * A unique value that identifies this item within the segmented control.\n */\n value: string\n /**\n * When true, prevents the user from interacting with this item.\n * @default false\n */\n disabled?: boolean\n ref?: Ref<HTMLElement>\n}\n\nexport const SegmentedControlItem = ({\n value,\n disabled = false,\n children,\n className,\n ref,\n ...rest\n}: SegmentedControlItemProps) => {\n const content = Children.toArray(children).map((child, index) => {\n if (typeof child === 'string' || typeof child === 'number') {\n return (\n <span key={`text-${index}`} data-spark-segmented-control-text>\n {child}\n </span>\n )\n }\n\n return child\n })\n\n return (\n <Radio.Root\n ref={ref}\n data-spark-component=\"segmented-control-item\"\n data-value={value}\n value={value}\n disabled={disabled}\n className={itemStyles({ className })}\n {...rest}\n >\n {content}\n </Radio.Root>\n )\n}\n\nSegmentedControlItem.displayName = 'SegmentedControl.Item'\n","import { SegmentedControl as Root } from './SegmentedControl'\nimport { SegmentedControlIndicator as Indicator } from './SegmentedControlIndicator'\nimport { SegmentedControlItem as Item } from './SegmentedControlItem'\n\nexport const SegmentedControl: typeof Root & {\n Item: typeof Item\n Indicator: typeof Indicator\n} = Object.assign(Root, {\n Item,\n Indicator,\n})\n\nSegmentedControl.displayName = 'SegmentedControl'\nItem.displayName = 'SegmentedControl.Item'\nIndicator.displayName = 'SegmentedControl.Indicator'\n\nexport type { SegmentedControlProps } from './SegmentedControl'\nexport type { SegmentedControlItemProps } from './SegmentedControlItem'\nexport type { SegmentedControlIndicatorProps } from './SegmentedControlIndicator'\n"],"names":["rootStyles","cva","itemStyles","indicatorStyles","SegmentedControlContext","createContext","useSegmentedControlContext","context","useContext","getFirstItemValue","children","firstValue","Children","child","isValidElement","SegmentedControl","value","defaultValue","onValueChange","className","ref","rest","containerRef","useRef","mergedRef","useMergeRefs","isControlled","internalValue","setInternalValue","useState","checkedValue","handleValueChange","newValue","next","labelId","description","isRequired","isInvalid","name","useFormFieldControl","jsx","RadioGroup","SegmentedControlIndicator","rect","setRect","selector","useMemo","useEffect","container","selectedItem","update","currentContainer","currentSelected","containerRect","itemRect","scaleX","scaleY","ro","style","SegmentedControlItem","disabled","content","index","Radio","Root","Item","Indicator"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/segmented-control/SegmentedControl.styles.ts","../../src/segmented-control/SegmentedControlContext.tsx","../../src/segmented-control/SegmentedControl.tsx","../../src/segmented-control/SegmentedControlIndicator.tsx","../../src/segmented-control/SegmentedControlItem.tsx","../../src/segmented-control/index.ts"],"sourcesContent":["import { cva, VariantProps } from 'class-variance-authority'\n\nexport const rootStyles = cva([\n 'default:self-start',\n 'group inline-grid grid-flow-col auto-cols-fr',\n 'relative items-stretch min-w-max',\n 'rounded-xl p-sm',\n 'bg-surface border-sm border-outline',\n])\n\nexport const itemStyles = cva([\n 'relative z-raised min-h-sz-44 focus-visible:outline-none',\n 'flex flex-none items-center justify-center gap-md',\n 'default:px-lg default:py-md',\n 'rounded-[20px]',\n 'cursor-pointer select-none',\n 'font-medium',\n 'transition-colors duration-150',\n 'outline-none',\n 'focus-visible:u-outline',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-dim-3',\n 'data-checked:text-on-support-container',\n // Avoid layout shift: simulate \"bold\" without changing font metrics.\n // Apply only to wrapped text nodes (not arbitrary nested JSX like Tag).\n 'data-checked:[&>[data-spark-segmented-control-text]]:[text-shadow:0.35px_0_currentColor,-0.35px_0_currentColor]',\n])\n\nexport const indicatorStyles = cva([\n 'absolute z-base',\n 'rounded-[20px]',\n 'bg-support-container border-md border-support',\n 'group-has-focus-visible:border-focus',\n 'transition-[left,top,width,height] duration-200 ease-in-out',\n 'pointer-events-none',\n])\n\nexport type SegmentedControlStylesProps = VariantProps<typeof itemStyles>\n","import { createContext, RefObject, useContext } from 'react'\n\nexport interface SegmentedControlContextInterface {\n checkedValue: string | null\n containerRef: RefObject<HTMLDivElement | null>\n}\n\nexport const SegmentedControlContext = createContext<SegmentedControlContextInterface>(\n {} as SegmentedControlContextInterface\n)\n\nexport const useSegmentedControlContext = () => {\n const context = useContext(SegmentedControlContext)\n\n if (!context) {\n throw Error('useSegmentedControlContext must be used within a SegmentedControlContext Provider')\n }\n\n return context\n}\n","import { RadioGroup } from '@base-ui/react/radio-group'\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport { useMergeRefs } from '@spark-ui/hooks/use-merge-refs'\nimport { Children, type ComponentProps, isValidElement, Ref, useRef, useState } from 'react'\n\nimport type { SegmentedControlStylesProps } from './SegmentedControl.styles'\nimport { rootStyles } from './SegmentedControl.styles'\nimport { SegmentedControlContext } from './SegmentedControlContext'\n\nexport interface SegmentedControlProps\n extends\n Omit<ComponentProps<typeof RadioGroup>, 'value' | 'defaultValue' | 'onValueChange'>,\n SegmentedControlStylesProps {\n /**\n * The controlled selected value.\n */\n value?: string\n /**\n * The uncontrolled default selected value.\n */\n defaultValue?: string\n /**\n * Callback fired when the selected value changes.\n */\n onValueChange?: (value: string) => void\n ref?: Ref<HTMLDivElement>\n}\n\nconst getFirstItemValue = (children: React.ReactNode): string | null => {\n let firstValue: string | null = null\n\n Children.forEach(children, child => {\n if (firstValue !== null) return\n if (isValidElement(child) && typeof (child.props as { value?: string }).value === 'string') {\n firstValue = (child.props as { value: string }).value\n }\n })\n\n return firstValue\n}\n\nexport const SegmentedControl = ({\n value,\n defaultValue,\n onValueChange,\n className,\n children,\n ref,\n ...rest\n}: SegmentedControlProps) => {\n const containerRef = useRef<HTMLDivElement | null>(null)\n const mergedRef = useMergeRefs(containerRef, ref)\n\n const firstValue = getFirstItemValue(children)\n\n const isControlled = value !== undefined\n const [internalValue, setInternalValue] = useState<string | null>(\n () => defaultValue ?? firstValue\n )\n const checkedValue = isControlled ? (value ?? null) : internalValue\n\n const handleValueChange = (newValue: unknown) => {\n const next = newValue as string\n\n if (!isControlled) {\n setInternalValue(next)\n }\n\n onValueChange?.(next)\n }\n\n const { labelId, description, isRequired, isInvalid, name } = useFormFieldControl()\n\n return (\n <SegmentedControlContext.Provider\n value={{\n checkedValue,\n containerRef,\n }}\n >\n <RadioGroup\n ref={mergedRef}\n value={isControlled ? value : undefined}\n defaultValue={!isControlled ? (defaultValue ?? firstValue ?? undefined) : undefined}\n onValueChange={handleValueChange}\n data-spark-component=\"segmented-control\"\n className={rootStyles({ className })}\n aria-labelledby={labelId}\n aria-describedby={description}\n aria-required={isRequired || undefined}\n aria-invalid={isInvalid || undefined}\n name={name}\n {...rest}\n >\n {children}\n </RadioGroup>\n </SegmentedControlContext.Provider>\n )\n}\n\nSegmentedControl.displayName = 'SegmentedControl'\n","import { type ComponentProps, type CSSProperties, Ref, useEffect, useMemo, useState } from 'react'\n\nimport { indicatorStyles } from './SegmentedControl.styles'\nimport { useSegmentedControlContext } from './SegmentedControlContext'\n\ninterface IndicatorRect {\n left: number\n top: number\n width: number\n height: number\n}\n\nexport interface SegmentedControlIndicatorProps extends ComponentProps<'span'> {\n ref?: Ref<HTMLSpanElement>\n}\n\nexport const SegmentedControlIndicator = ({\n className,\n ref,\n ...rest\n}: SegmentedControlIndicatorProps) => {\n const { checkedValue, containerRef } = useSegmentedControlContext()\n const [rect, setRect] = useState<IndicatorRect | null>(null)\n\n const selector = useMemo(\n () => (checkedValue ? `[data-value=\"${CSS.escape(checkedValue)}\"]` : null),\n [checkedValue]\n )\n\n useEffect(() => {\n const container = containerRef.current\n\n if (!container) {\n return\n }\n\n const selectedItem = selector ? container.querySelector<HTMLElement>(selector) : null\n\n const update = () => {\n const currentContainer = containerRef.current\n if (!currentContainer || !selector) {\n setRect(null)\n\n return\n }\n\n const currentSelected = currentContainer.querySelector<HTMLElement>(selector)\n if (!currentSelected) {\n setRect(null)\n\n return\n }\n\n const containerRect = currentContainer.getBoundingClientRect()\n const itemRect = currentSelected.getBoundingClientRect()\n\n // Storybook canvas \"zoom\" can be implemented via `transform: scale()`.\n // In that case, `getBoundingClientRect()` returns *scaled* values, but CSS positioning/sizing\n // expects unscaled layout pixels. We infer the scale factor from offset sizes and normalize.\n const scaleX =\n currentSelected.offsetWidth > 0 ? itemRect.width / currentSelected.offsetWidth : 1\n const scaleY =\n currentSelected.offsetHeight > 0 ? itemRect.height / currentSelected.offsetHeight : 1\n\n // `getBoundingClientRect()` is border-box; absolute positioning is relative to the padding box.\n setRect({\n left: (itemRect.left - containerRect.left) / scaleX - currentContainer.clientLeft,\n top: (itemRect.top - containerRect.top) / scaleY - currentContainer.clientTop,\n width: itemRect.width / scaleX,\n height: itemRect.height / scaleY,\n })\n }\n\n update()\n\n const ro =\n typeof ResizeObserver !== 'undefined'\n ? new ResizeObserver(() => {\n update()\n })\n : null\n\n ro?.observe(container)\n if (selectedItem) ro?.observe(selectedItem)\n\n window.addEventListener('resize', update, { passive: true })\n window.visualViewport?.addEventListener('resize', update, { passive: true })\n\n return () => {\n ro?.disconnect()\n window.removeEventListener('resize', update)\n window.visualViewport?.removeEventListener('resize', update)\n }\n }, [containerRef, selector])\n\n if (!rect) return null\n\n const style: CSSProperties = {\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n }\n\n return (\n <span\n ref={ref}\n data-spark-component=\"segmented-control-indicator\"\n aria-hidden\n className={indicatorStyles({ className })}\n style={style}\n {...rest}\n />\n )\n}\n\nSegmentedControlIndicator.displayName = 'SegmentedControl.Indicator'\n","import { Radio } from '@base-ui/react/radio'\nimport { Children, type ComponentProps, Ref } from 'react'\n\nimport { itemStyles } from './SegmentedControl.styles'\n\nexport interface SegmentedControlItemProps extends Omit<\n ComponentProps<typeof Radio.Root>,\n 'value'\n> {\n /**\n * A unique value that identifies this item within the segmented control.\n */\n value: string\n /**\n * When true, prevents the user from interacting with this item.\n * @default false\n */\n disabled?: boolean\n ref?: Ref<HTMLElement>\n}\n\nexport const SegmentedControlItem = ({\n value,\n disabled = false,\n children,\n className,\n ref,\n ...rest\n}: SegmentedControlItemProps) => {\n const content = Children.toArray(children).map((child, index) => {\n if (typeof child === 'string' || typeof child === 'number') {\n return (\n <span key={`text-${index}`} data-spark-segmented-control-text>\n {child}\n </span>\n )\n }\n\n return child\n })\n\n return (\n <Radio.Root\n ref={ref}\n data-spark-component=\"segmented-control-item\"\n data-value={value}\n value={value}\n disabled={disabled}\n className={itemStyles({ className })}\n {...rest}\n >\n {content}\n </Radio.Root>\n )\n}\n\nSegmentedControlItem.displayName = 'SegmentedControl.Item'\n","import { SegmentedControl as Root } from './SegmentedControl'\nimport { SegmentedControlIndicator as Indicator } from './SegmentedControlIndicator'\nimport { SegmentedControlItem as Item } from './SegmentedControlItem'\n\nexport const SegmentedControl: typeof Root & {\n Item: typeof Item\n Indicator: typeof Indicator\n} = Object.assign(Root, {\n Item,\n Indicator,\n})\n\nSegmentedControl.displayName = 'SegmentedControl'\nItem.displayName = 'SegmentedControl.Item'\nIndicator.displayName = 'SegmentedControl.Indicator'\n\nexport type { SegmentedControlProps } from './SegmentedControl'\nexport type { SegmentedControlItemProps } from './SegmentedControlItem'\nexport type { SegmentedControlIndicatorProps } from './SegmentedControlIndicator'\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),p=require("class-variance-authority"),d=require("react"),C=d.createContext(null),I=()=>{const e=d.useContext(C);if(!e)throw new Error("useSegmentedGaugeContext must be used within a SegmentedGauge provider");return e},h=({className:e,children:a,ref:t,id:r,...c})=>{const{labelId:n}=I();return s.jsx("span",{"data-spark-component":"segmented-gauge-label","data-testid":"segmented-gauge-label",ref:t,id:r||n,className:p.cx("default:text-on-surface default:text-body-2",e),...c,children:a})};h.displayName="SegmentedGauge.Label";const G=({index:e=0,className:a,children:t,ref:r,...c})=>{const{size:n,intent:g,customColor:o,currentIndex:m}=I(),i=m!==-1&&e<=m,x=m!==-1&&e===m,S=d.useMemo(()=>{if(o)return o;switch(g){case"main":return"var(--color-main)";case"support":return"var(--color-support)";case"accent":return"var(--color-accent)";case"success":return"var(--color-success)";case"alert":return"var(--color-alert)";case"danger":return"var(--color-error)";case"info":return"var(--color-info)";case"neutral":return"var(--color-neutral)";default:return"var(--color-neutral)"}},[g,o]),j=p.cx("border-outline relative rounded-full",{"h-sz-8 w-sz-24":n==="sm","h-sz-12 w-sz-36":n==="md","default:bg-[var(--gauge-color)]":i,"border-sm bg-surface":!i},a),u=p.cx("absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2","default:bg-surface default:rounded-full","border-[var(--gauge-color)]",{"size-sz-12 border-md":n==="sm","size-sz-20 border-lg":n==="md"});return s.jsxs("div",{"data-spark-component":"segmented-gauge-segment","data-testid":"segmented-gauge-segment","data-active":i,"data-current":x,ref:r,style:{"--gauge-color":S},className:j,...c,children:[t,x&&s.jsx("div",{className:u,"aria-hidden":"true"})]})};G.displayName="SegmentedGauge.Segment";const y=({className:e,children:a,ref:t,...r})=>s.jsx("div",{"data-spark-component":"segmented-gauge-track",ref:t,className:p.cx("gap-sm relative flex rounded-full",e),...r,children:a});y.displayName="SegmentedGauge.Track";const A=(e,a,t,r)=>{if(e==null)return-1;const c=Math.max(a,Math.min(t,e)),g=(t-a)/(r-1),o=(c-a)/g;return Math.max(0,Math.min(r-1,Math.round(o)))},z=({value:e,min:a,max:t,description:r,size:c="md",intent:n="neutral",customColor:g,id:o,"aria-label":m,className:i,ref:x,children:S,...j})=>{const u=t-a+1,l=d.useMemo(()=>A(e,a,t,u),[e,a,t,u]),f=d.useId(),k=d.useId(),v=o||k,N=d.useMemo(()=>Array.from({length:u},(T,b)=>({isActive:l!==-1&&b<=l,isCurrent:l!==-1&&b===l})),[u,l]),w=d.useMemo(()=>({value:e,min:a,max:t,segments:u,currentIndex:l,size:c,intent:n,customColor:g,labelId:f,gaugeId:v}),[e,a,t,u,l,c,n,g,f,v]),L=e!=null?{role:"meter","aria-valuenow":e,"aria-valuemin":a,"aria-valuemax":t}:{role:"status"};return s.jsx(C.Provider,{value:w,children:s.jsx("div",{id:v,"data-spark-component":"segmented-gauge",ref:x,className:p.cx("gap-md flex flex-wrap items-center",i),...L,"aria-labelledby":o?`${v}-label`:void 0,"aria-label":o?void 0:m,"aria-describedby":f,...j,children:S?S({segments:N,currentIndex:l}):s.jsxs(s.Fragment,{children:[s.jsx(y,{children:N.map((T,b)=>s.jsx(G,{index:b},b))}),r&&s.jsx(h,{id:f,children:r})]})})})};z.displayName="SegmentedGauge";const M=Object.assign(z,{Track:y,Segment:G,Label:h});M.displayName="SegmentedGauge";y.displayName="SegmentedGauge.Track";G.displayName="SegmentedGauge.Segment";h.displayName="SegmentedGauge.Label";exports.SegmentedGauge=M;
2
- //# sourceMappingURL=index.js.map
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);let e=require(`class-variance-authority`),t=require(`react`),n=require(`react/jsx-runtime`);var r=(0,t.createContext)(null),i=()=>{let e=(0,t.useContext)(r);if(!e)throw Error(`useSegmentedGaugeContext must be used within a SegmentedGauge provider`);return e},a=({className:t,children:r,ref:a,id:o,...s})=>{let{labelId:c}=i();return(0,n.jsx)(`span`,{"data-spark-component":`segmented-gauge-label`,"data-testid":`segmented-gauge-label`,ref:a,id:o||c,className:(0,e.cx)(`default:text-on-surface default:text-body-2`,t),...s,children:r})};a.displayName=`SegmentedGauge.Label`;var o=({index:r=0,className:a,children:o,ref:s,...c})=>{let{size:l,intent:u,customColor:d,currentIndex:f}=i(),p=f!==-1&&r<=f,m=f!==-1&&r===f,h=(0,t.useMemo)(()=>{if(d)return d;switch(u){case`main`:return`var(--color-main)`;case`support`:return`var(--color-support)`;case`accent`:return`var(--color-accent)`;case`success`:return`var(--color-success)`;case`alert`:return`var(--color-alert)`;case`danger`:return`var(--color-error)`;case`info`:return`var(--color-info)`;case`neutral`:return`var(--color-neutral)`;default:return`var(--color-neutral)`}},[u,d]),g=(0,e.cx)(`border-outline relative rounded-full`,{"h-sz-8 w-sz-24":l===`sm`,"h-sz-12 w-sz-36":l===`md`,"default:bg-[var(--gauge-color)]":p,"border-sm bg-surface":!p},a),_=(0,e.cx)(`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2`,`default:bg-surface default:rounded-full`,`border-[var(--gauge-color)]`,{"size-sz-12 border-md":l===`sm`,"size-sz-20 border-lg":l===`md`});return(0,n.jsxs)(`div`,{"data-spark-component":`segmented-gauge-segment`,"data-testid":`segmented-gauge-segment`,"data-active":p,"data-current":m,ref:s,style:{"--gauge-color":h},className:g,...c,children:[o,m&&(0,n.jsx)(`div`,{className:_,"aria-hidden":`true`})]})};o.displayName=`SegmentedGauge.Segment`;var s=({className:t,children:r,ref:i,...a})=>(0,n.jsx)(`div`,{"data-spark-component":`segmented-gauge-track`,ref:i,className:(0,e.cx)(`gap-sm relative flex rounded-full`,t),...a,children:r});s.displayName=`SegmentedGauge.Track`;var c=(e,t,n,r)=>{if(e==null)return-1;let i=Math.max(t,Math.min(n,e)),a=(n-t)/(r-1),o=(i-t)/a;return Math.max(0,Math.min(r-1,Math.round(o)))},l=({value:i,min:l,max:u,description:d,size:f=`md`,intent:p=`neutral`,customColor:m,id:h,"aria-label":g,className:_,ref:v,children:y,...b})=>{let x=u-l+1,S=(0,t.useMemo)(()=>c(i,l,u,x),[i,l,u,x]),C=(0,t.useId)(),w=(0,t.useId)(),T=h||w,E=(0,t.useMemo)(()=>Array.from({length:x},(e,t)=>({isActive:S!==-1&&t<=S,isCurrent:S!==-1&&t===S})),[x,S]),D=(0,t.useMemo)(()=>({value:i,min:l,max:u,segments:x,currentIndex:S,size:f,intent:p,customColor:m,labelId:C,gaugeId:T}),[i,l,u,x,S,f,p,m,C,T]),O=i==null?{role:`status`}:{role:`meter`,"aria-valuenow":i,"aria-valuemin":l,"aria-valuemax":u};return(0,n.jsx)(r.Provider,{value:D,children:(0,n.jsx)(`div`,{id:T,"data-spark-component":`segmented-gauge`,ref:v,className:(0,e.cx)(`gap-md flex flex-wrap items-center`,_),...O,"aria-labelledby":h?`${T}-label`:void 0,"aria-label":h?void 0:g,"aria-describedby":C,...b,children:y?y({segments:E,currentIndex:S}):(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s,{children:E.map((e,t)=>(0,n.jsx)(o,{index:t},t))}),d&&(0,n.jsx)(a,{id:C,children:d})]})})})};l.displayName=`SegmentedGauge`;var u=Object.assign(l,{Track:s,Segment:o,Label:a});u.displayName=`SegmentedGauge`,s.displayName=`SegmentedGauge.Track`,o.displayName=`SegmentedGauge.Segment`,a.displayName=`SegmentedGauge.Label`,exports.SegmentedGauge=u;
2
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/segmented-gauge/SegmentedGaugeContext.tsx","../../src/segmented-gauge/SegmentedGaugeLabel.tsx","../../src/segmented-gauge/SegmentedGaugeSegment.tsx","../../src/segmented-gauge/SegmentedGaugeTrack.tsx","../../src/segmented-gauge/SegmentedGauge.tsx","../../src/segmented-gauge/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface SegmentedGaugeContextValue {\n value?: number\n min: number\n max: number\n segments: number\n currentIndex: number\n size: 'sm' | 'md'\n intent: 'main' | 'support' | 'accent' | 'success' | 'alert' | 'danger' | 'info' | 'neutral'\n customColor?: string\n labelId: string\n gaugeId: string\n}\n\nexport const SegmentedGaugeContext = createContext<SegmentedGaugeContextValue | null>(null)\n\nexport const useSegmentedGaugeContext = () => {\n const context = useContext(SegmentedGaugeContext)\n\n if (!context) {\n throw new Error('useSegmentedGaugeContext must be used within a SegmentedGauge provider')\n }\n\n return context\n}\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref } from 'react'\n\nimport { useSegmentedGaugeContext } from './SegmentedGaugeContext'\n\nexport interface SegmentedGaugeLabelProps extends ComponentProps<'span'> {\n ref?: Ref<HTMLSpanElement>\n id?: string\n}\n\nexport const SegmentedGaugeLabel = ({\n className,\n children,\n ref,\n id,\n ...props\n}: SegmentedGaugeLabelProps) => {\n const { labelId } = useSegmentedGaugeContext()\n\n return (\n <span\n data-spark-component=\"segmented-gauge-label\"\n data-testid=\"segmented-gauge-label\"\n ref={ref}\n id={id || labelId}\n className={cx('default:text-on-surface default:text-body-2', className)}\n {...props}\n >\n {children}\n </span>\n )\n}\n\nSegmentedGaugeLabel.displayName = 'SegmentedGauge.Label'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref, useMemo } from 'react'\n\nimport { useSegmentedGaugeContext } from './SegmentedGaugeContext'\n\nexport interface SegmentedGaugeSegmentProps extends ComponentProps<'div'> {\n /**\n * Index of this segment (0-based)\n */\n index?: number\n ref?: Ref<HTMLDivElement>\n}\n\nexport const SegmentedGaugeSegment = ({\n index = 0,\n className,\n children,\n ref,\n ...props\n}: SegmentedGaugeSegmentProps) => {\n const { size, intent, customColor, currentIndex } = useSegmentedGaugeContext()\n\n // Calculate isActive and isCurrent from context and index\n const isActive = currentIndex !== -1 && index <= currentIndex\n const isCurrent = currentIndex !== -1 && index === currentIndex\n\n const gaugeColor = useMemo(() => {\n // If customColor is provided, use it\n if (customColor) {\n return customColor\n }\n\n // Handle predefined intents\n switch (intent) {\n case 'main':\n return 'var(--color-main)'\n case 'support':\n return 'var(--color-support)'\n case 'accent':\n return 'var(--color-accent)'\n case 'success':\n return 'var(--color-success)'\n case 'alert':\n return 'var(--color-alert)'\n case 'danger':\n return 'var(--color-error)'\n case 'info':\n return 'var(--color-info)'\n case 'neutral':\n return 'var(--color-neutral)'\n default:\n return 'var(--color-neutral)'\n }\n }, [intent, customColor])\n\n const segmentClasses = cx(\n 'border-outline relative rounded-full',\n {\n 'h-sz-8 w-sz-24': size === 'sm',\n 'h-sz-12 w-sz-36': size === 'md',\n 'default:bg-[var(--gauge-color)]': isActive,\n 'border-sm bg-surface': !isActive,\n },\n className\n )\n\n const indicatorClasses = cx(\n 'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2',\n 'default:bg-surface default:rounded-full',\n 'border-[var(--gauge-color)]',\n {\n 'size-sz-12 border-md': size === 'sm',\n 'size-sz-20 border-lg': size === 'md',\n }\n )\n\n return (\n <div\n data-spark-component=\"segmented-gauge-segment\"\n data-testid=\"segmented-gauge-segment\"\n data-active={isActive}\n data-current={isCurrent}\n ref={ref}\n style={\n {\n '--gauge-color': gaugeColor,\n } as React.CSSProperties\n }\n className={segmentClasses}\n {...props}\n >\n {children}\n {isCurrent && <div className={indicatorClasses} aria-hidden=\"true\" />}\n </div>\n )\n}\n\nSegmentedGaugeSegment.displayName = 'SegmentedGauge.Segment'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref } from 'react'\n\nexport interface SegmentedGaugeTrackProps extends ComponentProps<'div'> {\n ref?: Ref<HTMLDivElement>\n}\n\nexport const SegmentedGaugeTrack = ({\n className,\n children,\n ref,\n ...props\n}: SegmentedGaugeTrackProps) => {\n return (\n <div\n data-spark-component=\"segmented-gauge-track\"\n ref={ref}\n className={cx('gap-sm relative flex rounded-full', className)}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nSegmentedGaugeTrack.displayName = 'SegmentedGauge.Track'\n","import { cx } from 'class-variance-authority'\nimport { Ref, useId, useMemo } from 'react'\n\nimport { SegmentedGaugeContext } from './SegmentedGaugeContext'\nimport { SegmentedGaugeLabel } from './SegmentedGaugeLabel'\nimport { SegmentedGaugeSegment } from './SegmentedGaugeSegment'\nimport { SegmentedGaugeTrack } from './SegmentedGaugeTrack'\n\nconst calculateCurrentIndex = (\n value: number | undefined,\n min: number,\n max: number,\n segments: number\n) => {\n // If value is undefined or null, no segment is active\n if (value == null) {\n return -1\n }\n const normalizedValue = Math.max(min, Math.min(max, value))\n const range = max - min\n const segmentSize = range / (segments - 1)\n const rawIndex = (normalizedValue - min) / segmentSize\n\n // Clamp the index to valid range\n return Math.max(0, Math.min(segments - 1, Math.round(rawIndex)))\n}\n\nexport interface SegmentedGaugeProps {\n /**\n * The current value of the gauge\n */\n value?: number\n /**\n * Minimum value of the gauge (aria-valuemin)\n */\n min: number\n /**\n * Maximum value of the gauge (aria-valuemax)\n */\n max: number\n /**\n * Description text for the gauge (aria-describedby)\n */\n description?: string\n /**\n * Size of the gauge\n */\n size?: 'sm' | 'md'\n /**\n * Intent of the gauge - predefined color intent\n */\n intent?: 'main' | 'support' | 'accent' | 'success' | 'alert' | 'danger' | 'info' | 'neutral'\n /**\n * Custom color for the gauge (hex, CSS variable, etc.)\n */\n customColor?: string\n /**\n * ID of the gauge element\n */\n id?: string\n /**\n * Accessible label for the gauge (required if no id is provided)\n */\n 'aria-label'?: string\n /**\n * Textual representation of the current value (aria-valuetext)\n * By default, percentage is used (e.g. \"33%\")\n */\n 'aria-valuetext'?: string\n /**\n * Additional CSS classes\n */\n className?: string\n /**\n * Ref to the root element\n */\n ref?: Ref<HTMLDivElement>\n /**\n * Children render prop for custom rendering\n */\n children?: (props: {\n segments: {\n isActive: boolean\n isCurrent: boolean\n }[]\n currentIndex: number\n }) => React.ReactNode\n}\n\nexport const SegmentedGauge = ({\n value,\n min,\n max,\n description,\n size = 'md',\n intent = 'neutral',\n customColor,\n id,\n 'aria-label': ariaLabel,\n className,\n ref,\n children,\n ...props\n}: SegmentedGaugeProps) => {\n // Calculate segments from min and max\n const segments = max - min + 1\n const currentIndex = useMemo(\n () => calculateCurrentIndex(value, min, max, segments),\n [value, min, max, segments]\n )\n\n // Generate unique IDs\n const internalLabelId = useId()\n const generatedId = useId()\n // Use provided id or generated one for the gauge element\n const gaugeId = id || generatedId\n\n const segmentsData = useMemo(() => {\n return Array.from({ length: segments }, (_, index) => ({\n isActive: currentIndex !== -1 && index <= currentIndex,\n isCurrent: currentIndex !== -1 && index === currentIndex,\n }))\n }, [segments, currentIndex])\n\n const contextValue = useMemo(\n () => ({\n value,\n min,\n max,\n segments,\n currentIndex,\n size,\n intent,\n customColor,\n labelId: internalLabelId,\n gaugeId,\n }),\n [value, min, max, segments, currentIndex, size, intent, customColor, internalLabelId, gaugeId]\n )\n\n /**\n * A `meter` role MUST have a value. If the value is not available, the component uses a `status` role instead.\n */\n const roleProps =\n value != null\n ? {\n role: 'meter',\n 'aria-valuenow': value,\n 'aria-valuemin': min,\n 'aria-valuemax': max,\n }\n : {\n role: 'status',\n }\n\n return (\n <SegmentedGaugeContext.Provider value={contextValue}>\n <div\n id={gaugeId}\n data-spark-component=\"segmented-gauge\"\n ref={ref}\n className={cx('gap-md flex flex-wrap items-center', className)}\n {...roleProps}\n aria-labelledby={id ? `${gaugeId}-label` : undefined}\n aria-label={!id ? ariaLabel : undefined}\n aria-describedby={internalLabelId}\n {...props}\n >\n {children ? (\n children({\n segments: segmentsData,\n currentIndex,\n })\n ) : (\n <>\n <SegmentedGaugeTrack>\n {segmentsData.map((_, index) => (\n <SegmentedGaugeSegment key={index} index={index} />\n ))}\n </SegmentedGaugeTrack>\n\n {description && (\n <SegmentedGaugeLabel id={internalLabelId}>{description}</SegmentedGaugeLabel>\n )}\n </>\n )}\n </div>\n </SegmentedGaugeContext.Provider>\n )\n}\n\nSegmentedGauge.displayName = 'SegmentedGauge'\n","import { SegmentedGauge as Root } from './SegmentedGauge'\nimport { SegmentedGaugeLabel } from './SegmentedGaugeLabel'\nimport { SegmentedGaugeSegment } from './SegmentedGaugeSegment'\nimport { SegmentedGaugeTrack } from './SegmentedGaugeTrack'\n\nexport const SegmentedGauge: typeof Root & {\n Track: typeof SegmentedGaugeTrack\n Segment: typeof SegmentedGaugeSegment\n Label: typeof SegmentedGaugeLabel\n} = Object.assign(Root, {\n Track: SegmentedGaugeTrack,\n Segment: SegmentedGaugeSegment,\n Label: SegmentedGaugeLabel,\n})\n\nSegmentedGauge.displayName = 'SegmentedGauge'\nSegmentedGaugeTrack.displayName = 'SegmentedGauge.Track'\nSegmentedGaugeSegment.displayName = 'SegmentedGauge.Segment'\nSegmentedGaugeLabel.displayName = 'SegmentedGauge.Label'\n\nexport { type SegmentedGaugeProps } from './SegmentedGauge'\nexport { type SegmentedGaugeTrackProps } from './SegmentedGaugeTrack'\nexport { type SegmentedGaugeSegmentProps } from './SegmentedGaugeSegment'\nexport { type SegmentedGaugeLabelProps } from './SegmentedGaugeLabel'\n"],"names":["SegmentedGaugeContext","createContext","useSegmentedGaugeContext","context","useContext","SegmentedGaugeLabel","className","children","ref","id","props","labelId","jsx","cx","SegmentedGaugeSegment","index","size","intent","customColor","currentIndex","isActive","isCurrent","gaugeColor","useMemo","segmentClasses","indicatorClasses","jsxs","SegmentedGaugeTrack","calculateCurrentIndex","value","min","max","segments","normalizedValue","segmentSize","rawIndex","SegmentedGauge","description","ariaLabel","internalLabelId","useId","generatedId","gaugeId","segmentsData","_","contextValue","roleProps","Fragment","Root"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/segmented-gauge/SegmentedGaugeContext.tsx","../../src/segmented-gauge/SegmentedGaugeLabel.tsx","../../src/segmented-gauge/SegmentedGaugeSegment.tsx","../../src/segmented-gauge/SegmentedGaugeTrack.tsx","../../src/segmented-gauge/SegmentedGauge.tsx","../../src/segmented-gauge/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface SegmentedGaugeContextValue {\n value?: number\n min: number\n max: number\n segments: number\n currentIndex: number\n size: 'sm' | 'md'\n intent: 'main' | 'support' | 'accent' | 'success' | 'alert' | 'danger' | 'info' | 'neutral'\n customColor?: string\n labelId: string\n gaugeId: string\n}\n\nexport const SegmentedGaugeContext = createContext<SegmentedGaugeContextValue | null>(null)\n\nexport const useSegmentedGaugeContext = () => {\n const context = useContext(SegmentedGaugeContext)\n\n if (!context) {\n throw new Error('useSegmentedGaugeContext must be used within a SegmentedGauge provider')\n }\n\n return context\n}\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref } from 'react'\n\nimport { useSegmentedGaugeContext } from './SegmentedGaugeContext'\n\nexport interface SegmentedGaugeLabelProps extends ComponentProps<'span'> {\n ref?: Ref<HTMLSpanElement>\n id?: string\n}\n\nexport const SegmentedGaugeLabel = ({\n className,\n children,\n ref,\n id,\n ...props\n}: SegmentedGaugeLabelProps) => {\n const { labelId } = useSegmentedGaugeContext()\n\n return (\n <span\n data-spark-component=\"segmented-gauge-label\"\n data-testid=\"segmented-gauge-label\"\n ref={ref}\n id={id || labelId}\n className={cx('default:text-on-surface default:text-body-2', className)}\n {...props}\n >\n {children}\n </span>\n )\n}\n\nSegmentedGaugeLabel.displayName = 'SegmentedGauge.Label'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref, useMemo } from 'react'\n\nimport { useSegmentedGaugeContext } from './SegmentedGaugeContext'\n\nexport interface SegmentedGaugeSegmentProps extends ComponentProps<'div'> {\n /**\n * Index of this segment (0-based)\n */\n index?: number\n ref?: Ref<HTMLDivElement>\n}\n\nexport const SegmentedGaugeSegment = ({\n index = 0,\n className,\n children,\n ref,\n ...props\n}: SegmentedGaugeSegmentProps) => {\n const { size, intent, customColor, currentIndex } = useSegmentedGaugeContext()\n\n // Calculate isActive and isCurrent from context and index\n const isActive = currentIndex !== -1 && index <= currentIndex\n const isCurrent = currentIndex !== -1 && index === currentIndex\n\n const gaugeColor = useMemo(() => {\n // If customColor is provided, use it\n if (customColor) {\n return customColor\n }\n\n // Handle predefined intents\n switch (intent) {\n case 'main':\n return 'var(--color-main)'\n case 'support':\n return 'var(--color-support)'\n case 'accent':\n return 'var(--color-accent)'\n case 'success':\n return 'var(--color-success)'\n case 'alert':\n return 'var(--color-alert)'\n case 'danger':\n return 'var(--color-error)'\n case 'info':\n return 'var(--color-info)'\n case 'neutral':\n return 'var(--color-neutral)'\n default:\n return 'var(--color-neutral)'\n }\n }, [intent, customColor])\n\n const segmentClasses = cx(\n 'border-outline relative rounded-full',\n {\n 'h-sz-8 w-sz-24': size === 'sm',\n 'h-sz-12 w-sz-36': size === 'md',\n 'default:bg-[var(--gauge-color)]': isActive,\n 'border-sm bg-surface': !isActive,\n },\n className\n )\n\n const indicatorClasses = cx(\n 'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2',\n 'default:bg-surface default:rounded-full',\n 'border-[var(--gauge-color)]',\n {\n 'size-sz-12 border-md': size === 'sm',\n 'size-sz-20 border-lg': size === 'md',\n }\n )\n\n return (\n <div\n data-spark-component=\"segmented-gauge-segment\"\n data-testid=\"segmented-gauge-segment\"\n data-active={isActive}\n data-current={isCurrent}\n ref={ref}\n style={\n {\n '--gauge-color': gaugeColor,\n } as React.CSSProperties\n }\n className={segmentClasses}\n {...props}\n >\n {children}\n {isCurrent && <div className={indicatorClasses} aria-hidden=\"true\" />}\n </div>\n )\n}\n\nSegmentedGaugeSegment.displayName = 'SegmentedGauge.Segment'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref } from 'react'\n\nexport interface SegmentedGaugeTrackProps extends ComponentProps<'div'> {\n ref?: Ref<HTMLDivElement>\n}\n\nexport const SegmentedGaugeTrack = ({\n className,\n children,\n ref,\n ...props\n}: SegmentedGaugeTrackProps) => {\n return (\n <div\n data-spark-component=\"segmented-gauge-track\"\n ref={ref}\n className={cx('gap-sm relative flex rounded-full', className)}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nSegmentedGaugeTrack.displayName = 'SegmentedGauge.Track'\n","import { cx } from 'class-variance-authority'\nimport { Ref, useId, useMemo } from 'react'\n\nimport { SegmentedGaugeContext } from './SegmentedGaugeContext'\nimport { SegmentedGaugeLabel } from './SegmentedGaugeLabel'\nimport { SegmentedGaugeSegment } from './SegmentedGaugeSegment'\nimport { SegmentedGaugeTrack } from './SegmentedGaugeTrack'\n\nconst calculateCurrentIndex = (\n value: number | undefined,\n min: number,\n max: number,\n segments: number\n) => {\n // If value is undefined or null, no segment is active\n if (value == null) {\n return -1\n }\n const normalizedValue = Math.max(min, Math.min(max, value))\n const range = max - min\n const segmentSize = range / (segments - 1)\n const rawIndex = (normalizedValue - min) / segmentSize\n\n // Clamp the index to valid range\n return Math.max(0, Math.min(segments - 1, Math.round(rawIndex)))\n}\n\nexport interface SegmentedGaugeProps {\n /**\n * The current value of the gauge\n */\n value?: number\n /**\n * Minimum value of the gauge (aria-valuemin)\n */\n min: number\n /**\n * Maximum value of the gauge (aria-valuemax)\n */\n max: number\n /**\n * Description text for the gauge (aria-describedby)\n */\n description?: string\n /**\n * Size of the gauge\n */\n size?: 'sm' | 'md'\n /**\n * Intent of the gauge - predefined color intent\n */\n intent?: 'main' | 'support' | 'accent' | 'success' | 'alert' | 'danger' | 'info' | 'neutral'\n /**\n * Custom color for the gauge (hex, CSS variable, etc.)\n */\n customColor?: string\n /**\n * ID of the gauge element\n */\n id?: string\n /**\n * Accessible label for the gauge (required if no id is provided)\n */\n 'aria-label'?: string\n /**\n * Textual representation of the current value (aria-valuetext)\n * By default, percentage is used (e.g. \"33%\")\n */\n 'aria-valuetext'?: string\n /**\n * Additional CSS classes\n */\n className?: string\n /**\n * Ref to the root element\n */\n ref?: Ref<HTMLDivElement>\n /**\n * Children render prop for custom rendering\n */\n children?: (props: {\n segments: {\n isActive: boolean\n isCurrent: boolean\n }[]\n currentIndex: number\n }) => React.ReactNode\n}\n\nexport const SegmentedGauge = ({\n value,\n min,\n max,\n description,\n size = 'md',\n intent = 'neutral',\n customColor,\n id,\n 'aria-label': ariaLabel,\n className,\n ref,\n children,\n ...props\n}: SegmentedGaugeProps) => {\n // Calculate segments from min and max\n const segments = max - min + 1\n const currentIndex = useMemo(\n () => calculateCurrentIndex(value, min, max, segments),\n [value, min, max, segments]\n )\n\n // Generate unique IDs\n const internalLabelId = useId()\n const generatedId = useId()\n // Use provided id or generated one for the gauge element\n const gaugeId = id || generatedId\n\n const segmentsData = useMemo(() => {\n return Array.from({ length: segments }, (_, index) => ({\n isActive: currentIndex !== -1 && index <= currentIndex,\n isCurrent: currentIndex !== -1 && index === currentIndex,\n }))\n }, [segments, currentIndex])\n\n const contextValue = useMemo(\n () => ({\n value,\n min,\n max,\n segments,\n currentIndex,\n size,\n intent,\n customColor,\n labelId: internalLabelId,\n gaugeId,\n }),\n [value, min, max, segments, currentIndex, size, intent, customColor, internalLabelId, gaugeId]\n )\n\n /**\n * A `meter` role MUST have a value. If the value is not available, the component uses a `status` role instead.\n */\n const roleProps =\n value != null\n ? {\n role: 'meter',\n 'aria-valuenow': value,\n 'aria-valuemin': min,\n 'aria-valuemax': max,\n }\n : {\n role: 'status',\n }\n\n return (\n <SegmentedGaugeContext.Provider value={contextValue}>\n <div\n id={gaugeId}\n data-spark-component=\"segmented-gauge\"\n ref={ref}\n className={cx('gap-md flex flex-wrap items-center', className)}\n {...roleProps}\n aria-labelledby={id ? `${gaugeId}-label` : undefined}\n aria-label={!id ? ariaLabel : undefined}\n aria-describedby={internalLabelId}\n {...props}\n >\n {children ? (\n children({\n segments: segmentsData,\n currentIndex,\n })\n ) : (\n <>\n <SegmentedGaugeTrack>\n {segmentsData.map((_, index) => (\n <SegmentedGaugeSegment key={index} index={index} />\n ))}\n </SegmentedGaugeTrack>\n\n {description && (\n <SegmentedGaugeLabel id={internalLabelId}>{description}</SegmentedGaugeLabel>\n )}\n </>\n )}\n </div>\n </SegmentedGaugeContext.Provider>\n )\n}\n\nSegmentedGauge.displayName = 'SegmentedGauge'\n","import { SegmentedGauge as Root } from './SegmentedGauge'\nimport { SegmentedGaugeLabel } from './SegmentedGaugeLabel'\nimport { SegmentedGaugeSegment } from './SegmentedGaugeSegment'\nimport { SegmentedGaugeTrack } from './SegmentedGaugeTrack'\n\nexport const SegmentedGauge: typeof Root & {\n Track: typeof SegmentedGaugeTrack\n Segment: typeof SegmentedGaugeSegment\n Label: typeof SegmentedGaugeLabel\n} = Object.assign(Root, {\n Track: SegmentedGaugeTrack,\n Segment: SegmentedGaugeSegment,\n Label: SegmentedGaugeLabel,\n})\n\nSegmentedGauge.displayName = 'SegmentedGauge'\nSegmentedGaugeTrack.displayName = 'SegmentedGauge.Track'\nSegmentedGaugeSegment.displayName = 'SegmentedGauge.Segment'\nSegmentedGaugeLabel.displayName = 'SegmentedGauge.Label'\n\nexport { type SegmentedGaugeProps } from './SegmentedGauge'\nexport { type SegmentedGaugeTrackProps } from './SegmentedGaugeTrack'\nexport { type SegmentedGaugeSegmentProps } from './SegmentedGaugeSegment'\nexport { type SegmentedGaugeLabelProps } from './SegmentedGaugeLabel'\n"],"mappings":"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"}
@@ -1,199 +1,150 @@
1
- import { jsx as c, jsxs as I, Fragment as P } from "react/jsx-runtime";
2
- import { cx as p } from "class-variance-authority";
3
- import { createContext as V, useContext as _, useMemo as h, useId as z } from "react";
4
- const k = V(null), w = () => {
5
- const e = _(k);
6
- if (!e)
7
- throw new Error("useSegmentedGaugeContext must be used within a SegmentedGauge provider");
8
- return e;
9
- }, G = ({
10
- className: e,
11
- children: a,
12
- ref: t,
13
- id: r,
14
- ...o
15
- }) => {
16
- const { labelId: n } = w();
17
- return /* @__PURE__ */ c(
18
- "span",
19
- {
20
- "data-spark-component": "segmented-gauge-label",
21
- "data-testid": "segmented-gauge-label",
22
- ref: t,
23
- id: r || n,
24
- className: p("default:text-on-surface default:text-body-2", e),
25
- ...o,
26
- children: a
27
- }
28
- );
1
+ import { cx as e } from "class-variance-authority";
2
+ import { createContext as t, useContext as n, useId as r, useMemo as i } from "react";
3
+ import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
4
+ //#region src/segmented-gauge/SegmentedGaugeContext.tsx
5
+ var c = t(null), l = () => {
6
+ let e = n(c);
7
+ if (!e) throw Error("useSegmentedGaugeContext must be used within a SegmentedGauge provider");
8
+ return e;
9
+ }, u = ({ className: t, children: n, ref: r, id: i, ...a }) => {
10
+ let { labelId: s } = l();
11
+ return /* @__PURE__ */ o("span", {
12
+ "data-spark-component": "segmented-gauge-label",
13
+ "data-testid": "segmented-gauge-label",
14
+ ref: r,
15
+ id: i || s,
16
+ className: e("default:text-on-surface default:text-body-2", t),
17
+ ...a,
18
+ children: n
19
+ });
29
20
  };
30
- G.displayName = "SegmentedGauge.Label";
31
- const x = ({
32
- index: e = 0,
33
- className: a,
34
- children: t,
35
- ref: r,
36
- ...o
37
- }) => {
38
- const { size: n, intent: u, customColor: s, currentIndex: g } = w(), m = g !== -1 && e <= g, b = g !== -1 && e === g, f = h(() => {
39
- if (s)
40
- return s;
41
- switch (u) {
42
- case "main":
43
- return "var(--color-main)";
44
- case "support":
45
- return "var(--color-support)";
46
- case "accent":
47
- return "var(--color-accent)";
48
- case "success":
49
- return "var(--color-success)";
50
- case "alert":
51
- return "var(--color-alert)";
52
- case "danger":
53
- return "var(--color-error)";
54
- case "info":
55
- return "var(--color-info)";
56
- case "neutral":
57
- return "var(--color-neutral)";
58
- default:
59
- return "var(--color-neutral)";
60
- }
61
- }, [u, s]), N = p(
62
- "border-outline relative rounded-full",
63
- {
64
- "h-sz-8 w-sz-24": n === "sm",
65
- "h-sz-12 w-sz-36": n === "md",
66
- "default:bg-[var(--gauge-color)]": m,
67
- "border-sm bg-surface": !m
68
- },
69
- a
70
- ), l = p(
71
- "absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2",
72
- "default:bg-surface default:rounded-full",
73
- "border-[var(--gauge-color)]",
74
- {
75
- "size-sz-12 border-md": n === "sm",
76
- "size-sz-20 border-lg": n === "md"
77
- }
78
- );
79
- return /* @__PURE__ */ I(
80
- "div",
81
- {
82
- "data-spark-component": "segmented-gauge-segment",
83
- "data-testid": "segmented-gauge-segment",
84
- "data-active": m,
85
- "data-current": b,
86
- ref: r,
87
- style: {
88
- "--gauge-color": f
89
- },
90
- className: N,
91
- ...o,
92
- children: [
93
- t,
94
- b && /* @__PURE__ */ c("div", { className: l, "aria-hidden": "true" })
95
- ]
96
- }
97
- );
21
+ u.displayName = "SegmentedGauge.Label";
22
+ //#endregion
23
+ //#region src/segmented-gauge/SegmentedGaugeSegment.tsx
24
+ var d = ({ index: t = 0, className: n, children: r, ref: a, ...c }) => {
25
+ let { size: u, intent: d, customColor: f, currentIndex: p } = l(), m = p !== -1 && t <= p, h = p !== -1 && t === p, g = i(() => {
26
+ if (f) return f;
27
+ switch (d) {
28
+ case "main": return "var(--color-main)";
29
+ case "support": return "var(--color-support)";
30
+ case "accent": return "var(--color-accent)";
31
+ case "success": return "var(--color-success)";
32
+ case "alert": return "var(--color-alert)";
33
+ case "danger": return "var(--color-error)";
34
+ case "info": return "var(--color-info)";
35
+ case "neutral": return "var(--color-neutral)";
36
+ default: return "var(--color-neutral)";
37
+ }
38
+ }, [d, f]), _ = e("border-outline relative rounded-full", {
39
+ "h-sz-8 w-sz-24": u === "sm",
40
+ "h-sz-12 w-sz-36": u === "md",
41
+ "default:bg-[var(--gauge-color)]": m,
42
+ "border-sm bg-surface": !m
43
+ }, n), v = e("absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2", "default:bg-surface default:rounded-full", "border-[var(--gauge-color)]", {
44
+ "size-sz-12 border-md": u === "sm",
45
+ "size-sz-20 border-lg": u === "md"
46
+ });
47
+ return /* @__PURE__ */ s("div", {
48
+ "data-spark-component": "segmented-gauge-segment",
49
+ "data-testid": "segmented-gauge-segment",
50
+ "data-active": m,
51
+ "data-current": h,
52
+ ref: a,
53
+ style: { "--gauge-color": g },
54
+ className: _,
55
+ ...c,
56
+ children: [r, h && /* @__PURE__ */ o("div", {
57
+ className: v,
58
+ "aria-hidden": "true"
59
+ })]
60
+ });
98
61
  };
99
- x.displayName = "SegmentedGauge.Segment";
100
- const y = ({
101
- className: e,
102
- children: a,
103
- ref: t,
104
- ...r
105
- }) => /* @__PURE__ */ c(
106
- "div",
107
- {
108
- "data-spark-component": "segmented-gauge-track",
109
- ref: t,
110
- className: p("gap-sm relative flex rounded-full", e),
111
- ...r,
112
- children: a
113
- }
114
- );
115
- y.displayName = "SegmentedGauge.Track";
116
- const $ = (e, a, t, r) => {
117
- if (e == null)
118
- return -1;
119
- const o = Math.max(a, Math.min(t, e)), u = (t - a) / (r - 1), s = (o - a) / u;
120
- return Math.max(0, Math.min(r - 1, Math.round(s)));
121
- }, M = ({
122
- value: e,
123
- min: a,
124
- max: t,
125
- description: r,
126
- size: o = "md",
127
- intent: n = "neutral",
128
- customColor: u,
129
- id: s,
130
- "aria-label": g,
131
- className: m,
132
- ref: b,
133
- children: f,
134
- ...N
135
- }) => {
136
- const l = t - a + 1, d = h(
137
- () => $(e, a, t, l),
138
- [e, a, t, l]
139
- ), v = z(), L = z(), S = s || L, C = h(() => Array.from({ length: l }, (A, i) => ({
140
- isActive: d !== -1 && i <= d,
141
- isCurrent: d !== -1 && i === d
142
- })), [l, d]), T = h(
143
- () => ({
144
- value: e,
145
- min: a,
146
- max: t,
147
- segments: l,
148
- currentIndex: d,
149
- size: o,
150
- intent: n,
151
- customColor: u,
152
- labelId: v,
153
- gaugeId: S
154
- }),
155
- [e, a, t, l, d, o, n, u, v, S]
156
- ), j = e != null ? {
157
- role: "meter",
158
- "aria-valuenow": e,
159
- "aria-valuemin": a,
160
- "aria-valuemax": t
161
- } : {
162
- role: "status"
163
- };
164
- return /* @__PURE__ */ c(k.Provider, { value: T, children: /* @__PURE__ */ c(
165
- "div",
166
- {
167
- id: S,
168
- "data-spark-component": "segmented-gauge",
169
- ref: b,
170
- className: p("gap-md flex flex-wrap items-center", m),
171
- ...j,
172
- "aria-labelledby": s ? `${S}-label` : void 0,
173
- "aria-label": s ? void 0 : g,
174
- "aria-describedby": v,
175
- ...N,
176
- children: f ? f({
177
- segments: C,
178
- currentIndex: d
179
- }) : /* @__PURE__ */ I(P, { children: [
180
- /* @__PURE__ */ c(y, { children: C.map((A, i) => /* @__PURE__ */ c(x, { index: i }, i)) }),
181
- r && /* @__PURE__ */ c(G, { id: v, children: r })
182
- ] })
183
- }
184
- ) });
185
- };
186
- M.displayName = "SegmentedGauge";
187
- const D = Object.assign(M, {
188
- Track: y,
189
- Segment: x,
190
- Label: G
62
+ d.displayName = "SegmentedGauge.Segment";
63
+ //#endregion
64
+ //#region src/segmented-gauge/SegmentedGaugeTrack.tsx
65
+ var f = ({ className: t, children: n, ref: r, ...i }) => /* @__PURE__ */ o("div", {
66
+ "data-spark-component": "segmented-gauge-track",
67
+ ref: r,
68
+ className: e("gap-sm relative flex rounded-full", t),
69
+ ...i,
70
+ children: n
191
71
  });
192
- D.displayName = "SegmentedGauge";
193
- y.displayName = "SegmentedGauge.Track";
194
- x.displayName = "SegmentedGauge.Segment";
195
- G.displayName = "SegmentedGauge.Label";
196
- export {
197
- D as SegmentedGauge
72
+ f.displayName = "SegmentedGauge.Track";
73
+ //#endregion
74
+ //#region src/segmented-gauge/SegmentedGauge.tsx
75
+ var p = (e, t, n, r) => {
76
+ if (e == null) return -1;
77
+ let i = Math.max(t, Math.min(n, e)), a = (n - t) / (r - 1), o = (i - t) / a;
78
+ return Math.max(0, Math.min(r - 1, Math.round(o)));
79
+ }, m = ({ value: t, min: n, max: l, description: m, size: h = "md", intent: g = "neutral", customColor: _, id: v, "aria-label": y, className: b, ref: x, children: S, ...C }) => {
80
+ let w = l - n + 1, T = i(() => p(t, n, l, w), [
81
+ t,
82
+ n,
83
+ l,
84
+ w
85
+ ]), E = r(), D = r(), O = v || D, k = i(() => Array.from({ length: w }, (e, t) => ({
86
+ isActive: T !== -1 && t <= T,
87
+ isCurrent: T !== -1 && t === T
88
+ })), [w, T]), A = i(() => ({
89
+ value: t,
90
+ min: n,
91
+ max: l,
92
+ segments: w,
93
+ currentIndex: T,
94
+ size: h,
95
+ intent: g,
96
+ customColor: _,
97
+ labelId: E,
98
+ gaugeId: O
99
+ }), [
100
+ t,
101
+ n,
102
+ l,
103
+ w,
104
+ T,
105
+ h,
106
+ g,
107
+ _,
108
+ E,
109
+ O
110
+ ]), j = t == null ? { role: "status" } : {
111
+ role: "meter",
112
+ "aria-valuenow": t,
113
+ "aria-valuemin": n,
114
+ "aria-valuemax": l
115
+ };
116
+ return /* @__PURE__ */ o(c.Provider, {
117
+ value: A,
118
+ children: /* @__PURE__ */ o("div", {
119
+ id: O,
120
+ "data-spark-component": "segmented-gauge",
121
+ ref: x,
122
+ className: e("gap-md flex flex-wrap items-center", b),
123
+ ...j,
124
+ "aria-labelledby": v ? `${O}-label` : void 0,
125
+ "aria-label": v ? void 0 : y,
126
+ "aria-describedby": E,
127
+ ...C,
128
+ children: S ? S({
129
+ segments: k,
130
+ currentIndex: T
131
+ }) : /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o(f, { children: k.map((e, t) => /* @__PURE__ */ o(d, { index: t }, t)) }), m && /* @__PURE__ */ o(u, {
132
+ id: E,
133
+ children: m
134
+ })] })
135
+ })
136
+ });
198
137
  };
199
- //# sourceMappingURL=index.mjs.map
138
+ m.displayName = "SegmentedGauge";
139
+ //#endregion
140
+ //#region src/segmented-gauge/index.ts
141
+ var h = Object.assign(m, {
142
+ Track: f,
143
+ Segment: d,
144
+ Label: u
145
+ });
146
+ h.displayName = "SegmentedGauge", f.displayName = "SegmentedGauge.Track", d.displayName = "SegmentedGauge.Segment", u.displayName = "SegmentedGauge.Label";
147
+ //#endregion
148
+ export { h as SegmentedGauge };
149
+
150
+ //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../src/segmented-gauge/SegmentedGaugeContext.tsx","../../src/segmented-gauge/SegmentedGaugeLabel.tsx","../../src/segmented-gauge/SegmentedGaugeSegment.tsx","../../src/segmented-gauge/SegmentedGaugeTrack.tsx","../../src/segmented-gauge/SegmentedGauge.tsx","../../src/segmented-gauge/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface SegmentedGaugeContextValue {\n value?: number\n min: number\n max: number\n segments: number\n currentIndex: number\n size: 'sm' | 'md'\n intent: 'main' | 'support' | 'accent' | 'success' | 'alert' | 'danger' | 'info' | 'neutral'\n customColor?: string\n labelId: string\n gaugeId: string\n}\n\nexport const SegmentedGaugeContext = createContext<SegmentedGaugeContextValue | null>(null)\n\nexport const useSegmentedGaugeContext = () => {\n const context = useContext(SegmentedGaugeContext)\n\n if (!context) {\n throw new Error('useSegmentedGaugeContext must be used within a SegmentedGauge provider')\n }\n\n return context\n}\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref } from 'react'\n\nimport { useSegmentedGaugeContext } from './SegmentedGaugeContext'\n\nexport interface SegmentedGaugeLabelProps extends ComponentProps<'span'> {\n ref?: Ref<HTMLSpanElement>\n id?: string\n}\n\nexport const SegmentedGaugeLabel = ({\n className,\n children,\n ref,\n id,\n ...props\n}: SegmentedGaugeLabelProps) => {\n const { labelId } = useSegmentedGaugeContext()\n\n return (\n <span\n data-spark-component=\"segmented-gauge-label\"\n data-testid=\"segmented-gauge-label\"\n ref={ref}\n id={id || labelId}\n className={cx('default:text-on-surface default:text-body-2', className)}\n {...props}\n >\n {children}\n </span>\n )\n}\n\nSegmentedGaugeLabel.displayName = 'SegmentedGauge.Label'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref, useMemo } from 'react'\n\nimport { useSegmentedGaugeContext } from './SegmentedGaugeContext'\n\nexport interface SegmentedGaugeSegmentProps extends ComponentProps<'div'> {\n /**\n * Index of this segment (0-based)\n */\n index?: number\n ref?: Ref<HTMLDivElement>\n}\n\nexport const SegmentedGaugeSegment = ({\n index = 0,\n className,\n children,\n ref,\n ...props\n}: SegmentedGaugeSegmentProps) => {\n const { size, intent, customColor, currentIndex } = useSegmentedGaugeContext()\n\n // Calculate isActive and isCurrent from context and index\n const isActive = currentIndex !== -1 && index <= currentIndex\n const isCurrent = currentIndex !== -1 && index === currentIndex\n\n const gaugeColor = useMemo(() => {\n // If customColor is provided, use it\n if (customColor) {\n return customColor\n }\n\n // Handle predefined intents\n switch (intent) {\n case 'main':\n return 'var(--color-main)'\n case 'support':\n return 'var(--color-support)'\n case 'accent':\n return 'var(--color-accent)'\n case 'success':\n return 'var(--color-success)'\n case 'alert':\n return 'var(--color-alert)'\n case 'danger':\n return 'var(--color-error)'\n case 'info':\n return 'var(--color-info)'\n case 'neutral':\n return 'var(--color-neutral)'\n default:\n return 'var(--color-neutral)'\n }\n }, [intent, customColor])\n\n const segmentClasses = cx(\n 'border-outline relative rounded-full',\n {\n 'h-sz-8 w-sz-24': size === 'sm',\n 'h-sz-12 w-sz-36': size === 'md',\n 'default:bg-[var(--gauge-color)]': isActive,\n 'border-sm bg-surface': !isActive,\n },\n className\n )\n\n const indicatorClasses = cx(\n 'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2',\n 'default:bg-surface default:rounded-full',\n 'border-[var(--gauge-color)]',\n {\n 'size-sz-12 border-md': size === 'sm',\n 'size-sz-20 border-lg': size === 'md',\n }\n )\n\n return (\n <div\n data-spark-component=\"segmented-gauge-segment\"\n data-testid=\"segmented-gauge-segment\"\n data-active={isActive}\n data-current={isCurrent}\n ref={ref}\n style={\n {\n '--gauge-color': gaugeColor,\n } as React.CSSProperties\n }\n className={segmentClasses}\n {...props}\n >\n {children}\n {isCurrent && <div className={indicatorClasses} aria-hidden=\"true\" />}\n </div>\n )\n}\n\nSegmentedGaugeSegment.displayName = 'SegmentedGauge.Segment'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref } from 'react'\n\nexport interface SegmentedGaugeTrackProps extends ComponentProps<'div'> {\n ref?: Ref<HTMLDivElement>\n}\n\nexport const SegmentedGaugeTrack = ({\n className,\n children,\n ref,\n ...props\n}: SegmentedGaugeTrackProps) => {\n return (\n <div\n data-spark-component=\"segmented-gauge-track\"\n ref={ref}\n className={cx('gap-sm relative flex rounded-full', className)}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nSegmentedGaugeTrack.displayName = 'SegmentedGauge.Track'\n","import { cx } from 'class-variance-authority'\nimport { Ref, useId, useMemo } from 'react'\n\nimport { SegmentedGaugeContext } from './SegmentedGaugeContext'\nimport { SegmentedGaugeLabel } from './SegmentedGaugeLabel'\nimport { SegmentedGaugeSegment } from './SegmentedGaugeSegment'\nimport { SegmentedGaugeTrack } from './SegmentedGaugeTrack'\n\nconst calculateCurrentIndex = (\n value: number | undefined,\n min: number,\n max: number,\n segments: number\n) => {\n // If value is undefined or null, no segment is active\n if (value == null) {\n return -1\n }\n const normalizedValue = Math.max(min, Math.min(max, value))\n const range = max - min\n const segmentSize = range / (segments - 1)\n const rawIndex = (normalizedValue - min) / segmentSize\n\n // Clamp the index to valid range\n return Math.max(0, Math.min(segments - 1, Math.round(rawIndex)))\n}\n\nexport interface SegmentedGaugeProps {\n /**\n * The current value of the gauge\n */\n value?: number\n /**\n * Minimum value of the gauge (aria-valuemin)\n */\n min: number\n /**\n * Maximum value of the gauge (aria-valuemax)\n */\n max: number\n /**\n * Description text for the gauge (aria-describedby)\n */\n description?: string\n /**\n * Size of the gauge\n */\n size?: 'sm' | 'md'\n /**\n * Intent of the gauge - predefined color intent\n */\n intent?: 'main' | 'support' | 'accent' | 'success' | 'alert' | 'danger' | 'info' | 'neutral'\n /**\n * Custom color for the gauge (hex, CSS variable, etc.)\n */\n customColor?: string\n /**\n * ID of the gauge element\n */\n id?: string\n /**\n * Accessible label for the gauge (required if no id is provided)\n */\n 'aria-label'?: string\n /**\n * Textual representation of the current value (aria-valuetext)\n * By default, percentage is used (e.g. \"33%\")\n */\n 'aria-valuetext'?: string\n /**\n * Additional CSS classes\n */\n className?: string\n /**\n * Ref to the root element\n */\n ref?: Ref<HTMLDivElement>\n /**\n * Children render prop for custom rendering\n */\n children?: (props: {\n segments: {\n isActive: boolean\n isCurrent: boolean\n }[]\n currentIndex: number\n }) => React.ReactNode\n}\n\nexport const SegmentedGauge = ({\n value,\n min,\n max,\n description,\n size = 'md',\n intent = 'neutral',\n customColor,\n id,\n 'aria-label': ariaLabel,\n className,\n ref,\n children,\n ...props\n}: SegmentedGaugeProps) => {\n // Calculate segments from min and max\n const segments = max - min + 1\n const currentIndex = useMemo(\n () => calculateCurrentIndex(value, min, max, segments),\n [value, min, max, segments]\n )\n\n // Generate unique IDs\n const internalLabelId = useId()\n const generatedId = useId()\n // Use provided id or generated one for the gauge element\n const gaugeId = id || generatedId\n\n const segmentsData = useMemo(() => {\n return Array.from({ length: segments }, (_, index) => ({\n isActive: currentIndex !== -1 && index <= currentIndex,\n isCurrent: currentIndex !== -1 && index === currentIndex,\n }))\n }, [segments, currentIndex])\n\n const contextValue = useMemo(\n () => ({\n value,\n min,\n max,\n segments,\n currentIndex,\n size,\n intent,\n customColor,\n labelId: internalLabelId,\n gaugeId,\n }),\n [value, min, max, segments, currentIndex, size, intent, customColor, internalLabelId, gaugeId]\n )\n\n /**\n * A `meter` role MUST have a value. If the value is not available, the component uses a `status` role instead.\n */\n const roleProps =\n value != null\n ? {\n role: 'meter',\n 'aria-valuenow': value,\n 'aria-valuemin': min,\n 'aria-valuemax': max,\n }\n : {\n role: 'status',\n }\n\n return (\n <SegmentedGaugeContext.Provider value={contextValue}>\n <div\n id={gaugeId}\n data-spark-component=\"segmented-gauge\"\n ref={ref}\n className={cx('gap-md flex flex-wrap items-center', className)}\n {...roleProps}\n aria-labelledby={id ? `${gaugeId}-label` : undefined}\n aria-label={!id ? ariaLabel : undefined}\n aria-describedby={internalLabelId}\n {...props}\n >\n {children ? (\n children({\n segments: segmentsData,\n currentIndex,\n })\n ) : (\n <>\n <SegmentedGaugeTrack>\n {segmentsData.map((_, index) => (\n <SegmentedGaugeSegment key={index} index={index} />\n ))}\n </SegmentedGaugeTrack>\n\n {description && (\n <SegmentedGaugeLabel id={internalLabelId}>{description}</SegmentedGaugeLabel>\n )}\n </>\n )}\n </div>\n </SegmentedGaugeContext.Provider>\n )\n}\n\nSegmentedGauge.displayName = 'SegmentedGauge'\n","import { SegmentedGauge as Root } from './SegmentedGauge'\nimport { SegmentedGaugeLabel } from './SegmentedGaugeLabel'\nimport { SegmentedGaugeSegment } from './SegmentedGaugeSegment'\nimport { SegmentedGaugeTrack } from './SegmentedGaugeTrack'\n\nexport const SegmentedGauge: typeof Root & {\n Track: typeof SegmentedGaugeTrack\n Segment: typeof SegmentedGaugeSegment\n Label: typeof SegmentedGaugeLabel\n} = Object.assign(Root, {\n Track: SegmentedGaugeTrack,\n Segment: SegmentedGaugeSegment,\n Label: SegmentedGaugeLabel,\n})\n\nSegmentedGauge.displayName = 'SegmentedGauge'\nSegmentedGaugeTrack.displayName = 'SegmentedGauge.Track'\nSegmentedGaugeSegment.displayName = 'SegmentedGauge.Segment'\nSegmentedGaugeLabel.displayName = 'SegmentedGauge.Label'\n\nexport { type SegmentedGaugeProps } from './SegmentedGauge'\nexport { type SegmentedGaugeTrackProps } from './SegmentedGaugeTrack'\nexport { type SegmentedGaugeSegmentProps } from './SegmentedGaugeSegment'\nexport { type SegmentedGaugeLabelProps } from './SegmentedGaugeLabel'\n"],"names":["SegmentedGaugeContext","createContext","useSegmentedGaugeContext","context","useContext","SegmentedGaugeLabel","className","children","ref","id","props","labelId","jsx","cx","SegmentedGaugeSegment","index","size","intent","customColor","currentIndex","isActive","isCurrent","gaugeColor","useMemo","segmentClasses","indicatorClasses","jsxs","SegmentedGaugeTrack","calculateCurrentIndex","value","min","max","segments","normalizedValue","segmentSize","rawIndex","SegmentedGauge","description","ariaLabel","internalLabelId","useId","generatedId","gaugeId","segmentsData","_","contextValue","roleProps","Fragment","Root"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/segmented-gauge/SegmentedGaugeContext.tsx","../../src/segmented-gauge/SegmentedGaugeLabel.tsx","../../src/segmented-gauge/SegmentedGaugeSegment.tsx","../../src/segmented-gauge/SegmentedGaugeTrack.tsx","../../src/segmented-gauge/SegmentedGauge.tsx","../../src/segmented-gauge/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface SegmentedGaugeContextValue {\n value?: number\n min: number\n max: number\n segments: number\n currentIndex: number\n size: 'sm' | 'md'\n intent: 'main' | 'support' | 'accent' | 'success' | 'alert' | 'danger' | 'info' | 'neutral'\n customColor?: string\n labelId: string\n gaugeId: string\n}\n\nexport const SegmentedGaugeContext = createContext<SegmentedGaugeContextValue | null>(null)\n\nexport const useSegmentedGaugeContext = () => {\n const context = useContext(SegmentedGaugeContext)\n\n if (!context) {\n throw new Error('useSegmentedGaugeContext must be used within a SegmentedGauge provider')\n }\n\n return context\n}\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref } from 'react'\n\nimport { useSegmentedGaugeContext } from './SegmentedGaugeContext'\n\nexport interface SegmentedGaugeLabelProps extends ComponentProps<'span'> {\n ref?: Ref<HTMLSpanElement>\n id?: string\n}\n\nexport const SegmentedGaugeLabel = ({\n className,\n children,\n ref,\n id,\n ...props\n}: SegmentedGaugeLabelProps) => {\n const { labelId } = useSegmentedGaugeContext()\n\n return (\n <span\n data-spark-component=\"segmented-gauge-label\"\n data-testid=\"segmented-gauge-label\"\n ref={ref}\n id={id || labelId}\n className={cx('default:text-on-surface default:text-body-2', className)}\n {...props}\n >\n {children}\n </span>\n )\n}\n\nSegmentedGaugeLabel.displayName = 'SegmentedGauge.Label'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref, useMemo } from 'react'\n\nimport { useSegmentedGaugeContext } from './SegmentedGaugeContext'\n\nexport interface SegmentedGaugeSegmentProps extends ComponentProps<'div'> {\n /**\n * Index of this segment (0-based)\n */\n index?: number\n ref?: Ref<HTMLDivElement>\n}\n\nexport const SegmentedGaugeSegment = ({\n index = 0,\n className,\n children,\n ref,\n ...props\n}: SegmentedGaugeSegmentProps) => {\n const { size, intent, customColor, currentIndex } = useSegmentedGaugeContext()\n\n // Calculate isActive and isCurrent from context and index\n const isActive = currentIndex !== -1 && index <= currentIndex\n const isCurrent = currentIndex !== -1 && index === currentIndex\n\n const gaugeColor = useMemo(() => {\n // If customColor is provided, use it\n if (customColor) {\n return customColor\n }\n\n // Handle predefined intents\n switch (intent) {\n case 'main':\n return 'var(--color-main)'\n case 'support':\n return 'var(--color-support)'\n case 'accent':\n return 'var(--color-accent)'\n case 'success':\n return 'var(--color-success)'\n case 'alert':\n return 'var(--color-alert)'\n case 'danger':\n return 'var(--color-error)'\n case 'info':\n return 'var(--color-info)'\n case 'neutral':\n return 'var(--color-neutral)'\n default:\n return 'var(--color-neutral)'\n }\n }, [intent, customColor])\n\n const segmentClasses = cx(\n 'border-outline relative rounded-full',\n {\n 'h-sz-8 w-sz-24': size === 'sm',\n 'h-sz-12 w-sz-36': size === 'md',\n 'default:bg-[var(--gauge-color)]': isActive,\n 'border-sm bg-surface': !isActive,\n },\n className\n )\n\n const indicatorClasses = cx(\n 'absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2',\n 'default:bg-surface default:rounded-full',\n 'border-[var(--gauge-color)]',\n {\n 'size-sz-12 border-md': size === 'sm',\n 'size-sz-20 border-lg': size === 'md',\n }\n )\n\n return (\n <div\n data-spark-component=\"segmented-gauge-segment\"\n data-testid=\"segmented-gauge-segment\"\n data-active={isActive}\n data-current={isCurrent}\n ref={ref}\n style={\n {\n '--gauge-color': gaugeColor,\n } as React.CSSProperties\n }\n className={segmentClasses}\n {...props}\n >\n {children}\n {isCurrent && <div className={indicatorClasses} aria-hidden=\"true\" />}\n </div>\n )\n}\n\nSegmentedGaugeSegment.displayName = 'SegmentedGauge.Segment'\n","import { cx } from 'class-variance-authority'\nimport { ComponentProps, Ref } from 'react'\n\nexport interface SegmentedGaugeTrackProps extends ComponentProps<'div'> {\n ref?: Ref<HTMLDivElement>\n}\n\nexport const SegmentedGaugeTrack = ({\n className,\n children,\n ref,\n ...props\n}: SegmentedGaugeTrackProps) => {\n return (\n <div\n data-spark-component=\"segmented-gauge-track\"\n ref={ref}\n className={cx('gap-sm relative flex rounded-full', className)}\n {...props}\n >\n {children}\n </div>\n )\n}\n\nSegmentedGaugeTrack.displayName = 'SegmentedGauge.Track'\n","import { cx } from 'class-variance-authority'\nimport { Ref, useId, useMemo } from 'react'\n\nimport { SegmentedGaugeContext } from './SegmentedGaugeContext'\nimport { SegmentedGaugeLabel } from './SegmentedGaugeLabel'\nimport { SegmentedGaugeSegment } from './SegmentedGaugeSegment'\nimport { SegmentedGaugeTrack } from './SegmentedGaugeTrack'\n\nconst calculateCurrentIndex = (\n value: number | undefined,\n min: number,\n max: number,\n segments: number\n) => {\n // If value is undefined or null, no segment is active\n if (value == null) {\n return -1\n }\n const normalizedValue = Math.max(min, Math.min(max, value))\n const range = max - min\n const segmentSize = range / (segments - 1)\n const rawIndex = (normalizedValue - min) / segmentSize\n\n // Clamp the index to valid range\n return Math.max(0, Math.min(segments - 1, Math.round(rawIndex)))\n}\n\nexport interface SegmentedGaugeProps {\n /**\n * The current value of the gauge\n */\n value?: number\n /**\n * Minimum value of the gauge (aria-valuemin)\n */\n min: number\n /**\n * Maximum value of the gauge (aria-valuemax)\n */\n max: number\n /**\n * Description text for the gauge (aria-describedby)\n */\n description?: string\n /**\n * Size of the gauge\n */\n size?: 'sm' | 'md'\n /**\n * Intent of the gauge - predefined color intent\n */\n intent?: 'main' | 'support' | 'accent' | 'success' | 'alert' | 'danger' | 'info' | 'neutral'\n /**\n * Custom color for the gauge (hex, CSS variable, etc.)\n */\n customColor?: string\n /**\n * ID of the gauge element\n */\n id?: string\n /**\n * Accessible label for the gauge (required if no id is provided)\n */\n 'aria-label'?: string\n /**\n * Textual representation of the current value (aria-valuetext)\n * By default, percentage is used (e.g. \"33%\")\n */\n 'aria-valuetext'?: string\n /**\n * Additional CSS classes\n */\n className?: string\n /**\n * Ref to the root element\n */\n ref?: Ref<HTMLDivElement>\n /**\n * Children render prop for custom rendering\n */\n children?: (props: {\n segments: {\n isActive: boolean\n isCurrent: boolean\n }[]\n currentIndex: number\n }) => React.ReactNode\n}\n\nexport const SegmentedGauge = ({\n value,\n min,\n max,\n description,\n size = 'md',\n intent = 'neutral',\n customColor,\n id,\n 'aria-label': ariaLabel,\n className,\n ref,\n children,\n ...props\n}: SegmentedGaugeProps) => {\n // Calculate segments from min and max\n const segments = max - min + 1\n const currentIndex = useMemo(\n () => calculateCurrentIndex(value, min, max, segments),\n [value, min, max, segments]\n )\n\n // Generate unique IDs\n const internalLabelId = useId()\n const generatedId = useId()\n // Use provided id or generated one for the gauge element\n const gaugeId = id || generatedId\n\n const segmentsData = useMemo(() => {\n return Array.from({ length: segments }, (_, index) => ({\n isActive: currentIndex !== -1 && index <= currentIndex,\n isCurrent: currentIndex !== -1 && index === currentIndex,\n }))\n }, [segments, currentIndex])\n\n const contextValue = useMemo(\n () => ({\n value,\n min,\n max,\n segments,\n currentIndex,\n size,\n intent,\n customColor,\n labelId: internalLabelId,\n gaugeId,\n }),\n [value, min, max, segments, currentIndex, size, intent, customColor, internalLabelId, gaugeId]\n )\n\n /**\n * A `meter` role MUST have a value. If the value is not available, the component uses a `status` role instead.\n */\n const roleProps =\n value != null\n ? {\n role: 'meter',\n 'aria-valuenow': value,\n 'aria-valuemin': min,\n 'aria-valuemax': max,\n }\n : {\n role: 'status',\n }\n\n return (\n <SegmentedGaugeContext.Provider value={contextValue}>\n <div\n id={gaugeId}\n data-spark-component=\"segmented-gauge\"\n ref={ref}\n className={cx('gap-md flex flex-wrap items-center', className)}\n {...roleProps}\n aria-labelledby={id ? `${gaugeId}-label` : undefined}\n aria-label={!id ? ariaLabel : undefined}\n aria-describedby={internalLabelId}\n {...props}\n >\n {children ? (\n children({\n segments: segmentsData,\n currentIndex,\n })\n ) : (\n <>\n <SegmentedGaugeTrack>\n {segmentsData.map((_, index) => (\n <SegmentedGaugeSegment key={index} index={index} />\n ))}\n </SegmentedGaugeTrack>\n\n {description && (\n <SegmentedGaugeLabel id={internalLabelId}>{description}</SegmentedGaugeLabel>\n )}\n </>\n )}\n </div>\n </SegmentedGaugeContext.Provider>\n )\n}\n\nSegmentedGauge.displayName = 'SegmentedGauge'\n","import { SegmentedGauge as Root } from './SegmentedGauge'\nimport { SegmentedGaugeLabel } from './SegmentedGaugeLabel'\nimport { SegmentedGaugeSegment } from './SegmentedGaugeSegment'\nimport { SegmentedGaugeTrack } from './SegmentedGaugeTrack'\n\nexport const SegmentedGauge: typeof Root & {\n Track: typeof SegmentedGaugeTrack\n Segment: typeof SegmentedGaugeSegment\n Label: typeof SegmentedGaugeLabel\n} = Object.assign(Root, {\n Track: SegmentedGaugeTrack,\n Segment: SegmentedGaugeSegment,\n Label: SegmentedGaugeLabel,\n})\n\nSegmentedGauge.displayName = 'SegmentedGauge'\nSegmentedGaugeTrack.displayName = 'SegmentedGauge.Track'\nSegmentedGaugeSegment.displayName = 'SegmentedGauge.Segment'\nSegmentedGaugeLabel.displayName = 'SegmentedGauge.Label'\n\nexport { type SegmentedGaugeProps } from './SegmentedGauge'\nexport { type SegmentedGaugeTrackProps } from './SegmentedGaugeTrack'\nexport { type SegmentedGaugeSegmentProps } from './SegmentedGaugeSegment'\nexport { type SegmentedGaugeLabelProps } from './SegmentedGaugeLabel'\n"],"mappings":"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"}