@funstack/ui 0.0.0-stage → 0.1.0-alpha.1

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 (299) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -2
  3. package/dist/accordion/accordion-context.d.mts +5 -0
  4. package/dist/accordion/accordion-context.d.mts.map +1 -0
  5. package/dist/accordion/accordion-context.mjs +9 -0
  6. package/dist/accordion/accordion-context.mjs.map +1 -0
  7. package/dist/accordion/accordion-item.d.mts +53 -0
  8. package/dist/accordion/accordion-item.d.mts.map +1 -0
  9. package/dist/accordion/accordion-item.mjs +85 -0
  10. package/dist/accordion/accordion-item.mjs.map +1 -0
  11. package/dist/accordion/accordion-panel.d.mts +40 -0
  12. package/dist/accordion/accordion-panel.d.mts.map +1 -0
  13. package/dist/accordion/accordion-panel.mjs +40 -0
  14. package/dist/accordion/accordion-panel.mjs.map +1 -0
  15. package/dist/accordion/accordion-root.d.mts +90 -0
  16. package/dist/accordion/accordion-root.d.mts.map +1 -0
  17. package/dist/accordion/accordion-root.mjs +229 -0
  18. package/dist/accordion/accordion-root.mjs.map +1 -0
  19. package/dist/accordion/accordion-trigger.d.mts +37 -0
  20. package/dist/accordion/accordion-trigger.d.mts.map +1 -0
  21. package/dist/accordion/accordion-trigger.mjs +81 -0
  22. package/dist/accordion/accordion-trigger.mjs.map +1 -0
  23. package/dist/accordion/index.d.mts +20 -0
  24. package/dist/accordion/index.d.mts.map +1 -0
  25. package/dist/accordion/index.mjs +20 -0
  26. package/dist/accordion/index.mjs.map +1 -0
  27. package/dist/checkbox/checkbox.d.mts +92 -0
  28. package/dist/checkbox/checkbox.d.mts.map +1 -0
  29. package/dist/checkbox/checkbox.mjs +82 -0
  30. package/dist/checkbox/checkbox.mjs.map +1 -0
  31. package/dist/checkbox/index.d.mts +3 -0
  32. package/dist/checkbox/index.mjs +1 -0
  33. package/dist/checkbox-group/checkbox-group-context.mjs +24 -0
  34. package/dist/checkbox-group/checkbox-group-context.mjs.map +1 -0
  35. package/dist/checkbox-group/checkbox-group-item.d.mts +55 -0
  36. package/dist/checkbox-group/checkbox-group-item.d.mts.map +1 -0
  37. package/dist/checkbox-group/checkbox-group-item.mjs +90 -0
  38. package/dist/checkbox-group/checkbox-group-item.mjs.map +1 -0
  39. package/dist/checkbox-group/checkbox-group-label.d.mts +21 -0
  40. package/dist/checkbox-group/checkbox-group-label.d.mts.map +1 -0
  41. package/dist/checkbox-group/checkbox-group-label.mjs +30 -0
  42. package/dist/checkbox-group/checkbox-group-label.mjs.map +1 -0
  43. package/dist/checkbox-group/checkbox-group-parent.d.mts +68 -0
  44. package/dist/checkbox-group/checkbox-group-parent.d.mts.map +1 -0
  45. package/dist/checkbox-group/checkbox-group-parent.mjs +145 -0
  46. package/dist/checkbox-group/checkbox-group-parent.mjs.map +1 -0
  47. package/dist/checkbox-group/checkbox-group-root.d.mts +100 -0
  48. package/dist/checkbox-group/checkbox-group-root.d.mts.map +1 -0
  49. package/dist/checkbox-group/checkbox-group-root.mjs +291 -0
  50. package/dist/checkbox-group/checkbox-group-root.mjs.map +1 -0
  51. package/dist/checkbox-group/index.d.mts +23 -0
  52. package/dist/checkbox-group/index.d.mts.map +1 -0
  53. package/dist/checkbox-group/index.mjs +23 -0
  54. package/dist/checkbox-group/index.mjs.map +1 -0
  55. package/dist/dialog/dialog-close.d.mts +44 -0
  56. package/dist/dialog/dialog-close.d.mts.map +1 -0
  57. package/dist/dialog/dialog-close.mjs +76 -0
  58. package/dist/dialog/dialog-close.mjs.map +1 -0
  59. package/dist/dialog/dialog-context.mjs +13 -0
  60. package/dist/dialog/dialog-context.mjs.map +1 -0
  61. package/dist/dialog/dialog-description.d.mts +22 -0
  62. package/dist/dialog/dialog-description.d.mts.map +1 -0
  63. package/dist/dialog/dialog-description.mjs +31 -0
  64. package/dist/dialog/dialog-description.mjs.map +1 -0
  65. package/dist/dialog/dialog-form.d.mts +58 -0
  66. package/dist/dialog/dialog-form.d.mts.map +1 -0
  67. package/dist/dialog/dialog-form.mjs +108 -0
  68. package/dist/dialog/dialog-form.mjs.map +1 -0
  69. package/dist/dialog/dialog-popup.d.mts +81 -0
  70. package/dist/dialog/dialog-popup.d.mts.map +1 -0
  71. package/dist/dialog/dialog-popup.mjs +367 -0
  72. package/dist/dialog/dialog-popup.mjs.map +1 -0
  73. package/dist/dialog/dialog-root.d.mts +70 -0
  74. package/dist/dialog/dialog-root.d.mts.map +1 -0
  75. package/dist/dialog/dialog-root.mjs +113 -0
  76. package/dist/dialog/dialog-root.mjs.map +1 -0
  77. package/dist/dialog/dialog-title.d.mts +23 -0
  78. package/dist/dialog/dialog-title.d.mts.map +1 -0
  79. package/dist/dialog/dialog-title.mjs +31 -0
  80. package/dist/dialog/dialog-title.mjs.map +1 -0
  81. package/dist/dialog/dialog-trigger.d.mts +39 -0
  82. package/dist/dialog/dialog-trigger.d.mts.map +1 -0
  83. package/dist/dialog/dialog-trigger.mjs +80 -0
  84. package/dist/dialog/dialog-trigger.mjs.map +1 -0
  85. package/dist/dialog/index.d.mts +28 -0
  86. package/dist/dialog/index.d.mts.map +1 -0
  87. package/dist/dialog/index.mjs +28 -0
  88. package/dist/dialog/index.mjs.map +1 -0
  89. package/dist/index.d.mts +60 -0
  90. package/dist/index.mjs +12 -0
  91. package/dist/internal/action-details.mjs +47 -0
  92. package/dist/internal/action-details.mjs.map +1 -0
  93. package/dist/internal/anchor-position.d.mts +7 -0
  94. package/dist/internal/anchor-position.d.mts.map +1 -0
  95. package/dist/internal/anchor-position.mjs +16 -0
  96. package/dist/internal/anchor-position.mjs.map +1 -0
  97. package/dist/internal/data-attr.mjs +13 -0
  98. package/dist/internal/data-attr.mjs.map +1 -0
  99. package/dist/internal/merge-props.mjs +119 -0
  100. package/dist/internal/merge-props.mjs.map +1 -0
  101. package/dist/internal/platform-attributes.d.mts +55 -0
  102. package/dist/internal/platform-attributes.d.mts.map +1 -0
  103. package/dist/internal/sync-presence.mjs +19 -0
  104. package/dist/internal/sync-presence.mjs.map +1 -0
  105. package/dist/internal/transition-boundary.mjs +52 -0
  106. package/dist/internal/transition-boundary.mjs.map +1 -0
  107. package/dist/internal/transition-types.mjs +15 -0
  108. package/dist/internal/transition-types.mjs.map +1 -0
  109. package/dist/internal/types.d.mts +38 -0
  110. package/dist/internal/types.d.mts.map +1 -0
  111. package/dist/internal/use-action-trigger.mjs +58 -0
  112. package/dist/internal/use-action-trigger.mjs.map +1 -0
  113. package/dist/internal/use-controllable-action.mjs +115 -0
  114. package/dist/internal/use-controllable-action.mjs.map +1 -0
  115. package/dist/internal/use-delayed-pair.mjs +40 -0
  116. package/dist/internal/use-delayed-pair.mjs.map +1 -0
  117. package/dist/internal/use-dev-warning.mjs +21 -0
  118. package/dist/internal/use-dev-warning.mjs.map +1 -0
  119. package/dist/internal/use-exit-animation.mjs +55 -0
  120. package/dist/internal/use-exit-animation.mjs.map +1 -0
  121. package/dist/internal/use-form-reset.mjs +50 -0
  122. package/dist/internal/use-form-reset.mjs.map +1 -0
  123. package/dist/internal/use-native-checked.mjs +113 -0
  124. package/dist/internal/use-native-checked.mjs.map +1 -0
  125. package/dist/internal/use-native-group-reconciliation.mjs +64 -0
  126. package/dist/internal/use-native-group-reconciliation.mjs.map +1 -0
  127. package/dist/internal/use-popover-popup.mjs +274 -0
  128. package/dist/internal/use-popover-popup.mjs.map +1 -0
  129. package/dist/internal/use-popover-root.d.mts +2 -0
  130. package/dist/internal/use-popover-root.mjs +112 -0
  131. package/dist/internal/use-popover-root.mjs.map +1 -0
  132. package/dist/internal/use-popover-trigger.mjs +86 -0
  133. package/dist/internal/use-popover-trigger.mjs.map +1 -0
  134. package/dist/internal/use-render.mjs +51 -0
  135. package/dist/internal/use-render.mjs.map +1 -0
  136. package/dist/internal/use-until-found.mjs +40 -0
  137. package/dist/internal/use-until-found.mjs.map +1 -0
  138. package/dist/menu/index.d.mts +34 -0
  139. package/dist/menu/index.d.mts.map +1 -0
  140. package/dist/menu/index.mjs +34 -0
  141. package/dist/menu/index.mjs.map +1 -0
  142. package/dist/menu/menu-checkbox-item.d.mts +42 -0
  143. package/dist/menu/menu-checkbox-item.d.mts.map +1 -0
  144. package/dist/menu/menu-checkbox-item.mjs +71 -0
  145. package/dist/menu/menu-checkbox-item.mjs.map +1 -0
  146. package/dist/menu/menu-context.d.mts +1 -0
  147. package/dist/menu/menu-context.mjs +28 -0
  148. package/dist/menu/menu-context.mjs.map +1 -0
  149. package/dist/menu/menu-dom.mjs +37 -0
  150. package/dist/menu/menu-dom.mjs.map +1 -0
  151. package/dist/menu/menu-group.d.mts +48 -0
  152. package/dist/menu/menu-group.d.mts.map +1 -0
  153. package/dist/menu/menu-group.mjs +69 -0
  154. package/dist/menu/menu-group.mjs.map +1 -0
  155. package/dist/menu/menu-hover.mjs +29 -0
  156. package/dist/menu/menu-hover.mjs.map +1 -0
  157. package/dist/menu/menu-item.d.mts +45 -0
  158. package/dist/menu/menu-item.d.mts.map +1 -0
  159. package/dist/menu/menu-item.mjs +54 -0
  160. package/dist/menu/menu-item.mjs.map +1 -0
  161. package/dist/menu/menu-popup.d.mts +69 -0
  162. package/dist/menu/menu-popup.d.mts.map +1 -0
  163. package/dist/menu/menu-popup.mjs +207 -0
  164. package/dist/menu/menu-popup.mjs.map +1 -0
  165. package/dist/menu/menu-radio-group.d.mts +37 -0
  166. package/dist/menu/menu-radio-group.d.mts.map +1 -0
  167. package/dist/menu/menu-radio-group.mjs +72 -0
  168. package/dist/menu/menu-radio-group.mjs.map +1 -0
  169. package/dist/menu/menu-radio-item.d.mts +33 -0
  170. package/dist/menu/menu-radio-item.d.mts.map +1 -0
  171. package/dist/menu/menu-radio-item.mjs +62 -0
  172. package/dist/menu/menu-radio-item.mjs.map +1 -0
  173. package/dist/menu/menu-root.d.mts +54 -0
  174. package/dist/menu/menu-root.d.mts.map +1 -0
  175. package/dist/menu/menu-root.mjs +102 -0
  176. package/dist/menu/menu-root.mjs.map +1 -0
  177. package/dist/menu/menu-submenu-trigger.d.mts +31 -0
  178. package/dist/menu/menu-submenu-trigger.d.mts.map +1 -0
  179. package/dist/menu/menu-submenu-trigger.mjs +92 -0
  180. package/dist/menu/menu-submenu-trigger.mjs.map +1 -0
  181. package/dist/menu/menu-trigger.d.mts +36 -0
  182. package/dist/menu/menu-trigger.d.mts.map +1 -0
  183. package/dist/menu/menu-trigger.mjs +81 -0
  184. package/dist/menu/menu-trigger.mjs.map +1 -0
  185. package/dist/menu/use-menu-item.mjs +54 -0
  186. package/dist/menu/use-menu-item.mjs.map +1 -0
  187. package/dist/popover/index.d.mts +28 -0
  188. package/dist/popover/index.d.mts.map +1 -0
  189. package/dist/popover/index.mjs +28 -0
  190. package/dist/popover/index.mjs.map +1 -0
  191. package/dist/popover/popover-close.d.mts +41 -0
  192. package/dist/popover/popover-close.d.mts.map +1 -0
  193. package/dist/popover/popover-close.mjs +90 -0
  194. package/dist/popover/popover-close.mjs.map +1 -0
  195. package/dist/popover/popover-context.mjs +26 -0
  196. package/dist/popover/popover-context.mjs.map +1 -0
  197. package/dist/popover/popover-description.d.mts +22 -0
  198. package/dist/popover/popover-description.d.mts.map +1 -0
  199. package/dist/popover/popover-description.mjs +28 -0
  200. package/dist/popover/popover-description.mjs.map +1 -0
  201. package/dist/popover/popover-popup.d.mts +82 -0
  202. package/dist/popover/popover-popup.d.mts.map +1 -0
  203. package/dist/popover/popover-popup.mjs +93 -0
  204. package/dist/popover/popover-popup.mjs.map +1 -0
  205. package/dist/popover/popover-root.d.mts +64 -0
  206. package/dist/popover/popover-root.d.mts.map +1 -0
  207. package/dist/popover/popover-root.mjs +39 -0
  208. package/dist/popover/popover-root.mjs.map +1 -0
  209. package/dist/popover/popover-title.d.mts +23 -0
  210. package/dist/popover/popover-title.d.mts.map +1 -0
  211. package/dist/popover/popover-title.mjs +28 -0
  212. package/dist/popover/popover-title.mjs.map +1 -0
  213. package/dist/popover/popover-trigger.d.mts +37 -0
  214. package/dist/popover/popover-trigger.d.mts.map +1 -0
  215. package/dist/popover/popover-trigger.mjs +40 -0
  216. package/dist/popover/popover-trigger.mjs.map +1 -0
  217. package/dist/radio-group/index.d.mts +20 -0
  218. package/dist/radio-group/index.d.mts.map +1 -0
  219. package/dist/radio-group/index.mjs +20 -0
  220. package/dist/radio-group/index.mjs.map +1 -0
  221. package/dist/radio-group/radio-group-context.mjs +13 -0
  222. package/dist/radio-group/radio-group-context.mjs.map +1 -0
  223. package/dist/radio-group/radio-group-item.d.mts +54 -0
  224. package/dist/radio-group/radio-group-item.d.mts.map +1 -0
  225. package/dist/radio-group/radio-group-item.mjs +83 -0
  226. package/dist/radio-group/radio-group-item.mjs.map +1 -0
  227. package/dist/radio-group/radio-group-label.d.mts +21 -0
  228. package/dist/radio-group/radio-group-label.d.mts.map +1 -0
  229. package/dist/radio-group/radio-group-label.mjs +30 -0
  230. package/dist/radio-group/radio-group-label.mjs.map +1 -0
  231. package/dist/radio-group/radio-group-root.d.mts +92 -0
  232. package/dist/radio-group/radio-group-root.d.mts.map +1 -0
  233. package/dist/radio-group/radio-group-root.mjs +137 -0
  234. package/dist/radio-group/radio-group-root.mjs.map +1 -0
  235. package/dist/switch/index.d.mts +3 -0
  236. package/dist/switch/index.mjs +1 -0
  237. package/dist/switch/switch.d.mts +78 -0
  238. package/dist/switch/switch.d.mts.map +1 -0
  239. package/dist/switch/switch.mjs +77 -0
  240. package/dist/switch/switch.mjs.map +1 -0
  241. package/dist/tabs/index.d.mts +24 -0
  242. package/dist/tabs/index.d.mts.map +1 -0
  243. package/dist/tabs/index.mjs +23 -0
  244. package/dist/tabs/index.mjs.map +1 -0
  245. package/dist/tabs/tabs-context.d.mts +7 -0
  246. package/dist/tabs/tabs-context.d.mts.map +1 -0
  247. package/dist/tabs/tabs-context.mjs +14 -0
  248. package/dist/tabs/tabs-context.mjs.map +1 -0
  249. package/dist/tabs/tabs-ids.mjs +39 -0
  250. package/dist/tabs/tabs-ids.mjs.map +1 -0
  251. package/dist/tabs/tabs-indicator.d.mts +32 -0
  252. package/dist/tabs/tabs-indicator.d.mts.map +1 -0
  253. package/dist/tabs/tabs-indicator.mjs +49 -0
  254. package/dist/tabs/tabs-indicator.mjs.map +1 -0
  255. package/dist/tabs/tabs-list.d.mts +34 -0
  256. package/dist/tabs/tabs-list.d.mts.map +1 -0
  257. package/dist/tabs/tabs-list.mjs +130 -0
  258. package/dist/tabs/tabs-list.mjs.map +1 -0
  259. package/dist/tabs/tabs-panel.d.mts +50 -0
  260. package/dist/tabs/tabs-panel.d.mts.map +1 -0
  261. package/dist/tabs/tabs-panel.mjs +81 -0
  262. package/dist/tabs/tabs-panel.mjs.map +1 -0
  263. package/dist/tabs/tabs-root.d.mts +64 -0
  264. package/dist/tabs/tabs-root.d.mts.map +1 -0
  265. package/dist/tabs/tabs-root.mjs +90 -0
  266. package/dist/tabs/tabs-root.mjs.map +1 -0
  267. package/dist/tabs/tabs-tab.d.mts +49 -0
  268. package/dist/tabs/tabs-tab.d.mts.map +1 -0
  269. package/dist/tabs/tabs-tab.mjs +89 -0
  270. package/dist/tabs/tabs-tab.mjs.map +1 -0
  271. package/dist/toggle/index.d.mts +3 -0
  272. package/dist/toggle/index.mjs +1 -0
  273. package/dist/toggle/toggle.d.mts +57 -0
  274. package/dist/toggle/toggle.d.mts.map +1 -0
  275. package/dist/toggle/toggle.mjs +59 -0
  276. package/dist/toggle/toggle.mjs.map +1 -0
  277. package/dist/tooltip/index.d.mts +20 -0
  278. package/dist/tooltip/index.d.mts.map +1 -0
  279. package/dist/tooltip/index.mjs +19 -0
  280. package/dist/tooltip/index.mjs.map +1 -0
  281. package/dist/tooltip/tooltip-context.d.mts +5 -0
  282. package/dist/tooltip/tooltip-context.d.mts.map +1 -0
  283. package/dist/tooltip/tooltip-context.mjs +13 -0
  284. package/dist/tooltip/tooltip-context.mjs.map +1 -0
  285. package/dist/tooltip/tooltip-popup.d.mts +49 -0
  286. package/dist/tooltip/tooltip-popup.d.mts.map +1 -0
  287. package/dist/tooltip/tooltip-popup.mjs +52 -0
  288. package/dist/tooltip/tooltip-popup.mjs.map +1 -0
  289. package/dist/tooltip/tooltip-root.d.mts +41 -0
  290. package/dist/tooltip/tooltip-root.d.mts.map +1 -0
  291. package/dist/tooltip/tooltip-root.mjs +86 -0
  292. package/dist/tooltip/tooltip-root.mjs.map +1 -0
  293. package/dist/tooltip/tooltip-trigger.d.mts +38 -0
  294. package/dist/tooltip/tooltip-trigger.d.mts.map +1 -0
  295. package/dist/tooltip/tooltip-trigger.mjs +55 -0
  296. package/dist/tooltip/tooltip-trigger.mjs.map +1 -0
  297. package/dist/tooltip/use-tooltip-interaction.mjs +119 -0
  298. package/dist/tooltip/use-tooltip-interaction.mjs.map +1 -0
  299. package/package.json +73 -3
