aeon-ui-engine 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/CONSUMER.md +86 -0
  3. package/INTEGRATION.md +2 -0
  4. package/README.md +15 -4
  5. package/package.json +17 -1
  6. package/packages/core/dist/index.d.ts +257 -0
  7. package/packages/core/dist/index.js +378 -0
  8. package/packages/core/node_modules/.bin/esbuild +21 -0
  9. package/packages/core/node_modules/.bin/jiti +21 -0
  10. package/packages/core/node_modules/.bin/tsc +21 -0
  11. package/packages/core/node_modules/.bin/tsserver +21 -0
  12. package/packages/core/node_modules/.bin/tsup +21 -0
  13. package/packages/core/node_modules/.bin/tsup-node +21 -0
  14. package/packages/core/node_modules/.bin/tsx +21 -0
  15. package/packages/core/node_modules/.bin/vite +21 -0
  16. package/packages/core/node_modules/.bin/vitest +21 -0
  17. package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  18. package/packages/geometry/dist/index.d.ts +50 -0
  19. package/packages/geometry/dist/index.js +88 -0
  20. package/packages/geometry/node_modules/.bin/esbuild +21 -0
  21. package/packages/geometry/node_modules/.bin/jiti +21 -0
  22. package/packages/geometry/node_modules/.bin/tsc +21 -0
  23. package/packages/geometry/node_modules/.bin/tsserver +21 -0
  24. package/packages/geometry/node_modules/.bin/tsup +21 -0
  25. package/packages/geometry/node_modules/.bin/tsup-node +21 -0
  26. package/packages/geometry/node_modules/.bin/tsx +21 -0
  27. package/packages/primitives/dist/chunk-5S4DIRL4.js +42 -0
  28. package/packages/primitives/dist/chunk-H4KOEPYC.js +52 -0
  29. package/packages/primitives/dist/chunk-HONROWUG.js +41 -0
  30. package/packages/primitives/dist/chunk-J6JHKMVM.js +90 -0
  31. package/packages/primitives/dist/chunk-JBAG5E6W.js +46 -0
  32. package/packages/primitives/dist/chunk-LVNCD5F2.js +43 -0
  33. package/packages/primitives/dist/chunk-PB3LFHXU.js +72 -0
  34. package/packages/primitives/dist/chunk-SZV6KGXN.js +49 -0
  35. package/packages/primitives/dist/chunk-WVICCOQH.js +56 -0
  36. package/packages/primitives/dist/chunk-ZMGRX64G.js +74 -0
  37. package/packages/primitives/dist/index.d.ts +11 -0
  38. package/packages/primitives/dist/index.js +60 -0
  39. package/packages/primitives/dist/machines/accordion.d.ts +34 -0
  40. package/packages/primitives/dist/machines/accordion.js +6 -0
  41. package/packages/primitives/dist/machines/async.d.ts +111 -0
  42. package/packages/primitives/dist/machines/async.js +12 -0
  43. package/packages/primitives/dist/machines/button.d.ts +45 -0
  44. package/packages/primitives/dist/machines/button.js +8 -0
  45. package/packages/primitives/dist/machines/dialog.d.ts +57 -0
  46. package/packages/primitives/dist/machines/dialog.js +6 -0
  47. package/packages/primitives/dist/machines/field.d.ts +72 -0
  48. package/packages/primitives/dist/machines/field.js +12 -0
  49. package/packages/primitives/dist/machines/popover.d.ts +54 -0
  50. package/packages/primitives/dist/machines/popover.js +6 -0
  51. package/packages/primitives/dist/machines/slider.d.ts +71 -0
  52. package/packages/primitives/dist/machines/slider.js +10 -0
  53. package/packages/primitives/dist/machines/tabs.d.ts +39 -0
  54. package/packages/primitives/dist/machines/tabs.js +6 -0
  55. package/packages/primitives/dist/machines/toast.d.ts +31 -0
  56. package/packages/primitives/dist/machines/toast.js +6 -0
  57. package/packages/primitives/dist/machines/toggle.d.ts +54 -0
  58. package/packages/primitives/dist/machines/toggle.js +6 -0
  59. package/packages/primitives/node_modules/.bin/jiti +21 -0
  60. package/packages/primitives/node_modules/.bin/tsc +21 -0
  61. package/packages/primitives/node_modules/.bin/tsserver +21 -0
  62. package/packages/primitives/node_modules/.bin/tsup +21 -0
  63. package/packages/primitives/node_modules/.bin/tsup-node +21 -0
  64. package/packages/primitives/node_modules/.bin/tsx +21 -0
  65. package/packages/primitives/node_modules/.bin/vitest +21 -0
  66. package/packages/primitives/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  67. package/packages/react/dist/index.d.ts +564 -0
  68. package/packages/react/dist/index.js +3461 -0
  69. package/packages/react/node_modules/.bin/jiti +21 -0
  70. package/packages/react/node_modules/.bin/tsc +21 -0
  71. package/packages/react/node_modules/.bin/tsserver +21 -0
  72. package/packages/react/node_modules/.bin/tsup +21 -0
  73. package/packages/react/node_modules/.bin/tsup-node +21 -0
  74. package/packages/react/node_modules/.bin/tsx +21 -0
  75. package/packages/react/node_modules/.bin/vitest +21 -0
  76. package/packages/react/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  77. package/packages/react-scene/dist/index.d.ts +121 -0
  78. package/packages/react-scene/dist/index.js +430 -0
  79. package/packages/react-scene/node_modules/.bin/jiti +21 -0
  80. package/packages/react-scene/node_modules/.bin/tsc +21 -0
  81. package/packages/react-scene/node_modules/.bin/tsserver +21 -0
  82. package/packages/react-scene/node_modules/.bin/tsup +21 -0
  83. package/packages/react-scene/node_modules/.bin/tsup-node +21 -0
  84. package/packages/react-scene/node_modules/.bin/tsx +21 -0
  85. package/packages/scene/dist/index.d.ts +46 -0
  86. package/packages/scene/dist/index.js +54 -0
  87. package/packages/scene/node_modules/.bin/jiti +21 -0
  88. package/packages/scene/node_modules/.bin/tsc +21 -0
  89. package/packages/scene/node_modules/.bin/tsserver +21 -0
  90. package/packages/scene/node_modules/.bin/tsup +21 -0
  91. package/packages/scene/node_modules/.bin/tsup-node +21 -0
  92. package/packages/scene/node_modules/.bin/tsx +21 -0
  93. package/packages/signal/dist/index.d.ts +54 -0
  94. package/packages/signal/dist/index.js +169 -0
  95. package/packages/signal/node_modules/.bin/jiti +21 -0
  96. package/packages/signal/node_modules/.bin/tsc +21 -0
  97. package/packages/signal/node_modules/.bin/tsserver +21 -0
  98. package/packages/signal/node_modules/.bin/tsup +21 -0
  99. package/packages/signal/node_modules/.bin/tsup-node +21 -0
  100. package/packages/signal/node_modules/.bin/tsx +21 -0
  101. package/packages/site/dist/index.d.ts +31 -0
  102. package/packages/site/dist/index.js +62 -0
  103. package/packages/site/node_modules/.bin/jiti +21 -0
  104. package/packages/site/node_modules/.bin/tsc +21 -0
  105. package/packages/site/node_modules/.bin/tsserver +21 -0
  106. package/packages/site/node_modules/.bin/tsup +21 -0
  107. package/packages/site/node_modules/.bin/tsup-node +21 -0
  108. package/packages/site/node_modules/.bin/tsx +21 -0
  109. package/packages/solid/dist/index.d.ts +30 -0
  110. package/packages/solid/dist/index.js +174 -0
  111. package/packages/solid/node_modules/.bin/jiti +21 -0
  112. package/packages/solid/node_modules/.bin/tsc +21 -0
  113. package/packages/solid/node_modules/.bin/tsserver +21 -0
  114. package/packages/solid/node_modules/.bin/tsup +21 -0
  115. package/packages/solid/node_modules/.bin/tsup-node +21 -0
  116. package/packages/solid/node_modules/.bin/tsx +21 -0
  117. package/packages/surface/dist/index.d.ts +8 -0
  118. package/packages/surface/dist/index.js +14 -0
  119. package/packages/surface/node_modules/.bin/jiti +21 -0
  120. package/packages/surface/node_modules/.bin/tsc +21 -0
  121. package/packages/surface/node_modules/.bin/tsserver +21 -0
  122. package/packages/surface/node_modules/.bin/tsup +21 -0
  123. package/packages/surface/node_modules/.bin/tsup-node +21 -0
  124. package/packages/surface/node_modules/.bin/tsx +21 -0
  125. package/packages/svelte/dist/index.d.ts +12 -0
  126. package/packages/svelte/dist/index.js +15 -0
  127. package/packages/svelte/node_modules/.bin/acorn +21 -0
  128. package/packages/svelte/node_modules/.bin/jiti +21 -0
  129. package/packages/svelte/node_modules/.bin/svelte-check +21 -0
  130. package/packages/svelte/node_modules/.bin/tsc +21 -0
  131. package/packages/svelte/node_modules/.bin/tsserver +21 -0
  132. package/packages/svelte/node_modules/.bin/tsup +21 -0
  133. package/packages/svelte/node_modules/.bin/tsup-node +21 -0
  134. package/packages/svelte/node_modules/.bin/tsx +21 -0
  135. package/packages/svelte/node_modules/.bin/vite +21 -0
  136. package/packages/ui/dist/index.d.ts +200 -0
  137. package/packages/ui/dist/index.js +429 -0
  138. package/packages/ui/node_modules/.bin/jiti +21 -0
  139. package/packages/ui/node_modules/.bin/tsc +21 -0
  140. package/packages/ui/node_modules/.bin/tsserver +21 -0
  141. package/packages/ui/node_modules/.bin/tsup +21 -0
  142. package/packages/ui/node_modules/.bin/tsup-node +21 -0
  143. package/packages/ui/node_modules/.bin/tsx +21 -0
  144. package/packages/vue/dist/index.d.ts +71 -0
  145. package/packages/vue/dist/index.js +193 -0
  146. package/packages/vue/node_modules/.bin/jiti +21 -0
  147. package/packages/vue/node_modules/.bin/tsc +21 -0
  148. package/packages/vue/node_modules/.bin/tsserver +21 -0
  149. package/packages/vue/node_modules/.bin/tsup +21 -0
  150. package/packages/vue/node_modules/.bin/tsup-node +21 -0
  151. package/packages/vue/node_modules/.bin/tsx +21 -0
  152. package/scripts/vite-aliases.mjs +125 -0
  153. package/.changeset/README.md +0 -23
  154. package/.changeset/combobox-and-changesets.md +0 -9
  155. package/.changeset/config.json +0 -31
  156. package/.changeset/framework-adapters.md +0 -12
  157. package/.changeset/scene-3d.md +0 -6
  158. package/.changeset/scene-plane.md +0 -8
  159. package/.changeset/site-og.md +0 -5
  160. package/.cursor/rules/aeon-ui.mdc +0 -22
  161. package/ACCESSIBILITY.md +0 -32
  162. package/AGENTS.md +0 -226
  163. package/COMPONENTS.md +0 -41
  164. package/FRAMEWORKS.md +0 -57
  165. package/PHILOSOPHY.md +0 -71
  166. package/PUBLISHING.md +0 -105
  167. package/SCENE.md +0 -113
  168. package/STATES.md +0 -243
  169. package/apps/demo/index.html +0 -31
  170. package/apps/demo/og.config.mjs +0 -20
  171. package/apps/demo/package.json +0 -41
  172. package/apps/demo/public/favicon.svg +0 -16
  173. package/apps/demo/public/og-aeon-ui-engine.png +0 -0
  174. package/apps/demo/public/og.svg +0 -35
  175. package/apps/demo/scripts/generate-og-png.mjs +0 -62
  176. package/apps/demo/src/App.tsx +0 -31
  177. package/apps/demo/src/aeonDiagrams.ts +0 -42
  178. package/apps/demo/src/app.css +0 -16
  179. package/apps/demo/src/components/ActionCluster.tsx +0 -20
  180. package/apps/demo/src/components/AsyncMachineDemo.tsx +0 -97
  181. package/apps/demo/src/components/ButtonLifecycleDemo.tsx +0 -63
  182. package/apps/demo/src/components/CodeExample.tsx +0 -7
  183. package/apps/demo/src/components/ComboboxDemo.tsx +0 -30
  184. package/apps/demo/src/components/DiagramsSection.tsx +0 -37
  185. package/apps/demo/src/components/FieldStateDemo.tsx +0 -51
  186. package/apps/demo/src/components/GridMesh.tsx +0 -8
  187. package/apps/demo/src/components/HeroInstall.tsx +0 -13
  188. package/apps/demo/src/components/LandingFaq.tsx +0 -29
  189. package/apps/demo/src/components/LandingFooter.tsx +0 -30
  190. package/apps/demo/src/components/LandingHeader.tsx +0 -62
  191. package/apps/demo/src/components/LandingHero.tsx +0 -55
  192. package/apps/demo/src/components/LayersSection.tsx +0 -47
  193. package/apps/demo/src/components/MermaidDiagram.tsx +0 -86
  194. package/apps/demo/src/components/PhilosophySection.tsx +0 -31
  195. package/apps/demo/src/components/PlaygroundBlock.tsx +0 -18
  196. package/apps/demo/src/components/PlaygroundControlsDemo.tsx +0 -63
  197. package/apps/demo/src/components/PlaygroundSection.tsx +0 -120
  198. package/apps/demo/src/components/ScrollRegionDemo.tsx +0 -74
  199. package/apps/demo/src/components/ThemeSwitcher.tsx +0 -79
  200. package/apps/demo/src/demo-layout.css +0 -293
  201. package/apps/demo/src/landing.css +0 -1143
  202. package/apps/demo/src/main.tsx +0 -14
  203. package/apps/demo/src/nav.ts +0 -9
  204. package/apps/demo/src/site.ts +0 -218
  205. package/apps/demo/tsconfig.json +0 -17
  206. package/apps/demo/vite-plugins/og-meta.ts +0 -30
  207. package/apps/demo/vite.config.ts +0 -69
  208. package/docs/API_PATTERNS.md +0 -234
  209. package/docs/ARCHITECTURE.md +0 -125
  210. package/docs/COMPONENT_CHECKLIST.md +0 -103
  211. package/docs/FILE_MAP.md +0 -122
  212. package/docs/GLOSSARY.md +0 -125
  213. package/docs/INDEX.md +0 -53
  214. package/docs/LAYOUT_COORDINATES.md +0 -178
  215. package/docs/MACHINES.md +0 -171
  216. package/docs/MIGRATION_FROM_ARK.md +0 -295
  217. package/docs/VITE_CONSUMER.md +0 -114
  218. package/pnpm-workspace.yaml +0 -3
  219. package/vercel.json +0 -12
