@epilot/spark-ui 0.26.0 → 0.27.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 (223) hide show
  1. package/dist/components/accordion.cjs.map +1 -1
  2. package/dist/components/accordion.d.cts +1 -1
  3. package/dist/components/accordion.d.ts +1 -1
  4. package/dist/components/accordion.js.map +1 -1
  5. package/dist/components/alert-dialog.cjs +2 -2
  6. package/dist/components/alert-dialog.cjs.map +1 -1
  7. package/dist/components/alert-dialog.js +2 -2
  8. package/dist/components/alert-dialog.js.map +1 -1
  9. package/dist/components/attachment.d.cts +1 -1
  10. package/dist/components/attachment.d.ts +1 -1
  11. package/dist/components/avatar.d.cts +1 -1
  12. package/dist/components/avatar.d.ts +1 -1
  13. package/dist/components/badge.cjs +10 -2
  14. package/dist/components/badge.cjs.map +1 -1
  15. package/dist/components/badge.d.cts +2 -1
  16. package/dist/components/badge.d.ts +2 -1
  17. package/dist/components/badge.js +10 -2
  18. package/dist/components/badge.js.map +1 -1
  19. package/dist/components/banner.d.cts +1 -1
  20. package/dist/components/banner.d.ts +1 -1
  21. package/dist/components/box.d.cts +1 -1
  22. package/dist/components/box.d.ts +1 -1
  23. package/dist/components/bubble.cjs +1 -1
  24. package/dist/components/bubble.cjs.map +1 -1
  25. package/dist/components/bubble.d.cts +1 -1
  26. package/dist/components/bubble.d.ts +1 -1
  27. package/dist/components/bubble.js +1 -1
  28. package/dist/components/bubble.js.map +1 -1
  29. package/dist/components/button-group.d.cts +1 -1
  30. package/dist/components/button-group.d.ts +1 -1
  31. package/dist/components/button.cjs +27 -6
  32. package/dist/components/button.cjs.map +1 -1
  33. package/dist/components/button.d.cts +9 -8
  34. package/dist/components/button.d.ts +9 -8
  35. package/dist/components/button.js +27 -6
  36. package/dist/components/button.js.map +1 -1
  37. package/dist/components/callout.cjs +1 -1
  38. package/dist/components/callout.cjs.map +1 -1
  39. package/dist/components/callout.d.cts +1 -1
  40. package/dist/components/callout.d.ts +1 -1
  41. package/dist/components/callout.js +1 -1
  42. package/dist/components/callout.js.map +1 -1
  43. package/dist/components/card.cjs +8 -4
  44. package/dist/components/card.cjs.map +1 -1
  45. package/dist/components/card.d.cts +6 -2
  46. package/dist/components/card.d.ts +6 -2
  47. package/dist/components/card.js +8 -4
  48. package/dist/components/card.js.map +1 -1
  49. package/dist/components/checkbox-group.cjs +31 -0
  50. package/dist/components/checkbox-group.cjs.map +1 -0
  51. package/dist/components/checkbox-group.d.cts +27 -0
  52. package/dist/components/checkbox-group.d.ts +27 -0
  53. package/dist/components/checkbox-group.js +28 -0
  54. package/dist/components/checkbox-group.js.map +1 -0
  55. package/dist/components/checkbox.d.cts +1 -1
  56. package/dist/components/checkbox.d.ts +1 -1
  57. package/dist/components/dialog.cjs +2 -2
  58. package/dist/components/dialog.cjs.map +1 -1
  59. package/dist/components/dialog.js +2 -2
  60. package/dist/components/dialog.js.map +1 -1
  61. package/dist/components/drawer.cjs +1 -1
  62. package/dist/components/drawer.cjs.map +1 -1
  63. package/dist/components/drawer.js +1 -1
  64. package/dist/components/drawer.js.map +1 -1
  65. package/dist/components/empty-state.cjs +3 -13
  66. package/dist/components/empty-state.cjs.map +1 -1
  67. package/dist/components/empty-state.js +3 -13
  68. package/dist/components/empty-state.js.map +1 -1
  69. package/dist/components/energy-breakdown.cjs +1 -1
  70. package/dist/components/energy-breakdown.cjs.map +1 -1
  71. package/dist/components/energy-breakdown.js +1 -1
  72. package/dist/components/energy-breakdown.js.map +1 -1
  73. package/dist/components/entity-card.cjs +1 -1
  74. package/dist/components/entity-card.cjs.map +1 -1
  75. package/dist/components/entity-card.js +1 -1
  76. package/dist/components/entity-card.js.map +1 -1
  77. package/dist/components/field.cjs +113 -18
  78. package/dist/components/field.cjs.map +1 -1
  79. package/dist/components/field.d.cts +16 -3
  80. package/dist/components/field.d.ts +16 -3
  81. package/dist/components/field.js +114 -20
  82. package/dist/components/field.js.map +1 -1
  83. package/dist/components/input-group.cjs +9 -9
  84. package/dist/components/input-group.cjs.map +1 -1
  85. package/dist/components/input-group.d.cts +1 -1
  86. package/dist/components/input-group.d.ts +1 -1
  87. package/dist/components/input-group.js +9 -9
  88. package/dist/components/input-group.js.map +1 -1
  89. package/dist/components/input.d.cts +1 -1
  90. package/dist/components/input.d.ts +1 -1
  91. package/dist/components/list.cjs +21 -5
  92. package/dist/components/list.cjs.map +1 -1
  93. package/dist/components/list.d.cts +13 -5
  94. package/dist/components/list.d.ts +13 -5
  95. package/dist/components/list.js +21 -5
  96. package/dist/components/list.js.map +1 -1
  97. package/dist/components/marker.cjs +1 -1
  98. package/dist/components/marker.cjs.map +1 -1
  99. package/dist/components/marker.js +1 -1
  100. package/dist/components/marker.js.map +1 -1
  101. package/dist/components/message-scroller.cjs +1 -1
  102. package/dist/components/message-scroller.cjs.map +1 -1
  103. package/dist/components/message-scroller.js +1 -1
  104. package/dist/components/message-scroller.js.map +1 -1
  105. package/dist/components/page-header.d.cts +1 -1
  106. package/dist/components/page-header.d.ts +1 -1
  107. package/dist/components/pill.d.cts +1 -1
  108. package/dist/components/pill.d.ts +1 -1
  109. package/dist/components/radio.cjs +6 -2
  110. package/dist/components/radio.cjs.map +1 -1
  111. package/dist/components/radio.d.cts +4 -2
  112. package/dist/components/radio.d.ts +4 -2
  113. package/dist/components/radio.js +6 -2
  114. package/dist/components/radio.js.map +1 -1
  115. package/dist/components/rating.cjs +167 -0
  116. package/dist/components/rating.cjs.map +1 -0
  117. package/dist/components/rating.d.cts +50 -0
  118. package/dist/components/rating.d.ts +50 -0
  119. package/dist/components/rating.js +162 -0
  120. package/dist/components/rating.js.map +1 -0
  121. package/dist/components/schedule-list.cjs +1 -1
  122. package/dist/components/schedule-list.cjs.map +1 -1
  123. package/dist/components/schedule-list.js +1 -1
  124. package/dist/components/schedule-list.js.map +1 -1
  125. package/dist/components/scroll-area.cjs +9 -2
  126. package/dist/components/scroll-area.cjs.map +1 -1
  127. package/dist/components/scroll-area.d.cts +1 -1
  128. package/dist/components/scroll-area.d.ts +1 -1
  129. package/dist/components/scroll-area.js +10 -3
  130. package/dist/components/scroll-area.js.map +1 -1
  131. package/dist/components/segmented-control.d.cts +1 -1
  132. package/dist/components/segmented-control.d.ts +1 -1
  133. package/dist/components/select.d.cts +1 -1
  134. package/dist/components/select.d.ts +1 -1
  135. package/dist/components/selection-item.cjs +42 -0
  136. package/dist/components/selection-item.cjs.map +1 -0
  137. package/dist/components/selection-item.d.cts +25 -0
  138. package/dist/components/selection-item.d.ts +25 -0
  139. package/dist/components/selection-item.js +39 -0
  140. package/dist/components/selection-item.js.map +1 -0
  141. package/dist/components/sheet.cjs +1 -1
  142. package/dist/components/sheet.js +1 -1
  143. package/dist/components/skeleton.cjs +1 -1
  144. package/dist/components/skeleton.cjs.map +1 -1
  145. package/dist/components/skeleton.js +1 -1
  146. package/dist/components/skeleton.js.map +1 -1
  147. package/dist/components/slider.cjs +1 -1
  148. package/dist/components/slider.cjs.map +1 -1
  149. package/dist/components/slider.js +1 -1
  150. package/dist/components/slider.js.map +1 -1
  151. package/dist/components/spinner.cjs +81 -8
  152. package/dist/components/spinner.cjs.map +1 -1
  153. package/dist/components/spinner.js +81 -8
  154. package/dist/components/spinner.js.map +1 -1
  155. package/dist/components/stat-card.cjs +1 -1
  156. package/dist/components/stat-card.cjs.map +1 -1
  157. package/dist/components/stat-card.js +1 -1
  158. package/dist/components/stat-card.js.map +1 -1
  159. package/dist/components/stepper.cjs +3 -2
  160. package/dist/components/stepper.cjs.map +1 -1
  161. package/dist/components/stepper.js +3 -2
  162. package/dist/components/stepper.js.map +1 -1
  163. package/dist/components/switch-group.cjs +32 -0
  164. package/dist/components/switch-group.cjs.map +1 -0
  165. package/dist/components/switch-group.d.cts +26 -0
  166. package/dist/components/switch-group.d.ts +26 -0
  167. package/dist/components/switch-group.js +29 -0
  168. package/dist/components/switch-group.js.map +1 -0
  169. package/dist/components/switch.d.cts +1 -1
  170. package/dist/components/switch.d.ts +1 -1
  171. package/dist/components/tabs.cjs +32 -23
  172. package/dist/components/tabs.cjs.map +1 -1
  173. package/dist/components/tabs.d.cts +5 -5
  174. package/dist/components/tabs.d.ts +5 -5
  175. package/dist/components/tabs.js +32 -23
  176. package/dist/components/tabs.js.map +1 -1
  177. package/dist/components/textarea.d.cts +1 -1
  178. package/dist/components/textarea.d.ts +1 -1
  179. package/dist/components/theme.cjs +44 -2
  180. package/dist/components/theme.cjs.map +1 -1
  181. package/dist/components/theme.d.cts +4 -2
  182. package/dist/components/theme.d.ts +4 -2
  183. package/dist/components/theme.js +44 -2
  184. package/dist/components/theme.js.map +1 -1
  185. package/dist/components/toast.cjs +2 -2
  186. package/dist/components/toast.cjs.map +1 -1
  187. package/dist/components/toast.js +2 -2
  188. package/dist/components/toast.js.map +1 -1
  189. package/dist/components/toggle-group.d.cts +1 -1
  190. package/dist/components/toggle-group.d.ts +1 -1
  191. package/dist/components/toggle.d.cts +2 -2
  192. package/dist/components/toggle.d.ts +2 -2
  193. package/dist/lib/accent-theme.d.cts +1 -1
  194. package/dist/lib/accent-theme.d.ts +1 -1
  195. package/dist/lib/container-chrome.cjs +4 -4
  196. package/dist/lib/container-chrome.cjs.map +1 -1
  197. package/dist/lib/container-chrome.d.cts +1 -1
  198. package/dist/lib/container-chrome.d.ts +1 -1
  199. package/dist/lib/container-chrome.js +4 -4
  200. package/dist/lib/container-chrome.js.map +1 -1
  201. package/dist/lib/input-box-variants.cjs +8 -8
  202. package/dist/lib/input-box-variants.cjs.map +1 -1
  203. package/dist/lib/input-box-variants.d.cts +1 -1
  204. package/dist/lib/input-box-variants.d.ts +1 -1
  205. package/dist/lib/input-box-variants.js +8 -8
  206. package/dist/lib/input-box-variants.js.map +1 -1
  207. package/dist/lib/selection-list.cjs +17 -0
  208. package/dist/lib/selection-list.cjs.map +1 -0
  209. package/dist/lib/selection-list.d.cts +11 -0
  210. package/dist/lib/selection-list.d.ts +11 -0
  211. package/dist/lib/selection-list.js +15 -0
  212. package/dist/lib/selection-list.js.map +1 -0
  213. package/dist/lib/theme-types.cjs.map +1 -1
  214. package/dist/lib/theme-types.d.cts +2 -2
  215. package/dist/lib/theme-types.d.ts +2 -2
  216. package/dist/lib/theme-types.js.map +1 -1
  217. package/dist/lib/toggle-group-context.d.cts +2 -1
  218. package/dist/lib/toggle-group-context.d.ts +2 -1
  219. package/dist/styles/spark-default.css +12 -1
  220. package/dist/styles/theme.css +98 -0
  221. package/dist/{theme-types-Bn5E15-P.d.ts → theme-types-CKZzOmSa.d.cts} +11 -2
  222. package/dist/{theme-types-Bn5E15-P.d.cts → theme-types-CKZzOmSa.d.ts} +11 -2
  223. package/package.json +1 -1
