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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) 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/dialog/dialog-close.d.mts +44 -0
  34. package/dist/dialog/dialog-close.d.mts.map +1 -0
  35. package/dist/dialog/dialog-close.mjs +76 -0
  36. package/dist/dialog/dialog-close.mjs.map +1 -0
  37. package/dist/dialog/dialog-context.mjs +13 -0
  38. package/dist/dialog/dialog-context.mjs.map +1 -0
  39. package/dist/dialog/dialog-description.d.mts +22 -0
  40. package/dist/dialog/dialog-description.d.mts.map +1 -0
  41. package/dist/dialog/dialog-description.mjs +31 -0
  42. package/dist/dialog/dialog-description.mjs.map +1 -0
  43. package/dist/dialog/dialog-form.d.mts +58 -0
  44. package/dist/dialog/dialog-form.d.mts.map +1 -0
  45. package/dist/dialog/dialog-form.mjs +108 -0
  46. package/dist/dialog/dialog-form.mjs.map +1 -0
  47. package/dist/dialog/dialog-popup.d.mts +81 -0
  48. package/dist/dialog/dialog-popup.d.mts.map +1 -0
  49. package/dist/dialog/dialog-popup.mjs +366 -0
  50. package/dist/dialog/dialog-popup.mjs.map +1 -0
  51. package/dist/dialog/dialog-root.d.mts +70 -0
  52. package/dist/dialog/dialog-root.d.mts.map +1 -0
  53. package/dist/dialog/dialog-root.mjs +105 -0
  54. package/dist/dialog/dialog-root.mjs.map +1 -0
  55. package/dist/dialog/dialog-title.d.mts +23 -0
  56. package/dist/dialog/dialog-title.d.mts.map +1 -0
  57. package/dist/dialog/dialog-title.mjs +31 -0
  58. package/dist/dialog/dialog-title.mjs.map +1 -0
  59. package/dist/dialog/dialog-trigger.d.mts +39 -0
  60. package/dist/dialog/dialog-trigger.d.mts.map +1 -0
  61. package/dist/dialog/dialog-trigger.mjs +80 -0
  62. package/dist/dialog/dialog-trigger.mjs.map +1 -0
  63. package/dist/dialog/index.d.mts +28 -0
  64. package/dist/dialog/index.d.mts.map +1 -0
  65. package/dist/dialog/index.mjs +28 -0
  66. package/dist/dialog/index.mjs.map +1 -0
  67. package/dist/index.d.mts +38 -0
  68. package/dist/index.mjs +9 -0
  69. package/dist/internal/action-details.mjs +47 -0
  70. package/dist/internal/action-details.mjs.map +1 -0
  71. package/dist/internal/data-attr.mjs +13 -0
  72. package/dist/internal/data-attr.mjs.map +1 -0
  73. package/dist/internal/merge-props.mjs +119 -0
  74. package/dist/internal/merge-props.mjs.map +1 -0
  75. package/dist/internal/platform-attributes.d.mts +49 -0
  76. package/dist/internal/platform-attributes.d.mts.map +1 -0
  77. package/dist/internal/transition-boundary.mjs +52 -0
  78. package/dist/internal/transition-boundary.mjs.map +1 -0
  79. package/dist/internal/transition-types.mjs +15 -0
  80. package/dist/internal/transition-types.mjs.map +1 -0
  81. package/dist/internal/types.d.mts +38 -0
  82. package/dist/internal/types.d.mts.map +1 -0
  83. package/dist/internal/use-controllable-action.mjs +115 -0
  84. package/dist/internal/use-controllable-action.mjs.map +1 -0
  85. package/dist/internal/use-dev-warning.mjs +21 -0
  86. package/dist/internal/use-dev-warning.mjs.map +1 -0
  87. package/dist/internal/use-form-reset.mjs +50 -0
  88. package/dist/internal/use-form-reset.mjs.map +1 -0
  89. package/dist/internal/use-native-checked.mjs +113 -0
  90. package/dist/internal/use-native-checked.mjs.map +1 -0
  91. package/dist/internal/use-native-group-reconciliation.mjs +64 -0
  92. package/dist/internal/use-native-group-reconciliation.mjs.map +1 -0
  93. package/dist/internal/use-render.mjs +51 -0
  94. package/dist/internal/use-render.mjs.map +1 -0
  95. package/dist/internal/use-until-found.mjs +40 -0
  96. package/dist/internal/use-until-found.mjs.map +1 -0
  97. package/dist/radio-group/index.d.mts +20 -0
  98. package/dist/radio-group/index.d.mts.map +1 -0
  99. package/dist/radio-group/index.mjs +20 -0
  100. package/dist/radio-group/index.mjs.map +1 -0
  101. package/dist/radio-group/radio-group-context.mjs +13 -0
  102. package/dist/radio-group/radio-group-context.mjs.map +1 -0
  103. package/dist/radio-group/radio-group-item.d.mts +54 -0
  104. package/dist/radio-group/radio-group-item.d.mts.map +1 -0
  105. package/dist/radio-group/radio-group-item.mjs +88 -0
  106. package/dist/radio-group/radio-group-item.mjs.map +1 -0
  107. package/dist/radio-group/radio-group-label.d.mts +21 -0
  108. package/dist/radio-group/radio-group-label.d.mts.map +1 -0
  109. package/dist/radio-group/radio-group-label.mjs +30 -0
  110. package/dist/radio-group/radio-group-label.mjs.map +1 -0
  111. package/dist/radio-group/radio-group-root.d.mts +92 -0
  112. package/dist/radio-group/radio-group-root.d.mts.map +1 -0
  113. package/dist/radio-group/radio-group-root.mjs +137 -0
  114. package/dist/radio-group/radio-group-root.mjs.map +1 -0
  115. package/dist/switch/index.d.mts +3 -0
  116. package/dist/switch/index.mjs +1 -0
  117. package/dist/switch/switch.d.mts +78 -0
  118. package/dist/switch/switch.d.mts.map +1 -0
  119. package/dist/switch/switch.mjs +77 -0
  120. package/dist/switch/switch.mjs.map +1 -0
  121. package/dist/tabs/index.d.mts +24 -0
  122. package/dist/tabs/index.d.mts.map +1 -0
  123. package/dist/tabs/index.mjs +23 -0
  124. package/dist/tabs/index.mjs.map +1 -0
  125. package/dist/tabs/tabs-context.d.mts +7 -0
  126. package/dist/tabs/tabs-context.d.mts.map +1 -0
  127. package/dist/tabs/tabs-context.mjs +13 -0
  128. package/dist/tabs/tabs-context.mjs.map +1 -0
  129. package/dist/tabs/tabs-ids.mjs +39 -0
  130. package/dist/tabs/tabs-ids.mjs.map +1 -0
  131. package/dist/tabs/tabs-indicator.d.mts +32 -0
  132. package/dist/tabs/tabs-indicator.d.mts.map +1 -0
  133. package/dist/tabs/tabs-indicator.mjs +49 -0
  134. package/dist/tabs/tabs-indicator.mjs.map +1 -0
  135. package/dist/tabs/tabs-list.d.mts +34 -0
  136. package/dist/tabs/tabs-list.d.mts.map +1 -0
  137. package/dist/tabs/tabs-list.mjs +122 -0
  138. package/dist/tabs/tabs-list.mjs.map +1 -0
  139. package/dist/tabs/tabs-panel.d.mts +50 -0
  140. package/dist/tabs/tabs-panel.d.mts.map +1 -0
  141. package/dist/tabs/tabs-panel.mjs +81 -0
  142. package/dist/tabs/tabs-panel.mjs.map +1 -0
  143. package/dist/tabs/tabs-root.d.mts +64 -0
  144. package/dist/tabs/tabs-root.d.mts.map +1 -0
  145. package/dist/tabs/tabs-root.mjs +90 -0
  146. package/dist/tabs/tabs-root.mjs.map +1 -0
  147. package/dist/tabs/tabs-tab.d.mts +49 -0
  148. package/dist/tabs/tabs-tab.d.mts.map +1 -0
  149. package/dist/tabs/tabs-tab.mjs +86 -0
  150. package/dist/tabs/tabs-tab.mjs.map +1 -0
  151. package/dist/toggle/index.d.mts +3 -0
  152. package/dist/toggle/index.mjs +1 -0
  153. package/dist/toggle/toggle.d.mts +57 -0
  154. package/dist/toggle/toggle.d.mts.map +1 -0
  155. package/dist/toggle/toggle.mjs +59 -0
  156. package/dist/toggle/toggle.mjs.map +1 -0
  157. package/dist/tooltip/index.d.mts +20 -0
  158. package/dist/tooltip/index.d.mts.map +1 -0
  159. package/dist/tooltip/index.mjs +19 -0
  160. package/dist/tooltip/index.mjs.map +1 -0
  161. package/dist/tooltip/tooltip-context.d.mts +5 -0
  162. package/dist/tooltip/tooltip-context.d.mts.map +1 -0
  163. package/dist/tooltip/tooltip-context.mjs +13 -0
  164. package/dist/tooltip/tooltip-context.mjs.map +1 -0
  165. package/dist/tooltip/tooltip-popup.d.mts +49 -0
  166. package/dist/tooltip/tooltip-popup.d.mts.map +1 -0
  167. package/dist/tooltip/tooltip-popup.mjs +57 -0
  168. package/dist/tooltip/tooltip-popup.mjs.map +1 -0
  169. package/dist/tooltip/tooltip-root.d.mts +41 -0
  170. package/dist/tooltip/tooltip-root.d.mts.map +1 -0
  171. package/dist/tooltip/tooltip-root.mjs +86 -0
  172. package/dist/tooltip/tooltip-root.mjs.map +1 -0
  173. package/dist/tooltip/tooltip-trigger.d.mts +38 -0
  174. package/dist/tooltip/tooltip-trigger.d.mts.map +1 -0
  175. package/dist/tooltip/tooltip-trigger.mjs +55 -0
  176. package/dist/tooltip/tooltip-trigger.mjs.map +1 -0
  177. package/dist/tooltip/use-tooltip-interaction.mjs +131 -0
  178. package/dist/tooltip/use-tooltip-interaction.mjs.map +1 -0
  179. package/package.json +70 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-until-found.mjs","names":[],"sources":["../../src/internal/use-until-found.ts"],"sourcesContent":["\"use client\";\nimport { useEffect, useEffectEvent, useLayoutEffect, useRef } from \"react\";\nimport type { RefObject } from \"react\";\n\nexport interface UseUntilFoundOptions {\n /**\n * The element should currently be `hidden=\"until-found\"`. The part renders a boolean `hidden`\n * itself as well, so server-rendered HTML hides it (as `hidden=\"\"`) before hydration.\n *\n * Pass `false` while a change the element itself triggered (its `beforematch`) is pending:\n * the browser has already revealed it, and re-asserting would hide it again until the commit.\n * When that change is rejected the owner's optimistic state reverts, `active` becomes `true`\n * again and the next commit re-hides it.\n */\n active: boolean;\n /** Called with the `beforematch` event when find-in-page or a text fragment reveals it. */\n onMatch: (event: Event) => void;\n}\n\n/**\n * The single home of the `hidden=\"until-found\"` workaround (conventions 7.4).\n *\n * react-dom 19.3 serialises `hidden` as a boolean attribute (`hidden=\"\"` on client and server),\n * so the part renders a boolean `hidden` and this hook upgrades the attribute to `\"until-found\"`\n * through a ref in a layout effect. The upgrade is re-asserted after **every** commit while\n * `active`: when the browser reveals the element it removes the attribute itself, and if the\n * resulting action is rejected React sees no prop change (the boolean `hidden` stayed `true`\n * throughout) and would leave the element visible.\n *\n * `beforematch` has no React prop, so a native listener is attached in an effect through the\n * returned ref (conventions 2.6, 7.4). Attach the ref to the element that renders the boolean\n * `hidden`.\n */\nexport function useUntilFound<E extends HTMLElement>(\n options: UseUntilFoundOptions,\n): RefObject<E | null> {\n const { active } = options;\n const node = useRef<E | null>(null);\n const onMatch = useEffectEvent((event: Event) => {\n options.onMatch(event);\n });\n\n // No dependency array on purpose: re-assert after every commit of the owner (see above).\n useLayoutEffect(() => {\n const element = node.current;\n if (element !== null && active && element.getAttribute(\"hidden\") !== \"until-found\") {\n element.setAttribute(\"hidden\", \"until-found\");\n }\n });\n\n // Re-subscribed after every commit so a swapped element (a changed `render`) is covered.\n useEffect(() => {\n const element = node.current;\n if (element === null) return;\n const listener = (event: Event) => onMatch(event);\n element.addEventListener(\"beforematch\", listener);\n return () => element.removeEventListener(\"beforematch\", listener);\n });\n\n return node;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAiCA,SAAgB,cACd,SACqB;CACrB,MAAM,EAAE,WAAW;CACnB,MAAM,OAAO,OAAiB,IAAI;CAClC,MAAM,UAAU,gBAAgB,UAAiB;EAC/C,QAAQ,QAAQ,KAAK;CACvB,CAAC;CAGD,sBAAsB;EACpB,MAAM,UAAU,KAAK;EACrB,IAAI,YAAY,QAAQ,UAAU,QAAQ,aAAa,QAAQ,MAAM,eACnE,QAAQ,aAAa,UAAU,aAAa;CAEhD,CAAC;CAGD,gBAAgB;EACd,MAAM,UAAU,KAAK;EACrB,IAAI,YAAY,MAAM;EACtB,MAAM,YAAY,UAAiB,QAAQ,KAAK;EAChD,QAAQ,iBAAiB,eAAe,QAAQ;EAChD,aAAa,QAAQ,oBAAoB,eAAe,QAAQ;CAClE,CAAC;CAED,OAAO;AACT"}