@@ -0,0 +1,3461 @@
1
+ // src/button/index.tsx
2
+ import { buttonAnatomy, partAttrs } from "@aeon-ui/core";
3
+ import { forwardRef } from "react";
4
+
5
+ // src/utils/merge-props.ts
6
+ function mergeProps(...parts) {
7
+ const result = {};
8
+ for (const props of parts) {
9
+ if (!props) continue;
10
+ for (const [key, value] of Object.entries(props)) {
11
+ if (key === "className") {
12
+ result.className = [result.className, value].filter(Boolean).join(" ");
13
+ } else if (key.startsWith("on") && typeof value === "function" && typeof result[key] === "function") {
14
+ const prev = result[key];
15
+ result[key] = (...args) => {
16
+ prev(...args);
17
+ value(...args);
18
+ };
19
+ } else {
20
+ result[key] = value;
21
+ }
22
+ }
23
+ }
24
+ return result;
25
+ }
26
+
27
+ // src/button/index.tsx
28
+ import { jsx } from "react/jsx-runtime";
29
+ var Root = forwardRef(function ButtonRoot({ variant = "solid", size = "md", disabled, status = "idle", children, className, ...rest }, ref) {
30
+ const resolvedStatus = disabled ? "disabled" : status;
31
+ const isBusy = resolvedStatus === "pending";
32
+ return /* @__PURE__ */ jsx(
33
+ "button",
34
+ {
35
+ ref,
36
+ type: "button",
37
+ disabled: disabled || isBusy || resolvedStatus === "disabled",
38
+ "aria-busy": isBusy || void 0,
39
+ className,
40
+ "data-aeon-variant": variant,
41
+ "data-aeon-size": size,
42
+ ...mergeProps(
43
+ partAttrs(buttonAnatomy.scope, buttonAnatomy.root, {
44
+ state: resolvedStatus,
45
+ disabled: Boolean(disabled || resolvedStatus === "disabled")
46
+ }),
47
+ rest
48
+ ),
49
+ children
50
+ }
51
+ );
52
+ });
53
+ var Label = forwardRef(function ButtonLabel(props, ref) {
54
+ return /* @__PURE__ */ jsx("span", { ref, ...partAttrs(buttonAnatomy.scope, buttonAnatomy.label), ...props });
55
+ });
56
+ var Icon = forwardRef(function ButtonIcon(props, ref) {
57
+ return /* @__PURE__ */ jsx("span", { ref, ...partAttrs(buttonAnatomy.scope, buttonAnatomy.icon), ...props });
58
+ });
59
+ var Group = forwardRef(function ButtonGroup({ children, ...rest }, ref) {
60
+ return /* @__PURE__ */ jsx("div", { ref, ...partAttrs(buttonAnatomy.scope, buttonAnatomy.group), ...rest, children });
61
+ });
62
+ var Button = { Root, Label, Icon, Group };
63
+
64
+ // src/switch/index.tsx
65
+ import { partAttrs as partAttrs2, switchAnatomy } from "@aeon-ui/core";
66
+ import { toggleMachine } from "@aeon-ui/primitives";
67
+ import {
68
+ createContext,
69
+ forwardRef as forwardRef2,
70
+ useContext,
71
+ useEffect,
72
+ useMemo
73
+ } from "react";
74
+
75
+ // src/hooks/use-aeon-machine.ts
76
+ import { useMachine } from "@xstate/react";
77
+ function useAeonMachine(machine, options) {
78
+ return useMachine(machine, options);
79
+ }
80
+
81
+ // src/switch/index.tsx
82
+ import { jsx as jsx2 } from "react/jsx-runtime";
83
+ var SwitchCtx = createContext(null);
84
+ function useSwitchCtx() {
85
+ const ctx = useContext(SwitchCtx);
86
+ if (!ctx) throw new Error("Switch parts must be used within Switch.Root");
87
+ return ctx;
88
+ }
89
+ var Root2 = forwardRef2(function SwitchRoot({ checked, defaultChecked = false, disabled = false, onCheckedChange, children, className, ...rest }, ref) {
90
+ const [snapshot, send] = useAeonMachine(toggleMachine, {
91
+ input: { checked: defaultChecked, disabled }
92
+ });
93
+ const controlled = checked !== void 0;
94
+ const resolvedChecked = checked ?? snapshot.context.checked;
95
+ const pressState = snapshot.matches({ interaction: "pressed" }) ? "pressed" : "idle";
96
+ useEffect(() => {
97
+ if (checked === void 0) onCheckedChange?.(resolvedChecked);
98
+ }, [resolvedChecked, onCheckedChange, checked]);
99
+ useEffect(() => {
100
+ if (checked !== void 0) send({ type: "SET_CHECKED", checked });
101
+ }, [checked, send]);
102
+ const value = useMemo(
103
+ () => ({
104
+ checked: resolvedChecked,
105
+ disabled,
106
+ controlled,
107
+ onCheckedChange,
108
+ send,
109
+ pressState
110
+ }),
111
+ [resolvedChecked, disabled, controlled, onCheckedChange, send, pressState]
112
+ );
113
+ const toggle = () => {
114
+ if (disabled) return;
115
+ const next = !resolvedChecked;
116
+ if (controlled) onCheckedChange?.(next);
117
+ else send({ type: "TOGGLE" });
118
+ };
119
+ return /* @__PURE__ */ jsx2(SwitchCtx.Provider, { value, children: /* @__PURE__ */ jsx2(
120
+ "label",
121
+ {
122
+ ref,
123
+ className,
124
+ ...mergeProps(
125
+ partAttrs2(switchAnatomy.scope, switchAnatomy.root, {
126
+ state: `${resolvedChecked ? "checked" : "unchecked"} ${pressState}`,
127
+ disabled
128
+ }),
129
+ {
130
+ onClick: (e) => {
131
+ const target = e.target;
132
+ if (target.closest(`[data-aeon-part="${switchAnatomy.control}"]`)) return;
133
+ toggle();
134
+ }
135
+ },
136
+ rest
137
+ ),
138
+ children
139
+ }
140
+ ) });
141
+ });
142
+ var Control = forwardRef2(function SwitchControl({ className, onClick, onPointerDown, onPointerUp, onPointerLeave, ...rest }, ref) {
143
+ const { checked, disabled, controlled, onCheckedChange, send, pressState } = useSwitchCtx();
144
+ const toggle = () => {
145
+ if (disabled) return;
146
+ const next = !checked;
147
+ if (controlled) onCheckedChange?.(next);
148
+ else send({ type: "TOGGLE" });
149
+ };
150
+ return /* @__PURE__ */ jsx2(
151
+ "span",
152
+ {
153
+ ref,
154
+ role: "switch",
155
+ "aria-checked": checked,
156
+ tabIndex: disabled ? -1 : 0,
157
+ className,
158
+ ...mergeProps(
159
+ partAttrs2(switchAnatomy.scope, switchAnatomy.control, {
160
+ state: `${checked ? "checked" : "unchecked"} ${pressState}`,
161
+ disabled
162
+ }),
163
+ {
164
+ onClick: (e) => {
165
+ onClick?.(e);
166
+ toggle();
167
+ e.stopPropagation();
168
+ },
169
+ onPointerDown: (e) => {
170
+ onPointerDown?.(e);
171
+ if (!disabled) send({ type: "POINTER_DOWN" });
172
+ },
173
+ onPointerUp: (e) => {
174
+ onPointerUp?.(e);
175
+ send({ type: "POINTER_UP" });
176
+ },
177
+ onPointerLeave: (e) => {
178
+ onPointerLeave?.(e);
179
+ send({ type: "POINTER_LEAVE" });
180
+ },
181
+ onKeyDown: (e) => {
182
+ if (e.key === " " || e.key === "Enter") {
183
+ e.preventDefault();
184
+ toggle();
185
+ }
186
+ }
187
+ },
188
+ rest
189
+ )
190
+ }
191
+ );
192
+ });
193
+ var Thumb = forwardRef2(function SwitchThumb({ className, ...rest }, ref) {
194
+ const { checked, pressState } = useSwitchCtx();
195
+ return /* @__PURE__ */ jsx2(
196
+ "span",
197
+ {
198
+ ref,
199
+ className,
200
+ ...mergeProps(
201
+ partAttrs2(switchAnatomy.scope, switchAnatomy.thumb, {
202
+ state: `${checked ? "checked" : "unchecked"} ${pressState}`
203
+ }),
204
+ rest
205
+ )
206
+ }
207
+ );
208
+ });
209
+ var Label2 = forwardRef2(function SwitchLabel(props, ref) {
210
+ return /* @__PURE__ */ jsx2(
211
+ "span",
212
+ {
213
+ ref,
214
+ ...mergeProps(partAttrs2(switchAnatomy.scope, switchAnatomy.label), props)
215
+ }
216
+ );
217
+ });
218
+ var HiddenInput = forwardRef2(function SwitchHiddenInput(props, ref) {
219
+ const { checked } = useSwitchCtx();
220
+ return /* @__PURE__ */ jsx2(
221
+ "input",
222
+ {
223
+ ref,
224
+ type: "checkbox",
225
+ checked,
226
+ readOnly: true,
227
+ tabIndex: -1,
228
+ "aria-hidden": true,
229
+ ...mergeProps(partAttrs2(switchAnatomy.scope, switchAnatomy.hiddenInput), props)
230
+ }
231
+ );
232
+ });
233
+ var Switch = { Root: Root2, Control, Thumb, Label: Label2, HiddenInput };
234
+
235
+ // src/checkbox/index.tsx
236
+ import { checkboxAnatomy, partAttrs as partAttrs3 } from "@aeon-ui/core";
237
+ import { toggleMachine as toggleMachine2 } from "@aeon-ui/primitives";
238
+ import {
239
+ createContext as createContext2,
240
+ forwardRef as forwardRef3,
241
+ useContext as useContext2,
242
+ useEffect as useEffect2,
243
+ useMemo as useMemo2
244
+ } from "react";
245
+ import { jsx as jsx3 } from "react/jsx-runtime";
246
+ var CheckboxCtx = createContext2(null);
247
+ function useCheckboxCtx() {
248
+ const ctx = useContext2(CheckboxCtx);
249
+ if (!ctx) throw new Error("Checkbox parts must be used within Checkbox.Root");
250
+ return ctx;
251
+ }
252
+ var Root3 = forwardRef3(function CheckboxRoot({ checked, defaultChecked = false, disabled = false, onCheckedChange, children, className, ...rest }, ref) {
253
+ const [snapshot, send] = useAeonMachine(toggleMachine2, {
254
+ input: { checked: defaultChecked, disabled }
255
+ });
256
+ const resolvedChecked = checked ?? snapshot.context.checked;
257
+ useEffect2(() => {
258
+ if (checked === void 0) onCheckedChange?.(resolvedChecked);
259
+ }, [resolvedChecked, onCheckedChange, checked]);
260
+ useEffect2(() => {
261
+ if (checked !== void 0) send({ type: "SET_CHECKED", checked });
262
+ }, [checked, send]);
263
+ const value = useMemo2(
264
+ () => ({
265
+ checked: resolvedChecked,
266
+ disabled,
267
+ controlled: checked !== void 0,
268
+ onCheckedChange,
269
+ send
270
+ }),
271
+ [resolvedChecked, disabled, checked, onCheckedChange, send]
272
+ );
273
+ const toggle = () => {
274
+ if (disabled) return;
275
+ const next = !resolvedChecked;
276
+ if (checked !== void 0) onCheckedChange?.(next);
277
+ else send({ type: "TOGGLE" });
278
+ };
279
+ return /* @__PURE__ */ jsx3(CheckboxCtx.Provider, { value, children: /* @__PURE__ */ jsx3(
280
+ "label",
281
+ {
282
+ ref,
283
+ className,
284
+ ...mergeProps(
285
+ partAttrs3(checkboxAnatomy.scope, checkboxAnatomy.root, {
286
+ state: resolvedChecked ? "checked" : "unchecked",
287
+ disabled
288
+ }),
289
+ {
290
+ onClick: (e) => {
291
+ const target = e.target;
292
+ if (target.closest(`[data-aeon-part="${checkboxAnatomy.control}"]`)) return;
293
+ toggle();
294
+ }
295
+ },
296
+ rest
297
+ ),
298
+ children
299
+ }
300
+ ) });
301
+ });
302
+ var Control2 = forwardRef3(function CheckboxControl({ className, onClick, ...rest }, ref) {
303
+ const { checked, disabled, controlled, onCheckedChange, send } = useCheckboxCtx();
304
+ return /* @__PURE__ */ jsx3(
305
+ "span",
306
+ {
307
+ ref,
308
+ role: "checkbox",
309
+ "aria-checked": checked,
310
+ "aria-disabled": disabled || void 0,
311
+ tabIndex: disabled ? -1 : 0,
312
+ className,
313
+ ...mergeProps(
314
+ partAttrs3(checkboxAnatomy.scope, checkboxAnatomy.control, {
315
+ state: checked ? "checked" : "unchecked",
316
+ disabled
317
+ }),
318
+ {
319
+ onClick: (e) => {
320
+ onClick?.(e);
321
+ if (!disabled) {
322
+ const next = !checked;
323
+ if (controlled) onCheckedChange?.(next);
324
+ else send({ type: "TOGGLE" });
325
+ }
326
+ },
327
+ onKeyDown: (e) => {
328
+ if (e.key === " " || e.key === "Enter") {
329
+ e.preventDefault();
330
+ if (!disabled) {
331
+ const next = !checked;
332
+ if (controlled) onCheckedChange?.(next);
333
+ else send({ type: "TOGGLE" });
334
+ }
335
+ }
336
+ }
337
+ },
338
+ rest
339
+ )
340
+ }
341
+ );
342
+ });
343
+ var Indicator = forwardRef3(function CheckboxIndicator(props, ref) {
344
+ const { checked } = useCheckboxCtx();
345
+ if (!checked) return null;
346
+ return /* @__PURE__ */ jsx3(
347
+ "span",
348
+ {
349
+ ref,
350
+ ...mergeProps(
351
+ partAttrs3(checkboxAnatomy.scope, checkboxAnatomy.indicator, { state: "checked" }),
352
+ props
353
+ )
354
+ }
355
+ );
356
+ });
357
+ var Label3 = forwardRef3(function CheckboxLabel(props, ref) {
358
+ return /* @__PURE__ */ jsx3("span", { ref, ...mergeProps(partAttrs3(checkboxAnatomy.scope, checkboxAnatomy.label), props) });
359
+ });
360
+ var HiddenInput2 = forwardRef3(function CheckboxHiddenInput(props, ref) {
361
+ const { checked } = useCheckboxCtx();
362
+ return /* @__PURE__ */ jsx3(
363
+ "input",
364
+ {
365
+ ref,
366
+ type: "checkbox",
367
+ checked,
368
+ readOnly: true,
369
+ tabIndex: -1,
370
+ "aria-hidden": true,
371
+ ...mergeProps(partAttrs3(checkboxAnatomy.scope, checkboxAnatomy.hiddenInput), props)
372
+ }
373
+ );
374
+ });
375
+ var Checkbox = { Root: Root3, Control: Control2, Indicator, Label: Label3, HiddenInput: HiddenInput2 };
376
+
377
+ // src/dialog/index.tsx
378
+ import { dialogAnatomy, partAttrs as partAttrs4 } from "@aeon-ui/core";
379
+ import { dialogMachine } from "@aeon-ui/primitives";
380
+ import {
381
+ createContext as createContext3,
382
+ forwardRef as forwardRef4,
383
+ useContext as useContext3,
384
+ useEffect as useEffect6,
385
+ useId,
386
+ useMemo as useMemo3,
387
+ useRef
388
+ } from "react";
389
+
390
+ // src/hooks/use-focus-trap.ts
391
+ import { useEffect as useEffect3 } from "react";
392
+ var FOCUSABLE = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
393
+ function getFocusable(container) {
394
+ return Array.from(container.querySelectorAll(FOCUSABLE)).filter(
395
+ (el) => !el.hasAttribute("disabled") && el.tabIndex !== -1
396
+ );
397
+ }
398
+ function useFocusTrap(containerRef, active) {
399
+ useEffect3(() => {
400
+ if (!active || !containerRef.current) return;
401
+ const container = containerRef.current;
402
+ const previous = document.activeElement;
403
+ const focusables = getFocusable(container);
404
+ focusables[0]?.focus();
405
+ const onKeyDown = (e) => {
406
+ if (e.key !== "Tab") return;
407
+ const nodes = getFocusable(container);
408
+ if (nodes.length === 0) return;
409
+ const first = nodes[0];
410
+ const last = nodes[nodes.length - 1];
411
+ const current = document.activeElement;
412
+ if (e.shiftKey) {
413
+ if (current === first || !container.contains(current)) {
414
+ e.preventDefault();
415
+ last.focus();
416
+ }
417
+ } else if (current === last || !container.contains(current)) {
418
+ e.preventDefault();
419
+ first.focus();
420
+ }
421
+ };
422
+ document.addEventListener("keydown", onKeyDown);
423
+ return () => {
424
+ document.removeEventListener("keydown", onKeyDown);
425
+ if (previous instanceof HTMLElement && document.contains(previous)) {
426
+ previous.focus();
427
+ }
428
+ };
429
+ }, [active, containerRef]);
430
+ }
431
+
432
+ // src/hooks/use-portalled.ts
433
+ import { useEffect as useEffect4, useState } from "react";
434
+ import { createPortal } from "react-dom";
435
+ function usePortalledMount() {
436
+ const [mounted, setMounted] = useState(false);
437
+ useEffect4(() => {
438
+ setMounted(true);
439
+ }, []);
440
+ return mounted;
441
+ }
442
+ function renderPortalled(node, portalled, mounted) {
443
+ if (!portalled || !mounted) return node;
444
+ return createPortal(node, document.body);
445
+ }
446
+
447
+ // src/hooks/use-scroll-lock.ts
448
+ import { useEffect as useEffect5 } from "react";
449
+ function useScrollLock(active) {
450
+ useEffect5(() => {
451
+ if (!active) return;
452
+ const prev = document.body.style.overflow;
453
+ document.body.style.overflow = "hidden";
454
+ return () => {
455
+ document.body.style.overflow = prev;
456
+ };
457
+ }, [active]);
458
+ }
459
+
460
+ // src/dialog/index.tsx
461
+ import { jsx as jsx4 } from "react/jsx-runtime";
462
+ var DialogCtx = createContext3(null);
463
+ function useDialogCtx() {
464
+ const ctx = useContext3(DialogCtx);
465
+ if (!ctx) throw new Error("Dialog parts must be used within Dialog.Root");
466
+ return ctx;
467
+ }
468
+ var Root4 = forwardRef4(function DialogRoot({ open, defaultOpen = false, onOpenChange, children, className, ...rest }, ref) {
469
+ const [snapshot, send] = useAeonMachine(dialogMachine, {
470
+ input: { open: defaultOpen }
471
+ });
472
+ const resolvedOpen = open ?? snapshot.context.open;
473
+ const contentRef = useRef(null);
474
+ useEffect6(() => {
475
+ onOpenChange?.(resolvedOpen);
476
+ }, [resolvedOpen, onOpenChange]);
477
+ useEffect6(() => {
478
+ if (open !== void 0) {
479
+ send({ type: "SET_OPEN", open });
480
+ }
481
+ }, [open, send]);
482
+ const titleId = useId();
483
+ const descriptionId = useId();
484
+ const value = useMemo3(
485
+ () => ({ open: resolvedOpen, send, titleId, descriptionId, contentRef }),
486
+ [resolvedOpen, send, titleId, descriptionId]
487
+ );
488
+ return /* @__PURE__ */ jsx4(DialogCtx.Provider, { value, children: /* @__PURE__ */ jsx4(
489
+ "div",
490
+ {
491
+ ref,
492
+ className,
493
+ ...mergeProps(
494
+ partAttrs4(dialogAnatomy.scope, dialogAnatomy.root, {
495
+ state: resolvedOpen ? "open" : "closed"
496
+ }),
497
+ rest
498
+ ),
499
+ children
500
+ }
501
+ ) });
502
+ });
503
+ var Trigger = forwardRef4(function DialogTrigger({ onClick, ...rest }, ref) {
504
+ const { send } = useDialogCtx();
505
+ return /* @__PURE__ */ jsx4(
506
+ "button",
507
+ {
508
+ ref,
509
+ type: "button",
510
+ ...mergeProps(
511
+ partAttrs4(dialogAnatomy.scope, dialogAnatomy.trigger),
512
+ {
513
+ onClick: (e) => {
514
+ onClick?.(e);
515
+ send({ type: "OPEN" });
516
+ }
517
+ },
518
+ rest
519
+ )
520
+ }
521
+ );
522
+ });
523
+ var Portal = forwardRef4(function DialogPortal({ portalled = true, children, className, ...rest }, ref) {
524
+ const { open } = useDialogCtx();
525
+ const mounted = usePortalledMount();
526
+ useScrollLock(open);
527
+ if (!open) return null;
528
+ const node = /* @__PURE__ */ jsx4(
529
+ "div",
530
+ {
531
+ ref,
532
+ className,
533
+ ...mergeProps(partAttrs4(dialogAnatomy.scope, dialogAnatomy.portal, { state: "open" }), rest),
534
+ children
535
+ }
536
+ );
537
+ return renderPortalled(node, portalled, mounted);
538
+ });
539
+ var Backdrop = forwardRef4(function DialogBackdrop(props, ref) {
540
+ const { open, send } = useDialogCtx();
541
+ if (!open) return null;
542
+ return /* @__PURE__ */ jsx4(
543
+ "div",
544
+ {
545
+ ref,
546
+ ...mergeProps(
547
+ partAttrs4(dialogAnatomy.scope, dialogAnatomy.backdrop, { state: "open" }),
548
+ {
549
+ onClick: () => send({ type: "POINTER_DOWN_OUTSIDE" })
550
+ },
551
+ props
552
+ )
553
+ }
554
+ );
555
+ });
556
+ var Positioner = forwardRef4(function DialogPositioner(props, ref) {
557
+ const { open } = useDialogCtx();
558
+ if (!open) return null;
559
+ return /* @__PURE__ */ jsx4(
560
+ "div",
561
+ {
562
+ ref,
563
+ ...mergeProps(partAttrs4(dialogAnatomy.scope, dialogAnatomy.positioner, { state: "open" }), props)
564
+ }
565
+ );
566
+ });
567
+ var Content = forwardRef4(function DialogContent({ onKeyDown, ...rest }, ref) {
568
+ const { open, send, titleId, descriptionId, contentRef } = useDialogCtx();
569
+ useFocusTrap(contentRef, open);
570
+ useEffect6(() => {
571
+ if (open) contentRef.current?.focus();
572
+ }, [open, contentRef]);
573
+ if (!open) return null;
574
+ return /* @__PURE__ */ jsx4(
575
+ "div",
576
+ {
577
+ ref: (node) => {
578
+ contentRef.current = node;
579
+ if (typeof ref === "function") ref(node);
580
+ else if (ref) ref.current = node;
581
+ },
582
+ role: "dialog",
583
+ "aria-modal": "true",
584
+ "aria-labelledby": titleId,
585
+ "aria-describedby": descriptionId,
586
+ tabIndex: -1,
587
+ ...mergeProps(
588
+ partAttrs4(dialogAnatomy.scope, dialogAnatomy.content, { state: "open" }),
589
+ {
590
+ onKeyDown: (e) => {
591
+ onKeyDown?.(e);
592
+ if (e.key === "Escape") send({ type: "ESCAPE" });
593
+ }
594
+ },
595
+ rest
596
+ )
597
+ }
598
+ );
599
+ });
600
+ var Title = forwardRef4(function DialogTitle(props, ref) {
601
+ const { titleId } = useDialogCtx();
602
+ return /* @__PURE__ */ jsx4("h2", { ref, id: titleId, ...mergeProps(partAttrs4(dialogAnatomy.scope, dialogAnatomy.title), props) });
603
+ });
604
+ var Description = forwardRef4(
605
+ function DialogDescription(props, ref) {
606
+ const { descriptionId } = useDialogCtx();
607
+ return /* @__PURE__ */ jsx4(
608
+ "p",
609
+ {
610
+ ref,
611
+ id: descriptionId,
612
+ ...mergeProps(partAttrs4(dialogAnatomy.scope, dialogAnatomy.description), props)
613
+ }
614
+ );
615
+ }
616
+ );
617
+ var CloseTrigger = forwardRef4(
618
+ function DialogCloseTrigger({ onClick, ...rest }, ref) {
619
+ const { send } = useDialogCtx();
620
+ return /* @__PURE__ */ jsx4(
621
+ "button",
622
+ {
623
+ ref,
624
+ type: "button",
625
+ ...mergeProps(
626
+ partAttrs4(dialogAnatomy.scope, dialogAnatomy.closeTrigger),
627
+ {
628
+ "aria-label": "Close dialog",
629
+ onClick: (e) => {
630
+ onClick?.(e);
631
+ send({ type: "CLOSE" });
632
+ }
633
+ },
634
+ rest
635
+ )
636
+ }
637
+ );
638
+ }
639
+ );
640
+ var Dialog = {
641
+ Root: Root4,
642
+ Trigger,
643
+ Portal,
644
+ Backdrop,
645
+ Positioner,
646
+ Content,
647
+ Title,
648
+ Description,
649
+ CloseTrigger
650
+ };
651
+
652
+ // src/tabs/index.tsx
653
+ import { partAttrs as partAttrs5, tabsAnatomy } from "@aeon-ui/core";
654
+ import { tabsMachine } from "@aeon-ui/primitives";
655
+ import {
656
+ createContext as createContext4,
657
+ forwardRef as forwardRef5,
658
+ useContext as useContext4,
659
+ useEffect as useEffect7,
660
+ useMemo as useMemo4
661
+ } from "react";
662
+ import { jsx as jsx5 } from "react/jsx-runtime";
663
+ var TabsCtx = createContext4(null);
664
+ function useTabsCtx() {
665
+ const ctx = useContext4(TabsCtx);
666
+ if (!ctx) throw new Error("Tabs parts must be used within Tabs.Root");
667
+ return ctx;
668
+ }
669
+ var Root5 = forwardRef5(function TabsRoot({ value, defaultValue = "", onValueChange, children, className, ...rest }, ref) {
670
+ const [snapshot, send] = useAeonMachine(tabsMachine, {
671
+ input: { value: defaultValue, disabled: false }
672
+ });
673
+ const resolvedValue = value ?? snapshot.context.value;
674
+ useEffect7(() => {
675
+ onValueChange?.(resolvedValue);
676
+ }, [resolvedValue, onValueChange]);
677
+ useEffect7(() => {
678
+ if (value !== void 0) send({ type: "SET_VALUE", value });
679
+ }, [value, send]);
680
+ const ctx = useMemo4(() => ({ value: resolvedValue, send }), [resolvedValue, send]);
681
+ return /* @__PURE__ */ jsx5(TabsCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx5(
682
+ "div",
683
+ {
684
+ ref,
685
+ className,
686
+ ...mergeProps(partAttrs5(tabsAnatomy.scope, tabsAnatomy.root), rest),
687
+ children
688
+ }
689
+ ) });
690
+ });
691
+ var List = forwardRef5(function TabsList(props, ref) {
692
+ return /* @__PURE__ */ jsx5("div", { ref, role: "tablist", ...mergeProps(partAttrs5(tabsAnatomy.scope, tabsAnatomy.list), props) });
693
+ });
694
+ var Trigger2 = forwardRef5(function TabsTrigger({ value: triggerValue, onClick, ...rest }, ref) {
695
+ const { value, send } = useTabsCtx();
696
+ const selected = value === triggerValue;
697
+ return /* @__PURE__ */ jsx5(
698
+ "button",
699
+ {
700
+ ref,
701
+ type: "button",
702
+ role: "tab",
703
+ "aria-selected": selected,
704
+ "data-selected": selected ? "" : void 0,
705
+ ...mergeProps(
706
+ partAttrs5(tabsAnatomy.scope, tabsAnatomy.trigger, {
707
+ state: selected ? "selected" : "unselected",
708
+ highlighted: selected
709
+ }),
710
+ {
711
+ onClick: (e) => {
712
+ onClick?.(e);
713
+ send({ type: "SELECT", value: triggerValue });
714
+ }
715
+ },
716
+ rest
717
+ )
718
+ }
719
+ );
720
+ });
721
+ var Content2 = forwardRef5(function TabsContent({ value: contentValue, ...rest }, ref) {
722
+ const { value } = useTabsCtx();
723
+ if (value !== contentValue) return null;
724
+ return /* @__PURE__ */ jsx5(
725
+ "div",
726
+ {
727
+ ref,
728
+ role: "tabpanel",
729
+ ...mergeProps(
730
+ partAttrs5(tabsAnatomy.scope, tabsAnatomy.content, { state: "active" }),
731
+ rest
732
+ )
733
+ }
734
+ );
735
+ });
736
+ var Indicator2 = forwardRef5(function TabsIndicator(props, ref) {
737
+ return /* @__PURE__ */ jsx5("div", { ref, ...mergeProps(partAttrs5(tabsAnatomy.scope, tabsAnatomy.indicator), props) });
738
+ });
739
+ var Tabs = { Root: Root5, List, Trigger: Trigger2, Content: Content2, Indicator: Indicator2 };
740
+
741
+ // src/separator/index.tsx
742
+ import { partAttrs as partAttrs6, separatorAnatomy } from "@aeon-ui/core";
743
+ import { forwardRef as forwardRef6 } from "react";
744
+ import { jsx as jsx6 } from "react/jsx-runtime";
745
+ var Root6 = forwardRef6(function SeparatorRoot({ orientation = "horizontal", ...rest }, ref) {
746
+ return /* @__PURE__ */ jsx6(
747
+ "div",
748
+ {
749
+ ref,
750
+ role: "separator",
751
+ "aria-orientation": orientation,
752
+ ...mergeProps(partAttrs6(separatorAnatomy.scope, separatorAnatomy.root), rest)
753
+ }
754
+ );
755
+ });
756
+ var Separator = { Root: Root6 };
757
+
758
+ // src/progress/index.tsx
759
+ import { partAttrs as partAttrs7, partOnlyAttrs, progressAnatomy } from "@aeon-ui/core";
760
+ import {
761
+ createContext as createContext5,
762
+ forwardRef as forwardRef7,
763
+ useContext as useContext5,
764
+ useMemo as useMemo5
765
+ } from "react";
766
+ import { jsx as jsx7 } from "react/jsx-runtime";
767
+ var ProgressCtx = createContext5(null);
768
+ function useProgressCtx() {
769
+ const ctx = useContext5(ProgressCtx);
770
+ if (!ctx) throw new Error("Progress parts must be used within Progress.Root");
771
+ return ctx;
772
+ }
773
+ function resolveProgressState(value, max, indeterminate) {
774
+ if (indeterminate) return "loading";
775
+ if (value >= max) return "complete";
776
+ return "idle";
777
+ }
778
+ var Root7 = forwardRef7(function ProgressRoot({ value = 0, max = 100, indeterminate = false, children, className, ...rest }, ref) {
779
+ const clampedValue = Math.min(Math.max(value, 0), max);
780
+ const state = resolveProgressState(clampedValue, max, indeterminate);
781
+ const ctx = useMemo5(
782
+ () => ({ value: clampedValue, max, indeterminate, state }),
783
+ [clampedValue, max, indeterminate, state]
784
+ );
785
+ return /* @__PURE__ */ jsx7(ProgressCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx7(
786
+ "div",
787
+ {
788
+ ref,
789
+ className,
790
+ role: "progressbar",
791
+ "aria-valuemin": 0,
792
+ "aria-valuemax": max,
793
+ "aria-valuenow": indeterminate ? void 0 : clampedValue,
794
+ "aria-busy": indeterminate || void 0,
795
+ ...mergeProps(
796
+ partAttrs7(progressAnatomy.scope, progressAnatomy.root, { state }),
797
+ rest
798
+ ),
799
+ children
800
+ }
801
+ ) });
802
+ });
803
+ var Track = forwardRef7(function ProgressTrack(props, ref) {
804
+ return /* @__PURE__ */ jsx7("div", { ref, ...mergeProps(partOnlyAttrs(progressAnatomy.track), props) });
805
+ });
806
+ var Range = forwardRef7(function ProgressRange({ style, ...rest }, ref) {
807
+ const { value, max, indeterminate } = useProgressCtx();
808
+ const width = indeterminate ? void 0 : `${value / max * 100}%`;
809
+ return /* @__PURE__ */ jsx7(
810
+ "div",
811
+ {
812
+ ref,
813
+ ...mergeProps(partOnlyAttrs(progressAnatomy.range), rest, {
814
+ style: { ...style, width }
815
+ })
816
+ }
817
+ );
818
+ });
819
+ var Label4 = forwardRef7(function ProgressLabel(props, ref) {
820
+ return /* @__PURE__ */ jsx7("span", { ref, ...mergeProps(partOnlyAttrs(progressAnatomy.label), props) });
821
+ });
822
+ var Progress = { Root: Root7, Track, Range, Label: Label4 };
823
+
824
+ // src/radio-group/index.tsx
825
+ import { partAttrs as partAttrs8, partOnlyAttrs as partOnlyAttrs2, radioGroupAnatomy } from "@aeon-ui/core";
826
+ import { tabsMachine as tabsMachine2 } from "@aeon-ui/primitives";
827
+ import {
828
+ createContext as createContext6,
829
+ forwardRef as forwardRef8,
830
+ useContext as useContext6,
831
+ useEffect as useEffect8,
832
+ useMemo as useMemo6
833
+ } from "react";
834
+ import { jsx as jsx8 } from "react/jsx-runtime";
835
+ var RadioGroupCtx = createContext6(null);
836
+ function useRadioGroupCtx() {
837
+ const ctx = useContext6(RadioGroupCtx);
838
+ if (!ctx) throw new Error("RadioGroup parts must be used within RadioGroup.Root");
839
+ return ctx;
840
+ }
841
+ var RadioGroupItemCtx = createContext6(null);
842
+ function useRadioGroupItemCtx() {
843
+ const ctx = useContext6(RadioGroupItemCtx);
844
+ if (!ctx) throw new Error("RadioGroup item parts must be used within RadioGroup.Item");
845
+ return ctx;
846
+ }
847
+ var Root8 = forwardRef8(function RadioGroupRoot({ value, defaultValue = "", onValueChange, children, className, ...rest }, ref) {
848
+ const [snapshot, send] = useAeonMachine(tabsMachine2, {
849
+ input: { value: defaultValue, disabled: false }
850
+ });
851
+ const resolvedValue = value ?? snapshot.context.value;
852
+ useEffect8(() => {
853
+ onValueChange?.(resolvedValue);
854
+ }, [resolvedValue, onValueChange]);
855
+ useEffect8(() => {
856
+ if (value !== void 0) send({ type: "SET_VALUE", value });
857
+ }, [value, send]);
858
+ const ctx = useMemo6(() => ({ value: resolvedValue, send }), [resolvedValue, send]);
859
+ return /* @__PURE__ */ jsx8(RadioGroupCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx8(
860
+ "div",
861
+ {
862
+ ref,
863
+ role: "radiogroup",
864
+ className,
865
+ ...mergeProps(
866
+ partAttrs8(radioGroupAnatomy.scope, radioGroupAnatomy.root),
867
+ rest
868
+ ),
869
+ children
870
+ }
871
+ ) });
872
+ });
873
+ var Item = forwardRef8(function RadioGroupItem({ value: itemValue, children, ...rest }, ref) {
874
+ const { value } = useRadioGroupCtx();
875
+ const selected = value === itemValue;
876
+ const itemCtx = useMemo6(() => ({ value: itemValue, selected }), [itemValue, selected]);
877
+ return /* @__PURE__ */ jsx8(RadioGroupItemCtx.Provider, { value: itemCtx, children: /* @__PURE__ */ jsx8(
878
+ "div",
879
+ {
880
+ ref,
881
+ ...mergeProps(
882
+ partOnlyAttrs2(radioGroupAnatomy.item, {
883
+ state: selected ? "selected" : "unselected"
884
+ }),
885
+ rest
886
+ ),
887
+ children
888
+ }
889
+ ) });
890
+ });
891
+ var ItemControl = forwardRef8(function RadioGroupItemControl({ onClick, onKeyDown, ...rest }, ref) {
892
+ const { send } = useRadioGroupCtx();
893
+ const { value: itemValue, selected } = useRadioGroupItemCtx();
894
+ const select = () => send({ type: "SELECT", value: itemValue });
895
+ return /* @__PURE__ */ jsx8(
896
+ "span",
897
+ {
898
+ ref,
899
+ role: "radio",
900
+ "aria-checked": selected,
901
+ tabIndex: selected ? 0 : -1,
902
+ ...mergeProps(
903
+ partOnlyAttrs2(radioGroupAnatomy.itemControl, {
904
+ state: selected ? "selected" : "unselected",
905
+ highlighted: selected
906
+ }),
907
+ {
908
+ onClick: (e) => {
909
+ onClick?.(e);
910
+ select();
911
+ },
912
+ onKeyDown: (e) => {
913
+ onKeyDown?.(e);
914
+ if (e.key === " " || e.key === "Enter") {
915
+ e.preventDefault();
916
+ select();
917
+ }
918
+ }
919
+ },
920
+ rest
921
+ )
922
+ }
923
+ );
924
+ });
925
+ var ItemIndicator = forwardRef8(function RadioGroupItemIndicator(props, ref) {
926
+ const { selected } = useRadioGroupItemCtx();
927
+ if (!selected) return null;
928
+ return /* @__PURE__ */ jsx8(
929
+ "span",
930
+ {
931
+ ref,
932
+ ...mergeProps(
933
+ partOnlyAttrs2(radioGroupAnatomy.itemIndicator, { state: "selected" }),
934
+ props
935
+ )
936
+ }
937
+ );
938
+ });
939
+ var ItemLabel = forwardRef8(function RadioGroupItemLabel({ onClick, ...rest }, ref) {
940
+ const { send } = useRadioGroupCtx();
941
+ const { value: itemValue } = useRadioGroupItemCtx();
942
+ return /* @__PURE__ */ jsx8(
943
+ "span",
944
+ {
945
+ ref,
946
+ ...mergeProps(
947
+ partOnlyAttrs2(radioGroupAnatomy.itemLabel),
948
+ {
949
+ onClick: (e) => {
950
+ onClick?.(e);
951
+ send({ type: "SELECT", value: itemValue });
952
+ }
953
+ },
954
+ rest
955
+ )
956
+ }
957
+ );
958
+ });
959
+ var RadioGroup = { Root: Root8, Item, ItemControl, ItemIndicator, ItemLabel };
960
+
961
+ // src/slider/index.tsx
962
+ import { partAttrs as partAttrs9, partOnlyAttrs as partOnlyAttrs3, sliderAnatomy } from "@aeon-ui/core";
963
+ import { sliderMachine, snapSliderValue } from "@aeon-ui/primitives";
964
+ import {
965
+ createContext as createContext7,
966
+ forwardRef as forwardRef9,
967
+ useCallback,
968
+ useContext as useContext7,
969
+ useEffect as useEffect9,
970
+ useMemo as useMemo7,
971
+ useRef as useRef2
972
+ } from "react";
973
+ import { jsx as jsx9 } from "react/jsx-runtime";
974
+ var SliderCtx = createContext7(null);
975
+ function useSliderCtx() {
976
+ const ctx = useContext7(SliderCtx);
977
+ if (!ctx) throw new Error("Slider parts must be used within Slider.Root");
978
+ return ctx;
979
+ }
980
+ function percent(value, min, max) {
981
+ if (max <= min) return 0;
982
+ return (value - min) / (max - min) * 100;
983
+ }
984
+ var Root9 = forwardRef9(function SliderRoot({
985
+ value,
986
+ defaultValue,
987
+ min = 0,
988
+ max = 100,
989
+ step = 1,
990
+ disabled = false,
991
+ onValueChange,
992
+ children,
993
+ className,
994
+ ...rest
995
+ }, ref) {
996
+ const trackRef = useRef2(null);
997
+ const [snapshot, send] = useAeonMachine(sliderMachine, {
998
+ input: {
999
+ value: defaultValue ?? min,
1000
+ min,
1001
+ max,
1002
+ step,
1003
+ disabled
1004
+ }
1005
+ });
1006
+ const resolvedValue = value ?? snapshot.context.value;
1007
+ const dragging = snapshot.matches({ interaction: "dragging" });
1008
+ useEffect9(() => {
1009
+ onValueChange?.(resolvedValue);
1010
+ }, [resolvedValue, onValueChange]);
1011
+ useEffect9(() => {
1012
+ if (value !== void 0) send({ type: "SET_VALUE", value });
1013
+ }, [value, send]);
1014
+ const setValueFromClientX = useCallback(
1015
+ (clientX) => {
1016
+ const track = trackRef.current;
1017
+ if (!track || disabled) return;
1018
+ const rect = track.getBoundingClientRect();
1019
+ if (rect.width <= 0) return;
1020
+ const ratio = Math.min(1, Math.max(0, (clientX - rect.left) / rect.width));
1021
+ const next = snapSliderValue(min + ratio * (max - min), min, max, step);
1022
+ send({ type: "SET_VALUE", value: next });
1023
+ if (value === void 0) onValueChange?.(next);
1024
+ },
1025
+ [disabled, min, max, step, send, value, onValueChange]
1026
+ );
1027
+ useEffect9(() => {
1028
+ if (!dragging) return;
1029
+ const onMove = (e) => setValueFromClientX(e.clientX);
1030
+ const onUp = () => send({ type: "POINTER_UP" });
1031
+ window.addEventListener("pointermove", onMove);
1032
+ window.addEventListener("pointerup", onUp);
1033
+ return () => {
1034
+ window.removeEventListener("pointermove", onMove);
1035
+ window.removeEventListener("pointerup", onUp);
1036
+ };
1037
+ }, [dragging, setValueFromClientX, send]);
1038
+ const ctx = useMemo7(
1039
+ () => ({
1040
+ value: resolvedValue,
1041
+ min,
1042
+ max,
1043
+ step,
1044
+ disabled,
1045
+ dragging,
1046
+ send,
1047
+ onValueChange,
1048
+ setValueFromClientX,
1049
+ trackRef
1050
+ }),
1051
+ [resolvedValue, min, max, step, disabled, dragging, send, onValueChange, setValueFromClientX]
1052
+ );
1053
+ return /* @__PURE__ */ jsx9(SliderCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx9(
1054
+ "div",
1055
+ {
1056
+ ref,
1057
+ className,
1058
+ ...mergeProps(
1059
+ partAttrs9(sliderAnatomy.scope, sliderAnatomy.root, {
1060
+ state: dragging ? "dragging" : "idle",
1061
+ disabled
1062
+ }),
1063
+ rest
1064
+ ),
1065
+ children
1066
+ }
1067
+ ) });
1068
+ });
1069
+ var Track2 = forwardRef9(function SliderTrack({ onPointerDown, ...rest }, ref) {
1070
+ const { disabled, send, setValueFromClientX, trackRef } = useSliderCtx();
1071
+ return /* @__PURE__ */ jsx9(
1072
+ "div",
1073
+ {
1074
+ ref: (node) => {
1075
+ trackRef.current = node;
1076
+ if (typeof ref === "function") ref(node);
1077
+ else if (ref) ref.current = node;
1078
+ },
1079
+ ...mergeProps(
1080
+ partOnlyAttrs3(sliderAnatomy.track),
1081
+ {
1082
+ onPointerDown: (e) => {
1083
+ onPointerDown?.(e);
1084
+ if (disabled || e.button !== 0) return;
1085
+ e.currentTarget.setPointerCapture(e.pointerId);
1086
+ send({ type: "POINTER_DOWN" });
1087
+ setValueFromClientX(e.clientX);
1088
+ }
1089
+ },
1090
+ rest
1091
+ )
1092
+ }
1093
+ );
1094
+ });
1095
+ var Range2 = forwardRef9(function SliderRange({ style, ...rest }, ref) {
1096
+ const { value, min, max } = useSliderCtx();
1097
+ return /* @__PURE__ */ jsx9(
1098
+ "div",
1099
+ {
1100
+ ref,
1101
+ ...mergeProps(partOnlyAttrs3(sliderAnatomy.range), rest, {
1102
+ style: { ...style, width: `${percent(value, min, max)}%` }
1103
+ })
1104
+ }
1105
+ );
1106
+ });
1107
+ var Thumb2 = forwardRef9(function SliderThumb({ onKeyDown, onPointerDown, style, ...rest }, ref) {
1108
+ const { value, min, max, step, disabled, dragging, send } = useSliderCtx();
1109
+ return /* @__PURE__ */ jsx9(
1110
+ "span",
1111
+ {
1112
+ ref,
1113
+ role: "slider",
1114
+ tabIndex: disabled ? -1 : 0,
1115
+ "aria-valuemin": min,
1116
+ "aria-valuemax": max,
1117
+ "aria-valuenow": value,
1118
+ "aria-disabled": disabled || void 0,
1119
+ ...mergeProps(
1120
+ partOnlyAttrs3(sliderAnatomy.thumb, { state: dragging ? "dragging" : disabled ? "disabled" : "idle" }),
1121
+ {
1122
+ style: { ...style, left: `${percent(value, min, max)}%` },
1123
+ onPointerDown: (e) => {
1124
+ onPointerDown?.(e);
1125
+ if (disabled || e.button !== 0) return;
1126
+ e.stopPropagation();
1127
+ send({ type: "POINTER_DOWN" });
1128
+ },
1129
+ onKeyDown: (e) => {
1130
+ onKeyDown?.(e);
1131
+ if (disabled || e.defaultPrevented) return;
1132
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") {
1133
+ e.preventDefault();
1134
+ send({ type: "STEP", delta: step });
1135
+ }
1136
+ if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
1137
+ e.preventDefault();
1138
+ send({ type: "STEP", delta: -step });
1139
+ }
1140
+ if (e.key === "Home") {
1141
+ e.preventDefault();
1142
+ send({ type: "HOME" });
1143
+ }
1144
+ if (e.key === "End") {
1145
+ e.preventDefault();
1146
+ send({ type: "END" });
1147
+ }
1148
+ }
1149
+ },
1150
+ rest
1151
+ )
1152
+ }
1153
+ );
1154
+ });
1155
+ var ValueText = forwardRef9(function SliderValueText(props, ref) {
1156
+ const { value } = useSliderCtx();
1157
+ return /* @__PURE__ */ jsx9("span", { ref, ...mergeProps(partOnlyAttrs3(sliderAnatomy.valueText), props), children: props.children ?? value });
1158
+ });
1159
+ var Slider = { Root: Root9, Track: Track2, Range: Range2, Thumb: Thumb2, ValueText };
1160
+
1161
+ // src/pin-input/index.tsx
1162
+ import { partAttrs as partAttrs10, partOnlyAttrs as partOnlyAttrs4, pinInputAnatomy } from "@aeon-ui/core";
1163
+ import {
1164
+ createContext as createContext8,
1165
+ forwardRef as forwardRef10,
1166
+ useCallback as useCallback2,
1167
+ useContext as useContext8,
1168
+ useEffect as useEffect10,
1169
+ useMemo as useMemo8,
1170
+ useRef as useRef3,
1171
+ useState as useState2
1172
+ } from "react";
1173
+ import { jsx as jsx10 } from "react/jsx-runtime";
1174
+ var PinInputCtx = createContext8(null);
1175
+ function usePinInputCtx() {
1176
+ const ctx = useContext8(PinInputCtx);
1177
+ if (!ctx) throw new Error("PinInput parts must be used within PinInput.Root");
1178
+ return ctx;
1179
+ }
1180
+ function normalizePinValue(raw, length) {
1181
+ return raw.replace(/\s/g, "").slice(0, length).split("");
1182
+ }
1183
+ var Root10 = forwardRef10(function PinInputRoot({
1184
+ length = 4,
1185
+ value,
1186
+ defaultValue = "",
1187
+ disabled = false,
1188
+ onValueChange,
1189
+ onComplete,
1190
+ type = "numeric",
1191
+ children,
1192
+ className,
1193
+ ...rest
1194
+ }, ref) {
1195
+ const [uncontrolled, setUncontrolled] = useState2(() => normalizePinValue(defaultValue, length));
1196
+ const inputRefs = useRef3([]);
1197
+ const controlled = value !== void 0;
1198
+ const chars = controlled ? normalizePinValue(value, length) : uncontrolled;
1199
+ while (chars.length < length) chars.push("");
1200
+ const resolved = chars.slice(0, length).join("");
1201
+ useEffect10(() => {
1202
+ onValueChange?.(resolved);
1203
+ if (resolved.length === length && !resolved.includes("")) onComplete?.(resolved);
1204
+ }, [resolved, length, onValueChange, onComplete]);
1205
+ const setChars = useCallback2(
1206
+ (next) => {
1207
+ const joined = next.slice(0, length).join("");
1208
+ if (!controlled) setUncontrolled(next.slice(0, length));
1209
+ onValueChange?.(joined);
1210
+ if (joined.length === length && !joined.includes("")) onComplete?.(joined);
1211
+ },
1212
+ [controlled, length, onValueChange, onComplete]
1213
+ );
1214
+ const setChar = useCallback2(
1215
+ (index, char) => {
1216
+ const next = [...chars.slice(0, length)];
1217
+ while (next.length < length) next.push("");
1218
+ next[index] = char;
1219
+ setChars(next);
1220
+ },
1221
+ [chars, length, setChars]
1222
+ );
1223
+ const focusInput = useCallback2((index) => {
1224
+ const el = inputRefs.current[index];
1225
+ el?.focus();
1226
+ el?.select();
1227
+ }, []);
1228
+ const registerInput = useCallback2((index, el) => {
1229
+ inputRefs.current[index] = el;
1230
+ }, []);
1231
+ const ctx = useMemo8(
1232
+ () => ({ length, values: chars.slice(0, length), disabled, type, setChar, focusInput, registerInput }),
1233
+ [length, chars, disabled, type, setChar, focusInput, registerInput]
1234
+ );
1235
+ return /* @__PURE__ */ jsx10(PinInputCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx10(
1236
+ "div",
1237
+ {
1238
+ ref,
1239
+ className,
1240
+ ...mergeProps(
1241
+ partAttrs10(pinInputAnatomy.scope, pinInputAnatomy.root, {
1242
+ state: resolved.length === length && !resolved.includes("") ? "complete" : "idle",
1243
+ disabled
1244
+ }),
1245
+ rest
1246
+ ),
1247
+ children
1248
+ }
1249
+ ) });
1250
+ });
1251
+ var Input = forwardRef10(function PinInputInput({ index, onKeyDown, onChange, onPaste, ...rest }, ref) {
1252
+ const { length, values, disabled, type, setChar, focusInput, registerInput } = usePinInputCtx();
1253
+ const value = values[index] ?? "";
1254
+ const pattern = type === "numeric" ? /^[0-9]$/ : /^[0-9a-zA-Z]$/;
1255
+ const acceptChar = (raw) => {
1256
+ if (!raw) return "";
1257
+ const char = raw.slice(-1);
1258
+ return pattern.test(char) ? char : "";
1259
+ };
1260
+ return /* @__PURE__ */ jsx10(
1261
+ "input",
1262
+ {
1263
+ ref: (node) => {
1264
+ registerInput(index, node);
1265
+ if (typeof ref === "function") ref(node);
1266
+ else if (ref) ref.current = node;
1267
+ },
1268
+ type: "text",
1269
+ inputMode: type === "numeric" ? "numeric" : "text",
1270
+ autoComplete: rest.autoComplete ?? "one-time-code",
1271
+ maxLength: 1,
1272
+ value,
1273
+ disabled,
1274
+ "aria-label": `Character ${index + 1} of ${length}`,
1275
+ ...mergeProps(partOnlyAttrs4(pinInputAnatomy.input, { state: value ? "filled" : "empty" }), rest, {
1276
+ onChange: (e) => {
1277
+ onChange?.(e);
1278
+ const char = acceptChar(e.target.value);
1279
+ setChar(index, char);
1280
+ if (char && index < length - 1) focusInput(index + 1);
1281
+ },
1282
+ onKeyDown: (e) => {
1283
+ onKeyDown?.(e);
1284
+ if (e.key === "Backspace" && !value && index > 0) {
1285
+ e.preventDefault();
1286
+ setChar(index - 1, "");
1287
+ focusInput(index - 1);
1288
+ }
1289
+ if (e.key === "ArrowLeft" && index > 0) {
1290
+ e.preventDefault();
1291
+ focusInput(index - 1);
1292
+ }
1293
+ if (e.key === "ArrowRight" && index < length - 1) {
1294
+ e.preventDefault();
1295
+ focusInput(index + 1);
1296
+ }
1297
+ },
1298
+ onPaste: (e) => {
1299
+ onPaste?.(e);
1300
+ e.preventDefault();
1301
+ const text = e.clipboardData.getData("text").replace(/\s/g, "").slice(0, length - index);
1302
+ if (!text) return;
1303
+ for (let i = 0; i < text.length && index + i < length; i++) {
1304
+ const char = acceptChar(text[i]);
1305
+ if (char) setChar(index + i, char);
1306
+ }
1307
+ focusInput(Math.min(index + text.length, length - 1));
1308
+ }
1309
+ })
1310
+ }
1311
+ );
1312
+ });
1313
+ var Group2 = forwardRef10(
1314
+ function PinInputGroup({ inputClassName, className, ...rest }, ref) {
1315
+ const { length } = usePinInputCtx();
1316
+ return /* @__PURE__ */ jsx10("div", { ref, className, ...rest, children: Array.from({ length }, (_, index) => /* @__PURE__ */ jsx10(Input, { index, className: inputClassName }, index)) });
1317
+ }
1318
+ );
1319
+ var PinInput = { Root: Root10, Input, Group: Group2 };
1320
+
1321
+ // src/accordion/index.tsx
1322
+ import { accordionAnatomy, partOnlyAttrs as partOnlyAttrs5, scopeAttrs } from "@aeon-ui/core";
1323
+ import { accordionMachine } from "@aeon-ui/primitives";
1324
+ import {
1325
+ createContext as createContext9,
1326
+ forwardRef as forwardRef11,
1327
+ useContext as useContext9,
1328
+ useEffect as useEffect11,
1329
+ useMemo as useMemo9
1330
+ } from "react";
1331
+ import { jsx as jsx11 } from "react/jsx-runtime";
1332
+ var AccordionCtx = createContext9(null);
1333
+ function useAccordionCtx() {
1334
+ const ctx = useContext9(AccordionCtx);
1335
+ if (!ctx) throw new Error("Accordion parts must be used within Accordion.Root");
1336
+ return ctx;
1337
+ }
1338
+ var Root11 = forwardRef11(function AccordionRoot({
1339
+ value,
1340
+ defaultValue = [],
1341
+ multiple = false,
1342
+ collapsible = true,
1343
+ onValueChange,
1344
+ children,
1345
+ className,
1346
+ ...rest
1347
+ }, ref) {
1348
+ const [snapshot, send] = useAeonMachine(accordionMachine, {
1349
+ input: { value: defaultValue, multiple, collapsible }
1350
+ });
1351
+ const resolvedValue = value ?? snapshot.context.value;
1352
+ useEffect11(() => {
1353
+ onValueChange?.(resolvedValue);
1354
+ }, [resolvedValue, onValueChange]);
1355
+ useEffect11(() => {
1356
+ if (value !== void 0) send({ type: "SET_VALUE", value });
1357
+ }, [value, send]);
1358
+ const ctx = useMemo9(() => ({ value: resolvedValue, send }), [resolvedValue, send]);
1359
+ return /* @__PURE__ */ jsx11(AccordionCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx11(
1360
+ "div",
1361
+ {
1362
+ ref,
1363
+ className,
1364
+ ...mergeProps(
1365
+ scopeAttrs(accordionAnatomy.scope, accordionAnatomy.root),
1366
+ rest
1367
+ ),
1368
+ children
1369
+ }
1370
+ ) });
1371
+ });
1372
+ var Item2 = forwardRef11(function AccordionItem({ value: itemValue, children, ...rest }, ref) {
1373
+ const { value } = useAccordionCtx();
1374
+ const open = value.includes(itemValue);
1375
+ return /* @__PURE__ */ jsx11(
1376
+ "div",
1377
+ {
1378
+ ref,
1379
+ ...mergeProps(
1380
+ partOnlyAttrs5(accordionAnatomy.item, {
1381
+ state: open ? "open" : "closed"
1382
+ }),
1383
+ rest
1384
+ ),
1385
+ children
1386
+ }
1387
+ );
1388
+ });
1389
+ var ItemTrigger = forwardRef11(function AccordionItemTrigger({ value: itemValue, onClick, ...rest }, ref) {
1390
+ const { value, send } = useAccordionCtx();
1391
+ const open = value.includes(itemValue);
1392
+ return /* @__PURE__ */ jsx11(
1393
+ "button",
1394
+ {
1395
+ ref,
1396
+ type: "button",
1397
+ "aria-expanded": open,
1398
+ ...mergeProps(
1399
+ partOnlyAttrs5(accordionAnatomy.itemTrigger, {
1400
+ state: open ? "open" : "closed"
1401
+ }),
1402
+ {
1403
+ onClick: (e) => {
1404
+ onClick?.(e);
1405
+ send({ type: "TOGGLE", item: itemValue });
1406
+ }
1407
+ },
1408
+ rest
1409
+ )
1410
+ }
1411
+ );
1412
+ });
1413
+ var ItemContent = forwardRef11(function AccordionItemContent({ value: itemValue, children, ...rest }, ref) {
1414
+ const { value } = useAccordionCtx();
1415
+ if (!value.includes(itemValue)) return null;
1416
+ return /* @__PURE__ */ jsx11(
1417
+ "div",
1418
+ {
1419
+ ref,
1420
+ ...mergeProps(
1421
+ partOnlyAttrs5(accordionAnatomy.itemContent, { state: "open" }),
1422
+ rest
1423
+ ),
1424
+ children
1425
+ }
1426
+ );
1427
+ });
1428
+ var ItemIndicator2 = forwardRef11(function AccordionItemIndicator(props, ref) {
1429
+ return /* @__PURE__ */ jsx11(
1430
+ "span",
1431
+ {
1432
+ ref,
1433
+ ...mergeProps(partOnlyAttrs5(accordionAnatomy.itemIndicator), props)
1434
+ }
1435
+ );
1436
+ });
1437
+ var Accordion = { Root: Root11, Item: Item2, ItemTrigger, ItemContent, ItemIndicator: ItemIndicator2 };
1438
+
1439
+ // src/async/actions.tsx
1440
+ import { asyncAnatomy, partOnlyAttrs as partOnlyAttrs6 } from "@aeon-ui/core";
1441
+ import { forwardRef as forwardRef12 } from "react";
1442
+ import { jsx as jsx12 } from "react/jsx-runtime";
1443
+ var AsyncActions = forwardRef12(function AsyncActions2({ children, className, ...rest }, ref) {
1444
+ return /* @__PURE__ */ jsx12(
1445
+ "div",
1446
+ {
1447
+ ref,
1448
+ className,
1449
+ ...mergeProps(partOnlyAttrs6(asyncAnatomy.actions), rest),
1450
+ children
1451
+ }
1452
+ );
1453
+ });
1454
+
1455
+ // src/async/context.tsx
1456
+ import { createAsyncMachine } from "@aeon-ui/primitives";
1457
+ import { createContext as createContext10, useContext as useContext10, useMemo as useMemo10 } from "react";
1458
+ import { jsx as jsx13 } from "react/jsx-runtime";
1459
+ var defaultMachine = createAsyncMachine();
1460
+ var AsyncCtx = createContext10(null);
1461
+ function useAsyncContext() {
1462
+ const ctx = useContext10(AsyncCtx);
1463
+ if (!ctx) {
1464
+ throw new Error("Async compound components must be used within <Async.Root>");
1465
+ }
1466
+ return ctx;
1467
+ }
1468
+ function AsyncProvider({ children, machine }) {
1469
+ const resolvedMachine = machine ?? defaultMachine;
1470
+ const [snapshot, send] = useAeonMachine(resolvedMachine);
1471
+ const status = String(snapshot.value);
1472
+ const { data, error, stale } = snapshot.context;
1473
+ const stateAttr = stale && status === "success" ? `${status} stale` : status;
1474
+ const value = useMemo10(
1475
+ () => ({
1476
+ send,
1477
+ status,
1478
+ data,
1479
+ error,
1480
+ stale: Boolean(stale),
1481
+ stateAttr
1482
+ }),
1483
+ [send, status, data, error, stale, stateAttr]
1484
+ );
1485
+ return /* @__PURE__ */ jsx13(AsyncCtx.Provider, { value, children });
1486
+ }
1487
+
1488
+ // src/async/readout.tsx
1489
+ import { asyncAnatomy as asyncAnatomy2, partAttrs as partAttrs11, partOnlyAttrs as partOnlyAttrs7 } from "@aeon-ui/core";
1490
+ import { forwardRef as forwardRef13 } from "react";
1491
+ import { jsx as jsx14, jsxs } from "react/jsx-runtime";
1492
+ var AsyncReadout = forwardRef13(function AsyncReadout2({ children, className, ...rest }, ref) {
1493
+ const { stateAttr } = useAsyncContext();
1494
+ return /* @__PURE__ */ jsxs(
1495
+ "div",
1496
+ {
1497
+ ref,
1498
+ role: "status",
1499
+ "aria-live": "polite",
1500
+ className,
1501
+ ...mergeProps(partAttrs11(asyncAnatomy2.scope, asyncAnatomy2.readout, { state: stateAttr }), rest),
1502
+ children: [
1503
+ /* @__PURE__ */ jsx14(
1504
+ "span",
1505
+ {
1506
+ className: "aeon-async-readout__rail",
1507
+ "aria-hidden": true,
1508
+ ...partOnlyAttrs7(asyncAnatomy2.readoutRail)
1509
+ }
1510
+ ),
1511
+ /* @__PURE__ */ jsx14("div", { className: "aeon-async-readout__body", ...partOnlyAttrs7(asyncAnatomy2.readoutBody), children })
1512
+ ]
1513
+ }
1514
+ );
1515
+ });
1516
+
1517
+ // src/async/root.tsx
1518
+ import { asyncAnatomy as asyncAnatomy3, partAttrs as partAttrs12 } from "@aeon-ui/core";
1519
+ import { forwardRef as forwardRef14 } from "react";
1520
+ import { jsx as jsx15 } from "react/jsx-runtime";
1521
+ var AsyncRootInner = forwardRef14(function AsyncRootInner2({ children, className, ...rest }, ref) {
1522
+ const { stateAttr } = useAsyncContext();
1523
+ return /* @__PURE__ */ jsx15(
1524
+ "div",
1525
+ {
1526
+ ref,
1527
+ className,
1528
+ ...mergeProps(partAttrs12(asyncAnatomy3.scope, asyncAnatomy3.root, { state: stateAttr }), rest),
1529
+ children
1530
+ }
1531
+ );
1532
+ });
1533
+ var AsyncRoot = forwardRef14(function AsyncRoot2({ children, className, ...rest }, ref) {
1534
+ return /* @__PURE__ */ jsx15(AsyncProvider, { children: /* @__PURE__ */ jsx15(AsyncRootInner, { ref, className, ...rest, children }) });
1535
+ });
1536
+
1537
+ // src/async/track.tsx
1538
+ import { asyncAnatomy as asyncAnatomy4, partOnlyAttrs as partOnlyAttrs8 } from "@aeon-ui/core";
1539
+ import { ASYNC_LIFECYCLE_STATES } from "@aeon-ui/primitives";
1540
+ import { forwardRef as forwardRef15 } from "react";
1541
+ import { jsx as jsx16 } from "react/jsx-runtime";
1542
+ function segmentPhase(index, activeIndex) {
1543
+ if (activeIndex === -1) return "future";
1544
+ if (index === activeIndex) return "active";
1545
+ if (index < activeIndex) return "past";
1546
+ return "future";
1547
+ }
1548
+ var AsyncTrack = forwardRef15(function AsyncTrack2({ states = ASYNC_LIFECYCLE_STATES, className, ...rest }, ref) {
1549
+ const { status } = useAsyncContext();
1550
+ const activeIndex = states.indexOf(status);
1551
+ const { style, ...restWithoutStyle } = rest;
1552
+ return /* @__PURE__ */ jsx16(
1553
+ "div",
1554
+ {
1555
+ ref,
1556
+ role: "list",
1557
+ "aria-label": "Async lifecycle states",
1558
+ className,
1559
+ style: {
1560
+ ...style,
1561
+ ["--aeon-state-track-count"]: states.length
1562
+ },
1563
+ ...mergeProps(partOnlyAttrs8(asyncAnatomy4.track), restWithoutStyle),
1564
+ children: states.map((id, index) => {
1565
+ const phase = segmentPhase(index, activeIndex);
1566
+ return /* @__PURE__ */ jsx16(
1567
+ "span",
1568
+ {
1569
+ role: "listitem",
1570
+ "aria-current": phase === "active" ? "step" : void 0,
1571
+ title: id,
1572
+ className: `state-track__seg state-track__seg--${id} state-track__seg--${phase}`,
1573
+ ...partOnlyAttrs8(asyncAnatomy4.segment, { state: `${id} ${phase}` }),
1574
+ children: id
1575
+ },
1576
+ id
1577
+ );
1578
+ })
1579
+ }
1580
+ );
1581
+ });
1582
+
1583
+ // src/async/legacy-region.tsx
1584
+ import { partAttrs as partAttrs13 } from "@aeon-ui/core";
1585
+ import { createAsyncMachine as createAsyncMachine2 } from "@aeon-ui/primitives";
1586
+ import { useMemo as useMemo11 } from "react";
1587
+ import { Fragment, jsx as jsx17, jsxs as jsxs2 } from "react/jsx-runtime";
1588
+ function AsyncRegion({ children, className }) {
1589
+ const machine = useMemo11(() => createAsyncMachine2(), []);
1590
+ const [snapshot] = useAeonMachine(machine);
1591
+ const status = snapshot.value;
1592
+ const { data, error } = snapshot.context;
1593
+ const content = typeof children === "function" ? children({ status, data, error }) : children;
1594
+ return /* @__PURE__ */ jsx17(
1595
+ "div",
1596
+ {
1597
+ className,
1598
+ ...mergeProps(partAttrs13("async", "root", { state: status })),
1599
+ children: content ?? /* @__PURE__ */ jsxs2(Fragment, { children: [
1600
+ status === "idle" && /* @__PURE__ */ jsx17("span", { "data-aeon-part": "idle", children: "Ready" }),
1601
+ status === "loading" && /* @__PURE__ */ jsx17("span", { "data-aeon-part": "loading", children: "Loading\u2026" }),
1602
+ status === "success" && /* @__PURE__ */ jsx17("span", { "data-aeon-part": "success", children: String(data) }),
1603
+ status === "failure" && /* @__PURE__ */ jsx17("span", { "data-aeon-part": "failure", children: error }),
1604
+ status === "empty" && /* @__PURE__ */ jsx17("span", { "data-aeon-part": "empty", children: "No results" })
1605
+ ] })
1606
+ }
1607
+ );
1608
+ }
1609
+
1610
+ // src/async/index.tsx
1611
+ import { createAsyncMachine as createAsyncMachine3 } from "@aeon-ui/primitives";
1612
+ var Async = {
1613
+ Root: AsyncRoot,
1614
+ Provider: AsyncProvider,
1615
+ Track: AsyncTrack,
1616
+ Readout: AsyncReadout,
1617
+ Actions: AsyncActions
1618
+ };
1619
+
1620
+ // src/field/index.tsx
1621
+ import { fieldAnatomy, partAttrs as partAttrs14, partOnlyAttrs as partOnlyAttrs9, stateToAttr } from "@aeon-ui/core";
1622
+ import { fieldMachine } from "@aeon-ui/primitives";
1623
+ import {
1624
+ createContext as createContext11,
1625
+ forwardRef as forwardRef16,
1626
+ useContext as useContext11,
1627
+ useMemo as useMemo12
1628
+ } from "react";
1629
+ import { jsx as jsx18 } from "react/jsx-runtime";
1630
+ var FieldCtx = createContext11(null);
1631
+ function useFieldContext() {
1632
+ const ctx = useContext11(FieldCtx);
1633
+ if (!ctx) throw new Error("Field parts must be used within <Field.Root>");
1634
+ return ctx;
1635
+ }
1636
+ var Root12 = forwardRef16(function FieldRoot({ children, className, id }, ref) {
1637
+ const [snapshot, send] = useAeonMachine(fieldMachine);
1638
+ const stateAttr = stateToAttr(snapshot.value);
1639
+ const invalid = typeof snapshot.value === "object" && snapshot.value !== null && "validation" in snapshot.value && snapshot.value.validation === "invalid";
1640
+ const pending = typeof snapshot.value === "object" && snapshot.value !== null && "submission" in snapshot.value && snapshot.value.submission === "pending";
1641
+ const value = useMemo12(
1642
+ () => ({ stateAttr, send, invalid, pending }),
1643
+ [stateAttr, send, invalid, pending]
1644
+ );
1645
+ return /* @__PURE__ */ jsx18(FieldCtx.Provider, { value, children: /* @__PURE__ */ jsx18(
1646
+ "div",
1647
+ {
1648
+ ref,
1649
+ id,
1650
+ className,
1651
+ ...partAttrs14(fieldAnatomy.scope, fieldAnatomy.root, { state: stateAttr }),
1652
+ children
1653
+ }
1654
+ ) });
1655
+ });
1656
+ var Label5 = forwardRef16(function FieldLabel(props, ref) {
1657
+ return /* @__PURE__ */ jsx18("label", { ref, ...partOnlyAttrs9(fieldAnatomy.label), ...props });
1658
+ });
1659
+ var Control3 = forwardRef16(function FieldControl({ validate, onChange, onBlur, ...rest }, ref) {
1660
+ const { send, invalid } = useFieldContext();
1661
+ return /* @__PURE__ */ jsx18(
1662
+ "input",
1663
+ {
1664
+ ref,
1665
+ "aria-invalid": invalid || void 0,
1666
+ ...partOnlyAttrs9(fieldAnatomy.control),
1667
+ ...mergeProps(
1668
+ {
1669
+ onChange: (e) => {
1670
+ send({ type: "INPUT" });
1671
+ const ok = validate?.(e.target.value) ?? true;
1672
+ send({ type: "VALIDATE", valid: ok });
1673
+ onChange?.(e);
1674
+ },
1675
+ onBlur: (e) => {
1676
+ send({ type: "BLUR" });
1677
+ onBlur?.(e);
1678
+ }
1679
+ },
1680
+ rest
1681
+ )
1682
+ }
1683
+ );
1684
+ });
1685
+ var Textarea = forwardRef16(function FieldTextarea({ validate, onChange, onBlur, ...rest }, ref) {
1686
+ const { send, invalid } = useFieldContext();
1687
+ return /* @__PURE__ */ jsx18(
1688
+ "textarea",
1689
+ {
1690
+ ref,
1691
+ "aria-invalid": invalid || void 0,
1692
+ ...partOnlyAttrs9(fieldAnatomy.textarea),
1693
+ ...mergeProps(
1694
+ {
1695
+ onChange: (e) => {
1696
+ send({ type: "INPUT" });
1697
+ const ok = validate?.(e.target.value) ?? true;
1698
+ send({ type: "VALIDATE", valid: ok });
1699
+ onChange?.(e);
1700
+ },
1701
+ onBlur: (e) => {
1702
+ send({ type: "BLUR" });
1703
+ onBlur?.(e);
1704
+ }
1705
+ },
1706
+ rest
1707
+ )
1708
+ }
1709
+ );
1710
+ });
1711
+ var Message = forwardRef16(
1712
+ function FieldMessage(props, ref) {
1713
+ const { invalid } = useFieldContext();
1714
+ if (!invalid) return null;
1715
+ return /* @__PURE__ */ jsx18(
1716
+ "p",
1717
+ {
1718
+ ref,
1719
+ role: "alert",
1720
+ ...partOnlyAttrs9(fieldAnatomy.message, { state: "invalid" }),
1721
+ ...props
1722
+ }
1723
+ );
1724
+ }
1725
+ );
1726
+ var Hint = forwardRef16(
1727
+ function FieldHint(props, ref) {
1728
+ return /* @__PURE__ */ jsx18("p", { ref, ...partOnlyAttrs9(fieldAnatomy.hint), ...props });
1729
+ }
1730
+ );
1731
+ var Field = { Root: Root12, Label: Label5, Control: Control3, Textarea, Message, Hint };
1732
+
1733
+ // src/scroll/index.tsx
1734
+ import { scrollAnatomy, partAttrs as partAttrs15, partOnlyAttrs as partOnlyAttrs10 } from "@aeon-ui/core";
1735
+ import {
1736
+ createContext as createContext12,
1737
+ forwardRef as forwardRef17,
1738
+ useContext as useContext12,
1739
+ useMemo as useMemo13,
1740
+ useRef as useRef4
1741
+ } from "react";
1742
+
1743
+ // src/scroll/use-scroll-state.ts
1744
+ import { getScrollSnapshot } from "@aeon-ui/core";
1745
+ import { useLayoutEffect, useState as useState3 } from "react";
1746
+ function useScrollState(ref) {
1747
+ const [stateAttr, setStateAttr] = useState3("idle");
1748
+ useLayoutEffect(() => {
1749
+ const el = ref.current;
1750
+ if (!el) return;
1751
+ const update = () => {
1752
+ setStateAttr(getScrollSnapshot(el).stateAttr);
1753
+ };
1754
+ update();
1755
+ el.addEventListener("scroll", update, { passive: true });
1756
+ const ro = new ResizeObserver(update);
1757
+ ro.observe(el);
1758
+ const content = el.firstElementChild;
1759
+ if (content instanceof HTMLElement) ro.observe(content);
1760
+ return () => {
1761
+ el.removeEventListener("scroll", update);
1762
+ ro.disconnect();
1763
+ };
1764
+ }, [ref]);
1765
+ return stateAttr;
1766
+ }
1767
+
1768
+ // src/scroll/index.tsx
1769
+ import { jsx as jsx19 } from "react/jsx-runtime";
1770
+ var ScrollCtx = createContext12(null);
1771
+ function useScrollContext() {
1772
+ const ctx = useContext12(ScrollCtx);
1773
+ if (!ctx) throw new Error("Scroll parts must be used within <Scroll.Root>");
1774
+ return ctx;
1775
+ }
1776
+ var Root13 = forwardRef17(function ScrollRoot({ children, className, ...rest }, ref) {
1777
+ const viewportRef = useRef4(null);
1778
+ const stateAttr = useScrollState(viewportRef);
1779
+ const value = useMemo13(() => ({ stateAttr }), [stateAttr]);
1780
+ return /* @__PURE__ */ jsx19(ScrollCtx.Provider, { value, children: /* @__PURE__ */ jsx19(
1781
+ "div",
1782
+ {
1783
+ ref,
1784
+ className,
1785
+ ...partAttrs15(scrollAnatomy.scope, scrollAnatomy.root),
1786
+ ...rest,
1787
+ children: /* @__PURE__ */ jsx19(ScrollViewportRefContext.Provider, { value: viewportRef, children })
1788
+ }
1789
+ ) });
1790
+ });
1791
+ var ScrollViewportRefContext = createContext12(
1792
+ null
1793
+ );
1794
+ var Viewport = forwardRef17(function ScrollViewport({ children, className, ...rest }, forwardedRef) {
1795
+ const ctxRef = useContext12(ScrollViewportRefContext);
1796
+ const { stateAttr } = useScrollContext();
1797
+ return /* @__PURE__ */ jsx19(
1798
+ "div",
1799
+ {
1800
+ ref: (node) => {
1801
+ if (ctxRef) ctxRef.current = node;
1802
+ if (typeof forwardedRef === "function") forwardedRef(node);
1803
+ else if (forwardedRef) forwardedRef.current = node;
1804
+ },
1805
+ className,
1806
+ "data-aeon-scroll": "",
1807
+ ...partAttrs15(scrollAnatomy.scope, scrollAnatomy.viewport, { state: stateAttr }),
1808
+ ...rest,
1809
+ children
1810
+ }
1811
+ );
1812
+ });
1813
+ var Content3 = forwardRef17(function ScrollContent(props, ref) {
1814
+ return /* @__PURE__ */ jsx19("div", { ref, ...partOnlyAttrs10(scrollAnatomy.content), ...props });
1815
+ });
1816
+ var Scroll = {
1817
+ Root: Root13,
1818
+ Viewport,
1819
+ Content: Content3
1820
+ };
1821
+
1822
+ // src/select/index.tsx
1823
+ import { selectAnatomy, partAttrs as partAttrs17, partOnlyAttrs as partOnlyAttrs11 } from "@aeon-ui/core";
1824
+ import { popoverMachine } from "@aeon-ui/primitives";
1825
+ import {
1826
+ createContext as createContext13,
1827
+ forwardRef as forwardRef19,
1828
+ useCallback as useCallback3,
1829
+ useContext as useContext13,
1830
+ useId as useId2,
1831
+ useMemo as useMemo14,
1832
+ useRef as useRef5,
1833
+ useState as useState4
1834
+ } from "react";
1835
+
1836
+ // src/floating/FloatingPositioner.tsx
1837
+ import { partAttrs as partAttrs16 } from "@aeon-ui/core";
1838
+ import { forwardRef as forwardRef18 } from "react";
1839
+
1840
+ // src/hooks/use-anchor-position.ts
1841
+ import { useEffect as useEffect12 } from "react";
1842
+ function useAnchorPosition(anchorRef, floatingRef, active, placement = "bottom-start", options = {}) {
1843
+ const { matchWidth = false } = options;
1844
+ useEffect12(() => {
1845
+ if (!active || !anchorRef.current || !floatingRef.current) return;
1846
+ const update = () => {
1847
+ const anchor = anchorRef.current;
1848
+ const floating = floatingRef.current;
1849
+ if (!anchor || !floating) return;
1850
+ const rect = anchor.getBoundingClientRect();
1851
+ floating.style.position = "fixed";
1852
+ floating.style.left = `${rect.left}px`;
1853
+ floating.style.bottom = "";
1854
+ floating.style.right = "";
1855
+ floating.style.zIndex = "50";
1856
+ if (matchWidth) {
1857
+ floating.style.width = `${rect.width}px`;
1858
+ floating.style.minWidth = `${rect.width}px`;
1859
+ } else {
1860
+ floating.style.width = "";
1861
+ floating.style.minWidth = "";
1862
+ }
1863
+ if (placement === "top-start") {
1864
+ const height = floating.offsetHeight || floating.getBoundingClientRect().height;
1865
+ floating.style.top = `${rect.top - height - 4}px`;
1866
+ } else {
1867
+ floating.style.top = `${rect.bottom + 4}px`;
1868
+ }
1869
+ };
1870
+ update();
1871
+ requestAnimationFrame(update);
1872
+ window.addEventListener("resize", update);
1873
+ window.addEventListener("scroll", update, true);
1874
+ return () => {
1875
+ window.removeEventListener("resize", update);
1876
+ window.removeEventListener("scroll", update, true);
1877
+ };
1878
+ }, [active, anchorRef, floatingRef, placement, matchWidth]);
1879
+ }
1880
+
1881
+ // src/floating/FloatingPositioner.tsx
1882
+ import { jsx as jsx20 } from "react/jsx-runtime";
1883
+ var FloatingPositioner = forwardRef18(
1884
+ function FloatingPositioner2({
1885
+ open,
1886
+ scope,
1887
+ part,
1888
+ triggerRef,
1889
+ positionerRef,
1890
+ portalled = true,
1891
+ placement = "bottom-start",
1892
+ matchAnchorWidth = false,
1893
+ children,
1894
+ className,
1895
+ ...rest
1896
+ }, ref) {
1897
+ const mounted = usePortalledMount();
1898
+ useAnchorPosition(triggerRef, positionerRef, open && portalled, placement, {
1899
+ matchWidth: matchAnchorWidth
1900
+ });
1901
+ if (!open) return null;
1902
+ const node = /* @__PURE__ */ jsx20(
1903
+ "div",
1904
+ {
1905
+ ref: (el) => {
1906
+ positionerRef.current = el;
1907
+ if (typeof ref === "function") ref(el);
1908
+ else if (ref) ref.current = el;
1909
+ },
1910
+ className,
1911
+ ...mergeProps(partAttrs16(scope, part, { state: "open" }), rest),
1912
+ children
1913
+ }
1914
+ );
1915
+ return renderPortalled(node, portalled, mounted);
1916
+ }
1917
+ );
1918
+
1919
+ // src/hooks/use-outside-click.ts
1920
+ import { useEffect as useEffect13 } from "react";
1921
+ function useOutsideClick(refs, enabled, onOutside) {
1922
+ useEffect13(() => {
1923
+ if (!enabled) return;
1924
+ const onDown = (e) => {
1925
+ const target = e.target;
1926
+ if (refs.some((r) => r.current?.contains(target))) return;
1927
+ onOutside();
1928
+ };
1929
+ document.addEventListener("mousedown", onDown);
1930
+ return () => document.removeEventListener("mousedown", onDown);
1931
+ }, [refs, enabled, onOutside]);
1932
+ }
1933
+
1934
+ // src/select/index.tsx
1935
+ import { jsx as jsx21, jsxs as jsxs3 } from "react/jsx-runtime";
1936
+ var SelectCtx = createContext13(null);
1937
+ var SelectPositionerCtx = createContext13(false);
1938
+ function useSelectCtx() {
1939
+ const ctx = useContext13(SelectCtx);
1940
+ if (!ctx) throw new Error("Select parts must be used within <Select.Root>");
1941
+ return ctx;
1942
+ }
1943
+ function optionValuesFromDom(listboxId, content) {
1944
+ if (!content) return [];
1945
+ const prefix = `${listboxId}-option-`;
1946
+ return Array.from(content.querySelectorAll('button[role="option"]:not(:disabled)')).map((el) => el.id.startsWith(prefix) ? el.id.slice(prefix.length) : "").filter(Boolean);
1947
+ }
1948
+ var Root14 = forwardRef19(function SelectRoot({ value, onValueChange, children, className, disabled }, ref) {
1949
+ const [snapshot, send] = useAeonMachine(popoverMachine, { input: { open: false } });
1950
+ const [highlightedValue, setHighlightedValue] = useState4(null);
1951
+ const triggerRef = useRef5(null);
1952
+ const positionerRef = useRef5(null);
1953
+ const contentRef = useRef5(null);
1954
+ const rootRef = useRef5(null);
1955
+ const listboxId = useId2();
1956
+ const open = disabled ? false : snapshot.matches("open");
1957
+ const close = useCallback3(() => {
1958
+ send({ type: "CLOSE" });
1959
+ setHighlightedValue(null);
1960
+ }, [send]);
1961
+ useOutsideClick([rootRef, positionerRef], open, () => send({ type: "POINTER_DOWN_OUTSIDE" }));
1962
+ const getOptionValues = useCallback3(
1963
+ () => optionValuesFromDom(listboxId, contentRef.current),
1964
+ [listboxId, open]
1965
+ );
1966
+ const selectValue = useCallback3(
1967
+ (next) => {
1968
+ onValueChange?.(next);
1969
+ close();
1970
+ },
1971
+ [onValueChange, close]
1972
+ );
1973
+ const highlightValue = useCallback3((next) => {
1974
+ setHighlightedValue(next);
1975
+ }, []);
1976
+ const moveHighlight = useCallback3(
1977
+ (delta) => {
1978
+ const options = getOptionValues();
1979
+ if (options.length === 0) {
1980
+ setHighlightedValue(null);
1981
+ return;
1982
+ }
1983
+ const idx = highlightedValue ? options.indexOf(highlightedValue) : -1;
1984
+ let next = idx + delta;
1985
+ if (next < 0) next = options.length - 1;
1986
+ if (next >= options.length) next = 0;
1987
+ setHighlightedValue(options[next]);
1988
+ },
1989
+ [getOptionValues, highlightedValue]
1990
+ );
1991
+ const onListboxKeyDown = useCallback3(
1992
+ (e) => {
1993
+ if (e.defaultPrevented) return;
1994
+ if ((e.key === "Enter" || e.key === " ") && !open) {
1995
+ e.preventDefault();
1996
+ send({ type: "OPEN" });
1997
+ return;
1998
+ }
1999
+ if (e.key === "ArrowDown") {
2000
+ e.preventDefault();
2001
+ if (!open) send({ type: "OPEN" });
2002
+ else moveHighlight(1);
2003
+ return;
2004
+ }
2005
+ if (e.key === "ArrowUp") {
2006
+ e.preventDefault();
2007
+ if (!open) send({ type: "OPEN" });
2008
+ else moveHighlight(-1);
2009
+ return;
2010
+ }
2011
+ if (e.key === "Home" && open) {
2012
+ e.preventDefault();
2013
+ const first = getOptionValues()[0];
2014
+ if (first) highlightValue(first);
2015
+ return;
2016
+ }
2017
+ if (e.key === "End" && open) {
2018
+ e.preventDefault();
2019
+ const options = getOptionValues();
2020
+ const last = options[options.length - 1];
2021
+ if (last) highlightValue(last);
2022
+ return;
2023
+ }
2024
+ if ((e.key === "Enter" || e.key === " ") && open) {
2025
+ e.preventDefault();
2026
+ const pick = highlightedValue ?? getOptionValues()[0];
2027
+ if (pick) selectValue(pick);
2028
+ return;
2029
+ }
2030
+ if (e.key === "Escape") send({ type: "ESCAPE" });
2031
+ },
2032
+ [open, send, moveHighlight, getOptionValues, highlightValue, highlightedValue, selectValue]
2033
+ );
2034
+ const ctx = useMemo14(
2035
+ () => ({
2036
+ value,
2037
+ open,
2038
+ listboxId,
2039
+ highlightedValue,
2040
+ send,
2041
+ triggerRef,
2042
+ positionerRef,
2043
+ contentRef,
2044
+ onValueChange,
2045
+ moveHighlight,
2046
+ highlightValue,
2047
+ selectValue,
2048
+ onListboxKeyDown
2049
+ }),
2050
+ [
2051
+ value,
2052
+ open,
2053
+ listboxId,
2054
+ highlightedValue,
2055
+ send,
2056
+ onValueChange,
2057
+ moveHighlight,
2058
+ highlightValue,
2059
+ selectValue,
2060
+ onListboxKeyDown
2061
+ ]
2062
+ );
2063
+ return /* @__PURE__ */ jsx21(SelectCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx21(
2064
+ "div",
2065
+ {
2066
+ ref: (node) => {
2067
+ rootRef.current = node;
2068
+ if (typeof ref === "function") ref(node);
2069
+ else if (ref) ref.current = node;
2070
+ },
2071
+ className,
2072
+ ...partAttrs17(selectAnatomy.scope, selectAnatomy.root, {
2073
+ state: open ? "open" : "closed"
2074
+ }),
2075
+ children
2076
+ }
2077
+ ) });
2078
+ });
2079
+ var ValueText2 = forwardRef19(function SelectValueText(props, ref) {
2080
+ return /* @__PURE__ */ jsx21("span", { ref, ...partOnlyAttrs11(selectAnatomy.value), ...props });
2081
+ });
2082
+ var Trigger3 = forwardRef19(function SelectTrigger({ children, onClick, onKeyDown, ...rest }, ref) {
2083
+ const { open, send, listboxId, triggerRef, onListboxKeyDown } = useSelectCtx();
2084
+ return /* @__PURE__ */ jsxs3(
2085
+ "button",
2086
+ {
2087
+ ref: (node) => {
2088
+ triggerRef.current = node;
2089
+ if (typeof ref === "function") ref(node);
2090
+ else if (ref) ref.current = node;
2091
+ },
2092
+ type: "button",
2093
+ "aria-haspopup": "listbox",
2094
+ "aria-expanded": open,
2095
+ "aria-controls": open ? listboxId : void 0,
2096
+ ...partAttrs17(selectAnatomy.scope, selectAnatomy.trigger, { state: open ? "open" : "closed" }),
2097
+ ...mergeProps(rest, {
2098
+ onClick: (e) => {
2099
+ onClick?.(e);
2100
+ if (!e.defaultPrevented) send({ type: "TOGGLE" });
2101
+ },
2102
+ onKeyDown: (e) => {
2103
+ onKeyDown?.(e);
2104
+ onListboxKeyDown(e);
2105
+ }
2106
+ }),
2107
+ children: [
2108
+ children,
2109
+ /* @__PURE__ */ jsx21("span", { ...partOnlyAttrs11(selectAnatomy.icon), "aria-hidden": true })
2110
+ ]
2111
+ }
2112
+ );
2113
+ });
2114
+ var Positioner2 = forwardRef19(function SelectPositioner({ portalled = true, children, className, ...rest }, ref) {
2115
+ const { open, triggerRef, positionerRef } = useSelectCtx();
2116
+ return /* @__PURE__ */ jsx21(SelectPositionerCtx.Provider, { value: true, children: /* @__PURE__ */ jsx21(
2117
+ FloatingPositioner,
2118
+ {
2119
+ ref,
2120
+ open,
2121
+ scope: selectAnatomy.scope,
2122
+ part: selectAnatomy.positioner,
2123
+ triggerRef,
2124
+ positionerRef,
2125
+ portalled,
2126
+ matchAnchorWidth: true,
2127
+ className,
2128
+ ...rest,
2129
+ children
2130
+ }
2131
+ ) });
2132
+ });
2133
+ var Content4 = forwardRef19(function SelectContent({ portalled = true, onKeyDown, children, className, ...rest }, ref) {
2134
+ const inPositioner = useContext13(SelectPositionerCtx);
2135
+ const { open, listboxId, contentRef, highlightedValue, onListboxKeyDown, triggerRef, positionerRef } = useSelectCtx();
2136
+ if (!open) return null;
2137
+ const activeId = highlightedValue && open ? `${listboxId}-option-${highlightedValue}` : void 0;
2138
+ const listbox = /* @__PURE__ */ jsx21(
2139
+ "div",
2140
+ {
2141
+ ref: (node) => {
2142
+ contentRef.current = node;
2143
+ if (typeof ref === "function") ref(node);
2144
+ else if (ref) ref.current = node;
2145
+ },
2146
+ id: listboxId,
2147
+ role: "listbox",
2148
+ "aria-activedescendant": activeId,
2149
+ className,
2150
+ "data-aeon-scroll": "",
2151
+ ...partAttrs17(selectAnatomy.scope, selectAnatomy.content, { state: "open" }),
2152
+ ...mergeProps(rest, {
2153
+ onKeyDown: (e) => {
2154
+ onKeyDown?.(e);
2155
+ onListboxKeyDown(e);
2156
+ }
2157
+ }),
2158
+ children
2159
+ }
2160
+ );
2161
+ if (inPositioner) return listbox;
2162
+ return /* @__PURE__ */ jsx21(
2163
+ FloatingPositioner,
2164
+ {
2165
+ open,
2166
+ scope: selectAnatomy.scope,
2167
+ part: selectAnatomy.positioner,
2168
+ triggerRef,
2169
+ positionerRef,
2170
+ portalled,
2171
+ matchAnchorWidth: true,
2172
+ children: listbox
2173
+ }
2174
+ );
2175
+ });
2176
+ var Item3 = forwardRef19(function SelectItem({ value, disabled = false, children, onClick, ...rest }, ref) {
2177
+ const { value: selected, listboxId, highlightedValue, selectValue } = useSelectCtx();
2178
+ const selectedState = value === selected;
2179
+ const highlighted = value === highlightedValue;
2180
+ return /* @__PURE__ */ jsx21(
2181
+ "button",
2182
+ {
2183
+ ref,
2184
+ type: "button",
2185
+ role: "option",
2186
+ id: `${listboxId}-option-${value}`,
2187
+ "aria-selected": selectedState,
2188
+ disabled,
2189
+ ...partAttrs17(selectAnatomy.scope, selectAnatomy.item, {
2190
+ state: selectedState ? "selected" : highlighted ? "highlighted" : "idle",
2191
+ highlighted
2192
+ }),
2193
+ ...mergeProps(rest, {
2194
+ onClick: (e) => {
2195
+ onClick?.(e);
2196
+ if (!e.defaultPrevented && !disabled) selectValue(value);
2197
+ }
2198
+ }),
2199
+ children
2200
+ }
2201
+ );
2202
+ });
2203
+ var Select = {
2204
+ Root: Root14,
2205
+ Trigger: Trigger3,
2206
+ ValueText: ValueText2,
2207
+ Positioner: Positioner2,
2208
+ Content: Content4,
2209
+ Item: Item3
2210
+ };
2211
+
2212
+ // src/combobox/index.tsx
2213
+ import { comboboxAnatomy, partAttrs as partAttrs18, partOnlyAttrs as partOnlyAttrs12 } from "@aeon-ui/core";
2214
+ import {
2215
+ createContext as createContext14,
2216
+ forwardRef as forwardRef20,
2217
+ useCallback as useCallback4,
2218
+ useContext as useContext14,
2219
+ useEffect as useEffect14,
2220
+ useId as useId3,
2221
+ useMemo as useMemo15,
2222
+ useRef as useRef6,
2223
+ useState as useState5
2224
+ } from "react";
2225
+ import { Fragment as Fragment2, jsx as jsx22, jsxs as jsxs4 } from "react/jsx-runtime";
2226
+ var ComboboxCtx = createContext14(null);
2227
+ function useComboboxCtx() {
2228
+ const ctx = useContext14(ComboboxCtx);
2229
+ if (!ctx) throw new Error("Combobox parts must be used within <Combobox.Root>");
2230
+ return ctx;
2231
+ }
2232
+ function normalizeLabel(label, children) {
2233
+ if (label) return label;
2234
+ if (typeof children === "string") return children;
2235
+ return "";
2236
+ }
2237
+ function matchesQuery(label, query) {
2238
+ const q = query.trim().toLowerCase();
2239
+ if (!q) return true;
2240
+ return label.toLowerCase().includes(q);
2241
+ }
2242
+ var Root15 = forwardRef20(function ComboboxRoot({ value, onValueChange, children, className, disabled }, ref) {
2243
+ const [open, setOpenState] = useState5(false);
2244
+ const [query, setQuery] = useState5("");
2245
+ const [highlightedValue, setHighlightedValue] = useState5(null);
2246
+ const [itemsVersion, setItemsVersion] = useState5(0);
2247
+ const itemsRef = useRef6([]);
2248
+ const listboxId = useId3();
2249
+ const setOpen = useCallback4(
2250
+ (next) => {
2251
+ if (disabled) return;
2252
+ setOpenState(next);
2253
+ if (!next) {
2254
+ setQuery("");
2255
+ setHighlightedValue(null);
2256
+ }
2257
+ },
2258
+ [disabled]
2259
+ );
2260
+ const registerItem = useCallback4((item) => {
2261
+ itemsRef.current = [...itemsRef.current.filter((i) => i.value !== item.value), item];
2262
+ setItemsVersion((v) => v + 1);
2263
+ }, []);
2264
+ const unregisterItem = useCallback4((valueKey) => {
2265
+ itemsRef.current = itemsRef.current.filter((i) => i.value !== valueKey);
2266
+ setItemsVersion((v) => v + 1);
2267
+ }, []);
2268
+ const getItems = useCallback4(() => itemsRef.current, []);
2269
+ const ctx = useMemo15(
2270
+ () => ({
2271
+ value,
2272
+ open: disabled ? false : open,
2273
+ query,
2274
+ listboxId,
2275
+ highlightedValue,
2276
+ itemsVersion,
2277
+ setOpen,
2278
+ setQuery,
2279
+ setHighlightedValue,
2280
+ onValueChange,
2281
+ registerItem,
2282
+ unregisterItem,
2283
+ getItems
2284
+ }),
2285
+ [
2286
+ value,
2287
+ open,
2288
+ query,
2289
+ listboxId,
2290
+ highlightedValue,
2291
+ itemsVersion,
2292
+ setOpen,
2293
+ onValueChange,
2294
+ registerItem,
2295
+ unregisterItem,
2296
+ getItems,
2297
+ disabled
2298
+ ]
2299
+ );
2300
+ return /* @__PURE__ */ jsx22(ComboboxCtx.Provider, { value: ctx, children: /* @__PURE__ */ jsx22(
2301
+ "div",
2302
+ {
2303
+ ref,
2304
+ className,
2305
+ ...partAttrs18(comboboxAnatomy.scope, comboboxAnatomy.root, {
2306
+ state: open ? "open" : "closed"
2307
+ }),
2308
+ children
2309
+ }
2310
+ ) });
2311
+ });
2312
+ function useVisibleItems() {
2313
+ const { query, getItems, itemsVersion } = useComboboxCtx();
2314
+ return useMemo15(() => {
2315
+ void itemsVersion;
2316
+ return getItems().filter((i) => matchesQuery(i.label, query));
2317
+ }, [query, getItems, itemsVersion]);
2318
+ }
2319
+ var Input2 = forwardRef20(function ComboboxInput({ onChange, onKeyDown, onFocus, onClick, value: valueProp, ...rest }, ref) {
2320
+ const {
2321
+ value: selected,
2322
+ open,
2323
+ query,
2324
+ listboxId,
2325
+ highlightedValue,
2326
+ itemsVersion,
2327
+ setOpen,
2328
+ setQuery,
2329
+ setHighlightedValue,
2330
+ onValueChange,
2331
+ getItems
2332
+ } = useComboboxCtx();
2333
+ const inputRef = useRef6(null);
2334
+ const visible = useVisibleItems();
2335
+ const selectedLabel = useMemo15(() => {
2336
+ void itemsVersion;
2337
+ return getItems().find((i) => i.value === selected)?.label ?? "";
2338
+ }, [getItems, selected, itemsVersion]);
2339
+ const displayValue = open ? query : selectedLabel;
2340
+ const selectValue = useCallback4(
2341
+ (next) => {
2342
+ onValueChange?.(next);
2343
+ setOpen(false);
2344
+ setQuery("");
2345
+ setHighlightedValue(null);
2346
+ },
2347
+ [onValueChange, setOpen, setQuery, setHighlightedValue]
2348
+ );
2349
+ const moveHighlight = useCallback4(
2350
+ (delta) => {
2351
+ if (visible.length === 0) {
2352
+ setHighlightedValue(null);
2353
+ return;
2354
+ }
2355
+ const idx = highlightedValue ? visible.findIndex((i) => i.value === highlightedValue) : -1;
2356
+ let next = idx + delta;
2357
+ if (next < 0) next = visible.length - 1;
2358
+ if (next >= visible.length) next = 0;
2359
+ setHighlightedValue(visible[next].value);
2360
+ },
2361
+ [visible, highlightedValue, setHighlightedValue]
2362
+ );
2363
+ const setRefs = useCallback4(
2364
+ (node) => {
2365
+ inputRef.current = node;
2366
+ if (typeof ref === "function") ref(node);
2367
+ else if (ref) ref.current = node;
2368
+ },
2369
+ [ref]
2370
+ );
2371
+ useEffect14(() => {
2372
+ if (!open) return;
2373
+ const onPointerDown = (e) => {
2374
+ const root = inputRef.current?.closest('[data-aeon-scope="combobox"]');
2375
+ if (root && !root.contains(e.target)) setOpen(false);
2376
+ };
2377
+ const onKey = (e) => {
2378
+ if (e.key === "Escape") setOpen(false);
2379
+ };
2380
+ document.addEventListener("pointerdown", onPointerDown);
2381
+ document.addEventListener("keydown", onKey);
2382
+ return () => {
2383
+ document.removeEventListener("pointerdown", onPointerDown);
2384
+ document.removeEventListener("keydown", onKey);
2385
+ };
2386
+ }, [open, setOpen]);
2387
+ const activeDescendant = highlightedValue && open ? `${listboxId}-option-${highlightedValue}` : void 0;
2388
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
2389
+ /* @__PURE__ */ jsx22(
2390
+ "input",
2391
+ {
2392
+ ref: setRefs,
2393
+ type: "text",
2394
+ role: "combobox",
2395
+ "aria-autocomplete": "list",
2396
+ "aria-expanded": open,
2397
+ "aria-controls": open ? listboxId : void 0,
2398
+ "aria-activedescendant": activeDescendant,
2399
+ autoComplete: "off",
2400
+ value: valueProp ?? displayValue,
2401
+ ...partAttrs18(comboboxAnatomy.scope, comboboxAnatomy.input, { state: open ? "open" : "closed" }),
2402
+ ...mergeProps(rest, {
2403
+ onFocus: (e) => {
2404
+ onFocus?.(e);
2405
+ setOpen(true);
2406
+ },
2407
+ onClick: (e) => {
2408
+ onClick?.(e);
2409
+ setOpen(true);
2410
+ },
2411
+ onChange: (e) => {
2412
+ onChange?.(e);
2413
+ if (!e.defaultPrevented) {
2414
+ setOpen(true);
2415
+ setQuery(e.target.value);
2416
+ setHighlightedValue(null);
2417
+ }
2418
+ },
2419
+ onKeyDown: (e) => {
2420
+ onKeyDown?.(e);
2421
+ if (e.defaultPrevented) return;
2422
+ if (e.key === "ArrowDown") {
2423
+ e.preventDefault();
2424
+ if (!open) setOpen(true);
2425
+ else moveHighlight(1);
2426
+ }
2427
+ if (e.key === "ArrowUp") {
2428
+ e.preventDefault();
2429
+ if (!open) setOpen(true);
2430
+ else moveHighlight(-1);
2431
+ }
2432
+ if (e.key === "Home" && open) {
2433
+ e.preventDefault();
2434
+ if (visible[0]) setHighlightedValue(visible[0].value);
2435
+ }
2436
+ if (e.key === "End" && open) {
2437
+ e.preventDefault();
2438
+ if (visible[visible.length - 1]) setHighlightedValue(visible[visible.length - 1].value);
2439
+ }
2440
+ if (e.key === "Enter") {
2441
+ e.preventDefault();
2442
+ const pick = highlightedValue ?? visible[0]?.value;
2443
+ if (pick) selectValue(pick);
2444
+ }
2445
+ if (e.key === "Escape") setOpen(false);
2446
+ }
2447
+ })
2448
+ }
2449
+ ),
2450
+ /* @__PURE__ */ jsx22(
2451
+ "span",
2452
+ {
2453
+ ...partOnlyAttrs12(comboboxAnatomy.icon, { state: open ? "open" : "closed" }),
2454
+ "aria-hidden": true,
2455
+ style: open ? { transform: "rotate(-135deg) translateY(2px)" } : void 0
2456
+ }
2457
+ )
2458
+ ] });
2459
+ });
2460
+ var Content5 = forwardRef20(function ComboboxContent({ children, className, ...rest }, ref) {
2461
+ const { open, listboxId } = useComboboxCtx();
2462
+ if (!open) return null;
2463
+ return /* @__PURE__ */ jsx22(
2464
+ "div",
2465
+ {
2466
+ ref,
2467
+ id: listboxId,
2468
+ role: "listbox",
2469
+ className,
2470
+ "data-aeon-scroll": "",
2471
+ ...partAttrs18(comboboxAnatomy.scope, comboboxAnatomy.content),
2472
+ ...rest,
2473
+ children
2474
+ }
2475
+ );
2476
+ });
2477
+ var Item4 = forwardRef20(function ComboboxItem({ value, textValue, children, onClick, ...rest }, ref) {
2478
+ const {
2479
+ value: selected,
2480
+ query,
2481
+ highlightedValue,
2482
+ listboxId,
2483
+ onValueChange,
2484
+ setOpen,
2485
+ setHighlightedValue,
2486
+ registerItem,
2487
+ unregisterItem
2488
+ } = useComboboxCtx();
2489
+ const label = normalizeLabel(textValue, children);
2490
+ const resolvedOptionId = `${listboxId}-option-${value}`;
2491
+ useEffect14(() => {
2492
+ registerItem({ value, label });
2493
+ return () => unregisterItem(value);
2494
+ }, [value, label, registerItem, unregisterItem]);
2495
+ if (!matchesQuery(label, query)) return null;
2496
+ const selectedState = value === selected;
2497
+ const highlighted = value === highlightedValue;
2498
+ return /* @__PURE__ */ jsx22(
2499
+ "button",
2500
+ {
2501
+ ref,
2502
+ type: "button",
2503
+ role: "option",
2504
+ id: resolvedOptionId,
2505
+ "aria-selected": selectedState,
2506
+ "data-highlighted": highlighted ? "" : void 0,
2507
+ ...partAttrs18(comboboxAnatomy.scope, comboboxAnatomy.item, {
2508
+ state: selectedState ? "selected" : "idle",
2509
+ highlighted
2510
+ }),
2511
+ ...mergeProps(rest, {
2512
+ onClick: (e) => {
2513
+ onClick?.(e);
2514
+ if (!e.defaultPrevented) {
2515
+ onValueChange?.(value);
2516
+ setOpen(false);
2517
+ }
2518
+ },
2519
+ onMouseEnter: () => setHighlightedValue(value)
2520
+ }),
2521
+ children
2522
+ }
2523
+ );
2524
+ });
2525
+ var Empty = forwardRef20(function ComboboxEmpty({ children, className, ...rest }, ref) {
2526
+ const { open, query } = useComboboxCtx();
2527
+ const visible = useVisibleItems();
2528
+ if (!open || !query.trim() || visible.length > 0) return null;
2529
+ return /* @__PURE__ */ jsx22(
2530
+ "div",
2531
+ {
2532
+ ref,
2533
+ className,
2534
+ ...partAttrs18(comboboxAnatomy.scope, comboboxAnatomy.empty),
2535
+ ...rest,
2536
+ children: children ?? "No results"
2537
+ }
2538
+ );
2539
+ });
2540
+ var Combobox = {
2541
+ Root: Root15,
2542
+ Input: Input2,
2543
+ Content: Content5,
2544
+ Item: Item4,
2545
+ Empty
2546
+ };
2547
+
2548
+ // src/popover/index.tsx
2549
+ import { popoverAnatomy, partAttrs as partAttrs19 } from "@aeon-ui/core";
2550
+ import { popoverMachine as popoverMachine2 } from "@aeon-ui/primitives";
2551
+ import {
2552
+ createContext as createContext15,
2553
+ forwardRef as forwardRef21,
2554
+ useCallback as useCallback5,
2555
+ useContext as useContext15,
2556
+ useEffect as useEffect15,
2557
+ useId as useId4,
2558
+ useMemo as useMemo16,
2559
+ useRef as useRef7
2560
+ } from "react";
2561
+ import { jsx as jsx23 } from "react/jsx-runtime";
2562
+ var PopoverCtx = createContext15(null);
2563
+ function usePopoverCtx() {
2564
+ const ctx = useContext15(PopoverCtx);
2565
+ if (!ctx) throw new Error("Popover parts must be used within Popover.Root");
2566
+ return ctx;
2567
+ }
2568
+ var Root16 = forwardRef21(function PopoverRoot({ open, defaultOpen = false, onOpenChange, children, className, ...rest }, ref) {
2569
+ const [snapshot, send] = useAeonMachine(popoverMachine2, {
2570
+ input: { open: defaultOpen }
2571
+ });
2572
+ const resolvedOpen = open ?? snapshot.context.open;
2573
+ const rootRef = useRef7(null);
2574
+ const triggerRef = useRef7(null);
2575
+ const positionerRef = useRef7(null);
2576
+ const triggerId = useId4();
2577
+ const contentId = useId4();
2578
+ useEffect15(() => {
2579
+ onOpenChange?.(resolvedOpen);
2580
+ }, [resolvedOpen, onOpenChange]);
2581
+ useEffect15(() => {
2582
+ if (open !== void 0) send({ type: "SET_OPEN", open });
2583
+ }, [open, send]);
2584
+ const close = useCallback5(() => send({ type: "CLOSE" }), [send]);
2585
+ useOutsideClick([rootRef, positionerRef], resolvedOpen, close);
2586
+ const value = useMemo16(
2587
+ () => ({ open: resolvedOpen, send, triggerId, contentId, triggerRef, positionerRef }),
2588
+ [resolvedOpen, send, triggerId, contentId]
2589
+ );
2590
+ return /* @__PURE__ */ jsx23(PopoverCtx.Provider, { value, children: /* @__PURE__ */ jsx23(
2591
+ "div",
2592
+ {
2593
+ ref: (node) => {
2594
+ rootRef.current = node;
2595
+ if (typeof ref === "function") ref(node);
2596
+ else if (ref) ref.current = node;
2597
+ },
2598
+ className,
2599
+ ...mergeProps(
2600
+ partAttrs19(popoverAnatomy.scope, popoverAnatomy.root, {
2601
+ state: resolvedOpen ? "open" : "closed"
2602
+ }),
2603
+ rest
2604
+ ),
2605
+ children
2606
+ }
2607
+ ) });
2608
+ });
2609
+ var Trigger4 = forwardRef21(function PopoverTrigger({ onClick, ...rest }, ref) {
2610
+ const { open, send, triggerId, contentId, triggerRef } = usePopoverCtx();
2611
+ return /* @__PURE__ */ jsx23(
2612
+ "button",
2613
+ {
2614
+ ref: (node) => {
2615
+ triggerRef.current = node;
2616
+ if (typeof ref === "function") ref(node);
2617
+ else if (ref) ref.current = node;
2618
+ },
2619
+ type: "button",
2620
+ id: triggerId,
2621
+ "aria-expanded": open,
2622
+ "aria-controls": open ? contentId : void 0,
2623
+ ...mergeProps(
2624
+ partAttrs19(popoverAnatomy.scope, popoverAnatomy.trigger, { state: open ? "open" : "closed" }),
2625
+ {
2626
+ onClick: (e) => {
2627
+ onClick?.(e);
2628
+ if (!e.defaultPrevented) send({ type: "TOGGLE" });
2629
+ }
2630
+ },
2631
+ rest
2632
+ )
2633
+ }
2634
+ );
2635
+ });
2636
+ var Positioner3 = forwardRef21(function PopoverPositioner({ portalled = true, placement = "bottom-start", children, className, ...rest }, ref) {
2637
+ const { open, triggerRef, positionerRef } = usePopoverCtx();
2638
+ return /* @__PURE__ */ jsx23(
2639
+ FloatingPositioner,
2640
+ {
2641
+ ref,
2642
+ open,
2643
+ scope: popoverAnatomy.scope,
2644
+ part: popoverAnatomy.positioner,
2645
+ triggerRef,
2646
+ positionerRef,
2647
+ portalled,
2648
+ placement,
2649
+ className,
2650
+ ...rest,
2651
+ children
2652
+ }
2653
+ );
2654
+ });
2655
+ var Content6 = forwardRef21(function PopoverContent({ onKeyDown, ...rest }, ref) {
2656
+ const { open, send, triggerId, contentId } = usePopoverCtx();
2657
+ if (!open) return null;
2658
+ return /* @__PURE__ */ jsx23(
2659
+ "div",
2660
+ {
2661
+ ref,
2662
+ id: contentId,
2663
+ role: "dialog",
2664
+ "aria-modal": false,
2665
+ "aria-labelledby": triggerId,
2666
+ ...mergeProps(
2667
+ partAttrs19(popoverAnatomy.scope, popoverAnatomy.content, { state: "open" }),
2668
+ {
2669
+ onKeyDown: (e) => {
2670
+ onKeyDown?.(e);
2671
+ if (e.key === "Escape") send({ type: "ESCAPE" });
2672
+ }
2673
+ },
2674
+ rest
2675
+ )
2676
+ }
2677
+ );
2678
+ });
2679
+ var Arrow = forwardRef21(function PopoverArrow(props, ref) {
2680
+ const { open } = usePopoverCtx();
2681
+ if (!open) return null;
2682
+ return /* @__PURE__ */ jsx23("div", { ref, ...mergeProps(partAttrs19(popoverAnatomy.scope, popoverAnatomy.arrow), props) });
2683
+ });
2684
+ var CloseTrigger2 = forwardRef21(
2685
+ function PopoverCloseTrigger({ onClick, ...rest }, ref) {
2686
+ const { send } = usePopoverCtx();
2687
+ return /* @__PURE__ */ jsx23(
2688
+ "button",
2689
+ {
2690
+ ref,
2691
+ type: "button",
2692
+ "aria-label": "Close",
2693
+ ...mergeProps(
2694
+ partAttrs19(popoverAnatomy.scope, popoverAnatomy.closeTrigger),
2695
+ {
2696
+ onClick: (e) => {
2697
+ onClick?.(e);
2698
+ send({ type: "CLOSE" });
2699
+ }
2700
+ },
2701
+ rest
2702
+ )
2703
+ }
2704
+ );
2705
+ }
2706
+ );
2707
+ var Popover = { Root: Root16, Trigger: Trigger4, Positioner: Positioner3, Content: Content6, Arrow, CloseTrigger: CloseTrigger2 };
2708
+
2709
+ // src/menu/index.tsx
2710
+ import { menuAnatomy, partAttrs as partAttrs20 } from "@aeon-ui/core";
2711
+ import { popoverMachine as popoverMachine3 } from "@aeon-ui/primitives";
2712
+ import {
2713
+ createContext as createContext16,
2714
+ forwardRef as forwardRef22,
2715
+ useCallback as useCallback6,
2716
+ useContext as useContext16,
2717
+ useEffect as useEffect16,
2718
+ useId as useId5,
2719
+ useMemo as useMemo17,
2720
+ useRef as useRef8
2721
+ } from "react";
2722
+ import { jsx as jsx24 } from "react/jsx-runtime";
2723
+ var MenuCtx = createContext16(null);
2724
+ function useMenuCtx() {
2725
+ const ctx = useContext16(MenuCtx);
2726
+ if (!ctx) throw new Error("Menu parts must be used within Menu.Root");
2727
+ return ctx;
2728
+ }
2729
+ var Root17 = forwardRef22(function MenuRoot({ open, defaultOpen = false, onOpenChange, children, className, ...rest }, ref) {
2730
+ const [snapshot, send] = useAeonMachine(popoverMachine3, { input: { open: defaultOpen } });
2731
+ const resolvedOpen = open ?? snapshot.context.open;
2732
+ const rootRef = useRef8(null);
2733
+ const triggerRef = useRef8(null);
2734
+ const positionerRef = useRef8(null);
2735
+ const triggerId = useId5();
2736
+ const menuId = useId5();
2737
+ useEffect16(() => {
2738
+ onOpenChange?.(resolvedOpen);
2739
+ }, [resolvedOpen, onOpenChange]);
2740
+ useEffect16(() => {
2741
+ if (open !== void 0) send({ type: "SET_OPEN", open });
2742
+ }, [open, send]);
2743
+ const close = useCallback6(() => send({ type: "CLOSE" }), [send]);
2744
+ useOutsideClick([rootRef, positionerRef], resolvedOpen, close);
2745
+ const value = useMemo17(
2746
+ () => ({ open: resolvedOpen, send, triggerId, menuId, triggerRef, positionerRef }),
2747
+ [resolvedOpen, send, triggerId, menuId]
2748
+ );
2749
+ return /* @__PURE__ */ jsx24(MenuCtx.Provider, { value, children: /* @__PURE__ */ jsx24(
2750
+ "div",
2751
+ {
2752
+ ref: (node) => {
2753
+ rootRef.current = node;
2754
+ if (typeof ref === "function") ref(node);
2755
+ else if (ref) ref.current = node;
2756
+ },
2757
+ className,
2758
+ ...mergeProps(
2759
+ partAttrs20(menuAnatomy.scope, menuAnatomy.root, { state: resolvedOpen ? "open" : "closed" }),
2760
+ rest
2761
+ ),
2762
+ children
2763
+ }
2764
+ ) });
2765
+ });
2766
+ var Trigger5 = forwardRef22(function MenuTrigger({ onClick, ...rest }, ref) {
2767
+ const { open, send, triggerId, menuId, triggerRef } = useMenuCtx();
2768
+ return /* @__PURE__ */ jsx24(
2769
+ "button",
2770
+ {
2771
+ ref: (node) => {
2772
+ triggerRef.current = node;
2773
+ if (typeof ref === "function") ref(node);
2774
+ else if (ref) ref.current = node;
2775
+ },
2776
+ type: "button",
2777
+ id: triggerId,
2778
+ "aria-haspopup": "menu",
2779
+ "aria-expanded": open,
2780
+ "aria-controls": open ? menuId : void 0,
2781
+ ...mergeProps(
2782
+ partAttrs20(menuAnatomy.scope, menuAnatomy.trigger, { state: open ? "open" : "closed" }),
2783
+ {
2784
+ onClick: (e) => {
2785
+ onClick?.(e);
2786
+ if (!e.defaultPrevented) send({ type: "TOGGLE" });
2787
+ }
2788
+ },
2789
+ rest
2790
+ )
2791
+ }
2792
+ );
2793
+ });
2794
+ var Positioner4 = forwardRef22(function MenuPositioner({ portalled = true, placement = "bottom-start", children, className, ...rest }, ref) {
2795
+ const { open, triggerRef, positionerRef } = useMenuCtx();
2796
+ return /* @__PURE__ */ jsx24(
2797
+ FloatingPositioner,
2798
+ {
2799
+ ref,
2800
+ open,
2801
+ scope: menuAnatomy.scope,
2802
+ part: menuAnatomy.positioner,
2803
+ triggerRef,
2804
+ positionerRef,
2805
+ portalled,
2806
+ placement,
2807
+ className,
2808
+ ...rest,
2809
+ children
2810
+ }
2811
+ );
2812
+ });
2813
+ var Content7 = forwardRef22(function MenuContent({ onKeyDown, ...rest }, ref) {
2814
+ const { open, send, menuId } = useMenuCtx();
2815
+ if (!open) return null;
2816
+ return /* @__PURE__ */ jsx24(
2817
+ "div",
2818
+ {
2819
+ ref,
2820
+ id: menuId,
2821
+ role: "menu",
2822
+ ...mergeProps(
2823
+ partAttrs20(menuAnatomy.scope, menuAnatomy.content, { state: "open" }),
2824
+ {
2825
+ onKeyDown: (e) => {
2826
+ onKeyDown?.(e);
2827
+ if (e.key === "Escape") send({ type: "ESCAPE" });
2828
+ }
2829
+ },
2830
+ rest
2831
+ )
2832
+ }
2833
+ );
2834
+ });
2835
+ var Item5 = forwardRef22(function MenuItem({ closeOnSelect = true, onClick, ...rest }, ref) {
2836
+ const { send } = useMenuCtx();
2837
+ return /* @__PURE__ */ jsx24(
2838
+ "button",
2839
+ {
2840
+ ref,
2841
+ type: "button",
2842
+ role: "menuitem",
2843
+ ...mergeProps(
2844
+ partAttrs20(menuAnatomy.scope, menuAnatomy.item),
2845
+ {
2846
+ onClick: (e) => {
2847
+ onClick?.(e);
2848
+ if (closeOnSelect && !e.defaultPrevented) send({ type: "CLOSE" });
2849
+ }
2850
+ },
2851
+ rest
2852
+ )
2853
+ }
2854
+ );
2855
+ });
2856
+ var Separator2 = forwardRef22(function MenuSeparator(props, ref) {
2857
+ return /* @__PURE__ */ jsx24("div", { ref, role: "separator", ...mergeProps(partAttrs20(menuAnatomy.scope, menuAnatomy.separator), props) });
2858
+ });
2859
+ var Menu = { Root: Root17, Trigger: Trigger5, Positioner: Positioner4, Content: Content7, Item: Item5, Separator: Separator2 };
2860
+
2861
+ // src/tooltip/index.tsx
2862
+ import { tooltipAnatomy, partAttrs as partAttrs21 } from "@aeon-ui/core";
2863
+ import {
2864
+ createContext as createContext17,
2865
+ forwardRef as forwardRef23,
2866
+ useContext as useContext17,
2867
+ useEffect as useEffect18,
2868
+ useId as useId6,
2869
+ useMemo as useMemo18,
2870
+ useRef as useRef9,
2871
+ useState as useState7
2872
+ } from "react";
2873
+
2874
+ // src/hooks/use-prefers-hover.ts
2875
+ import { useEffect as useEffect17, useState as useState6 } from "react";
2876
+ function usePrefersHover() {
2877
+ const [prefersHover, setPrefersHover] = useState6(true);
2878
+ useEffect17(() => {
2879
+ const mq = window.matchMedia("(hover: hover) and (pointer: fine)");
2880
+ const update = () => setPrefersHover(mq.matches);
2881
+ update();
2882
+ mq.addEventListener("change", update);
2883
+ return () => mq.removeEventListener("change", update);
2884
+ }, []);
2885
+ return prefersHover;
2886
+ }
2887
+
2888
+ // src/tooltip/index.tsx
2889
+ import { jsx as jsx25 } from "react/jsx-runtime";
2890
+ var TooltipCtx = createContext17(null);
2891
+ function useTooltipCtx() {
2892
+ const ctx = useContext17(TooltipCtx);
2893
+ if (!ctx) throw new Error("Tooltip parts must be used within Tooltip.Root");
2894
+ return ctx;
2895
+ }
2896
+ var Root18 = forwardRef23(function TooltipRoot({
2897
+ open,
2898
+ defaultOpen = false,
2899
+ onOpenChange,
2900
+ openDelay = 400,
2901
+ closeDelay = 100,
2902
+ touchDurationMs = 5e3,
2903
+ touchOutsideGraceMs = 400,
2904
+ showOnFocus = true,
2905
+ children,
2906
+ className,
2907
+ ...rest
2908
+ }, ref) {
2909
+ const [uncontrolled, setUncontrolled] = useState7(defaultOpen);
2910
+ const resolvedOpen = open ?? uncontrolled;
2911
+ const showTimer = useRef9(void 0);
2912
+ const hideTimer = useRef9(void 0);
2913
+ const triggerRef = useRef9(null);
2914
+ const positionerRef = useRef9(null);
2915
+ const triggerId = useId6();
2916
+ const contentId = useId6();
2917
+ const prefersHover = usePrefersHover();
2918
+ const [outsideClickEnabled, setOutsideClickEnabled] = useState7(false);
2919
+ useEffect18(() => {
2920
+ if (!resolvedOpen || prefersHover) {
2921
+ setOutsideClickEnabled(false);
2922
+ return;
2923
+ }
2924
+ setOutsideClickEnabled(false);
2925
+ const id = window.setTimeout(() => setOutsideClickEnabled(true), touchOutsideGraceMs);
2926
+ return () => window.clearTimeout(id);
2927
+ }, [resolvedOpen, prefersHover, touchOutsideGraceMs]);
2928
+ const setOpen = (next) => {
2929
+ if (open === void 0) setUncontrolled(next);
2930
+ onOpenChange?.(next);
2931
+ };
2932
+ useEffect18(() => {
2933
+ onOpenChange?.(resolvedOpen);
2934
+ }, [resolvedOpen, onOpenChange]);
2935
+ const hideNow = () => {
2936
+ if (showTimer.current !== void 0) clearTimeout(showTimer.current);
2937
+ if (hideTimer.current !== void 0) clearTimeout(hideTimer.current);
2938
+ setOpen(false);
2939
+ };
2940
+ const showImmediately = () => {
2941
+ if (showTimer.current !== void 0) clearTimeout(showTimer.current);
2942
+ if (hideTimer.current !== void 0) clearTimeout(hideTimer.current);
2943
+ setOpen(true);
2944
+ if (!prefersHover) {
2945
+ if (touchDurationMs > 0) {
2946
+ hideTimer.current = setTimeout(() => hideNow(), touchDurationMs);
2947
+ }
2948
+ }
2949
+ };
2950
+ const scheduleShow = () => {
2951
+ if (hideTimer.current !== void 0) clearTimeout(hideTimer.current);
2952
+ showTimer.current = setTimeout(() => setOpen(true), openDelay);
2953
+ };
2954
+ const scheduleHide = () => {
2955
+ if (showTimer.current !== void 0) clearTimeout(showTimer.current);
2956
+ if (closeDelay <= 0) {
2957
+ setOpen(false);
2958
+ return;
2959
+ }
2960
+ hideTimer.current = setTimeout(() => setOpen(false), closeDelay);
2961
+ };
2962
+ const toggleTouch = () => {
2963
+ if (resolvedOpen) hideNow();
2964
+ else showImmediately();
2965
+ };
2966
+ useOutsideClick([triggerRef, positionerRef], resolvedOpen && !prefersHover && outsideClickEnabled, hideNow);
2967
+ const value = useMemo18(
2968
+ () => ({
2969
+ open: resolvedOpen,
2970
+ setOpen,
2971
+ triggerId,
2972
+ contentId,
2973
+ triggerRef,
2974
+ positionerRef,
2975
+ scheduleShow,
2976
+ scheduleHide,
2977
+ showImmediately,
2978
+ hideNow,
2979
+ toggleTouch,
2980
+ showOnFocus,
2981
+ prefersHover
2982
+ }),
2983
+ [resolvedOpen, triggerId, contentId, openDelay, closeDelay, touchDurationMs, touchOutsideGraceMs, showOnFocus, prefersHover]
2984
+ );
2985
+ return /* @__PURE__ */ jsx25(TooltipCtx.Provider, { value, children: /* @__PURE__ */ jsx25(
2986
+ "div",
2987
+ {
2988
+ ref,
2989
+ className,
2990
+ ...mergeProps(
2991
+ partAttrs21(tooltipAnatomy.scope, tooltipAnatomy.root, {
2992
+ state: resolvedOpen ? "open" : "closed"
2993
+ }),
2994
+ rest
2995
+ ),
2996
+ children
2997
+ }
2998
+ ) });
2999
+ });
3000
+ var Trigger6 = forwardRef23(function TooltipTrigger({ onClick, onMouseEnter, onMouseLeave, onFocus, onBlur, onPointerDown, ...rest }, ref) {
3001
+ const {
3002
+ open,
3003
+ triggerId,
3004
+ contentId,
3005
+ triggerRef,
3006
+ scheduleShow,
3007
+ scheduleHide,
3008
+ hideNow,
3009
+ toggleTouch,
3010
+ showOnFocus,
3011
+ prefersHover
3012
+ } = useTooltipCtx();
3013
+ return /* @__PURE__ */ jsx25(
3014
+ "span",
3015
+ {
3016
+ ref: (node) => {
3017
+ triggerRef.current = node;
3018
+ if (typeof ref === "function") ref(node);
3019
+ else if (ref) ref.current = node;
3020
+ },
3021
+ id: triggerId,
3022
+ tabIndex: 0,
3023
+ "aria-describedby": open ? contentId : void 0,
3024
+ ...mergeProps(
3025
+ partAttrs21(tooltipAnatomy.scope, tooltipAnatomy.trigger, { state: open ? "open" : "closed" }),
3026
+ {
3027
+ onMouseEnter: (e) => {
3028
+ onMouseEnter?.(e);
3029
+ if (prefersHover) scheduleShow();
3030
+ },
3031
+ onMouseLeave: (e) => {
3032
+ onMouseLeave?.(e);
3033
+ if (prefersHover) scheduleHide();
3034
+ },
3035
+ onFocus: (e) => {
3036
+ onFocus?.(e);
3037
+ if (showOnFocus && prefersHover) scheduleShow();
3038
+ },
3039
+ onBlur: (e) => {
3040
+ onBlur?.(e);
3041
+ if (showOnFocus && prefersHover) scheduleHide();
3042
+ },
3043
+ onClick: (e) => {
3044
+ onClick?.(e);
3045
+ if (!e.defaultPrevented && !prefersHover) toggleTouch();
3046
+ },
3047
+ onPointerDown: (e) => {
3048
+ onPointerDown?.(e);
3049
+ if (showOnFocus && prefersHover && e.pointerType === "mouse") hideNow();
3050
+ }
3051
+ },
3052
+ rest
3053
+ )
3054
+ }
3055
+ );
3056
+ });
3057
+ var Positioner5 = forwardRef23(function TooltipPositioner({ portalled = true, placement = "top-start", children, className, ...rest }, ref) {
3058
+ const { open, triggerRef, positionerRef } = useTooltipCtx();
3059
+ return /* @__PURE__ */ jsx25(
3060
+ FloatingPositioner,
3061
+ {
3062
+ ref,
3063
+ open,
3064
+ scope: tooltipAnatomy.scope,
3065
+ part: tooltipAnatomy.positioner,
3066
+ triggerRef,
3067
+ positionerRef,
3068
+ portalled,
3069
+ placement,
3070
+ className,
3071
+ ...rest,
3072
+ children
3073
+ }
3074
+ );
3075
+ });
3076
+ var Content8 = forwardRef23(function TooltipContent(props, ref) {
3077
+ const { open, contentId } = useTooltipCtx();
3078
+ if (!open) return null;
3079
+ return /* @__PURE__ */ jsx25(
3080
+ "div",
3081
+ {
3082
+ ref,
3083
+ id: contentId,
3084
+ role: "tooltip",
3085
+ ...mergeProps(partAttrs21(tooltipAnatomy.scope, tooltipAnatomy.content, { state: "open" }), props)
3086
+ }
3087
+ );
3088
+ });
3089
+ var Arrow2 = forwardRef23(function TooltipArrow(props, ref) {
3090
+ const { open } = useTooltipCtx();
3091
+ if (!open) return null;
3092
+ return /* @__PURE__ */ jsx25("div", { ref, ...mergeProps(partAttrs21(tooltipAnatomy.scope, tooltipAnatomy.arrow), props) });
3093
+ });
3094
+ var Tooltip = { Root: Root18, Trigger: Trigger6, Positioner: Positioner5, Content: Content8, Arrow: Arrow2 };
3095
+
3096
+ // src/toast/primitives.tsx
3097
+ import { toastAnatomy, partAttrs as partAttrs22 } from "@aeon-ui/core";
3098
+ import { toastMachine } from "@aeon-ui/primitives";
3099
+ import {
3100
+ createContext as createContext18,
3101
+ forwardRef as forwardRef24,
3102
+ useContext as useContext18,
3103
+ useEffect as useEffect19,
3104
+ useId as useId7,
3105
+ useMemo as useMemo19,
3106
+ useRef as useRef10
3107
+ } from "react";
3108
+ import { jsx as jsx26 } from "react/jsx-runtime";
3109
+ var ToastCtx = createContext18(null);
3110
+ function useToastCtx() {
3111
+ const ctx = useContext18(ToastCtx);
3112
+ if (!ctx) throw new Error("Toast parts must be used within Toast.Root");
3113
+ return ctx;
3114
+ }
3115
+ var Root19 = forwardRef24(function ToastRoot({ durationMs = 5e3, defaultVisible = false, onVisibleChange, children, className, ...rest }, ref) {
3116
+ const [snapshot, send] = useAeonMachine(toastMachine, { input: { durationMs } });
3117
+ const visible = snapshot.matches("visible");
3118
+ const titleId = useId7();
3119
+ const hasBeenVisible = useRef10(false);
3120
+ useEffect19(() => {
3121
+ if (defaultVisible) send({ type: "SHOW" });
3122
+ }, [defaultVisible, send]);
3123
+ useEffect19(() => {
3124
+ if (visible) {
3125
+ hasBeenVisible.current = true;
3126
+ onVisibleChange?.(true);
3127
+ return;
3128
+ }
3129
+ if (hasBeenVisible.current) onVisibleChange?.(false);
3130
+ }, [visible, onVisibleChange]);
3131
+ const value = useMemo19(() => ({ visible, send, titleId }), [visible, send, titleId]);
3132
+ return /* @__PURE__ */ jsx26(ToastCtx.Provider, { value, children: /* @__PURE__ */ jsx26(
3133
+ "div",
3134
+ {
3135
+ ref,
3136
+ role: "status",
3137
+ "aria-live": "polite",
3138
+ "aria-atomic": "true",
3139
+ ...mergeProps(
3140
+ partAttrs22(toastAnatomy.scope, toastAnatomy.root, { state: visible ? "visible" : "hidden" }),
3141
+ rest
3142
+ ),
3143
+ className,
3144
+ hidden: !visible,
3145
+ children: visible ? children : null
3146
+ }
3147
+ ) });
3148
+ });
3149
+ var Title2 = forwardRef24(function ToastTitle(props, ref) {
3150
+ const { titleId } = useToastCtx();
3151
+ return /* @__PURE__ */ jsx26("p", { ref, id: titleId, ...mergeProps(partAttrs22(toastAnatomy.scope, toastAnatomy.title), props) });
3152
+ });
3153
+ var Description2 = forwardRef24(
3154
+ function ToastDescription(props, ref) {
3155
+ return /* @__PURE__ */ jsx26("p", { ref, ...mergeProps(partAttrs22(toastAnatomy.scope, toastAnatomy.description), props) });
3156
+ }
3157
+ );
3158
+ var CloseTrigger3 = forwardRef24(
3159
+ function ToastCloseTrigger({ onClick, children, ...rest }, ref) {
3160
+ const { send } = useToastCtx();
3161
+ return /* @__PURE__ */ jsx26(
3162
+ "button",
3163
+ {
3164
+ ref,
3165
+ type: "button",
3166
+ "aria-label": typeof children === "string" ? void 0 : "Dismiss",
3167
+ ...mergeProps(
3168
+ partAttrs22(toastAnatomy.scope, toastAnatomy.closeTrigger),
3169
+ {
3170
+ onClick: (e) => {
3171
+ onClick?.(e);
3172
+ send({ type: "DISMISS" });
3173
+ }
3174
+ },
3175
+ rest
3176
+ ),
3177
+ children: children ?? "Dismiss"
3178
+ }
3179
+ );
3180
+ }
3181
+ );
3182
+ function Show({ durationMs }) {
3183
+ const { send } = useToastCtx();
3184
+ useEffect19(() => {
3185
+ send({ type: "SHOW" });
3186
+ if (durationMs !== void 0) {
3187
+ return () => send({ type: "DISMISS" });
3188
+ }
3189
+ }, [send, durationMs]);
3190
+ return null;
3191
+ }
3192
+
3193
+ // src/toast/provider.tsx
3194
+ import { toastAnatomy as toastAnatomy2, partAttrs as partAttrs23 } from "@aeon-ui/core";
3195
+ import {
3196
+ useCallback as useCallback7,
3197
+ useEffect as useEffect20,
3198
+ useMemo as useMemo20,
3199
+ useState as useState8
3200
+ } from "react";
3201
+ import { createPortal as createPortal2 } from "react-dom";
3202
+
3203
+ // src/toast/context.tsx
3204
+ import { createContext as createContext19, useContext as useContext19 } from "react";
3205
+ var ToastStoreCtx = createContext19(null);
3206
+ function useToastStore() {
3207
+ const ctx = useContext19(ToastStoreCtx);
3208
+ if (!ctx) {
3209
+ throw new Error("useToast must be used within Toast.Provider");
3210
+ }
3211
+ return ctx;
3212
+ }
3213
+
3214
+ // src/toast/toast-item.tsx
3215
+ import { forwardRef as forwardRef25 } from "react";
3216
+ import { jsx as jsx27, jsxs as jsxs5 } from "react/jsx-runtime";
3217
+ var ToastItem = forwardRef25(function ToastItem2({ item, onExited, className, ...rest }, ref) {
3218
+ const { id, title, description, durationMs } = item;
3219
+ return /* @__PURE__ */ jsxs5(
3220
+ Root19,
3221
+ {
3222
+ ref,
3223
+ className,
3224
+ defaultVisible: true,
3225
+ durationMs: durationMs ?? 5e3,
3226
+ onVisibleChange: (visible) => {
3227
+ if (!visible) onExited(id);
3228
+ },
3229
+ ...rest,
3230
+ children: [
3231
+ title ? /* @__PURE__ */ jsx27(Title2, { children: title }) : null,
3232
+ description ? /* @__PURE__ */ jsx27(Description2, { children: description }) : null,
3233
+ /* @__PURE__ */ jsx27(CloseTrigger3, {})
3234
+ ]
3235
+ }
3236
+ );
3237
+ });
3238
+
3239
+ // src/toast/provider.tsx
3240
+ import { jsx as jsx28 } from "react/jsx-runtime";
3241
+ var PLACEMENT_ATTR = {
3242
+ "top-start": "top-start",
3243
+ "top-end": "top-end",
3244
+ "bottom-start": "bottom-start",
3245
+ "bottom-end": "bottom-end"
3246
+ };
3247
+ function nextToastId() {
3248
+ return `toast-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
3249
+ }
3250
+ function ToastProvider({ children, limit = 5 }) {
3251
+ const [items, setItems] = useState8([]);
3252
+ const dismiss = useCallback7((id) => {
3253
+ setItems((prev) => prev.filter((t) => t.id !== id));
3254
+ }, []);
3255
+ const dismissAll = useCallback7(() => {
3256
+ setItems([]);
3257
+ }, []);
3258
+ const publish = useCallback7(
3259
+ (options) => {
3260
+ const id = options.id ?? nextToastId();
3261
+ const record = { ...options, id };
3262
+ setItems((prev) => {
3263
+ const without = prev.filter((t) => t.id !== id);
3264
+ const next = [...without, record];
3265
+ return next.length > limit ? next.slice(-limit) : next;
3266
+ });
3267
+ return id;
3268
+ },
3269
+ [limit]
3270
+ );
3271
+ const value = useMemo20(
3272
+ () => ({ items, publish, dismiss, dismissAll }),
3273
+ [items, publish, dismiss, dismissAll]
3274
+ );
3275
+ return /* @__PURE__ */ jsx28(ToastStoreCtx.Provider, { value, children });
3276
+ }
3277
+ function ToastViewport({ placement = "bottom-end", className, ...rest }) {
3278
+ const { items, dismiss } = useToastStore();
3279
+ const [mounted, setMounted] = useState8(false);
3280
+ useEffect20(() => {
3281
+ setMounted(true);
3282
+ }, []);
3283
+ if (!mounted) return null;
3284
+ return createPortal2(
3285
+ /* @__PURE__ */ jsx28(
3286
+ "div",
3287
+ {
3288
+ ...mergeProps(
3289
+ partAttrs23(toastAnatomy2.scope, toastAnatomy2.viewport, {
3290
+ state: items.length > 0 ? "active" : "idle"
3291
+ }),
3292
+ {
3293
+ "data-placement": PLACEMENT_ATTR[placement]
3294
+ },
3295
+ rest
3296
+ ),
3297
+ className,
3298
+ children: items.map((item) => /* @__PURE__ */ jsx28(ToastItem, { item, onExited: dismiss }, item.id))
3299
+ }
3300
+ ),
3301
+ document.body
3302
+ );
3303
+ }
3304
+ function useToast() {
3305
+ const { publish, dismiss, dismissAll } = useToastStore();
3306
+ return { publish, dismiss, dismissAll };
3307
+ }
3308
+
3309
+ // src/toast/index.tsx
3310
+ var Toast = {
3311
+ Provider: ToastProvider,
3312
+ Viewport: ToastViewport,
3313
+ Root: Root19,
3314
+ Title: Title2,
3315
+ Description: Description2,
3316
+ CloseTrigger: CloseTrigger3,
3317
+ Show
3318
+ };
3319
+
3320
+ // src/avatar/index.tsx
3321
+ import { avatarAnatomy, partAttrs as partAttrs24 } from "@aeon-ui/core";
3322
+ import {
3323
+ createContext as createContext20,
3324
+ forwardRef as forwardRef26,
3325
+ useCallback as useCallback8,
3326
+ useContext as useContext20,
3327
+ useEffect as useEffect21,
3328
+ useMemo as useMemo21,
3329
+ useState as useState9
3330
+ } from "react";
3331
+ import { jsx as jsx29 } from "react/jsx-runtime";
3332
+ var AvatarCtx = createContext20(null);
3333
+ function useAvatarCtx() {
3334
+ const ctx = useContext20(AvatarCtx);
3335
+ if (!ctx) throw new Error("Avatar parts must be used within Avatar.Root");
3336
+ return ctx;
3337
+ }
3338
+ var Root20 = forwardRef26(function AvatarRoot({ children, className, ...rest }, ref) {
3339
+ const [status, setStatus] = useState9("idle");
3340
+ const value = useMemo21(() => ({ status, setStatus }), [status]);
3341
+ return /* @__PURE__ */ jsx29(AvatarCtx.Provider, { value, children: /* @__PURE__ */ jsx29(
3342
+ "span",
3343
+ {
3344
+ ref,
3345
+ className,
3346
+ ...mergeProps(
3347
+ partAttrs24(avatarAnatomy.scope, avatarAnatomy.root, { state: status }),
3348
+ rest
3349
+ ),
3350
+ children
3351
+ }
3352
+ ) });
3353
+ });
3354
+ var Image = forwardRef26(function AvatarImage({ src, alt, onLoad, onError, className, ...rest }, ref) {
3355
+ const { status, setStatus } = useAvatarCtx();
3356
+ useEffect21(() => {
3357
+ if (!src) setStatus("idle");
3358
+ else setStatus("loading");
3359
+ }, [src, setStatus]);
3360
+ const handleLoad = useCallback8(
3361
+ (e) => {
3362
+ onLoad?.(e);
3363
+ setStatus("loaded");
3364
+ },
3365
+ [onLoad, setStatus]
3366
+ );
3367
+ const handleError = useCallback8(
3368
+ (e) => {
3369
+ onError?.(e);
3370
+ setStatus("error");
3371
+ },
3372
+ [onError, setStatus]
3373
+ );
3374
+ return /* @__PURE__ */ jsx29(
3375
+ "img",
3376
+ {
3377
+ ref,
3378
+ src,
3379
+ alt,
3380
+ hidden: status !== "loaded",
3381
+ ...partAttrs24(avatarAnatomy.scope, avatarAnatomy.image, { state: status }),
3382
+ className,
3383
+ ...mergeProps(rest, { onLoad: handleLoad, onError: handleError })
3384
+ }
3385
+ );
3386
+ });
3387
+ var Fallback = forwardRef26(function AvatarFallback({ className, ...rest }, ref) {
3388
+ const { status } = useAvatarCtx();
3389
+ const show = status !== "loaded";
3390
+ return /* @__PURE__ */ jsx29(
3391
+ "span",
3392
+ {
3393
+ ref,
3394
+ hidden: !show,
3395
+ ...partAttrs24(avatarAnatomy.scope, avatarAnatomy.fallback, { state: status }),
3396
+ className,
3397
+ ...rest
3398
+ }
3399
+ );
3400
+ });
3401
+ var Avatar = {
3402
+ Root: Root20,
3403
+ Image,
3404
+ Fallback
3405
+ };
3406
+
3407
+ // src/hooks/use-layout-mode.ts
3408
+ import { getCompactMq, layoutCompositionForMode, matchLayoutMode } from "@aeon-ui/core";
3409
+ import { useEffect as useEffect22, useMemo as useMemo22, useState as useState10 } from "react";
3410
+ function useLayoutMode(spec) {
3411
+ const mq = useMemo22(() => getCompactMq(spec), [spec.compactMq]);
3412
+ const [mode, setMode] = useState10(() => matchLayoutMode(spec, mq));
3413
+ useEffect22(() => {
3414
+ const sync = () => setMode(matchLayoutMode(spec, mq));
3415
+ sync();
3416
+ mq.addEventListener("change", sync);
3417
+ return () => mq.removeEventListener("change", sync);
3418
+ }, [spec, mq]);
3419
+ const composition = useMemo22(() => layoutCompositionForMode(spec, mode), [spec, mode]);
3420
+ return { mode, composition };
3421
+ }
3422
+ export {
3423
+ Accordion,
3424
+ Async,
3425
+ AsyncActions,
3426
+ AsyncProvider,
3427
+ AsyncReadout,
3428
+ AsyncRegion,
3429
+ AsyncRoot,
3430
+ AsyncTrack,
3431
+ Avatar,
3432
+ Button,
3433
+ Checkbox,
3434
+ Combobox,
3435
+ Dialog,
3436
+ Field,
3437
+ Menu,
3438
+ PinInput,
3439
+ Popover,
3440
+ Progress,
3441
+ RadioGroup,
3442
+ Scroll,
3443
+ Select,
3444
+ Separator,
3445
+ Slider,
3446
+ Switch,
3447
+ Tabs,
3448
+ Toast,
3449
+ ToastItem,
3450
+ Tooltip,
3451
+ createAsyncMachine3 as createAsyncMachine,
3452
+ fieldMachine,
3453
+ useAeonMachine,
3454
+ useAsyncContext,
3455
+ useFieldContext,
3456
+ useLayoutMode,
3457
+ useScrollContext,
3458
+ useScrollState,
3459
+ useToast,
3460
+ useToastStore
3461
+ };