@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,82 @@
1
+ "use client";
2
+ import { useTransitionBoundary } from "../internal/transition-boundary.mjs";
3
+ import { createActionDetails } from "../internal/action-details.mjs";
4
+ import { dataAttr } from "../internal/data-attr.mjs";
5
+ import { transitionTypes } from "../internal/transition-types.mjs";
6
+ import { useControllableAction } from "../internal/use-controllable-action.mjs";
7
+ import { useRender } from "../internal/use-render.mjs";
8
+ import { guardCheckableChange, useNativeChecked } from "../internal/use-native-checked.mjs";
9
+ //#region src/checkbox/checkbox.tsx
10
+ /**
11
+ * A checkbox (WAI-ARIA "Checkbox" pattern, dual- and mixed-state). Renders
12
+ * `<input type="checkbox">` whose DOM `checked` is the optimistic state; the input carries
13
+ * `data-pending` while `checkedChangeAction` is in flight and takes part in forms natively.
14
+ *
15
+ * Owned keys (a `render` element's value is overridden): `type`, `checked`, `defaultChecked`,
16
+ * `indeterminate` (stripped), `aria-checked` (always removed), `disabled`, `data-checked`,
17
+ * `data-indeterminate`, `data-pending`, `data-disabled`. `role` passes through. Event handlers
18
+ * are merged rather than owned: a `render` element's own `onChange` (or `onClick`) runs first,
19
+ * then the library's; an `onClick` that calls `preventDefault()` cancels the change (nothing is
20
+ * dispatched).
21
+ */
22
+ function Checkbox({ checked, defaultChecked, indeterminate = false, checkedChangeAction, disabled = false, transition, className, style, render, ...rest }) {
23
+ const { optimistic, pending, dispatch, latestInFlight } = useControllableAction({
24
+ controlled: checked,
25
+ defaultValue: defaultChecked,
26
+ initialValue: false,
27
+ action: checkedChangeAction,
28
+ transitionTypes: (next) => transitionTypes("checkbox", next ? "check" : "uncheck"),
29
+ warn: {
30
+ component: "Checkbox",
31
+ prop: "checked"
32
+ }
33
+ });
34
+ const shownIndeterminate = indeterminate && !pending;
35
+ const inputRef = useNativeChecked({
36
+ type: "checkbox",
37
+ component: "Checkbox",
38
+ checked: optimistic,
39
+ defaultChecked: checked === void 0 ? defaultChecked ?? false : void 0,
40
+ indeterminate: shownIndeterminate,
41
+ latestInFlight,
42
+ onPlatformChange: (next, event) => dispatch(next, createActionDetails(event, { reason: "platform" }))
43
+ });
44
+ const element = useRender({
45
+ defaultElement: "input",
46
+ render,
47
+ state: {
48
+ checked: optimistic,
49
+ indeterminate: shownIndeterminate,
50
+ pending,
51
+ disabled
52
+ },
53
+ className,
54
+ style,
55
+ children: void 0,
56
+ ref: inputRef,
57
+ props: rest,
58
+ libraryProps: {
59
+ type: "checkbox",
60
+ checked: optimistic,
61
+ defaultChecked: void 0,
62
+ indeterminate: void 0,
63
+ "aria-checked": void 0,
64
+ disabled,
65
+ "data-checked": dataAttr(optimistic),
66
+ "data-indeterminate": dataAttr(shownIndeterminate),
67
+ "data-pending": dataAttr(pending),
68
+ "data-disabled": dataAttr(disabled),
69
+ onChange: (event) => {
70
+ if (disabled) return;
71
+ const nativeEvent = event.nativeEvent;
72
+ guardCheckableChange(nativeEvent, () => dispatch(!optimistic, createActionDetails(nativeEvent, { reason: "activate" })), "Checkbox");
73
+ }
74
+ }
75
+ });
76
+ return useTransitionBoundary("Checkbox", transition, element);
77
+ }
78
+ Checkbox.displayName = "Checkbox";
79
+ //#endregion
80
+ export { Checkbox };
81
+
82
+ //# sourceMappingURL=checkbox.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox.mjs","names":[],"sources":["../../src/checkbox/checkbox.tsx"],"sourcesContent":["\"use client\";\nimport type { ChangeEvent, ComponentPropsWithRef, CSSProperties, ViewTransitionClass } from \"react\";\nimport { useTransitionBoundary } from \"../internal/transition-boundary.js\";\nimport { createActionDetails } from \"../internal/action-details.js\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport { transitionTypes } from \"../internal/transition-types.js\";\nimport type {\n ActionDetails,\n ChangeAction,\n ChangeReason,\n RenderProp,\n StateValue,\n} from \"../internal/types.js\";\nimport { useControllableAction } from \"../internal/use-controllable-action.js\";\nimport { guardCheckableChange, useNativeChecked } from \"../internal/use-native-checked.js\";\nimport { useRender } from \"../internal/use-render.js\";\n\nexport interface CheckboxState {\n /** Optimistic checked state: what the user sees, including an in-flight change. */\n readonly checked: boolean;\n /**\n * The `indeterminate` prop, suspended while an action is in flight: `false` whenever `pending`\n * is true, so that the attribute, the DOM property and `:indeterminate` always agree.\n */\n readonly indeterminate: boolean;\n /** An action dispatched by this Checkbox is in flight (including the resulting render). */\n readonly pending: boolean;\n /** The `disabled` prop. */\n readonly disabled: boolean;\n}\n\n/** Details passed as the second argument of `checkedChangeAction`. */\nexport interface CheckboxCheckedChangeDetails extends ActionDetails {\n /**\n * `\"activate\"`: the user toggled the box (click, Space, label click); `event` is the native\n * `click` event. `\"platform\"`: the browser changed the value itself: a form reset (`event` is\n * the `reset` event) or a click before hydration / Firefox form-state restoration found on\n * mount (`event` is `undefined`).\n */\n readonly reason: ChangeReason;\n}\n\nexport interface CheckboxProps extends Omit<\n ComponentPropsWithRef<\"input\">,\n | \"type\"\n | \"checked\"\n | \"defaultChecked\"\n | \"onChange\"\n | \"aria-checked\"\n | \"className\"\n | \"style\"\n | \"children\"\n> {\n /** Controlled checked state. `undefined` means uncontrolled. */\n checked?: boolean;\n /**\n * Initial checked state in uncontrolled mode (default `false`). Also the value a form reset\n * returns to: the latest prop value is mirrored into the input's `defaultChecked`.\n */\n defaultChecked?: boolean;\n /**\n * Controlled-only mixed state (APG tri-state checkbox), derived by the parent from other state;\n * there is no `defaultIndeterminate` and no action. Rendered as `el.indeterminate`,\n * `data-indeterminate` and `:indeterminate`, except while an action is pending. Clicking a\n * mixed box dispatches `checked: true` (for the usual unchecked + mixed representation). Does\n * not affect what the form submits.\n */\n indeterminate?: boolean;\n /**\n * Called with the next checked state on every change. Runs inside the Checkbox's transition;\n * may be sync or async (also a Server Function). Rejections reach the nearest Error Boundary.\n * Also called with `details.reason === \"platform\"` for a form reset or a pre-hydration click.\n *\n * A `setState` placed after your own `await` is not a Transition update; wrap it in\n * `startTransition` (React limitation). `details.event.preventDefault()` is not a veto and is\n * unsupported here; use controlled mode to veto a change.\n */\n checkedChangeAction?: ChangeAction<boolean, CheckboxCheckedChangeDetails>;\n /** Renders a natively disabled input; never dispatches. Default `false`. */\n disabled?: boolean;\n /** Submitted as the input's value when checked. Default `\"on\"` (platform). */\n value?: string;\n /**\n * Forwarded as `default` to the Checkbox's `<ViewTransition>`. Default: no boundary. Animates the\n * commit that ends an action, not the optimistic flip; animate the flip with CSS on `:checked`.\n *\n * Static: without `transition` the part renders no `<ViewTransition>`; changing it between\n * `undefined` and a value remounts the element. Any value, `\"none\"` included, makes a mount or\n * `<Activity>` reveal of this part inside a transition start a document view transition: the\n * page cross-fades for about 250 ms and the next transition commit waits for it (issue #35).\n */\n transition?: ViewTransitionClass;\n className?: StateValue<string | undefined, CheckboxState>;\n style?: StateValue<CSSProperties | undefined, CheckboxState>;\n /**\n * Replace the rendered element (element form) or take over rendering (function form). Must keep\n * an `<input type=\"checkbox\">`.\n */\n render?: RenderProp<ComponentPropsWithRef<\"input\">, CheckboxState>;\n}\n\n/**\n * A checkbox (WAI-ARIA \"Checkbox\" pattern, dual- and mixed-state). Renders\n * `<input type=\"checkbox\">` whose DOM `checked` is the optimistic state; the input carries\n * `data-pending` while `checkedChangeAction` is in flight and takes part in forms natively.\n *\n * Owned keys (a `render` element's value is overridden): `type`, `checked`, `defaultChecked`,\n * `indeterminate` (stripped), `aria-checked` (always removed), `disabled`, `data-checked`,\n * `data-indeterminate`, `data-pending`, `data-disabled`. `role` passes through. Event handlers\n * are merged rather than owned: a `render` element's own `onChange` (or `onClick`) runs first,\n * then the library's; an `onClick` that calls `preventDefault()` cancels the change (nothing is\n * dispatched).\n */\nexport function Checkbox({\n checked,\n defaultChecked,\n indeterminate = false,\n checkedChangeAction,\n disabled = false,\n transition,\n className,\n style,\n render,\n ...rest\n}: CheckboxProps) {\n const { optimistic, pending, dispatch, latestInFlight } = useControllableAction<\n boolean,\n CheckboxCheckedChangeDetails\n >({\n controlled: checked,\n defaultValue: defaultChecked,\n initialValue: false,\n action: checkedChangeAction,\n transitionTypes: (next) => transitionTypes(\"checkbox\", next ? \"check\" : \"uncheck\"),\n warn: { component: \"Checkbox\", prop: \"checked\" },\n });\n\n // Suspended while pending (conventions 4.1): the browser clears the property on the click, and\n // the parent may not have recomputed yet. Restored on settle if the parent still says mixed.\n const shownIndeterminate = indeterminate && !pending;\n\n const inputRef = useNativeChecked({\n type: \"checkbox\",\n component: \"Checkbox\",\n checked: optimistic,\n // Uncontrolled: the latest prop is the reset target. Controlled: React's mount-time value.\n defaultChecked: checked === undefined ? (defaultChecked ?? false) : undefined,\n indeterminate: shownIndeterminate,\n latestInFlight,\n onPlatformChange: (next, event) =>\n dispatch(next, createActionDetails(event, { reason: \"platform\" })),\n });\n\n const state: CheckboxState = {\n checked: optimistic,\n indeterminate: shownIndeterminate,\n pending,\n disabled,\n };\n\n const element = useRender<ComponentPropsWithRef<\"input\">, CheckboxState>({\n defaultElement: \"input\",\n render,\n state,\n className,\n style,\n children: undefined,\n ref: inputRef,\n // Pass-through layer: a `render` element's own props win over these (`role` included).\n props: rest,\n // Library-controlled layer (owned keys, conventions 1.2).\n libraryProps: {\n type: \"checkbox\",\n // The DOM state is the optimistic state (conventions 3.2).\n checked: optimistic,\n defaultChecked: undefined,\n // Not a DOM attribute; the hook sets the property. Owned so a `render` element's own\n // `indeterminate` prop (which react-dom would warn about) is stripped.\n ...({ indeterminate: undefined } as object),\n \"aria-checked\": undefined,\n // Owned so that native disabledness, `data-disabled` and the click guard always agree: a\n // `render` element cannot re-enable (`disabled={false}`) or disable the input on its own.\n disabled,\n \"data-checked\": dataAttr(optimistic),\n \"data-indeterminate\": dataAttr(shownIndeterminate),\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n onChange: (event: ChangeEvent<HTMLInputElement>) => {\n // A natively disabled input fires no click; this covers `render` elements that do not\n // honour `disabled`.\n if (disabled) return;\n const nativeEvent = event.nativeEvent;\n // `indeterminate` plays no part: the platform's rule is \"flip checked, clear mixed\".\n guardCheckableChange(\n nativeEvent,\n () => dispatch(!optimistic, createActionDetails(nativeEvent, { reason: \"activate\" })),\n \"Checkbox\",\n );\n },\n },\n });\n\n return useTransitionBoundary(\"Checkbox\", transition, element);\n}\n\nCheckbox.displayName = \"Checkbox\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAiHA,SAAgB,SAAS,EACvB,SACA,gBACA,gBAAgB,OAChB,qBACA,WAAW,OACX,YACA,WACA,OACA,QACA,GAAG,QACa;CAChB,MAAM,EAAE,YAAY,SAAS,UAAU,mBAAmB,sBAGxD;EACA,YAAY;EACZ,cAAc;EACd,cAAc;EACd,QAAQ;EACR,kBAAkB,SAAS,gBAAgB,YAAY,OAAO,UAAU,SAAS;EACjF,MAAM;GAAE,WAAW;GAAY,MAAM;EAAU;CACjD,CAAC;CAID,MAAM,qBAAqB,iBAAiB,CAAC;CAE7C,MAAM,WAAW,iBAAiB;EAChC,MAAM;EACN,WAAW;EACX,SAAS;EAET,gBAAgB,YAAY,KAAA,IAAa,kBAAkB,QAAS,KAAA;EACpE,eAAe;EACf;EACA,mBAAmB,MAAM,UACvB,SAAS,MAAM,oBAAoB,OAAO,EAAE,QAAQ,WAAW,CAAC,CAAC;CACrE,CAAC;CASD,MAAM,UAAU,UAAyD;EACvE,gBAAgB;EAChB;EACA,OAAA;GATA,SAAS;GACT,eAAe;GACf;GACA;EAMI;EACJ;EACA;EACA,UAAU,KAAA;EACV,KAAK;EAEL,OAAO;EAEP,cAAc;GACZ,MAAM;GAEN,SAAS;GACT,gBAAgB,KAAA;GAGV,eAAe,KAAA;GACrB,gBAAgB,KAAA;GAGhB;GACA,gBAAgB,SAAS,UAAU;GACnC,sBAAsB,SAAS,kBAAkB;GACjD,gBAAgB,SAAS,OAAO;GAChC,iBAAiB,SAAS,QAAQ;GAClC,WAAW,UAAyC;IAGlD,IAAI,UAAU;IACd,MAAM,cAAc,MAAM;IAE1B,qBACE,mBACM,SAAS,CAAC,YAAY,oBAAoB,aAAa,EAAE,QAAQ,WAAW,CAAC,CAAC,GACpF,UACF;GACF;EACF;CACF,CAAC;CAED,OAAO,sBAAsB,YAAY,YAAY,OAAO;AAC9D;AAEA,SAAS,cAAc"}
@@ -0,0 +1,3 @@
1
+ import "../internal/platform-attributes.mjs";
2
+ import { Checkbox, CheckboxCheckedChangeDetails, CheckboxProps, CheckboxState } from "./checkbox.mjs";
3
+ export { Checkbox, type CheckboxCheckedChangeDetails, type CheckboxProps, type CheckboxState };
@@ -0,0 +1 @@
1
+ export { Checkbox } from "./checkbox.mjs";
@@ -0,0 +1,44 @@
1
+ import { Action, ActionDetails, RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
3
+ //#region src/dialog/dialog-close.d.ts
4
+ export interface DialogCloseState {
5
+ /** The `action` is in flight. */
6
+ readonly pending: boolean;
7
+ readonly disabled: boolean;
8
+ }
9
+ /** Details passed to `Dialog.Close`'s `action`. */
10
+ export interface DialogCloseDetails extends ActionDetails {
11
+ /** The `value` the dialog closes with (`dialog.returnValue`); `""` without `value`. */
12
+ readonly returnValue: string;
13
+ }
14
+ export interface DialogCloseProps extends Omit<ComponentPropsWithRef<"button">, "onClick" | "value" | "className" | "style" | "children"> {
15
+ /**
16
+ * Runs inside this part's own transition, then closes the dialog with `close(value)`. A
17
+ * rejection reaches the nearest Error Boundary above the Close part and leaves the dialog open.
18
+ * Without `action` the button is a native `command="request-close"` invoker (JS-free).
19
+ */
20
+ action?: Action<[details: DialogCloseDetails]>;
21
+ /** Becomes `dialog.returnValue` (and `details.returnValue` of the close notification). */
22
+ value?: string;
23
+ disabled?: boolean;
24
+ className?: StateValue<string | undefined, DialogCloseState>;
25
+ style?: StateValue<CSSProperties | undefined, DialogCloseState>;
26
+ children?: StateValue<ReactNode, DialogCloseState>;
27
+ render?: RenderProp<ComponentPropsWithRef<"button">, DialogCloseState>;
28
+ }
29
+ /**
30
+ * A close button: `<button type="button" commandfor command="request-close">`. Without `action`
31
+ * the browser closes the dialog (a close request: `cancel`, then `close`), with `value` as the
32
+ * `returnValue`. With `action` the click is cancelled, the action runs in this part's own
33
+ * transition (`data-pending` on the button) and the dialog closes with `close(value)` once it
34
+ * resolves; a rejection leaves the dialog open.
35
+ *
36
+ * Owned keys (conventions 1.2): `type` (on a `<button>` only), `disabled`, `commandfor`,
37
+ * `command`, `value`, `onClick` (with `action`), `data-pending`, `data-disabled`.
38
+ */
39
+ export declare function DialogClose({ action, value, disabled, className, style, children, render, ...rest }: DialogCloseProps): ReactNode;
40
+ export declare namespace DialogClose {
41
+ var displayName: string;
42
+ }
43
+ //#endregion
44
+ //# sourceMappingURL=dialog-close.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-close.d.mts","names":[],"sources":["../../src/dialog/dialog-close.tsx"],"mappings":";;;iBAUiB;;WAEN;WACA;;;iBAIM,2BAA2B;;WAEjC;;iBAGM,yBAAyB,KACxC;;;;;;EAQA,SAAS,QAAQ,SAAS;;EAE1B;EACA;EACA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,iCAAiC;;;;;;;;;;;;wBAevC,cACd,QACA,OACA,UACA,WACA,OACA,UACA,WACG,QACF,mBAAgB;yBATH"}
@@ -0,0 +1,76 @@
1
+ "use client";
2
+ import { createActionDetails } from "../internal/action-details.mjs";
3
+ import { dataAttr } from "../internal/data-attr.mjs";
4
+ import { rendersButton, useRender } from "../internal/use-render.mjs";
5
+ import { useDialogContext } from "./dialog-context.mjs";
6
+ import { useCallback, useTransition } from "react";
7
+ //#region src/dialog/dialog-close.tsx
8
+ const isDev = process.env.NODE_ENV !== "production";
9
+ /**
10
+ * A close button: `<button type="button" commandfor command="request-close">`. Without `action`
11
+ * the browser closes the dialog (a close request: `cancel`, then `close`), with `value` as the
12
+ * `returnValue`. With `action` the click is cancelled, the action runs in this part's own
13
+ * transition (`data-pending` on the button) and the dialog closes with `close(value)` once it
14
+ * resolves; a rejection leaves the dialog open.
15
+ *
16
+ * Owned keys (conventions 1.2): `type` (on a `<button>` only), `disabled`, `commandfor`,
17
+ * `command`, `value`, `onClick` (with `action`), `data-pending`, `data-disabled`.
18
+ */
19
+ function DialogClose({ action, value, disabled = false, className, style, children, render, ...rest }) {
20
+ const ctx = useDialogContext("Dialog.Close");
21
+ const [pending, startOwnTransition] = useTransition();
22
+ const { ids, dialogRef, recordCloseIntent } = ctx;
23
+ const hasAction = action !== void 0;
24
+ const state = {
25
+ pending,
26
+ disabled
27
+ };
28
+ const devRef = useCallback((element) => {
29
+ if (isDev && !hasAction && element.tagName !== "BUTTON") console.error(`Dialog.Close: rendered a <${element.tagName.toLowerCase()}> without \`action\`. Only a <button> runs \`command="request-close"\`; this element will not close the dialog.`);
30
+ return () => {};
31
+ }, [hasAction]);
32
+ const onClick = (event) => {
33
+ if (action === void 0) return;
34
+ event.preventDefault();
35
+ if (disabled) return;
36
+ const native = event.nativeEvent;
37
+ const returnValue = value ?? "";
38
+ const details = createActionDetails(native, { returnValue });
39
+ startOwnTransition(async () => {
40
+ await action(details);
41
+ const dialog = dialogRef.current;
42
+ if (dialog === null || !dialog.open) return;
43
+ recordCloseIntent({
44
+ reason: "activate",
45
+ event: native
46
+ });
47
+ dialog.close(returnValue);
48
+ });
49
+ };
50
+ const libraryProps = {
51
+ ...rendersButton(render) && { type: "button" },
52
+ disabled,
53
+ commandfor: ids.dialog,
54
+ command: "request-close",
55
+ value,
56
+ ...hasAction && { onClick },
57
+ "data-pending": dataAttr(pending),
58
+ "data-disabled": dataAttr(disabled)
59
+ };
60
+ return useRender({
61
+ defaultElement: "button",
62
+ render,
63
+ state,
64
+ className,
65
+ style,
66
+ children,
67
+ props: rest,
68
+ libraryProps,
69
+ ref: devRef
70
+ });
71
+ }
72
+ DialogClose.displayName = "DialogClose";
73
+ //#endregion
74
+ export { DialogClose };
75
+
76
+ //# sourceMappingURL=dialog-close.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-close.mjs","names":[],"sources":["../../src/dialog/dialog-close.tsx"],"sourcesContent":["\"use client\";\nimport { useCallback, useTransition } from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, MouseEvent, ReactNode } from \"react\";\nimport { createActionDetails } from \"../internal/action-details.js\";\nimport { dataAttr } from \"../internal/data-attr.js\";\nimport type { Action, ActionDetails, RenderProp, StateValue } from \"../internal/types.js\";\nimport { rendersButton, useRender } from \"../internal/use-render.js\";\nimport type { DataAttributes } from \"../internal/use-render.js\";\nimport { useDialogContext } from \"./dialog-context.js\";\n\nexport interface DialogCloseState {\n /** The `action` is in flight. */\n readonly pending: boolean;\n readonly disabled: boolean;\n}\n\n/** Details passed to `Dialog.Close`'s `action`. */\nexport interface DialogCloseDetails extends ActionDetails {\n /** The `value` the dialog closes with (`dialog.returnValue`); `\"\"` without `value`. */\n readonly returnValue: string;\n}\n\nexport interface DialogCloseProps extends Omit<\n ComponentPropsWithRef<\"button\">,\n \"onClick\" | \"value\" | \"className\" | \"style\" | \"children\"\n> {\n /**\n * Runs inside this part's own transition, then closes the dialog with `close(value)`. A\n * rejection reaches the nearest Error Boundary above the Close part and leaves the dialog open.\n * Without `action` the button is a native `command=\"request-close\"` invoker (JS-free).\n */\n action?: Action<[details: DialogCloseDetails]>;\n /** Becomes `dialog.returnValue` (and `details.returnValue` of the close notification). */\n value?: string;\n disabled?: boolean;\n className?: StateValue<string | undefined, DialogCloseState>;\n style?: StateValue<CSSProperties | undefined, DialogCloseState>;\n children?: StateValue<ReactNode, DialogCloseState>;\n render?: RenderProp<ComponentPropsWithRef<\"button\">, DialogCloseState>;\n}\n\nconst isDev = process.env.NODE_ENV !== \"production\";\n\n/**\n * A close button: `<button type=\"button\" commandfor command=\"request-close\">`. Without `action`\n * the browser closes the dialog (a close request: `cancel`, then `close`), with `value` as the\n * `returnValue`. With `action` the click is cancelled, the action runs in this part's own\n * transition (`data-pending` on the button) and the dialog closes with `close(value)` once it\n * resolves; a rejection leaves the dialog open.\n *\n * Owned keys (conventions 1.2): `type` (on a `<button>` only), `disabled`, `commandfor`,\n * `command`, `value`, `onClick` (with `action`), `data-pending`, `data-disabled`.\n */\nexport function DialogClose({\n action,\n value,\n disabled = false,\n className,\n style,\n children,\n render,\n ...rest\n}: DialogCloseProps) {\n const ctx = useDialogContext(\"Dialog.Close\");\n const [pending, startOwnTransition] = useTransition();\n const { ids, dialogRef, recordCloseIntent } = ctx;\n const hasAction = action !== undefined;\n\n const state: DialogCloseState = { pending, disabled };\n\n const devRef = useCallback(\n (element: HTMLElement) => {\n if (isDev && !hasAction && element.tagName !== \"BUTTON\") {\n console.error(\n `Dialog.Close: rendered a <${element.tagName.toLowerCase()}> without \\`action\\`. Only a ` +\n '<button> runs `command=\"request-close\"`; this element will not close the dialog.',\n );\n }\n // A cleanup, so the merged ref never calls back with `null`.\n return () => {};\n },\n [hasAction],\n );\n\n const onClick = (event: MouseEvent<HTMLElement>) => {\n if (action === undefined) return;\n // Cancelling the click cancels the command.\n event.preventDefault();\n if (disabled) return;\n const native = event.nativeEvent;\n const returnValue = value ?? \"\";\n const details = createActionDetails(native, { returnValue });\n startOwnTransition(async () => {\n await action(details);\n // Repeated clicks re-run the action; the first `close()` wins (design 3.4).\n const dialog = dialogRef.current;\n if (dialog === null || !dialog.open) return;\n recordCloseIntent({ reason: \"activate\", event: native });\n dialog.close(returnValue);\n });\n };\n\n const libraryProps: ComponentPropsWithRef<\"button\"> & DataAttributes = {\n ...(rendersButton(render) && { type: \"button\" as const }),\n // Owned: a render element must not re-enable a disabled Close.\n disabled,\n commandfor: ids.dialog,\n command: \"request-close\",\n value,\n ...(hasAction && { onClick }),\n \"data-pending\": dataAttr(pending),\n \"data-disabled\": dataAttr(disabled),\n };\n\n return useRender<ComponentPropsWithRef<\"button\">, DialogCloseState>({\n defaultElement: \"button\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n libraryProps,\n ref: devRef,\n });\n}\n\nDialogClose.displayName = \"DialogClose\";\n"],"mappings":";;;;;;;AAyCA,MAAM,QAAQ,QAAQ,IAAI,aAAa;;;;;;;;;;;AAYvC,SAAgB,YAAY,EAC1B,QACA,OACA,WAAW,OACX,WACA,OACA,UACA,QACA,GAAG,QACgB;CACnB,MAAM,MAAM,iBAAiB,cAAc;CAC3C,MAAM,CAAC,SAAS,sBAAsB,cAAc;CACpD,MAAM,EAAE,KAAK,WAAW,sBAAsB;CAC9C,MAAM,YAAY,WAAW,KAAA;CAE7B,MAAM,QAA0B;EAAE;EAAS;CAAS;CAEpD,MAAM,SAAS,aACZ,YAAyB;EACxB,IAAI,SAAS,CAAC,aAAa,QAAQ,YAAY,UAC7C,QAAQ,MACN,6BAA6B,QAAQ,QAAQ,YAAY,EAAE,gHAE7D;EAGF,aAAa,CAAC;CAChB,GACA,CAAC,SAAS,CACZ;CAEA,MAAM,WAAW,UAAmC;EAClD,IAAI,WAAW,KAAA,GAAW;EAE1B,MAAM,eAAe;EACrB,IAAI,UAAU;EACd,MAAM,SAAS,MAAM;EACrB,MAAM,cAAc,SAAS;EAC7B,MAAM,UAAU,oBAAoB,QAAQ,EAAE,YAAY,CAAC;EAC3D,mBAAmB,YAAY;GAC7B,MAAM,OAAO,OAAO;GAEpB,MAAM,SAAS,UAAU;GACzB,IAAI,WAAW,QAAQ,CAAC,OAAO,MAAM;GACrC,kBAAkB;IAAE,QAAQ;IAAY,OAAO;GAAO,CAAC;GACvD,OAAO,MAAM,WAAW;EAC1B,CAAC;CACH;CAEA,MAAM,eAAiE;EACrE,GAAI,cAAc,MAAM,KAAK,EAAE,MAAM,SAAkB;EAEvD;EACA,YAAY,IAAI;EAChB,SAAS;EACT;EACA,GAAI,aAAa,EAAE,QAAQ;EAC3B,gBAAgB,SAAS,OAAO;EAChC,iBAAiB,SAAS,QAAQ;CACpC;CAEA,OAAO,UAA6D;EAClE,gBAAgB;EAChB;EACA;EACA;EACA;EACA;EACA,OAAO;EACP;EACA,KAAK;CACP,CAAC;AACH;AAEA,YAAY,cAAc"}
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { createContext, use } from "react";
3
+ //#region src/dialog/dialog-context.ts
4
+ const DialogContext = createContext(null);
5
+ function useDialogContext(part) {
6
+ const context = use(DialogContext);
7
+ if (context === null) throw new Error(`${part} must be rendered inside a Dialog.Root.`);
8
+ return context;
9
+ }
10
+ //#endregion
11
+ export { DialogContext, useDialogContext };
12
+
13
+ //# sourceMappingURL=dialog-context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-context.mjs","names":[],"sources":["../../src/dialog/dialog-context.ts"],"sourcesContent":["\"use client\";\nimport { createContext, use } from \"react\";\nimport type { RefObject } from \"react\";\nimport type { ChangeReason } from \"../internal/types.js\";\n\n/**\n * \"static\": JS-free mode, the browser owns open and close through Invoker Commands. \"library\":\n * open is library-owned (a transition keyed on committed state), close is browser-owned and\n * notified (design section 2).\n */\nexport type DialogMode = \"static\" | \"library\";\n\n/**\n * What caused the next `close` event, recorded just before the close happens (design 2.3). The\n * `close` event carries no source; without an intent the close is a `\"dismiss\"`.\n */\nexport interface DialogCloseIntent {\n readonly reason: ChangeReason;\n readonly event: Event | undefined;\n}\n\nexport interface DialogContextValue {\n readonly mode: DialogMode;\n /** `useId`-based ids: the `<dialog>`, its Title and its Description. */\n readonly ids: { readonly dialog: string; readonly title: string; readonly description: string };\n readonly modal: boolean;\n /** Committed open state (library mode); `false` in static mode. */\n readonly committed: boolean;\n /** Optimistic open state (library mode); `false` in static mode. */\n readonly optimistic: boolean;\n /** The Root's transition is pending (library mode). */\n readonly pending: boolean;\n /**\n * Open the dialog through the Root's transition (library mode): a Trigger click, a foreign\n * `show-modal` command, or mount reconciliation. A no-op when the user already intends `true`.\n */\n readonly requestOpen: (event: Event | undefined, reason: ChangeReason) => void;\n /**\n * The dialog closed natively: dispatch the `false` notification unless the user (or the\n * library's own echo) already intends `false`.\n */\n readonly notifyClosed: (event: Event, reason: ChangeReason, returnValue: string) => void;\n /** From `useControllableAction`: the latest in-flight intent, or `null`. */\n readonly latestInFlight: () => { readonly next: boolean } | null;\n /** The registered Trigger element, for the focus-return fallback (design 6.2). */\n readonly triggerRef: RefObject<HTMLElement | null>;\n /** The `<dialog>`, set by the Popup's ref; how Close and Form reach `close(value)`. */\n readonly dialogRef: RefObject<HTMLDialogElement | null>;\n /** Record what causes the next close. Cleared after a task if the dialog did not close. */\n readonly recordCloseIntent: (intent: DialogCloseIntent | undefined) => void;\n /** Read and clear the recorded intent (the Popup's `close` listener). */\n readonly takeCloseIntent: () => DialogCloseIntent | undefined;\n}\n\nexport const DialogContext = createContext<DialogContextValue | null>(null);\n\nexport function useDialogContext(part: string): DialogContextValue {\n const context = use(DialogContext);\n if (context === null) {\n throw new Error(`${part} must be rendered inside a Dialog.Root.`);\n }\n return context;\n}\n"],"mappings":";;;AAsDA,MAAa,gBAAgB,cAAyC,IAAI;AAE1E,SAAgB,iBAAiB,MAAkC;CACjE,MAAM,UAAU,IAAI,aAAa;CACjC,IAAI,YAAY,MACd,MAAM,IAAI,MAAM,GAAG,KAAK,wCAAwC;CAElE,OAAO;AACT"}
@@ -0,0 +1,22 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { DialogPopupState } from "./dialog-popup.mjs";
3
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
4
+ //#region src/dialog/dialog-description.d.ts
5
+ export type DialogDescriptionState = DialogPopupState;
6
+ export interface DialogDescriptionProps extends Omit<ComponentPropsWithRef<"p">, "id" | "className" | "style" | "children"> {
7
+ className?: StateValue<string | undefined, DialogDescriptionState>;
8
+ style?: StateValue<CSSProperties | undefined, DialogDescriptionState>;
9
+ children?: StateValue<ReactNode, DialogDescriptionState>;
10
+ render?: RenderProp<ComponentPropsWithRef<"p">, DialogDescriptionState>;
11
+ }
12
+ /**
13
+ * The dialog's description: a `<p>` whose id the Popup references with `aria-describedby`.
14
+ *
15
+ * Owned key (conventions 1.2): `id`.
16
+ */
17
+ export declare function DialogDescription({ className, style, children, render, ...rest }: DialogDescriptionProps): ReactNode;
18
+ export declare namespace DialogDescription {
19
+ var displayName: string;
20
+ }
21
+ //#endregion
22
+ //# sourceMappingURL=dialog-description.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-description.d.mts","names":[],"sources":["../../src/dialog/dialog-description.tsx"],"mappings":";;;;YAOY,yBAAyB;iBAEpB,+BAA+B,KAC9C;EAGA,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,4BAA4B;;;;;;;wBAQlC,oBACd,WACA,OACA,UACA,WACG,QACF,yBAAsB;yBANT"}
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { useRender } from "../internal/use-render.mjs";
3
+ import { useDialogContext } from "./dialog-context.mjs";
4
+ //#region src/dialog/dialog-description.tsx
5
+ /**
6
+ * The dialog's description: a `<p>` whose id the Popup references with `aria-describedby`.
7
+ *
8
+ * Owned key (conventions 1.2): `id`.
9
+ */
10
+ function DialogDescription({ className, style, children, render, ...rest }) {
11
+ const ctx = useDialogContext("Dialog.Description");
12
+ const state = {
13
+ open: ctx.committed,
14
+ modal: ctx.modal
15
+ };
16
+ return useRender({
17
+ defaultElement: "p",
18
+ render,
19
+ state,
20
+ className,
21
+ style,
22
+ children,
23
+ props: rest,
24
+ libraryProps: { id: ctx.ids.description }
25
+ });
26
+ }
27
+ DialogDescription.displayName = "DialogDescription";
28
+ //#endregion
29
+ export { DialogDescription };
30
+
31
+ //# sourceMappingURL=dialog-description.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-description.mjs","names":[],"sources":["../../src/dialog/dialog-description.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 { useDialogContext } from \"./dialog-context.js\";\nimport type { DialogPopupState } from \"./dialog-popup.js\";\n\nexport type DialogDescriptionState = DialogPopupState;\n\nexport interface DialogDescriptionProps extends Omit<\n ComponentPropsWithRef<\"p\">,\n \"id\" | \"className\" | \"style\" | \"children\"\n> {\n className?: StateValue<string | undefined, DialogDescriptionState>;\n style?: StateValue<CSSProperties | undefined, DialogDescriptionState>;\n children?: StateValue<ReactNode, DialogDescriptionState>;\n render?: RenderProp<ComponentPropsWithRef<\"p\">, DialogDescriptionState>;\n}\n\n/**\n * The dialog's description: a `<p>` whose id the Popup references with `aria-describedby`.\n *\n * Owned key (conventions 1.2): `id`.\n */\nexport function DialogDescription({\n className,\n style,\n children,\n render,\n ...rest\n}: DialogDescriptionProps) {\n const ctx = useDialogContext(\"Dialog.Description\");\n const state: DialogDescriptionState = { open: ctx.committed, modal: ctx.modal };\n return useRender<ComponentPropsWithRef<\"p\">, DialogDescriptionState>({\n defaultElement: \"p\",\n render,\n state,\n className,\n style,\n children,\n props: rest,\n libraryProps: { id: ctx.ids.description },\n });\n}\n\nDialogDescription.displayName = \"DialogDescription\";\n"],"mappings":";;;;;;;;;AAwBA,SAAgB,kBAAkB,EAChC,WACA,OACA,UACA,QACA,GAAG,QACsB;CACzB,MAAM,MAAM,iBAAiB,oBAAoB;CACjD,MAAM,QAAgC;EAAE,MAAM,IAAI;EAAW,OAAO,IAAI;CAAM;CAC9E,OAAO,UAA8D;EACnE,gBAAgB;EAChB;EACA;EACA;EACA;EACA;EACA,OAAO;EACP,cAAc,EAAE,IAAI,IAAI,IAAI,YAAY;CAC1C,CAAC;AACH;AAEA,kBAAkB,cAAc"}
@@ -0,0 +1,58 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ReactNode } from "react";
3
+ //#region src/dialog/dialog-form.d.ts
4
+ export interface DialogFormState {
5
+ /** `useFormStatus().pending` of this form, exposed for `className` / `children` functions. */
6
+ readonly pending: boolean;
7
+ }
8
+ export interface DialogFormProps extends Omit<ComponentPropsWithRef<"form">, "method" | "action" | "className" | "style" | "children"> {
9
+ /**
10
+ * React form action (`(formData) => unknown`, may be a Server Function). Passed to the form
11
+ * unwrapped so React's progressive enhancement is kept; the dialog closes with the submitter's
12
+ * `value` as `returnValue` once the action's transition settles (see `closeOnSettle`). A
13
+ * rejection leaves the dialog open. Without `action` the form renders `method="dialog"`:
14
+ * submitting closes the dialog natively. A string `action` (a URL) is a plain navigating form.
15
+ */
16
+ action?: string | ((formData: FormData) => unknown);
17
+ /**
18
+ * With a function `action`: close the dialog once the action's transition settles without
19
+ * throwing. Default `true`.
20
+ *
21
+ * Any result that does not throw counts as success, including a `useActionState`-style result
22
+ * that reports validation errors: with the default the dialog closes and those errors are never
23
+ * seen. Throw to keep the dialog open, or set `closeOnSettle={false}` and close it yourself:
24
+ * a `Dialog.Close`, a submitter with `formMethod="dialog"`, or a controlled `open`.
25
+ *
26
+ * The dialog is not closed either when it was closed (Escape, a Close part) while the action
27
+ * ran, also if the user re-opened it meanwhile.
28
+ */
29
+ closeOnSettle?: boolean;
30
+ /**
31
+ * Only with a string `action` (a navigating form, for example `"post"`). Owned otherwise:
32
+ * `"dialog"` without `action`, React's own with a function `action`.
33
+ */
34
+ method?: ComponentPropsWithRef<"form">["method"];
35
+ className?: StateValue<string | undefined, DialogFormState>;
36
+ style?: StateValue<CSSProperties | undefined, DialogFormState>;
37
+ children?: StateValue<ReactNode, DialogFormState>;
38
+ render?: RenderProp<ComponentPropsWithRef<"form">, DialogFormState>;
39
+ }
40
+ /**
41
+ * A form that completes the dialog. Without `action`: `<form method="dialog">`, so a submit
42
+ * closes the dialog natively (JS-free) with the submitter's `value` as `returnValue`. With a
43
+ * function `action`: `<form action={action}>` (React overrides the method) and a status watcher
44
+ * that closes the dialog once the action has settled, with the submitter's `value`, unless
45
+ * `closeOnSettle` is `false` or the dialog was closed while the action ran.
46
+ *
47
+ * `DialogFormState.pending` is this form's own status; it is not emitted as `data-pending` and
48
+ * is not folded into any control's `pending` (conventions 2.7). Submit buttons read
49
+ * `useFormStatus()` themselves.
50
+ *
51
+ * Owned keys (conventions 1.2): `method` (except with a string `action`), `action`.
52
+ */
53
+ export declare function DialogForm({ action, closeOnSettle, method, className, style, children, render, ...rest }: DialogFormProps): ReactNode;
54
+ export declare namespace DialogForm {
55
+ var displayName: string;
56
+ }
57
+ //#endregion
58
+ //# sourceMappingURL=dialog-form.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-form.d.mts","names":[],"sources":["../../src/dialog/dialog-form.tsx"],"mappings":";;;iBAQiB;;WAEN;;iBAGM,wBAAwB,KACvC;;;;;;;;EAUA,oBAAoB,UAAU;;;;;;;;;;;;;EAa9B;;;;;EAKA,SAAS;EACT,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;EACjC,SAAS,WAAW,+BAA+B;;;;;;;;;;;;;;;wBAwCrC,aACd,QACA,eACA,QACA,WACA,OACA,UACA,WACG,QACF,kBAAe;yBATF"}
@@ -0,0 +1,108 @@
1
+ "use client";
2
+ import { resolveStateValue, useRender } from "../internal/use-render.mjs";
3
+ import { useDialogContext } from "./dialog-context.mjs";
4
+ import { useCallback, useEffect, useRef, useState } from "react";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { useFormStatus } from "react-dom";
7
+ //#region src/dialog/dialog-form.tsx
8
+ /**
9
+ * Observes React's form channel (design 8.1): `useFormStatus().pending` covers the action's
10
+ * whole transition, including the Suspense wait of what it re-renders. On `true → false` the
11
+ * submission succeeded (a rejection unmounts the form through the nearest Error Boundary, so the
12
+ * edge is never seen).
13
+ */
14
+ function FormStatusWatcher({ onPendingChange, onSettled }) {
15
+ const { pending } = useFormStatus();
16
+ const previous = useRef(false);
17
+ useEffect(() => {
18
+ const was = previous.current;
19
+ previous.current = pending;
20
+ if (was === pending) return;
21
+ onPendingChange(pending);
22
+ if (was && !pending) onSettled();
23
+ }, [
24
+ pending,
25
+ onPendingChange,
26
+ onSettled
27
+ ]);
28
+ return null;
29
+ }
30
+ /**
31
+ * A form that completes the dialog. Without `action`: `<form method="dialog">`, so a submit
32
+ * closes the dialog natively (JS-free) with the submitter's `value` as `returnValue`. With a
33
+ * function `action`: `<form action={action}>` (React overrides the method) and a status watcher
34
+ * that closes the dialog once the action has settled, with the submitter's `value`, unless
35
+ * `closeOnSettle` is `false` or the dialog was closed while the action ran.
36
+ *
37
+ * `DialogFormState.pending` is this form's own status; it is not emitted as `data-pending` and
38
+ * is not folded into any control's `pending` (conventions 2.7). Submit buttons read
39
+ * `useFormStatus()` themselves.
40
+ *
41
+ * Owned keys (conventions 1.2): `method` (except with a string `action`), `action`.
42
+ */
43
+ function DialogForm({ action, closeOnSettle = true, method, className, style, children, render, ...rest }) {
44
+ const { dialogRef, recordCloseIntent } = useDialogContext("Dialog.Form");
45
+ const [pending, setPending] = useState(false);
46
+ const submission = useRef(null);
47
+ const closedSinceSubmit = useRef(false);
48
+ const watches = typeof action === "function";
49
+ const libraryRef = useCallback((form) => {
50
+ const onSubmit = (event) => {
51
+ if (event.target !== form) return;
52
+ const submitter = event.submitter;
53
+ submission.current = {
54
+ event,
55
+ returnValue: submitter?.value ?? ""
56
+ };
57
+ closedSinceSubmit.current = false;
58
+ };
59
+ const dialog = form.closest("dialog");
60
+ const onClose = (event) => {
61
+ if (event.target === dialog) closedSinceSubmit.current = true;
62
+ };
63
+ form.addEventListener("submit", onSubmit, true);
64
+ dialog?.addEventListener("close", onClose);
65
+ return () => {
66
+ form.removeEventListener("submit", onSubmit, true);
67
+ dialog?.removeEventListener("close", onClose);
68
+ };
69
+ }, []);
70
+ const onSettled = useCallback(() => {
71
+ const dialog = dialogRef.current;
72
+ const submitted = submission.current;
73
+ submission.current = null;
74
+ if (!closeOnSettle || closedSinceSubmit.current) return;
75
+ if (dialog === null || !dialog.open) return;
76
+ recordCloseIntent({
77
+ reason: "activate",
78
+ event: submitted?.event
79
+ });
80
+ dialog.close(submitted?.returnValue ?? "");
81
+ }, [
82
+ closeOnSettle,
83
+ dialogRef,
84
+ recordCloseIntent
85
+ ]);
86
+ return useRender({
87
+ defaultElement: "form",
88
+ render,
89
+ state: { pending },
90
+ className,
91
+ style,
92
+ children: (s) => /* @__PURE__ */ jsxs(Fragment, { children: [resolveStateValue(children, s), watches && /* @__PURE__ */ jsx(FormStatusWatcher, {
93
+ onPendingChange: setPending,
94
+ onSettled
95
+ })] }),
96
+ props: rest,
97
+ libraryProps: {
98
+ method: action === void 0 ? "dialog" : typeof action === "string" ? method : void 0,
99
+ action
100
+ },
101
+ ref: libraryRef
102
+ });
103
+ }
104
+ DialogForm.displayName = "DialogForm";
105
+ //#endregion
106
+ export { DialogForm };
107
+
108
+ //# sourceMappingURL=dialog-form.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-form.mjs","names":[],"sources":["../../src/dialog/dialog-form.tsx"],"sourcesContent":["\"use client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ComponentPropsWithRef, CSSProperties, ReactNode } from \"react\";\nimport { useFormStatus } from \"react-dom\";\nimport type { RenderProp, StateValue } from \"../internal/types.js\";\nimport { resolveStateValue, useRender } from \"../internal/use-render.js\";\nimport { useDialogContext } from \"./dialog-context.js\";\n\nexport interface DialogFormState {\n /** `useFormStatus().pending` of this form, exposed for `className` / `children` functions. */\n readonly pending: boolean;\n}\n\nexport interface DialogFormProps extends Omit<\n ComponentPropsWithRef<\"form\">,\n \"method\" | \"action\" | \"className\" | \"style\" | \"children\"\n> {\n /**\n * React form action (`(formData) => unknown`, may be a Server Function). Passed to the form\n * unwrapped so React's progressive enhancement is kept; the dialog closes with the submitter's\n * `value` as `returnValue` once the action's transition settles (see `closeOnSettle`). A\n * rejection leaves the dialog open. Without `action` the form renders `method=\"dialog\"`:\n * submitting closes the dialog natively. A string `action` (a URL) is a plain navigating form.\n */\n action?: string | ((formData: FormData) => unknown);\n /**\n * With a function `action`: close the dialog once the action's transition settles without\n * throwing. Default `true`.\n *\n * Any result that does not throw counts as success, including a `useActionState`-style result\n * that reports validation errors: with the default the dialog closes and those errors are never\n * seen. Throw to keep the dialog open, or set `closeOnSettle={false}` and close it yourself:\n * a `Dialog.Close`, a submitter with `formMethod=\"dialog\"`, or a controlled `open`.\n *\n * The dialog is not closed either when it was closed (Escape, a Close part) while the action\n * ran, also if the user re-opened it meanwhile.\n */\n closeOnSettle?: boolean;\n /**\n * Only with a string `action` (a navigating form, for example `\"post\"`). Owned otherwise:\n * `\"dialog\"` without `action`, React's own with a function `action`.\n */\n method?: ComponentPropsWithRef<\"form\">[\"method\"];\n className?: StateValue<string | undefined, DialogFormState>;\n style?: StateValue<CSSProperties | undefined, DialogFormState>;\n children?: StateValue<ReactNode, DialogFormState>;\n render?: RenderProp<ComponentPropsWithRef<\"form\">, DialogFormState>;\n}\n\ninterface FormStatusWatcherProps {\n readonly onPendingChange: (pending: boolean) => void;\n readonly onSettled: () => void;\n}\n\n/**\n * Observes React's form channel (design 8.1): `useFormStatus().pending` covers the action's\n * whole transition, including the Suspense wait of what it re-renders. On `true → false` the\n * submission succeeded (a rejection unmounts the form through the nearest Error Boundary, so the\n * edge is never seen).\n */\nfunction FormStatusWatcher({ onPendingChange, onSettled }: FormStatusWatcherProps) {\n const { pending } = useFormStatus();\n const previous = useRef(false);\n useEffect(() => {\n const was = previous.current;\n previous.current = pending;\n if (was === pending) return;\n onPendingChange(pending);\n if (was && !pending) onSettled();\n }, [pending, onPendingChange, onSettled]);\n return null;\n}\n\n/**\n * A form that completes the dialog. Without `action`: `<form method=\"dialog\">`, so a submit\n * closes the dialog natively (JS-free) with the submitter's `value` as `returnValue`. With a\n * function `action`: `<form action={action}>` (React overrides the method) and a status watcher\n * that closes the dialog once the action has settled, with the submitter's `value`, unless\n * `closeOnSettle` is `false` or the dialog was closed while the action ran.\n *\n * `DialogFormState.pending` is this form's own status; it is not emitted as `data-pending` and\n * is not folded into any control's `pending` (conventions 2.7). Submit buttons read\n * `useFormStatus()` themselves.\n *\n * Owned keys (conventions 1.2): `method` (except with a string `action`), `action`.\n */\nexport function DialogForm({\n action,\n closeOnSettle = true,\n method,\n className,\n style,\n children,\n render,\n ...rest\n}: DialogFormProps) {\n const ctx = useDialogContext(\"Dialog.Form\");\n const { dialogRef, recordCloseIntent } = ctx;\n const [pending, setPending] = useState(false);\n const submission = useRef<{ event: Event; returnValue: string } | null>(null);\n // The dialog closed after the last submit (Escape, a Close part): the settle must not close it\n // again, also when the user re-opened it meanwhile (the review's walkthrough 11.8 variant).\n const closedSinceSubmit = useRef(false);\n const watches = typeof action === \"function\";\n\n // The submitter's `value` comes from the native `submit` event (capture, before React's\n // handler runs the action).\n const libraryRef = useCallback((form: HTMLFormElement) => {\n const onSubmit = (event: Event) => {\n if (event.target !== form) return;\n const submitter = (event as SubmitEvent).submitter as\n | HTMLButtonElement\n | HTMLInputElement\n | null;\n submission.current = { event, returnValue: submitter?.value ?? \"\" };\n closedSinceSubmit.current = false;\n };\n const dialog = form.closest(\"dialog\");\n const onClose = (event: Event) => {\n if (event.target === dialog) closedSinceSubmit.current = true;\n };\n form.addEventListener(\"submit\", onSubmit, true);\n dialog?.addEventListener(\"close\", onClose);\n return () => {\n form.removeEventListener(\"submit\", onSubmit, true);\n dialog?.removeEventListener(\"close\", onClose);\n };\n }, []);\n\n const onSettled = useCallback(() => {\n const dialog = dialogRef.current;\n const submitted = submission.current;\n submission.current = null;\n if (!closeOnSettle || closedSinceSubmit.current) return;\n if (dialog === null || !dialog.open) return;\n recordCloseIntent({ reason: \"activate\", event: submitted?.event });\n dialog.close(submitted?.returnValue ?? \"\");\n }, [closeOnSettle, dialogRef, recordCloseIntent]);\n\n const state: DialogFormState = { pending };\n\n return useRender<ComponentPropsWithRef<\"form\">, DialogFormState>({\n defaultElement: \"form\",\n render,\n state,\n className,\n style,\n children: (s) => (\n <>\n {resolveStateValue(children, s)}\n {watches && <FormStatusWatcher onPendingChange={setPending} onSettled={onSettled} />}\n </>\n ),\n props: rest,\n libraryProps: {\n method: action === undefined ? \"dialog\" : typeof action === \"string\" ? method : undefined,\n // React's own type wants `void | Promise<void>`; the library's actions return `unknown`\n // (conventions 2.2) and React ignores the result.\n action: action as ComponentPropsWithRef<\"form\">[\"action\"],\n },\n ref: libraryRef,\n });\n}\n\nDialogForm.displayName = \"DialogForm\";\n"],"mappings":";;;;;;;;;;;;;AA4DA,SAAS,kBAAkB,EAAE,iBAAiB,aAAqC;CACjF,MAAM,EAAE,YAAY,cAAc;CAClC,MAAM,WAAW,OAAO,KAAK;CAC7B,gBAAgB;EACd,MAAM,MAAM,SAAS;EACrB,SAAS,UAAU;EACnB,IAAI,QAAQ,SAAS;EACrB,gBAAgB,OAAO;EACvB,IAAI,OAAO,CAAC,SAAS,UAAU;CACjC,GAAG;EAAC;EAAS;EAAiB;CAAS,CAAC;CACxC,OAAO;AACT;;;;;;;;;;;;;;AAeA,SAAgB,WAAW,EACzB,QACA,gBAAgB,MAChB,QACA,WACA,OACA,UACA,QACA,GAAG,QACe;CAElB,MAAM,EAAE,WAAW,sBADP,iBAAiB,aACc;CAC3C,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAC5C,MAAM,aAAa,OAAqD,IAAI;CAG5E,MAAM,oBAAoB,OAAO,KAAK;CACtC,MAAM,UAAU,OAAO,WAAW;CAIlC,MAAM,aAAa,aAAa,SAA0B;EACxD,MAAM,YAAY,UAAiB;GACjC,IAAI,MAAM,WAAW,MAAM;GAC3B,MAAM,YAAa,MAAsB;GAIzC,WAAW,UAAU;IAAE;IAAO,aAAa,WAAW,SAAS;GAAG;GAClE,kBAAkB,UAAU;EAC9B;EACA,MAAM,SAAS,KAAK,QAAQ,QAAQ;EACpC,MAAM,WAAW,UAAiB;GAChC,IAAI,MAAM,WAAW,QAAQ,kBAAkB,UAAU;EAC3D;EACA,KAAK,iBAAiB,UAAU,UAAU,IAAI;EAC9C,QAAQ,iBAAiB,SAAS,OAAO;EACzC,aAAa;GACX,KAAK,oBAAoB,UAAU,UAAU,IAAI;GACjD,QAAQ,oBAAoB,SAAS,OAAO;EAC9C;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,YAAY,kBAAkB;EAClC,MAAM,SAAS,UAAU;EACzB,MAAM,YAAY,WAAW;EAC7B,WAAW,UAAU;EACrB,IAAI,CAAC,iBAAiB,kBAAkB,SAAS;EACjD,IAAI,WAAW,QAAQ,CAAC,OAAO,MAAM;EACrC,kBAAkB;GAAE,QAAQ;GAAY,OAAO,WAAW;EAAM,CAAC;EACjE,OAAO,MAAM,WAAW,eAAe,EAAE;CAC3C,GAAG;EAAC;EAAe;EAAW;CAAiB,CAAC;CAIhD,OAAO,UAA0D;EAC/D,gBAAgB;EAChB;EACA,OAAA,EAL+B,QAK3B;EACJ;EACA;EACA,WAAW,MACT,qBAAA,UAAA,EAAA,UAAA,CACG,kBAAkB,UAAU,CAAC,GAC7B,WAAW,oBAAC,mBAAD;GAAmB,iBAAiB;GAAuB;EAAY,CAAA,CACnF,EAAA,CAAA;EAEJ,OAAO;EACP,cAAc;GACZ,QAAQ,WAAW,KAAA,IAAY,WAAW,OAAO,WAAW,WAAW,SAAS,KAAA;GAGxE;EACV;EACA,KAAK;CACP,CAAC;AACH;AAEA,WAAW,cAAc"}
@@ -0,0 +1,81 @@
1
+ import { RenderProp, StateValue } from "../internal/types.mjs";
2
+ import { CSSProperties, ComponentPropsWithRef, ReactNode, RefObject, ViewTransitionClass } from "react";
3
+ //#region src/dialog/dialog-popup.d.ts
4
+ export interface DialogPopupState {
5
+ /** Committed open state (library mode); `false` in JS-free mode. Read `:open` for the DOM truth. */
6
+ readonly open: boolean;
7
+ readonly modal: boolean;
8
+ }
9
+ export interface DialogPopupProps extends Omit<ComponentPropsWithRef<"dialog">, "id" | "open" | "closedby" | "onToggle" | "onBeforeToggle" | "className" | "style" | "children"> {
10
+ /**
11
+ * Library mode: what happens to the children while the dialog is closed.
12
+ * - `false` (default): not rendered. Mounting them is part of the opening transition, so
13
+ * content that suspends holds the open until it is ready. Unmount waits for the dialog's
14
+ * exit animations.
15
+ * - `true`: rendered inside `<Activity mode="hidden">`: DOM and state preserved, effects
16
+ * stopped, pre-rendered at low priority. Not in the server HTML.
17
+ *
18
+ * Ignored in JS-free mode (always mounted).
19
+ */
20
+ keepMounted?: boolean;
21
+ /**
22
+ * Element to focus when the dialog opens: a ref, or a selector resolved inside the dialog.
23
+ * The library writes `autofocus` on it right before `showModal()` / `show()` and the platform
24
+ * focuses it. Default: the platform's choice (first focusable descendant; the dialog itself if
25
+ * none). Use `tabIndex={-1}` on a heading or wrapper for long or destructive dialogs (APG).
26
+ *
27
+ * In JS-free mode the browser opens the dialog itself, so the attribute is written after
28
+ * hydration and kept while mounted; before hydration only `autoFocus` in the markup works.
29
+ */
30
+ initialFocus?: RefObject<HTMLElement | null> | string;
31
+ /**
32
+ * Close on a click outside the dialog (on the backdrop for modal dialogs). Default `false`.
33
+ * Baseline: JS `pointerdown` + `click` listeners, which close only when both the press and the
34
+ * click land outside (a drag that starts inside, such as selecting text, never closes); with
35
+ * `experimental_closedBy`, native `closedby="any"`, which behaves the same.
36
+ */
37
+ lightDismiss?: boolean;
38
+ /**
39
+ * Experimental (Chrome 134+, Firefox 141+; Safari 27.0 ignores it). Renders `closedby`
40
+ * (`"any"` when `lightDismiss`, else `"closerequest"`) and skips the JS dismiss listeners where
41
+ * `HTMLDialogElement.prototype.closedBy` exists. Elsewhere the JS baseline stays active.
42
+ * Default `false`.
43
+ */
44
+ experimental_closedBy?: boolean;
45
+ /**
46
+ * Library mode only. Forwarded to the `<ViewTransition default>` around the dialog. Animates
47
+ * the opening commit and content changes while open; the close is the browser's and animates
48
+ * with CSS. Ignored (dev warning) in JS-free mode.
49
+ *
50
+ * Static: without `transition` the part renders no `<ViewTransition>`; changing it between
51
+ * `undefined` and a value remounts the element. Any value, `"none"` included, makes a mount or
52
+ * `<Activity>` reveal of this part inside a transition start a document view transition: the
53
+ * page cross-fades for about 250 ms and the next transition commit waits for it (issue #35).
54
+ */
55
+ transition?: ViewTransitionClass;
56
+ className?: StateValue<string | undefined, DialogPopupState>;
57
+ style?: StateValue<CSSProperties | undefined, DialogPopupState>;
58
+ children?: StateValue<ReactNode, DialogPopupState>;
59
+ /** Must render a `<dialog>`. */
60
+ render?: RenderProp<ComponentPropsWithRef<"dialog">, DialogPopupState>;
61
+ }
62
+ /**
63
+ * The dialog itself: a `<dialog>` with the id the Trigger's `commandfor` names, wired to Title
64
+ * and Description through `aria-labelledby` / `aria-describedby`. Never renders `open`: modal
65
+ * opening and closing go through `showModal()` / `close()` only. Style it with `:open` and
66
+ * `:modal`; it emits `data-modal` but no `data-open`.
67
+ *
68
+ * In library mode the children render from committed state, so content that suspends keeps the
69
+ * dialog closed (and the Trigger pending) until it is ready; `showModal()` runs in the layout
70
+ * effect of the commit that mounted them. Closing is the browser's: the native `close` event
71
+ * becomes `openChangeAction(false, { reason, returnValue })`.
72
+ *
73
+ * Owned keys (conventions 1.2): `id`, `open`, `closedby`, `aria-labelledby` and
74
+ * `aria-describedby` (token-merged), `data-modal`, `suppressHydrationWarning`.
75
+ */
76
+ export declare function DialogPopup({ keepMounted, initialFocus, lightDismiss, experimental_closedBy, transition, className, style, children, render, ...rest }: DialogPopupProps): ReactNode;
77
+ export declare namespace DialogPopup {
78
+ var displayName: string;
79
+ }
80
+ //#endregion
81
+ //# sourceMappingURL=dialog-popup.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-popup.d.mts","names":[],"sources":["../../src/dialog/dialog-popup.tsx"],"mappings":";;;iBA0BiB;;WAEN;WACA;;iBAGM,yBAAyB,KACxC;;;;;;;;;;;EAaA;;;;;;;;;;EAUA,eAAe,UAAU;;;;;;;EAOzB;;;;;;;EAOA;;;;;;;;;;;EAWA,aAAa;EACb,YAAY,+BAA+B;EAC3C,QAAQ,WAAW,2BAA2B;EAC9C,WAAW,WAAW,WAAW;;EAEjC,SAAS,WAAW,iCAAiC;;;;;;;;;;;;;;;;wBA2FvC,cACd,aACA,cACA,cACA,uBACA,YACA,WACA,OACA,UACA,WACG,QACF,mBAAgB;yBAXH"}