@funstack/ui 0.1.0-alpha.1 → 0.1.0-alpha.3

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 (288) hide show
  1. package/dist/accordion/accordion-context.mjs.map +1 -1
  2. package/dist/accordion/accordion-item.mjs +18 -4
  3. package/dist/accordion/accordion-item.mjs.map +1 -1
  4. package/dist/accordion/accordion-panel.mjs +2 -3
  5. package/dist/accordion/accordion-panel.mjs.map +1 -1
  6. package/dist/accordion/accordion-root.d.mts.map +1 -1
  7. package/dist/accordion/accordion-root.mjs +32 -14
  8. package/dist/accordion/accordion-root.mjs.map +1 -1
  9. package/dist/accordion/accordion-trigger.mjs +4 -5
  10. package/dist/accordion/accordion-trigger.mjs.map +1 -1
  11. package/dist/checkbox/checkbox.d.mts +5 -3
  12. package/dist/checkbox/checkbox.d.mts.map +1 -1
  13. package/dist/checkbox/checkbox.mjs +25 -9
  14. package/dist/checkbox/checkbox.mjs.map +1 -1
  15. package/dist/checkbox-group/checkbox-group-context.mjs.map +1 -1
  16. package/dist/checkbox-group/checkbox-group-item.d.mts +2 -1
  17. package/dist/checkbox-group/checkbox-group-item.d.mts.map +1 -1
  18. package/dist/checkbox-group/checkbox-group-item.mjs +3 -1
  19. package/dist/checkbox-group/checkbox-group-item.mjs.map +1 -1
  20. package/dist/checkbox-group/checkbox-group-root.d.mts +5 -2
  21. package/dist/checkbox-group/checkbox-group-root.d.mts.map +1 -1
  22. package/dist/checkbox-group/checkbox-group-root.mjs +24 -5
  23. package/dist/checkbox-group/checkbox-group-root.mjs.map +1 -1
  24. package/dist/combobox/combobox-clear.d.mts +34 -0
  25. package/dist/combobox/combobox-clear.d.mts.map +1 -0
  26. package/dist/combobox/combobox-clear.mjs +58 -0
  27. package/dist/combobox/combobox-clear.mjs.map +1 -0
  28. package/dist/combobox/combobox-context.mjs +23 -0
  29. package/dist/combobox/combobox-context.mjs.map +1 -0
  30. package/dist/combobox/combobox-group.d.mts +72 -0
  31. package/dist/combobox/combobox-group.d.mts.map +1 -0
  32. package/dist/combobox/combobox-group.mjs +104 -0
  33. package/dist/combobox/combobox-group.mjs.map +1 -0
  34. package/dist/combobox/combobox-input.d.mts +42 -0
  35. package/dist/combobox/combobox-input.d.mts.map +1 -0
  36. package/dist/combobox/combobox-input.mjs +102 -0
  37. package/dist/combobox/combobox-input.mjs.map +1 -0
  38. package/dist/combobox/combobox-label.d.mts +22 -0
  39. package/dist/combobox/combobox-label.d.mts.map +1 -0
  40. package/dist/combobox/combobox-label.mjs +32 -0
  41. package/dist/combobox/combobox-label.mjs.map +1 -0
  42. package/dist/combobox/combobox-list.d.mts +37 -0
  43. package/dist/combobox/combobox-list.d.mts.map +1 -0
  44. package/dist/combobox/combobox-list.mjs +70 -0
  45. package/dist/combobox/combobox-list.mjs.map +1 -0
  46. package/dist/combobox/combobox-option.d.mts +45 -0
  47. package/dist/combobox/combobox-option.d.mts.map +1 -0
  48. package/dist/combobox/combobox-option.mjs +88 -0
  49. package/dist/combobox/combobox-option.mjs.map +1 -0
  50. package/dist/combobox/combobox-popup.d.mts +49 -0
  51. package/dist/combobox/combobox-popup.d.mts.map +1 -0
  52. package/dist/combobox/combobox-popup.mjs +86 -0
  53. package/dist/combobox/combobox-popup.mjs.map +1 -0
  54. package/dist/combobox/combobox-root.d.mts +135 -0
  55. package/dist/combobox/combobox-root.d.mts.map +1 -0
  56. package/dist/combobox/combobox-root.mjs +523 -0
  57. package/dist/combobox/combobox-root.mjs.map +1 -0
  58. package/dist/combobox/combobox-trigger.d.mts +36 -0
  59. package/dist/combobox/combobox-trigger.d.mts.map +1 -0
  60. package/dist/combobox/combobox-trigger.mjs +92 -0
  61. package/dist/combobox/combobox-trigger.mjs.map +1 -0
  62. package/dist/combobox/index.d.mts +36 -0
  63. package/dist/combobox/index.d.mts.map +1 -0
  64. package/dist/combobox/index.mjs +36 -0
  65. package/dist/combobox/index.mjs.map +1 -0
  66. package/dist/dialog/dialog-close.d.mts +17 -10
  67. package/dist/dialog/dialog-close.d.mts.map +1 -1
  68. package/dist/dialog/dialog-close.mjs +31 -20
  69. package/dist/dialog/dialog-close.mjs.map +1 -1
  70. package/dist/dialog/dialog-context.mjs.map +1 -1
  71. package/dist/dialog/dialog-form.d.mts +12 -5
  72. package/dist/dialog/dialog-form.d.mts.map +1 -1
  73. package/dist/dialog/dialog-form.mjs +16 -28
  74. package/dist/dialog/dialog-form.mjs.map +1 -1
  75. package/dist/dialog/dialog-popup.d.mts +10 -4
  76. package/dist/dialog/dialog-popup.d.mts.map +1 -1
  77. package/dist/dialog/dialog-popup.mjs +106 -41
  78. package/dist/dialog/dialog-popup.mjs.map +1 -1
  79. package/dist/dialog/dialog-root.d.mts +14 -8
  80. package/dist/dialog/dialog-root.d.mts.map +1 -1
  81. package/dist/dialog/dialog-root.mjs +66 -11
  82. package/dist/dialog/dialog-root.mjs.map +1 -1
  83. package/dist/dialog/dialog-trigger.d.mts +3 -2
  84. package/dist/dialog/dialog-trigger.d.mts.map +1 -1
  85. package/dist/dialog/dialog-trigger.mjs.map +1 -1
  86. package/dist/dialog/index.d.mts +4 -2
  87. package/dist/dialog/index.d.mts.map +1 -1
  88. package/dist/dialog/index.mjs +4 -2
  89. package/dist/dialog/index.mjs.map +1 -1
  90. package/dist/field/field-control.d.mts +33 -0
  91. package/dist/field/field-control.d.mts.map +1 -0
  92. package/dist/field/field-control.mjs +68 -0
  93. package/dist/field/field-control.mjs.map +1 -0
  94. package/dist/field/field-description.d.mts +24 -0
  95. package/dist/field/field-description.d.mts.map +1 -0
  96. package/dist/field/field-description.mjs +34 -0
  97. package/dist/field/field-description.mjs.map +1 -0
  98. package/dist/field/field-error.d.mts +30 -0
  99. package/dist/field/field-error.d.mts.map +1 -0
  100. package/dist/field/field-error.mjs +42 -0
  101. package/dist/field/field-error.mjs.map +1 -0
  102. package/dist/field/field-label.d.mts +25 -0
  103. package/dist/field/field-label.d.mts.map +1 -0
  104. package/dist/field/field-label.mjs +46 -0
  105. package/dist/field/field-label.mjs.map +1 -0
  106. package/dist/field/field-root.d.mts +53 -0
  107. package/dist/field/field-root.d.mts.map +1 -0
  108. package/dist/field/field-root.mjs +317 -0
  109. package/dist/field/field-root.mjs.map +1 -0
  110. package/dist/field/index.d.mts +18 -0
  111. package/dist/field/index.d.mts.map +1 -0
  112. package/dist/field/index.mjs +17 -0
  113. package/dist/field/index.mjs.map +1 -0
  114. package/dist/form/form-root.d.mts +58 -0
  115. package/dist/form/form-root.d.mts.map +1 -0
  116. package/dist/form/form-root.mjs +146 -0
  117. package/dist/form/form-root.mjs.map +1 -0
  118. package/dist/form/form-submit.d.mts +31 -0
  119. package/dist/form/form-submit.d.mts.map +1 -0
  120. package/dist/form/form-submit.mjs +52 -0
  121. package/dist/form/form-submit.mjs.map +1 -0
  122. package/dist/form/index.d.mts +11 -0
  123. package/dist/form/index.d.mts.map +1 -0
  124. package/dist/form/index.mjs +11 -0
  125. package/dist/form/index.mjs.map +1 -0
  126. package/dist/index.d.mts +46 -2
  127. package/dist/index.mjs +8 -1
  128. package/dist/internal/content-focus-probe.mjs +42 -0
  129. package/dist/internal/content-focus-probe.mjs.map +1 -0
  130. package/dist/internal/field-context.d.mts +19 -0
  131. package/dist/internal/field-context.d.mts.map +1 -0
  132. package/dist/internal/field-context.mjs +14 -0
  133. package/dist/internal/field-context.mjs.map +1 -0
  134. package/dist/internal/focus-first-invalid.mjs +67 -0
  135. package/dist/internal/focus-first-invalid.mjs.map +1 -0
  136. package/dist/internal/form-status-watcher.mjs +31 -0
  137. package/dist/internal/form-status-watcher.mjs.map +1 -0
  138. package/dist/internal/modal-registry.mjs +39 -0
  139. package/dist/internal/modal-registry.mjs.map +1 -0
  140. package/dist/internal/platform-attributes.d.mts +12 -1
  141. package/dist/internal/platform-attributes.d.mts.map +1 -1
  142. package/dist/internal/types.d.mts +11 -1
  143. package/dist/internal/types.d.mts.map +1 -1
  144. package/dist/internal/use-controllable-action.mjs +35 -13
  145. package/dist/internal/use-controllable-action.mjs.map +1 -1
  146. package/dist/internal/use-field-control.mjs +107 -0
  147. package/dist/internal/use-field-control.mjs.map +1 -0
  148. package/dist/internal/use-form-owner-event.mjs +44 -0
  149. package/dist/internal/use-form-owner-event.mjs.map +1 -0
  150. package/dist/internal/use-form-reset.mjs +12 -31
  151. package/dist/internal/use-form-reset.mjs.map +1 -1
  152. package/dist/internal/use-hydrated-mount.mjs +21 -0
  153. package/dist/internal/use-hydrated-mount.mjs.map +1 -0
  154. package/dist/internal/use-latest.mjs +32 -0
  155. package/dist/internal/use-latest.mjs.map +1 -0
  156. package/dist/internal/use-modal-registration.mjs +47 -0
  157. package/dist/internal/use-modal-registration.mjs.map +1 -0
  158. package/dist/internal/use-native-group-reconciliation.mjs +6 -5
  159. package/dist/internal/use-native-group-reconciliation.mjs.map +1 -1
  160. package/dist/internal/use-native-select-value.mjs +184 -0
  161. package/dist/internal/use-native-select-value.mjs.map +1 -0
  162. package/dist/internal/use-popover-popup.mjs +8 -22
  163. package/dist/internal/use-popover-popup.mjs.map +1 -1
  164. package/dist/internal/use-popover-root.mjs +58 -23
  165. package/dist/internal/use-popover-root.mjs.map +1 -1
  166. package/dist/internal/validity.d.mts +24 -0
  167. package/dist/internal/validity.d.mts.map +1 -0
  168. package/dist/internal/validity.mjs +108 -0
  169. package/dist/internal/validity.mjs.map +1 -0
  170. package/dist/menu/menu-group.d.mts.map +1 -1
  171. package/dist/menu/menu-group.mjs +3 -2
  172. package/dist/menu/menu-group.mjs.map +1 -1
  173. package/dist/menu/menu-radio-group.mjs +9 -4
  174. package/dist/menu/menu-radio-group.mjs.map +1 -1
  175. package/dist/menu/menu-root.mjs.map +1 -1
  176. package/dist/radio-group/radio-group-root.d.mts +4 -2
  177. package/dist/radio-group/radio-group-root.d.mts.map +1 -1
  178. package/dist/radio-group/radio-group-root.mjs +34 -8
  179. package/dist/radio-group/radio-group-root.mjs.map +1 -1
  180. package/dist/select/index.d.mts +30 -0
  181. package/dist/select/index.d.mts.map +1 -0
  182. package/dist/select/index.mjs +30 -0
  183. package/dist/select/index.mjs.map +1 -0
  184. package/dist/select/select-context.mjs +13 -0
  185. package/dist/select/select-context.mjs.map +1 -0
  186. package/dist/select/select-dom.mjs +44 -0
  187. package/dist/select/select-dom.mjs.map +1 -0
  188. package/dist/select/select-group-label.d.mts +22 -0
  189. package/dist/select/select-group-label.d.mts.map +1 -0
  190. package/dist/select/select-group-label.mjs +39 -0
  191. package/dist/select/select-group-label.mjs.map +1 -0
  192. package/dist/select/select-group.d.mts +28 -0
  193. package/dist/select/select-group.d.mts.map +1 -0
  194. package/dist/select/select-group.mjs +47 -0
  195. package/dist/select/select-group.mjs.map +1 -0
  196. package/dist/select/select-option.d.mts +42 -0
  197. package/dist/select/select-option.d.mts.map +1 -0
  198. package/dist/select/select-option.mjs +65 -0
  199. package/dist/select/select-option.mjs.map +1 -0
  200. package/dist/select/select-root.d.mts +68 -0
  201. package/dist/select/select-root.d.mts.map +1 -0
  202. package/dist/select/select-root.mjs +114 -0
  203. package/dist/select/select-root.mjs.map +1 -0
  204. package/dist/select/select-separator.d.mts +20 -0
  205. package/dist/select/select-separator.d.mts.map +1 -0
  206. package/dist/select/select-separator.mjs +30 -0
  207. package/dist/select/select-separator.mjs.map +1 -0
  208. package/dist/select/select-trigger.d.mts +29 -0
  209. package/dist/select/select-trigger.d.mts.map +1 -0
  210. package/dist/select/select-trigger.mjs +48 -0
  211. package/dist/select/select-trigger.mjs.map +1 -0
  212. package/dist/select/select-value.d.mts +31 -0
  213. package/dist/select/select-value.d.mts.map +1 -0
  214. package/dist/select/select-value.mjs +101 -0
  215. package/dist/select/select-value.mjs.map +1 -0
  216. package/dist/slider/index.d.mts +32 -0
  217. package/dist/slider/index.d.mts.map +1 -0
  218. package/dist/slider/index.mjs +27 -0
  219. package/dist/slider/index.mjs.map +1 -0
  220. package/dist/slider/slider-arithmetic.mjs +120 -0
  221. package/dist/slider/slider-arithmetic.mjs.map +1 -0
  222. package/dist/slider/slider-context.mjs +13 -0
  223. package/dist/slider/slider-context.mjs.map +1 -0
  224. package/dist/slider/slider-indicator.d.mts +22 -0
  225. package/dist/slider/slider-indicator.d.mts.map +1 -0
  226. package/dist/slider/slider-indicator.mjs +36 -0
  227. package/dist/slider/slider-indicator.mjs.map +1 -0
  228. package/dist/slider/slider-label.d.mts +23 -0
  229. package/dist/slider/slider-label.d.mts.map +1 -0
  230. package/dist/slider/slider-label.mjs +44 -0
  231. package/dist/slider/slider-label.mjs.map +1 -0
  232. package/dist/slider/slider-root.d.mts +111 -0
  233. package/dist/slider/slider-root.d.mts.map +1 -0
  234. package/dist/slider/slider-root.mjs +582 -0
  235. package/dist/slider/slider-root.mjs.map +1 -0
  236. package/dist/slider/slider-thumb.d.mts +58 -0
  237. package/dist/slider/slider-thumb.d.mts.map +1 -0
  238. package/dist/slider/slider-thumb.mjs +145 -0
  239. package/dist/slider/slider-thumb.mjs.map +1 -0
  240. package/dist/slider/slider-track.d.mts +29 -0
  241. package/dist/slider/slider-track.d.mts.map +1 -0
  242. package/dist/slider/slider-track.mjs +54 -0
  243. package/dist/slider/slider-track.mjs.map +1 -0
  244. package/dist/slider/slider-value.d.mts +34 -0
  245. package/dist/slider/slider-value.d.mts.map +1 -0
  246. package/dist/slider/slider-value.mjs +38 -0
  247. package/dist/slider/slider-value.mjs.map +1 -0
  248. package/dist/switch/switch.d.mts +5 -3
  249. package/dist/switch/switch.d.mts.map +1 -1
  250. package/dist/switch/switch.mjs +24 -8
  251. package/dist/switch/switch.mjs.map +1 -1
  252. package/dist/tabs/tabs-root.mjs +13 -3
  253. package/dist/tabs/tabs-root.mjs.map +1 -1
  254. package/dist/toast/index.d.mts +25 -0
  255. package/dist/toast/index.d.mts.map +1 -0
  256. package/dist/toast/index.mjs +26 -0
  257. package/dist/toast/index.mjs.map +1 -0
  258. package/dist/toast/toast-action.d.mts +39 -0
  259. package/dist/toast/toast-action.d.mts.map +1 -0
  260. package/dist/toast/toast-action.mjs +64 -0
  261. package/dist/toast/toast-action.mjs.map +1 -0
  262. package/dist/toast/toast-close.d.mts +25 -0
  263. package/dist/toast/toast-close.d.mts.map +1 -0
  264. package/dist/toast/toast-close.mjs +46 -0
  265. package/dist/toast/toast-close.mjs.map +1 -0
  266. package/dist/toast/toast-context.mjs +19 -0
  267. package/dist/toast/toast-context.mjs.map +1 -0
  268. package/dist/toast/toast-description.d.mts +24 -0
  269. package/dist/toast/toast-description.d.mts.map +1 -0
  270. package/dist/toast/toast-description.mjs +35 -0
  271. package/dist/toast/toast-description.mjs.map +1 -0
  272. package/dist/toast/toast-root.d.mts +43 -0
  273. package/dist/toast/toast-root.d.mts.map +1 -0
  274. package/dist/toast/toast-root.mjs +204 -0
  275. package/dist/toast/toast-root.mjs.map +1 -0
  276. package/dist/toast/toast-title.d.mts +24 -0
  277. package/dist/toast/toast-title.d.mts.map +1 -0
  278. package/dist/toast/toast-title.mjs +33 -0
  279. package/dist/toast/toast-title.mjs.map +1 -0
  280. package/dist/toast/toast-viewport.d.mts +52 -0
  281. package/dist/toast/toast-viewport.d.mts.map +1 -0
  282. package/dist/toast/toast-viewport.mjs +621 -0
  283. package/dist/toast/toast-viewport.mjs.map +1 -0
  284. package/dist/toast/toast.d.mts +119 -0
  285. package/dist/toast/toast.d.mts.map +1 -0
  286. package/dist/toast/toast.mjs +153 -0
  287. package/dist/toast/toast.mjs.map +1 -0
  288. package/package.json +7 -1
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-group-context.mjs","names":[],"sources":["../../src/checkbox-group/checkbox-group-context.ts"],"sourcesContent":["\"use client\";\nimport { createContext, use } from \"react\";\n\n/** A change to the group's set of checked values (design/components/checkbox-group.md 5.2). */\nexport interface CheckboxGroupPatch {\n readonly added: readonly string[];\n readonly removed: readonly string[];\n}\n\nexport interface CheckboxGroupContextValue {\n /** The `name` shared by every Item of the group (prop or `useId()`). */\n readonly name: string;\n readonly form: string | undefined;\n /**\n * The Root's `required` while no value of an enabled Item is checked (design section 7):\n * rendered as native `required` on every Item. Before the Items have registered (server render,\n * hydration render) it is `required && optimistic.size === 0`, which is what the server can\n * compute.\n */\n readonly required: boolean;\n /** Optimistic checked values: Items and Parents render from it. */\n readonly optimistic: ReadonlySet<string>;\n /** Committed checked values. For per-part pending and the Parent's restore memory only. */\n readonly committed: ReadonlySet<string>;\n readonly pending: boolean;\n /** `Root disabled` (reaches the boxes natively through `<fieldset disabled>`). */\n readonly disabled: boolean;\n /**\n * Uncontrolled mode: the latest `defaultValue` as a set, mirrored by each Item into\n * `el.defaultChecked` (and by each Parent, derived) so that a form reset returns to it.\n * `undefined` in controlled mode, where React's mount-time value stays the reset target\n * (conventions 3.8 rule 6).\n */\n readonly defaultValue: ReadonlySet<string> | undefined;\n /**\n * Item click. No-op when `optimistic.has(value) === checked`. Checks neither `disabled` nor\n * `defaultPrevented` (the Item's `guardCheckableChange` does).\n */\n readonly toggle: (value: string, checked: boolean, event: Event) => void;\n /** Parent click: a whole patch. No-op when it changes nothing against the optimistic set. */\n readonly apply: (patch: CheckboxGroupPatch, event: Event) => void;\n /**\n * Values whose every mounted Item has its own `disabled` prop (`Root disabled` is not counted).\n * A Parent leaves them alone (design 6.2). Empty until the Items registered.\n */\n readonly disabledItems: ReadonlySet<string>;\n /**\n * Stable. Each Item calls it from a layout effect with its value and its own `disabled` prop;\n * returns the unregister function.\n */\n readonly registerItem: (value: string, disabled: boolean) => () => void;\n /** From `useNativeGroupReconciliation`; Items and Parents call it from their mount layout effect. */\n readonly onItemMounted: (element: HTMLInputElement | null) => void;\n /**\n * A Parent mounted with a DOM `checked` that differs from its derivation (a click before\n * hydration). Folded into the Root's next mount read as \"check all\" / \"uncheck all\" of\n * `values` (design 8.1). Call before `onItemMounted`.\n */\n readonly reportParent: (values: readonly string[], checked: boolean) => void;\n /**\n * The optimistic set as the Root state's `value`: an array in the Items' document order as of\n * the Root's last render (see `CheckboxGroupRootState.value`).\n */\n readonly value: readonly string[];\n /**\n * Sorts values by the current document order of the group's Items (a DOM read); values with no\n * Item keep their iteration order, after them. Call from handlers and effects only.\n */\n readonly sortByDocument: (values: Iterable<string>) => string[];\n}\n\n/**\n * The values a Parent over `values` acts on and derives from: those not in `disabledItems`\n * (values with no Item included). When that leaves nothing (every value has only disabled\n * Items), all of `values`: a Parent the consumer left enabled over disabled Items still shows and\n * changes their state (disable the Parent to make it inert).\n */\nexport function enabledValues(\n values: readonly string[],\n disabledItems: ReadonlySet<string>,\n): readonly string[] {\n if (disabledItems.size === 0) return values;\n const enabled = values.filter((v) => !disabledItems.has(v));\n return enabled.length > 0 ? enabled : values;\n}\n\nexport const CheckboxGroupContext = createContext<CheckboxGroupContextValue | null>(null);\n\nexport function useCheckboxGroupContext(part: string): CheckboxGroupContextValue {\n const context = use(CheckboxGroupContext);\n if (context === null) {\n throw new Error(`${part} must be rendered inside a CheckboxGroup.Root.`);\n }\n return context;\n}\n"],"mappings":";;;;;;;;;AA6EA,SAAgB,cACd,QACA,eACmB;CACnB,IAAI,cAAc,SAAS,GAAG,OAAO;CACrC,MAAM,UAAU,OAAO,QAAQ,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC;CAC1D,OAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEA,MAAa,uBAAuB,cAAgD,IAAI;AAExF,SAAgB,wBAAwB,MAAyC;CAC/E,MAAM,UAAU,IAAI,oBAAoB;CACxC,IAAI,YAAY,MACd,MAAM,IAAI,MAAM,GAAG,KAAK,+CAA+C;CAEzE,OAAO;AACT"}
1
+ {"version":3,"file":"checkbox-group-context.mjs","names":[],"sources":["../../src/checkbox-group/checkbox-group-context.ts"],"sourcesContent":["\"use client\";\nimport { createContext, use } from \"react\";\n\n/** A change to the group's set of checked values (design/components/checkbox-group.md 5.2). */\nexport interface CheckboxGroupPatch {\n readonly added: readonly string[];\n readonly removed: readonly string[];\n}\n\nexport interface CheckboxGroupContextValue {\n /** The `name` shared by every Item of the group (prop or `useId()`). */\n readonly name: string;\n readonly form: string | undefined;\n /** Inside a `Field.Root`: the Field's `aria-invalid`, rendered on every Item. Else `undefined`. */\n readonly fieldInvalid: \"true\" | \"false\" | undefined;\n /**\n * The Root's `required` while no value of an enabled Item is checked (design section 7):\n * rendered as native `required` on every Item. Before the Items have registered (server render,\n * hydration render) it is `required && optimistic.size === 0`, which is what the server can\n * compute.\n */\n readonly required: boolean;\n /** Optimistic checked values: Items and Parents render from it. */\n readonly optimistic: ReadonlySet<string>;\n /** Committed checked values. For per-part pending and the Parent's restore memory only. */\n readonly committed: ReadonlySet<string>;\n readonly pending: boolean;\n /** `Root disabled` (reaches the boxes natively through `<fieldset disabled>`). */\n readonly disabled: boolean;\n /**\n * Uncontrolled mode: the latest `defaultValue` as a set, mirrored by each Item into\n * `el.defaultChecked` (and by each Parent, derived) so that a form reset returns to it.\n * `undefined` in controlled mode, where React's mount-time value stays the reset target\n * (conventions 3.8 rule 6).\n */\n readonly defaultValue: ReadonlySet<string> | undefined;\n /**\n * Item click. No-op when `optimistic.has(value) === checked`. Checks neither `disabled` nor\n * `defaultPrevented` (the Item's `guardCheckableChange` does).\n */\n readonly toggle: (value: string, checked: boolean, event: Event) => void;\n /** Parent click: a whole patch. No-op when it changes nothing against the optimistic set. */\n readonly apply: (patch: CheckboxGroupPatch, event: Event) => void;\n /**\n * Values whose every mounted Item has its own `disabled` prop (`Root disabled` is not counted).\n * A Parent leaves them alone (design 6.2). Empty until the Items registered.\n */\n readonly disabledItems: ReadonlySet<string>;\n /**\n * Stable. Each Item calls it from a layout effect with its value and its own `disabled` prop;\n * returns the unregister function.\n */\n readonly registerItem: (value: string, disabled: boolean) => () => void;\n /** From `useNativeGroupReconciliation`; Items and Parents call it from their mount layout effect. */\n readonly onItemMounted: (element: HTMLInputElement | null) => void;\n /**\n * A Parent mounted with a DOM `checked` that differs from its derivation (a click before\n * hydration). Folded into the Root's next mount read as \"check all\" / \"uncheck all\" of\n * `values` (design 8.1). Call before `onItemMounted`.\n */\n readonly reportParent: (values: readonly string[], checked: boolean) => void;\n /**\n * The optimistic set as the Root state's `value`: an array in the Items' document order as of\n * the Root's last render (see `CheckboxGroupRootState.value`).\n */\n readonly value: readonly string[];\n /**\n * Sorts values by the current document order of the group's Items (a DOM read); values with no\n * Item keep their iteration order, after them. Call from handlers and effects only.\n */\n readonly sortByDocument: (values: Iterable<string>) => string[];\n}\n\n/**\n * The values a Parent over `values` acts on and derives from: those not in `disabledItems`\n * (values with no Item included). When that leaves nothing (every value has only disabled\n * Items), all of `values`: a Parent the consumer left enabled over disabled Items still shows and\n * changes their state (disable the Parent to make it inert).\n */\nexport function enabledValues(\n values: readonly string[],\n disabledItems: ReadonlySet<string>,\n): readonly string[] {\n if (disabledItems.size === 0) return values;\n const enabled = values.filter((v) => !disabledItems.has(v));\n return enabled.length > 0 ? enabled : values;\n}\n\nexport const CheckboxGroupContext = createContext<CheckboxGroupContextValue | null>(null);\n\nexport function useCheckboxGroupContext(part: string): CheckboxGroupContextValue {\n const context = use(CheckboxGroupContext);\n if (context === null) {\n throw new Error(`${part} must be rendered inside a CheckboxGroup.Root.`);\n }\n return context;\n}\n"],"mappings":";;;;;;;;;AA+EA,SAAgB,cACd,QACA,eACmB;CACnB,IAAI,cAAc,SAAS,GAAG,OAAO;CACrC,MAAM,UAAU,OAAO,QAAQ,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC;CAC1D,OAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEA,MAAa,uBAAuB,cAAgD,IAAI;AAExF,SAAgB,wBAAwB,MAAyC;CAC/E,MAAM,UAAU,IAAI,oBAAoB;CACxC,IAAI,YAAY,MACd,MAAM,IAAI,MAAM,GAAG,KAAK,+CAA+C;CAEzE,OAAO;AACT"}
@@ -44,7 +44,8 @@ export interface CheckboxGroupItemProps extends Omit<ComponentPropsWithRef<"inpu
44
44
  * Owned keys (conventions 1.2; a `render` element's value is overridden): `type`, `name`,
45
45
  * `value`, `checked`, `defaultChecked` (never rendered), `disabled`, `form`, `required`
46
46
  * (computed by the Root from its `required` prop), `aria-checked` (removed), `data-checked`,
47
- * `data-pending`, `data-disabled`. `onChange` is merged: a `render` element's own handler runs
47
+ * `data-pending`, `data-disabled`; inside a `Field.Root` also `aria-invalid` (the Field's).
48
+ * `onChange` is merged: a `render` element's own handler runs
48
49
  * first, then the library's. `role` passes through.
49
50
  */
50
51
  export declare function CheckboxGroupItem({ value, disabled: disabledProp, transition, className, style, render, ...rest }: CheckboxGroupItemProps): import("react").ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-group-item.d.mts","names":[],"sources":["../../src/checkbox-group/checkbox-group-item.tsx"],"mappings":";;;iBAWiB;WACN;;WAEA;;WAEA;;WAEA;;iBAGM,+BAA+B,KAC9C;;EAgBA;;;;;;EAMA;;;;;;;;;;;EAWA,aAAa;EACb,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;EAE9C,SAAS,WAAW,gCAAgC;;;;;;;;;;;;;;wBAetC,oBACd,OACA,UAAU,cACV,YACA,WACA,OACA,WACG,QACF,yCAAsB;yBART"}
1
+ {"version":3,"file":"checkbox-group-item.d.mts","names":[],"sources":["../../src/checkbox-group/checkbox-group-item.tsx"],"mappings":";;;iBAWiB;WACN;;WAEA;;WAEA;;WAEA;;iBAGM,+BAA+B,KAC9C;;EAgBA;;;;;;EAMA;;;;;;;;;;;EAWA,aAAa;EACb,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;EAE9C,SAAS,WAAW,gCAAgC;;;;;;;;;;;;;;;wBAgBtC,oBACd,OACA,UAAU,cACV,YACA,WACA,OACA,WACG,QACF,yCAAsB;yBART"}
@@ -16,7 +16,8 @@ import { useLayoutEffect } from "react";
16
16
  * Owned keys (conventions 1.2; a `render` element's value is overridden): `type`, `name`,
17
17
  * `value`, `checked`, `defaultChecked` (never rendered), `disabled`, `form`, `required`
18
18
  * (computed by the Root from its `required` prop), `aria-checked` (removed), `data-checked`,
19
- * `data-pending`, `data-disabled`. `onChange` is merged: a `render` element's own handler runs
19
+ * `data-pending`, `data-disabled`; inside a `Field.Root` also `aria-invalid` (the Field's).
20
+ * `onChange` is merged: a `render` element's own handler runs
20
21
  * first, then the library's. `role` passes through.
21
22
  */
22
23
  function CheckboxGroupItem({ value, disabled: disabledProp = false, transition, className, style, render, ...rest }) {
@@ -74,6 +75,7 @@ function CheckboxGroupItem({ value, disabled: disabledProp = false, transition,
74
75
  "data-checked": dataAttr(checked),
75
76
  "data-pending": dataAttr(pending),
76
77
  "data-disabled": dataAttr(disabled),
78
+ ...ctx.fieldInvalid === void 0 ? {} : { "aria-invalid": ctx.fieldInvalid },
77
79
  onChange: (event) => {
78
80
  if (disabled) return;
79
81
  const nativeEvent = event.nativeEvent;
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-group-item.mjs","names":[],"sources":["../../src/checkbox-group/checkbox-group-item.tsx"],"sourcesContent":["\"use client\";\nimport { useLayoutEffect } from \"react\";\nimport type { ChangeEvent, ComponentPropsWithRef, CSSProperties, ViewTransitionClass } from \"react\";\nimport { useTransitionBoundary } from \"../internal/transition-boundary.js\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { guardCheckableChange, useNativeChecked } from \"../internal/use-native-checked.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { useCheckboxGroupContext } from \"./checkbox-group-context.js\";\nimport { syncPresence } from \"../internal/sync-presence.js\";\n\nexport interface CheckboxGroupItemState {\n readonly value: string;\n /** Optimistic: true as soon as the user checks this box, before the action settles. */\n readonly checked: boolean;\n /** The Root is pending and this box's optimistic state differs from its committed state. */\n readonly pending: boolean;\n /** Disabled by its own prop or by `Root disabled`. */\n readonly disabled: boolean;\n}\n\nexport interface CheckboxGroupItemProps extends Omit<\n ComponentPropsWithRef<\"input\">,\n | \"type\"\n | \"name\"\n | \"value\"\n | \"checked\"\n | \"defaultChecked\"\n | \"defaultValue\"\n | \"form\"\n | \"required\"\n | \"aria-checked\"\n | \"onChange\"\n | \"className\"\n | \"style\"\n | \"children\"\n> {\n /** The value this box contributes when checked. Must be unique within the Root. */\n value: string;\n /**\n * Native `disabled`: unfocusable, never dispatches, barred from constraint validation. A\n * `Parent` leaves a disabled Item's value alone and derives its state without it; a checked\n * disabled Item does not satisfy the group's `required`.\n */\n disabled?: boolean;\n /**\n * Forwarded to the Item's `<ViewTransition default>`. Default: no boundary. Fires only on the\n * commit that settles the action (or rolls it back), never on the optimistic check; animate the\n * check itself with CSS on `:checked`.\n *\n * Static: without `transition` the part renders no `<ViewTransition>`; changing it between\n * `undefined` and a value remounts the element. Any value, `\"none\"` included, makes a mount or\n * `<Activity>` reveal of this part inside a transition start a document view transition: the\n * page cross-fades for about 250 ms and the next transition commit waits for it (issue #35).\n */\n transition?: ViewTransitionClass;\n className?: StateValue<string | undefined, CheckboxGroupItemState>;\n style?: StateValue<CSSProperties | undefined, CheckboxGroupItemState>;\n /** Replace the rendered element. Must keep an `<input>`; the library sets `type=\"checkbox\"`. */\n render?: RenderProp<ComponentPropsWithRef<\"input\">, CheckboxGroupItemState>;\n}\n\n/**\n * One `<input type=\"checkbox\">` of the group, checked while its `value` is in the group's set.\n * Its DOM `checked` is the optimistic state (`checked={optimistic.has(value)}`): react-dom\n * restores a controlled input to its props after every event, and only the sync-lane optimistic\n * value survives that restore.\n *\n * Owned keys (conventions 1.2; a `render` element's value is overridden): `type`, `name`,\n * `value`, `checked`, `defaultChecked` (never rendered), `disabled`, `form`, `required`\n * (computed by the Root from its `required` prop), `aria-checked` (removed), `data-checked`,\n * `data-pending`, `data-disabled`. `onChange` is merged: a `render` element's own handler runs\n * first, then the library's. `role` passes through.\n */\nexport function CheckboxGroupItem({\n value,\n disabled: disabledProp = false,\n transition,\n className,\n style,\n render,\n ...rest\n}: CheckboxGroupItemProps) {\n const ctx = useCheckboxGroupContext(\"CheckboxGroup.Item\");\n const checked = ctx.optimistic.has(value);\n const pending = ctx.pending && checked !== ctx.committed.has(value);\n const disabled = ctx.disabled || disabledProp;\n const required = ctx.required;\n\n // The Root needs every Item's own `disabled` for the Parents and `required` (design 6.2, 7).\n const { registerItem } = ctx;\n useLayoutEffect(() => registerItem(value, disabledProp), [registerItem, value, disabledProp]);\n\n // Group mode: element check and re-apply only; the Root reports the residual paths once.\n const inputRef = useNativeChecked({\n type: \"checkbox\",\n component: \"CheckboxGroup.Item\",\n checked,\n group: true,\n onItemMounted: (el) => {\n // Hydration keeps server attributes that differ from the client render (React only warns).\n // An Item hydrating after its Root can render a different state than the server did (a\n // click on an already hydrated box), and stale attributes would stay until the next change.\n if (el !== null) {\n syncPresence(el, \"data-checked\", checked);\n syncPresence(el, \"data-pending\", pending);\n syncPresence(el, \"data-disabled\", disabled);\n syncPresence(el, \"required\", required);\n }\n ctx.onItemMounted(el);\n },\n defaultChecked: ctx.defaultValue === undefined ? undefined : ctx.defaultValue.has(value),\n });\n\n const state: CheckboxGroupItemState = { value, checked, pending, disabled };\n\n const element = useRender<ComponentPropsWithRef<\"input\">, CheckboxGroupItemState>({\n defaultElement: \"input\",\n render,\n state,\n className,\n style,\n children: undefined,\n ref: inputRef,\n // Pass-through layer: a `render` element's own props win over these.\n props: rest,\n libraryProps: {\n type: \"checkbox\",\n name: ctx.name,\n value,\n checked,\n defaultChecked: undefined,\n \"aria-checked\": undefined,\n // Owned (Switch precedent) so that native disabledness, `data-disabled` and the click guard\n // agree. Only the Item's own prop: `Root disabled` reaches the box through the fieldset.\n disabled: disabledProp,\n form: ctx.form,\n required,\n \"data-checked\": dataAttr(checked),\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n onChange: (event: ChangeEvent<HTMLInputElement>) => {\n // A natively disabled box fires no click; this covers `render` elements that do not\n // honour `disabled`.\n if (disabled) return;\n const nativeEvent = event.nativeEvent;\n guardCheckableChange(\n nativeEvent,\n () => ctx.toggle(value, !checked, nativeEvent),\n \"CheckboxGroup.Item\",\n );\n },\n },\n });\n\n return useTransitionBoundary(\"CheckboxGroup.Item\", transition, element);\n}\n\nCheckboxGroupItem.displayName = \"CheckboxGroupItem\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA0EA,SAAgB,kBAAkB,EAChC,OACA,UAAU,eAAe,OACzB,YACA,WACA,OACA,QACA,GAAG,QACsB;CACzB,MAAM,MAAM,wBAAwB,oBAAoB;CACxD,MAAM,UAAU,IAAI,WAAW,IAAI,KAAK;CACxC,MAAM,UAAU,IAAI,WAAW,YAAY,IAAI,UAAU,IAAI,KAAK;CAClE,MAAM,WAAW,IAAI,YAAY;CACjC,MAAM,WAAW,IAAI;CAGrB,MAAM,EAAE,iBAAiB;CACzB,sBAAsB,aAAa,OAAO,YAAY,GAAG;EAAC;EAAc;EAAO;CAAY,CAAC;CAG5F,MAAM,WAAW,iBAAiB;EAChC,MAAM;EACN,WAAW;EACX;EACA,OAAO;EACP,gBAAgB,OAAO;GAIrB,IAAI,OAAO,MAAM;IACf,aAAa,IAAI,gBAAgB,OAAO;IACxC,aAAa,IAAI,gBAAgB,OAAO;IACxC,aAAa,IAAI,iBAAiB,QAAQ;IAC1C,aAAa,IAAI,YAAY,QAAQ;GACvC;GACA,IAAI,cAAc,EAAE;EACtB;EACA,gBAAgB,IAAI,iBAAiB,KAAA,IAAY,KAAA,IAAY,IAAI,aAAa,IAAI,KAAK;CACzF,CAAC;CAID,MAAM,UAAU,UAAkE;EAChF,gBAAgB;EAChB;EACA,OAAA;GALsC;GAAO;GAAS;GAAS;EAK3D;EACJ;EACA;EACA,UAAU,KAAA;EACV,KAAK;EAEL,OAAO;EACP,cAAc;GACZ,MAAM;GACN,MAAM,IAAI;GACV;GACA;GACA,gBAAgB,KAAA;GAChB,gBAAgB,KAAA;GAGhB,UAAU;GACV,MAAM,IAAI;GACV;GACA,gBAAgB,SAAS,OAAO;GAChC,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;GAClC,WAAW,UAAyC;IAGlD,IAAI,UAAU;IACd,MAAM,cAAc,MAAM;IAC1B,qBACE,mBACM,IAAI,OAAO,OAAO,CAAC,SAAS,WAAW,GAC7C,oBACF;GACF;EACF;CACF,CAAC;CAED,OAAO,sBAAsB,sBAAsB,YAAY,OAAO;AACxE;AAEA,kBAAkB,cAAc"}
1
+ {"version":3,"file":"checkbox-group-item.mjs","names":[],"sources":["../../src/checkbox-group/checkbox-group-item.tsx"],"sourcesContent":["\"use client\";\nimport { useLayoutEffect } from \"react\";\nimport type { ChangeEvent, ComponentPropsWithRef, CSSProperties, ViewTransitionClass } from \"react\";\nimport { useTransitionBoundary } from \"../internal/transition-boundary.js\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { guardCheckableChange, useNativeChecked } from \"../internal/use-native-checked.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { useCheckboxGroupContext } from \"./checkbox-group-context.js\";\nimport { syncPresence } from \"../internal/sync-presence.js\";\n\nexport interface CheckboxGroupItemState {\n readonly value: string;\n /** Optimistic: true as soon as the user checks this box, before the action settles. */\n readonly checked: boolean;\n /** The Root is pending and this box's optimistic state differs from its committed state. */\n readonly pending: boolean;\n /** Disabled by its own prop or by `Root disabled`. */\n readonly disabled: boolean;\n}\n\nexport interface CheckboxGroupItemProps extends Omit<\n ComponentPropsWithRef<\"input\">,\n | \"type\"\n | \"name\"\n | \"value\"\n | \"checked\"\n | \"defaultChecked\"\n | \"defaultValue\"\n | \"form\"\n | \"required\"\n | \"aria-checked\"\n | \"onChange\"\n | \"className\"\n | \"style\"\n | \"children\"\n> {\n /** The value this box contributes when checked. Must be unique within the Root. */\n value: string;\n /**\n * Native `disabled`: unfocusable, never dispatches, barred from constraint validation. A\n * `Parent` leaves a disabled Item's value alone and derives its state without it; a checked\n * disabled Item does not satisfy the group's `required`.\n */\n disabled?: boolean;\n /**\n * Forwarded to the Item's `<ViewTransition default>`. Default: no boundary. Fires only on the\n * commit that settles the action (or rolls it back), never on the optimistic check; animate the\n * check itself with CSS on `:checked`.\n *\n * Static: without `transition` the part renders no `<ViewTransition>`; changing it between\n * `undefined` and a value remounts the element. Any value, `\"none\"` included, makes a mount or\n * `<Activity>` reveal of this part inside a transition start a document view transition: the\n * page cross-fades for about 250 ms and the next transition commit waits for it (issue #35).\n */\n transition?: ViewTransitionClass;\n className?: StateValue<string | undefined, CheckboxGroupItemState>;\n style?: StateValue<CSSProperties | undefined, CheckboxGroupItemState>;\n /** Replace the rendered element. Must keep an `<input>`; the library sets `type=\"checkbox\"`. */\n render?: RenderProp<ComponentPropsWithRef<\"input\">, CheckboxGroupItemState>;\n}\n\n/**\n * One `<input type=\"checkbox\">` of the group, checked while its `value` is in the group's set.\n * Its DOM `checked` is the optimistic state (`checked={optimistic.has(value)}`): react-dom\n * restores a controlled input to its props after every event, and only the sync-lane optimistic\n * value survives that restore.\n *\n * Owned keys (conventions 1.2; a `render` element's value is overridden): `type`, `name`,\n * `value`, `checked`, `defaultChecked` (never rendered), `disabled`, `form`, `required`\n * (computed by the Root from its `required` prop), `aria-checked` (removed), `data-checked`,\n * `data-pending`, `data-disabled`; inside a `Field.Root` also `aria-invalid` (the Field's).\n * `onChange` is merged: a `render` element's own handler runs\n * first, then the library's. `role` passes through.\n */\nexport function CheckboxGroupItem({\n value,\n disabled: disabledProp = false,\n transition,\n className,\n style,\n render,\n ...rest\n}: CheckboxGroupItemProps) {\n const ctx = useCheckboxGroupContext(\"CheckboxGroup.Item\");\n const checked = ctx.optimistic.has(value);\n const pending = ctx.pending && checked !== ctx.committed.has(value);\n const disabled = ctx.disabled || disabledProp;\n const required = ctx.required;\n\n // The Root needs every Item's own `disabled` for the Parents and `required` (design 6.2, 7).\n const { registerItem } = ctx;\n useLayoutEffect(() => registerItem(value, disabledProp), [registerItem, value, disabledProp]);\n\n // Group mode: element check and re-apply only; the Root reports the residual paths once.\n const inputRef = useNativeChecked({\n type: \"checkbox\",\n component: \"CheckboxGroup.Item\",\n checked,\n group: true,\n onItemMounted: (el) => {\n // Hydration keeps server attributes that differ from the client render (React only warns).\n // An Item hydrating after its Root can render a different state than the server did (a\n // click on an already hydrated box), and stale attributes would stay until the next change.\n if (el !== null) {\n syncPresence(el, \"data-checked\", checked);\n syncPresence(el, \"data-pending\", pending);\n syncPresence(el, \"data-disabled\", disabled);\n syncPresence(el, \"required\", required);\n }\n ctx.onItemMounted(el);\n },\n defaultChecked: ctx.defaultValue === undefined ? undefined : ctx.defaultValue.has(value),\n });\n\n const state: CheckboxGroupItemState = { value, checked, pending, disabled };\n\n const element = useRender<ComponentPropsWithRef<\"input\">, CheckboxGroupItemState>({\n defaultElement: \"input\",\n render,\n state,\n className,\n style,\n children: undefined,\n ref: inputRef,\n // Pass-through layer: a `render` element's own props win over these.\n props: rest,\n libraryProps: {\n type: \"checkbox\",\n name: ctx.name,\n value,\n checked,\n defaultChecked: undefined,\n \"aria-checked\": undefined,\n // Owned (Switch precedent) so that native disabledness, `data-disabled` and the click guard\n // agree. Only the Item's own prop: `Root disabled` reaches the box through the fieldset.\n disabled: disabledProp,\n form: ctx.form,\n required,\n \"data-checked\": dataAttr(checked),\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n // Inside a Field (owned there): the group's invalid state, since the fieldset cannot carry it.\n ...(ctx.fieldInvalid === undefined ? {} : { \"aria-invalid\": ctx.fieldInvalid }),\n onChange: (event: ChangeEvent<HTMLInputElement>) => {\n // A natively disabled box fires no click; this covers `render` elements that do not\n // honour `disabled`.\n if (disabled) return;\n const nativeEvent = event.nativeEvent;\n guardCheckableChange(\n nativeEvent,\n () => ctx.toggle(value, !checked, nativeEvent),\n \"CheckboxGroup.Item\",\n );\n },\n },\n });\n\n return useTransitionBoundary(\"CheckboxGroup.Item\", transition, element);\n}\n\nCheckboxGroupItem.displayName = \"CheckboxGroupItem\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2EA,SAAgB,kBAAkB,EAChC,OACA,UAAU,eAAe,OACzB,YACA,WACA,OACA,QACA,GAAG,QACsB;CACzB,MAAM,MAAM,wBAAwB,oBAAoB;CACxD,MAAM,UAAU,IAAI,WAAW,IAAI,KAAK;CACxC,MAAM,UAAU,IAAI,WAAW,YAAY,IAAI,UAAU,IAAI,KAAK;CAClE,MAAM,WAAW,IAAI,YAAY;CACjC,MAAM,WAAW,IAAI;CAGrB,MAAM,EAAE,iBAAiB;CACzB,sBAAsB,aAAa,OAAO,YAAY,GAAG;EAAC;EAAc;EAAO;CAAY,CAAC;CAG5F,MAAM,WAAW,iBAAiB;EAChC,MAAM;EACN,WAAW;EACX;EACA,OAAO;EACP,gBAAgB,OAAO;GAIrB,IAAI,OAAO,MAAM;IACf,aAAa,IAAI,gBAAgB,OAAO;IACxC,aAAa,IAAI,gBAAgB,OAAO;IACxC,aAAa,IAAI,iBAAiB,QAAQ;IAC1C,aAAa,IAAI,YAAY,QAAQ;GACvC;GACA,IAAI,cAAc,EAAE;EACtB;EACA,gBAAgB,IAAI,iBAAiB,KAAA,IAAY,KAAA,IAAY,IAAI,aAAa,IAAI,KAAK;CACzF,CAAC;CAID,MAAM,UAAU,UAAkE;EAChF,gBAAgB;EAChB;EACA,OAAA;GALsC;GAAO;GAAS;GAAS;EAK3D;EACJ;EACA;EACA,UAAU,KAAA;EACV,KAAK;EAEL,OAAO;EACP,cAAc;GACZ,MAAM;GACN,MAAM,IAAI;GACV;GACA;GACA,gBAAgB,KAAA;GAChB,gBAAgB,KAAA;GAGhB,UAAU;GACV,MAAM,IAAI;GACV;GACA,gBAAgB,SAAS,OAAO;GAChC,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;GAElC,GAAI,IAAI,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,gBAAgB,IAAI,aAAa;GAC7E,WAAW,UAAyC;IAGlD,IAAI,UAAU;IACd,MAAM,cAAc,MAAM;IAC1B,qBACE,mBACM,IAAI,OAAO,OAAO,CAAC,SAAS,WAAW,GAC7C,oBACF;GACF;EACF;CACF,CAAC;CAED,OAAO,sBAAsB,sBAAsB,YAAY,OAAO;AACxE;AAEA,kBAAkB,cAAc"}
@@ -87,12 +87,15 @@ export interface CheckboxGroupRootProps extends Omit<ComponentPropsWithRef<"fiel
87
87
  * (design/components/checkbox-group.md 14.3). Carries `data-pending` while `valueChangeAction`
88
88
  * is in flight. Its implicit role is `group`; no `role` is written.
89
89
  *
90
- * Owned keys (conventions 1.2): `disabled`, `form`, `data-pending`, `data-disabled`.
90
+ * Owned keys (conventions 1.2): `disabled`, `form`, `data-pending`, `data-disabled`; inside a
91
+ * `Field.Root` also `aria-labelledby` (→ `Field.Label`, token-merged), `aria-describedby`
92
+ * (token-merged), `aria-invalid` and `data-invalid`, and `name` / `required` / `disabled` default
93
+ * from the Field.
91
94
  *
92
95
  * Unlike RadioGroup, Items may hydrate after their Root (a Suspense boundary between them): a
93
96
  * click before an Item hydrated is reconciled when it does.
94
97
  */
95
- export declare function CheckboxGroupRoot({ value, defaultValue, valueChangeAction, name: nameProp, form, required, disabled, className, style, children, render, ...rest }: CheckboxGroupRootProps): import("react").JSX.Element;
98
+ export declare function CheckboxGroupRoot({ value, defaultValue, valueChangeAction, name: nameProp, form, required: requiredProp, disabled: disabledProp, className, style, children, render, ...rest }: CheckboxGroupRootProps): import("react").JSX.Element;
96
99
  export declare namespace CheckboxGroupRoot {
97
100
  var displayName: string;
98
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-group-root.d.mts","names":[],"sources":["../../src/checkbox-group/checkbox-group-root.tsx"],"mappings":";;;;iBA8BiB,wCAAwC;;;;;;;WAO9C,QAAQ;;WAER;;WAEA;;iBAGM;;;;;;;;WAQN;;WAEA;;WAEA;;iBAGM,+BAA+B,KAC9C;;;;;;;;;EAkBA;;;;;EAKA;;;;;;;;;;;;;;EAcA,oBAAoB,uBAAuB;;;;;EAK3C;;EAEA;;;;;;;;EAQA;;EAEA;EACA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,mCAAmC;;;;;;;;;;;;;wBAoFzC,oBACd,OACA,cACA,mBACA,MAAM,UACN,MACA,UACA,UACA,WACA,OACA,UACA,WACG,QACF,yCAAsB,IAAA;yBAbT"}
1
+ {"version":3,"file":"checkbox-group-root.d.mts","names":[],"sources":["../../src/checkbox-group/checkbox-group-root.tsx"],"mappings":";;;;iBAmCiB,wCAAwC;;;;;;;WAO9C,QAAQ;;WAER;;WAEA;;iBAGM;;;;;;;;WAQN;;WAEA;;WAEA;;iBAGM,+BAA+B,KAC9C;;;;;;;;;EAkBA;;;;;EAKA;;;;;;;;;;;;;;EAcA,oBAAoB,uBAAuB;;;;;EAK3C;;EAEA;;;;;;;;EAQA;;EAEA;EACA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,mCAAmC;;;;;;;;;;;;;;;;wBAuFzC,oBACd,OACA,cACA,mBACA,MAAM,UACN,MACA,UAAU,cACV,UAAU,cACV,WACA,OACA,UACA,WACG,QACF,yCAAsB,IAAA;yBAbT"}
@@ -4,6 +4,7 @@ import { dataAttr } from "../internal/data-attr.mjs";
4
4
  import { transitionTypes } from "../internal/transition-types.mjs";
5
5
  import { useControllableAction } from "../internal/use-controllable-action.mjs";
6
6
  import { useRender } from "../internal/use-render.mjs";
7
+ import { useFieldControl, useFieldValueChange, useMergedRef } from "../internal/use-field-control.mjs";
7
8
  import { useNativeGroupReconciliation } from "../internal/use-native-group-reconciliation.mjs";
8
9
  import { CheckboxGroupContext, enabledValues } from "./checkbox-group-context.mjs";
9
10
  import { useCallback, useEffectEvent, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
@@ -67,14 +68,26 @@ function readItems(fieldset, name) {
67
68
  * (design/components/checkbox-group.md 14.3). Carries `data-pending` while `valueChangeAction`
68
69
  * is in flight. Its implicit role is `group`; no `role` is written.
69
70
  *
70
- * Owned keys (conventions 1.2): `disabled`, `form`, `data-pending`, `data-disabled`.
71
+ * Owned keys (conventions 1.2): `disabled`, `form`, `data-pending`, `data-disabled`; inside a
72
+ * `Field.Root` also `aria-labelledby` (→ `Field.Label`, token-merged), `aria-describedby`
73
+ * (token-merged), `aria-invalid` and `data-invalid`, and `name` / `required` / `disabled` default
74
+ * from the Field.
71
75
  *
72
76
  * Unlike RadioGroup, Items may hydrate after their Root (a Suspense boundary between them): a
73
77
  * click before an Item hydrated is reconciled when it does.
74
78
  */
75
- function CheckboxGroupRoot({ value, defaultValue, valueChangeAction, name: nameProp, form, required = false, disabled = false, className, style, children, render, ...rest }) {
79
+ function CheckboxGroupRoot({ value, defaultValue, valueChangeAction, name: nameProp, form, required: requiredProp, disabled: disabledProp, className, style, children, render, ...rest }) {
80
+ const field = useFieldControl({
81
+ labelable: false,
82
+ name: nameProp,
83
+ disabled: disabledProp,
84
+ required: requiredProp,
85
+ component: "CheckboxGroup.Root"
86
+ });
87
+ const required = field.required;
88
+ const disabled = field.disabled;
76
89
  const fallbackName = useId();
77
- const name = nameProp ?? fallbackName;
90
+ const name = field.name ?? fallbackName;
78
91
  const fieldsetRef = useRef(null);
79
92
  const warnedElement = useRef(false);
80
93
  const warnedDuplicate = useRef(false);
@@ -219,10 +232,15 @@ function CheckboxGroupRoot({ value, defaultValue, valueChangeAction, name: nameP
219
232
  fieldsetRef.current = null;
220
233
  };
221
234
  }, []);
235
+ const rootRef = useMergedRef(libraryRef, field.ref);
236
+ const itemsRequired = required && (items === null ? optimistic.size === 0 : ![...optimistic].some((v) => items.get(v) === true));
237
+ useFieldValueChange(`${[...optimistic].sort().join("\0")}|${String(itemsRequired)}`);
238
+ const { "aria-invalid": fieldInvalid, ...groupAttributes } = field.attributes;
222
239
  const context = {
223
240
  name,
224
241
  form,
225
- required: required && (items === null ? optimistic.size === 0 : ![...optimistic].some((v) => items.get(v) === true)),
242
+ fieldInvalid,
243
+ required: itemsRequired,
226
244
  disabledItems,
227
245
  registerItem,
228
246
  optimistic,
@@ -272,12 +290,13 @@ function CheckboxGroupRoot({ value, defaultValue, valueChangeAction, name: nameP
272
290
  children,
273
291
  props: rest,
274
292
  libraryProps: {
293
+ ...groupAttributes,
275
294
  disabled,
276
295
  form,
277
296
  "data-pending": dataAttr(pending),
278
297
  "data-disabled": dataAttr(disabled)
279
298
  },
280
- ref: libraryRef
299
+ ref: rootRef
281
300
  });
282
301
  return /* @__PURE__ */ jsx(CheckboxGroupContext, {
283
302
  value: context,
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-group-root.mjs","names":[],"sources":["../../src/checkbox-group/checkbox-group-root.tsx"],"sourcesContent":["\"use client\";\nimport {\n useCallback,\n useEffectEvent,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport { createActionDetails } from \"../internal/action-details.js\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport { transitionTypes } from \"../internal/transition-types.js\";\nimport type {\n ActionDetails,\n ChangeAction,\n ChangeReason,\n RenderProp,\n StateValue,\n} from \"../internal/types.js\";\nimport { useControllableAction } from \"../internal/use-controllable-action.js\";\nimport { useNativeGroupReconciliation } from \"../internal/use-native-group-reconciliation.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { CheckboxGroupContext, enabledValues } from \"./checkbox-group-context.js\";\nimport type { CheckboxGroupContextValue, CheckboxGroupPatch } from \"./checkbox-group-context.js\";\n\nconst isDev = process.env.NODE_ENV !== \"production\";\n\n/** Details passed as the second argument of `valueChangeAction`. */\nexport interface CheckboxGroupValueChangeDetails extends ActionDetails {\n /**\n * `\"activate\"`: the user toggled an Item or a Parent (click, Space, label click; `event` is the\n * native `click`). `\"platform\"`: the browser changed the checked boxes itself: a form reset\n * (`event` is the `reset` event), or clicks before hydration / Firefox form-state restoration\n * found at mount (`event` is `undefined`).\n */\n readonly reason: ChangeReason;\n /** Values this dispatch checked, in document order of their Items (values with no Item last). */\n readonly added: readonly string[];\n /** Values this dispatch unchecked, same order. */\n readonly removed: readonly string[];\n}\n\nexport interface CheckboxGroupRootState {\n /**\n * Optimistic checked values, in document order of the Items as of the Root's last render\n * (values with no Item last). Items reordered by a component that re-renders without the Root\n * keep the previous order here until the Root renders again; `next` and `details` of\n * `valueChangeAction` always read the current DOM order. The server render and the first client\n * render use the value's own order. Content rendered from it must not suspend.\n */\n readonly value: readonly string[];\n /** An action dispatched through this group is in flight. */\n readonly pending: boolean;\n /** The `disabled` prop. */\n readonly disabled: boolean;\n}\n\nexport interface CheckboxGroupRootProps extends Omit<\n ComponentPropsWithRef<\"fieldset\">,\n | \"className\"\n | \"style\"\n | \"children\"\n | \"defaultValue\"\n | \"defaultChecked\"\n | \"name\"\n | \"disabled\"\n | \"form\"\n> {\n /**\n * Controlled checked values. `[]` checks nothing; `undefined` means uncontrolled. Order is not\n * significant and duplicates are ignored: the value is a set.\n *\n * A form reset returns each box to the `checked` it had when *that box* mounted (React sets\n * `defaultChecked` once, from the initial `checked`). The reset is offered to\n * `valueChangeAction` as a `\"platform\"` change; for a stable target use `defaultValue`.\n */\n value?: string[];\n /**\n * Initial values in uncontrolled mode. Defaults to `[]`. Also the values a form reset returns\n * to: the latest prop value is mirrored into the boxes' `defaultChecked`.\n */\n defaultValue?: string[];\n /**\n * Runs inside the Root's transition whenever the set of checked values changes. May be sync\n * or async (also a Server Function); rejections reach the nearest Error Boundary and roll the\n * change back.\n *\n * `next` is the whole set as a fresh array in document order of the Items; treat it as a set.\n * `details.added` / `details.removed` say what changed. When controlled and updating after\n * your own `await`, prefer a functional update keyed by `added` / `removed` over\n * `setValue(next)`: two overlapping actions completing out of order would otherwise land the\n * older whole set last. A `setState` placed after your own `await` is not a Transition update;\n * wrap it in `startTransition` (React limitation). `details.event.preventDefault()` is not a\n * veto; use controlled mode to veto a change.\n */\n valueChangeAction?: ChangeAction<string[], CheckboxGroupValueChangeDetails>;\n /**\n * The `name` shared by every Item (form data key: `formData.getAll(name)`). Defaults to a\n * `useId()` value; pass a real name when the group is inside a `<form>` you submit.\n */\n name?: string;\n /** The `form` attribute, applied to the fieldset and to every Item. */\n form?: string;\n /**\n * \"At least one Item must be checked.\" Rendered as native `required` on every Item while no\n * enabled Item is checked, and on none once one is: values with no Item and checked disabled\n * Items (neither is submitted) do not satisfy it. Until the Items have mounted (server HTML,\n * before hydration) any checked value satisfies it. Not exposed on the fieldset (ARIA does not\n * allow `aria-required` on role `group`): say it in the `Label` or through `aria-describedby`.\n */\n required?: boolean;\n /** Renders `<fieldset disabled>`: every Item and Parent is disabled and unfocusable. */\n disabled?: boolean;\n className?: StateValue<string | undefined, CheckboxGroupRootState>;\n style?: StateValue<CSSProperties | undefined, CheckboxGroupRootState>;\n children?: StateValue<ReactNode, CheckboxGroupRootState>;\n /** Replace the rendered element. Must keep a `<fieldset>`. */\n render?: RenderProp<ComponentPropsWithRef<\"fieldset\">, CheckboxGroupRootState>;\n}\n\ntype ValueSet = ReadonlySet<string>;\n\nconst EMPTY: ValueSet = new Set();\n\nfunction toSet(value: readonly string[]): ValueSet {\n return new Set(value);\n}\n\nfunction setsEqual(a: ValueSet, b: ValueSet): boolean {\n if (a.size !== b.size) return false;\n for (const v of a) if (!b.has(v)) return false;\n return true;\n}\n\n/** The optimistic reducer (design 5.2): apply a patch, so stacked dispatches re-base. */\nfunction reduce(set: ValueSet, patch: CheckboxGroupPatch): ValueSet {\n const next = new Set(set);\n for (const v of patch.removed) next.delete(v);\n for (const v of patch.added) next.add(v);\n return next;\n}\n\n/**\n * `values` sorted by `order` (the Items' values in document order); values not in `order` keep\n * their iteration order, after the others.\n */\nfunction sortByOrder(values: Iterable<string>, order: readonly string[]): string[] {\n const wanted = new Set(values);\n const sorted: string[] = [];\n for (const v of order) if (wanted.delete(v)) sorted.push(v);\n for (const v of wanted) sorted.push(v);\n return sorted;\n}\n\n/** Value → \"has an Item without its own `disabled`\", over the registered Items. */\ntype ItemRegistry = Map<object, { readonly value: string; readonly disabled: boolean }>;\n\nfunction summarize(registry: ItemRegistry): Map<string, boolean> {\n const items = new Map<string, boolean>();\n for (const { value, disabled } of registry.values()) {\n items.set(value, (items.get(value) ?? false) || !disabled);\n }\n return items;\n}\n\nfunction disabledOf(items: ReadonlyMap<string, boolean> | null): ValueSet {\n if (items === null) return EMPTY;\n const disabled = new Set<string>();\n for (const [value, enabled] of items) if (!enabled) disabled.add(value);\n return disabled.size === 0 ? EMPTY : disabled;\n}\n\nfunction mapsEqual(a: ReadonlyMap<string, boolean>, b: ReadonlyMap<string, boolean>): boolean {\n if (a.size !== b.size) return false;\n for (const [k, v] of a) if (b.get(k) !== v) return false;\n return true;\n}\n\nfunction arraysEqual(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n}\n\n/** The group's Items: checkboxes of this `name` in the fieldset (Parents have none). */\nfunction readItems(fieldset: HTMLFieldSetElement | null, name: string): HTMLInputElement[] {\n if (fieldset === null) return [];\n return [...fieldset.querySelectorAll<HTMLInputElement>('input[type=\"checkbox\"]')].filter(\n (box) => box.name === name,\n );\n}\n\n/**\n * `<fieldset>` that owns the group's state (a set of values), the transition, the shared `name`,\n * the form-reset listener, the mount reconciliation and the group-level `required`\n * (design/components/checkbox-group.md 14.3). Carries `data-pending` while `valueChangeAction`\n * is in flight. Its implicit role is `group`; no `role` is written.\n *\n * Owned keys (conventions 1.2): `disabled`, `form`, `data-pending`, `data-disabled`.\n *\n * Unlike RadioGroup, Items may hydrate after their Root (a Suspense boundary between them): a\n * click before an Item hydrated is reconciled when it does.\n */\nexport function CheckboxGroupRoot({\n value,\n defaultValue,\n valueChangeAction,\n name: nameProp,\n form,\n required = false,\n disabled = false,\n className,\n style,\n children,\n render,\n ...rest\n}: CheckboxGroupRootProps) {\n const fallbackName = useId();\n const name = nameProp ?? fallbackName;\n const fieldsetRef = useRef<HTMLFieldSetElement | null>(null);\n const warnedElement = useRef(false);\n const warnedDuplicate = useRef(false);\n /** Parent reports waiting for the next mount read (design 8.1). */\n const parentReports = useRef<{ values: readonly string[]; checked: boolean }[]>([]);\n\n // Item registration (design 6.2, 7): each Item reports its value and own `disabled` from a\n // layout effect. The ref is current for the residual-path reads; the state, set only when the\n // summary changes, is what render uses. `null` until an Item registered, so the server render\n // and the hydration render (which cannot know) agree.\n const itemRegistry = useRef<ItemRegistry>(new Map());\n const [items, setItems] = useState<ReadonlyMap<string, boolean> | null>(null);\n const registerItem = useCallback((value: string, disabled: boolean) => {\n const publish = () => {\n const next = summarize(itemRegistry.current);\n setItems((prev) => (prev !== null && mapsEqual(prev, next) ? prev : next));\n };\n const token = {};\n itemRegistry.current.set(token, { value, disabled });\n publish();\n return () => {\n itemRegistry.current.delete(token);\n publish();\n };\n }, []);\n const disabledItems = useMemo(() => disabledOf(items), [items]);\n\n const controlledSet = useMemo(() => (value === undefined ? undefined : toSet(value)), [value]);\n const defaultSet = useMemo(\n () => (defaultValue === undefined ? undefined : toSet(defaultValue)),\n [defaultValue],\n );\n\n /** Sorts by the Items' current document order. Reads the DOM: handlers and effects only. */\n const sortByDocument = (values: Iterable<string>): string[] =>\n sortByOrder(\n values,\n readItems(fieldsetRef.current, name).map((item) => item.value),\n );\n\n const { optimistic, committed, pending, dispatch, latestInFlight } = useControllableAction<\n ValueSet,\n CheckboxGroupValueChangeDetails\n >({\n controlled: controlledSet,\n defaultValue: defaultSet,\n initialValue: EMPTY,\n action:\n valueChangeAction && ((next, details) => valueChangeAction(sortByDocument(next), details)),\n transitionTypes: (_next, _prev, details) => [\n ...transitionTypes(\"checkbox-group\"),\n ...(details.added.length > 0 ? [\"fsui-checkbox-group-check\"] : []),\n ...(details.removed.length > 0 ? [\"fsui-checkbox-group-uncheck\"] : []),\n ],\n reducer: (prev, _next, details) => reduce(prev, details),\n warn: { component: \"CheckboxGroup.Root\", prop: \"value\" },\n });\n // Deliberately no warning when neither `value` nor `defaultValue` is given: an empty group is\n // the HTML default (design 3.1).\n\n /** What the user intends: the latest in-flight dispatch, else optimistic (conventions 3.8 rule 1). */\n const base = (): ValueSet => {\n const inFlight = latestInFlight();\n return inFlight === null ? optimistic : inFlight.next;\n };\n\n /** Dispatches `patch` on top of `from`, with the details of design 3.1. */\n const dispatchPatch = (\n from: ValueSet,\n patch: CheckboxGroupPatch,\n reason: ChangeReason,\n event: Event | undefined,\n ): void => {\n const details = createActionDetails(event, {\n reason,\n added: sortByDocument(patch.added),\n removed: sortByDocument(patch.removed),\n });\n dispatch(reduce(from, details), details);\n };\n\n /**\n * The group as the DOM shows it (`checked`) or as a form reset leaves it (`defaultChecked`),\n * laid over `base()` so that values with no Item are kept (they have no DOM to read).\n */\n const readDom = (prop: \"checked\" | \"defaultChecked\"): Map<string, boolean> =>\n new Map(readItems(fieldsetRef.current, name).map((item) => [item.value, item[prop]]));\n const readGroup = (\n prop: \"checked\" | \"defaultChecked\",\n from: ValueSet,\n dom: ReadonlyMap<string, boolean> = readDom(prop),\n ): Set<string> => {\n const next = new Set(from);\n for (const [v, isChecked] of dom) {\n if (isChecked) next.add(v);\n else next.delete(v);\n }\n return next;\n };\n\n /**\n * The Root's own mount reconciliation ran: later member mounts are \"late\" (8.3). Set after the\n * adapter's mount effect; reset by the cleanup (StrictMode included).\n */\n const rootMounted = useRef(false);\n /**\n * Late mounts: the members' `checked` read in the first late member's mount layout effect. The\n * adapter reads the group in a microtask, but the Items' registration re-renders the group\n * right after the layout effects, and that re-render re-applies each Item's `checked`, erasing a\n * click made before the Item hydrated. Every member of the commit is in the DOM by then.\n */\n const lateSnapshot = useRef<Map<string, boolean> | null>(null);\n\n // The residual browser paths (design section 8): one dispatch per group, from here. Items and\n // Parents that mount after the Root report through `onItemMounted`.\n const { onItemMounted: onMemberMounted } = useNativeGroupReconciliation<ValueSet>({\n element: fieldsetRef,\n readCurrent: () => {\n const next = readGroup(\"checked\", base(), lateSnapshot.current ?? undefined);\n lateSnapshot.current = null;\n // A Parent clicked before hydration means what its click means: check / uncheck all of its\n // values whose Items are enabled (8.1, 6.2). Read from the registry ref: the Items of this\n // commit registered before this runs, and render has not caught up yet.\n const disabledNow = disabledOf(summarize(itemRegistry.current));\n for (const report of parentReports.current) {\n for (const v of enabledValues(report.values, disabledNow)) {\n if (report.checked) next.add(v);\n else next.delete(v);\n }\n }\n parentReports.current = [];\n return next;\n },\n // Uncontrolled: start from `defaultValue`, so values with no Item return to it too (they have\n // no `defaultChecked` to read). Controlled: from `base()`, as for the mount read; the parent\n // decides.\n readDefault: () =>\n readGroup(\"defaultChecked\", value === undefined ? (defaultSet ?? EMPTY) : base()),\n base,\n equals: setsEqual,\n onPlatformChange: (next, event) => {\n const from = base();\n const added = [...next].filter((v) => !from.has(v));\n const removed = [...from].filter((v) => !next.has(v));\n dispatchPatch(from, { added, removed }, \"platform\", event);\n },\n });\n\n useLayoutEffect(() => {\n rootMounted.current = true;\n return () => {\n rootMounted.current = false;\n };\n }, []);\n const onItemMounted = (el: HTMLInputElement | null) => {\n const late = rootMounted.current;\n if (late && lateSnapshot.current === null) lateSnapshot.current = readDom(\"checked\");\n onMemberMounted(el);\n // A snapshot the adapter did not consume (it queues one read per commit, before this).\n if (late) {\n queueMicrotask(() => {\n lateSnapshot.current = null;\n });\n }\n };\n\n // The state's `value` is in document order. Render cannot read the DOM, so the Items' order is\n // kept in state, refreshed after a commit only when the rendered `value` would change (a value\n // given out of document order, Items reordered or added). The first render, and the server,\n // use the value's own order.\n const [itemOrder, setItemOrder] = useState<readonly string[]>([]);\n const renderedValue = sortByOrder(optimistic, itemOrder);\n // After every commit of the Root (a deps-less layout effect runs only when the Root itself\n // committed: Items moved by a child that re-renders alone are picked up at the Root's next\n // render). The comparison ends the chain: the re-render it causes renders exactly the value\n // just compared against.\n const syncItemOrder = useEffectEvent(() => {\n const order = readItems(fieldsetRef.current, name).map((item) => item.value);\n if (!arraysEqual(sortByOrder(optimistic, order), renderedValue)) setItemOrder(order);\n\n // Dev only: Item values must be unique within the Root (design 14.6).\n if (!isDev || warnedDuplicate.current) return;\n const duplicate = order.find((v, i) => order.indexOf(v) !== i);\n if (duplicate !== undefined) {\n warnedDuplicate.current = true;\n console.error(\n `CheckboxGroup.Item: two Items share the value \"${duplicate}\" in one ` +\n `CheckboxGroup.Root. Item values must be unique; both boxes follow the same value.`,\n );\n }\n });\n useLayoutEffect(() => {\n syncItemOrder();\n });\n\n const libraryRef = useCallback((el: HTMLFieldSetElement) => {\n fieldsetRef.current = el;\n if (isDev && !warnedElement.current && el.tagName !== \"FIELDSET\") {\n warnedElement.current = true;\n console.error(\n `CheckboxGroup.Root: expected to render a <fieldset> element but got ` +\n `<${el.tagName.toLowerCase()}>. The platform semantics (legend naming, disabled ` +\n `inheritance, form reset) need a real <fieldset>.`,\n );\n }\n return () => {\n fieldsetRef.current = null;\n };\n }, []);\n\n const context: CheckboxGroupContextValue = {\n name,\n form,\n required:\n required &&\n (items === null\n ? optimistic.size === 0\n : ![...optimistic].some((v) => items.get(v) === true)),\n disabledItems,\n registerItem,\n optimistic,\n committed,\n pending,\n disabled,\n defaultValue: value === undefined ? (defaultSet ?? EMPTY) : undefined,\n onItemMounted,\n reportParent: (values, checked) => {\n parentReports.current.push({ values, checked });\n },\n value: renderedValue,\n sortByDocument,\n toggle: (item, checked, event) => {\n // No-op rule against the optimistic set (conventions 2.3 item 8).\n if (optimistic.has(item) === checked) return;\n const patch = checked ? { added: [item], removed: [] } : { added: [], removed: [item] };\n dispatchPatch(optimistic, patch, \"activate\", event);\n },\n apply: (patch, event) => {\n const added = patch.added.filter((v) => !optimistic.has(v));\n const removed = patch.removed.filter((v) => optimistic.has(v));\n if (added.length === 0 && removed.length === 0) return;\n dispatchPatch(optimistic, { added, removed }, \"activate\", event);\n },\n };\n\n const state: CheckboxGroupRootState = {\n value: renderedValue,\n pending,\n disabled,\n };\n\n const element = useRender<ComponentPropsWithRef<\"fieldset\">, CheckboxGroupRootState>({\n defaultElement: \"fieldset\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n libraryProps: {\n disabled,\n form,\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n },\n ref: libraryRef,\n });\n\n return <CheckboxGroupContext value={context}>{element}</CheckboxGroupContext>;\n}\n\nCheckboxGroupRoot.displayName = \"CheckboxGroupRoot\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"checkbox-group-root.mjs","names":[],"sources":["../../src/checkbox-group/checkbox-group-root.tsx"],"sourcesContent":["\"use client\";\nimport {\n useCallback,\n useEffectEvent,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport { createActionDetails } from \"../internal/action-details.js\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport { transitionTypes } from \"../internal/transition-types.js\";\nimport type {\n ActionDetails,\n ChangeAction,\n ChangeReason,\n RenderProp,\n StateValue,\n} from \"../internal/types.js\";\nimport { useControllableAction } from \"../internal/use-controllable-action.js\";\nimport { useNativeGroupReconciliation } from \"../internal/use-native-group-reconciliation.js\";\nimport {\n useFieldControl,\n useFieldValueChange,\n useMergedRef,\n} from \"../internal/use-field-control.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { CheckboxGroupContext, enabledValues } from \"./checkbox-group-context.js\";\nimport type { CheckboxGroupContextValue, CheckboxGroupPatch } from \"./checkbox-group-context.js\";\n\nconst isDev = process.env.NODE_ENV !== \"production\";\n\n/** Details passed as the second argument of `valueChangeAction`. */\nexport interface CheckboxGroupValueChangeDetails extends ActionDetails {\n /**\n * `\"activate\"`: the user toggled an Item or a Parent (click, Space, label click; `event` is the\n * native `click`). `\"platform\"`: the browser changed the checked boxes itself: a form reset\n * (`event` is the `reset` event), or clicks before hydration / Firefox form-state restoration\n * found at mount (`event` is `undefined`).\n */\n readonly reason: ChangeReason;\n /** Values this dispatch checked, in document order of their Items (values with no Item last). */\n readonly added: readonly string[];\n /** Values this dispatch unchecked, same order. */\n readonly removed: readonly string[];\n}\n\nexport interface CheckboxGroupRootState {\n /**\n * Optimistic checked values, in document order of the Items as of the Root's last render\n * (values with no Item last). Items reordered by a component that re-renders without the Root\n * keep the previous order here until the Root renders again; `next` and `details` of\n * `valueChangeAction` always read the current DOM order. The server render and the first client\n * render use the value's own order. Content rendered from it must not suspend.\n */\n readonly value: readonly string[];\n /** An action dispatched through this group is in flight. */\n readonly pending: boolean;\n /** The `disabled` prop. */\n readonly disabled: boolean;\n}\n\nexport interface CheckboxGroupRootProps extends Omit<\n ComponentPropsWithRef<\"fieldset\">,\n | \"className\"\n | \"style\"\n | \"children\"\n | \"defaultValue\"\n | \"defaultChecked\"\n | \"name\"\n | \"disabled\"\n | \"form\"\n> {\n /**\n * Controlled checked values. `[]` checks nothing; `undefined` means uncontrolled. Order is not\n * significant and duplicates are ignored: the value is a set.\n *\n * A form reset returns each box to the `checked` it had when *that box* mounted (React sets\n * `defaultChecked` once, from the initial `checked`). The reset is offered to\n * `valueChangeAction` as a `\"platform\"` change; for a stable target use `defaultValue`.\n */\n value?: string[];\n /**\n * Initial values in uncontrolled mode. Defaults to `[]`. Also the values a form reset returns\n * to: the latest prop value is mirrored into the boxes' `defaultChecked`.\n */\n defaultValue?: string[];\n /**\n * Runs inside the Root's transition whenever the set of checked values changes. May be sync\n * or async (also a Server Function); rejections reach the nearest Error Boundary and roll the\n * change back.\n *\n * `next` is the whole set as a fresh array in document order of the Items; treat it as a set.\n * `details.added` / `details.removed` say what changed. When controlled and updating after\n * your own `await`, prefer a functional update keyed by `added` / `removed` over\n * `setValue(next)`: two overlapping actions completing out of order would otherwise land the\n * older whole set last. A `setState` placed after your own `await` is not a Transition update;\n * wrap it in `startTransition` (React limitation). `details.event.preventDefault()` is not a\n * veto; use controlled mode to veto a change.\n */\n valueChangeAction?: ChangeAction<string[], CheckboxGroupValueChangeDetails>;\n /**\n * The `name` shared by every Item (form data key: `formData.getAll(name)`). Defaults to a\n * `useId()` value; pass a real name when the group is inside a `<form>` you submit.\n */\n name?: string;\n /** The `form` attribute, applied to the fieldset and to every Item. */\n form?: string;\n /**\n * \"At least one Item must be checked.\" Rendered as native `required` on every Item while no\n * enabled Item is checked, and on none once one is: values with no Item and checked disabled\n * Items (neither is submitted) do not satisfy it. Until the Items have mounted (server HTML,\n * before hydration) any checked value satisfies it. Not exposed on the fieldset (ARIA does not\n * allow `aria-required` on role `group`): say it in the `Label` or through `aria-describedby`.\n */\n required?: boolean;\n /** Renders `<fieldset disabled>`: every Item and Parent is disabled and unfocusable. */\n disabled?: boolean;\n className?: StateValue<string | undefined, CheckboxGroupRootState>;\n style?: StateValue<CSSProperties | undefined, CheckboxGroupRootState>;\n children?: StateValue<ReactNode, CheckboxGroupRootState>;\n /** Replace the rendered element. Must keep a `<fieldset>`. */\n render?: RenderProp<ComponentPropsWithRef<\"fieldset\">, CheckboxGroupRootState>;\n}\n\ntype ValueSet = ReadonlySet<string>;\n\nconst EMPTY: ValueSet = new Set();\n\nfunction toSet(value: readonly string[]): ValueSet {\n return new Set(value);\n}\n\nfunction setsEqual(a: ValueSet, b: ValueSet): boolean {\n if (a.size !== b.size) return false;\n for (const v of a) if (!b.has(v)) return false;\n return true;\n}\n\n/** The optimistic reducer (design 5.2): apply a patch, so stacked dispatches re-base. */\nfunction reduce(set: ValueSet, patch: CheckboxGroupPatch): ValueSet {\n const next = new Set(set);\n for (const v of patch.removed) next.delete(v);\n for (const v of patch.added) next.add(v);\n return next;\n}\n\n/**\n * `values` sorted by `order` (the Items' values in document order); values not in `order` keep\n * their iteration order, after the others.\n */\nfunction sortByOrder(values: Iterable<string>, order: readonly string[]): string[] {\n const wanted = new Set(values);\n const sorted: string[] = [];\n for (const v of order) if (wanted.delete(v)) sorted.push(v);\n for (const v of wanted) sorted.push(v);\n return sorted;\n}\n\n/** Value → \"has an Item without its own `disabled`\", over the registered Items. */\ntype ItemRegistry = Map<object, { readonly value: string; readonly disabled: boolean }>;\n\nfunction summarize(registry: ItemRegistry): Map<string, boolean> {\n const items = new Map<string, boolean>();\n for (const { value, disabled } of registry.values()) {\n items.set(value, (items.get(value) ?? false) || !disabled);\n }\n return items;\n}\n\nfunction disabledOf(items: ReadonlyMap<string, boolean> | null): ValueSet {\n if (items === null) return EMPTY;\n const disabled = new Set<string>();\n for (const [value, enabled] of items) if (!enabled) disabled.add(value);\n return disabled.size === 0 ? EMPTY : disabled;\n}\n\nfunction mapsEqual(a: ReadonlyMap<string, boolean>, b: ReadonlyMap<string, boolean>): boolean {\n if (a.size !== b.size) return false;\n for (const [k, v] of a) if (b.get(k) !== v) return false;\n return true;\n}\n\nfunction arraysEqual(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((v, i) => v === b[i]);\n}\n\n/** The group's Items: checkboxes of this `name` in the fieldset (Parents have none). */\nfunction readItems(fieldset: HTMLFieldSetElement | null, name: string): HTMLInputElement[] {\n if (fieldset === null) return [];\n return [...fieldset.querySelectorAll<HTMLInputElement>('input[type=\"checkbox\"]')].filter(\n (box) => box.name === name,\n );\n}\n\n/**\n * `<fieldset>` that owns the group's state (a set of values), the transition, the shared `name`,\n * the form-reset listener, the mount reconciliation and the group-level `required`\n * (design/components/checkbox-group.md 14.3). Carries `data-pending` while `valueChangeAction`\n * is in flight. Its implicit role is `group`; no `role` is written.\n *\n * Owned keys (conventions 1.2): `disabled`, `form`, `data-pending`, `data-disabled`; inside a\n * `Field.Root` also `aria-labelledby` (→ `Field.Label`, token-merged), `aria-describedby`\n * (token-merged), `aria-invalid` and `data-invalid`, and `name` / `required` / `disabled` default\n * from the Field.\n *\n * Unlike RadioGroup, Items may hydrate after their Root (a Suspense boundary between them): a\n * click before an Item hydrated is reconciled when it does.\n */\nexport function CheckboxGroupRoot({\n value,\n defaultValue,\n valueChangeAction,\n name: nameProp,\n form,\n required: requiredProp,\n disabled: disabledProp,\n className,\n style,\n children,\n render,\n ...rest\n}: CheckboxGroupRootProps) {\n // Inside a Field.Root (design/components/field-form.md 7.2) the fieldset is the Field's group\n // control: `aria-labelledby` → `Field.Label`, the ARIA wiring, and `name` / `required` (\"at\n // least one\") / `disabled` defaulting from the Field.\n const field = useFieldControl({\n labelable: false,\n name: nameProp,\n disabled: disabledProp,\n required: requiredProp,\n component: \"CheckboxGroup.Root\",\n });\n const required = field.required;\n const disabled = field.disabled;\n const fallbackName = useId();\n const name = field.name ?? fallbackName;\n const fieldsetRef = useRef<HTMLFieldSetElement | null>(null);\n const warnedElement = useRef(false);\n const warnedDuplicate = useRef(false);\n /** Parent reports waiting for the next mount read (design 8.1). */\n const parentReports = useRef<{ values: readonly string[]; checked: boolean }[]>([]);\n\n // Item registration (design 6.2, 7): each Item reports its value and own `disabled` from a\n // layout effect. The ref is current for the residual-path reads; the state, set only when the\n // summary changes, is what render uses. `null` until an Item registered, so the server render\n // and the hydration render (which cannot know) agree.\n const itemRegistry = useRef<ItemRegistry>(new Map());\n const [items, setItems] = useState<ReadonlyMap<string, boolean> | null>(null);\n const registerItem = useCallback((value: string, disabled: boolean) => {\n const publish = () => {\n const next = summarize(itemRegistry.current);\n setItems((prev) => (prev !== null && mapsEqual(prev, next) ? prev : next));\n };\n const token = {};\n itemRegistry.current.set(token, { value, disabled });\n publish();\n return () => {\n itemRegistry.current.delete(token);\n publish();\n };\n }, []);\n const disabledItems = useMemo(() => disabledOf(items), [items]);\n\n const controlledSet = useMemo(() => (value === undefined ? undefined : toSet(value)), [value]);\n const defaultSet = useMemo(\n () => (defaultValue === undefined ? undefined : toSet(defaultValue)),\n [defaultValue],\n );\n\n /** Sorts by the Items' current document order. Reads the DOM: handlers and effects only. */\n const sortByDocument = (values: Iterable<string>): string[] =>\n sortByOrder(\n values,\n readItems(fieldsetRef.current, name).map((item) => item.value),\n );\n\n const { optimistic, committed, pending, dispatch, latestInFlight } = useControllableAction<\n ValueSet,\n CheckboxGroupValueChangeDetails\n >({\n controlled: controlledSet,\n defaultValue: defaultSet,\n initialValue: EMPTY,\n action:\n valueChangeAction && ((next, details) => valueChangeAction(sortByDocument(next), details)),\n transitionTypes: (_next, _prev, details) => [\n ...transitionTypes(\"checkbox-group\"),\n ...(details.added.length > 0 ? [\"fsui-checkbox-group-check\"] : []),\n ...(details.removed.length > 0 ? [\"fsui-checkbox-group-uncheck\"] : []),\n ],\n reducer: (prev, _next, details) => reduce(prev, details),\n warn: { component: \"CheckboxGroup.Root\", prop: \"value\" },\n });\n // Deliberately no warning when neither `value` nor `defaultValue` is given: an empty group is\n // the HTML default (design 3.1).\n\n /** What the user intends: the latest in-flight dispatch, else optimistic (conventions 3.8 rule 1). */\n const base = (): ValueSet => {\n const inFlight = latestInFlight();\n return inFlight === null ? optimistic : inFlight.next;\n };\n\n /** Dispatches `patch` on top of `from`, with the details of design 3.1. */\n const dispatchPatch = (\n from: ValueSet,\n patch: CheckboxGroupPatch,\n reason: ChangeReason,\n event: Event | undefined,\n ): void => {\n const details = createActionDetails(event, {\n reason,\n added: sortByDocument(patch.added),\n removed: sortByDocument(patch.removed),\n });\n dispatch(reduce(from, details), details);\n };\n\n /**\n * The group as the DOM shows it (`checked`) or as a form reset leaves it (`defaultChecked`),\n * laid over `base()` so that values with no Item are kept (they have no DOM to read).\n */\n const readDom = (prop: \"checked\" | \"defaultChecked\"): Map<string, boolean> =>\n new Map(readItems(fieldsetRef.current, name).map((item) => [item.value, item[prop]]));\n const readGroup = (\n prop: \"checked\" | \"defaultChecked\",\n from: ValueSet,\n dom: ReadonlyMap<string, boolean> = readDom(prop),\n ): Set<string> => {\n const next = new Set(from);\n for (const [v, isChecked] of dom) {\n if (isChecked) next.add(v);\n else next.delete(v);\n }\n return next;\n };\n\n /**\n * The Root's own mount reconciliation ran: later member mounts are \"late\" (8.3). Set after the\n * adapter's mount effect; reset by the cleanup (StrictMode included).\n */\n const rootMounted = useRef(false);\n /**\n * Late mounts: the members' `checked` read in the first late member's mount layout effect. The\n * adapter reads the group in a microtask, but the Items' registration re-renders the group\n * right after the layout effects, and that re-render re-applies each Item's `checked`, erasing a\n * click made before the Item hydrated. Every member of the commit is in the DOM by then.\n */\n const lateSnapshot = useRef<Map<string, boolean> | null>(null);\n\n // The residual browser paths (design section 8): one dispatch per group, from here. Items and\n // Parents that mount after the Root report through `onItemMounted`.\n const { onItemMounted: onMemberMounted } = useNativeGroupReconciliation<ValueSet>({\n element: fieldsetRef,\n readCurrent: () => {\n const next = readGroup(\"checked\", base(), lateSnapshot.current ?? undefined);\n lateSnapshot.current = null;\n // A Parent clicked before hydration means what its click means: check / uncheck all of its\n // values whose Items are enabled (8.1, 6.2). Read from the registry ref: the Items of this\n // commit registered before this runs, and render has not caught up yet.\n const disabledNow = disabledOf(summarize(itemRegistry.current));\n for (const report of parentReports.current) {\n for (const v of enabledValues(report.values, disabledNow)) {\n if (report.checked) next.add(v);\n else next.delete(v);\n }\n }\n parentReports.current = [];\n return next;\n },\n // Uncontrolled: start from `defaultValue`, so values with no Item return to it too (they have\n // no `defaultChecked` to read). Controlled: from `base()`, as for the mount read; the parent\n // decides.\n readDefault: () =>\n readGroup(\"defaultChecked\", value === undefined ? (defaultSet ?? EMPTY) : base()),\n base,\n equals: setsEqual,\n onPlatformChange: (next, event) => {\n const from = base();\n const added = [...next].filter((v) => !from.has(v));\n const removed = [...from].filter((v) => !next.has(v));\n dispatchPatch(from, { added, removed }, \"platform\", event);\n },\n });\n\n useLayoutEffect(() => {\n rootMounted.current = true;\n return () => {\n rootMounted.current = false;\n };\n }, []);\n const onItemMounted = (el: HTMLInputElement | null) => {\n const late = rootMounted.current;\n if (late && lateSnapshot.current === null) lateSnapshot.current = readDom(\"checked\");\n onMemberMounted(el);\n // A snapshot the adapter did not consume (it queues one read per commit, before this).\n if (late) {\n queueMicrotask(() => {\n lateSnapshot.current = null;\n });\n }\n };\n\n // The state's `value` is in document order. Render cannot read the DOM, so the Items' order is\n // kept in state, refreshed after a commit only when the rendered `value` would change (a value\n // given out of document order, Items reordered or added). The first render, and the server,\n // use the value's own order.\n const [itemOrder, setItemOrder] = useState<readonly string[]>([]);\n const renderedValue = sortByOrder(optimistic, itemOrder);\n // After every commit of the Root (a deps-less layout effect runs only when the Root itself\n // committed: Items moved by a child that re-renders alone are picked up at the Root's next\n // render). The comparison ends the chain: the re-render it causes renders exactly the value\n // just compared against.\n const syncItemOrder = useEffectEvent(() => {\n const order = readItems(fieldsetRef.current, name).map((item) => item.value);\n if (!arraysEqual(sortByOrder(optimistic, order), renderedValue)) setItemOrder(order);\n\n // Dev only: Item values must be unique within the Root (design 14.6).\n if (!isDev || warnedDuplicate.current) return;\n const duplicate = order.find((v, i) => order.indexOf(v) !== i);\n if (duplicate !== undefined) {\n warnedDuplicate.current = true;\n console.error(\n `CheckboxGroup.Item: two Items share the value \"${duplicate}\" in one ` +\n `CheckboxGroup.Root. Item values must be unique; both boxes follow the same value.`,\n );\n }\n });\n useLayoutEffect(() => {\n syncItemOrder();\n });\n\n const libraryRef = useCallback((el: HTMLFieldSetElement) => {\n fieldsetRef.current = el;\n if (isDev && !warnedElement.current && el.tagName !== \"FIELDSET\") {\n warnedElement.current = true;\n console.error(\n `CheckboxGroup.Root: expected to render a <fieldset> element but got ` +\n `<${el.tagName.toLowerCase()}>. The platform semantics (legend naming, disabled ` +\n `inheritance, form reset) need a real <fieldset>.`,\n );\n }\n return () => {\n fieldsetRef.current = null;\n };\n }, []);\n const rootRef = useMergedRef<HTMLFieldSetElement>(libraryRef, field.ref);\n\n const itemsRequired =\n required &&\n (items === null ? optimistic.size === 0 : ![...optimistic].some((v) => items.get(v) === true));\n // Inside a Field: the Items' `checked` and derived `required` are written by React after the\n // click's `change` (a Parent checks Items with no event of their own), so the Field re-reads\n // validity and `validate` after the commit (design/components/field-form.md 7.2).\n useFieldValueChange(`${[...optimistic].sort().join(\"\\u0000\")}|${String(itemsRequired)}`);\n\n // `aria-invalid` is not supported on role `group` (ARIA 1.2 made it widget-specific): inside a\n // Field it goes on every Item (a `checkbox`) instead; the fieldset keeps `data-invalid` and\n // `aria-describedby`, read when focus enters the group.\n const { \"aria-invalid\": fieldInvalid, ...groupAttributes } = field.attributes;\n\n const context: CheckboxGroupContextValue = {\n name,\n form,\n fieldInvalid,\n required: itemsRequired,\n disabledItems,\n registerItem,\n optimistic,\n committed,\n pending,\n disabled,\n defaultValue: value === undefined ? (defaultSet ?? EMPTY) : undefined,\n onItemMounted,\n reportParent: (values, checked) => {\n parentReports.current.push({ values, checked });\n },\n value: renderedValue,\n sortByDocument,\n toggle: (item, checked, event) => {\n // No-op rule against the optimistic set (conventions 2.3 item 8).\n if (optimistic.has(item) === checked) return;\n const patch = checked ? { added: [item], removed: [] } : { added: [], removed: [item] };\n dispatchPatch(optimistic, patch, \"activate\", event);\n },\n apply: (patch, event) => {\n const added = patch.added.filter((v) => !optimistic.has(v));\n const removed = patch.removed.filter((v) => optimistic.has(v));\n if (added.length === 0 && removed.length === 0) return;\n dispatchPatch(optimistic, { added, removed }, \"activate\", event);\n },\n };\n\n const state: CheckboxGroupRootState = {\n value: renderedValue,\n pending,\n disabled,\n };\n\n const element = useRender<ComponentPropsWithRef<\"fieldset\">, CheckboxGroupRootState>({\n defaultElement: \"fieldset\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n libraryProps: {\n ...groupAttributes,\n disabled,\n form,\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n },\n ref: rootRef,\n });\n\n return <CheckboxGroupContext value={context}>{element}</CheckboxGroupContext>;\n}\n\nCheckboxGroupRoot.displayName = \"CheckboxGroupRoot\";\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
3
+ //#region src/combobox/combobox-clear.d.ts
4
+ export interface ComboboxClearState {
5
+ /** Optimistic selection. */
6
+ readonly value: string | null;
7
+ readonly inputValue: string;
8
+ readonly disabled: boolean;
9
+ }
10
+ export interface ComboboxClearProps extends Omit<ComponentPropsWithRef<"button">, "onClick" | "onPointerDown" | "onMouseDown" | "tabIndex" | "disabled" | "className" | "style" | "children"> {
11
+ /** Disables this button; the Root's `disabled` does too. */
12
+ disabled?: boolean;
13
+ className?: StateValue<string | undefined, ComboboxClearState>;
14
+ style?: StateValue<CSSProperties | undefined, ComboboxClearState>;
15
+ children?: StateValue<ReactNode, ComboboxClearState>;
16
+ /** Should render a `<button>`. */
17
+ render?: RenderProp<ComponentPropsWithRef<"button">, ComboboxClearState>;
18
+ }
19
+ /**
20
+ * The optional button that clears the combobox: `<button type="button" tabindex="-1">`. A click
21
+ * empties the text (urgent) and dispatches `valueChangeAction(null)` unless nothing is selected;
22
+ * the input keeps focus. Always rendered: hide it with CSS (`:placeholder-shown`) or `state`.
23
+ * A click while the listbox is open closes it (the platform's light dismiss: the button is
24
+ * outside the popup).
25
+ *
26
+ * Owned keys: `type` (on a `<button>`), `tabIndex`, `disabled`, `onClick`, `onPointerDown`,
27
+ * `onMouseDown`, `data-disabled`.
28
+ */
29
+ export declare function ComboboxClear({ disabled: ownDisabled, className, style, children, render, ...rest }: ComboboxClearProps): ReactNode;
30
+ export declare namespace ComboboxClear {
31
+ var displayName: string;
32
+ }
33
+ //#endregion
34
+ //# sourceMappingURL=combobox-clear.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combobox-clear.d.mts","names":[],"sources":["../../src/combobox/combobox-clear.tsx"],"mappings":";;;iBAeiB;;WAEN;WACA;WACA;;iBAGM,2BAA2B,KAC1C;;EAWA;EACA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,iCAAiC;;;;;;;;;;;;wBAavC,gBACd,UAAU,aACV,WACA,OACA,UACA,WACG,QACF,qBAAkB;yBAPL"}
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { dataAttr } from "../internal/data-attr.mjs";
3
+ import { rendersButton, useRender } from "../internal/use-render.mjs";
4
+ import { useComboboxContext } from "./combobox-context.mjs";
5
+ import { useNameWarning } from "./combobox-trigger.mjs";
6
+ //#region src/combobox/combobox-clear.tsx
7
+ /**
8
+ * The optional button that clears the combobox: `<button type="button" tabindex="-1">`. A click
9
+ * empties the text (urgent) and dispatches `valueChangeAction(null)` unless nothing is selected;
10
+ * the input keeps focus. Always rendered: hide it with CSS (`:placeholder-shown`) or `state`.
11
+ * A click while the listbox is open closes it (the platform's light dismiss: the button is
12
+ * outside the popup).
13
+ *
14
+ * Owned keys: `type` (on a `<button>`), `tabIndex`, `disabled`, `onClick`, `onPointerDown`,
15
+ * `onMouseDown`, `data-disabled`.
16
+ */
17
+ function ComboboxClear({ disabled: ownDisabled = false, className, style, children, render, ...rest }) {
18
+ const ctx = useComboboxContext("Combobox.Clear");
19
+ const disabled = ownDisabled || ctx.disabled;
20
+ const ref = useNameWarning("Combobox.Clear");
21
+ const state = {
22
+ value: ctx.value,
23
+ inputValue: ctx.inputValue,
24
+ disabled
25
+ };
26
+ const libraryProps = {
27
+ ...rendersButton(render) && { type: "button" },
28
+ tabIndex: -1,
29
+ disabled,
30
+ onPointerDown: (event) => {
31
+ event.preventDefault();
32
+ },
33
+ onMouseDown: (event) => {
34
+ event.preventDefault();
35
+ },
36
+ onClick: (event) => {
37
+ if (disabled) return;
38
+ ctx.clear(event.nativeEvent);
39
+ },
40
+ "data-disabled": dataAttr(disabled)
41
+ };
42
+ return useRender({
43
+ defaultElement: "button",
44
+ render,
45
+ state,
46
+ className,
47
+ style,
48
+ children,
49
+ props: rest,
50
+ libraryProps,
51
+ ref
52
+ });
53
+ }
54
+ ComboboxClear.displayName = "ComboboxClear";
55
+ //#endregion
56
+ export { ComboboxClear };
57
+
58
+ //# sourceMappingURL=combobox-clear.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combobox-clear.mjs","names":[],"sources":["../../src/combobox/combobox-clear.tsx"],"sourcesContent":["\"use client\";\nimport type {\n ComponentPropsWithRef,\n CSSProperties,\n MouseEvent,\n PointerEvent,\n ReactNode,\n} from \"react\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { rendersButton, useRender } from \"../internal/use-render.js\";\nimport type { DataAttributes } from \"../internal/use-render.js\";\nimport { useComboboxContext } from \"./combobox-context.js\";\nimport { useNameWarning } from \"./combobox-trigger.js\";\n\nexport interface ComboboxClearState {\n /** Optimistic selection. */\n readonly value: string | null;\n readonly inputValue: string;\n readonly disabled: boolean;\n}\n\nexport interface ComboboxClearProps extends Omit<\n ComponentPropsWithRef<\"button\">,\n | \"onClick\"\n | \"onPointerDown\"\n | \"onMouseDown\"\n | \"tabIndex\"\n | \"disabled\"\n | \"className\"\n | \"style\"\n | \"children\"\n> {\n /** Disables this button; the Root's `disabled` does too. */\n disabled?: boolean;\n className?: StateValue<string | undefined, ComboboxClearState>;\n style?: StateValue<CSSProperties | undefined, ComboboxClearState>;\n children?: StateValue<ReactNode, ComboboxClearState>;\n /** Should render a `<button>`. */\n render?: RenderProp<ComponentPropsWithRef<\"button\">, ComboboxClearState>;\n}\n\n/**\n * The optional button that clears the combobox: `<button type=\"button\" tabindex=\"-1\">`. A click\n * empties the text (urgent) and dispatches `valueChangeAction(null)` unless nothing is selected;\n * the input keeps focus. Always rendered: hide it with CSS (`:placeholder-shown`) or `state`.\n * A click while the listbox is open closes it (the platform's light dismiss: the button is\n * outside the popup).\n *\n * Owned keys: `type` (on a `<button>`), `tabIndex`, `disabled`, `onClick`, `onPointerDown`,\n * `onMouseDown`, `data-disabled`.\n */\nexport function ComboboxClear({\n disabled: ownDisabled = false,\n className,\n style,\n children,\n render,\n ...rest\n}: ComboboxClearProps) {\n const ctx = useComboboxContext(\"Combobox.Clear\");\n const disabled = ownDisabled || ctx.disabled;\n const ref = useNameWarning(\"Combobox.Clear\");\n const state: ComboboxClearState = { value: ctx.value, inputValue: ctx.inputValue, disabled };\n\n const libraryProps: ComponentPropsWithRef<\"button\"> & DataAttributes = {\n ...(rendersButton(render) && { type: \"button\" as const }),\n tabIndex: -1,\n disabled,\n onPointerDown: (event: PointerEvent<HTMLButtonElement>) => {\n event.preventDefault();\n },\n onMouseDown: (event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n },\n onClick: (event: MouseEvent<HTMLButtonElement>) => {\n if (disabled) return;\n ctx.clear(event.nativeEvent);\n },\n \"data-disabled\": dataAttr(disabled),\n };\n\n return useRender<ComponentPropsWithRef<\"button\">, ComboboxClearState>({\n defaultElement: \"button\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n libraryProps,\n ref,\n });\n}\n\nComboboxClear.displayName = \"ComboboxClear\";\n"],"mappings":";;;;;;;;;;;;;;;;AAoDA,SAAgB,cAAc,EAC5B,UAAU,cAAc,OACxB,WACA,OACA,UACA,QACA,GAAG,QACkB;CACrB,MAAM,MAAM,mBAAmB,gBAAgB;CAC/C,MAAM,WAAW,eAAe,IAAI;CACpC,MAAM,MAAM,eAAe,gBAAgB;CAC3C,MAAM,QAA4B;EAAE,OAAO,IAAI;EAAO,YAAY,IAAI;EAAY;CAAS;CAE3F,MAAM,eAAiE;EACrE,GAAI,cAAc,MAAM,KAAK,EAAE,MAAM,SAAkB;EACvD,UAAU;EACV;EACA,gBAAgB,UAA2C;GACzD,MAAM,eAAe;EACvB;EACA,cAAc,UAAyC;GACrD,MAAM,eAAe;EACvB;EACA,UAAU,UAAyC;GACjD,IAAI,UAAU;GACd,IAAI,MAAM,MAAM,WAAW;EAC7B;EACA,iBAAiB,SAAS,QAAQ;CACpC;CAEA,OAAO,UAA+D;EACpE,gBAAgB;EAChB;EACA;EACA;EACA;EACA;EACA,OAAO;EACP;EACA;CACF,CAAC;AACH;AAEA,cAAc,cAAc"}
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import { createContext, use } from "react";
3
+ //#region src/combobox/combobox-context.ts
4
+ const ComboboxContext = createContext(null);
5
+ function useComboboxContext(part) {
6
+ const context = use(ComboboxContext);
7
+ if (context === null) throw new Error(`${part} must be rendered inside a Combobox.Root.`);
8
+ return context;
9
+ }
10
+ /** Provided by `Combobox.Popup` (a List outside a Popup warns). */
11
+ const ComboboxPopupContext = createContext(false);
12
+ /** Provided by `Combobox.List` (an Option outside a List warns). */
13
+ const ComboboxListContext = createContext(false);
14
+ /** `Combobox.Group`: the id its `Combobox.GroupLabel` renders. */
15
+ const ComboboxGroupContext = createContext(null);
16
+ /** The id fragment of an option value: stable across result sets, no whitespace (design 3.5). */
17
+ function optionId(prefix, value) {
18
+ return `${prefix}${encodeURIComponent(value)}`;
19
+ }
20
+ //#endregion
21
+ export { ComboboxContext, ComboboxGroupContext, ComboboxListContext, ComboboxPopupContext, optionId, useComboboxContext };
22
+
23
+ //# sourceMappingURL=combobox-context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combobox-context.mjs","names":[],"sources":["../../src/combobox/combobox-context.ts"],"sourcesContent":["\"use client\";\nimport { createContext, use } from \"react\";\nimport type { RefObject } from \"react\";\nimport type { PopoverRootValue } from \"../internal/use-popover-root.js\";\n\n/** What a mounted `Combobox.Option` tells its Root (design 2, \"mounted options, labels\"). */\nexport interface ComboboxOptionEntry {\n readonly element: HTMLElement;\n /** The `label` prop; `undefined`: the element's trimmed `textContent` at the moment of use. */\n readonly label: string | undefined;\n readonly disabled: boolean;\n}\n\n/** One Combobox: what its Root provides to every part (design 14, `combobox-context.ts`). */\nexport interface ComboboxContextValue {\n /** The shared popover machinery (`usePopoverRoot`, library mode). */\n readonly popover: PopoverRootValue;\n readonly ids: {\n readonly input: string;\n readonly label: string;\n readonly list: string;\n /** `${root}-option-`: an Option's id is this plus `encodeURIComponent(value)`. */\n readonly optionPrefix: string;\n };\n /** Optimistic selection. */\n readonly value: string | null;\n /** The `valueChangeAction` transition is in flight. */\n readonly valuePending: boolean;\n /** `valuePending` or the open transition is in flight (the Root's `pending`). */\n readonly pending: boolean;\n /** The urgent text. */\n readonly inputValue: string;\n /** `useDeferredValue(inputValue)`: what the mounted results are for. */\n readonly query: string;\n readonly stale: boolean;\n /** The option `aria-activedescendant` points at (urgent virtual focus), or `null`. */\n readonly activeValue: string | null;\n /** No option is mounted and the results are settled (`Empty`, `data-empty`). */\n readonly empty: boolean;\n /** A `Combobox.Status` is mounted inside the List (a Suspense fallback): results are loading. */\n readonly loading: boolean;\n /** A `Combobox.Label` is mounted (the List's `aria-labelledby` names it only then). */\n readonly hasLabel: boolean;\n /** The enclosing `Field.Label`'s id: names the List when no `Combobox.Label` is mounted. */\n readonly fieldLabelId: string | undefined;\n readonly disabled: boolean;\n readonly inputRef: RefObject<HTMLInputElement | null>;\n readonly listRef: RefObject<HTMLElement | null>;\n /** Registers a mounted Option; returns the unregistration. */\n readonly registerOption: (value: string, entry: ComboboxOptionEntry) => () => void;\n /** Registers a mounted `Combobox.Status`; while one is mounted the results count as loading. */\n readonly registerStatus: () => () => void;\n /** Registers a mounted `Combobox.Label`; returns the unregistration. */\n readonly registerLabel: () => () => void;\n /** Make `value` the active option (urgent; never dispatches). */\n readonly setActive: (value: string | null) => void;\n /** Accept an option (design 5.2): urgent text write, dispatch, close when it settles. */\n readonly accept: (value: string, event: Event) => void;\n /** `Combobox.Clear` (design 3.3). */\n readonly clear: (event: Event) => void;\n /** The `change` of the Input: urgent text write and an open request (design 2.2, 5.1). */\n readonly typed: (text: string, event: Event) => void;\n /** Keyboard model of design section 8, run by the Input's `onKeyDown`. */\n readonly keyDown: (event: KeyboardEvent) => boolean;\n /** Focus left the Input (design 5.4): close at once, then revert or commit free text. */\n readonly focusOut: (event: FocusEvent) => void;\n /** A pointer click in the Input (`openOnClick`). */\n readonly inputClick: (event: MouseEvent) => void;\n}\n\nexport const ComboboxContext = createContext<ComboboxContextValue | null>(null);\n\nexport function useComboboxContext(part: string): ComboboxContextValue {\n const context = use(ComboboxContext);\n if (context === null) {\n throw new Error(`${part} must be rendered inside a Combobox.Root.`);\n }\n return context;\n}\n\n/** Provided by `Combobox.Popup` (a List outside a Popup warns). */\nexport const ComboboxPopupContext = createContext<boolean>(false);\n\n/** Provided by `Combobox.List` (an Option outside a List warns). */\nexport const ComboboxListContext = createContext<boolean>(false);\n\n/** `Combobox.Group`: the id its `Combobox.GroupLabel` renders. */\nexport const ComboboxGroupContext = createContext<string | null>(null);\n\n/** The id fragment of an option value: stable across result sets, no whitespace (design 3.5). */\nexport function optionId(prefix: string, value: string): string {\n return `${prefix}${encodeURIComponent(value)}`;\n}\n"],"mappings":";;;AAsEA,MAAa,kBAAkB,cAA2C,IAAI;AAE9E,SAAgB,mBAAmB,MAAoC;CACrE,MAAM,UAAU,IAAI,eAAe;CACnC,IAAI,YAAY,MACd,MAAM,IAAI,MAAM,GAAG,KAAK,0CAA0C;CAEpE,OAAO;AACT;;AAGA,MAAa,uBAAuB,cAAuB,KAAK;;AAGhE,MAAa,sBAAsB,cAAuB,KAAK;;AAG/D,MAAa,uBAAuB,cAA6B,IAAI;;AAGrE,SAAgB,SAAS,QAAgB,OAAuB;CAC9D,OAAO,GAAG,SAAS,mBAAmB,KAAK;AAC7C"}
@@ -0,0 +1,72 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { ComboboxListState } from "./combobox-list.mjs";
3
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
4
+ //#region src/combobox/combobox-group.d.ts
5
+ /** `Combobox.Group`, `Combobox.GroupLabel` and `Combobox.Status` have no state of their own. */
6
+ export type ComboboxGroupState = Record<string, never>;
7
+ export type ComboboxGroupLabelState = Record<string, never>;
8
+ export type ComboboxStatusState = Record<string, never>;
9
+ /** `Combobox.Empty` renders from the List's state. */
10
+ export type ComboboxEmptyState = ComboboxListState;
11
+ export interface ComboboxGroupProps extends Omit<ComponentPropsWithRef<"div">, "role" | "className" | "style" | "children"> {
12
+ className?: StateValue<string | undefined, ComboboxGroupState>;
13
+ style?: StateValue<CSSProperties | undefined, ComboboxGroupState>;
14
+ children?: StateValue<ReactNode, ComboboxGroupState>;
15
+ render?: RenderProp<ComponentPropsWithRef<"div">, ComboboxGroupState>;
16
+ }
17
+ /**
18
+ * A labelled set of options: `<div role="group" aria-labelledby>` named by the
19
+ * `Combobox.GroupLabel` inside it. Owned keys: `role`, `aria-labelledby` (token-merged).
20
+ */
21
+ export declare function ComboboxGroup({ className, style, children, render, ...rest }: ComboboxGroupProps): import("react").JSX.Element;
22
+ export declare namespace ComboboxGroup {
23
+ var displayName: string;
24
+ }
25
+ export interface ComboboxGroupLabelProps extends Omit<ComponentPropsWithRef<"div">, "id" | "className" | "style" | "children"> {
26
+ className?: StateValue<string | undefined, ComboboxGroupLabelState>;
27
+ style?: StateValue<CSSProperties | undefined, ComboboxGroupLabelState>;
28
+ children?: StateValue<ReactNode, ComboboxGroupLabelState>;
29
+ render?: RenderProp<ComponentPropsWithRef<"div">, ComboboxGroupLabelState>;
30
+ }
31
+ /** The name of the enclosing `Combobox.Group`: a `<div>` with the referenced id. Owned key: `id`. */
32
+ export declare function ComboboxGroupLabel({ className, style, children, render, ...rest }: ComboboxGroupLabelProps): ReactNode;
33
+ export declare namespace ComboboxGroupLabel {
34
+ var displayName: string;
35
+ }
36
+ export interface ComboboxEmptyProps extends Omit<ComponentPropsWithRef<"div">, "className" | "style" | "children"> {
37
+ className?: StateValue<string | undefined, ComboboxEmptyState>;
38
+ style?: StateValue<CSSProperties | undefined, ComboboxEmptyState>;
39
+ children?: StateValue<ReactNode, ComboboxEmptyState>;
40
+ render?: RenderProp<ComponentPropsWithRef<"div">, ComboboxEmptyState>;
41
+ }
42
+ /**
43
+ * "No results": renders a `<div>` with its children only when the List has **no mounted
44
+ * options, the results are not stale and none are loading** (no `Combobox.Status` mounted inside
45
+ * the List, i.e. no Suspense fallback showing); nothing otherwise (design 6.3). Place it in the
46
+ * Popup, outside the List (a listbox holds only options). Owns no keys.
47
+ */
48
+ export declare function ComboboxEmpty({ className, style, children, render, ...rest }: ComboboxEmptyProps): ReactNode;
49
+ export declare namespace ComboboxEmpty {
50
+ var displayName: string;
51
+ }
52
+ export interface ComboboxStatusProps extends Omit<ComponentPropsWithRef<"div">, "role" | "className" | "style" | "children"> {
53
+ className?: StateValue<string | undefined, ComboboxStatusState>;
54
+ style?: StateValue<CSSProperties | undefined, ComboboxStatusState>;
55
+ children?: StateValue<ReactNode, ComboboxStatusState>;
56
+ render?: RenderProp<ComponentPropsWithRef<"div">, ComboboxStatusState>;
57
+ }
58
+ /**
59
+ * A loading row or a hint. Rendered **inside the List** (the usual Suspense fallback,
60
+ * `<Suspense fallback={<Combobox.Status>Searching…</Combobox.Status>}>`), it marks the results
61
+ * as loading: `<div role="none">` (a listbox owns only options and groups, and a live region
62
+ * there would talk over the count; the List is `aria-busy` instead), `Empty` stays hidden and
63
+ * nothing is announced while it is mounted. Rendered in the Popup outside the List it is a plain
64
+ * hint, `<div role="status">`. No live-region work of its own either way (the result count is
65
+ * announced with `ariaNotify`). Owned key: `role`.
66
+ */
67
+ export declare function ComboboxStatus({ className, style, children, render, ...rest }: ComboboxStatusProps): ReactNode;
68
+ export declare namespace ComboboxStatus {
69
+ var displayName: string;
70
+ }
71
+ //#endregion
72
+ //# sourceMappingURL=combobox-group.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combobox-group.d.mts","names":[],"sources":["../../src/combobox/combobox-group.tsx"],"mappings":";;;;;YAcY,qBAAqB;YACrB,0BAA0B;YAC1B,sBAAsB;;YAEtB,qBAAqB;iBAIhB,2BAA2B,KAC1C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,8BAA8B;;;;;;wBAOpC,gBAAgB,WAAW,OAAO,UAAU,WAAW,QAAQ,qCAAkB,IAAA;yBAAjF;;;iBAkBC,gCAAgC,KAC/C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,8BAA8B;;;wBAIpC,qBACd,WACA,OACA,UACA,WACG,QACF,0BAAuB;yBANV;;;iBA0BC,2BAA2B,KAC1C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,8BAA8B;;;;;;;;wBASpC,gBAAgB,WAAW,OAAO,UAAU,WAAW,QAAQ,qBAAkB;yBAAjF;;;iBAiBC,4BAA4B,KAC3C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,8BAA8B;;;;;;;;;;;wBAYpC,iBACd,WACA,OACA,UACA,WACG,QACF,sBAAmB;yBANN"}