@@ -0,0 +1,82 @@
1
+ "use client";
2
+ import { useTransitionBoundary } from "../internal/transition-boundary.mjs";
3
+ import { createActionDetails } from "../internal/action-details.mjs";
4
+ import { dataAttr } from "../internal/data-attr.mjs";
5
+ import { transitionTypes } from "../internal/transition-types.mjs";
6
+ import { useControllableAction } from "../internal/use-controllable-action.mjs";
7
+ import { useRender } from "../internal/use-render.mjs";
8
+ import { guardCheckableChange, useNativeChecked } from "../internal/use-native-checked.mjs";
9
+ //#region src/checkbox/checkbox.tsx
10
+ /**
11
+ * A checkbox (WAI-ARIA "Checkbox" pattern, dual- and mixed-state). Renders
12
+ * `<input type="checkbox">` whose DOM `checked` is the optimistic state; the input carries
13
+ * `data-pending` while `checkedChangeAction` is in flight and takes part in forms natively.
14
+ *
15
+ * Owned keys (a `render` element's value is overridden): `type`, `checked`, `defaultChecked`,
16
+ * `indeterminate` (stripped), `aria-checked` (always removed), `disabled`, `data-checked`,
17
+ * `data-indeterminate`, `data-pending`, `data-disabled`. `role` passes through. Event handlers
18
+ * are merged rather than owned: a `render` element's own `onChange` (or `onClick`) runs first,
19
+ * then the library's; an `onClick` that calls `preventDefault()` cancels the change (nothing is
20
+ * dispatched).
21
+ */
22
+ function Checkbox({ checked, defaultChecked, indeterminate = false, checkedChangeAction, disabled = false, transition, className, style, render, ...rest }) {
23
+ const { optimistic, pending, dispatch, latestInFlight } = useControllableAction({
24
+ controlled: checked,
25
+ defaultValue: defaultChecked,
26
+ initialValue: false,
27
+ action: checkedChangeAction,
28
+ transitionTypes: (next) => transitionTypes("checkbox", next ? "check" : "uncheck"),
29
+ warn: {
30
+ component: "Checkbox",
31
+ prop: "checked"
32
+ }
33
+ });
34
+ const shownIndeterminate = indeterminate && !pending;
35
+ const inputRef = useNativeChecked({
36
+ type: "checkbox",
37
+ component: "Checkbox",
38
+ checked: optimistic,
39
+ defaultChecked: checked === void 0 ? defaultChecked ?? false : void 0,
40
+ indeterminate: shownIndeterminate,
41
+ latestInFlight,
42
+ onPlatformChange: (next, event) => dispatch(next, createActionDetails(event, { reason: "platform" }))
43
+ });
44
+ const element = useRender({
45
+ defaultElement: "input",
46
+ render,
47
+ state: {
48
+ checked: optimistic,
49
+ indeterminate: shownIndeterminate,
50
+ pending,
51
+ disabled
52
+ },
53
+ className,
54
+ style,
55
+ children: void 0,
56
+ ref: inputRef,
57
+ props: rest,
58
+ libraryProps: {
59
+ type: "checkbox",
60
+ checked: optimistic,
61
+ defaultChecked: void 0,
62
+ indeterminate: void 0,
63
+ "aria-checked": void 0,
64
+ disabled,
65
+ "data-checked": dataAttr(optimistic),
66
+ "data-indeterminate": dataAttr(shownIndeterminate),
67
+ "data-pending": dataAttr(pending),
68
+ "data-disabled": dataAttr(disabled),
69
+ onChange: (event) => {
70
+ if (disabled) return;
71
+ const nativeEvent = event.nativeEvent;
72
+ guardCheckableChange(nativeEvent, () => dispatch(!optimistic, createActionDetails(nativeEvent, { reason: "activate" })), "Checkbox");
73
+ }
74
+ }
75
+ });
76
+ return useTransitionBoundary("Checkbox", transition, element);
77
+ }
78
+ Checkbox.displayName = "Checkbox";
79
+ //#endregion
80
+ export { Checkbox };
81
+
82
+ //# sourceMappingURL=checkbox.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox.mjs","names":[],"sources":["../../src/checkbox/checkbox.tsx"],"sourcesContent":["\"use client\";\nimport type { ChangeEvent, ComponentPropsWithRef, CSSProperties, ViewTransitionClass } from \"react\";\nimport { useTransitionBoundary } from \"../internal/transition-boundary.js\";\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 { guardCheckableChange, useNativeChecked } from \"../internal/use-native-checked.js\";\nimport { useRender } from \"../internal/use-render.js\";\n\nexport interface CheckboxState {\n /** Optimistic checked state: what the user sees, including an in-flight change. */\n readonly checked: boolean;\n /**\n * The `indeterminate` prop, suspended while an action is in flight: `false` whenever `pending`\n * is true, so that the attribute, the DOM property and `:indeterminate` always agree.\n */\n readonly indeterminate: boolean;\n /** An action dispatched by this Checkbox is in flight (including the resulting render). */\n readonly pending: boolean;\n /** The `disabled` prop. */\n readonly disabled: boolean;\n}\n\n/** Details passed as the second argument of `checkedChangeAction`. */\nexport interface CheckboxCheckedChangeDetails extends ActionDetails {\n /**\n * `\"activate\"`: the user toggled the box (click, Space, label click); `event` is the native\n * `click` event. `\"platform\"`: the browser changed the value itself: a form reset (`event` is\n * the `reset` event) or a click before hydration / Firefox form-state restoration found on\n * mount (`event` is `undefined`).\n */\n readonly reason: ChangeReason;\n}\n\nexport interface CheckboxProps extends Omit<\n ComponentPropsWithRef<\"input\">,\n | \"type\"\n | \"checked\"\n | \"defaultChecked\"\n | \"onChange\"\n | \"aria-checked\"\n | \"className\"\n | \"style\"\n | \"children\"\n> {\n /** Controlled checked state. `undefined` means uncontrolled. */\n checked?: boolean;\n /**\n * Initial checked state in uncontrolled mode (default `false`). Also the value a form reset\n * returns to: the latest prop value is mirrored into the input's `defaultChecked`.\n */\n defaultChecked?: boolean;\n /**\n * Controlled-only mixed state (APG tri-state checkbox), derived by the parent from other state;\n * there is no `defaultIndeterminate` and no action. Rendered as `el.indeterminate`,\n * `data-indeterminate` and `:indeterminate`, except while an action is pending. Clicking a\n * mixed box dispatches `checked: true` (for the usual unchecked + mixed representation). Does\n * not affect what the form submits.\n */\n indeterminate?: boolean;\n /**\n * Called with the next checked state on every change. Runs inside the Checkbox's transition;\n * may be sync or async (also a Server Function). Rejections reach the nearest Error Boundary.\n * Also called with `details.reason === \"platform\"` for a form reset or a pre-hydration click.\n *\n * A `setState` placed after your own `await` is not a Transition update; wrap it in\n * `startTransition` (React limitation). `details.event.preventDefault()` is not a veto and is\n * unsupported here; use controlled mode to veto a change.\n */\n checkedChangeAction?: ChangeAction<boolean, CheckboxCheckedChangeDetails>;\n /** Renders a natively disabled input; never dispatches. Default `false`. */\n disabled?: boolean;\n /** Submitted as the input's value when checked. Default `\"on\"` (platform). */\n value?: string;\n /**\n * Forwarded as `default` to the Checkbox's `<ViewTransition>`. Default: no boundary. Animates the\n * commit that ends an action, not the optimistic flip; animate the flip 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, CheckboxState>;\n style?: StateValue<CSSProperties | undefined, CheckboxState>;\n /**\n * Replace the rendered element (element form) or take over rendering (function form). Must keep\n * an `<input type=\"checkbox\">`.\n */\n render?: RenderProp<ComponentPropsWithRef<\"input\">, CheckboxState>;\n}\n\n/**\n * A checkbox (WAI-ARIA \"Checkbox\" pattern, dual- and mixed-state). Renders\n * `<input type=\"checkbox\">` whose DOM `checked` is the optimistic state; the input carries\n * `data-pending` while `checkedChangeAction` is in flight and takes part in forms natively.\n *\n * Owned keys (a `render` element's value is overridden): `type`, `checked`, `defaultChecked`,\n * `indeterminate` (stripped), `aria-checked` (always removed), `disabled`, `data-checked`,\n * `data-indeterminate`, `data-pending`, `data-disabled`. `role` passes through. Event handlers\n * are merged rather than owned: a `render` element's own `onChange` (or `onClick`) runs first,\n * then the library's; an `onClick` that calls `preventDefault()` cancels the change (nothing is\n * dispatched).\n */\nexport function Checkbox({\n checked,\n defaultChecked,\n indeterminate = false,\n checkedChangeAction,\n disabled = false,\n transition,\n className,\n style,\n render,\n ...rest\n}: CheckboxProps) {\n const { optimistic, pending, dispatch, latestInFlight } = useControllableAction<\n boolean,\n CheckboxCheckedChangeDetails\n >({\n controlled: checked,\n defaultValue: defaultChecked,\n initialValue: false,\n action: checkedChangeAction,\n transitionTypes: (next) => transitionTypes(\"checkbox\", next ? \"check\" : \"uncheck\"),\n warn: { component: \"Checkbox\", prop: \"checked\" },\n });\n\n // Suspended while pending (conventions 4.1): the browser clears the property on the click, and\n // the parent may not have recomputed yet. Restored on settle if the parent still says mixed.\n const shownIndeterminate = indeterminate && !pending;\n\n const inputRef = useNativeChecked({\n type: \"checkbox\",\n component: \"Checkbox\",\n checked: optimistic,\n // Uncontrolled: the latest prop is the reset target. Controlled: React's mount-time value.\n defaultChecked: checked === undefined ? (defaultChecked ?? false) : undefined,\n indeterminate: shownIndeterminate,\n latestInFlight,\n onPlatformChange: (next, event) =>\n dispatch(next, createActionDetails(event, { reason: \"platform\" })),\n });\n\n const state: CheckboxState = {\n checked: optimistic,\n indeterminate: shownIndeterminate,\n pending,\n disabled,\n };\n\n const element = useRender<ComponentPropsWithRef<\"input\">, CheckboxState>({\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 (`role` included).\n props: rest,\n // Library-controlled layer (owned keys, conventions 1.2).\n libraryProps: {\n type: \"checkbox\",\n // The DOM state is the optimistic state (conventions 3.2).\n checked: optimistic,\n defaultChecked: undefined,\n // Not a DOM attribute; the hook sets the property. Owned so a `render` element's own\n // `indeterminate` prop (which react-dom would warn about) is stripped.\n ...({ indeterminate: undefined } as object),\n \"aria-checked\": undefined,\n // Owned so that native disabledness, `data-disabled` and the click guard always agree: a\n // `render` element cannot re-enable (`disabled={false}`) or disable the input on its own.\n disabled,\n \"data-checked\": dataAttr(optimistic),\n \"data-indeterminate\": dataAttr(shownIndeterminate),\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n onChange: (event: ChangeEvent<HTMLInputElement>) => {\n // A natively disabled input fires no click; this covers `render` elements that do not\n // honour `disabled`.\n if (disabled) return;\n const nativeEvent = event.nativeEvent;\n // `indeterminate` plays no part: the platform's rule is \"flip checked, clear mixed\".\n guardCheckableChange(\n nativeEvent,\n () => dispatch(!optimistic, createActionDetails(nativeEvent, { reason: \"activate\" })),\n \"Checkbox\",\n );\n },\n },\n });\n\n return useTransitionBoundary(\"Checkbox\", transition, element);\n}\n\nCheckbox.displayName = \"Checkbox\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAiHA,SAAgB,SAAS,EACvB,SACA,gBACA,gBAAgB,OAChB,qBACA,WAAW,OACX,YACA,WACA,OACA,QACA,GAAG,QACa;CAChB,MAAM,EAAE,YAAY,SAAS,UAAU,mBAAmB,sBAGxD;EACA,YAAY;EACZ,cAAc;EACd,cAAc;EACd,QAAQ;EACR,kBAAkB,SAAS,gBAAgB,YAAY,OAAO,UAAU,SAAS;EACjF,MAAM;GAAE,WAAW;GAAY,MAAM;EAAU;CACjD,CAAC;CAID,MAAM,qBAAqB,iBAAiB,CAAC;CAE7C,MAAM,WAAW,iBAAiB;EAChC,MAAM;EACN,WAAW;EACX,SAAS;EAET,gBAAgB,YAAY,KAAA,IAAa,kBAAkB,QAAS,KAAA;EACpE,eAAe;EACf;EACA,mBAAmB,MAAM,UACvB,SAAS,MAAM,oBAAoB,OAAO,EAAE,QAAQ,WAAW,CAAC,CAAC;CACrE,CAAC;CASD,MAAM,UAAU,UAAyD;EACvE,gBAAgB;EAChB;EACA,OAAA;GATA,SAAS;GACT,eAAe;GACf;GACA;EAMI;EACJ;EACA;EACA,UAAU,KAAA;EACV,KAAK;EAEL,OAAO;EAEP,cAAc;GACZ,MAAM;GAEN,SAAS;GACT,gBAAgB,KAAA;GAGV,eAAe,KAAA;GACrB,gBAAgB,KAAA;GAGhB;GACA,gBAAgB,SAAS,UAAU;GACnC,sBAAsB,SAAS,kBAAkB;GACjD,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;GAClC,WAAW,UAAyC;IAGlD,IAAI,UAAU;IACd,MAAM,cAAc,MAAM;IAE1B,qBACE,mBACM,SAAS,CAAC,YAAY,oBAAoB,aAAa,EAAE,QAAQ,WAAW,CAAC,CAAC,GACpF,UACF;GACF;EACF;CACF,CAAC;CAED,OAAO,sBAAsB,YAAY,YAAY,OAAO;AAC9D;AAEA,SAAS,cAAc"}
@@ -0,0 +1,3 @@
1
+ import "../internal/platform-attributes.mjs";
2
+ import { Checkbox, CheckboxCheckedChangeDetails, CheckboxProps, CheckboxState } from "./checkbox.mjs";
3
+ export { Checkbox, type CheckboxCheckedChangeDetails, type CheckboxProps, type CheckboxState };
@@ -0,0 +1 @@
1
+ export { Checkbox } from "./checkbox.mjs";
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { createContext, use } from "react";
3
+ //#region src/checkbox-group/checkbox-group-context.ts
4
+ /**
5
+ * The values a Parent over `values` acts on and derives from: those not in `disabledItems`
6
+ * (values with no Item included). When that leaves nothing (every value has only disabled
7
+ * Items), all of `values`: a Parent the consumer left enabled over disabled Items still shows and
8
+ * changes their state (disable the Parent to make it inert).
9
+ */
10
+ function enabledValues(values, disabledItems) {
11
+ if (disabledItems.size === 0) return values;
12
+ const enabled = values.filter((v) => !disabledItems.has(v));
13
+ return enabled.length > 0 ? enabled : values;
14
+ }
15
+ const CheckboxGroupContext = createContext(null);
16
+ function useCheckboxGroupContext(part) {
17
+ const context = use(CheckboxGroupContext);
18
+ if (context === null) throw new Error(`${part} must be rendered inside a CheckboxGroup.Root.`);
19
+ return context;
20
+ }
21
+ //#endregion
22
+ export { CheckboxGroupContext, enabledValues, useCheckboxGroupContext };
23
+
24
+ //# sourceMappingURL=checkbox-group-context.mjs.map
@@ -0,0 +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"}
@@ -0,0 +1,55 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ViewTransitionClass } from "react";
3
+ //#region src/checkbox-group/checkbox-group-item.d.ts
4
+ export interface CheckboxGroupItemState {
5
+ readonly value: string;
6
+ /** Optimistic: true as soon as the user checks this box, before the action settles. */
7
+ readonly checked: boolean;
8
+ /** The Root is pending and this box's optimistic state differs from its committed state. */
9
+ readonly pending: boolean;
10
+ /** Disabled by its own prop or by `Root disabled`. */
11
+ readonly disabled: boolean;
12
+ }
13
+ export interface CheckboxGroupItemProps extends Omit<ComponentPropsWithRef<"input">, "type" | "name" | "value" | "checked" | "defaultChecked" | "defaultValue" | "form" | "required" | "aria-checked" | "onChange" | "className" | "style" | "children"> {
14
+ /** The value this box contributes when checked. Must be unique within the Root. */
15
+ value: string;
16
+ /**
17
+ * Native `disabled`: unfocusable, never dispatches, barred from constraint validation. A
18
+ * `Parent` leaves a disabled Item's value alone and derives its state without it; a checked
19
+ * disabled Item does not satisfy the group's `required`.
20
+ */
21
+ disabled?: boolean;
22
+ /**
23
+ * Forwarded to the Item's `<ViewTransition default>`. Default: no boundary. Fires only on the
24
+ * commit that settles the action (or rolls it back), never on the optimistic check; animate the
25
+ * check itself with CSS on `:checked`.
26
+ *
27
+ * Static: without `transition` the part renders no `<ViewTransition>`; changing it between
28
+ * `undefined` and a value remounts the element. Any value, `"none"` included, makes a mount or
29
+ * `<Activity>` reveal of this part inside a transition start a document view transition: the
30
+ * page cross-fades for about 250 ms and the next transition commit waits for it (issue #35).
31
+ */
32
+ transition?: ViewTransitionClass;
33
+ className?: StateValue<string | undefined, CheckboxGroupItemState>;
34
+ style?: StateValue<CSSProperties | undefined, CheckboxGroupItemState>;
35
+ /** Replace the rendered element. Must keep an `<input>`; the library sets `type="checkbox"`. */
36
+ render?: RenderProp<ComponentPropsWithRef<"input">, CheckboxGroupItemState>;
37
+ }
38
+ /**
39
+ * One `<input type="checkbox">` of the group, checked while its `value` is in the group's set.
40
+ * Its DOM `checked` is the optimistic state (`checked={optimistic.has(value)}`): react-dom
41
+ * restores a controlled input to its props after every event, and only the sync-lane optimistic
42
+ * value survives that restore.
43
+ *
44
+ * Owned keys (conventions 1.2; a `render` element's value is overridden): `type`, `name`,
45
+ * `value`, `checked`, `defaultChecked` (never rendered), `disabled`, `form`, `required`
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
48
+ * first, then the library's. `role` passes through.
49
+ */
50
+ export declare function CheckboxGroupItem({ value, disabled: disabledProp, transition, className, style, render, ...rest }: CheckboxGroupItemProps): import("react").ReactNode;
51
+ export declare namespace CheckboxGroupItem {
52
+ var displayName: string;
53
+ }
54
+ //#endregion
55
+ //# sourceMappingURL=checkbox-group-item.d.mts.map
@@ -0,0 +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"}
@@ -0,0 +1,90 @@
1
+ "use client";
2
+ import { useTransitionBoundary } from "../internal/transition-boundary.mjs";
3
+ import { dataAttr } from "../internal/data-attr.mjs";
4
+ import { useRender } from "../internal/use-render.mjs";
5
+ import { guardCheckableChange, useNativeChecked } from "../internal/use-native-checked.mjs";
6
+ import { syncPresence } from "../internal/sync-presence.mjs";
7
+ import { useCheckboxGroupContext } from "./checkbox-group-context.mjs";
8
+ import { useLayoutEffect } from "react";
9
+ //#region src/checkbox-group/checkbox-group-item.tsx
10
+ /**
11
+ * One `<input type="checkbox">` of the group, checked while its `value` is in the group's set.
12
+ * Its DOM `checked` is the optimistic state (`checked={optimistic.has(value)}`): react-dom
13
+ * restores a controlled input to its props after every event, and only the sync-lane optimistic
14
+ * value survives that restore.
15
+ *
16
+ * Owned keys (conventions 1.2; a `render` element's value is overridden): `type`, `name`,
17
+ * `value`, `checked`, `defaultChecked` (never rendered), `disabled`, `form`, `required`
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
20
+ * first, then the library's. `role` passes through.
21
+ */
22
+ function CheckboxGroupItem({ value, disabled: disabledProp = false, transition, className, style, render, ...rest }) {
23
+ const ctx = useCheckboxGroupContext("CheckboxGroup.Item");
24
+ const checked = ctx.optimistic.has(value);
25
+ const pending = ctx.pending && checked !== ctx.committed.has(value);
26
+ const disabled = ctx.disabled || disabledProp;
27
+ const required = ctx.required;
28
+ const { registerItem } = ctx;
29
+ useLayoutEffect(() => registerItem(value, disabledProp), [
30
+ registerItem,
31
+ value,
32
+ disabledProp
33
+ ]);
34
+ const inputRef = useNativeChecked({
35
+ type: "checkbox",
36
+ component: "CheckboxGroup.Item",
37
+ checked,
38
+ group: true,
39
+ onItemMounted: (el) => {
40
+ if (el !== null) {
41
+ syncPresence(el, "data-checked", checked);
42
+ syncPresence(el, "data-pending", pending);
43
+ syncPresence(el, "data-disabled", disabled);
44
+ syncPresence(el, "required", required);
45
+ }
46
+ ctx.onItemMounted(el);
47
+ },
48
+ defaultChecked: ctx.defaultValue === void 0 ? void 0 : ctx.defaultValue.has(value)
49
+ });
50
+ const element = useRender({
51
+ defaultElement: "input",
52
+ render,
53
+ state: {
54
+ value,
55
+ checked,
56
+ pending,
57
+ disabled
58
+ },
59
+ className,
60
+ style,
61
+ children: void 0,
62
+ ref: inputRef,
63
+ props: rest,
64
+ libraryProps: {
65
+ type: "checkbox",
66
+ name: ctx.name,
67
+ value,
68
+ checked,
69
+ defaultChecked: void 0,
70
+ "aria-checked": void 0,
71
+ disabled: disabledProp,
72
+ form: ctx.form,
73
+ required,
74
+ "data-checked": dataAttr(checked),
75
+ "data-pending": dataAttr(pending),
76
+ "data-disabled": dataAttr(disabled),
77
+ onChange: (event) => {
78
+ if (disabled) return;
79
+ const nativeEvent = event.nativeEvent;
80
+ guardCheckableChange(nativeEvent, () => ctx.toggle(value, !checked, nativeEvent), "CheckboxGroup.Item");
81
+ }
82
+ }
83
+ });
84
+ return useTransitionBoundary("CheckboxGroup.Item", transition, element);
85
+ }
86
+ CheckboxGroupItem.displayName = "CheckboxGroupItem";
87
+ //#endregion
88
+ export { CheckboxGroupItem };
89
+
90
+ //# sourceMappingURL=checkbox-group-item.mjs.map
@@ -0,0 +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"}
@@ -0,0 +1,21 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CheckboxGroupRootState } from "./checkbox-group-root.mjs";
3
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
4
+ //#region src/checkbox-group/checkbox-group-label.d.ts
5
+ export interface CheckboxGroupLabelProps extends Omit<ComponentPropsWithRef<"legend">, "className" | "style" | "children"> {
6
+ className?: StateValue<string | undefined, CheckboxGroupRootState>;
7
+ style?: StateValue<CSSProperties | undefined, CheckboxGroupRootState>;
8
+ /** Receives the Root's state: a group-level pending indicator goes here. */
9
+ children?: StateValue<ReactNode, CheckboxGroupRootState>;
10
+ render?: RenderProp<ComponentPropsWithRef<"legend">, CheckboxGroupRootState>;
11
+ }
12
+ /**
13
+ * The group's `<legend>`, which names the fieldset natively. Optional; must be the **first child**
14
+ * of `CheckboxGroup.Root` (HTML content model). Its state is the Root's state. Owns no keys.
15
+ */
16
+ export declare function CheckboxGroupLabel({ className, style, children, render, ...rest }: CheckboxGroupLabelProps): ReactNode;
17
+ export declare namespace CheckboxGroupLabel {
18
+ var displayName: string;
19
+ }
20
+ //#endregion
21
+ //# sourceMappingURL=checkbox-group-label.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-group-label.d.mts","names":[],"sources":["../../src/checkbox-group/checkbox-group-label.tsx"],"mappings":";;;;iBAOiB,gCAAgC,KAC/C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;EAE9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,iCAAiC;;;;;;wBAOvC,qBACd,WACA,OACA,UACA,WACG,QACF,0BAAuB;yBANV"}
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { useRender } from "../internal/use-render.mjs";
3
+ import { useCheckboxGroupContext } from "./checkbox-group-context.mjs";
4
+ //#region src/checkbox-group/checkbox-group-label.tsx
5
+ /**
6
+ * The group's `<legend>`, which names the fieldset natively. Optional; must be the **first child**
7
+ * of `CheckboxGroup.Root` (HTML content model). Its state is the Root's state. Owns no keys.
8
+ */
9
+ function CheckboxGroupLabel({ className, style, children, render, ...rest }) {
10
+ const ctx = useCheckboxGroupContext("CheckboxGroup.Label");
11
+ const state = {
12
+ value: ctx.value,
13
+ pending: ctx.pending,
14
+ disabled: ctx.disabled
15
+ };
16
+ return useRender({
17
+ defaultElement: "legend",
18
+ render,
19
+ state,
20
+ className,
21
+ style,
22
+ children,
23
+ props: rest
24
+ });
25
+ }
26
+ CheckboxGroupLabel.displayName = "CheckboxGroupLabel";
27
+ //#endregion
28
+ export { CheckboxGroupLabel };
29
+
30
+ //# sourceMappingURL=checkbox-group-label.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-group-label.mjs","names":[],"sources":["../../src/checkbox-group/checkbox-group-label.tsx"],"sourcesContent":["\"use client\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { useCheckboxGroupContext } from \"./checkbox-group-context.js\";\nimport type { CheckboxGroupRootState } from \"./checkbox-group-root.js\";\n\nexport interface CheckboxGroupLabelProps extends Omit<\n ComponentPropsWithRef<\"legend\">,\n \"className\" | \"style\" | \"children\"\n> {\n className?: StateValue<string | undefined, CheckboxGroupRootState>;\n style?: StateValue<CSSProperties | undefined, CheckboxGroupRootState>;\n /** Receives the Root's state: a group-level pending indicator goes here. */\n children?: StateValue<ReactNode, CheckboxGroupRootState>;\n render?: RenderProp<ComponentPropsWithRef<\"legend\">, CheckboxGroupRootState>;\n}\n\n/**\n * The group's `<legend>`, which names the fieldset natively. Optional; must be the **first child**\n * of `CheckboxGroup.Root` (HTML content model). Its state is the Root's state. Owns no keys.\n */\nexport function CheckboxGroupLabel({\n className,\n style,\n children,\n render,\n ...rest\n}: CheckboxGroupLabelProps) {\n const ctx = useCheckboxGroupContext(\"CheckboxGroup.Label\");\n const state: CheckboxGroupRootState = {\n value: ctx.value,\n pending: ctx.pending,\n disabled: ctx.disabled,\n };\n return useRender<ComponentPropsWithRef<\"legend\">, CheckboxGroupRootState>({\n defaultElement: \"legend\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n });\n}\n\nCheckboxGroupLabel.displayName = \"CheckboxGroupLabel\";\n"],"mappings":";;;;;;;;AAsBA,SAAgB,mBAAmB,EACjC,WACA,OACA,UACA,QACA,GAAG,QACuB;CAC1B,MAAM,MAAM,wBAAwB,qBAAqB;CACzD,MAAM,QAAgC;EACpC,OAAO,IAAI;EACX,SAAS,IAAI;EACb,UAAU,IAAI;CAChB;CACA,OAAO,UAAmE;EACxE,gBAAgB;EAChB;EACA;EACA;EACA;EACA;EACA,OAAO;CACT,CAAC;AACH;AAEA,mBAAmB,cAAc"}
@@ -0,0 +1,68 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ViewTransitionClass } from "react";
3
+ //#region src/checkbox-group/checkbox-group-parent.d.ts
4
+ export interface CheckboxGroupParentState {
5
+ readonly values: readonly string[];
6
+ /** Every value in `values` is optimistically checked (`false` when `values` is empty). */
7
+ readonly checked: boolean;
8
+ /**
9
+ * Some but not all of `values` are optimistically checked. Never true together with
10
+ * `checked`. Not suspended while pending (it is derived from optimistic state).
11
+ */
12
+ readonly indeterminate: boolean;
13
+ /** The Root is pending and at least one of `values` differs between optimistic and committed. */
14
+ readonly pending: boolean;
15
+ /** Disabled by its own prop or by `Root disabled`. */
16
+ readonly disabled: boolean;
17
+ }
18
+ export interface CheckboxGroupParentProps extends Omit<ComponentPropsWithRef<"input">, "type" | "name" | "value" | "checked" | "defaultChecked" | "defaultValue" | "form" | "required" | "autoComplete" | "aria-checked" | "onChange" | "className" | "style" | "children"> {
19
+ /**
20
+ * The Item values this Parent controls (usually every Item of the group). Its checked and
21
+ * mixed states are derived from them; its click checks or unchecks all of them. Values with
22
+ * no Item are still added to / removed from the group's value.
23
+ *
24
+ * Values whose Items are disabled (their own `disabled` prop) are left alone: the click does
25
+ * not change them and the derivation ignores them, so the Parent shows checked when every
26
+ * enabled Item is. When every value has only disabled Items, the Parent acts on all of them
27
+ * (disable the Parent to make it inert). Before hydration the server-rendered state counts
28
+ * disabled Items too; it settles when the Items hydrate.
29
+ */
30
+ values: string[];
31
+ /** Native `disabled`: unfocusable, never dispatches. */
32
+ disabled?: boolean;
33
+ /**
34
+ * Forwarded to the Parent's `<ViewTransition default>`. Default: no boundary. Fires only on the
35
+ * commit that settles the action (or rolls it back), never on the optimistic flip; animate the
36
+ * flip itself with CSS on `:checked` / `:indeterminate`.
37
+ *
38
+ * Static: without `transition` the part renders no `<ViewTransition>`; changing it between
39
+ * `undefined` and a value remounts the element. Any value, `"none"` included, makes a mount or
40
+ * `<Activity>` reveal of this part inside a transition start a document view transition: the
41
+ * page cross-fades for about 250 ms and the next transition commit waits for it (issue #35).
42
+ */
43
+ transition?: ViewTransitionClass;
44
+ className?: StateValue<string | undefined, CheckboxGroupParentState>;
45
+ style?: StateValue<CSSProperties | undefined, CheckboxGroupParentState>;
46
+ /** Replace the rendered element. Must keep an `<input>`; the library sets `type="checkbox"`. */
47
+ render?: RenderProp<ComponentPropsWithRef<"input">, CheckboxGroupParentState>;
48
+ }
49
+ /**
50
+ * The mixed-state "select all" checkbox of a group (WAI-ARIA APG "Checkbox (Mixed-State)"):
51
+ * `<input type="checkbox">` checked when every value in `values` is in the group's optimistic
52
+ * set, mixed (`el.indeterminate`, `data-indeterminate`) when some are. A click checks every value
53
+ * when mixed, unchecks every value when checked, and from unchecked restores the last partial
54
+ * combination of its values the group committed (seeded at mount), else checks every value. Each
55
+ * click is one dispatch through the Root's `valueChangeAction`. Never submitted (no `name`).
56
+ * "Its values" are those whose Items are enabled: disabled Items are left alone (see `values`).
57
+ *
58
+ * Owned keys (conventions 1.2): `type`, `name` (removed), `value` (removed), `checked`,
59
+ * `defaultChecked`, `indeterminate` (stripped; the property is set), `required` (removed), `form`
60
+ * (removed), `autoComplete` (`"off"`), `disabled`, `aria-checked` (removed), `data-checked`, `data-indeterminate`,
61
+ * `data-pending`, `data-disabled`. `onChange` is merged.
62
+ */
63
+ export declare function CheckboxGroupParent({ values, disabled: disabledProp, transition, className, style, render, ...rest }: CheckboxGroupParentProps): import("react").ReactNode;
64
+ export declare namespace CheckboxGroupParent {
65
+ var displayName: string;
66
+ }
67
+ //#endregion
68
+ //# sourceMappingURL=checkbox-group-parent.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-group-parent.d.mts","names":[],"sources":["../../src/checkbox-group/checkbox-group-parent.tsx"],"mappings":";;;iBAaiB;WACN;;WAEA;;;;;WAKA;;WAEA;;WAEA;;iBAGM,iCAAiC,KAChD;;;;;;;;;;;;EA2BA;;EAEA;;;;;;;;;;;EAWA,aAAa;EACb,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;EAE9C,SAAS,WAAW,gCAAgC;;;;;;;;;;;;;;;;wBA2BtC,sBACd,QACA,UAAU,cACV,YACA,WACA,OACA,WACG,QACF,2CAAwB;yBARX"}
@@ -0,0 +1,145 @@
1
+ "use client";
2
+ import { useTransitionBoundary } from "../internal/transition-boundary.mjs";
3
+ import { dataAttr } from "../internal/data-attr.mjs";
4
+ import { useRender } from "../internal/use-render.mjs";
5
+ import { useFormReset } from "../internal/use-form-reset.mjs";
6
+ import { guardCheckableChange, useNativeChecked } from "../internal/use-native-checked.mjs";
7
+ import { syncPresence } from "../internal/sync-presence.mjs";
8
+ import { enabledValues, useCheckboxGroupContext } from "./checkbox-group-context.mjs";
9
+ import { useCallback, useLayoutEffect, useMemo, useRef, useSyncExternalStore } from "react";
10
+ //#region src/checkbox-group/checkbox-group-parent.tsx
11
+ const subscribeNothing = () => () => {};
12
+ /** `checked` / `indeterminate` of a Parent over `values` against `set` (design 6.1). */
13
+ function derive(values, set) {
14
+ let inSet = 0;
15
+ for (const v of values) if (set.has(v)) inSet += 1;
16
+ const checked = values.length > 0 && inSet === values.length;
17
+ return {
18
+ checked,
19
+ indeterminate: inSet > 0 && !checked
20
+ };
21
+ }
22
+ /**
23
+ * The mixed-state "select all" checkbox of a group (WAI-ARIA APG "Checkbox (Mixed-State)"):
24
+ * `<input type="checkbox">` checked when every value in `values` is in the group's optimistic
25
+ * set, mixed (`el.indeterminate`, `data-indeterminate`) when some are. A click checks every value
26
+ * when mixed, unchecks every value when checked, and from unchecked restores the last partial
27
+ * combination of its values the group committed (seeded at mount), else checks every value. Each
28
+ * click is one dispatch through the Root's `valueChangeAction`. Never submitted (no `name`).
29
+ * "Its values" are those whose Items are enabled: disabled Items are left alone (see `values`).
30
+ *
31
+ * Owned keys (conventions 1.2): `type`, `name` (removed), `value` (removed), `checked`,
32
+ * `defaultChecked`, `indeterminate` (stripped; the property is set), `required` (removed), `form`
33
+ * (removed), `autoComplete` (`"off"`), `disabled`, `aria-checked` (removed), `data-checked`, `data-indeterminate`,
34
+ * `data-pending`, `data-disabled`. `onChange` is merged.
35
+ */
36
+ function CheckboxGroupParent({ values, disabled: disabledProp = false, transition, className, style, render, ...rest }) {
37
+ const ctx = useCheckboxGroupContext("CheckboxGroup.Parent");
38
+ const hydrating = useSyncExternalStore(subscribeNothing, () => false, () => true);
39
+ const { disabledItems } = ctx;
40
+ const effective = useMemo(() => hydrating ? values : enabledValues(values, disabledItems), [
41
+ hydrating,
42
+ values,
43
+ disabledItems
44
+ ]);
45
+ const { checked, indeterminate } = derive(effective, ctx.optimistic);
46
+ const pending = ctx.pending && values.some((v) => ctx.optimistic.has(v) !== ctx.committed.has(v));
47
+ const disabled = ctx.disabled || disabledProp;
48
+ const memory = useRef(null);
49
+ const { committed } = ctx;
50
+ useLayoutEffect(() => {
51
+ const inCommitted = effective.filter((v) => committed.has(v));
52
+ if (inCommitted.length > 0 && inCommitted.length < effective.length) memory.current = inCommitted;
53
+ }, [committed, effective]);
54
+ const inputRef = useNativeChecked({
55
+ type: "checkbox",
56
+ component: "CheckboxGroup.Parent",
57
+ checked,
58
+ indeterminate,
59
+ group: true,
60
+ onItemMounted: (el) => {
61
+ if (el !== null) {
62
+ if (el.checked !== checked) ctx.reportParent(values, el.checked);
63
+ syncPresence(el, "data-checked", checked);
64
+ syncPresence(el, "data-indeterminate", indeterminate);
65
+ syncPresence(el, "data-pending", pending);
66
+ syncPresence(el, "data-disabled", disabled);
67
+ }
68
+ ctx.onItemMounted(el);
69
+ },
70
+ defaultChecked: ctx.defaultValue === void 0 ? void 0 : derive(effective, ctx.defaultValue).checked
71
+ });
72
+ const node = useRef(null);
73
+ const ref = useCallback((el) => {
74
+ node.current = el;
75
+ const cleanup = inputRef(el);
76
+ return () => {
77
+ node.current = null;
78
+ if (typeof cleanup === "function") cleanup();
79
+ };
80
+ }, [inputRef]);
81
+ useFormReset(node, () => {
82
+ const el = node.current;
83
+ if (el !== null && el.checked !== checked) el.checked = checked;
84
+ });
85
+ /** The click cycle of design 6.2. */
86
+ const cyclePatch = () => {
87
+ if (checked) return {
88
+ added: [],
89
+ removed: [...effective]
90
+ };
91
+ if (indeterminate) return {
92
+ added: effective.filter((v) => !ctx.optimistic.has(v)),
93
+ removed: []
94
+ };
95
+ const restore = memory.current?.filter((v) => effective.includes(v)) ?? [];
96
+ return {
97
+ added: restore.length > 0 ? restore : [...effective],
98
+ removed: []
99
+ };
100
+ };
101
+ const element = useRender({
102
+ defaultElement: "input",
103
+ render,
104
+ state: {
105
+ values,
106
+ checked,
107
+ indeterminate,
108
+ pending,
109
+ disabled
110
+ },
111
+ className,
112
+ style,
113
+ children: void 0,
114
+ ref,
115
+ props: rest,
116
+ libraryProps: {
117
+ type: "checkbox",
118
+ name: void 0,
119
+ value: void 0,
120
+ required: void 0,
121
+ form: void 0,
122
+ autoComplete: "off",
123
+ checked,
124
+ defaultChecked: void 0,
125
+ indeterminate: void 0,
126
+ "aria-checked": void 0,
127
+ disabled: disabledProp,
128
+ "data-checked": dataAttr(checked),
129
+ "data-indeterminate": dataAttr(indeterminate),
130
+ "data-pending": dataAttr(pending),
131
+ "data-disabled": dataAttr(disabled),
132
+ onChange: (event) => {
133
+ if (disabled) return;
134
+ const nativeEvent = event.nativeEvent;
135
+ guardCheckableChange(nativeEvent, () => ctx.apply(cyclePatch(), nativeEvent), "CheckboxGroup.Parent");
136
+ }
137
+ }
138
+ });
139
+ return useTransitionBoundary("CheckboxGroup.Parent", transition, element);
140
+ }
141
+ CheckboxGroupParent.displayName = "CheckboxGroupParent";
142
+ //#endregion
143
+ export { CheckboxGroupParent };
144
+
145
+ //# sourceMappingURL=checkbox-group-parent.mjs.map