@funstack/ui 0.1.0-alpha.0 → 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 (154) hide show
  1. package/README.md +1 -1
  2. package/dist/checkbox-group/checkbox-group-context.mjs +24 -0
  3. package/dist/checkbox-group/checkbox-group-context.mjs.map +1 -0
  4. package/dist/checkbox-group/checkbox-group-item.d.mts +55 -0
  5. package/dist/checkbox-group/checkbox-group-item.d.mts.map +1 -0
  6. package/dist/checkbox-group/checkbox-group-item.mjs +90 -0
  7. package/dist/checkbox-group/checkbox-group-item.mjs.map +1 -0
  8. package/dist/checkbox-group/checkbox-group-label.d.mts +21 -0
  9. package/dist/checkbox-group/checkbox-group-label.d.mts.map +1 -0
  10. package/dist/checkbox-group/checkbox-group-label.mjs +30 -0
  11. package/dist/checkbox-group/checkbox-group-label.mjs.map +1 -0
  12. package/dist/checkbox-group/checkbox-group-parent.d.mts +68 -0
  13. package/dist/checkbox-group/checkbox-group-parent.d.mts.map +1 -0
  14. package/dist/checkbox-group/checkbox-group-parent.mjs +145 -0
  15. package/dist/checkbox-group/checkbox-group-parent.mjs.map +1 -0
  16. package/dist/checkbox-group/checkbox-group-root.d.mts +100 -0
  17. package/dist/checkbox-group/checkbox-group-root.d.mts.map +1 -0
  18. package/dist/checkbox-group/checkbox-group-root.mjs +291 -0
  19. package/dist/checkbox-group/checkbox-group-root.mjs.map +1 -0
  20. package/dist/checkbox-group/index.d.mts +23 -0
  21. package/dist/checkbox-group/index.d.mts.map +1 -0
  22. package/dist/checkbox-group/index.mjs +23 -0
  23. package/dist/checkbox-group/index.mjs.map +1 -0
  24. package/dist/dialog/dialog-close.d.mts.map +1 -1
  25. package/dist/dialog/dialog-close.mjs +4 -4
  26. package/dist/dialog/dialog-close.mjs.map +1 -1
  27. package/dist/dialog/dialog-context.mjs.map +1 -1
  28. package/dist/dialog/dialog-popup.mjs +1 -0
  29. package/dist/dialog/dialog-popup.mjs.map +1 -1
  30. package/dist/dialog/dialog-root.mjs +9 -1
  31. package/dist/dialog/dialog-root.mjs.map +1 -1
  32. package/dist/index.d.mts +23 -1
  33. package/dist/index.mjs +4 -1
  34. package/dist/internal/anchor-position.d.mts +7 -0
  35. package/dist/internal/anchor-position.d.mts.map +1 -0
  36. package/dist/internal/anchor-position.mjs +16 -0
  37. package/dist/internal/anchor-position.mjs.map +1 -0
  38. package/dist/internal/platform-attributes.d.mts +6 -0
  39. package/dist/internal/platform-attributes.d.mts.map +1 -1
  40. package/dist/internal/sync-presence.mjs +19 -0
  41. package/dist/internal/sync-presence.mjs.map +1 -0
  42. package/dist/internal/use-action-trigger.mjs +58 -0
  43. package/dist/internal/use-action-trigger.mjs.map +1 -0
  44. package/dist/internal/use-delayed-pair.mjs +40 -0
  45. package/dist/internal/use-delayed-pair.mjs.map +1 -0
  46. package/dist/internal/use-exit-animation.mjs +55 -0
  47. package/dist/internal/use-exit-animation.mjs.map +1 -0
  48. package/dist/internal/use-native-group-reconciliation.mjs +2 -2
  49. package/dist/internal/use-native-group-reconciliation.mjs.map +1 -1
  50. package/dist/internal/use-popover-popup.mjs +274 -0
  51. package/dist/internal/use-popover-popup.mjs.map +1 -0
  52. package/dist/internal/use-popover-root.d.mts +2 -0
  53. package/dist/internal/use-popover-root.mjs +112 -0
  54. package/dist/internal/use-popover-root.mjs.map +1 -0
  55. package/dist/internal/use-popover-trigger.mjs +86 -0
  56. package/dist/internal/use-popover-trigger.mjs.map +1 -0
  57. package/dist/menu/index.d.mts +34 -0
  58. package/dist/menu/index.d.mts.map +1 -0
  59. package/dist/menu/index.mjs +34 -0
  60. package/dist/menu/index.mjs.map +1 -0
  61. package/dist/menu/menu-checkbox-item.d.mts +42 -0
  62. package/dist/menu/menu-checkbox-item.d.mts.map +1 -0
  63. package/dist/menu/menu-checkbox-item.mjs +71 -0
  64. package/dist/menu/menu-checkbox-item.mjs.map +1 -0
  65. package/dist/menu/menu-context.d.mts +1 -0
  66. package/dist/menu/menu-context.mjs +28 -0
  67. package/dist/menu/menu-context.mjs.map +1 -0
  68. package/dist/menu/menu-dom.mjs +37 -0
  69. package/dist/menu/menu-dom.mjs.map +1 -0
  70. package/dist/menu/menu-group.d.mts +48 -0
  71. package/dist/menu/menu-group.d.mts.map +1 -0
  72. package/dist/menu/menu-group.mjs +69 -0
  73. package/dist/menu/menu-group.mjs.map +1 -0
  74. package/dist/menu/menu-hover.mjs +29 -0
  75. package/dist/menu/menu-hover.mjs.map +1 -0
  76. package/dist/menu/menu-item.d.mts +45 -0
  77. package/dist/menu/menu-item.d.mts.map +1 -0
  78. package/dist/menu/menu-item.mjs +54 -0
  79. package/dist/menu/menu-item.mjs.map +1 -0
  80. package/dist/menu/menu-popup.d.mts +69 -0
  81. package/dist/menu/menu-popup.d.mts.map +1 -0
  82. package/dist/menu/menu-popup.mjs +207 -0
  83. package/dist/menu/menu-popup.mjs.map +1 -0
  84. package/dist/menu/menu-radio-group.d.mts +37 -0
  85. package/dist/menu/menu-radio-group.d.mts.map +1 -0
  86. package/dist/menu/menu-radio-group.mjs +72 -0
  87. package/dist/menu/menu-radio-group.mjs.map +1 -0
  88. package/dist/menu/menu-radio-item.d.mts +33 -0
  89. package/dist/menu/menu-radio-item.d.mts.map +1 -0
  90. package/dist/menu/menu-radio-item.mjs +62 -0
  91. package/dist/menu/menu-radio-item.mjs.map +1 -0
  92. package/dist/menu/menu-root.d.mts +54 -0
  93. package/dist/menu/menu-root.d.mts.map +1 -0
  94. package/dist/menu/menu-root.mjs +102 -0
  95. package/dist/menu/menu-root.mjs.map +1 -0
  96. package/dist/menu/menu-submenu-trigger.d.mts +31 -0
  97. package/dist/menu/menu-submenu-trigger.d.mts.map +1 -0
  98. package/dist/menu/menu-submenu-trigger.mjs +92 -0
  99. package/dist/menu/menu-submenu-trigger.mjs.map +1 -0
  100. package/dist/menu/menu-trigger.d.mts +36 -0
  101. package/dist/menu/menu-trigger.d.mts.map +1 -0
  102. package/dist/menu/menu-trigger.mjs +81 -0
  103. package/dist/menu/menu-trigger.mjs.map +1 -0
  104. package/dist/menu/use-menu-item.mjs +54 -0
  105. package/dist/menu/use-menu-item.mjs.map +1 -0
  106. package/dist/popover/index.d.mts +28 -0
  107. package/dist/popover/index.d.mts.map +1 -0
  108. package/dist/popover/index.mjs +28 -0
  109. package/dist/popover/index.mjs.map +1 -0
  110. package/dist/popover/popover-close.d.mts +41 -0
  111. package/dist/popover/popover-close.d.mts.map +1 -0
  112. package/dist/popover/popover-close.mjs +90 -0
  113. package/dist/popover/popover-close.mjs.map +1 -0
  114. package/dist/popover/popover-context.mjs +26 -0
  115. package/dist/popover/popover-context.mjs.map +1 -0
  116. package/dist/popover/popover-description.d.mts +22 -0
  117. package/dist/popover/popover-description.d.mts.map +1 -0
  118. package/dist/popover/popover-description.mjs +28 -0
  119. package/dist/popover/popover-description.mjs.map +1 -0
  120. package/dist/popover/popover-popup.d.mts +82 -0
  121. package/dist/popover/popover-popup.d.mts.map +1 -0
  122. package/dist/popover/popover-popup.mjs +93 -0
  123. package/dist/popover/popover-popup.mjs.map +1 -0
  124. package/dist/popover/popover-root.d.mts +64 -0
  125. package/dist/popover/popover-root.d.mts.map +1 -0
  126. package/dist/popover/popover-root.mjs +39 -0
  127. package/dist/popover/popover-root.mjs.map +1 -0
  128. package/dist/popover/popover-title.d.mts +23 -0
  129. package/dist/popover/popover-title.d.mts.map +1 -0
  130. package/dist/popover/popover-title.mjs +28 -0
  131. package/dist/popover/popover-title.mjs.map +1 -0
  132. package/dist/popover/popover-trigger.d.mts +37 -0
  133. package/dist/popover/popover-trigger.d.mts.map +1 -0
  134. package/dist/popover/popover-trigger.mjs +40 -0
  135. package/dist/popover/popover-trigger.mjs.map +1 -0
  136. package/dist/radio-group/radio-group-item.d.mts.map +1 -1
  137. package/dist/radio-group/radio-group-item.mjs +1 -6
  138. package/dist/radio-group/radio-group-item.mjs.map +1 -1
  139. package/dist/tabs/tabs-context.mjs +2 -1
  140. package/dist/tabs/tabs-context.mjs.map +1 -1
  141. package/dist/tabs/tabs-list.d.mts +1 -1
  142. package/dist/tabs/tabs-list.d.mts.map +1 -1
  143. package/dist/tabs/tabs-list.mjs +17 -9
  144. package/dist/tabs/tabs-list.mjs.map +1 -1
  145. package/dist/tabs/tabs-tab.d.mts +1 -1
  146. package/dist/tabs/tabs-tab.d.mts.map +1 -1
  147. package/dist/tabs/tabs-tab.mjs +6 -3
  148. package/dist/tabs/tabs-tab.mjs.map +1 -1
  149. package/dist/tooltip/tooltip-popup.d.mts.map +1 -1
  150. package/dist/tooltip/tooltip-popup.mjs +2 -7
  151. package/dist/tooltip/tooltip-popup.mjs.map +1 -1
  152. package/dist/tooltip/use-tooltip-interaction.mjs +5 -17
  153. package/dist/tooltip/use-tooltip-interaction.mjs.map +1 -1
  154. package/package.json +4 -1
