aeon-ui-engine 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (430) hide show
  1. package/.changeset/README.md +23 -0
  2. package/.changeset/combobox-and-changesets.md +9 -0
  3. package/.changeset/config.json +30 -0
  4. package/.changeset/framework-adapters.md +12 -0
  5. package/.changeset/scene-3d.md +6 -0
  6. package/.changeset/scene-plane.md +8 -0
  7. package/.changeset/site-og.md +5 -0
  8. package/.cursor/rules/aeon-ui.mdc +22 -0
  9. package/ACCESSIBILITY.md +32 -0
  10. package/AGENTS.md +226 -0
  11. package/COMPONENTS.md +36 -0
  12. package/FRAMEWORKS.md +57 -0
  13. package/INTEGRATION.md +89 -0
  14. package/LICENSE +21 -0
  15. package/PHILOSOPHY.md +71 -0
  16. package/PUBLISHING.md +85 -0
  17. package/README.md +154 -0
  18. package/SCENE.md +113 -0
  19. package/STATES.md +243 -0
  20. package/apps/demo/index.html +31 -0
  21. package/apps/demo/og.config.mjs +15 -0
  22. package/apps/demo/package.json +41 -0
  23. package/apps/demo/public/favicon.svg +16 -0
  24. package/apps/demo/public/og.png +0 -0
  25. package/apps/demo/public/og.svg +35 -0
  26. package/apps/demo/scripts/generate-og-png.mjs +60 -0
  27. package/apps/demo/src/App.tsx +31 -0
  28. package/apps/demo/src/aeonDiagrams.ts +100 -0
  29. package/apps/demo/src/app.css +16 -0
  30. package/apps/demo/src/components/ActionCluster.tsx +20 -0
  31. package/apps/demo/src/components/AsyncMachineDemo.tsx +97 -0
  32. package/apps/demo/src/components/ButtonLifecycleDemo.tsx +63 -0
  33. package/apps/demo/src/components/CodeExample.tsx +7 -0
  34. package/apps/demo/src/components/ComboboxDemo.tsx +30 -0
  35. package/apps/demo/src/components/DiagramsSection.tsx +38 -0
  36. package/apps/demo/src/components/FieldStateDemo.tsx +51 -0
  37. package/apps/demo/src/components/GridMesh.tsx +8 -0
  38. package/apps/demo/src/components/HeroInstall.tsx +10 -0
  39. package/apps/demo/src/components/LandingFaq.tsx +29 -0
  40. package/apps/demo/src/components/LandingFooter.tsx +22 -0
  41. package/apps/demo/src/components/LandingHeader.tsx +60 -0
  42. package/apps/demo/src/components/LandingHero.tsx +55 -0
  43. package/apps/demo/src/components/LayersSection.tsx +51 -0
  44. package/apps/demo/src/components/MermaidDiagram.tsx +84 -0
  45. package/apps/demo/src/components/PhilosophySection.tsx +33 -0
  46. package/apps/demo/src/components/PlaygroundBlock.tsx +23 -0
  47. package/apps/demo/src/components/PlaygroundSection.tsx +204 -0
  48. package/apps/demo/src/components/SceneSection.tsx +157 -0
  49. package/apps/demo/src/components/ScrollRegionDemo.tsx +74 -0
  50. package/apps/demo/src/components/ThemeSwitcher.tsx +76 -0
  51. package/apps/demo/src/demo-layout.css +264 -0
  52. package/apps/demo/src/landing.css +1094 -0
  53. package/apps/demo/src/main.tsx +14 -0
  54. package/apps/demo/src/nav.ts +9 -0
  55. package/apps/demo/src/site.ts +347 -0
  56. package/apps/demo/tsconfig.json +17 -0
  57. package/apps/demo/vite-plugins/og-meta.ts +30 -0
  58. package/apps/demo/vite.config.ts +69 -0
  59. package/docs/API_PATTERNS.md +234 -0
  60. package/docs/ARCHITECTURE.md +125 -0
  61. package/docs/COMPONENT_CHECKLIST.md +103 -0
  62. package/docs/FILE_MAP.md +122 -0
  63. package/docs/GLOSSARY.md +125 -0
  64. package/docs/INDEX.md +53 -0
  65. package/docs/LAYOUT_COORDINATES.md +178 -0
  66. package/docs/MACHINES.md +166 -0
  67. package/docs/MIGRATION_FROM_ARK.md +295 -0
  68. package/docs/VITE_CONSUMER.md +114 -0
  69. package/package.json +25 -0
  70. package/packages/core/README.md +69 -0
  71. package/packages/core/package.json +37 -0
  72. package/packages/core/src/anatomy.ts +144 -0
  73. package/packages/core/src/attrs.ts +47 -0
  74. package/packages/core/src/index.ts +8 -0
  75. package/packages/core/src/layout.ts +176 -0
  76. package/packages/core/src/machine.test.ts +18 -0
  77. package/packages/core/src/machine.ts +15 -0
  78. package/packages/core/src/philosophy.ts +10 -0
  79. package/packages/core/src/scroll.ts +72 -0
  80. package/packages/core/src/theme.test.ts +14 -0
  81. package/packages/core/src/theme.ts +53 -0
  82. package/packages/core/src/types.ts +25 -0
  83. package/packages/core/theme-transition.css +58 -0
  84. package/packages/core/tsconfig.json +8 -0
  85. package/packages/core/vitest.config.ts +8 -0
  86. package/packages/geometry/README.md +7 -0
  87. package/packages/geometry/package.json +35 -0
  88. package/packages/geometry/src/index.ts +3 -0
  89. package/packages/geometry/src/patterns.ts +55 -0
  90. package/packages/geometry/src/scene-attrs.ts +11 -0
  91. package/packages/geometry/src/svg.ts +60 -0
  92. package/packages/geometry/tsconfig.json +8 -0
  93. package/packages/panda/README.md +66 -0
  94. package/packages/panda/package.json +40 -0
  95. package/packages/panda/panda.config.ts +229 -0
  96. package/packages/panda/scripts/emit-theme-runtime.ts +37 -0
  97. package/packages/panda/src/recipes/accordion.ts +95 -0
  98. package/packages/panda/src/recipes/async.ts +76 -0
  99. package/packages/panda/src/recipes/badge.ts +44 -0
  100. package/packages/panda/src/recipes/button-group.ts +33 -0
  101. package/packages/panda/src/recipes/button.ts +91 -0
  102. package/packages/panda/src/recipes/checkbox.ts +41 -0
  103. package/packages/panda/src/recipes/combobox.ts +121 -0
  104. package/packages/panda/src/recipes/dialog.ts +96 -0
  105. package/packages/panda/src/recipes/field-shared.ts +29 -0
  106. package/packages/panda/src/recipes/field.ts +72 -0
  107. package/packages/panda/src/recipes/floating.ts +170 -0
  108. package/packages/panda/src/recipes/index.ts +14 -0
  109. package/packages/panda/src/recipes/scroll-region.ts +55 -0
  110. package/packages/panda/src/recipes/select.ts +111 -0
  111. package/packages/panda/src/recipes/switch.ts +51 -0
  112. package/packages/panda/src/recipes/tabs.ts +50 -0
  113. package/packages/panda/src/theme/catalog-types.ts +24 -0
  114. package/packages/panda/src/theme/catalog.ts +73 -0
  115. package/packages/panda/src/theme/chrome.css +75 -0
  116. package/packages/panda/src/theme/global-theme-css.ts +42 -0
  117. package/packages/panda/src/theme/index.ts +5 -0
  118. package/packages/panda/src/theme/palette.ts +65 -0
  119. package/packages/panda/src/theme/scrollbars.css +96 -0
  120. package/packages/panda/src/theme/semantic-tokens.ts +17 -0
  121. package/packages/panda/src/theme/themes.config.ts +516 -0
  122. package/packages/panda/src/theme/tokens.ts +51 -0
  123. package/packages/panda/styled-system/css/conditions.mjs +36 -0
  124. package/packages/panda/styled-system/css/css.d.ts +22 -0
  125. package/packages/panda/styled-system/css/css.mjs +45 -0
  126. package/packages/panda/styled-system/css/cva.d.ts +6 -0
  127. package/packages/panda/styled-system/css/cva.mjs +87 -0
  128. package/packages/panda/styled-system/css/cx.d.ts +5 -0
  129. package/packages/panda/styled-system/css/cx.mjs +15 -0
  130. package/packages/panda/styled-system/css/index.d.ts +5 -0
  131. package/packages/panda/styled-system/css/index.mjs +4 -0
  132. package/packages/panda/styled-system/css/sva.d.ts +4 -0
  133. package/packages/panda/styled-system/css/sva.mjs +41 -0
  134. package/packages/panda/styled-system/helpers.mjs +339 -0
  135. package/packages/panda/styled-system/jsx/aspect-ratio.d.ts +10 -0
  136. package/packages/panda/styled-system/jsx/aspect-ratio.mjs +14 -0
  137. package/packages/panda/styled-system/jsx/bleed.d.ts +10 -0
  138. package/packages/panda/styled-system/jsx/bleed.mjs +14 -0
  139. package/packages/panda/styled-system/jsx/box.d.ts +10 -0
  140. package/packages/panda/styled-system/jsx/box.mjs +14 -0
  141. package/packages/panda/styled-system/jsx/center.d.ts +10 -0
  142. package/packages/panda/styled-system/jsx/center.mjs +14 -0
  143. package/packages/panda/styled-system/jsx/circle.d.ts +10 -0
  144. package/packages/panda/styled-system/jsx/circle.mjs +14 -0
  145. package/packages/panda/styled-system/jsx/container.d.ts +10 -0
  146. package/packages/panda/styled-system/jsx/container.mjs +14 -0
  147. package/packages/panda/styled-system/jsx/cq.d.ts +10 -0
  148. package/packages/panda/styled-system/jsx/cq.mjs +14 -0
  149. package/packages/panda/styled-system/jsx/divider.d.ts +10 -0
  150. package/packages/panda/styled-system/jsx/divider.mjs +14 -0
  151. package/packages/panda/styled-system/jsx/factory-helper.mjs +22 -0
  152. package/packages/panda/styled-system/jsx/factory.d.ts +3 -0
  153. package/packages/panda/styled-system/jsx/factory.mjs +80 -0
  154. package/packages/panda/styled-system/jsx/flex.d.ts +10 -0
  155. package/packages/panda/styled-system/jsx/flex.mjs +14 -0
  156. package/packages/panda/styled-system/jsx/float.d.ts +10 -0
  157. package/packages/panda/styled-system/jsx/float.mjs +14 -0
  158. package/packages/panda/styled-system/jsx/grid-item.d.ts +10 -0
  159. package/packages/panda/styled-system/jsx/grid-item.mjs +14 -0
  160. package/packages/panda/styled-system/jsx/grid.d.ts +10 -0
  161. package/packages/panda/styled-system/jsx/grid.mjs +14 -0
  162. package/packages/panda/styled-system/jsx/hstack.d.ts +10 -0
  163. package/packages/panda/styled-system/jsx/hstack.mjs +14 -0
  164. package/packages/panda/styled-system/jsx/index.d.ts +24 -0
  165. package/packages/panda/styled-system/jsx/index.mjs +22 -0
  166. package/packages/panda/styled-system/jsx/is-valid-prop.d.ts +11 -0
  167. package/packages/panda/styled-system/jsx/is-valid-prop.mjs +17 -0
  168. package/packages/panda/styled-system/jsx/link-overlay.d.ts +10 -0
  169. package/packages/panda/styled-system/jsx/link-overlay.mjs +14 -0
  170. package/packages/panda/styled-system/jsx/spacer.d.ts +10 -0
  171. package/packages/panda/styled-system/jsx/spacer.mjs +14 -0
  172. package/packages/panda/styled-system/jsx/square.d.ts +10 -0
  173. package/packages/panda/styled-system/jsx/square.mjs +14 -0
  174. package/packages/panda/styled-system/jsx/stack.d.ts +10 -0
  175. package/packages/panda/styled-system/jsx/stack.mjs +14 -0
  176. package/packages/panda/styled-system/jsx/visually-hidden.d.ts +10 -0
  177. package/packages/panda/styled-system/jsx/visually-hidden.mjs +14 -0
  178. package/packages/panda/styled-system/jsx/vstack.d.ts +10 -0
  179. package/packages/panda/styled-system/jsx/vstack.mjs +14 -0
  180. package/packages/panda/styled-system/jsx/wrap.d.ts +10 -0
  181. package/packages/panda/styled-system/jsx/wrap.mjs +14 -0
  182. package/packages/panda/styled-system/patterns/aspect-ratio.d.ts +21 -0
  183. package/packages/panda/styled-system/patterns/aspect-ratio.mjs +38 -0
  184. package/packages/panda/styled-system/patterns/bleed.d.ts +22 -0
  185. package/packages/panda/styled-system/patterns/bleed.mjs +24 -0
  186. package/packages/panda/styled-system/patterns/box.d.ts +21 -0
  187. package/packages/panda/styled-system/patterns/box.mjs +15 -0
  188. package/packages/panda/styled-system/patterns/center.d.ts +21 -0
  189. package/packages/panda/styled-system/patterns/center.mjs +21 -0
  190. package/packages/panda/styled-system/patterns/circle.d.ts +21 -0
  191. package/packages/panda/styled-system/patterns/circle.mjs +25 -0
  192. package/packages/panda/styled-system/patterns/container.d.ts +21 -0
  193. package/packages/panda/styled-system/patterns/container.mjs +21 -0
  194. package/packages/panda/styled-system/patterns/cq.d.ts +22 -0
  195. package/packages/panda/styled-system/patterns/cq.mjs +21 -0
  196. package/packages/panda/styled-system/patterns/divider.d.ts +23 -0
  197. package/packages/panda/styled-system/patterns/divider.mjs +25 -0
  198. package/packages/panda/styled-system/patterns/flex.d.ts +27 -0
  199. package/packages/panda/styled-system/patterns/flex.mjs +26 -0
  200. package/packages/panda/styled-system/patterns/float.d.ts +24 -0
  201. package/packages/panda/styled-system/patterns/float.mjs +52 -0
  202. package/packages/panda/styled-system/patterns/grid-item.d.ts +26 -0
  203. package/packages/panda/styled-system/patterns/grid-item.mjs +25 -0
  204. package/packages/panda/styled-system/patterns/grid.d.ts +25 -0
  205. package/packages/panda/styled-system/patterns/grid.mjs +27 -0
  206. package/packages/panda/styled-system/patterns/hstack.d.ts +22 -0
  207. package/packages/panda/styled-system/patterns/hstack.mjs +24 -0
  208. package/packages/panda/styled-system/patterns/index.d.ts +21 -0
  209. package/packages/panda/styled-system/patterns/index.mjs +20 -0
  210. package/packages/panda/styled-system/patterns/link-overlay.d.ts +21 -0
  211. package/packages/panda/styled-system/patterns/link-overlay.mjs +24 -0
  212. package/packages/panda/styled-system/patterns/spacer.d.ts +21 -0
  213. package/packages/panda/styled-system/patterns/spacer.mjs +21 -0
  214. package/packages/panda/styled-system/patterns/square.d.ts +21 -0
  215. package/packages/panda/styled-system/patterns/square.mjs +24 -0
  216. package/packages/panda/styled-system/patterns/stack.d.ts +24 -0
  217. package/packages/panda/styled-system/patterns/stack.mjs +24 -0
  218. package/packages/panda/styled-system/patterns/visually-hidden.d.ts +21 -0
  219. package/packages/panda/styled-system/patterns/visually-hidden.mjs +18 -0
  220. package/packages/panda/styled-system/patterns/vstack.d.ts +22 -0
  221. package/packages/panda/styled-system/patterns/vstack.mjs +24 -0
  222. package/packages/panda/styled-system/patterns/wrap.d.ts +25 -0
  223. package/packages/panda/styled-system/patterns/wrap.mjs +25 -0
  224. package/packages/panda/styled-system/recipes/aeon-accordion.d.ts +32 -0
  225. package/packages/panda/styled-system/recipes/aeon-accordion.mjs +48 -0
  226. package/packages/panda/styled-system/recipes/aeon-async.d.ts +32 -0
  227. package/packages/panda/styled-system/recipes/aeon-async.mjs +56 -0
  228. package/packages/panda/styled-system/recipes/aeon-badge.d.ts +31 -0
  229. package/packages/panda/styled-system/recipes/aeon-badge.mjs +32 -0
  230. package/packages/panda/styled-system/recipes/aeon-button-group.d.ts +39 -0
  231. package/packages/panda/styled-system/recipes/aeon-button-group.mjs +37 -0
  232. package/packages/panda/styled-system/recipes/aeon-button.d.ts +39 -0
  233. package/packages/panda/styled-system/recipes/aeon-button.mjs +39 -0
  234. package/packages/panda/styled-system/recipes/aeon-checkbox.d.ts +28 -0
  235. package/packages/panda/styled-system/recipes/aeon-checkbox.mjs +48 -0
  236. package/packages/panda/styled-system/recipes/aeon-combobox.d.ts +32 -0
  237. package/packages/panda/styled-system/recipes/aeon-combobox.mjs +52 -0
  238. package/packages/panda/styled-system/recipes/aeon-dialog.d.ts +28 -0
  239. package/packages/panda/styled-system/recipes/aeon-dialog.mjs +60 -0
  240. package/packages/panda/styled-system/recipes/aeon-field.d.ts +32 -0
  241. package/packages/panda/styled-system/recipes/aeon-field.mjs +52 -0
  242. package/packages/panda/styled-system/recipes/aeon-menu.d.ts +28 -0
  243. package/packages/panda/styled-system/recipes/aeon-menu.mjs +52 -0
  244. package/packages/panda/styled-system/recipes/aeon-popover.d.ts +28 -0
  245. package/packages/panda/styled-system/recipes/aeon-popover.mjs +52 -0
  246. package/packages/panda/styled-system/recipes/aeon-scroll.d.ts +43 -0
  247. package/packages/panda/styled-system/recipes/aeon-scroll.mjs +63 -0
  248. package/packages/panda/styled-system/recipes/aeon-select.d.ts +32 -0
  249. package/packages/panda/styled-system/recipes/aeon-select.mjs +56 -0
  250. package/packages/panda/styled-system/recipes/aeon-switch.d.ts +28 -0
  251. package/packages/panda/styled-system/recipes/aeon-switch.mjs +48 -0
  252. package/packages/panda/styled-system/recipes/aeon-tabs.d.ts +28 -0
  253. package/packages/panda/styled-system/recipes/aeon-tabs.mjs +48 -0
  254. package/packages/panda/styled-system/recipes/aeon-toast.d.ts +28 -0
  255. package/packages/panda/styled-system/recipes/aeon-toast.mjs +48 -0
  256. package/packages/panda/styled-system/recipes/aeon-tooltip.d.ts +28 -0
  257. package/packages/panda/styled-system/recipes/aeon-tooltip.mjs +48 -0
  258. package/packages/panda/styled-system/recipes/create-recipe.mjs +82 -0
  259. package/packages/panda/styled-system/recipes/index.d.ts +18 -0
  260. package/packages/panda/styled-system/recipes/index.mjs +17 -0
  261. package/packages/panda/styled-system/styles.css +2157 -0
  262. package/packages/panda/styled-system/tokens/index.d.ts +9 -0
  263. package/packages/panda/styled-system/tokens/index.mjs +2156 -0
  264. package/packages/panda/styled-system/tokens/tokens.d.ts +60 -0
  265. package/packages/panda/styled-system/types/composition.d.ts +164 -0
  266. package/packages/panda/styled-system/types/conditions.d.ts +322 -0
  267. package/packages/panda/styled-system/types/csstype.d.ts +21298 -0
  268. package/packages/panda/styled-system/types/global.d.ts +20 -0
  269. package/packages/panda/styled-system/types/index.d.ts +8 -0
  270. package/packages/panda/styled-system/types/jsx.d.ts +52 -0
  271. package/packages/panda/styled-system/types/parts.d.ts +8 -0
  272. package/packages/panda/styled-system/types/pattern.d.ts +78 -0
  273. package/packages/panda/styled-system/types/prop-type.d.ts +240 -0
  274. package/packages/panda/styled-system/types/recipe.d.ts +181 -0
  275. package/packages/panda/styled-system/types/selectors.d.ts +59 -0
  276. package/packages/panda/styled-system/types/static-css.d.ts +56 -0
  277. package/packages/panda/styled-system/types/style-props.d.ts +7491 -0
  278. package/packages/panda/styled-system/types/system-types.d.ts +193 -0
  279. package/packages/panda/theme-runtime.css +842 -0
  280. package/packages/panda/tsconfig.json +8 -0
  281. package/packages/primitives/README.md +54 -0
  282. package/packages/primitives/package.json +41 -0
  283. package/packages/primitives/src/__tests__/floating-surface.test.ts +29 -0
  284. package/packages/primitives/src/index.ts +9 -0
  285. package/packages/primitives/src/machines/accordion.ts +56 -0
  286. package/packages/primitives/src/machines/async.ts +108 -0
  287. package/packages/primitives/src/machines/button.ts +66 -0
  288. package/packages/primitives/src/machines/dialog.ts +61 -0
  289. package/packages/primitives/src/machines/field.ts +85 -0
  290. package/packages/primitives/src/machines/popover.ts +52 -0
  291. package/packages/primitives/src/machines/tabs.ts +46 -0
  292. package/packages/primitives/src/machines/toast.ts +48 -0
  293. package/packages/primitives/src/machines/toggle.ts +61 -0
  294. package/packages/primitives/tsconfig.json +8 -0
  295. package/packages/primitives/vitest.config.ts +8 -0
  296. package/packages/react/README.md +65 -0
  297. package/packages/react/package.json +52 -0
  298. package/packages/react/src/accordion/index.tsx +179 -0
  299. package/packages/react/src/async/actions.tsx +22 -0
  300. package/packages/react/src/async/context.tsx +54 -0
  301. package/packages/react/src/async/index.tsx +21 -0
  302. package/packages/react/src/async/legacy-region.tsx +38 -0
  303. package/packages/react/src/async/readout.tsx +34 -0
  304. package/packages/react/src/async/root.tsx +39 -0
  305. package/packages/react/src/async/track.tsx +59 -0
  306. package/packages/react/src/avatar/avatar.test.tsx +27 -0
  307. package/packages/react/src/avatar/index.tsx +122 -0
  308. package/packages/react/src/button/index.tsx +70 -0
  309. package/packages/react/src/checkbox/index.tsx +180 -0
  310. package/packages/react/src/combobox/index.tsx +430 -0
  311. package/packages/react/src/dialog/dialog.test.tsx +50 -0
  312. package/packages/react/src/dialog/index.tsx +275 -0
  313. package/packages/react/src/field/index.tsx +172 -0
  314. package/packages/react/src/hooks/use-aeon-machine.ts +10 -0
  315. package/packages/react/src/hooks/use-anchor-position.ts +33 -0
  316. package/packages/react/src/hooks/use-focus-trap.ts +51 -0
  317. package/packages/react/src/hooks/use-layout-mode.ts +22 -0
  318. package/packages/react/src/hooks/use-outside-click.ts +19 -0
  319. package/packages/react/src/hooks/use-portalled.ts +16 -0
  320. package/packages/react/src/hooks/use-scroll-lock.ts +13 -0
  321. package/packages/react/src/index.ts +18 -0
  322. package/packages/react/src/menu/index.tsx +195 -0
  323. package/packages/react/src/popover/index.tsx +191 -0
  324. package/packages/react/src/scroll/index.tsx +98 -0
  325. package/packages/react/src/scroll/use-scroll-state.ts +30 -0
  326. package/packages/react/src/select/index.tsx +372 -0
  327. package/packages/react/src/select/select.test.tsx +60 -0
  328. package/packages/react/src/switch/index.tsx +215 -0
  329. package/packages/react/src/tabs/index.tsx +140 -0
  330. package/packages/react/src/toast/context.tsx +28 -0
  331. package/packages/react/src/toast/index.tsx +20 -0
  332. package/packages/react/src/toast/primitives.tsx +129 -0
  333. package/packages/react/src/toast/provider.tsx +111 -0
  334. package/packages/react/src/toast/toast-item.tsx +32 -0
  335. package/packages/react/src/tooltip/index.tsx +191 -0
  336. package/packages/react/src/utils/merge-props.ts +24 -0
  337. package/packages/react/tsconfig.json +8 -0
  338. package/packages/react/vitest.config.ts +9 -0
  339. package/packages/react/vitest.setup.ts +5 -0
  340. package/packages/react-scene/README.md +11 -0
  341. package/packages/react-scene/package.json +47 -0
  342. package/packages/react-scene/scene-3d.css +37 -0
  343. package/packages/react-scene/scene-room.css +95 -0
  344. package/packages/react-scene/src/index.ts +20 -0
  345. package/packages/react-scene/src/procedural-grid.tsx +35 -0
  346. package/packages/react-scene/src/scene-layer.tsx +38 -0
  347. package/packages/react-scene/src/scene-plane.tsx +69 -0
  348. package/packages/react-scene/src/scene-room.tsx +81 -0
  349. package/packages/react-scene/src/scene-root.tsx +49 -0
  350. package/packages/react-scene/src/scene-slot.tsx +41 -0
  351. package/packages/react-scene/src/scene-stage.tsx +37 -0
  352. package/packages/react-scene/src/scene-surface.tsx +20 -0
  353. package/packages/react-scene/src/signal-bars.tsx +57 -0
  354. package/packages/react-scene/src/use-signal-visualizer.ts +103 -0
  355. package/packages/react-scene/tsconfig.json +8 -0
  356. package/packages/scene/README.md +5 -0
  357. package/packages/scene/package.json +32 -0
  358. package/packages/scene/src/index.ts +2 -0
  359. package/packages/scene/src/room.ts +40 -0
  360. package/packages/scene/src/transform.ts +60 -0
  361. package/packages/scene/tsconfig.json +8 -0
  362. package/packages/signal/README.md +9 -0
  363. package/packages/signal/package.json +32 -0
  364. package/packages/signal/src/analyser.ts +113 -0
  365. package/packages/signal/src/bands.ts +33 -0
  366. package/packages/signal/src/index.ts +3 -0
  367. package/packages/signal/src/motion.ts +80 -0
  368. package/packages/signal/tsconfig.json +8 -0
  369. package/packages/site/README.md +19 -0
  370. package/packages/site/package.json +32 -0
  371. package/packages/site/src/index.ts +8 -0
  372. package/packages/site/src/open-graph.ts +90 -0
  373. package/packages/site/tsconfig.json +8 -0
  374. package/packages/solid/README.md +30 -0
  375. package/packages/solid/package.json +42 -0
  376. package/packages/solid/src/hooks/use-aeon-machine.ts +10 -0
  377. package/packages/solid/src/index.ts +2 -0
  378. package/packages/solid/src/switch/index.tsx +191 -0
  379. package/packages/solid/src/utils/merge-props.ts +3 -0
  380. package/packages/solid/tsconfig.json +10 -0
  381. package/packages/surface/README.md +10 -0
  382. package/packages/surface/package.json +33 -0
  383. package/packages/surface/src/index.ts +1 -0
  384. package/packages/surface/src/materials.ts +14 -0
  385. package/packages/surface/surface.css +113 -0
  386. package/packages/surface/tsconfig.json +8 -0
  387. package/packages/svelte/README.md +45 -0
  388. package/packages/svelte/package.json +49 -0
  389. package/packages/svelte/src/Switch.svelte +86 -0
  390. package/packages/svelte/src/SwitchControl.svelte +45 -0
  391. package/packages/svelte/src/SwitchHiddenInput.svelte +12 -0
  392. package/packages/svelte/src/SwitchLabel.svelte +9 -0
  393. package/packages/svelte/src/SwitchThumb.svelte +16 -0
  394. package/packages/svelte/src/hooks/use-aeon-machine.ts +23 -0
  395. package/packages/svelte/src/index.ts +2 -0
  396. package/packages/svelte/src/switch-context.ts +13 -0
  397. package/packages/svelte/tsconfig.json +8 -0
  398. package/packages/ui/README.md +63 -0
  399. package/packages/ui/package.json +45 -0
  400. package/packages/ui/src/accordion.tsx +27 -0
  401. package/packages/ui/src/async.tsx +43 -0
  402. package/packages/ui/src/badge.tsx +18 -0
  403. package/packages/ui/src/button.tsx +38 -0
  404. package/packages/ui/src/checkbox.tsx +24 -0
  405. package/packages/ui/src/cn.ts +1 -0
  406. package/packages/ui/src/combobox.tsx +29 -0
  407. package/packages/ui/src/dialog.tsx +32 -0
  408. package/packages/ui/src/field.tsx +33 -0
  409. package/packages/ui/src/index.ts +17 -0
  410. package/packages/ui/src/menu.tsx +25 -0
  411. package/packages/ui/src/popover.tsx +22 -0
  412. package/packages/ui/src/scroll.tsx +51 -0
  413. package/packages/ui/src/select.tsx +33 -0
  414. package/packages/ui/src/styles.css +2 -0
  415. package/packages/ui/src/switch.tsx +22 -0
  416. package/packages/ui/src/tabs.tsx +22 -0
  417. package/packages/ui/src/toast.tsx +36 -0
  418. package/packages/ui/src/tooltip.tsx +19 -0
  419. package/packages/ui/tsconfig.json +12 -0
  420. package/packages/vue/README.md +40 -0
  421. package/packages/vue/package.json +42 -0
  422. package/packages/vue/src/hooks/use-aeon-machine.ts +10 -0
  423. package/packages/vue/src/index.ts +2 -0
  424. package/packages/vue/src/switch/index.ts +208 -0
  425. package/packages/vue/src/utils/part-props.ts +8 -0
  426. package/packages/vue/tsconfig.json +8 -0
  427. package/pnpm-workspace.yaml +3 -0
  428. package/scripts/ensure-headless-built.mjs +25 -0
  429. package/tsconfig.base.json +21 -0
  430. package/vercel.json +12 -0