@@ -0,0 +1,20 @@
1
+ import "../internal/platform-attributes.mjs";
2
+ import { RadioGroupItem, RadioGroupItemProps, RadioGroupItemState } from "./radio-group-item.mjs";
3
+ import { RadioGroupRoot, RadioGroupRootProps, RadioGroupRootState, RadioGroupValueChangeDetails } from "./radio-group-root.mjs";
4
+ import { RadioGroupLabel, RadioGroupLabelProps } from "./radio-group-label.mjs";
5
+ //#region src/radio-group/index.d.ts
6
+ /**
7
+ * RadioGroup (WAI-ARIA APG Radio Group pattern, native HTML radio variant): `Root`
8
+ * (`fieldset[role=radiogroup]`), an optional `Label` (`legend`, first child) and one `Item`
9
+ * (`input[type=radio]`) per option. The keyboard is entirely native. Each Item's DOM `checked` is
10
+ * the optimistic value; the Root and the checked Item carry `data-pending` while
11
+ * `valueChangeAction` is in flight.
12
+ */
13
+ export declare const RadioGroup: {
14
+ readonly Root: typeof RadioGroupRoot;
15
+ readonly Label: typeof RadioGroupLabel;
16
+ readonly Item: typeof RadioGroupItem;
17
+ };
18
+ //#endregion
19
+ export type { RadioGroupItemProps, RadioGroupItemState, RadioGroupLabelProps, RadioGroupRootProps, RadioGroupRootState, RadioGroupValueChangeDetails };
20
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/radio-group/index.ts"],"mappings":";;;;;;;;;;;;qBAca;WACX,aAAI;WACJ,cAAK;WACL,aAAI"}
@@ -0,0 +1,20 @@
1
+ import { RadioGroupItem } from "./radio-group-item.mjs";
2
+ import { RadioGroupLabel } from "./radio-group-label.mjs";
3
+ import { RadioGroupRoot } from "./radio-group-root.mjs";
4
+ //#region src/radio-group/index.ts
5
+ /**
6
+ * RadioGroup (WAI-ARIA APG Radio Group pattern, native HTML radio variant): `Root`
7
+ * (`fieldset[role=radiogroup]`), an optional `Label` (`legend`, first child) and one `Item`
8
+ * (`input[type=radio]`) per option. The keyboard is entirely native. Each Item's DOM `checked` is
9
+ * the optimistic value; the Root and the checked Item carry `data-pending` while
10
+ * `valueChangeAction` is in flight.
11
+ */
12
+ const RadioGroup = {
13
+ Root: RadioGroupRoot,
14
+ Label: RadioGroupLabel,
15
+ Item: RadioGroupItem
16
+ };
17
+ //#endregion
18
+ export { RadioGroup };
19
+
20
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/radio-group/index.ts"],"sourcesContent":["// Ships the platform attribute typings with this subpath (conventions 7.4). Type-only: the\n// built JS has no import of it.\nimport \"../internal/platform-attributes.js\";\nimport { RadioGroupItem } from \"./radio-group-item.js\";\nimport { RadioGroupLabel } from \"./radio-group-label.js\";\nimport { RadioGroupRoot } from \"./radio-group-root.js\";\n\n/**\n * RadioGroup (WAI-ARIA APG Radio Group pattern, native HTML radio variant): `Root`\n * (`fieldset[role=radiogroup]`), an optional `Label` (`legend`, first child) and one `Item`\n * (`input[type=radio]`) per option. The keyboard is entirely native. Each Item's DOM `checked` is\n * the optimistic value; the Root and the checked Item carry `data-pending` while\n * `valueChangeAction` is in flight.\n */\nexport const RadioGroup = {\n Root: RadioGroupRoot,\n Label: RadioGroupLabel,\n Item: RadioGroupItem,\n} as const;\n\nexport type {\n RadioGroupRootProps,\n RadioGroupRootState,\n RadioGroupValueChangeDetails,\n} from \"./radio-group-root.js\";\nexport type { RadioGroupLabelProps } from \"./radio-group-label.js\";\nexport type { RadioGroupItemProps, RadioGroupItemState } from \"./radio-group-item.js\";\n"],"mappings":";;;;;;;;;;;AAcA,MAAa,aAAa;CACxB,MAAM;CACN,OAAO;CACP,MAAM;AACR"}
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { createContext, use } from "react";
3
+ //#region src/radio-group/radio-group-context.ts
4
+ const RadioGroupContext = createContext(null);
5
+ function useRadioGroupContext(part) {
6
+ const context = use(RadioGroupContext);
7
+ if (context === null) throw new Error(`${part} must be rendered inside a RadioGroup.Root.`);
8
+ return context;
9
+ }
10
+ //#endregion
11
+ export { RadioGroupContext, useRadioGroupContext };
12
+
13
+ //# sourceMappingURL=radio-group-context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group-context.mjs","names":[],"sources":["../../src/radio-group/radio-group-context.ts"],"sourcesContent":["\"use client\";\nimport { createContext, use } from \"react\";\n\nexport interface RadioGroupContextValue {\n /** The `name` shared by every radio of the group (prop or `useId()`). */\n readonly name: string;\n readonly form: string | undefined;\n readonly required: boolean;\n /** Optimistic value: Items render `checked` from it. */\n readonly optimistic: string | null;\n readonly pending: boolean;\n /** `Root disabled` (reaches the radios natively through `<fieldset disabled>`). */\n readonly disabled: boolean;\n /**\n * Uncontrolled mode: the latest `defaultValue` (`null` when omitted), mirrored by each Item into\n * `el.defaultChecked` so that a form reset returns to it. `undefined` in controlled mode, where\n * React's mount-time value stays the reset target (conventions 3.8 rule 6).\n */\n readonly defaultValue: string | null | undefined;\n /**\n * Dispatches a user check. No-op when `value` is already the optimistic value. Checks neither\n * `disabled` (a disabled radio fires no click) nor `defaultPrevented` (the Item's\n * `guardCheckableChange` does).\n */\n readonly select: (value: string, event: Event) => void;\n /**\n * Called by each Item from its mount layout effect. An Item that mounts after the Root (under a\n * Suspense boundary, selective hydration) asks the Root to reconcile the group again, so a click\n * made before that Item hydrated is reported once (deduped by the Root's hook). Receives the\n * Item's element, which the Root uses for the dev-only partial-hydration warning.\n */\n readonly onItemMounted: (element: HTMLInputElement | null) => void;\n}\n\nexport const RadioGroupContext = createContext<RadioGroupContextValue | null>(null);\n\nexport function useRadioGroupContext(part: string): RadioGroupContextValue {\n const context = use(RadioGroupContext);\n if (context === null) {\n throw new Error(`${part} must be rendered inside a RadioGroup.Root.`);\n }\n return context;\n}\n"],"mappings":";;;AAkCA,MAAa,oBAAoB,cAA6C,IAAI;AAElF,SAAgB,qBAAqB,MAAsC;CACzE,MAAM,UAAU,IAAI,iBAAiB;CACrC,IAAI,YAAY,MACd,MAAM,IAAI,MAAM,GAAG,KAAK,4CAA4C;CAEtE,OAAO;AACT"}
@@ -0,0 +1,54 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ViewTransitionClass } from "react";
3
+ //#region src/radio-group/radio-group-item.d.ts
4
+ export interface RadioGroupItemState {
5
+ readonly value: string;
6
+ /** Optimistic: true as soon as the user checks this radio, before the action settles. */
7
+ readonly checked: boolean;
8
+ /** The Root is pending and this radio is the optimistic target. */
9
+ readonly pending: boolean;
10
+ /** Disabled by its own prop or by `Root disabled`. */
11
+ readonly disabled: boolean;
12
+ }
13
+ export interface RadioGroupItemProps extends Omit<ComponentPropsWithRef<"input">, "type" | "name" | "value" | "checked" | "defaultChecked" | "defaultValue" | "form" | "required" | "onChange" | "className" | "style" | "children"> {
14
+ /** The value this radio checks. Must be unique within the Root. Submitted as the form value. */
15
+ value: string;
16
+ /** Native `disabled`: unfocusable, skipped by arrow keys, never dispatches. */
17
+ disabled?: boolean;
18
+ /**
19
+ * Forwarded to the Item's `<ViewTransition default>`. Default: no boundary. Fires only on the commit
20
+ * that settles the action (or rolls it back), never on the optimistic check; animate the check
21
+ * itself with CSS on `:checked`.
22
+ *
23
+ * Static: without `transition` the part renders no `<ViewTransition>`; changing it between
24
+ * `undefined` and a value remounts the element. Any value, `"none"` included, makes a mount or
25
+ * `<Activity>` reveal of this part inside a transition start a document view transition: the
26
+ * page cross-fades for about 250 ms and the next transition commit waits for it (issue #35).
27
+ */
28
+ transition?: ViewTransitionClass;
29
+ className?: StateValue<string | undefined, RadioGroupItemState>;
30
+ style?: StateValue<CSSProperties | undefined, RadioGroupItemState>;
31
+ /** Replace the rendered element. Must keep an `<input>`; the library sets `type="radio"`. */
32
+ render?: RenderProp<ComponentPropsWithRef<"input">, RadioGroupItemState>;
33
+ }
34
+ /**
35
+ * One `<input type="radio">` of the group. Its DOM `checked` is the optimistic value
36
+ * (`checked={optimistic === value}`): react-dom restores a controlled input to its props after
37
+ * every event, and only the sync-lane optimistic value survives that restore.
38
+ *
39
+ * Owned keys (conventions 1.2; a `render` element's value is overridden): `type`, `name`,
40
+ * `value`, `checked`, `defaultChecked` (never rendered), `disabled`, `form`, `required`,
41
+ * `data-checked`, `data-pending`, `data-disabled`. `onChange` is merged: a `render` element's own
42
+ * handler runs first, then the library's.
43
+ *
44
+ * Form reset in controlled mode: React sets an input's `defaultChecked` once, from its initial
45
+ * `checked`. An Item added on the client while the Root's `value` equals its value gets
46
+ * `defaultChecked` too, so two radios may carry it and a reset does not necessarily return to
47
+ * the group's mount-time value (see `RadioGroup.Root` `value`).
48
+ */
49
+ export declare function RadioGroupItem({ value, disabled: disabledProp, transition, className, style, render, ...rest }: RadioGroupItemProps): import("react").ReactNode;
50
+ export declare namespace RadioGroupItem {
51
+ var displayName: string;
52
+ }
53
+ //#endregion
54
+ //# sourceMappingURL=radio-group-item.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group-item.d.mts","names":[],"sources":["../../src/radio-group/radio-group-item.tsx"],"mappings":";;;iBASiB;WACN;;WAEA;;WAEA;;WAEA;;iBAGM,4BAA4B,KAC3C;;EAeA;;EAEA;;;;;;;;;;;EAWA,aAAa;EACb,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;EAE9C,SAAS,WAAW,gCAAgC;;;;;;;;;;;;;;;;;wBAkBtC,iBACd,OACA,UAAU,cACV,YACA,WACA,OACA,WACG,QACF,sCAAmB;yBARN"}
@@ -0,0 +1,88 @@
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 { useRadioGroupContext } from "./radio-group-context.mjs";
7
+ //#region src/radio-group/radio-group-item.tsx
8
+ /**
9
+ * One `<input type="radio">` of the group. Its DOM `checked` is the optimistic value
10
+ * (`checked={optimistic === value}`): react-dom restores a controlled input to its props after
11
+ * every event, and only the sync-lane optimistic value survives that restore.
12
+ *
13
+ * Owned keys (conventions 1.2; a `render` element's value is overridden): `type`, `name`,
14
+ * `value`, `checked`, `defaultChecked` (never rendered), `disabled`, `form`, `required`,
15
+ * `data-checked`, `data-pending`, `data-disabled`. `onChange` is merged: a `render` element's own
16
+ * handler runs first, then the library's.
17
+ *
18
+ * Form reset in controlled mode: React sets an input's `defaultChecked` once, from its initial
19
+ * `checked`. An Item added on the client while the Root's `value` equals its value gets
20
+ * `defaultChecked` too, so two radios may carry it and a reset does not necessarily return to
21
+ * the group's mount-time value (see `RadioGroup.Root` `value`).
22
+ */
23
+ function RadioGroupItem({ value, disabled: disabledProp = false, transition, className, style, render, ...rest }) {
24
+ const ctx = useRadioGroupContext("RadioGroup.Item");
25
+ const checked = ctx.optimistic === value;
26
+ const pending = ctx.pending && checked;
27
+ const disabled = ctx.disabled || disabledProp;
28
+ const inputRef = useNativeChecked({
29
+ type: "radio",
30
+ component: "RadioGroup.Item",
31
+ checked,
32
+ group: true,
33
+ onItemMounted: (el) => {
34
+ if (el !== null) {
35
+ syncPresence(el, "data-checked", checked);
36
+ syncPresence(el, "data-pending", pending);
37
+ syncPresence(el, "data-disabled", disabled);
38
+ }
39
+ ctx.onItemMounted(el);
40
+ },
41
+ defaultChecked: ctx.defaultValue === void 0 ? void 0 : ctx.defaultValue === value
42
+ });
43
+ const element = useRender({
44
+ defaultElement: "input",
45
+ render,
46
+ state: {
47
+ value,
48
+ checked,
49
+ pending,
50
+ disabled
51
+ },
52
+ className,
53
+ style,
54
+ children: void 0,
55
+ ref: inputRef,
56
+ props: rest,
57
+ libraryProps: {
58
+ type: "radio",
59
+ name: ctx.name,
60
+ value,
61
+ checked,
62
+ defaultChecked: void 0,
63
+ disabled: disabledProp,
64
+ form: ctx.form,
65
+ required: ctx.required,
66
+ "data-checked": dataAttr(checked),
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, () => ctx.select(value, nativeEvent), "RadioGroup.Item");
73
+ }
74
+ }
75
+ });
76
+ return useTransitionBoundary("RadioGroup.Item", transition, element);
77
+ }
78
+ RadioGroupItem.displayName = "RadioGroupItem";
79
+ function syncPresence(el, name, present) {
80
+ if (el.hasAttribute(name) !== present) {
81
+ if (present) el.setAttribute(name, "");
82
+ else el.removeAttribute(name);
83
+ }
84
+ }
85
+ //#endregion
86
+ export { RadioGroupItem };
87
+
88
+ //# sourceMappingURL=radio-group-item.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group-item.mjs","names":[],"sources":["../../src/radio-group/radio-group-item.tsx"],"sourcesContent":["\"use client\";\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 { useRadioGroupContext } from \"./radio-group-context.js\";\n\nexport interface RadioGroupItemState {\n readonly value: string;\n /** Optimistic: true as soon as the user checks this radio, before the action settles. */\n readonly checked: boolean;\n /** The Root is pending and this radio is the optimistic target. */\n readonly pending: boolean;\n /** Disabled by its own prop or by `Root disabled`. */\n readonly disabled: boolean;\n}\n\nexport interface RadioGroupItemProps extends Omit<\n ComponentPropsWithRef<\"input\">,\n | \"type\"\n | \"name\"\n | \"value\"\n | \"checked\"\n | \"defaultChecked\"\n | \"defaultValue\"\n | \"form\"\n | \"required\"\n | \"onChange\"\n | \"className\"\n | \"style\"\n | \"children\"\n> {\n /** The value this radio checks. Must be unique within the Root. Submitted as the form value. */\n value: string;\n /** Native `disabled`: unfocusable, skipped by arrow keys, never dispatches. */\n disabled?: boolean;\n /**\n * Forwarded to the Item's `<ViewTransition default>`. Default: no boundary. Fires only on the commit\n * that settles the action (or rolls it back), never on the optimistic check; animate the check\n * 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, RadioGroupItemState>;\n style?: StateValue<CSSProperties | undefined, RadioGroupItemState>;\n /** Replace the rendered element. Must keep an `<input>`; the library sets `type=\"radio\"`. */\n render?: RenderProp<ComponentPropsWithRef<\"input\">, RadioGroupItemState>;\n}\n\n/**\n * One `<input type=\"radio\">` of the group. Its DOM `checked` is the optimistic value\n * (`checked={optimistic === value}`): react-dom restores a controlled input to its props after\n * every event, and only the sync-lane optimistic 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 * `data-checked`, `data-pending`, `data-disabled`. `onChange` is merged: a `render` element's own\n * handler runs first, then the library's.\n *\n * Form reset in controlled mode: React sets an input's `defaultChecked` once, from its initial\n * `checked`. An Item added on the client while the Root's `value` equals its value gets\n * `defaultChecked` too, so two radios may carry it and a reset does not necessarily return to\n * the group's mount-time value (see `RadioGroup.Root` `value`).\n */\nexport function RadioGroupItem({\n value,\n disabled: disabledProp = false,\n transition,\n className,\n style,\n render,\n ...rest\n}: RadioGroupItemProps) {\n const ctx = useRadioGroupContext(\"RadioGroup.Item\");\n const checked = ctx.optimistic === value;\n const pending = ctx.pending && checked;\n const disabled = ctx.disabled || disabledProp;\n\n // Group mode: element check and re-apply only; the Root reports the residual paths once. The\n // hook calls `onItemMounted` at mount so that an Item mounting after its Root (a Suspense\n // boundary that hydrates later) still gets the group reconciled.\n const inputRef = useNativeChecked({\n type: \"radio\",\n component: \"RadioGroup.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 (partial hydration, Root JSDoc) can render a different\n // `checked` than the server did, e.g. after a click on an already hydrated radio, and a\n // stale `data-checked` would then stay until the prop changes again.\n if (el !== null) {\n syncPresence(el, \"data-checked\", checked);\n syncPresence(el, \"data-pending\", pending);\n syncPresence(el, \"data-disabled\", disabled);\n }\n ctx.onItemMounted(el);\n },\n defaultChecked: ctx.defaultValue === undefined ? undefined : ctx.defaultValue === value,\n });\n\n const state: RadioGroupItemState = { value, checked, pending, disabled };\n\n const element = useRender<ComponentPropsWithRef<\"input\">, RadioGroupItemState>({\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: \"radio\",\n name: ctx.name,\n value,\n checked,\n defaultChecked: 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 radio through the fieldset.\n disabled: disabledProp,\n form: ctx.form,\n required: ctx.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 radio fires no click; this covers `render` elements that do not\n // honour `disabled`.\n if (disabled) return;\n const nativeEvent = event.nativeEvent;\n guardCheckableChange(nativeEvent, () => ctx.select(value, nativeEvent), \"RadioGroup.Item\");\n },\n },\n });\n\n return useTransitionBoundary(\"RadioGroup.Item\", transition, element);\n}\n\nRadioGroupItem.displayName = \"RadioGroupItem\";\n\nfunction syncPresence(el: Element, name: string, present: boolean): void {\n if (el.hasAttribute(name) !== present) {\n if (present) el.setAttribute(name, \"\");\n else el.removeAttribute(name);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAsEA,SAAgB,eAAe,EAC7B,OACA,UAAU,eAAe,OACzB,YACA,WACA,OACA,QACA,GAAG,QACmB;CACtB,MAAM,MAAM,qBAAqB,iBAAiB;CAClD,MAAM,UAAU,IAAI,eAAe;CACnC,MAAM,UAAU,IAAI,WAAW;CAC/B,MAAM,WAAW,IAAI,YAAY;CAKjC,MAAM,WAAW,iBAAiB;EAChC,MAAM;EACN,WAAW;EACX;EACA,OAAO;EACP,gBAAgB,OAAO;GAKrB,IAAI,OAAO,MAAM;IACf,aAAa,IAAI,gBAAgB,OAAO;IACxC,aAAa,IAAI,gBAAgB,OAAO;IACxC,aAAa,IAAI,iBAAiB,QAAQ;GAC5C;GACA,IAAI,cAAc,EAAE;EACtB;EACA,gBAAgB,IAAI,iBAAiB,KAAA,IAAY,KAAA,IAAY,IAAI,iBAAiB;CACpF,CAAC;CAID,MAAM,UAAU,UAA+D;EAC7E,gBAAgB;EAChB;EACA,OAAA;GALmC;GAAO;GAAS;GAAS;EAKxD;EACJ;EACA;EACA,UAAU,KAAA;EACV,KAAK;EAEL,OAAO;EACP,cAAc;GACZ,MAAM;GACN,MAAM,IAAI;GACV;GACA;GACA,gBAAgB,KAAA;GAGhB,UAAU;GACV,MAAM,IAAI;GACV,UAAU,IAAI;GACd,gBAAgB,SAAS,OAAO;GAChC,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;GAClC,WAAW,UAAyC;IAGlD,IAAI,UAAU;IACd,MAAM,cAAc,MAAM;IAC1B,qBAAqB,mBAAmB,IAAI,OAAO,OAAO,WAAW,GAAG,iBAAiB;GAC3F;EACF;CACF,CAAC;CAED,OAAO,sBAAsB,mBAAmB,YAAY,OAAO;AACrE;AAEA,eAAe,cAAc;AAE7B,SAAS,aAAa,IAAa,MAAc,SAAwB;CACvE,IAAI,GAAG,aAAa,IAAI,MAAM,SAAS;EACrC,IAAI,SAAS,GAAG,aAAa,MAAM,EAAE;OAChC,GAAG,gBAAgB,IAAI;CAC9B;AACF"}
@@ -0,0 +1,21 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { RadioGroupRootState } from "./radio-group-root.mjs";
3
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
4
+ //#region src/radio-group/radio-group-label.d.ts
5
+ export interface RadioGroupLabelProps extends Omit<ComponentPropsWithRef<"legend">, "className" | "style" | "children"> {
6
+ className?: StateValue<string | undefined, RadioGroupRootState>;
7
+ style?: StateValue<CSSProperties | undefined, RadioGroupRootState>;
8
+ /** Receives the Root's state: a group-level pending indicator goes here. */
9
+ children?: StateValue<ReactNode, RadioGroupRootState>;
10
+ render?: RenderProp<ComponentPropsWithRef<"legend">, RadioGroupRootState>;
11
+ }
12
+ /**
13
+ * The group's `<legend>`, which names the fieldset natively. Optional; must be the **first child**
14
+ * of `RadioGroup.Root` (HTML content model). Its state is the Root's state. Owns no keys.
15
+ */
16
+ export declare function RadioGroupLabel({ className, style, children, render, ...rest }: RadioGroupLabelProps): ReactNode;
17
+ export declare namespace RadioGroupLabel {
18
+ var displayName: string;
19
+ }
20
+ //#endregion
21
+ //# sourceMappingURL=radio-group-label.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group-label.d.mts","names":[],"sources":["../../src/radio-group/radio-group-label.tsx"],"mappings":";;;;iBAOiB,6BAA6B,KAC5C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;;EAE9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,iCAAiC;;;;;;wBAOvC,kBACd,WACA,OACA,UACA,WACG,QACF,uBAAoB;yBANP"}
@@ -0,0 +1,30 @@
1
+ "use client";
2
+ import { useRender } from "../internal/use-render.mjs";
3
+ import { useRadioGroupContext } from "./radio-group-context.mjs";
4
+ //#region src/radio-group/radio-group-label.tsx
5
+ /**
6
+ * The group's `<legend>`, which names the fieldset natively. Optional; must be the **first child**
7
+ * of `RadioGroup.Root` (HTML content model). Its state is the Root's state. Owns no keys.
8
+ */
9
+ function RadioGroupLabel({ className, style, children, render, ...rest }) {
10
+ const ctx = useRadioGroupContext("RadioGroup.Label");
11
+ const state = {
12
+ value: ctx.optimistic,
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
+ RadioGroupLabel.displayName = "RadioGroupLabel";
27
+ //#endregion
28
+ export { RadioGroupLabel };
29
+
30
+ //# sourceMappingURL=radio-group-label.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group-label.mjs","names":[],"sources":["../../src/radio-group/radio-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 { useRadioGroupContext } from \"./radio-group-context.js\";\nimport type { RadioGroupRootState } from \"./radio-group-root.js\";\n\nexport interface RadioGroupLabelProps extends Omit<\n ComponentPropsWithRef<\"legend\">,\n \"className\" | \"style\" | \"children\"\n> {\n className?: StateValue<string | undefined, RadioGroupRootState>;\n style?: StateValue<CSSProperties | undefined, RadioGroupRootState>;\n /** Receives the Root's state: a group-level pending indicator goes here. */\n children?: StateValue<ReactNode, RadioGroupRootState>;\n render?: RenderProp<ComponentPropsWithRef<\"legend\">, RadioGroupRootState>;\n}\n\n/**\n * The group's `<legend>`, which names the fieldset natively. Optional; must be the **first child**\n * of `RadioGroup.Root` (HTML content model). Its state is the Root's state. Owns no keys.\n */\nexport function RadioGroupLabel({\n className,\n style,\n children,\n render,\n ...rest\n}: RadioGroupLabelProps) {\n const ctx = useRadioGroupContext(\"RadioGroup.Label\");\n const state: RadioGroupRootState = {\n value: ctx.optimistic,\n pending: ctx.pending,\n disabled: ctx.disabled,\n };\n return useRender<ComponentPropsWithRef<\"legend\">, RadioGroupRootState>({\n defaultElement: \"legend\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n });\n}\n\nRadioGroupLabel.displayName = \"RadioGroupLabel\";\n"],"mappings":";;;;;;;;AAsBA,SAAgB,gBAAgB,EAC9B,WACA,OACA,UACA,QACA,GAAG,QACoB;CACvB,MAAM,MAAM,qBAAqB,kBAAkB;CACnD,MAAM,QAA6B;EACjC,OAAO,IAAI;EACX,SAAS,IAAI;EACb,UAAU,IAAI;CAChB;CACA,OAAO,UAAgE;EACrE,gBAAgB;EAChB;EACA;EACA;EACA;EACA;EACA,OAAO;CACT,CAAC;AACH;AAEA,gBAAgB,cAAc"}
@@ -0,0 +1,92 @@
1
+ import { ActionDetails, ChangeAction, ChangeReason, RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
3
+ //#region src/radio-group/radio-group-root.d.ts
4
+ /** Details passed as the second argument of `valueChangeAction`. */
5
+ export interface RadioGroupValueChangeDetails extends ActionDetails {
6
+ /**
7
+ * `"activate"`: the user checked a radio (click, Space, label click, or an arrow key, all of
8
+ * which arrive as a native `click`). `"platform"`: the browser changed the checked radio
9
+ * itself: a form reset (`details.event` is the `reset` event), or a click before hydration /
10
+ * Firefox form-state restoration found at mount (`details.event` is `undefined`).
11
+ */
12
+ readonly reason: ChangeReason;
13
+ }
14
+ export interface RadioGroupRootState {
15
+ /** Optimistic checked value, or `null`. Content rendered from it must not suspend. */
16
+ readonly value: string | null;
17
+ /** An action dispatched through this group is in flight. */
18
+ readonly pending: boolean;
19
+ /** The `disabled` prop. */
20
+ readonly disabled: boolean;
21
+ }
22
+ export interface RadioGroupRootProps extends Omit<ComponentPropsWithRef<"fieldset">, "className" | "style" | "children" | "defaultValue" | "defaultChecked" | "name" | "disabled" | "form"> {
23
+ /**
24
+ * Controlled checked value. `null` checks nothing; `undefined` means uncontrolled.
25
+ *
26
+ * A form reset returns each radio to the `checked` it had when *that radio* mounted (React sets
27
+ * `defaultChecked` once, from the initial `checked`). An Item added on the client while `value`
28
+ * equals its value therefore also gets `defaultChecked`, so two radios may carry it and the
29
+ * reset target is not necessarily the group's mount-time value. The reset is offered to
30
+ * `valueChangeAction` as usual; for a stable target remount the group with a `key` or use
31
+ * `defaultValue`, whose latest value every Item mirrors.
32
+ */
33
+ value?: string | null;
34
+ /**
35
+ * Initial value in uncontrolled mode. Defaults to `null` (nothing checked). Also the value a
36
+ * form reset returns to: the latest prop value is mirrored into the radios' `defaultChecked`.
37
+ */
38
+ defaultValue?: string | null;
39
+ /**
40
+ * Runs inside the Root's transition whenever the checked radio changes. May be sync or async
41
+ * (also a Server Function); rejections reach the nearest Error Boundary and roll the selection
42
+ * back.
43
+ *
44
+ * `next` is a string for every user interaction. It is `null` only with
45
+ * `details.reason === "platform"`, when a form reset returned the group to "nothing checked".
46
+ * Every arrow key press dispatches; the latest dispatch wins. A `setState` placed after your
47
+ * own `await` is not a Transition update; wrap it in `startTransition` (React limitation).
48
+ * `details.event.preventDefault()` is not a veto; use controlled mode to veto a change.
49
+ */
50
+ valueChangeAction?: ChangeAction<string | null, RadioGroupValueChangeDetails>;
51
+ /**
52
+ * The `name` shared by every radio in the group (form data key). Defaults to a `useId()` value;
53
+ * pass a real name when the group is inside a `<form>` you submit. Must be unique within the
54
+ * form: react-dom throws if a non-React radio shares it.
55
+ */
56
+ name?: string;
57
+ /** The `form` attribute, applied to the fieldset and to every radio. */
58
+ form?: string;
59
+ /**
60
+ * Marks every radio `required`, which makes the group required (one checked radio satisfies it),
61
+ * and renders `aria-required="true"` on the fieldset so the radiogroup itself is exposed as
62
+ * required.
63
+ */
64
+ required?: boolean;
65
+ /** Renders `<fieldset disabled>`: every radio is disabled, unfocusable and skipped by arrows. */
66
+ disabled?: boolean;
67
+ className?: StateValue<string | undefined, RadioGroupRootState>;
68
+ style?: StateValue<CSSProperties | undefined, RadioGroupRootState>;
69
+ children?: StateValue<ReactNode, RadioGroupRootState>;
70
+ /** Replace the rendered element. Must keep a `<fieldset>`. */
71
+ render?: RenderProp<ComponentPropsWithRef<"fieldset">, RadioGroupRootState>;
72
+ }
73
+ /**
74
+ * `<fieldset role="radiogroup">` that owns the group's state, the transition, the shared `name`,
75
+ * the form-reset listener and the mount reconciliation (design/components/radio-group.md 13.3).
76
+ * Carries `data-pending` while `valueChangeAction` is in flight.
77
+ *
78
+ * Owned keys (conventions 1.2): `role`, `aria-required`, `disabled`, `form`, `data-pending`,
79
+ * `data-disabled`.
80
+ *
81
+ * Keep every Item in the same Suspense boundary as its Root when server rendering. Partial
82
+ * hydration of a group (a boundary between Root and Items that stays dehydrated while the user
83
+ * interacts) is not supported by React: clicking a hydrated radio while same-`name` siblings are
84
+ * still dehydrated makes react-dom throw "Mixing React and non-React radio inputs with the same
85
+ * `name` is not supported". Development warns when Items hydrate after their Root.
86
+ */
87
+ export declare function RadioGroupRoot({ value, defaultValue, valueChangeAction, name: nameProp, form, required, disabled, className, style, children, render, ...rest }: RadioGroupRootProps): import("react").JSX.Element;
88
+ export declare namespace RadioGroupRoot {
89
+ var displayName: string;
90
+ }
91
+ //#endregion
92
+ //# sourceMappingURL=radio-group-root.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group-root.d.mts","names":[],"sources":["../../src/radio-group/radio-group-root.tsx"],"mappings":";;;;iBAsBiB,qCAAqC;;;;;;;WAO3C,QAAQ;;iBAGF;;WAEN;;WAEA;;WAEA;;iBAGM,4BAA4B,KAC3C;;;;;;;;;;;EAoBA;;;;;EAKA;;;;;;;;;;;;EAYA,oBAAoB,4BAA4B;;;;;;EAMhD;;EAEA;;;;;;EAMA;;EAEA;EACA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,mCAAmC;;;;;;;;;;;;;;;;wBAkCzC,iBACd,OACA,cACA,mBACA,MAAM,UACN,MACA,UACA,UACA,WACA,OACA,UACA,WACG,QACF,sCAAmB,IAAA;yBAbN"}
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import { createActionDetails } from "../internal/action-details.mjs";
3
+ import { dataAttr } from "../internal/data-attr.mjs";
4
+ import { transitionTypes } from "../internal/transition-types.mjs";
5
+ import { useControllableAction } from "../internal/use-controllable-action.mjs";
6
+ import { useRender } from "../internal/use-render.mjs";
7
+ import { RadioGroupContext } from "./radio-group-context.mjs";
8
+ import { useNativeGroupReconciliation } from "../internal/use-native-group-reconciliation.mjs";
9
+ import { useCallback, useId, useLayoutEffect, useRef } from "react";
10
+ import { jsx } from "react/jsx-runtime";
11
+ //#region src/radio-group/radio-group-root.tsx
12
+ const isDev = process.env.NODE_ENV !== "production";
13
+ /**
14
+ * Value of the group's checked radio as the DOM shows it (`prop: "checked"`) or as a form reset
15
+ * leaves it (`prop: "defaultChecked"`), or `null`. Only radios of this group's `name` count, so a
16
+ * nested group is ignored.
17
+ */
18
+ function readGroup(fieldset, name, prop) {
19
+ if (fieldset === null) return null;
20
+ for (const radio of fieldset.querySelectorAll("input[type=\"radio\"]")) if (radio.name === name && radio[prop]) return radio.value;
21
+ return null;
22
+ }
23
+ /**
24
+ * `<fieldset role="radiogroup">` that owns the group's state, the transition, the shared `name`,
25
+ * the form-reset listener and the mount reconciliation (design/components/radio-group.md 13.3).
26
+ * Carries `data-pending` while `valueChangeAction` is in flight.
27
+ *
28
+ * Owned keys (conventions 1.2): `role`, `aria-required`, `disabled`, `form`, `data-pending`,
29
+ * `data-disabled`.
30
+ *
31
+ * Keep every Item in the same Suspense boundary as its Root when server rendering. Partial
32
+ * hydration of a group (a boundary between Root and Items that stays dehydrated while the user
33
+ * interacts) is not supported by React: clicking a hydrated radio while same-`name` siblings are
34
+ * still dehydrated makes react-dom throw "Mixing React and non-React radio inputs with the same
35
+ * `name` is not supported". Development warns when Items hydrate after their Root.
36
+ */
37
+ function RadioGroupRoot({ value, defaultValue, valueChangeAction, name: nameProp, form, required = false, disabled = false, className, style, children, render, ...rest }) {
38
+ const fallbackName = useId();
39
+ const name = nameProp ?? fallbackName;
40
+ const fieldsetRef = useRef(null);
41
+ const warnedElement = useRef(false);
42
+ const { optimistic, pending, dispatch, latestInFlight } = useControllableAction({
43
+ controlled: value,
44
+ defaultValue,
45
+ initialValue: null,
46
+ action: valueChangeAction,
47
+ transitionTypes: () => transitionTypes("radio-group"),
48
+ warn: {
49
+ component: "RadioGroup.Root",
50
+ prop: "value"
51
+ }
52
+ });
53
+ /** What the user intends: the latest in-flight dispatch, else optimistic (conventions 3.8 rule 1). */
54
+ const base = () => {
55
+ const inFlight = latestInFlight();
56
+ return inFlight === null ? optimistic : inFlight.next;
57
+ };
58
+ const { onItemMounted } = useNativeGroupReconciliation({
59
+ element: fieldsetRef,
60
+ readCurrent: () => readGroup(fieldsetRef.current, name, "checked"),
61
+ readDefault: () => readGroup(fieldsetRef.current, name, "defaultChecked"),
62
+ base,
63
+ onPlatformChange: (next, event) => dispatch(next, createActionDetails(event, { reason: "platform" }))
64
+ });
65
+ const serverRadios = useRef(null);
66
+ const warnedPartialHydration = useRef(false);
67
+ useLayoutEffect(() => {
68
+ if (!isDev) return;
69
+ const el = fieldsetRef.current;
70
+ serverRadios.current = new Set(el === null ? [] : el.querySelectorAll("input[type=\"radio\"]"));
71
+ return () => {
72
+ serverRadios.current = null;
73
+ };
74
+ }, []);
75
+ const onItemMountedWithCheck = useCallback((element) => {
76
+ if (isDev && !warnedPartialHydration.current && element != null && serverRadios.current?.has(element) === true) {
77
+ warnedPartialHydration.current = true;
78
+ console.error("RadioGroup.Item: an Item hydrated after its RadioGroup.Root (a Suspense boundary between them). Partial hydration of a radio group is not supported by React: clicking a hydrated radio while same-name radios are still dehydrated makes react-dom throw \"Mixing React and non-React radio inputs with the same name is not supported\". Keep every Item in the same Suspense boundary as its Root.");
79
+ }
80
+ onItemMounted(element);
81
+ }, [onItemMounted]);
82
+ const libraryRef = useCallback((el) => {
83
+ fieldsetRef.current = el;
84
+ if (isDev && !warnedElement.current && el.tagName !== "FIELDSET") {
85
+ warnedElement.current = true;
86
+ console.error(`RadioGroup.Root: expected to render a <fieldset> element but got <${el.tagName.toLowerCase()}>. The platform semantics (legend naming, disabled inheritance, form reset) need a real <fieldset>.`);
87
+ }
88
+ return () => {
89
+ fieldsetRef.current = null;
90
+ };
91
+ }, []);
92
+ const context = {
93
+ name,
94
+ form,
95
+ required,
96
+ optimistic,
97
+ pending,
98
+ disabled,
99
+ defaultValue: value === void 0 ? defaultValue ?? null : void 0,
100
+ onItemMounted: onItemMountedWithCheck,
101
+ select: (next, event) => {
102
+ if (next === optimistic) return;
103
+ dispatch(next, createActionDetails(event, { reason: "activate" }));
104
+ }
105
+ };
106
+ const element = useRender({
107
+ defaultElement: "fieldset",
108
+ render,
109
+ state: {
110
+ value: optimistic,
111
+ pending,
112
+ disabled
113
+ },
114
+ className,
115
+ style,
116
+ children,
117
+ props: rest,
118
+ libraryProps: {
119
+ role: "radiogroup",
120
+ "aria-required": required ? "true" : void 0,
121
+ disabled,
122
+ form,
123
+ "data-pending": dataAttr(pending),
124
+ "data-disabled": dataAttr(disabled)
125
+ },
126
+ ref: libraryRef
127
+ });
128
+ return /* @__PURE__ */ jsx(RadioGroupContext, {
129
+ value: context,
130
+ children: element
131
+ });
132
+ }
133
+ RadioGroupRoot.displayName = "RadioGroupRoot";
134
+ //#endregion
135
+ export { RadioGroupRoot };
136
+
137
+ //# sourceMappingURL=radio-group-root.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group-root.mjs","names":[],"sources":["../../src/radio-group/radio-group-root.tsx"],"sourcesContent":["\"use client\";\nimport { useCallback, useId, useLayoutEffect, useRef } from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport { createActionDetails } from \"../internal/action-details.js\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport { transitionTypes } from \"../internal/transition-types.js\";\nimport type {\n ActionDetails,\n ChangeAction,\n ChangeReason,\n RenderProp,\n StateValue,\n} from \"../internal/types.js\";\nimport { useControllableAction } from \"../internal/use-controllable-action.js\";\nimport { useNativeGroupReconciliation } from \"../internal/use-native-group-reconciliation.js\";\nimport { useRender } from \"../internal/use-render.js\";\nimport { RadioGroupContext } from \"./radio-group-context.js\";\nimport type { RadioGroupContextValue } from \"./radio-group-context.js\";\n\nconst isDev = process.env.NODE_ENV !== \"production\";\n\n/** Details passed as the second argument of `valueChangeAction`. */\nexport interface RadioGroupValueChangeDetails extends ActionDetails {\n /**\n * `\"activate\"`: the user checked a radio (click, Space, label click, or an arrow key, all of\n * which arrive as a native `click`). `\"platform\"`: the browser changed the checked radio\n * itself: a form reset (`details.event` is the `reset` event), or a click before hydration /\n * Firefox form-state restoration found at mount (`details.event` is `undefined`).\n */\n readonly reason: ChangeReason;\n}\n\nexport interface RadioGroupRootState {\n /** Optimistic checked value, or `null`. Content rendered from it must not suspend. */\n readonly value: string | null;\n /** An action dispatched through this group is in flight. */\n readonly pending: boolean;\n /** The `disabled` prop. */\n readonly disabled: boolean;\n}\n\nexport interface RadioGroupRootProps extends Omit<\n ComponentPropsWithRef<\"fieldset\">,\n | \"className\"\n | \"style\"\n | \"children\"\n | \"defaultValue\"\n | \"defaultChecked\"\n | \"name\"\n | \"disabled\"\n | \"form\"\n> {\n /**\n * Controlled checked value. `null` checks nothing; `undefined` means uncontrolled.\n *\n * A form reset returns each radio to the `checked` it had when *that radio* mounted (React sets\n * `defaultChecked` once, from the initial `checked`). An Item added on the client while `value`\n * equals its value therefore also gets `defaultChecked`, so two radios may carry it and the\n * reset target is not necessarily the group's mount-time value. The reset is offered to\n * `valueChangeAction` as usual; for a stable target remount the group with a `key` or use\n * `defaultValue`, whose latest value every Item mirrors.\n */\n value?: string | null;\n /**\n * Initial value in uncontrolled mode. Defaults to `null` (nothing checked). Also the value a\n * form reset returns to: the latest prop value is mirrored into the radios' `defaultChecked`.\n */\n defaultValue?: string | null;\n /**\n * Runs inside the Root's transition whenever the checked radio changes. May be sync or async\n * (also a Server Function); rejections reach the nearest Error Boundary and roll the selection\n * back.\n *\n * `next` is a string for every user interaction. It is `null` only with\n * `details.reason === \"platform\"`, when a form reset returned the group to \"nothing checked\".\n * Every arrow key press dispatches; the latest dispatch wins. A `setState` placed after your\n * own `await` is not a Transition update; wrap it in `startTransition` (React limitation).\n * `details.event.preventDefault()` is not a veto; use controlled mode to veto a change.\n */\n valueChangeAction?: ChangeAction<string | null, RadioGroupValueChangeDetails>;\n /**\n * The `name` shared by every radio in the group (form data key). Defaults to a `useId()` value;\n * pass a real name when the group is inside a `<form>` you submit. Must be unique within the\n * form: react-dom throws if a non-React radio shares it.\n */\n name?: string;\n /** The `form` attribute, applied to the fieldset and to every radio. */\n form?: string;\n /**\n * Marks every radio `required`, which makes the group required (one checked radio satisfies it),\n * and renders `aria-required=\"true\"` on the fieldset so the radiogroup itself is exposed as\n * required.\n */\n required?: boolean;\n /** Renders `<fieldset disabled>`: every radio is disabled, unfocusable and skipped by arrows. */\n disabled?: boolean;\n className?: StateValue<string | undefined, RadioGroupRootState>;\n style?: StateValue<CSSProperties | undefined, RadioGroupRootState>;\n children?: StateValue<ReactNode, RadioGroupRootState>;\n /** Replace the rendered element. Must keep a `<fieldset>`. */\n render?: RenderProp<ComponentPropsWithRef<\"fieldset\">, RadioGroupRootState>;\n}\n\n/**\n * Value of the group's checked radio as the DOM shows it (`prop: \"checked\"`) or as a form reset\n * leaves it (`prop: \"defaultChecked\"`), or `null`. Only radios of this group's `name` count, so a\n * nested group is ignored.\n */\nfunction readGroup(\n fieldset: HTMLFieldSetElement | null,\n name: string,\n prop: \"checked\" | \"defaultChecked\",\n): string | null {\n if (fieldset === null) return null;\n for (const radio of fieldset.querySelectorAll<HTMLInputElement>('input[type=\"radio\"]')) {\n if (radio.name === name && radio[prop]) return radio.value;\n }\n return null;\n}\n\n/**\n * `<fieldset role=\"radiogroup\">` that owns the group's state, the transition, the shared `name`,\n * the form-reset listener and the mount reconciliation (design/components/radio-group.md 13.3).\n * Carries `data-pending` while `valueChangeAction` is in flight.\n *\n * Owned keys (conventions 1.2): `role`, `aria-required`, `disabled`, `form`, `data-pending`,\n * `data-disabled`.\n *\n * Keep every Item in the same Suspense boundary as its Root when server rendering. Partial\n * hydration of a group (a boundary between Root and Items that stays dehydrated while the user\n * interacts) is not supported by React: clicking a hydrated radio while same-`name` siblings are\n * still dehydrated makes react-dom throw \"Mixing React and non-React radio inputs with the same\n * `name` is not supported\". Development warns when Items hydrate after their Root.\n */\nexport function RadioGroupRoot({\n value,\n defaultValue,\n valueChangeAction,\n name: nameProp,\n form,\n required = false,\n disabled = false,\n className,\n style,\n children,\n render,\n ...rest\n}: RadioGroupRootProps) {\n const fallbackName = useId();\n const name = nameProp ?? fallbackName;\n const fieldsetRef = useRef<HTMLFieldSetElement | null>(null);\n const warnedElement = useRef(false);\n\n const { optimistic, pending, dispatch, latestInFlight } = useControllableAction<\n string | null,\n RadioGroupValueChangeDetails\n >({\n controlled: value,\n defaultValue,\n initialValue: null,\n action: valueChangeAction,\n transitionTypes: () => transitionTypes(\"radio-group\"),\n warn: { component: \"RadioGroup.Root\", prop: \"value\" },\n });\n // Deliberately no warning when neither `value` nor `defaultValue` is given: an unchecked group\n // is the HTML default (design decision 2).\n\n /** What the user intends: the latest in-flight dispatch, else optimistic (conventions 3.8 rule 1). */\n const base = (): string | null => {\n const inFlight = latestInFlight();\n // Not `?.next ?? optimistic`: an in-flight reset to `null` is a real intent.\n return inFlight === null ? optimistic : inFlight.next;\n };\n\n // The residual browser paths (design section 5): one dispatch per group, from here. Items that\n // mount after the Root report through `onItemMounted` so the group is reconciled again.\n const { onItemMounted } = useNativeGroupReconciliation<string | null>({\n element: fieldsetRef,\n readCurrent: () => readGroup(fieldsetRef.current, name, \"checked\"),\n readDefault: () => readGroup(fieldsetRef.current, name, \"defaultChecked\"),\n base,\n onPlatformChange: (next, event) =>\n dispatch(next, createActionDetails(event, { reason: \"platform\" })),\n });\n\n // Dev-only partial-hydration detection. The radios present in the fieldset when the Root\n // mounts are either mounted in the Root's commit or still dehydrated server HTML. An Item that\n // mounts later on one of those elements hydrated after the Root (an Item created on the client\n // gets a new element). Items of the Root's own commit run their mount effect before this one,\n // while the snapshot is still `null`; StrictMode's re-run finds it reset by the cleanup.\n const serverRadios = useRef<ReadonlySet<Element> | null>(null);\n const warnedPartialHydration = useRef(false);\n useLayoutEffect(() => {\n if (!isDev) return;\n const el = fieldsetRef.current;\n serverRadios.current = new Set(el === null ? [] : el.querySelectorAll('input[type=\"radio\"]'));\n return () => {\n serverRadios.current = null;\n };\n }, []);\n const onItemMountedWithCheck = useCallback(\n (element?: Element | null) => {\n if (\n isDev &&\n !warnedPartialHydration.current &&\n element != null &&\n serverRadios.current?.has(element) === true\n ) {\n warnedPartialHydration.current = true;\n console.error(\n `RadioGroup.Item: an Item hydrated after its RadioGroup.Root (a Suspense boundary ` +\n `between them). Partial hydration of a radio group is not supported by React: ` +\n `clicking a hydrated radio while same-name radios are still dehydrated makes ` +\n `react-dom throw \"Mixing React and non-React radio inputs with the same name is not ` +\n `supported\". Keep every Item in the same Suspense boundary as its Root.`,\n );\n }\n onItemMounted(element);\n },\n [onItemMounted],\n );\n\n const libraryRef = useCallback((el: HTMLFieldSetElement) => {\n fieldsetRef.current = el;\n if (isDev && !warnedElement.current && el.tagName !== \"FIELDSET\") {\n warnedElement.current = true;\n console.error(\n `RadioGroup.Root: expected to render a <fieldset> element but got ` +\n `<${el.tagName.toLowerCase()}>. The platform semantics (legend naming, disabled ` +\n `inheritance, form reset) need a real <fieldset>.`,\n );\n }\n return () => {\n fieldsetRef.current = null;\n };\n }, []);\n\n const context: RadioGroupContextValue = {\n name,\n form,\n required,\n optimistic,\n pending,\n disabled,\n defaultValue: value === undefined ? (defaultValue ?? null) : undefined,\n onItemMounted: onItemMountedWithCheck,\n select: (next, event) => {\n // No-op rule against the optimistic value (conventions 2.3 item 7, design 4.2).\n if (next === optimistic) return;\n dispatch(next, createActionDetails(event, { reason: \"activate\" }));\n },\n };\n\n const state: RadioGroupRootState = { value: optimistic, pending, disabled };\n\n const element = useRender<ComponentPropsWithRef<\"fieldset\">, RadioGroupRootState>({\n defaultElement: \"fieldset\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n libraryProps: {\n role: \"radiogroup\",\n \"aria-required\": required ? \"true\" : undefined,\n disabled,\n form,\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n },\n ref: libraryRef,\n });\n\n return <RadioGroupContext value={context}>{element}</RadioGroupContext>;\n}\n\nRadioGroupRoot.displayName = \"RadioGroupRoot\";\n"],"mappings":";;;;;;;;;;;AAmBA,MAAM,QAAQ,QAAQ,IAAI,aAAa;;;;;;AAyFvC,SAAS,UACP,UACA,MACA,MACe;CACf,IAAI,aAAa,MAAM,OAAO;CAC9B,KAAK,MAAM,SAAS,SAAS,iBAAmC,uBAAqB,GACnF,IAAI,MAAM,SAAS,QAAQ,MAAM,OAAO,OAAO,MAAM;CAEvD,OAAO;AACT;;;;;;;;;;;;;;;AAgBA,SAAgB,eAAe,EAC7B,OACA,cACA,mBACA,MAAM,UACN,MACA,WAAW,OACX,WAAW,OACX,WACA,OACA,UACA,QACA,GAAG,QACmB;CACtB,MAAM,eAAe,MAAM;CAC3B,MAAM,OAAO,YAAY;CACzB,MAAM,cAAc,OAAmC,IAAI;CAC3D,MAAM,gBAAgB,OAAO,KAAK;CAElC,MAAM,EAAE,YAAY,SAAS,UAAU,mBAAmB,sBAGxD;EACA,YAAY;EACZ;EACA,cAAc;EACd,QAAQ;EACR,uBAAuB,gBAAgB,aAAa;EACpD,MAAM;GAAE,WAAW;GAAmB,MAAM;EAAQ;CACtD,CAAC;;CAKD,MAAM,aAA4B;EAChC,MAAM,WAAW,eAAe;EAEhC,OAAO,aAAa,OAAO,aAAa,SAAS;CACnD;CAIA,MAAM,EAAE,kBAAkB,6BAA4C;EACpE,SAAS;EACT,mBAAmB,UAAU,YAAY,SAAS,MAAM,SAAS;EACjE,mBAAmB,UAAU,YAAY,SAAS,MAAM,gBAAgB;EACxE;EACA,mBAAmB,MAAM,UACvB,SAAS,MAAM,oBAAoB,OAAO,EAAE,QAAQ,WAAW,CAAC,CAAC;CACrE,CAAC;CAOD,MAAM,eAAe,OAAoC,IAAI;CAC7D,MAAM,yBAAyB,OAAO,KAAK;CAC3C,sBAAsB;EACpB,IAAI,CAAC,OAAO;EACZ,MAAM,KAAK,YAAY;EACvB,aAAa,UAAU,IAAI,IAAI,OAAO,OAAO,CAAC,IAAI,GAAG,iBAAiB,uBAAqB,CAAC;EAC5F,aAAa;GACX,aAAa,UAAU;EACzB;CACF,GAAG,CAAC,CAAC;CACL,MAAM,yBAAyB,aAC5B,YAA6B;EAC5B,IACE,SACA,CAAC,uBAAuB,WACxB,WAAW,QACX,aAAa,SAAS,IAAI,OAAO,MAAM,MACvC;GACA,uBAAuB,UAAU;GACjC,QAAQ,MACN,uYAKF;EACF;EACA,cAAc,OAAO;CACvB,GACA,CAAC,aAAa,CAChB;CAEA,MAAM,aAAa,aAAa,OAA4B;EAC1D,YAAY,UAAU;EACtB,IAAI,SAAS,CAAC,cAAc,WAAW,GAAG,YAAY,YAAY;GAChE,cAAc,UAAU;GACxB,QAAQ,MACN,qEACM,GAAG,QAAQ,YAAY,EAAE,oGAEjC;EACF;EACA,aAAa;GACX,YAAY,UAAU;EACxB;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,UAAkC;EACtC;EACA;EACA;EACA;EACA;EACA;EACA,cAAc,UAAU,KAAA,IAAa,gBAAgB,OAAQ,KAAA;EAC7D,eAAe;EACf,SAAS,MAAM,UAAU;GAEvB,IAAI,SAAS,YAAY;GACzB,SAAS,MAAM,oBAAoB,OAAO,EAAE,QAAQ,WAAW,CAAC,CAAC;EACnE;CACF;CAIA,MAAM,UAAU,UAAkE;EAChF,gBAAgB;EAChB;EACA,OAAA;GALmC,OAAO;GAAY;GAAS;EAK3D;EACJ;EACA;EACA;EACA,OAAO;EACP,cAAc;GACZ,MAAM;GACN,iBAAiB,WAAW,SAAS,KAAA;GACrC;GACA;GACA,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;EACpC;EACA,KAAK;CACP,CAAC;CAED,OAAO,oBAAC,mBAAD;EAAmB,OAAO;EAAU,UAAA;CAA2B,CAAA;AACxE;AAEA,eAAe,cAAc"}
@@ -0,0 +1,3 @@
1
+ import "../internal/platform-attributes.mjs";
2
+ import { Switch, SwitchCheckedChangeDetails, SwitchProps, SwitchState } from "./switch.mjs";
3
+ export { Switch, type SwitchCheckedChangeDetails, type SwitchProps, type SwitchState };
@@ -0,0 +1 @@
1
+ export { Switch } from "./switch.mjs";