package/README.md CHANGED
@@ -21,7 +21,7 @@ Documentation: https://ui.funstack.work
21
21
  ## Installation
22
22
 
23
23
  ```sh
24
- npm install @funstack/ui
24
+ npm install @funstack/ui@alpha
25
25
  ```
26
26
 
27
27
  React 19.3 or later is required (`react` and `react-dom` are peer dependencies).
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-group-parent.mjs","names":[],"sources":["../../src/checkbox-group/checkbox-group-parent.tsx"],"sourcesContent":["\"use client\";\nimport { useCallback, useLayoutEffect, useMemo, useRef, useSyncExternalStore } 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 { useFormReset } from \"../internal/use-form-reset.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { enabledValues, useCheckboxGroupContext } from \"./checkbox-group-context.js\";\nimport type { CheckboxGroupPatch } from \"./checkbox-group-context.js\";\nimport { syncPresence } from \"../internal/sync-presence.js\";\n\nexport interface CheckboxGroupParentState {\n readonly values: readonly string[];\n /** Every value in `values` is optimistically checked (`false` when `values` is empty). */\n readonly checked: boolean;\n /**\n * Some but not all of `values` are optimistically checked. Never true together with\n * `checked`. Not suspended while pending (it is derived from optimistic state).\n */\n readonly indeterminate: boolean;\n /** The Root is pending and at least one of `values` differs between optimistic and committed. */\n readonly pending: boolean;\n /** Disabled by its own prop or by `Root disabled`. */\n readonly disabled: boolean;\n}\n\nexport interface CheckboxGroupParentProps extends Omit<\n ComponentPropsWithRef<\"input\">,\n | \"type\"\n | \"name\"\n | \"value\"\n | \"checked\"\n | \"defaultChecked\"\n | \"defaultValue\"\n | \"form\"\n | \"required\"\n | \"autoComplete\"\n | \"aria-checked\"\n | \"onChange\"\n | \"className\"\n | \"style\"\n | \"children\"\n> {\n /**\n * The Item values this Parent controls (usually every Item of the group). Its checked and\n * mixed states are derived from them; its click checks or unchecks all of them. Values with\n * no Item are still added to / removed from the group's value.\n *\n * Values whose Items are disabled (their own `disabled` prop) are left alone: the click does\n * not change them and the derivation ignores them, so the Parent shows checked when every\n * enabled Item is. When every value has only disabled Items, the Parent acts on all of them\n * (disable the Parent to make it inert). Before hydration the server-rendered state counts\n * disabled Items too; it settles when the Items hydrate.\n */\n values: string[];\n /** Native `disabled`: unfocusable, never dispatches. */\n disabled?: boolean;\n /**\n * Forwarded to the Parent's `<ViewTransition default>`. Default: no boundary. Fires only on the\n * commit that settles the action (or rolls it back), never on the optimistic flip; animate the\n * flip itself with CSS on `:checked` / `:indeterminate`.\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, CheckboxGroupParentState>;\n style?: StateValue<CSSProperties | undefined, CheckboxGroupParentState>;\n /** Replace the rendered element. Must keep an `<input>`; the library sets `type=\"checkbox\"`. */\n render?: RenderProp<ComponentPropsWithRef<\"input\">, CheckboxGroupParentState>;\n}\n\nconst subscribeNothing = () => () => {};\n\n/** `checked` / `indeterminate` of a Parent over `values` against `set` (design 6.1). */\nfunction derive(values: readonly string[], set: ReadonlySet<string>) {\n let inSet = 0;\n for (const v of values) if (set.has(v)) inSet += 1;\n const checked = values.length > 0 && inSet === values.length;\n return { checked, indeterminate: inSet > 0 && !checked };\n}\n\n/**\n * The mixed-state \"select all\" checkbox of a group (WAI-ARIA APG \"Checkbox (Mixed-State)\"):\n * `<input type=\"checkbox\">` checked when every value in `values` is in the group's optimistic\n * set, mixed (`el.indeterminate`, `data-indeterminate`) when some are. A click checks every value\n * when mixed, unchecks every value when checked, and from unchecked restores the last partial\n * combination of its values the group committed (seeded at mount), else checks every value. Each\n * click is one dispatch through the Root's `valueChangeAction`. Never submitted (no `name`).\n * \"Its values\" are those whose Items are enabled: disabled Items are left alone (see `values`).\n *\n * Owned keys (conventions 1.2): `type`, `name` (removed), `value` (removed), `checked`,\n * `defaultChecked`, `indeterminate` (stripped; the property is set), `required` (removed), `form`\n * (removed), `autoComplete` (`\"off\"`), `disabled`, `aria-checked` (removed), `data-checked`, `data-indeterminate`,\n * `data-pending`, `data-disabled`. `onChange` is merged.\n */\nexport function CheckboxGroupParent({\n values,\n disabled: disabledProp = false,\n transition,\n className,\n style,\n render,\n ...rest\n}: CheckboxGroupParentProps) {\n const ctx = useCheckboxGroupContext(\"CheckboxGroup.Parent\");\n // The values the Parent acts on: `values` minus disabled Items (design 6.2). A hydration\n // render uses every value, as the server did (it cannot know which Items are disabled), so\n // that the DOM `checked` it hydrates can be compared with the derivation for the\n // pre-hydration report below, also when this Parent hydrates after the Items registered.\n const hydrating = useSyncExternalStore(\n subscribeNothing,\n () => false,\n () => true,\n );\n const { disabledItems } = ctx;\n const effective = useMemo(\n () => (hydrating ? values : enabledValues(values, disabledItems)),\n [hydrating, values, disabledItems],\n );\n const { checked, indeterminate } = derive(effective, ctx.optimistic);\n const pending = ctx.pending && values.some((v) => ctx.optimistic.has(v) !== ctx.committed.has(v));\n const disabled = ctx.disabled || disabledProp;\n\n // The APG restore memory: the last partial combination of `values` the group committed\n // (design 6.2). Committed, not optimistic, so a partial state that only ever rolled back is\n // never restored. The first run seeds it from the mount-time value.\n const memory = useRef<readonly string[] | null>(null);\n const { committed } = ctx;\n useLayoutEffect(() => {\n const inCommitted = effective.filter((v) => committed.has(v));\n if (inCommitted.length > 0 && inCommitted.length < effective.length) {\n memory.current = inCommitted;\n }\n }, [committed, effective]);\n\n const inputRef = useNativeChecked({\n type: \"checkbox\",\n component: \"CheckboxGroup.Parent\",\n checked,\n indeterminate,\n group: true,\n onItemMounted: (el) => {\n if (el !== null) {\n // A click before hydration flipped the box (design 8.1): report it as the Parent's\n // semantic before the Root reads the group (which leaves disabled Items alone). Firefox's\n // form-state restoration cannot cause this: the Parent renders `autocomplete=\"off\"`.\n if (el.checked !== checked) ctx.reportParent(values, el.checked);\n syncPresence(el, \"data-checked\", checked);\n syncPresence(el, \"data-indeterminate\", indeterminate);\n syncPresence(el, \"data-pending\", pending);\n syncPresence(el, \"data-disabled\", disabled);\n }\n ctx.onItemMounted(el);\n },\n defaultChecked:\n ctx.defaultValue === undefined ? undefined : derive(effective, ctx.defaultValue).checked,\n });\n\n // A form reset sets the Parent's DOM `checked` to its `defaultChecked`, which in controlled\n // mode is React's mount-time value and can be stale (its `values` changed, it mounted after the\n // Items with another value). The Parent re-renders only if the Root dispatches; otherwise put\n // the derivation back (the Root's own microtask, queued after this one, may still dispatch,\n // and the re-render re-applies `checked`).\n const node = useRef<HTMLInputElement | null>(null);\n const ref = useCallback(\n (el: HTMLInputElement) => {\n node.current = el;\n const cleanup = inputRef(el);\n return () => {\n node.current = null;\n if (typeof cleanup === \"function\") cleanup();\n };\n },\n [inputRef],\n );\n useFormReset(node, () => {\n const el = node.current;\n if (el !== null && el.checked !== checked) el.checked = checked;\n });\n\n /** The click cycle of design 6.2. */\n const cyclePatch = (): CheckboxGroupPatch => {\n if (checked) return { added: [], removed: [...effective] };\n if (indeterminate) {\n return { added: effective.filter((v) => !ctx.optimistic.has(v)), removed: [] };\n }\n const restore = memory.current?.filter((v) => effective.includes(v)) ?? [];\n return { added: restore.length > 0 ? restore : [...effective], removed: [] };\n };\n\n const state: CheckboxGroupParentState = { values, checked, indeterminate, pending, disabled };\n\n const element = useRender<ComponentPropsWithRef<\"input\">, CheckboxGroupParentState>({\n defaultElement: \"input\",\n render,\n state,\n className,\n style,\n children: undefined,\n ref,\n props: rest,\n libraryProps: {\n type: \"checkbox\",\n // A Parent is not a value: it never posts and is never required.\n name: undefined,\n value: undefined,\n required: undefined,\n form: undefined,\n // Nothing to restore (it is not a value): without this, Firefox restores its `checked` on\n // reload and the mount read would take it for a click before hydration (design 8.1).\n autoComplete: \"off\",\n checked,\n defaultChecked: undefined,\n // Not a DOM attribute; the hook sets the property. Owned so that 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 disabled: disabledProp,\n \"data-checked\": dataAttr(checked),\n \"data-indeterminate\": dataAttr(indeterminate),\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n onChange: (event: ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n const nativeEvent = event.nativeEvent;\n guardCheckableChange(\n nativeEvent,\n () => ctx.apply(cyclePatch(), nativeEvent),\n \"CheckboxGroup.Parent\",\n );\n },\n },\n });\n\n return useTransitionBoundary(\"CheckboxGroup.Parent\", transition, element);\n}\n\nCheckboxGroupParent.displayName = \"CheckboxGroupParent\";\n"],"mappings":";;;;;;;;;;AA4EA,MAAM,+BAA+B,CAAC;;AAGtC,SAAS,OAAO,QAA2B,KAA0B;CACnE,IAAI,QAAQ;CACZ,KAAK,MAAM,KAAK,QAAQ,IAAI,IAAI,IAAI,CAAC,GAAG,SAAS;CACjD,MAAM,UAAU,OAAO,SAAS,KAAK,UAAU,OAAO;CACtD,OAAO;EAAE;EAAS,eAAe,QAAQ,KAAK,CAAC;CAAQ;AACzD;;;;;;;;;;;;;;;AAgBA,SAAgB,oBAAoB,EAClC,QACA,UAAU,eAAe,OACzB,YACA,WACA,OACA,QACA,GAAG,QACwB;CAC3B,MAAM,MAAM,wBAAwB,sBAAsB;CAK1D,MAAM,YAAY,qBAChB,wBACM,aACA,IACR;CACA,MAAM,EAAE,kBAAkB;CAC1B,MAAM,YAAY,cACT,YAAY,SAAS,cAAc,QAAQ,aAAa,GAC/D;EAAC;EAAW;EAAQ;CAAa,CACnC;CACA,MAAM,EAAE,SAAS,kBAAkB,OAAO,WAAW,IAAI,UAAU;CACnE,MAAM,UAAU,IAAI,WAAW,OAAO,MAAM,MAAM,IAAI,WAAW,IAAI,CAAC,MAAM,IAAI,UAAU,IAAI,CAAC,CAAC;CAChG,MAAM,WAAW,IAAI,YAAY;CAKjC,MAAM,SAAS,OAAiC,IAAI;CACpD,MAAM,EAAE,cAAc;CACtB,sBAAsB;EACpB,MAAM,cAAc,UAAU,QAAQ,MAAM,UAAU,IAAI,CAAC,CAAC;EAC5D,IAAI,YAAY,SAAS,KAAK,YAAY,SAAS,UAAU,QAC3D,OAAO,UAAU;CAErB,GAAG,CAAC,WAAW,SAAS,CAAC;CAEzB,MAAM,WAAW,iBAAiB;EAChC,MAAM;EACN,WAAW;EACX;EACA;EACA,OAAO;EACP,gBAAgB,OAAO;GACrB,IAAI,OAAO,MAAM;IAIf,IAAI,GAAG,YAAY,SAAS,IAAI,aAAa,QAAQ,GAAG,OAAO;IAC/D,aAAa,IAAI,gBAAgB,OAAO;IACxC,aAAa,IAAI,sBAAsB,aAAa;IACpD,aAAa,IAAI,gBAAgB,OAAO;IACxC,aAAa,IAAI,iBAAiB,QAAQ;GAC5C;GACA,IAAI,cAAc,EAAE;EACtB;EACA,gBACE,IAAI,iBAAiB,KAAA,IAAY,KAAA,IAAY,OAAO,WAAW,IAAI,YAAY,CAAC,CAAC;CACrF,CAAC;CAOD,MAAM,OAAO,OAAgC,IAAI;CACjD,MAAM,MAAM,aACT,OAAyB;EACxB,KAAK,UAAU;EACf,MAAM,UAAU,SAAS,EAAE;EAC3B,aAAa;GACX,KAAK,UAAU;GACf,IAAI,OAAO,YAAY,YAAY,QAAQ;EAC7C;CACF,GACA,CAAC,QAAQ,CACX;CACA,aAAa,YAAY;EACvB,MAAM,KAAK,KAAK;EAChB,IAAI,OAAO,QAAQ,GAAG,YAAY,SAAS,GAAG,UAAU;CAC1D,CAAC;;CAGD,MAAM,mBAAuC;EAC3C,IAAI,SAAS,OAAO;GAAE,OAAO,CAAC;GAAG,SAAS,CAAC,GAAG,SAAS;EAAE;EACzD,IAAI,eACF,OAAO;GAAE,OAAO,UAAU,QAAQ,MAAM,CAAC,IAAI,WAAW,IAAI,CAAC,CAAC;GAAG,SAAS,CAAC;EAAE;EAE/E,MAAM,UAAU,OAAO,SAAS,QAAQ,MAAM,UAAU,SAAS,CAAC,CAAC,KAAK,CAAC;EACzE,OAAO;GAAE,OAAO,QAAQ,SAAS,IAAI,UAAU,CAAC,GAAG,SAAS;GAAG,SAAS,CAAC;EAAE;CAC7E;CAIA,MAAM,UAAU,UAAoE;EAClF,gBAAgB;EAChB;EACA,OAAA;GALwC;GAAQ;GAAS;GAAe;GAAS;EAK7E;EACJ;EACA;EACA,UAAU,KAAA;EACV;EACA,OAAO;EACP,cAAc;GACZ,MAAM;GAEN,MAAM,KAAA;GACN,OAAO,KAAA;GACP,UAAU,KAAA;GACV,MAAM,KAAA;GAGN,cAAc;GACd;GACA,gBAAgB,KAAA;GAGV,eAAe,KAAA;GACrB,gBAAgB,KAAA;GAChB,UAAU;GACV,gBAAgB,SAAS,OAAO;GAChC,sBAAsB,SAAS,aAAa;GAC5C,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;GAClC,WAAW,UAAyC;IAClD,IAAI,UAAU;IACd,MAAM,cAAc,MAAM;IAC1B,qBACE,mBACM,IAAI,MAAM,WAAW,GAAG,WAAW,GACzC,sBACF;GACF;EACF;CACF,CAAC;CAED,OAAO,sBAAsB,wBAAwB,YAAY,OAAO;AAC1E;AAEA,oBAAoB,cAAc"}
@@ -0,0 +1,100 @@
1
+ import { ActionDetails, ChangeAction, ChangeReason, RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
3
+ //#region src/checkbox-group/checkbox-group-root.d.ts
4
+ /** Details passed as the second argument of `valueChangeAction`. */
5
+ export interface CheckboxGroupValueChangeDetails extends ActionDetails {
6
+ /**
7
+ * `"activate"`: the user toggled an Item or a Parent (click, Space, label click; `event` is the
8
+ * native `click`). `"platform"`: the browser changed the checked boxes itself: a form reset
9
+ * (`event` is the `reset` event), or clicks before hydration / Firefox form-state restoration
10
+ * found at mount (`event` is `undefined`).
11
+ */
12
+ readonly reason: ChangeReason;
13
+ /** Values this dispatch checked, in document order of their Items (values with no Item last). */
14
+ readonly added: readonly string[];
15
+ /** Values this dispatch unchecked, same order. */
16
+ readonly removed: readonly string[];
17
+ }
18
+ export interface CheckboxGroupRootState {
19
+ /**
20
+ * Optimistic checked values, in document order of the Items as of the Root's last render
21
+ * (values with no Item last). Items reordered by a component that re-renders without the Root
22
+ * keep the previous order here until the Root renders again; `next` and `details` of
23
+ * `valueChangeAction` always read the current DOM order. The server render and the first client
24
+ * render use the value's own order. Content rendered from it must not suspend.
25
+ */
26
+ readonly value: readonly string[];
27
+ /** An action dispatched through this group is in flight. */
28
+ readonly pending: boolean;
29
+ /** The `disabled` prop. */
30
+ readonly disabled: boolean;
31
+ }
32
+ export interface CheckboxGroupRootProps extends Omit<ComponentPropsWithRef<"fieldset">, "className" | "style" | "children" | "defaultValue" | "defaultChecked" | "name" | "disabled" | "form"> {
33
+ /**
34
+ * Controlled checked values. `[]` checks nothing; `undefined` means uncontrolled. Order is not
35
+ * significant and duplicates are ignored: the value is a set.
36
+ *
37
+ * A form reset returns each box to the `checked` it had when *that box* mounted (React sets
38
+ * `defaultChecked` once, from the initial `checked`). The reset is offered to
39
+ * `valueChangeAction` as a `"platform"` change; for a stable target use `defaultValue`.
40
+ */
41
+ value?: string[];
42
+ /**
43
+ * Initial values in uncontrolled mode. Defaults to `[]`. Also the values a form reset returns
44
+ * to: the latest prop value is mirrored into the boxes' `defaultChecked`.
45
+ */
46
+ defaultValue?: string[];
47
+ /**
48
+ * Runs inside the Root's transition whenever the set of checked values changes. May be sync
49
+ * or async (also a Server Function); rejections reach the nearest Error Boundary and roll the
50
+ * change back.
51
+ *
52
+ * `next` is the whole set as a fresh array in document order of the Items; treat it as a set.
53
+ * `details.added` / `details.removed` say what changed. When controlled and updating after
54
+ * your own `await`, prefer a functional update keyed by `added` / `removed` over
55
+ * `setValue(next)`: two overlapping actions completing out of order would otherwise land the
56
+ * older whole set last. A `setState` placed after your own `await` is not a Transition update;
57
+ * wrap it in `startTransition` (React limitation). `details.event.preventDefault()` is not a
58
+ * veto; use controlled mode to veto a change.
59
+ */
60
+ valueChangeAction?: ChangeAction<string[], CheckboxGroupValueChangeDetails>;
61
+ /**
62
+ * The `name` shared by every Item (form data key: `formData.getAll(name)`). Defaults to a
63
+ * `useId()` value; pass a real name when the group is inside a `<form>` you submit.
64
+ */
65
+ name?: string;
66
+ /** The `form` attribute, applied to the fieldset and to every Item. */
67
+ form?: string;
68
+ /**
69
+ * "At least one Item must be checked." Rendered as native `required` on every Item while no
70
+ * enabled Item is checked, and on none once one is: values with no Item and checked disabled
71
+ * Items (neither is submitted) do not satisfy it. Until the Items have mounted (server HTML,
72
+ * before hydration) any checked value satisfies it. Not exposed on the fieldset (ARIA does not
73
+ * allow `aria-required` on role `group`): say it in the `Label` or through `aria-describedby`.
74
+ */
75
+ required?: boolean;
76
+ /** Renders `<fieldset disabled>`: every Item and Parent is disabled and unfocusable. */
77
+ disabled?: boolean;
78
+ className?: StateValue<string | undefined, CheckboxGroupRootState>;
79
+ style?: StateValue<CSSProperties | undefined, CheckboxGroupRootState>;
80
+ children?: StateValue<ReactNode, CheckboxGroupRootState>;
81
+ /** Replace the rendered element. Must keep a `<fieldset>`. */
82
+ render?: RenderProp<ComponentPropsWithRef<"fieldset">, CheckboxGroupRootState>;
83
+ }
84
+ /**
85
+ * `<fieldset>` that owns the group's state (a set of values), the transition, the shared `name`,
86
+ * the form-reset listener, the mount reconciliation and the group-level `required`
87
+ * (design/components/checkbox-group.md 14.3). Carries `data-pending` while `valueChangeAction`
88
+ * is in flight. Its implicit role is `group`; no `role` is written.
89
+ *
90
+ * Owned keys (conventions 1.2): `disabled`, `form`, `data-pending`, `data-disabled`.
91
+ *
92
+ * Unlike RadioGroup, Items may hydrate after their Root (a Suspense boundary between them): a
93
+ * click before an Item hydrated is reconciled when it does.
94
+ */
95
+ export declare function CheckboxGroupRoot({ value, defaultValue, valueChangeAction, name: nameProp, form, required, disabled, className, style, children, render, ...rest }: CheckboxGroupRootProps): import("react").JSX.Element;
96
+ export declare namespace CheckboxGroupRoot {
97
+ var displayName: string;
98
+ }
99
+ //#endregion
100
+ //# sourceMappingURL=checkbox-group-root.d.mts.map
@@ -0,0 +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"}