package/PUBLISHING.md ADDED
@@ -0,0 +1,85 @@
1
+ # Publishing to npm
2
+
3
+ Packages are versioned together at **0.1.0** (pre-release) using [Changesets](https://github.com/changesets/changesets).
4
+
5
+ ## Packages
6
+
7
+ | npm name | Path |
8
+ |----------|------|
9
+ | `@aeon-ui/core` | `packages/core` |
10
+ | `@aeon-ui/primitives` | `packages/primitives` |
11
+ | `@aeon-ui/react` | `packages/react` |
12
+ | `@aeon-ui/panda` | `packages/panda` |
13
+ | `@aeon-ui/ui` | `packages/ui` |
14
+ | `@aeon-ui/vue` | `packages/vue` |
15
+ | `@aeon-ui/solid` | `packages/solid` |
16
+ | `@aeon-ui/svelte` | `packages/svelte` |
17
+
18
+ All eight publishable packages are in a **fixed** changeset group — one version bump applies to every package.
19
+
20
+ ## Day-to-day versioning
21
+
22
+ 1. After shipping features or fixes, run `pnpm changeset` and describe the change.
23
+ 2. When ready to release, run `pnpm version-packages` (updates `package.json` versions and package CHANGELOGs).
24
+ 3. Run `pnpm build` and `pnpm typecheck`.
25
+ 4. Run `pnpm release` to publish (requires `npm login` and `@aeon-ui` scope access).
26
+
27
+ See `.changeset/README.md` for a short maintainer cheat sheet.
28
+
29
+ ## Before first publish (0.1.0)
30
+
31
+ 1. `pnpm install` — includes `@changesets/cli` and adapter deps.
32
+ 2. `pnpm build` — codegen + all package builds.
33
+ 3. `pnpm typecheck` — workspace clean.
34
+ 4. Confirm `files` in each `package.json` includes `dist` (and Panda `styled-system` / CSS assets; Svelte `.svelte` sources where applicable).
35
+ 5. Create npm org or scope `@aeon-ui` and login: `npm login`.
36
+ 6. Apply pending changesets: `pnpm version-packages`.
37
+ 7. Dry-run: `pnpm release --dry-run` (if your Changesets version supports it) or publish one package manually to verify.
38
+ 8. `pnpm release`.
39
+
40
+ ### Publish order (manual fallback)
41
+
42
+ Dependency order is satisfied automatically when all packages share one version and declare `workspace:*` / semver peers. Manual order if needed:
43
+
44
+ ```bash
45
+ pnpm --filter @aeon-ui/core publish --access public
46
+ pnpm --filter @aeon-ui/primitives publish --access public
47
+ pnpm --filter @aeon-ui/react publish --access public
48
+ pnpm --filter @aeon-ui/vue publish --access public
49
+ pnpm --filter @aeon-ui/solid publish --access public
50
+ pnpm --filter @aeon-ui/svelte publish --access public
51
+ pnpm --filter @aeon-ui/panda publish --access public
52
+ pnpm --filter @aeon-ui/ui publish --access public
53
+ ```
54
+
55
+ Prefer `pnpm release` once Changesets is in use.
56
+
57
+ ## Consumer install
58
+
59
+ **React + styled:**
60
+
61
+ ```bash
62
+ pnpm add @aeon-ui/ui @aeon-ui/react @aeon-ui/panda
63
+ ```
64
+
65
+ **Vue headless:**
66
+
67
+ ```bash
68
+ pnpm add @aeon-ui/vue @aeon-ui/core @aeon-ui/primitives xstate
69
+ ```
70
+
71
+ **Solid headless:**
72
+
73
+ ```bash
74
+ pnpm add @aeon-ui/solid @aeon-ui/core @aeon-ui/primitives xstate solid-js
75
+ ```
76
+
77
+ **Svelte headless:**
78
+
79
+ ```bash
80
+ pnpm add @aeon-ui/svelte @aeon-ui/core @aeon-ui/primitives xstate svelte
81
+ ```
82
+
83
+ ## Demo app
84
+
85
+ The `apps/demo` package stays private and is listed in Changesets `ignore`.
package/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # Aeon UI
2
+
3
+ **Future-proof UI infrastructure for the web.**
4
+
5
+ **State is defined first. UI represents the totality of that definition.**
6
+
7
+ > **Coding agents:** read **[AGENTS.md](./AGENTS.md)** first, then [docs/INDEX.md](./docs/INDEX.md). Human overview below.
8
+
9
+ Aeon UI models interactive behavior as executable [statecharts](https://www.theseus.fi/bitstream/handle/10024/334118/Thanh_Nguyen.pdf?sequence=2&isAllowed=y), exposes production-ready headless compound components, and ships a styled layer powered by **[Panda CSS](https://panda-css.com)** slot recipes aligned with `@aeon-ui/core` anatomy. Every primitive projects a full machine snapshot onto the DOM — structure, copy, and `data-aeon-state` stay in sync.
10
+
11
+ ## Packages
12
+
13
+ | Package | Purpose |
14
+ |---------|---------|
15
+ | `@aeon-ui/core` | Anatomy tokens, `data-aeon-*` attributes, machine helpers |
16
+ | `@aeon-ui/primitives` | XState machines (toggle, dialog, tabs, accordion, async, button lifecycle, field) |
17
+ | `@aeon-ui/react` | React headless bindings |
18
+ | `@aeon-ui/panda` | Design tokens, `defineSlotRecipe` styles, generated `styled-system` |
19
+ | `@aeon-ui/ui` | Styled components (`aeonButton`, `aeonAccordion`, …) |
20
+ | `@aeon-ui/vue` | Vue 3 headless adapter (v0.1: Switch + `useAeonMachine`) |
21
+ | `@aeon-ui/solid` | Solid headless adapter (v0.1: Switch + `useAeonMachine`) |
22
+ | `@aeon-ui/svelte` | Svelte headless adapter (v0.1: Switch + `useAeonMachine`) |
23
+
24
+ **Catalog (React):** Button, Switch, Checkbox, Dialog, Tabs, Accordion, Select, **Combobox**, Async, Field, Scroll, **Menu**, **Popover**, **Tooltip**, **Toast** — see [COMPONENTS.md](./COMPONENTS.md). **Vue / Solid / Svelte:** reference Switch port; more components follow — [FRAMEWORKS.md](./FRAMEWORKS.md).
25
+
26
+ ## Quick start
27
+
28
+ **Early access** — DM FOR EARLY ACCESS (npm publish is wired via Changesets; public install docs ship when the scope is live).
29
+
30
+ Open [https://github.com/GenericCPU/aeon-ui](https://github.com/GenericCPU/aeon-ui) for the repo. The marketing demo lives at [https://aeon-ui.com](https://aeon-ui.com) — set `VITE_SITE_ORIGIN` to that origin in Vercel so Open Graph previews resolve `og.png` correctly.
31
+
32
+ When published: `pnpm add @aeon-ui/ui @aeon-ui/react @aeon-ui/panda`
33
+
34
+ After changing recipes or tokens in `packages/panda`:
35
+
36
+ ```bash
37
+ pnpm codegen
38
+ ```
39
+
40
+ ## Styling (Panda CSS)
41
+
42
+ Recipes live in `packages/panda/src/recipes/` and map to core anatomy parts (`accordion`, `dialog`, `tabs`, …). The styled layer applies them:
43
+
44
+ ```tsx
45
+ import { aeonAccordion } from '@aeon-ui/panda/styled-system/recipes'
46
+
47
+ const styles = aeonAccordion()
48
+ // styles.root, styles.itemTrigger, …
49
+ ```
50
+
51
+ Apps import generated CSS once, then runtime theme overrides (required for light/dark):
52
+
53
+ ```tsx
54
+ import '@aeon-ui/panda/styles.css'
55
+ import '@aeon-ui/panda/theme-runtime.css'
56
+ import '@aeon-ui/panda/scrollbars.css'
57
+ import '@aeon-ui/panda/chrome.css'
58
+ ```
59
+
60
+ Legacy `--aeon-*` CSS variables are still emitted on `:root` for landing layout and gradual migration.
61
+
62
+ ## Themes (light / dark × mood)
63
+
64
+ Edit **`packages/panda/src/theme/themes.config.ts`** — one entry per mood (`default`, `signal`, `berry`, `slate`, `neon`, …), each with `light` + `dark` palette fields. Run `pnpm codegen` in `packages/panda` to regenerate `theme-runtime.css`.
65
+
66
+ ```ts
67
+ // themes.config.ts — add a mood
68
+ {
69
+ id: 'brand',
70
+ label: 'Brand',
71
+ description: 'Your product',
72
+ light: { bg: '#f5f5f5', surface: '#fff', border: '#ddd', text: '#111', muted: '#666', accent: '#3366ff' },
73
+ dark: { bg: '#0a0a0a', surface: '#141414', border: '#333', text: '#eee', muted: '#999', accent: '#6699ff' },
74
+ }
75
+ ```
76
+
77
+ Runtime API:
78
+
79
+ ```ts
80
+ import { applyAeonTheme, AEON_THEMES } from '@aeon-ui/panda/themes'
81
+
82
+ applyAeonTheme('ocean', 'light')
83
+ ```
84
+
85
+ Built-in moods: **Aeon**, **Signal**, **Dusk**, **Calm**, **Ocean**, **Ember**, **Frost**, **Dawn**, **Forest**, **Noir**. The demo uses a custom **Select** (not the OS dropdown) plus a Light/Dark rail.
86
+
87
+ **Focus policy:** `chrome.css` shows focus rings only for keyboard (`:focus-visible`). Selected tabs, pressed buttons, and open selects use surface tint — not a focus “circle” on click.
88
+
89
+ ## Docs
90
+
91
+ | Doc | Purpose |
92
+ |-----|---------|
93
+ | **[AGENTS.md](./AGENTS.md)** | **LLM/agent entry — rules, workflows, naming** |
94
+ | [docs/INDEX.md](./docs/INDEX.md) | Full documentation map |
95
+ | [docs/MACHINES.md](./docs/MACHINES.md) | Machine vs prop vs `useState` (ground truth) |
96
+ | [docs/LAYOUT_COORDINATES.md](./docs/LAYOUT_COORDINATES.md) | Responsive play surfaces — normalized coordinate plane |
97
+ | [docs/COMPONENT_CHECKLIST.md](./docs/COMPONENT_CHECKLIST.md) | Add or change a component (ordered steps) |
98
+ | [COMPONENTS.md](./COMPONENTS.md) | What ships today vs planned |
99
+ | [INTEGRATION.md](./INTEGRATION.md) | Headless, Panda, Tailwind |
100
+ | [PUBLISHING.md](./PUBLISHING.md) | npm release checklist |
101
+ | [FRAMEWORKS.md](./FRAMEWORKS.md) | React now; adapter contract |
102
+ | [ACCESSIBILITY.md](./ACCESSIBILITY.md) | Roles, focus, checklist |
103
+
104
+ ## Philosophy & state catalog
105
+
106
+ Read [PHILOSOPHY.md](./PHILOSOPHY.md) and **[STATES.md](./STATES.md)** — gaps traditional UI leaves implicit (empty vs idle, button pending/success, orthogonal field regions) and how Aeon models them.
107
+
108
+ **UI = f(state).** Define every stable condition in the chart; build UI that expresses the whole definition, not a fragment of it.
109
+
110
+ ### Async region (totality)
111
+
112
+ ```tsx
113
+ import { Async, Button } from '@aeon-ui/ui'
114
+
115
+ <Async.Root>
116
+ <Async.Track />
117
+ <Async.Readout>Ready when you are</Async.Readout>
118
+ <Async.Actions>
119
+ <Button.Root size="sm">Fetch</Button.Root>
120
+ </Async.Actions>
121
+ </Async.Root>
122
+ ```
123
+
124
+ ## Example
125
+
126
+ ```tsx
127
+ import { Dialog, Button, Switch } from '@aeon-ui/ui'
128
+
129
+ <Switch.Root defaultChecked>
130
+ <Switch.Control><Switch.Thumb /></Switch.Control>
131
+ <Switch.Label>Notifications</Switch.Label>
132
+ </Switch.Root>
133
+
134
+ <Dialog.Root>
135
+ <Dialog.Trigger><Button.Root>Open</Button.Root></Dialog.Trigger>
136
+ <Dialog.Backdrop />
137
+ <Dialog.Positioner>
138
+ <Dialog.Content>
139
+ <Dialog.Title>Title</Dialog.Title>
140
+ <Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
141
+ </Dialog.Content>
142
+ </Dialog.Positioner>
143
+ </Dialog.Root>
144
+ ```
145
+
146
+ Headless usage:
147
+
148
+ ```tsx
149
+ import { Dialog } from '@aeon-ui/react'
150
+ ```
151
+
152
+ ## License
153
+
154
+ MIT
package/SCENE.md ADDED
@@ -0,0 +1,113 @@
1
+ # Aeon Scene (optional plane)
2
+
3
+ **Control plane** (`@aeon-ui/primitives`, `@aeon-ui/react`, `@aeon-ui/ui`) models interactive UI with statecharts.
4
+
5
+ **Scene plane** adds ambient visuals — geometry, materials, and audio-driven motion — without changing that contract.
6
+
7
+ ## Packages
8
+
9
+ | Package | Role |
10
+ |---------|------|
11
+ | `@aeon-ui/signal` | Web Audio analyser tap, FFT bands, bar motion smoothing |
12
+ | `@aeon-ui/geometry` | Grid/wave patterns, SVG bar layout, `sceneAttrs()` |
13
+ | `@aeon-ui/surface` | Procedural CSS materials (stone, gravel, brick, pavement, kraft) — import `surface.css` once |
14
+ | `@aeon-ui/scene` | CSS 3D transforms, perspective, wall clips (framework-agnostic) |
15
+ | `@aeon-ui/react-scene` | React: backdrops/visualizers + `SceneStage`, `SceneLayer`, `ScenePlane`, `SceneSlot` |
16
+
17
+ Install only what you need. Sic Bo might use `surface` + `geometry`; a player app might add `signal` + `react-scene`.
18
+
19
+ ## Quick start (React)
20
+
21
+ ```bash
22
+ pnpm add @aeon-ui/react-scene @aeon-ui/signal @aeon-ui/geometry @aeon-ui/surface
23
+ ```
24
+
25
+ ```tsx
26
+ import '@aeon-ui/surface/surface.css'
27
+ import { SceneRoot, SceneSurface, SignalBars } from '@aeon-ui/react-scene'
28
+ import { createDemoSignal } from '@aeon-ui/signal'
29
+
30
+ // Demo oscillator for playgrounds (use attachMediaAnalyser(audio) in production)
31
+ const demo = createDemoSignal()
32
+ demo.start()
33
+
34
+ <SceneRoot state="active">
35
+ <SceneSurface material="stone" style={{ minHeight: 120 }} />
36
+ <SignalBars analyser={demo.analyser} active barCount={7} />
37
+ </SceneRoot>
38
+ ```
39
+
40
+ ## Anatomy
41
+
42
+ Scene regions use the same attribute story as controls:
43
+
44
+ - `data-aeon-scope="scene"`
45
+ - `data-aeon-part="backdrop" | "grid" | "surface" | "visualizer" | …`
46
+ - `data-aeon-state="idle" | "active" | "paused"` when playback or motion applies
47
+
48
+ Style with Panda/CSS like any other Aeon part — no requirement to use `@aeon-ui/ui` components.
49
+
50
+ ## Construct a 3D scene from UI elements
51
+
52
+ Use **CSS 3D** (not WebGL): a `SceneStage` sets perspective; `SceneRoom` builds a box (floor, ceiling, back, left, right) with one shared vanishing point; `SceneLayer` / `ScenePlane` cover ad-hoc layouts; `SceneSlot` mounts interactive UI at a transform. Prefer `SceneRoom` for alley/corridor spaces.
53
+
54
+ ```bash
55
+ pnpm add @aeon-ui/react-scene @aeon-ui/scene @aeon-ui/surface @aeon-ui/geometry
56
+ ```
57
+
58
+ ```tsx
59
+ import '@aeon-ui/surface/surface.css'
60
+ import '@aeon-ui/react-scene/scene-3d.css'
61
+ import { SceneStage, SceneRoom, SceneLayer, ScenePlane, SceneSlot } from '@aeon-ui/react-scene'
62
+
63
+ <SceneStage minHeight={360} perspective={{ distance: 1100, origin: '50% 48%' }}>
64
+ <SceneRoom
65
+ size={{ width: 1280, height: 680, depth: 920 }}
66
+ camera={{ pitch: 11, offsetZ: -60 }}
67
+ floorMaterial="pavement"
68
+ wallMaterial="brick"
69
+ floor={<YourGameBoard />}
70
+ />
71
+ </SceneStage>
72
+
73
+ <!-- Or manual layers: -->
74
+ <SceneStage minHeight={360} perspective={{ distance: 1000, origin: '50% 38%' }}>
75
+ <SceneLayer transform={{ z: -140 }}>
76
+ <ScenePlane part="sky" style={{ background: 'linear-gradient(180deg, #1a2030, #0d1117)' }} />
77
+ </SceneLayer>
78
+
79
+ <SceneLayer transform={{ z: -70, rotateY: 38 }} origin="0% 100%">
80
+ <ScenePlane part="wall-left" wall="left" material="brick" fill={false} style={{ width: '52%', height: '72%' }} />
81
+ </SceneLayer>
82
+
83
+ <SceneLayer transform={{ z: -70, rotateY: -38 }} origin="100% 100%">
84
+ <ScenePlane part="wall-right" wall="right" material="brick" fill={false} style={{ right: 0, width: '52%', height: '72%' }} />
85
+ </SceneLayer>
86
+
87
+ <SceneLayer transform={{ z: 0, rotateX: 58 }} origin="50% 0%">
88
+ <ScenePlane part="ground" material="gravel">
89
+ <SceneSlot transform={{ z: 24 }} style={{ left: '12%', right: '12%', top: '18%' }}>
90
+ {/* Any React UI — table, cards, controls */}
91
+ <YourGameBoard />
92
+ </SceneSlot>
93
+ </ScenePlane>
94
+ </SceneLayer>
95
+ </SceneStage>
96
+ ```
97
+
98
+ **Image URLs (optional):** pass `texture="…"` on `ScenePlane` when you have art assets. Prefer `@aeon-ui/surface` classes (`aeon-surface--pavement`, `--kraft`, `--brick`, …) for zero-asset materials — see the Sic Bo alley demo.
99
+
100
+ **Low-level:** import `sceneTransformStyle`, `sceneStageStyle`, `sceneWallClip` from `@aeon-ui/scene` for Vue/Solid/Svelte bindings.
101
+
102
+ Layers use `data-aeon-scope="scene"` and `data-aeon-part` from `@aeon-ui/geometry` — style in Panda/CSS like controls.
103
+
104
+ ## Soundbase lineage
105
+
106
+ Bar motion and analyser patterns are adapted from the Soundbase logo visualizer (`logo-visualizer-core`, `logo-audio-analyser`). Product-specific logos stay in the app; the math lives in `@aeon-ui/signal`.
107
+
108
+ ## What not to put here
109
+
110
+ - Form controls, dialogs, async data — stay in **primitives / ui**
111
+ - Full WebGL/game engines — separate packages or app code; Scene provides CSS/SVG/canvas-friendly building blocks first
112
+
113
+ Future: `@aeon-ui/vue-scene`, canvas render targets, image-based texture atlases, shared `@aeon-ui/motion` for non-audio springs. WebGL/Three.js stays app-level; Scene 3D is DOM + CSS transforms first.
package/STATES.md ADDED
@@ -0,0 +1,243 @@
1
+ # States traditional UI forgets — and how Aeon models them
2
+
3
+ **Agents:** start at [AGENTS.md](./AGENTS.md) and [docs/MACHINES.md](./docs/MACHINES.md) for which components use machines vs props.
4
+
5
+ Aeon’s north star: **[state is defined first; UI expresses the totality of that definition](./PHILOSOPHY.md)** (`UI = f(snapshot)`).
6
+
7
+ Traditional interfaces collapse rich behavior into a few booleans (`disabled`, `loading`, `open`) or hide conditions entirely. This document catalogs common gaps, how Aeon addresses them today, and how to extend the library.
8
+
9
+ ---
10
+
11
+ ## The attribute contract
12
+
13
+ Every styled surface should be targetable consistently:
14
+
15
+ | Attribute | Purpose |
16
+ |-----------|---------|
17
+ | `data-aeon-scope` | Component family (`button`, `async`, `field`, …) |
18
+ | `data-aeon-part` | Compound part (`root`, `track`, `control`, …) |
19
+ | `data-aeon-state` | Active condition(s) from the machine snapshot |
20
+
21
+ Nested parallel regions flatten with `stateToAttr` from `@aeon-ui/core`:
22
+
23
+ ```ts
24
+ import { stateToAttr } from '@aeon-ui/core'
25
+ // e.g. "interaction:dirty validation:invalid submission:idle"
26
+ ```
27
+
28
+ Panda recipes and `globalCss` in `@aeon-ui/panda` key off these attributes — not ad hoc class names in product code.
29
+
30
+ ---
31
+
32
+ ## 1. Async data regions
33
+
34
+ ### What traditional UI skips
35
+
36
+ | Condition | Typical mistake |
37
+ |-----------|-----------------|
38
+ | **Idle** (never fetched) | Looks like “empty” |
39
+ | **Loading** | Spinner with no named state |
40
+ | **Success** | Only happy path styled |
41
+ | **Failure** | Toast only, easy to miss |
42
+ | **Empty** (success, zero results) | Same UI as idle |
43
+ | **Stale** (success + background refresh) | Silent flicker |
44
+
45
+ ### Aeon model
46
+
47
+ Machine: `createAsyncMachine()` in `@aeon-ui/primitives`
48
+ States: `idle` · `loading` · `success` · `failure` · `empty`
49
+ Context flag: `stale` on success → readout uses `data-aeon-state="success stale"`
50
+
51
+ Constants: `ASYNC_LIFECYCLE_STATES`, `isEmptyAsyncData()`
52
+
53
+ ### UI kit (totality pattern)
54
+
55
+ ```tsx
56
+ import { Async, Button } from '@aeon-ui/ui'
57
+
58
+ <Async.Root>
59
+ <Async.Track /> {/* every lifecycle state visible on the rail */}
60
+ <Async.Readout>…</Async.Readout>
61
+ <Async.Actions>
62
+ <Button.Root>Fetch</Button.Root>
63
+ </Async.Actions>
64
+ </Async.Root>
65
+ ```
66
+
67
+ Headless: `@aeon-ui/react` → `Async`, `useAsyncContext`
68
+ Anatomy: `asyncAnatomy` (`track`, `segment`, `readout`, `actions`, …)
69
+ Styles: `aeonAsync` slot recipe
70
+
71
+ **Rule:** If the chart lists five states, the track lists five segments — one active, none implicit.
72
+
73
+ ---
74
+
75
+ ## 2. Action button lifecycle
76
+
77
+ ### What traditional UI skips
78
+
79
+ `disabled` is used for: in-flight submit, success, permission denied, validation blocked, and “busy”.
80
+
81
+ Missing named states: **pending**, **success**, **failure**, distinct from **disabled**.
82
+
83
+ ### Aeon model
84
+
85
+ Machine: `buttonLifecycleMachine`
86
+ States: `idle` · `pending` · `success` · `failure` · `disabled`
87
+
88
+ ### Component API
89
+
90
+ ```tsx
91
+ <Button.Root status="pending" aria-busy>
92
+ Submitting…
93
+ </Button.Root>
94
+ ```
95
+
96
+ `status` maps to `data-aeon-state`. Global styles adjust cursor/opacity/border per state.
97
+
98
+ For full chart-driven flows, run `buttonLifecycleMachine` with `useAeonMachine` and drive `status` from `snapshot.value` (see playground **Button lifecycle**).
99
+
100
+ ---
101
+
102
+ ## 3. Form field (orthogonal regions)
103
+
104
+ ### What traditional UI skips
105
+
106
+ Interaction, validation, and submission are merged into one visual “error state.”
107
+
108
+ ### Aeon model
109
+
110
+ Machine: `fieldMachine` (parallel)
111
+
112
+ | Region | States |
113
+ |--------|--------|
114
+ | `interaction` | `pristine` · `dirty` |
115
+ | `validation` | `valid` · `invalid` |
116
+ | `submission` | `idle` · `pending` |
117
+
118
+ Root: `data-aeon-state="interaction:dirty validation:invalid submission:idle"`
119
+
120
+ ### Component API
121
+
122
+ ```tsx
123
+ import { Field } from '@aeon-ui/ui'
124
+
125
+ <Field.Root>
126
+ <Field.Label htmlFor="email">Email</Field.Label>
127
+ <Field.Control id="email" validate={(v) => isValidEmail(v)} />
128
+ <Field.Message>Enter a valid email.</Field.Message>
129
+ <Field.Hint>Shown when pristine.</Field.Hint>
130
+ </Field.Root>
131
+ ```
132
+
133
+ `Field.Control` sends `INPUT`, `BLUR`, and `VALIDATE` events.
134
+ `Field.Message` renders only when `validation:invalid`.
135
+ Pending submission dims the control via `[data-aeon-state*="submission:pending"]` in global CSS.
136
+
137
+ ---
138
+
139
+ ## 4. Primitives already chart-backed
140
+
141
+ | Primitive | Stable states (high level) |
142
+ |-----------|----------------------------|
143
+ | **Dialog** | `closed` · `open` |
144
+ | **Toggle / Switch** | `checked` / `unchecked` + interaction `idle` · `pressed` |
145
+ | **Tabs** | single active value |
146
+ | **Accordion** | per-item open/closed |
147
+
148
+ Future optional substates (documented, not all implemented): dialog `entering` / `exiting`, accordion `expanding` / `collapsing`.
149
+
150
+ ---
151
+
152
+ ## 5. Scroll regions
153
+
154
+ ### What traditional UI skips
155
+
156
+ Scroll position is implicit. Overflow axis (vertical, horizontal, or both) and whether the user is at the start, middle, or end of each axis are rarely reflected in the DOM — so edge fades, scrollbar styling, and assistive hints stay out of sync.
157
+
158
+ ### Aeon model
159
+
160
+ No XState machine — `getScrollSnapshot()` in `@aeon-ui/core` derives state from the viewport element on scroll and resize.
161
+
162
+ | `data-aeon-state` token | Meaning |
163
+ |-------------------------|---------|
164
+ | `idle` | No overflow on either axis |
165
+ | `overflow-y` · `overflow-x` · `overflow-both` | Which axes scroll |
166
+ | `at-start-y` · `between-y` · `at-end-y` | Vertical edge position |
167
+ | `at-start-x` · `between-x` · `at-end-x` | Horizontal edge position |
168
+
169
+ ### Component API
170
+
171
+ ```tsx
172
+ import { Scroll } from '@aeon-ui/ui'
173
+
174
+ <Scroll.Root axis="both" maxH="md">
175
+ <Scroll.Viewport>
176
+ <Scroll.Content>{children}</Scroll.Content>
177
+ </Scroll.Viewport>
178
+ <Scroll.StateReadout />
179
+ </Scroll.Root>
180
+ ```
181
+
182
+ Import `@aeon-ui/panda/scrollbars.css` after `theme-runtime.css` for WebKit + Firefox scrollbar styling on `html`, `[data-aeon-scroll]`, and `.code-example`.
183
+
184
+ ---
185
+
186
+ ## 6. States to model in product code
187
+
188
+ Aeon does not ship every domain machine, but the same rules apply:
189
+
190
+ | Concern | Suggested states |
191
+ |---------|------------------|
192
+ | **Offline** | `online` · `offline` · `reconnecting` |
193
+ | **Permissions** | `allowed` · `denied` (not `disabled`) |
194
+ | **Optimistic UI** | `optimistic` · `confirmed` · `rolledBack` |
195
+ | **Rate limit** | `ok` · `throttled` |
196
+ | **Selection** | add `indeterminate` on checkboxes |
197
+
198
+ Use **orthogonal regions** when concerns are independent (Nguyen / Harel statecharts).
199
+
200
+ ---
201
+
202
+ ## 7. Styling checklist
203
+
204
+ Full ordered steps: **[docs/COMPONENT_CHECKLIST.md](./docs/COMPONENT_CHECKLIST.md)**.
205
+
206
+ 1. Model the chart in `@aeon-ui/primitives` (or app-level XState).
207
+ 2. Add anatomy in `@aeon-ui/core` if new scope.
208
+ 3. Project snapshot in `@aeon-ui/react` with `partAttrs` / `stateToAttr`.
209
+ 4. Add slot recipe or `globalCss` keyed on `data-aeon-state` in `@aeon-ui/panda`.
210
+ 5. Export styled compound from `@aeon-ui/ui`.
211
+ 6. Demo the **full rail** — track + readout + actions.
212
+
213
+ ---
214
+
215
+ ## 8. Play-surface layout (spatial, not XState)
216
+
217
+ Games and spatial UIs need **desktop vs mobile composition** without breaking pointer math. Aeon models this separately from behavior:
218
+
219
+ - **Layout mode** — `compact` | `wide` on `data-aeon-layout-mode`
220
+ - **Composition** — `split` | `stack` | `overlay` on `data-aeon-layout-composition`
221
+ - **Normalized coordinates** — `normFromClient` / `clientFromNorm` in `@aeon-ui/core` (0–100 plane per measured region)
222
+
223
+ Full guide: **[docs/LAYOUT_COORDINATES.md](./docs/LAYOUT_COORDINATES.md)** · Anatomy: `playSurfaceAnatomy` · Hook: `useLayoutMode`.
224
+
225
+ ---
226
+
227
+ ## 9. Package map
228
+
229
+ | Package | Role |
230
+ |---------|------|
231
+ | `@aeon-ui/primitives` | Machines: `async`, `buttonLifecycle`, `field`, … |
232
+ | `@aeon-ui/core` | `asyncAnatomy`, `fieldAnatomy`, `scrollAnatomy`, `getScrollSnapshot` |
233
+ | `@aeon-ui/react` | `Async.*`, `Field.*`, `Scroll.*`, `Button` + `status` |
234
+ | `@aeon-ui/panda` | `aeonAsync`, `aeonField`, `aeonScroll`, `scrollbars.css` |
235
+ | `@aeon-ui/ui` | Styled exports |
236
+
237
+ ---
238
+
239
+ ## References
240
+
241
+ - [PHILOSOPHY.md](./PHILOSOPHY.md) — north star and tenets
242
+ - [Thanh Nguyen (2020) — Statecharts for modern web application state management](https://www.theseus.fi/bitstream/handle/10024/334118/Thanh_Nguyen.pdf?sequence=2&isAllowed=y)
243
+ - Live examples: `apps/demo` playground (**Async region**, **Button lifecycle**, **Field regions**, **Scroll regions**)
@@ -0,0 +1,31 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Aeon UI — Future-proof UI infrastructure</title>
7
+ <!-- OG_META -->
8
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
10
+ <link
11
+ href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=Instrument+Sans:wght@400;500;600;700&family=Syne:wght@600;700;800&display=swap"
12
+ rel="stylesheet"
13
+ />
14
+ </head>
15
+ <body>
16
+ <div id="root"></div>
17
+ <script>
18
+ (function () {
19
+ var t = localStorage.getItem('aeon-theme') || 'default';
20
+ var m = localStorage.getItem('aeon-mode');
21
+ if (m !== 'light' && m !== 'dark') {
22
+ m = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
23
+ }
24
+ document.documentElement.dataset.aeonTheme = t;
25
+ document.documentElement.dataset.aeonMode = m;
26
+ document.documentElement.style.colorScheme = m;
27
+ })();
28
+ </script>
29
+ <script type="module" src="/src/main.tsx"></script>
30
+ </body>
31
+ </html>
@@ -0,0 +1,15 @@
1
+ /** Shared OG / canonical URLs — override in CI with VITE_SITE_ORIGIN. */
2
+ export const siteOrigin = (process.env.VITE_SITE_ORIGIN ?? 'https://aeon-ui.com').replace(
3
+ /\/$/,
4
+ '',
5
+ )
6
+
7
+ export const og = {
8
+ title: 'Aeon UI — Future-proof UI infrastructure',
9
+ description:
10
+ 'Statechart-driven headless primitives and a Panda CSS styled layer — dependable behavior, anatomy you can theme, built to last.',
11
+ siteName: 'Aeon UI',
12
+ imagePath: '/og.png',
13
+ imageAlt: 'Aeon UI — Future-proof UI infrastructure for the web',
14
+ themeColor: '#0c0e12',
15
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@aeon-ui/demo",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "dev": "vite",
7
+ "generate:og": "node scripts/generate-og-png.mjs",
8
+ "build": "pnpm --filter @aeon-ui/panda codegen && pnpm --filter @aeon-ui/site build && node scripts/generate-og-png.mjs && vite build",
9
+ "preview": "vite preview",
10
+ "typecheck": "tsc --noEmit"
11
+ },
12
+ "dependencies": {
13
+ "@aeon-ui/geometry": "workspace:*",
14
+ "@aeon-ui/panda": "workspace:*",
15
+ "@aeon-ui/primitives": "workspace:*",
16
+ "@aeon-ui/react": "workspace:*",
17
+ "@aeon-ui/react-scene": "workspace:*",
18
+ "@aeon-ui/signal": "workspace:*",
19
+ "@aeon-ui/surface": "workspace:*",
20
+ "@aeon-ui/ui": "workspace:*",
21
+ "@xstate/react": "^5.0.3",
22
+ "mermaid": "^11.15.0",
23
+ "react": "^19.1.0",
24
+ "react-dom": "^19.1.0",
25
+ "xstate": "^5.19.2"
26
+ },
27
+ "devDependencies": {
28
+ "@aeon-ui/site": "workspace:*",
29
+ "@fontsource/ibm-plex-mono": "^5.2.7",
30
+ "@fontsource/instrument-sans": "^5.2.8",
31
+ "@fontsource/syne": "^5.2.7",
32
+ "@resvg/resvg-js": "^2.6.2",
33
+ "@types/node": "^22.15.3",
34
+ "@types/react": "^19.1.2",
35
+ "@types/react-dom": "^19.1.2",
36
+ "@vitejs/plugin-react": "^4.4.1",
37
+ "typescript": "^5.8.3",
38
+ "vite": "^6.3.5",
39
+ "wawoff2": "^2.0.1"
40
+ }
41
+ }