@@ -46,7 +46,7 @@ function MessageScrollerViewport({ className, ...props }) {
46
46
  function MessageScrollerContent({ className, ...props }) {
47
47
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_shadcn_react_message_scroller.MessageScroller.Content, {
48
48
  "data-slot": "message-scroller-content",
49
- className: (0, cn.cn)("flex h-max min-h-full flex-col gap-8", className),
49
+ className: (0, cn.cn)("flex h-max min-h-full flex-col gap-[calc(var(--spark-layout-gap)*8)]", className),
50
50
  ...props
51
51
  });
52
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message-scroller.cjs","names":["React","LazyMotion","domAnimation","MessageScrollerPrimitive","useReducedMotion","MESSAGE_ANIMATIONS","Button","ArrowDownward","ArrowUpward"],"sources":["../../src/components/message-scroller.tsx"],"sourcesContent":["import { ArrowDownward, ArrowUpward } from '@epilot/spark-icons'\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from '@shadcn/react/message-scroller'\nimport { LazyMotion, domAnimation } from 'motion/react'\nimport { create } from 'motion/react-m'\nimport * as React from 'react'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { MESSAGE_ANIMATIONS } from '../lib/message-animations'\nimport { cn } from '../utils/cn'\nimport { Button, type ButtonProps } from './button'\n\nconst MessageScrollerAnimationReadyContext = React.createContext(false)\nconst MotionDiv = create('div')\n\ntype MessageScrollerItemProps = Omit<\n React.ComponentProps<typeof MessageScrollerPrimitive.Item>,\n | 'animate'\n | 'exit'\n | 'initial'\n | 'variants'\n | 'onAnimationStart'\n | 'onDrag'\n | 'onDragStart'\n | 'onDragEnd'\n | 'onDragTransitionEnd'\n>\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\n) {\n const [ready, setReady] = React.useState(false)\n\n React.useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <LazyMotion features={domAnimation} strict>\n <MessageScrollerAnimationReadyContext.Provider value={ready}>\n <MessageScrollerPrimitive.Provider {...props} />\n </MessageScrollerAnimationReadyContext.Provider>\n </LazyMotion>\n )\n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\n return (\n <MessageScrollerPrimitive.Root\n data-slot=\"message-scroller\"\n className={cn(\n 'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\n return (\n <MessageScrollerPrimitive.Viewport\n data-slot=\"message-scroller-viewport\"\n // The bottom fade follows the primitive's data-scrollable instead of a\n // scroll timeline, which counts the anchor spacer and so faded the last\n // message with nothing below it. Never hide the bar with no-scrollbar\n // here: it drops the stable gutter, so content reflows and can retrigger\n // autoscroll in a loop.\n className={cn(\n 'size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [mask-image:linear-gradient(to_bottom,#000_calc(100%_-_var(--scroll-fade-b)),transparent)] transition-[--scroll-fade-b] duration-200 contain-content [--scroll-fade-b:0px] [scrollbar-gutter:stable] [scrollbar-width:thin] focus-visible:ring-2 focus-visible:ring-spark-11 focus-visible:ring-offset-2 focus-visible:outline-hidden data-[scrollable~=end]:[--scroll-fade-b:min(12%,calc(var(--spacing)*10))] motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\n return (\n <MessageScrollerPrimitive.Content\n data-slot=\"message-scroller-content\"\n className={cn('flex h-max min-h-full flex-col gap-8', className)}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n children,\n ...props\n}: MessageScrollerItemProps) {\n const ready = React.useContext(MessageScrollerAnimationReadyContext)\n const shouldReduceMotion = useReducedMotion()\n const skipEntrance = !ready || shouldReduceMotion\n\n return (\n <MessageScrollerPrimitive.Item\n {...props}\n data-slot=\"message-scroller-item\"\n scrollAnchor={scrollAnchor}\n className={cn(\n 'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\n className,\n )}\n >\n <MotionDiv\n className=\"w-full min-w-0\"\n variants={MESSAGE_ANIMATIONS['slide-up'].variants}\n initial={skipEntrance ? false : 'initial'}\n animate=\"animate\"\n exit={skipEntrance ? undefined : 'exit'}\n >\n {children}\n </MotionDiv>\n </MessageScrollerPrimitive.Item>\n )\n}\n\n// Renders a spark <Button> via `render`, so its `styleVariant`/`color`/`size`\n// recipe paints the chrome — we only add positioning + the enter/leave animation\n// keyed off the primitive's data-[active] state. Icon is a Spark icon, pointing\n// down for `end` and up for `start`.\nfunction MessageScrollerButton({\n direction = 'end',\n className,\n children,\n render,\n styleVariant = 'surface',\n color = 'neutral',\n size = 'icon-small',\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\n Pick<ButtonProps, 'styleVariant' | 'color' | 'size'>) {\n return (\n <MessageScrollerPrimitive.Button\n data-slot=\"message-scroller-button\"\n data-direction={direction}\n direction={direction}\n className={cn(\n 'absolute inset-s-1/2 -translate-x-1/2 rounded-full transition-[translate,scale,opacity] duration-200 data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full motion-reduce:transition-none rtl:translate-x-1/2',\n className,\n )}\n render={\n render ?? (\n <Button styleVariant={styleVariant} color={color} size={size} />\n )\n }\n {...props}\n >\n {children ?? (\n <>\n {direction === 'end' ? <ArrowDownward /> : <ArrowUpward />}\n <span className=\"sr-only\">\n {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\n </span>\n </>\n )}\n </MessageScrollerPrimitive.Button>\n )\n}\n\nexport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAM,uCAAuCA,MAAM,cAAc,KAAK;AACtE,MAAM,aAAA,GAAA,eAAA,QAAmB,KAAK;AAe9B,SAAS,wBACP,OACA;CACA,MAAM,CAAC,OAAO,YAAYA,MAAM,SAAS,KAAK;CAE9C,MAAM,gBAAgB;EACpB,SAAS,IAAI;CACf,GAAG,CAAC,CAAC;CAEL,OACE,iBAAA,GAAA,kBAAA,KAACC,aAAAA,YAAD;EAAY,UAAUC,aAAAA;EAAc,QAAA;YAClC,iBAAA,GAAA,kBAAA,KAAC,qCAAqC,UAAtC;GAA+C,OAAO;aACpD,iBAAA,GAAA,kBAAA,KAACC,+BAAAA,gBAAyB,UAA1B,EAAmC,GAAI,MAAQ,CAAA;EACF,CAAA;CACrC,CAAA;AAEhB;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC0D;CAC7D,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,MAA1B;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,UAA1B;EACE,aAAU;EAMV,YAAA,GAAA,GAAA,IACE,8eACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,SAA1B;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IAAc,wCAAwC,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAC3B,WACA,eAAe,OACf,UACA,GAAG,SACwB;CAC3B,MAAM,QAAQH,MAAM,WAAW,oCAAoC;CACnE,MAAM,qBAAqBI,iCAAAA,iBAAiB;CAC5C,MAAM,eAAe,CAAC,SAAS;CAE/B,OACE,iBAAA,GAAA,kBAAA,KAACD,+BAAAA,gBAAyB,MAA1B;EACE,GAAI;EACJ,aAAU;EACI;EACd,YAAA,GAAA,GAAA,IACE,kFACA,SACF;YAEA,iBAAA,GAAA,kBAAA,KAAC,WAAD;GACE,WAAU;GACV,UAAUE,+BAAAA,mBAAmB,YAAY;GACzC,SAAS,eAAe,QAAQ;GAChC,SAAQ;GACR,MAAM,eAAe,KAAA,IAAY;GAEhC;EACQ,CAAA;CACkB,CAAA;AAEnC;AAMA,SAAS,sBAAsB,EAC7B,YAAY,OACZ,WACA,UACA,QACA,eAAe,WACf,QAAQ,WACR,OAAO,cACP,GAAG,SAEmD;CACtD,OACE,iBAAA,GAAA,kBAAA,KAACF,+BAAAA,gBAAyB,QAA1B;EACE,aAAU;EACV,kBAAgB;EACL;EACX,YAAA,GAAA,GAAA,IACE,ypBACA,SACF;EACA,QACE,UACE,iBAAA,GAAA,kBAAA,KAACG,0BAAAA,QAAD;GAAsB;GAAqB;GAAa;EAAO,CAAA;EAGnE,GAAI;YAEH,YACC,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACG,cAAc,QAAQ,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,eAAD,CAAgB,CAAA,IAAI,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,aAAD,CAAc,CAAA,GACzD,iBAAA,GAAA,kBAAA,KAAC,QAAD;GAAM,WAAU;aACb,cAAc,QAAQ,kBAAkB;EACrC,CAAA,CACN,EAAA,CAAA;CAE2B,CAAA;AAErC"}
1
+ {"version":3,"file":"message-scroller.cjs","names":["React","LazyMotion","domAnimation","MessageScrollerPrimitive","useReducedMotion","MESSAGE_ANIMATIONS","Button","ArrowDownward","ArrowUpward"],"sources":["../../src/components/message-scroller.tsx"],"sourcesContent":["import { ArrowDownward, ArrowUpward } from '@epilot/spark-icons'\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from '@shadcn/react/message-scroller'\nimport { LazyMotion, domAnimation } from 'motion/react'\nimport { create } from 'motion/react-m'\nimport * as React from 'react'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { MESSAGE_ANIMATIONS } from '../lib/message-animations'\nimport { cn } from '../utils/cn'\nimport { Button, type ButtonProps } from './button'\n\nconst MessageScrollerAnimationReadyContext = React.createContext(false)\nconst MotionDiv = create('div')\n\ntype MessageScrollerItemProps = Omit<\n React.ComponentProps<typeof MessageScrollerPrimitive.Item>,\n | 'animate'\n | 'exit'\n | 'initial'\n | 'variants'\n | 'onAnimationStart'\n | 'onDrag'\n | 'onDragStart'\n | 'onDragEnd'\n | 'onDragTransitionEnd'\n>\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\n) {\n const [ready, setReady] = React.useState(false)\n\n React.useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <LazyMotion features={domAnimation} strict>\n <MessageScrollerAnimationReadyContext.Provider value={ready}>\n <MessageScrollerPrimitive.Provider {...props} />\n </MessageScrollerAnimationReadyContext.Provider>\n </LazyMotion>\n )\n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\n return (\n <MessageScrollerPrimitive.Root\n data-slot=\"message-scroller\"\n className={cn(\n 'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\n return (\n <MessageScrollerPrimitive.Viewport\n data-slot=\"message-scroller-viewport\"\n // The bottom fade follows the primitive's data-scrollable instead of a\n // scroll timeline, which counts the anchor spacer and so faded the last\n // message with nothing below it. Never hide the bar with no-scrollbar\n // here: it drops the stable gutter, so content reflows and can retrigger\n // autoscroll in a loop.\n className={cn(\n 'size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [mask-image:linear-gradient(to_bottom,#000_calc(100%_-_var(--scroll-fade-b)),transparent)] transition-[--scroll-fade-b] duration-200 contain-content [--scroll-fade-b:0px] [scrollbar-gutter:stable] [scrollbar-width:thin] focus-visible:ring-2 focus-visible:ring-spark-11 focus-visible:ring-offset-2 focus-visible:outline-hidden data-[scrollable~=end]:[--scroll-fade-b:min(12%,calc(var(--spacing)*10))] motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\n return (\n <MessageScrollerPrimitive.Content\n data-slot=\"message-scroller-content\"\n className={cn(\n 'flex h-max min-h-full flex-col gap-[calc(var(--spark-layout-gap)*8)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n children,\n ...props\n}: MessageScrollerItemProps) {\n const ready = React.useContext(MessageScrollerAnimationReadyContext)\n const shouldReduceMotion = useReducedMotion()\n const skipEntrance = !ready || shouldReduceMotion\n\n return (\n <MessageScrollerPrimitive.Item\n {...props}\n data-slot=\"message-scroller-item\"\n scrollAnchor={scrollAnchor}\n className={cn(\n 'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\n className,\n )}\n >\n <MotionDiv\n className=\"w-full min-w-0\"\n variants={MESSAGE_ANIMATIONS['slide-up'].variants}\n initial={skipEntrance ? false : 'initial'}\n animate=\"animate\"\n exit={skipEntrance ? undefined : 'exit'}\n >\n {children}\n </MotionDiv>\n </MessageScrollerPrimitive.Item>\n )\n}\n\n// Renders a spark <Button> via `render`, so its `styleVariant`/`color`/`size`\n// recipe paints the chrome — we only add positioning + the enter/leave animation\n// keyed off the primitive's data-[active] state. Icon is a Spark icon, pointing\n// down for `end` and up for `start`.\nfunction MessageScrollerButton({\n direction = 'end',\n className,\n children,\n render,\n styleVariant = 'surface',\n color = 'neutral',\n size = 'icon-small',\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\n Pick<ButtonProps, 'styleVariant' | 'color' | 'size'>) {\n return (\n <MessageScrollerPrimitive.Button\n data-slot=\"message-scroller-button\"\n data-direction={direction}\n direction={direction}\n className={cn(\n 'absolute inset-s-1/2 -translate-x-1/2 rounded-full transition-[translate,scale,opacity] duration-200 data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full motion-reduce:transition-none rtl:translate-x-1/2',\n className,\n )}\n render={\n render ?? (\n <Button styleVariant={styleVariant} color={color} size={size} />\n )\n }\n {...props}\n >\n {children ?? (\n <>\n {direction === 'end' ? <ArrowDownward /> : <ArrowUpward />}\n <span className=\"sr-only\">\n {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\n </span>\n </>\n )}\n </MessageScrollerPrimitive.Button>\n )\n}\n\nexport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAM,uCAAuCA,MAAM,cAAc,KAAK;AACtE,MAAM,aAAA,GAAA,eAAA,QAAmB,KAAK;AAe9B,SAAS,wBACP,OACA;CACA,MAAM,CAAC,OAAO,YAAYA,MAAM,SAAS,KAAK;CAE9C,MAAM,gBAAgB;EACpB,SAAS,IAAI;CACf,GAAG,CAAC,CAAC;CAEL,OACE,iBAAA,GAAA,kBAAA,KAACC,aAAAA,YAAD;EAAY,UAAUC,aAAAA;EAAc,QAAA;YAClC,iBAAA,GAAA,kBAAA,KAAC,qCAAqC,UAAtC;GAA+C,OAAO;aACpD,iBAAA,GAAA,kBAAA,KAACC,+BAAAA,gBAAyB,UAA1B,EAAmC,GAAI,MAAQ,CAAA;EACF,CAAA;CACrC,CAAA;AAEhB;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC0D;CAC7D,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,MAA1B;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,UAA1B;EACE,aAAU;EAMV,YAAA,GAAA,GAAA,IACE,8eACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,iBAAA,GAAA,kBAAA,KAACA,+BAAAA,gBAAyB,SAA1B;EACE,aAAU;EACV,YAAA,GAAA,GAAA,IACE,wEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAC3B,WACA,eAAe,OACf,UACA,GAAG,SACwB;CAC3B,MAAM,QAAQH,MAAM,WAAW,oCAAoC;CACnE,MAAM,qBAAqBI,iCAAAA,iBAAiB;CAC5C,MAAM,eAAe,CAAC,SAAS;CAE/B,OACE,iBAAA,GAAA,kBAAA,KAACD,+BAAAA,gBAAyB,MAA1B;EACE,GAAI;EACJ,aAAU;EACI;EACd,YAAA,GAAA,GAAA,IACE,kFACA,SACF;YAEA,iBAAA,GAAA,kBAAA,KAAC,WAAD;GACE,WAAU;GACV,UAAUE,+BAAAA,mBAAmB,YAAY;GACzC,SAAS,eAAe,QAAQ;GAChC,SAAQ;GACR,MAAM,eAAe,KAAA,IAAY;GAEhC;EACQ,CAAA;CACkB,CAAA;AAEnC;AAMA,SAAS,sBAAsB,EAC7B,YAAY,OACZ,WACA,UACA,QACA,eAAe,WACf,QAAQ,WACR,OAAO,cACP,GAAG,SAEmD;CACtD,OACE,iBAAA,GAAA,kBAAA,KAACF,+BAAAA,gBAAyB,QAA1B;EACE,aAAU;EACV,kBAAgB;EACL;EACX,YAAA,GAAA,GAAA,IACE,ypBACA,SACF;EACA,QACE,UACE,iBAAA,GAAA,kBAAA,KAACG,0BAAAA,QAAD;GAAsB;GAAqB;GAAa;EAAO,CAAA;EAGnE,GAAI;YAEH,YACC,iBAAA,GAAA,kBAAA,MAAA,kBAAA,UAAA,EAAA,UAAA,CACG,cAAc,QAAQ,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,eAAD,CAAgB,CAAA,IAAI,iBAAA,GAAA,kBAAA,KAACC,oBAAAA,aAAD,CAAc,CAAA,GACzD,iBAAA,GAAA,kBAAA,KAAC,QAAD;GAAM,WAAU;aACb,cAAc,QAAQ,kBAAkB;EACrC,CAAA,CACN,EAAA,CAAA;CAE2B,CAAA;AAErC"}
@@ -43,7 +43,7 @@ function MessageScrollerViewport({ className, ...props }) {
43
43
  function MessageScrollerContent({ className, ...props }) {
44
44
  return /* @__PURE__ */ jsx(MessageScroller$1.Content, {
45
45
  "data-slot": "message-scroller-content",
46
- className: cn("flex h-max min-h-full flex-col gap-8", className),
46
+ className: cn("flex h-max min-h-full flex-col gap-[calc(var(--spark-layout-gap)*8)]", className),
47
47
  ...props
48
48
  });
49
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message-scroller.js","names":["React","MessageScrollerPrimitive"],"sources":["../../src/components/message-scroller.tsx"],"sourcesContent":["import { ArrowDownward, ArrowUpward } from '@epilot/spark-icons'\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from '@shadcn/react/message-scroller'\nimport { LazyMotion, domAnimation } from 'motion/react'\nimport { create } from 'motion/react-m'\nimport * as React from 'react'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { MESSAGE_ANIMATIONS } from '../lib/message-animations'\nimport { cn } from '../utils/cn'\nimport { Button, type ButtonProps } from './button'\n\nconst MessageScrollerAnimationReadyContext = React.createContext(false)\nconst MotionDiv = create('div')\n\ntype MessageScrollerItemProps = Omit<\n React.ComponentProps<typeof MessageScrollerPrimitive.Item>,\n | 'animate'\n | 'exit'\n | 'initial'\n | 'variants'\n | 'onAnimationStart'\n | 'onDrag'\n | 'onDragStart'\n | 'onDragEnd'\n | 'onDragTransitionEnd'\n>\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\n) {\n const [ready, setReady] = React.useState(false)\n\n React.useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <LazyMotion features={domAnimation} strict>\n <MessageScrollerAnimationReadyContext.Provider value={ready}>\n <MessageScrollerPrimitive.Provider {...props} />\n </MessageScrollerAnimationReadyContext.Provider>\n </LazyMotion>\n )\n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\n return (\n <MessageScrollerPrimitive.Root\n data-slot=\"message-scroller\"\n className={cn(\n 'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\n return (\n <MessageScrollerPrimitive.Viewport\n data-slot=\"message-scroller-viewport\"\n // The bottom fade follows the primitive's data-scrollable instead of a\n // scroll timeline, which counts the anchor spacer and so faded the last\n // message with nothing below it. Never hide the bar with no-scrollbar\n // here: it drops the stable gutter, so content reflows and can retrigger\n // autoscroll in a loop.\n className={cn(\n 'size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [mask-image:linear-gradient(to_bottom,#000_calc(100%_-_var(--scroll-fade-b)),transparent)] transition-[--scroll-fade-b] duration-200 contain-content [--scroll-fade-b:0px] [scrollbar-gutter:stable] [scrollbar-width:thin] focus-visible:ring-2 focus-visible:ring-spark-11 focus-visible:ring-offset-2 focus-visible:outline-hidden data-[scrollable~=end]:[--scroll-fade-b:min(12%,calc(var(--spacing)*10))] motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\n return (\n <MessageScrollerPrimitive.Content\n data-slot=\"message-scroller-content\"\n className={cn('flex h-max min-h-full flex-col gap-8', className)}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n children,\n ...props\n}: MessageScrollerItemProps) {\n const ready = React.useContext(MessageScrollerAnimationReadyContext)\n const shouldReduceMotion = useReducedMotion()\n const skipEntrance = !ready || shouldReduceMotion\n\n return (\n <MessageScrollerPrimitive.Item\n {...props}\n data-slot=\"message-scroller-item\"\n scrollAnchor={scrollAnchor}\n className={cn(\n 'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\n className,\n )}\n >\n <MotionDiv\n className=\"w-full min-w-0\"\n variants={MESSAGE_ANIMATIONS['slide-up'].variants}\n initial={skipEntrance ? false : 'initial'}\n animate=\"animate\"\n exit={skipEntrance ? undefined : 'exit'}\n >\n {children}\n </MotionDiv>\n </MessageScrollerPrimitive.Item>\n )\n}\n\n// Renders a spark <Button> via `render`, so its `styleVariant`/`color`/`size`\n// recipe paints the chrome — we only add positioning + the enter/leave animation\n// keyed off the primitive's data-[active] state. Icon is a Spark icon, pointing\n// down for `end` and up for `start`.\nfunction MessageScrollerButton({\n direction = 'end',\n className,\n children,\n render,\n styleVariant = 'surface',\n color = 'neutral',\n size = 'icon-small',\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\n Pick<ButtonProps, 'styleVariant' | 'color' | 'size'>) {\n return (\n <MessageScrollerPrimitive.Button\n data-slot=\"message-scroller-button\"\n data-direction={direction}\n direction={direction}\n className={cn(\n 'absolute inset-s-1/2 -translate-x-1/2 rounded-full transition-[translate,scale,opacity] duration-200 data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full motion-reduce:transition-none rtl:translate-x-1/2',\n className,\n )}\n render={\n render ?? (\n <Button styleVariant={styleVariant} color={color} size={size} />\n )\n }\n {...props}\n >\n {children ?? (\n <>\n {direction === 'end' ? <ArrowDownward /> : <ArrowUpward />}\n <span className=\"sr-only\">\n {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\n </span>\n </>\n )}\n </MessageScrollerPrimitive.Button>\n )\n}\n\nexport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,uCAAuCA,QAAM,cAAc,KAAK;AACtE,MAAM,YAAY,OAAO,KAAK;AAe9B,SAAS,wBACP,OACA;CACA,MAAM,CAAC,OAAO,YAAYA,QAAM,SAAS,KAAK;CAE9C,QAAM,gBAAgB;EACpB,SAAS,IAAI;CACf,GAAG,CAAC,CAAC;CAEL,OACE,oBAAC,YAAD;EAAY,UAAU;EAAc,QAAA;YAClC,oBAAC,qCAAqC,UAAtC;GAA+C,OAAO;aACpD,oBAACC,kBAAyB,UAA1B,EAAmC,GAAI,MAAQ,CAAA;EACF,CAAA;CACrC,CAAA;AAEhB;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC0D;CAC7D,OACE,oBAACA,kBAAyB,MAA1B;EACE,aAAU;EACV,WAAW,GACT,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,oBAACA,kBAAyB,UAA1B;EACE,aAAU;EAMV,WAAW,GACT,8eACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,oBAACA,kBAAyB,SAA1B;EACE,aAAU;EACV,WAAW,GAAG,wCAAwC,SAAS;EAC/D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAC3B,WACA,eAAe,OACf,UACA,GAAG,SACwB;CAC3B,MAAM,QAAQD,QAAM,WAAW,oCAAoC;CACnE,MAAM,qBAAqB,iBAAiB;CAC5C,MAAM,eAAe,CAAC,SAAS;CAE/B,OACE,oBAACC,kBAAyB,MAA1B;EACE,GAAI;EACJ,aAAU;EACI;EACd,WAAW,GACT,kFACA,SACF;YAEA,oBAAC,WAAD;GACE,WAAU;GACV,UAAU,mBAAmB,YAAY;GACzC,SAAS,eAAe,QAAQ;GAChC,SAAQ;GACR,MAAM,eAAe,KAAA,IAAY;GAEhC;EACQ,CAAA;CACkB,CAAA;AAEnC;AAMA,SAAS,sBAAsB,EAC7B,YAAY,OACZ,WACA,UACA,QACA,eAAe,WACf,QAAQ,WACR,OAAO,cACP,GAAG,SAEmD;CACtD,OACE,oBAACA,kBAAyB,QAA1B;EACE,aAAU;EACV,kBAAgB;EACL;EACX,WAAW,GACT,ypBACA,SACF;EACA,QACE,UACE,oBAAC,QAAD;GAAsB;GAAqB;GAAa;EAAO,CAAA;EAGnE,GAAI;YAEH,YACC,qBAAA,UAAA,EAAA,UAAA,CACG,cAAc,QAAQ,oBAAC,eAAD,CAAgB,CAAA,IAAI,oBAAC,aAAD,CAAc,CAAA,GACzD,oBAAC,QAAD;GAAM,WAAU;aACb,cAAc,QAAQ,kBAAkB;EACrC,CAAA,CACN,EAAA,CAAA;CAE2B,CAAA;AAErC"}
1
+ {"version":3,"file":"message-scroller.js","names":["React","MessageScrollerPrimitive"],"sources":["../../src/components/message-scroller.tsx"],"sourcesContent":["import { ArrowDownward, ArrowUpward } from '@epilot/spark-icons'\nimport {\n MessageScroller as MessageScrollerPrimitive,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n} from '@shadcn/react/message-scroller'\nimport { LazyMotion, domAnimation } from 'motion/react'\nimport { create } from 'motion/react-m'\nimport * as React from 'react'\nimport { useReducedMotion } from '../hooks/use-reduced-motion'\nimport { MESSAGE_ANIMATIONS } from '../lib/message-animations'\nimport { cn } from '../utils/cn'\nimport { Button, type ButtonProps } from './button'\n\nconst MessageScrollerAnimationReadyContext = React.createContext(false)\nconst MotionDiv = create('div')\n\ntype MessageScrollerItemProps = Omit<\n React.ComponentProps<typeof MessageScrollerPrimitive.Item>,\n | 'animate'\n | 'exit'\n | 'initial'\n | 'variants'\n | 'onAnimationStart'\n | 'onDrag'\n | 'onDragStart'\n | 'onDragEnd'\n | 'onDragTransitionEnd'\n>\n\nfunction MessageScrollerProvider(\n props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\n) {\n const [ready, setReady] = React.useState(false)\n\n React.useEffect(() => {\n setReady(true)\n }, [])\n\n return (\n <LazyMotion features={domAnimation} strict>\n <MessageScrollerAnimationReadyContext.Provider value={ready}>\n <MessageScrollerPrimitive.Provider {...props} />\n </MessageScrollerAnimationReadyContext.Provider>\n </LazyMotion>\n )\n}\n\nfunction MessageScroller({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\n return (\n <MessageScrollerPrimitive.Root\n data-slot=\"message-scroller\"\n className={cn(\n 'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerViewport({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\n return (\n <MessageScrollerPrimitive.Viewport\n data-slot=\"message-scroller-viewport\"\n // The bottom fade follows the primitive's data-scrollable instead of a\n // scroll timeline, which counts the anchor spacer and so faded the last\n // message with nothing below it. Never hide the bar with no-scrollbar\n // here: it drops the stable gutter, so content reflows and can retrigger\n // autoscroll in a loop.\n className={cn(\n 'size-full min-h-0 min-w-0 overflow-y-auto overscroll-contain [mask-image:linear-gradient(to_bottom,#000_calc(100%_-_var(--scroll-fade-b)),transparent)] transition-[--scroll-fade-b] duration-200 contain-content [--scroll-fade-b:0px] [scrollbar-gutter:stable] [scrollbar-width:thin] focus-visible:ring-2 focus-visible:ring-spark-11 focus-visible:ring-offset-2 focus-visible:outline-hidden data-[scrollable~=end]:[--scroll-fade-b:min(12%,calc(var(--spacing)*10))] motion-reduce:transition-none',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerContent({\n className,\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\n return (\n <MessageScrollerPrimitive.Content\n data-slot=\"message-scroller-content\"\n className={cn(\n 'flex h-max min-h-full flex-col gap-[calc(var(--spark-layout-gap)*8)]',\n className,\n )}\n {...props}\n />\n )\n}\n\nfunction MessageScrollerItem({\n className,\n scrollAnchor = false,\n children,\n ...props\n}: MessageScrollerItemProps) {\n const ready = React.useContext(MessageScrollerAnimationReadyContext)\n const shouldReduceMotion = useReducedMotion()\n const skipEntrance = !ready || shouldReduceMotion\n\n return (\n <MessageScrollerPrimitive.Item\n {...props}\n data-slot=\"message-scroller-item\"\n scrollAnchor={scrollAnchor}\n className={cn(\n 'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\n className,\n )}\n >\n <MotionDiv\n className=\"w-full min-w-0\"\n variants={MESSAGE_ANIMATIONS['slide-up'].variants}\n initial={skipEntrance ? false : 'initial'}\n animate=\"animate\"\n exit={skipEntrance ? undefined : 'exit'}\n >\n {children}\n </MotionDiv>\n </MessageScrollerPrimitive.Item>\n )\n}\n\n// Renders a spark <Button> via `render`, so its `styleVariant`/`color`/`size`\n// recipe paints the chrome — we only add positioning + the enter/leave animation\n// keyed off the primitive's data-[active] state. Icon is a Spark icon, pointing\n// down for `end` and up for `start`.\nfunction MessageScrollerButton({\n direction = 'end',\n className,\n children,\n render,\n styleVariant = 'surface',\n color = 'neutral',\n size = 'icon-small',\n ...props\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\n Pick<ButtonProps, 'styleVariant' | 'color' | 'size'>) {\n return (\n <MessageScrollerPrimitive.Button\n data-slot=\"message-scroller-button\"\n data-direction={direction}\n direction={direction}\n className={cn(\n 'absolute inset-s-1/2 -translate-x-1/2 rounded-full transition-[translate,scale,opacity] duration-200 data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full motion-reduce:transition-none rtl:translate-x-1/2',\n className,\n )}\n render={\n render ?? (\n <Button styleVariant={styleVariant} color={color} size={size} />\n )\n }\n {...props}\n >\n {children ?? (\n <>\n {direction === 'end' ? <ArrowDownward /> : <ArrowUpward />}\n <span className=\"sr-only\">\n {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\n </span>\n </>\n )}\n </MessageScrollerPrimitive.Button>\n )\n}\n\nexport {\n MessageScroller,\n MessageScrollerButton,\n MessageScrollerContent,\n MessageScrollerItem,\n MessageScrollerProvider,\n MessageScrollerViewport,\n useMessageScroller,\n useMessageScrollerScrollable,\n useMessageScrollerVisibility,\n}\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,uCAAuCA,QAAM,cAAc,KAAK;AACtE,MAAM,YAAY,OAAO,KAAK;AAe9B,SAAS,wBACP,OACA;CACA,MAAM,CAAC,OAAO,YAAYA,QAAM,SAAS,KAAK;CAE9C,QAAM,gBAAgB;EACpB,SAAS,IAAI;CACf,GAAG,CAAC,CAAC;CAEL,OACE,oBAAC,YAAD;EAAY,UAAU;EAAc,QAAA;YAClC,oBAAC,qCAAqC,UAAtC;GAA+C,OAAO;aACpD,oBAACC,kBAAyB,UAA1B,EAAmC,GAAI,MAAQ,CAAA;EACF,CAAA;CACrC,CAAA;AAEhB;AAEA,SAAS,gBAAgB,EACvB,WACA,GAAG,SAC0D;CAC7D,OACE,oBAACA,kBAAyB,MAA1B;EACE,aAAU;EACV,WAAW,GACT,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,wBAAwB,EAC/B,WACA,GAAG,SAC8D;CACjE,OACE,oBAACA,kBAAyB,UAA1B;EACE,aAAU;EAMV,WAAW,GACT,8eACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,uBAAuB,EAC9B,WACA,GAAG,SAC6D;CAChE,OACE,oBAACA,kBAAyB,SAA1B;EACE,aAAU;EACV,WAAW,GACT,wEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,oBAAoB,EAC3B,WACA,eAAe,OACf,UACA,GAAG,SACwB;CAC3B,MAAM,QAAQD,QAAM,WAAW,oCAAoC;CACnE,MAAM,qBAAqB,iBAAiB;CAC5C,MAAM,eAAe,CAAC,SAAS;CAE/B,OACE,oBAACC,kBAAyB,MAA1B;EACE,GAAI;EACJ,aAAU;EACI;EACd,WAAW,GACT,kFACA,SACF;YAEA,oBAAC,WAAD;GACE,WAAU;GACV,UAAU,mBAAmB,YAAY;GACzC,SAAS,eAAe,QAAQ;GAChC,SAAQ;GACR,MAAM,eAAe,KAAA,IAAY;GAEhC;EACQ,CAAA;CACkB,CAAA;AAEnC;AAMA,SAAS,sBAAsB,EAC7B,YAAY,OACZ,WACA,UACA,QACA,eAAe,WACf,QAAQ,WACR,OAAO,cACP,GAAG,SAEmD;CACtD,OACE,oBAACA,kBAAyB,QAA1B;EACE,aAAU;EACV,kBAAgB;EACL;EACX,WAAW,GACT,ypBACA,SACF;EACA,QACE,UACE,oBAAC,QAAD;GAAsB;GAAqB;GAAa;EAAO,CAAA;EAGnE,GAAI;YAEH,YACC,qBAAA,UAAA,EAAA,UAAA,CACG,cAAc,QAAQ,oBAAC,eAAD,CAAgB,CAAA,IAAI,oBAAC,aAAD,CAAc,CAAA,GACzD,oBAAC,QAAD;GAAM,WAAU;aACb,cAAc,QAAQ,kBAAkB;EACrC,CAAA,CACN,EAAA,CAAA;CAE2B,CAAA;AAErC"}
@@ -6,7 +6,7 @@ import { useRender } from "@base-ui/react/use-render";
6
6
 
7
7
  //#region src/components/page-header.d.ts
8
8
  declare const PageHeader: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLElement> & React$1.RefAttributes<HTMLElement>>;
9
- declare const PageHeaderBackButton: React$1.ForwardRefExoticComponent<Omit<ButtonProps, "color" | "size" | "styleVariant"> & React$1.RefAttributes<HTMLButtonElement>>;
9
+ declare const PageHeaderBackButton: React$1.ForwardRefExoticComponent<Omit<ButtonProps, "size" | "styleVariant" | "color"> & React$1.RefAttributes<HTMLButtonElement>>;
10
10
  declare const PageHeaderTitle: ({
11
11
  className,
12
12
  ...props
@@ -6,7 +6,7 @@ import { useRender } from "@base-ui/react/use-render";
6
6
 
7
7
  //#region src/components/page-header.d.ts
8
8
  declare const PageHeader: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLElement> & React$1.RefAttributes<HTMLElement>>;
9
- declare const PageHeaderBackButton: React$1.ForwardRefExoticComponent<Omit<ButtonProps, "color" | "size" | "styleVariant"> & React$1.RefAttributes<HTMLButtonElement>>;
9
+ declare const PageHeaderBackButton: React$1.ForwardRefExoticComponent<Omit<ButtonProps, "size" | "styleVariant" | "color"> & React$1.RefAttributes<HTMLButtonElement>>;
10
10
  declare const PageHeaderTitle: ({
11
11
  className,
12
12
  ...props
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { f as SparkStyle } from "../theme-types-Bn5E15-P.cjs";
3
+ import { g as SparkStyle } from "../theme-types-CKZzOmSa.cjs";
4
4
  import { SparkAccentColor } from "../lib/accent-colors.cjs";
5
5
  import * as React$1 from "react";
6
6
 
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { f as SparkStyle } from "../theme-types-Bn5E15-P.js";
3
+ import { g as SparkStyle } from "../theme-types-CKZzOmSa.js";
4
4
  import { SparkAccentColor } from "../lib/accent-colors.js";
5
5
  import * as React$1 from "react";
6
6
 
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_chunk = require("../chunk-DY84GLCh.cjs");
4
4
  const require_lib_accent_colors = require("../lib/accent-colors.cjs");
5
+ const require_components_field = require("./field.cjs");
6
+ const require_lib_selection_list = require("../lib/selection-list.cjs");
5
7
  let react = require("react");
6
8
  react = require_chunk.__toESM(react);
7
9
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -9,12 +11,14 @@ let _base_ui_react_radio = require("@base-ui/react/radio");
9
11
  let _base_ui_react_radio_group = require("@base-ui/react/radio-group");
10
12
  let cn = require("cn");
11
13
  //#region src/components/radio.tsx
12
- function RadioGroup({ className, styleVariant, color, gap = 3, style, ...props }) {
14
+ function RadioGroup({ className, styleVariant, color, gap = 3, listStyle, style, ...props }) {
13
15
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_radio_group.RadioGroup, {
14
16
  "data-slot": "radio-group",
15
17
  "data-style": styleVariant !== void 0 || color !== void 0 ? styleVariant ?? "solid" : void 0,
16
18
  "data-accent-color": color ? require_lib_accent_colors.accentByColor[color] : void 0,
17
- className: (0, cn.cn)("grid gap-[calc(var(--spark-layout-gap)*var(--radio-group-gap-steps,3))]", className),
19
+ "data-list-style": listStyle,
20
+ "data-invalid": require_components_field.useFieldSetInvalid(),
21
+ className: (0, cn.cn)("grid", listStyle ? require_lib_selection_list.selectionListClasses[listStyle] : "gap-[calc(var(--spark-layout-gap)*var(--radio-group-gap-steps,3))]", className),
18
22
  style: {
19
23
  "--radio-group-gap-steps": gap,
20
24
  ...style
@@ -1 +1 @@
1
- {"version":3,"file":"radio.cjs","names":["RadioGroupPrimitive","accentByColor","RadioPrimitive"],"sources":["../../src/components/radio.tsx"],"sourcesContent":["import { Radio as RadioPrimitive } from '@base-ui/react/radio'\nimport { RadioGroup as RadioGroupPrimitive } from '@base-ui/react/radio-group'\nimport * as React from 'react'\nimport { accentByColor } from '../lib/accent-colors'\nimport type { SparkStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\n\nexport type SparkRadioColor = 'accent' | 'neutral' | 'danger'\n\ntype RadioGroupProps = Omit<\n React.ComponentProps<typeof RadioGroupPrimitive>,\n 'style'\n> & {\n styleVariant?: SparkStyle\n color?: SparkRadioColor\n /** How many `--spark-layout-gap` units apart each radio sits. */\n gap?: number\n // Base UI's own `style` also accepts a state-callback form; the gap-steps var below\n // needs a plain object to merge into, so narrow it to that here.\n style?: React.CSSProperties\n}\n\nfunction RadioGroup({\n className,\n styleVariant,\n color,\n gap = 3,\n style,\n ...props\n}: RadioGroupProps) {\n const hasLook = styleVariant !== undefined || color !== undefined\n const dataStyle = hasLook ? (styleVariant ?? 'solid') : undefined\n const dataAccentColor = color ? accentByColor[color] : undefined\n\n return (\n <RadioGroupPrimitive\n data-slot=\"radio-group\"\n data-style={dataStyle}\n data-accent-color={dataAccentColor}\n className={cn(\n 'grid gap-[calc(var(--spark-layout-gap)*var(--radio-group-gap-steps,3))]',\n className,\n )}\n style={\n { '--radio-group-gap-steps': gap, ...style } as React.CSSProperties\n }\n {...props}\n />\n )\n}\n\ntype RadioProps = React.ComponentProps<typeof RadioPrimitive.Root> & {\n styleVariant?: SparkStyle\n color?: SparkRadioColor\n}\n\nfunction Radio({\n className,\n styleVariant,\n color,\n render,\n nativeButton,\n ...props\n}: RadioProps) {\n const hasLook = styleVariant !== undefined || color !== undefined\n const dataStyle = hasLook ? (styleVariant ?? 'solid') : undefined\n const dataAccentColor = color ? accentByColor[color] : undefined\n\n return (\n <RadioPrimitive.Root\n data-slot=\"radio\"\n data-style={dataStyle}\n data-accent-color={dataAccentColor}\n // a native button owns the caller's `id`; on Base UI's default <span> the\n // `id` lands on the hidden input and the control gets a generated one\n nativeButton={nativeButton ?? render === undefined}\n render={render ?? <button />}\n className={cn(\n // p-0 defends the 24px box against the UA button padding when the\n // consumer's CSS has no Tailwind preflight\n 'peer touch-target relative my-2 inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 p-0 transition-colors any-pointer-coarse:my-[calc((2.75rem-var(--spacing)*6)/2)]',\n // both overlays are reserved as layout, so neither can bleed into a scroller;\n // the coarse margin tracks --spacing so the 44px reserve holds at any [data-scaling]\n \"before:absolute before:top-1/2 before:left-1/2 before:size-10 before:-translate-x-1/2 before:-translate-y-1/2 before:content-['']\",\n 'focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-50',\n 'border-(--spark-style-idle-border,var(--color-accent-ui)) bg-base-accent-soft data-unchecked:border-(length:--spark-style-border-width,2px)',\n 'data-checked:border-(--spark-radio-ring,var(--spark-9))',\n className,\n )}\n {...props}\n >\n <RadioPrimitive.Indicator\n data-slot=\"radio-indicator\"\n className=\"flex items-center justify-center\"\n >\n <span className=\"size-4 rounded-full bg-(--spark-radio-dot,var(--spark-9)) motion-safe:animate-dot-pop\" />\n </RadioPrimitive.Indicator>\n </RadioPrimitive.Root>\n )\n}\n\nexport { Radio, RadioGroup }\nexport type { RadioGroupProps, RadioProps }\n"],"mappings":";;;;;;;;;;;AAsBA,SAAS,WAAW,EAClB,WACA,cACA,OACA,MAAM,GACN,OACA,GAAG,SACe;CAKlB,OACE,iBAAA,GAAA,kBAAA,KAACA,2BAAAA,YAAD;EACE,aAAU;EACV,cAPY,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAC3B,gBAAgB,UAAW,KAAA;EAOpD,qBANoB,QAAQC,0BAAAA,cAAc,SAAS,KAAA;EAOnD,YAAA,GAAA,GAAA,IACE,2EACA,SACF;EACA,OACE;GAAE,2BAA2B;GAAK,GAAG;EAAM;EAE7C,GAAI;CACL,CAAA;AAEL;AAOA,SAAS,MAAM,EACb,WACA,cACA,OACA,QACA,cACA,GAAG,SACU;CAEb,MAAM,YADU,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAC3B,gBAAgB,UAAW,KAAA;CACxD,MAAM,kBAAkB,QAAQA,0BAAAA,cAAc,SAAS,KAAA;CAEvD,OACE,iBAAA,GAAA,kBAAA,KAACC,qBAAAA,MAAe,MAAhB;EACE,aAAU;EACV,cAAY;EACZ,qBAAmB;EAGnB,cAAc,gBAAgB,WAAW,KAAA;EACzC,QAAQ,UAAU,iBAAA,GAAA,kBAAA,KAAC,UAAD,CAAS,CAAA;EAC3B,YAAA,GAAA,GAAA,IAGE,iNAGA,qIACA,iFACA,6DACA,+IACA,2DACA,SACF;EACA,GAAI;YAEJ,iBAAA,GAAA,kBAAA,KAACA,qBAAAA,MAAe,WAAhB;GACE,aAAU;GACV,WAAU;aAEV,iBAAA,GAAA,kBAAA,KAAC,QAAD,EAAM,WAAU,wFAAyF,CAAA;EACjF,CAAA;CACP,CAAA;AAEzB"}
1
+ {"version":3,"file":"radio.cjs","names":["RadioGroupPrimitive","accentByColor","useFieldSetInvalid","selectionListClasses","RadioPrimitive"],"sources":["../../src/components/radio.tsx"],"sourcesContent":["import { Radio as RadioPrimitive } from '@base-ui/react/radio'\nimport { RadioGroup as RadioGroupPrimitive } from '@base-ui/react/radio-group'\nimport * as React from 'react'\nimport { accentByColor } from '../lib/accent-colors'\nimport { selectionListClasses } from '../lib/selection-list'\nimport type { SparkInputStyle, SparkStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { useFieldSetInvalid } from './field'\n\nexport type SparkRadioColor = 'accent' | 'neutral' | 'danger'\n\ntype RadioGroupProps = Omit<\n React.ComponentProps<typeof RadioGroupPrimitive>,\n 'style'\n> & {\n styleVariant?: SparkStyle\n color?: SparkRadioColor\n /** How many `--spark-layout-gap` units apart each radio sits. */\n gap?: number\n /** Shows the options as a styled list of `SelectionItem` rows; ignores `gap`. */\n listStyle?: SparkInputStyle\n // Base UI's own `style` also accepts a state-callback form; the gap-steps var below\n // needs a plain object to merge into, so narrow it to that here.\n style?: React.CSSProperties\n}\n\nfunction RadioGroup({\n className,\n styleVariant,\n color,\n gap = 3,\n listStyle,\n style,\n ...props\n}: RadioGroupProps) {\n const hasLook = styleVariant !== undefined || color !== undefined\n const dataStyle = hasLook ? (styleVariant ?? 'solid') : undefined\n const dataAccentColor = color ? accentByColor[color] : undefined\n const invalid = useFieldSetInvalid()\n\n return (\n <RadioGroupPrimitive\n data-slot=\"radio-group\"\n data-style={dataStyle}\n data-accent-color={dataAccentColor}\n data-list-style={listStyle}\n data-invalid={invalid}\n className={cn(\n 'grid',\n listStyle\n ? selectionListClasses[listStyle]\n : 'gap-[calc(var(--spark-layout-gap)*var(--radio-group-gap-steps,3))]',\n className,\n )}\n style={\n { '--radio-group-gap-steps': gap, ...style } as React.CSSProperties\n }\n {...props}\n />\n )\n}\n\ntype RadioProps = React.ComponentProps<typeof RadioPrimitive.Root> & {\n styleVariant?: SparkStyle\n color?: SparkRadioColor\n}\n\nfunction Radio({\n className,\n styleVariant,\n color,\n render,\n nativeButton,\n ...props\n}: RadioProps) {\n const hasLook = styleVariant !== undefined || color !== undefined\n const dataStyle = hasLook ? (styleVariant ?? 'solid') : undefined\n const dataAccentColor = color ? accentByColor[color] : undefined\n\n return (\n <RadioPrimitive.Root\n data-slot=\"radio\"\n data-style={dataStyle}\n data-accent-color={dataAccentColor}\n // a native button owns the caller's `id`; on Base UI's default <span> the\n // `id` lands on the hidden input and the control gets a generated one\n nativeButton={nativeButton ?? render === undefined}\n render={render ?? <button />}\n className={cn(\n // p-0 defends the 24px box against the UA button padding when the\n // consumer's CSS has no Tailwind preflight\n 'peer touch-target relative my-2 inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 p-0 transition-colors any-pointer-coarse:my-[calc((2.75rem-var(--spacing)*6)/2)]',\n // both overlays are reserved as layout, so neither can bleed into a scroller;\n // the coarse margin tracks --spacing so the 44px reserve holds at any [data-scaling]\n \"before:absolute before:top-1/2 before:left-1/2 before:size-10 before:-translate-x-1/2 before:-translate-y-1/2 before:content-['']\",\n 'focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-50',\n 'border-(--spark-style-idle-border,var(--color-accent-ui)) bg-base-accent-soft data-unchecked:border-(length:--spark-style-border-width,2px)',\n 'data-checked:border-(--spark-radio-ring,var(--spark-9))',\n className,\n )}\n {...props}\n >\n <RadioPrimitive.Indicator\n data-slot=\"radio-indicator\"\n className=\"flex items-center justify-center\"\n >\n <span className=\"size-4 rounded-full bg-(--spark-radio-dot,var(--spark-9)) motion-safe:animate-dot-pop\" />\n </RadioPrimitive.Indicator>\n </RadioPrimitive.Root>\n )\n}\n\nexport { Radio, RadioGroup }\nexport type { RadioGroupProps, RadioProps }\n"],"mappings":";;;;;;;;;;;;;AA0BA,SAAS,WAAW,EAClB,WACA,cACA,OACA,MAAM,GACN,WACA,OACA,GAAG,SACe;CAMlB,OACE,iBAAA,GAAA,kBAAA,KAACA,2BAAAA,YAAD;EACE,aAAU;EACV,cARY,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAC3B,gBAAgB,UAAW,KAAA;EAQpD,qBAPoB,QAAQC,0BAAAA,cAAc,SAAS,KAAA;EAQnD,mBAAiB;EACjB,gBARYC,yBAAAA,mBAQQ;EACpB,YAAA,GAAA,GAAA,IACE,QACA,YACIC,2BAAAA,qBAAqB,aACrB,sEACJ,SACF;EACA,OACE;GAAE,2BAA2B;GAAK,GAAG;EAAM;EAE7C,GAAI;CACL,CAAA;AAEL;AAOA,SAAS,MAAM,EACb,WACA,cACA,OACA,QACA,cACA,GAAG,SACU;CAEb,MAAM,YADU,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAC3B,gBAAgB,UAAW,KAAA;CACxD,MAAM,kBAAkB,QAAQF,0BAAAA,cAAc,SAAS,KAAA;CAEvD,OACE,iBAAA,GAAA,kBAAA,KAACG,qBAAAA,MAAe,MAAhB;EACE,aAAU;EACV,cAAY;EACZ,qBAAmB;EAGnB,cAAc,gBAAgB,WAAW,KAAA;EACzC,QAAQ,UAAU,iBAAA,GAAA,kBAAA,KAAC,UAAD,CAAS,CAAA;EAC3B,YAAA,GAAA,GAAA,IAGE,iNAGA,qIACA,iFACA,6DACA,+IACA,2DACA,SACF;EACA,GAAI;YAEJ,iBAAA,GAAA,kBAAA,KAACA,qBAAAA,MAAe,WAAhB;GACE,aAAU;GACV,WAAU;aAEV,iBAAA,GAAA,kBAAA,KAAC,QAAD,EAAM,WAAU,wFAAyF,CAAA;EACjF,CAAA;CACP,CAAA;AAEzB"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { f as SparkStyle } from "../theme-types-Bn5E15-P.cjs";
3
+ import { g as SparkStyle, l as SparkInputStyle } from "../theme-types-CKZzOmSa.cjs";
4
4
  import * as React$1 from "react";
5
5
  import { Radio as Radio$1 } from "@base-ui/react/radio";
6
6
  import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
@@ -10,7 +10,8 @@ type SparkRadioColor = 'accent' | 'neutral' | 'danger';
10
10
  type RadioGroupProps = Omit<React$1.ComponentProps<typeof RadioGroup$1>, 'style'> & {
11
11
  styleVariant?: SparkStyle;
12
12
  color?: SparkRadioColor; /** How many `--spark-layout-gap` units apart each radio sits. */
13
- gap?: number;
13
+ gap?: number; /** Shows the options as a styled list of `SelectionItem` rows; ignores `gap`. */
14
+ listStyle?: SparkInputStyle;
14
15
  style?: React$1.CSSProperties;
15
16
  };
16
17
  declare function RadioGroup({
@@ -18,6 +19,7 @@ declare function RadioGroup({
18
19
  styleVariant,
19
20
  color,
20
21
  gap,
22
+ listStyle,
21
23
  style,
22
24
  ...props
23
25
  }: RadioGroupProps): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { f as SparkStyle } from "../theme-types-Bn5E15-P.js";
3
+ import { g as SparkStyle, l as SparkInputStyle } from "../theme-types-CKZzOmSa.js";
4
4
  import * as React$1 from "react";
5
5
  import { Radio as Radio$1 } from "@base-ui/react/radio";
6
6
  import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
@@ -10,7 +10,8 @@ type SparkRadioColor = 'accent' | 'neutral' | 'danger';
10
10
  type RadioGroupProps = Omit<React$1.ComponentProps<typeof RadioGroup$1>, 'style'> & {
11
11
  styleVariant?: SparkStyle;
12
12
  color?: SparkRadioColor; /** How many `--spark-layout-gap` units apart each radio sits. */
13
- gap?: number;
13
+ gap?: number; /** Shows the options as a styled list of `SelectionItem` rows; ignores `gap`. */
14
+ listStyle?: SparkInputStyle;
14
15
  style?: React$1.CSSProperties;
15
16
  };
16
17
  declare function RadioGroup({
@@ -18,6 +19,7 @@ declare function RadioGroup({
18
19
  styleVariant,
19
20
  color,
20
21
  gap,
22
+ listStyle,
21
23
  style,
22
24
  ...props
23
25
  }: RadioGroupProps): import("react/jsx-runtime").JSX.Element;
@@ -1,17 +1,21 @@
1
1
  "use client";
2
2
  import { cn } from "../utils/cn.js";
3
3
  import { accentByColor } from "../lib/accent-colors.js";
4
+ import { useFieldSetInvalid } from "./field.js";
5
+ import { selectionListClasses } from "../lib/selection-list.js";
4
6
  import "react";
5
7
  import { jsx } from "react/jsx-runtime";
6
8
  import { Radio as Radio$1 } from "@base-ui/react/radio";
7
9
  import { RadioGroup as RadioGroup$1 } from "@base-ui/react/radio-group";
8
10
  //#region src/components/radio.tsx
9
- function RadioGroup({ className, styleVariant, color, gap = 3, style, ...props }) {
11
+ function RadioGroup({ className, styleVariant, color, gap = 3, listStyle, style, ...props }) {
10
12
  return /* @__PURE__ */ jsx(RadioGroup$1, {
11
13
  "data-slot": "radio-group",
12
14
  "data-style": styleVariant !== void 0 || color !== void 0 ? styleVariant ?? "solid" : void 0,
13
15
  "data-accent-color": color ? accentByColor[color] : void 0,
14
- className: cn("grid gap-[calc(var(--spark-layout-gap)*var(--radio-group-gap-steps,3))]", className),
16
+ "data-list-style": listStyle,
17
+ "data-invalid": useFieldSetInvalid(),
18
+ className: cn("grid", listStyle ? selectionListClasses[listStyle] : "gap-[calc(var(--spark-layout-gap)*var(--radio-group-gap-steps,3))]", className),
15
19
  style: {
16
20
  "--radio-group-gap-steps": gap,
17
21
  ...style
@@ -1 +1 @@
1
- {"version":3,"file":"radio.js","names":["RadioGroupPrimitive","RadioPrimitive"],"sources":["../../src/components/radio.tsx"],"sourcesContent":["import { Radio as RadioPrimitive } from '@base-ui/react/radio'\nimport { RadioGroup as RadioGroupPrimitive } from '@base-ui/react/radio-group'\nimport * as React from 'react'\nimport { accentByColor } from '../lib/accent-colors'\nimport type { SparkStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\n\nexport type SparkRadioColor = 'accent' | 'neutral' | 'danger'\n\ntype RadioGroupProps = Omit<\n React.ComponentProps<typeof RadioGroupPrimitive>,\n 'style'\n> & {\n styleVariant?: SparkStyle\n color?: SparkRadioColor\n /** How many `--spark-layout-gap` units apart each radio sits. */\n gap?: number\n // Base UI's own `style` also accepts a state-callback form; the gap-steps var below\n // needs a plain object to merge into, so narrow it to that here.\n style?: React.CSSProperties\n}\n\nfunction RadioGroup({\n className,\n styleVariant,\n color,\n gap = 3,\n style,\n ...props\n}: RadioGroupProps) {\n const hasLook = styleVariant !== undefined || color !== undefined\n const dataStyle = hasLook ? (styleVariant ?? 'solid') : undefined\n const dataAccentColor = color ? accentByColor[color] : undefined\n\n return (\n <RadioGroupPrimitive\n data-slot=\"radio-group\"\n data-style={dataStyle}\n data-accent-color={dataAccentColor}\n className={cn(\n 'grid gap-[calc(var(--spark-layout-gap)*var(--radio-group-gap-steps,3))]',\n className,\n )}\n style={\n { '--radio-group-gap-steps': gap, ...style } as React.CSSProperties\n }\n {...props}\n />\n )\n}\n\ntype RadioProps = React.ComponentProps<typeof RadioPrimitive.Root> & {\n styleVariant?: SparkStyle\n color?: SparkRadioColor\n}\n\nfunction Radio({\n className,\n styleVariant,\n color,\n render,\n nativeButton,\n ...props\n}: RadioProps) {\n const hasLook = styleVariant !== undefined || color !== undefined\n const dataStyle = hasLook ? (styleVariant ?? 'solid') : undefined\n const dataAccentColor = color ? accentByColor[color] : undefined\n\n return (\n <RadioPrimitive.Root\n data-slot=\"radio\"\n data-style={dataStyle}\n data-accent-color={dataAccentColor}\n // a native button owns the caller's `id`; on Base UI's default <span> the\n // `id` lands on the hidden input and the control gets a generated one\n nativeButton={nativeButton ?? render === undefined}\n render={render ?? <button />}\n className={cn(\n // p-0 defends the 24px box against the UA button padding when the\n // consumer's CSS has no Tailwind preflight\n 'peer touch-target relative my-2 inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 p-0 transition-colors any-pointer-coarse:my-[calc((2.75rem-var(--spacing)*6)/2)]',\n // both overlays are reserved as layout, so neither can bleed into a scroller;\n // the coarse margin tracks --spacing so the 44px reserve holds at any [data-scaling]\n \"before:absolute before:top-1/2 before:left-1/2 before:size-10 before:-translate-x-1/2 before:-translate-y-1/2 before:content-['']\",\n 'focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-50',\n 'border-(--spark-style-idle-border,var(--color-accent-ui)) bg-base-accent-soft data-unchecked:border-(length:--spark-style-border-width,2px)',\n 'data-checked:border-(--spark-radio-ring,var(--spark-9))',\n className,\n )}\n {...props}\n >\n <RadioPrimitive.Indicator\n data-slot=\"radio-indicator\"\n className=\"flex items-center justify-center\"\n >\n <span className=\"size-4 rounded-full bg-(--spark-radio-dot,var(--spark-9)) motion-safe:animate-dot-pop\" />\n </RadioPrimitive.Indicator>\n </RadioPrimitive.Root>\n )\n}\n\nexport { Radio, RadioGroup }\nexport type { RadioGroupProps, RadioProps }\n"],"mappings":";;;;;;;;AAsBA,SAAS,WAAW,EAClB,WACA,cACA,OACA,MAAM,GACN,OACA,GAAG,SACe;CAKlB,OACE,oBAACA,cAAD;EACE,aAAU;EACV,cAPY,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAC3B,gBAAgB,UAAW,KAAA;EAOpD,qBANoB,QAAQ,cAAc,SAAS,KAAA;EAOnD,WAAW,GACT,2EACA,SACF;EACA,OACE;GAAE,2BAA2B;GAAK,GAAG;EAAM;EAE7C,GAAI;CACL,CAAA;AAEL;AAOA,SAAS,MAAM,EACb,WACA,cACA,OACA,QACA,cACA,GAAG,SACU;CAEb,MAAM,YADU,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAC3B,gBAAgB,UAAW,KAAA;CACxD,MAAM,kBAAkB,QAAQ,cAAc,SAAS,KAAA;CAEvD,OACE,oBAACC,QAAe,MAAhB;EACE,aAAU;EACV,cAAY;EACZ,qBAAmB;EAGnB,cAAc,gBAAgB,WAAW,KAAA;EACzC,QAAQ,UAAU,oBAAC,UAAD,CAAS,CAAA;EAC3B,WAAW,GAGT,iNAGA,qIACA,iFACA,6DACA,+IACA,2DACA,SACF;EACA,GAAI;YAEJ,oBAACA,QAAe,WAAhB;GACE,aAAU;GACV,WAAU;aAEV,oBAAC,QAAD,EAAM,WAAU,wFAAyF,CAAA;EACjF,CAAA;CACP,CAAA;AAEzB"}
1
+ {"version":3,"file":"radio.js","names":["RadioGroupPrimitive","RadioPrimitive"],"sources":["../../src/components/radio.tsx"],"sourcesContent":["import { Radio as RadioPrimitive } from '@base-ui/react/radio'\nimport { RadioGroup as RadioGroupPrimitive } from '@base-ui/react/radio-group'\nimport * as React from 'react'\nimport { accentByColor } from '../lib/accent-colors'\nimport { selectionListClasses } from '../lib/selection-list'\nimport type { SparkInputStyle, SparkStyle } from '../lib/theme-types'\nimport { cn } from '../utils/cn'\nimport { useFieldSetInvalid } from './field'\n\nexport type SparkRadioColor = 'accent' | 'neutral' | 'danger'\n\ntype RadioGroupProps = Omit<\n React.ComponentProps<typeof RadioGroupPrimitive>,\n 'style'\n> & {\n styleVariant?: SparkStyle\n color?: SparkRadioColor\n /** How many `--spark-layout-gap` units apart each radio sits. */\n gap?: number\n /** Shows the options as a styled list of `SelectionItem` rows; ignores `gap`. */\n listStyle?: SparkInputStyle\n // Base UI's own `style` also accepts a state-callback form; the gap-steps var below\n // needs a plain object to merge into, so narrow it to that here.\n style?: React.CSSProperties\n}\n\nfunction RadioGroup({\n className,\n styleVariant,\n color,\n gap = 3,\n listStyle,\n style,\n ...props\n}: RadioGroupProps) {\n const hasLook = styleVariant !== undefined || color !== undefined\n const dataStyle = hasLook ? (styleVariant ?? 'solid') : undefined\n const dataAccentColor = color ? accentByColor[color] : undefined\n const invalid = useFieldSetInvalid()\n\n return (\n <RadioGroupPrimitive\n data-slot=\"radio-group\"\n data-style={dataStyle}\n data-accent-color={dataAccentColor}\n data-list-style={listStyle}\n data-invalid={invalid}\n className={cn(\n 'grid',\n listStyle\n ? selectionListClasses[listStyle]\n : 'gap-[calc(var(--spark-layout-gap)*var(--radio-group-gap-steps,3))]',\n className,\n )}\n style={\n { '--radio-group-gap-steps': gap, ...style } as React.CSSProperties\n }\n {...props}\n />\n )\n}\n\ntype RadioProps = React.ComponentProps<typeof RadioPrimitive.Root> & {\n styleVariant?: SparkStyle\n color?: SparkRadioColor\n}\n\nfunction Radio({\n className,\n styleVariant,\n color,\n render,\n nativeButton,\n ...props\n}: RadioProps) {\n const hasLook = styleVariant !== undefined || color !== undefined\n const dataStyle = hasLook ? (styleVariant ?? 'solid') : undefined\n const dataAccentColor = color ? accentByColor[color] : undefined\n\n return (\n <RadioPrimitive.Root\n data-slot=\"radio\"\n data-style={dataStyle}\n data-accent-color={dataAccentColor}\n // a native button owns the caller's `id`; on Base UI's default <span> the\n // `id` lands on the hidden input and the control gets a generated one\n nativeButton={nativeButton ?? render === undefined}\n render={render ?? <button />}\n className={cn(\n // p-0 defends the 24px box against the UA button padding when the\n // consumer's CSS has no Tailwind preflight\n 'peer touch-target relative my-2 inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 p-0 transition-colors any-pointer-coarse:my-[calc((2.75rem-var(--spacing)*6)/2)]',\n // both overlays are reserved as layout, so neither can bleed into a scroller;\n // the coarse margin tracks --spacing so the 44px reserve holds at any [data-scaling]\n \"before:absolute before:top-1/2 before:left-1/2 before:size-10 before:-translate-x-1/2 before:-translate-y-1/2 before:content-['']\",\n 'focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-50',\n 'border-(--spark-style-idle-border,var(--color-accent-ui)) bg-base-accent-soft data-unchecked:border-(length:--spark-style-border-width,2px)',\n 'data-checked:border-(--spark-radio-ring,var(--spark-9))',\n className,\n )}\n {...props}\n >\n <RadioPrimitive.Indicator\n data-slot=\"radio-indicator\"\n className=\"flex items-center justify-center\"\n >\n <span className=\"size-4 rounded-full bg-(--spark-radio-dot,var(--spark-9)) motion-safe:animate-dot-pop\" />\n </RadioPrimitive.Indicator>\n </RadioPrimitive.Root>\n )\n}\n\nexport { Radio, RadioGroup }\nexport type { RadioGroupProps, RadioProps }\n"],"mappings":";;;;;;;;;;AA0BA,SAAS,WAAW,EAClB,WACA,cACA,OACA,MAAM,GACN,WACA,OACA,GAAG,SACe;CAMlB,OACE,oBAACA,cAAD;EACE,aAAU;EACV,cARY,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAC3B,gBAAgB,UAAW,KAAA;EAQpD,qBAPoB,QAAQ,cAAc,SAAS,KAAA;EAQnD,mBAAiB;EACjB,gBARY,mBAQQ;EACpB,WAAW,GACT,QACA,YACI,qBAAqB,aACrB,sEACJ,SACF;EACA,OACE;GAAE,2BAA2B;GAAK,GAAG;EAAM;EAE7C,GAAI;CACL,CAAA;AAEL;AAOA,SAAS,MAAM,EACb,WACA,cACA,OACA,QACA,cACA,GAAG,SACU;CAEb,MAAM,YADU,iBAAiB,KAAA,KAAa,UAAU,KAAA,IAC3B,gBAAgB,UAAW,KAAA;CACxD,MAAM,kBAAkB,QAAQ,cAAc,SAAS,KAAA;CAEvD,OACE,oBAACC,QAAe,MAAhB;EACE,aAAU;EACV,cAAY;EACZ,qBAAmB;EAGnB,cAAc,gBAAgB,WAAW,KAAA;EACzC,QAAQ,UAAU,oBAAC,UAAD,CAAS,CAAA;EAC3B,WAAW,GAGT,iNAGA,qIACA,iFACA,6DACA,+IACA,2DACA,SACF;EACA,GAAI;YAEJ,oBAACA,QAAe,WAAhB;GACE,aAAU;GACV,WAAU;aAEV,oBAAC,QAAD,EAAM,WAAU,wFAAyF,CAAA;EACjF,CAAA;CACP,CAAA;AAEzB"}
@@ -0,0 +1,167 @@
1
+ "use client";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require_chunk = require("../chunk-DY84GLCh.cjs");
4
+ const require_components_field = require("./field.cjs");
5
+ let react = require("react");
6
+ react = require_chunk.__toESM(react);
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
+ let _base_ui_react_radio = require("@base-ui/react/radio");
9
+ let _base_ui_react_radio_group = require("@base-ui/react/radio-group");
10
+ let cn = require("cn");
11
+ //#region src/components/rating.tsx
12
+ const RatingContext = react.createContext(null);
13
+ function useRating() {
14
+ const context = react.useContext(RatingContext);
15
+ if (!context) throw new Error("RatingStars and RatingCaption need a Rating");
16
+ return context;
17
+ }
18
+ function Rating({ value: valueProp, defaultValue = null, onValueChange, max = 5, labels, size = "medium", readOnly = false, disabled = false, name, className, children, ...props }) {
19
+ const [uncontrolled, setUncontrolled] = react.useState(defaultValue);
20
+ const [hovered, setHovered] = react.useState(null);
21
+ const value = valueProp === void 0 ? uncontrolled : valueProp;
22
+ const setValue = react.useCallback((next) => {
23
+ setUncontrolled(next);
24
+ onValueChange?.(next);
25
+ }, [onValueChange]);
26
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RatingContext.Provider, {
27
+ value: {
28
+ value,
29
+ setValue,
30
+ hovered: readOnly || disabled ? null : hovered,
31
+ setHovered,
32
+ max,
33
+ labels,
34
+ size,
35
+ readOnly,
36
+ disabled,
37
+ name
38
+ },
39
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40
+ "data-slot": "rating",
41
+ className: (0, cn.cn)("flex flex-col items-start gap-[calc(var(--spark-layout-gap)*1)]", className),
42
+ ...props,
43
+ children
44
+ })
45
+ });
46
+ }
47
+ const sizeClasses = {
48
+ small: {
49
+ star: "size-4",
50
+ button: "size-6"
51
+ },
52
+ medium: {
53
+ star: "size-6",
54
+ button: "size-8"
55
+ },
56
+ large: {
57
+ star: "size-8",
58
+ button: "size-11"
59
+ }
60
+ };
61
+ const compactSizeClasses = {
62
+ small: {
63
+ star: "size-3.5",
64
+ button: "size-6"
65
+ },
66
+ medium: {
67
+ star: "size-4.5",
68
+ button: "size-6"
69
+ },
70
+ large: {
71
+ star: "size-5",
72
+ button: "size-6"
73
+ }
74
+ };
75
+ function starTone(fill, disabled) {
76
+ if (disabled) return fill === "off" ? "fill-none stroke-gray-a6" : "fill-gray-a7 stroke-gray-a7";
77
+ if (fill === "on") return "fill-spark-9 stroke-spark-9";
78
+ if (fill === "preview") return "fill-spark-a4 stroke-spark-9";
79
+ return "fill-none stroke-gray-a9";
80
+ }
81
+ function captionTone(hasLabel, hovered, disabled) {
82
+ if (disabled) return "text-gray-a9";
83
+ if (!hasLabel) return "text-gray-11";
84
+ return hovered ? "text-spark-11" : "text-gray-12";
85
+ }
86
+ function Star({ className }) {
87
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
88
+ xmlns: "http://www.w3.org/2000/svg",
89
+ viewBox: "0 0 24 24",
90
+ strokeWidth: 1.5,
91
+ strokeLinejoin: "round",
92
+ "aria-hidden": "true",
93
+ className: (0, cn.cn)("transition-colors motion-reduce:transition-none", className),
94
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M12.60 3.17 L14.72 8.03 Q15.00 8.67 15.69 8.74 L20.97 9.26 Q22.46 9.40 21.34 10.40 L17.37 13.91 Q16.85 14.38 17.00 15.06 L18.14 20.23 Q18.47 21.70 17.17 20.94 L12.60 18.25 Q12.00 17.90 11.40 18.25 L6.83 20.94 Q5.53 21.70 5.86 20.23 L7.00 15.06 Q7.15 14.38 6.63 13.91 L2.66 10.40 Q1.54 9.40 3.03 9.26 L8.31 8.74 Q9.00 8.67 9.28 8.03 L11.40 3.17 Q12.00 1.80 12.60 3.17Z" })
95
+ });
96
+ }
97
+ function RatingStars({ className, onPointerLeave, onKeyDown, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedByProp, ...props }) {
98
+ const rating = useRating();
99
+ const { field, ariaDescribedBy, ariaInvalid } = require_components_field.useFieldControl({ ariaDescribedBy: ariaDescribedByProp });
100
+ const invalid = require_components_field.useFieldSetInvalid();
101
+ const { star: starSize, button: buttonSize } = (rating.max > 5 ? compactSizeClasses : sizeClasses)[rating.size];
102
+ const interactive = !rating.readOnly && !rating.disabled;
103
+ const low = Math.min(rating.value ?? 0, rating.hovered ?? rating.value ?? 0);
104
+ const high = Math.max(rating.value ?? 0, rating.hovered ?? 0);
105
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_radio_group.RadioGroup, {
106
+ "data-slot": "rating-stars",
107
+ "data-invalid": invalid,
108
+ "aria-labelledby": ariaLabelledBy ?? (field?.readOnly ? field.labelId : void 0),
109
+ "aria-describedby": ariaDescribedBy,
110
+ "aria-invalid": ariaInvalid,
111
+ value: rating.value,
112
+ onValueChange: (next) => next !== null && rating.setValue(next),
113
+ readOnly: rating.readOnly,
114
+ disabled: rating.disabled,
115
+ name: rating.name,
116
+ className: (0, cn.cn)("flex", className),
117
+ onPointerLeave: (event) => {
118
+ rating.setHovered(null);
119
+ onPointerLeave?.(event);
120
+ },
121
+ onKeyDown: (event) => {
122
+ rating.setHovered(null);
123
+ onKeyDown?.(event);
124
+ },
125
+ ...props,
126
+ children: Array.from({ length: rating.max }, (_, index) => {
127
+ const star = index + 1;
128
+ const fill = star <= low ? "on" : star <= high ? "preview" : "off";
129
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_base_ui_react_radio.Radio.Root, {
130
+ value: star,
131
+ "aria-label": rating.labels?.[index] ?? String(star),
132
+ "data-slot": "rating-star",
133
+ "data-fill": fill,
134
+ "aria-readonly": void 0,
135
+ nativeButton: true,
136
+ render: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {}),
137
+ onPointerEnter: interactive ? () => rating.setHovered(star) : void 0,
138
+ className: (0, cn.cn)("inline-flex min-h-[24px] min-w-[24px] shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0 touch-target-row any-pointer-coarse:min-w-11", "focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden", "data-disabled:cursor-not-allowed data-readonly:cursor-default", buttonSize),
139
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Star, { className: (0, cn.cn)(starSize, starTone(fill, rating.disabled)) })
140
+ }, star);
141
+ })
142
+ });
143
+ }
144
+ const captionTextSize = {
145
+ small: "text-[0.8125rem]",
146
+ medium: "text-sm",
147
+ large: "text-base"
148
+ };
149
+ function RatingCaption({ className, children, ...props }) {
150
+ const rating = useRating();
151
+ const shown = rating.hovered ?? rating.value;
152
+ const label = shown ? rating.labels?.[shown - 1] : void 0;
153
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
154
+ "data-slot": "rating-caption",
155
+ "aria-hidden": "true",
156
+ "aria-disabled": rating.disabled || void 0,
157
+ className: (0, cn.cn)("leading-5", captionTextSize[rating.size], label !== void 0 && "font-medium", captionTone(label !== void 0, !!rating.hovered, rating.disabled), className),
158
+ ...props,
159
+ children: label ?? children
160
+ });
161
+ }
162
+ //#endregion
163
+ exports.Rating = Rating;
164
+ exports.RatingCaption = RatingCaption;
165
+ exports.RatingStars = RatingStars;
166
+
167
+ //# sourceMappingURL=rating.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rating.cjs","names":["React","useFieldControl","useFieldSetInvalid","RadioGroupPrimitive","RadioPrimitive"],"sources":["../../src/components/rating.tsx"],"sourcesContent":["import { Radio as RadioPrimitive } from '@base-ui/react/radio'\nimport { RadioGroup as RadioGroupPrimitive } from '@base-ui/react/radio-group'\nimport * as React from 'react'\nimport { cn } from '../utils/cn'\nimport { useFieldControl, useFieldSetInvalid } from './field'\n\ntype RatingSize = 'small' | 'medium' | 'large'\n\ntype RatingContextValue = {\n value: number | null\n setValue: (value: number) => void\n hovered: number | null\n setHovered: (value: number | null) => void\n max: number\n labels?: string[]\n size: RatingSize\n readOnly: boolean\n disabled: boolean\n name?: string\n}\n\nconst RatingContext = React.createContext<RatingContextValue | null>(null)\n\nfunction useRating() {\n const context = React.useContext(RatingContext)\n if (!context) throw new Error('RatingStars and RatingCaption need a Rating')\n return context\n}\n\ninterface RatingProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'defaultValue' | 'onChange'\n> {\n /** The chosen star, 1-based. `null` means nothing is chosen yet. */\n value?: number | null\n defaultValue?: number | null\n onValueChange?: (value: number) => void\n max?: number\n /** One label per star: the star's accessible name and the caption text. */\n labels?: string[]\n size?: RatingSize\n readOnly?: boolean\n disabled?: boolean\n name?: string\n}\n\nfunction Rating({\n value: valueProp,\n defaultValue = null,\n onValueChange,\n max = 5,\n labels,\n size = 'medium',\n readOnly = false,\n disabled = false,\n name,\n className,\n children,\n ...props\n}: RatingProps) {\n const [uncontrolled, setUncontrolled] = React.useState(defaultValue)\n const [hovered, setHovered] = React.useState<number | null>(null)\n const value = valueProp === undefined ? uncontrolled : valueProp\n\n const setValue = React.useCallback(\n (next: number) => {\n setUncontrolled(next)\n onValueChange?.(next)\n },\n [onValueChange],\n )\n\n return (\n <RatingContext.Provider\n value={{\n value,\n setValue,\n hovered: readOnly || disabled ? null : hovered,\n setHovered,\n max,\n labels,\n size,\n readOnly,\n disabled,\n name,\n }}\n >\n <div\n data-slot=\"rating\"\n className={cn(\n 'flex flex-col items-start gap-[calc(var(--spark-layout-gap)*1)]',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </RatingContext.Provider>\n )\n}\n\ntype SizeClasses = { star: string; button: string }\n\nconst sizeClasses: Record<RatingSize, SizeClasses> = {\n small: { star: 'size-4', button: 'size-6' },\n medium: { star: 'size-6', button: 'size-8' },\n large: { star: 'size-8', button: 'size-11' },\n}\n\n// above five stars the row would outgrow narrow panels\nconst compactSizeClasses: Record<RatingSize, SizeClasses> = {\n small: { star: 'size-3.5', button: 'size-6' },\n medium: { star: 'size-4.5', button: 'size-6' },\n large: { star: 'size-5', button: 'size-6' },\n}\n\ntype StarFill = 'on' | 'preview' | 'off'\n\nfunction starTone(fill: StarFill, disabled: boolean) {\n if (disabled) {\n return fill === 'off'\n ? 'fill-none stroke-gray-a6'\n : 'fill-gray-a7 stroke-gray-a7'\n }\n if (fill === 'on') return 'fill-spark-9 stroke-spark-9'\n if (fill === 'preview') return 'fill-spark-a4 stroke-spark-9'\n return 'fill-none stroke-gray-a9'\n}\n\nfunction captionTone(hasLabel: boolean, hovered: boolean, disabled: boolean) {\n if (disabled) return 'text-gray-a9'\n if (!hasLabel) return 'text-gray-11'\n return hovered ? 'text-spark-11' : 'text-gray-12'\n}\n\nfunction Star({ className }: { className: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n className={cn(\n 'transition-colors motion-reduce:transition-none',\n className,\n )}\n >\n <path d=\"M12.60 3.17 L14.72 8.03 Q15.00 8.67 15.69 8.74 L20.97 9.26 Q22.46 9.40 21.34 10.40 L17.37 13.91 Q16.85 14.38 17.00 15.06 L18.14 20.23 Q18.47 21.70 17.17 20.94 L12.60 18.25 Q12.00 17.90 11.40 18.25 L6.83 20.94 Q5.53 21.70 5.86 20.23 L7.00 15.06 Q7.15 14.38 6.63 13.91 L2.66 10.40 Q1.54 9.40 3.03 9.26 L8.31 8.74 Q9.00 8.67 9.28 8.03 L11.40 3.17 Q12.00 1.80 12.60 3.17Z\" />\n </svg>\n )\n}\n\ntype RatingStarsProps = Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'defaultValue' | 'onChange'\n>\n\nfunction RatingStars({\n className,\n onPointerLeave,\n onKeyDown,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedByProp,\n ...props\n}: RatingStarsProps) {\n const rating = useRating()\n const { field, ariaDescribedBy, ariaInvalid } = useFieldControl({\n ariaDescribedBy: ariaDescribedByProp,\n })\n const invalid = useFieldSetInvalid()\n const { star: starSize, button: buttonSize } = (\n rating.max > 5 ? compactSizeClasses : sizeClasses\n )[rating.size]\n const interactive = !rating.readOnly && !rating.disabled\n const low = Math.min(rating.value ?? 0, rating.hovered ?? rating.value ?? 0)\n const high = Math.max(rating.value ?? 0, rating.hovered ?? 0)\n\n return (\n <RadioGroupPrimitive<number | null>\n data-slot=\"rating-stars\"\n data-invalid={invalid}\n // a read-only FieldLabel renders the Field's labelId and drops a caller id\n aria-labelledby={\n ariaLabelledBy ?? (field?.readOnly ? field.labelId : undefined)\n }\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n value={rating.value}\n onValueChange={(next) => next !== null && rating.setValue(next)}\n readOnly={rating.readOnly}\n disabled={rating.disabled}\n name={rating.name}\n className={cn('flex', className)}\n onPointerLeave={(event) => {\n rating.setHovered(null)\n onPointerLeave?.(event)\n }}\n onKeyDown={(event) => {\n rating.setHovered(null)\n onKeyDown?.(event)\n }}\n {...props}\n >\n {Array.from({ length: rating.max }, (_, index) => {\n const star = index + 1\n const fill: StarFill =\n star <= low ? 'on' : star <= high ? 'preview' : 'off'\n return (\n <RadioPrimitive.Root\n key={star}\n value={star}\n aria-label={rating.labels?.[index] ?? String(star)}\n data-slot=\"rating-star\"\n data-fill={fill}\n // ARIA allows aria-readonly on the radiogroup, which Base UI also sets, not on a radio\n aria-readonly={undefined}\n nativeButton\n render={<button />}\n onPointerEnter={\n interactive ? () => rating.setHovered(star) : undefined\n }\n className={cn(\n // p-0 keeps the box against the UA button padding without preflight;\n // the px floor keeps axe's 24px target size when [data-scaling] shrinks rems\n 'inline-flex min-h-[24px] min-w-[24px] shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0 touch-target-row any-pointer-coarse:min-w-11',\n 'focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',\n 'data-disabled:cursor-not-allowed data-readonly:cursor-default',\n buttonSize,\n )}\n >\n <Star className={cn(starSize, starTone(fill, rating.disabled))} />\n </RadioPrimitive.Root>\n )\n })}\n </RadioGroupPrimitive>\n )\n}\n\nconst captionTextSize: Record<RatingSize, string> = {\n small: 'text-[0.8125rem]',\n medium: 'text-sm',\n large: 'text-base',\n}\n\nfunction RatingCaption({\n className,\n children,\n ...props\n}: React.HTMLAttributes<HTMLParagraphElement>) {\n const rating = useRating()\n const shown = rating.hovered ?? rating.value\n const label = shown ? rating.labels?.[shown - 1] : undefined\n\n return (\n <p\n data-slot=\"rating-caption\"\n // the stars already carry each label as their accessible name\n aria-hidden=\"true\"\n // axe skips contrast on inactive text, and the dim tone is the disabled cue\n aria-disabled={rating.disabled || undefined}\n className={cn(\n 'leading-5',\n captionTextSize[rating.size],\n label !== undefined && 'font-medium',\n captionTone(label !== undefined, !!rating.hovered, rating.disabled),\n className,\n )}\n {...props}\n >\n {label ?? children}\n </p>\n )\n}\n\nexport { Rating, RatingCaption, RatingStars }\nexport type { RatingProps, RatingStarsProps }\n"],"mappings":";;;;;;;;;;;AAqBA,MAAM,gBAAgBA,MAAM,cAAyC,IAAI;AAEzE,SAAS,YAAY;CACnB,MAAM,UAAUA,MAAM,WAAW,aAAa;CAC9C,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,6CAA6C;CAC3E,OAAO;AACT;AAmBA,SAAS,OAAO,EACd,OAAO,WACP,eAAe,MACf,eACA,MAAM,GACN,QACA,OAAO,UACP,WAAW,OACX,WAAW,OACX,MACA,WACA,UACA,GAAG,SACW;CACd,MAAM,CAAC,cAAc,mBAAmBA,MAAM,SAAS,YAAY;CACnE,MAAM,CAAC,SAAS,cAAcA,MAAM,SAAwB,IAAI;CAChE,MAAM,QAAQ,cAAc,KAAA,IAAY,eAAe;CAEvD,MAAM,WAAWA,MAAM,aACpB,SAAiB;EAChB,gBAAgB,IAAI;EACpB,gBAAgB,IAAI;CACtB,GACA,CAAC,aAAa,CAChB;CAEA,OACE,iBAAA,GAAA,kBAAA,KAAC,cAAc,UAAf;EACE,OAAO;GACL;GACA;GACA,SAAS,YAAY,WAAW,OAAO;GACvC;GACA;GACA;GACA;GACA;GACA;GACA;EACF;YAEA,iBAAA,GAAA,kBAAA,KAAC,OAAD;GACE,aAAU;GACV,YAAA,GAAA,GAAA,IACE,mEACA,SACF;GACA,GAAI;GAEH;EACE,CAAA;CACiB,CAAA;AAE5B;AAIA,MAAM,cAA+C;CACnD,OAAO;EAAE,MAAM;EAAU,QAAQ;CAAS;CAC1C,QAAQ;EAAE,MAAM;EAAU,QAAQ;CAAS;CAC3C,OAAO;EAAE,MAAM;EAAU,QAAQ;CAAU;AAC7C;AAGA,MAAM,qBAAsD;CAC1D,OAAO;EAAE,MAAM;EAAY,QAAQ;CAAS;CAC5C,QAAQ;EAAE,MAAM;EAAY,QAAQ;CAAS;CAC7C,OAAO;EAAE,MAAM;EAAU,QAAQ;CAAS;AAC5C;AAIA,SAAS,SAAS,MAAgB,UAAmB;CACnD,IAAI,UACF,OAAO,SAAS,QACZ,6BACA;CAEN,IAAI,SAAS,MAAM,OAAO;CAC1B,IAAI,SAAS,WAAW,OAAO;CAC/B,OAAO;AACT;AAEA,SAAS,YAAY,UAAmB,SAAkB,UAAmB;CAC3E,IAAI,UAAU,OAAO;CACrB,IAAI,CAAC,UAAU,OAAO;CACtB,OAAO,UAAU,kBAAkB;AACrC;AAEA,SAAS,KAAK,EAAE,aAAoC;CAClD,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,OAAM;EACN,SAAQ;EACR,aAAa;EACb,gBAAe;EACf,eAAY;EACZ,YAAA,GAAA,GAAA,IACE,mDACA,SACF;YAEA,iBAAA,GAAA,kBAAA,KAAC,QAAD,EAAM,GAAE,kXAAmX,CAAA;CACxX,CAAA;AAET;AAOA,SAAS,YAAY,EACnB,WACA,gBACA,WACA,mBAAmB,gBACnB,oBAAoB,qBACpB,GAAG,SACgB;CACnB,MAAM,SAAS,UAAU;CACzB,MAAM,EAAE,OAAO,iBAAiB,gBAAgBC,yBAAAA,gBAAgB,EAC9D,iBAAiB,oBACnB,CAAC;CACD,MAAM,UAAUC,yBAAAA,mBAAmB;CACnC,MAAM,EAAE,MAAM,UAAU,QAAQ,gBAC9B,OAAO,MAAM,IAAI,qBAAqB,aACtC,OAAO;CACT,MAAM,cAAc,CAAC,OAAO,YAAY,CAAC,OAAO;CAChD,MAAM,MAAM,KAAK,IAAI,OAAO,SAAS,GAAG,OAAO,WAAW,OAAO,SAAS,CAAC;CAC3E,MAAM,OAAO,KAAK,IAAI,OAAO,SAAS,GAAG,OAAO,WAAW,CAAC;CAE5D,OACE,iBAAA,GAAA,kBAAA,KAACC,2BAAAA,YAAD;EACE,aAAU;EACV,gBAAc;EAEd,mBACE,mBAAmB,OAAO,WAAW,MAAM,UAAU,KAAA;EAEvD,oBAAkB;EAClB,gBAAc;EACd,OAAO,OAAO;EACd,gBAAgB,SAAS,SAAS,QAAQ,OAAO,SAAS,IAAI;EAC9D,UAAU,OAAO;EACjB,UAAU,OAAO;EACjB,MAAM,OAAO;EACb,YAAA,GAAA,GAAA,IAAc,QAAQ,SAAS;EAC/B,iBAAiB,UAAU;GACzB,OAAO,WAAW,IAAI;GACtB,iBAAiB,KAAK;EACxB;EACA,YAAY,UAAU;GACpB,OAAO,WAAW,IAAI;GACtB,YAAY,KAAK;EACnB;EACA,GAAI;YAEH,MAAM,KAAK,EAAE,QAAQ,OAAO,IAAI,IAAI,GAAG,UAAU;GAChD,MAAM,OAAO,QAAQ;GACrB,MAAM,OACJ,QAAQ,MAAM,OAAO,QAAQ,OAAO,YAAY;GAClD,OACE,iBAAA,GAAA,kBAAA,KAACC,qBAAAA,MAAe,MAAhB;IAEE,OAAO;IACP,cAAY,OAAO,SAAS,UAAU,OAAO,IAAI;IACjD,aAAU;IACV,aAAW;IAEX,iBAAe,KAAA;IACf,cAAA;IACA,QAAQ,iBAAA,GAAA,kBAAA,KAAC,UAAD,CAAS,CAAA;IACjB,gBACE,oBAAoB,OAAO,WAAW,IAAI,IAAI,KAAA;IAEhD,YAAA,GAAA,GAAA,IAGE,iLACA,iFACA,iEACA,UACF;cAEA,iBAAA,GAAA,kBAAA,KAAC,MAAD,EAAM,YAAA,GAAA,GAAA,IAAc,UAAU,SAAS,MAAM,OAAO,QAAQ,CAAC,EAAI,CAAA;GAC9C,GAtBd,IAsBc;EAEzB,CAAC;CACkB,CAAA;AAEzB;AAEA,MAAM,kBAA8C;CAClD,OAAO;CACP,QAAQ;CACR,OAAO;AACT;AAEA,SAAS,cAAc,EACrB,WACA,UACA,GAAG,SAC0C;CAC7C,MAAM,SAAS,UAAU;CACzB,MAAM,QAAQ,OAAO,WAAW,OAAO;CACvC,MAAM,QAAQ,QAAQ,OAAO,SAAS,QAAQ,KAAK,KAAA;CAEnD,OACE,iBAAA,GAAA,kBAAA,KAAC,KAAD;EACE,aAAU;EAEV,eAAY;EAEZ,iBAAe,OAAO,YAAY,KAAA;EAClC,YAAA,GAAA,GAAA,IACE,aACA,gBAAgB,OAAO,OACvB,UAAU,KAAA,KAAa,eACvB,YAAY,UAAU,KAAA,GAAW,CAAC,CAAC,OAAO,SAAS,OAAO,QAAQ,GAClE,SACF;EACA,GAAI;YAEH,SAAS;CACT,CAAA;AAEP"}
@@ -0,0 +1,50 @@
1
+ "use client";
2
+
3
+ import * as React$1 from "react";
4
+
5
+ //#region src/components/rating.d.ts
6
+ type RatingSize = 'small' | 'medium' | 'large';
7
+ interface RatingProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'> {
8
+ /** The chosen star, 1-based. `null` means nothing is chosen yet. */
9
+ value?: number | null;
10
+ defaultValue?: number | null;
11
+ onValueChange?: (value: number) => void;
12
+ max?: number;
13
+ /** One label per star: the star's accessible name and the caption text. */
14
+ labels?: string[];
15
+ size?: RatingSize;
16
+ readOnly?: boolean;
17
+ disabled?: boolean;
18
+ name?: string;
19
+ }
20
+ declare function Rating({
21
+ value: valueProp,
22
+ defaultValue,
23
+ onValueChange,
24
+ max,
25
+ labels,
26
+ size,
27
+ readOnly,
28
+ disabled,
29
+ name,
30
+ className,
31
+ children,
32
+ ...props
33
+ }: RatingProps): import("react/jsx-runtime").JSX.Element;
34
+ type RatingStarsProps = Omit<React$1.HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'>;
35
+ declare function RatingStars({
36
+ className,
37
+ onPointerLeave,
38
+ onKeyDown,
39
+ 'aria-labelledby': ariaLabelledBy,
40
+ 'aria-describedby': ariaDescribedByProp,
41
+ ...props
42
+ }: RatingStarsProps): import("react/jsx-runtime").JSX.Element;
43
+ declare function RatingCaption({
44
+ className,
45
+ children,
46
+ ...props
47
+ }: React$1.HTMLAttributes<HTMLParagraphElement>): import("react/jsx-runtime").JSX.Element;
48
+ //#endregion
49
+ export { Rating, RatingCaption, type RatingProps, RatingStars, type RatingStarsProps };
50
+ //# sourceMappingURL=rating.d.cts.map
@@ -0,0 +1,50 @@
1
+ "use client";
2
+
3
+ import * as React$1 from "react";
4
+
5
+ //#region src/components/rating.d.ts
6
+ type RatingSize = 'small' | 'medium' | 'large';
7
+ interface RatingProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'> {
8
+ /** The chosen star, 1-based. `null` means nothing is chosen yet. */
9
+ value?: number | null;
10
+ defaultValue?: number | null;
11
+ onValueChange?: (value: number) => void;
12
+ max?: number;
13
+ /** One label per star: the star's accessible name and the caption text. */
14
+ labels?: string[];
15
+ size?: RatingSize;
16
+ readOnly?: boolean;
17
+ disabled?: boolean;
18
+ name?: string;
19
+ }
20
+ declare function Rating({
21
+ value: valueProp,
22
+ defaultValue,
23
+ onValueChange,
24
+ max,
25
+ labels,
26
+ size,
27
+ readOnly,
28
+ disabled,
29
+ name,
30
+ className,
31
+ children,
32
+ ...props
33
+ }: RatingProps): import("react/jsx-runtime").JSX.Element;
34
+ type RatingStarsProps = Omit<React$1.HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'>;
35
+ declare function RatingStars({
36
+ className,
37
+ onPointerLeave,
38
+ onKeyDown,
39
+ 'aria-labelledby': ariaLabelledBy,
40
+ 'aria-describedby': ariaDescribedByProp,
41
+ ...props
42
+ }: RatingStarsProps): import("react/jsx-runtime").JSX.Element;
43
+ declare function RatingCaption({
44
+ className,
45
+ children,
46
+ ...props
47
+ }: React$1.HTMLAttributes<HTMLParagraphElement>): import("react/jsx-runtime").JSX.Element;
48
+ //#endregion
49
+ export { Rating, RatingCaption, type RatingProps, RatingStars, type RatingStarsProps };
50
+ //# sourceMappingURL=rating.d.ts.map