aeon-ui-engine 1.0.1 → 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.
- package/CHANGELOG.md +51 -0
- package/CONSUMER.md +86 -0
- package/INTEGRATION.md +2 -0
- package/README.md +15 -4
- package/package.json +17 -1
- package/packages/core/dist/index.d.ts +257 -0
- package/packages/core/dist/index.js +378 -0
- package/packages/core/node_modules/.bin/esbuild +21 -0
- package/packages/core/node_modules/.bin/jiti +21 -0
- package/packages/core/node_modules/.bin/tsc +21 -0
- package/packages/core/node_modules/.bin/tsserver +21 -0
- package/packages/core/node_modules/.bin/tsup +21 -0
- package/packages/core/node_modules/.bin/tsup-node +21 -0
- package/packages/core/node_modules/.bin/tsx +21 -0
- package/packages/core/node_modules/.bin/vite +21 -0
- package/packages/core/node_modules/.bin/vitest +21 -0
- package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/geometry/dist/index.d.ts +50 -0
- package/packages/geometry/dist/index.js +88 -0
- package/packages/geometry/node_modules/.bin/esbuild +21 -0
- package/packages/geometry/node_modules/.bin/jiti +21 -0
- package/packages/geometry/node_modules/.bin/tsc +21 -0
- package/packages/geometry/node_modules/.bin/tsserver +21 -0
- package/packages/geometry/node_modules/.bin/tsup +21 -0
- package/packages/geometry/node_modules/.bin/tsup-node +21 -0
- package/packages/geometry/node_modules/.bin/tsx +21 -0
- package/packages/panda/src/recipes/button.ts +4 -4
- package/packages/panda/src/recipes/combobox.ts +1 -1
- package/packages/panda/src/recipes/select.ts +1 -1
- package/packages/panda/src/theme/tokens.ts +5 -0
- package/packages/panda/styled-system/styles.css +10 -6
- package/packages/panda/styled-system/tokens/index.mjs +32 -0
- package/packages/panda/styled-system/tokens/tokens.d.ts +2 -2
- package/packages/primitives/dist/chunk-5S4DIRL4.js +42 -0
- package/packages/primitives/dist/chunk-H4KOEPYC.js +52 -0
- package/packages/primitives/dist/chunk-HONROWUG.js +41 -0
- package/packages/primitives/dist/chunk-J6JHKMVM.js +90 -0
- package/packages/primitives/dist/chunk-JBAG5E6W.js +46 -0
- package/packages/primitives/dist/chunk-LVNCD5F2.js +43 -0
- package/packages/primitives/dist/chunk-PB3LFHXU.js +72 -0
- package/packages/primitives/dist/chunk-SZV6KGXN.js +49 -0
- package/packages/primitives/dist/chunk-WVICCOQH.js +56 -0
- package/packages/primitives/dist/chunk-ZMGRX64G.js +74 -0
- package/packages/primitives/dist/index.d.ts +11 -0
- package/packages/primitives/dist/index.js +60 -0
- package/packages/primitives/dist/machines/accordion.d.ts +34 -0
- package/packages/primitives/dist/machines/accordion.js +6 -0
- package/packages/primitives/dist/machines/async.d.ts +111 -0
- package/packages/primitives/dist/machines/async.js +12 -0
- package/packages/primitives/dist/machines/button.d.ts +45 -0
- package/packages/primitives/dist/machines/button.js +8 -0
- package/packages/primitives/dist/machines/dialog.d.ts +57 -0
- package/packages/primitives/dist/machines/dialog.js +6 -0
- package/packages/primitives/dist/machines/field.d.ts +72 -0
- package/packages/primitives/dist/machines/field.js +12 -0
- package/packages/primitives/dist/machines/popover.d.ts +54 -0
- package/packages/primitives/dist/machines/popover.js +6 -0
- package/packages/primitives/dist/machines/slider.d.ts +71 -0
- package/packages/primitives/dist/machines/slider.js +10 -0
- package/packages/primitives/dist/machines/tabs.d.ts +39 -0
- package/packages/primitives/dist/machines/tabs.js +6 -0
- package/packages/primitives/dist/machines/toast.d.ts +31 -0
- package/packages/primitives/dist/machines/toast.js +6 -0
- package/packages/primitives/dist/machines/toggle.d.ts +54 -0
- package/packages/primitives/dist/machines/toggle.js +6 -0
- package/packages/primitives/node_modules/.bin/jiti +21 -0
- package/packages/primitives/node_modules/.bin/tsc +21 -0
- package/packages/primitives/node_modules/.bin/tsserver +21 -0
- package/packages/primitives/node_modules/.bin/tsup +21 -0
- package/packages/primitives/node_modules/.bin/tsup-node +21 -0
- package/packages/primitives/node_modules/.bin/tsx +21 -0
- package/packages/primitives/node_modules/.bin/vitest +21 -0
- package/packages/primitives/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/react/dist/index.d.ts +564 -0
- package/packages/react/dist/index.js +3461 -0
- package/packages/react/node_modules/.bin/jiti +21 -0
- package/packages/react/node_modules/.bin/tsc +21 -0
- package/packages/react/node_modules/.bin/tsserver +21 -0
- package/packages/react/node_modules/.bin/tsup +21 -0
- package/packages/react/node_modules/.bin/tsup-node +21 -0
- package/packages/react/node_modules/.bin/tsx +21 -0
- package/packages/react/node_modules/.bin/vitest +21 -0
- package/packages/react/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/react-scene/dist/index.d.ts +121 -0
- package/packages/react-scene/dist/index.js +430 -0
- package/packages/react-scene/node_modules/.bin/jiti +21 -0
- package/packages/react-scene/node_modules/.bin/tsc +21 -0
- package/packages/react-scene/node_modules/.bin/tsserver +21 -0
- package/packages/react-scene/node_modules/.bin/tsup +21 -0
- package/packages/react-scene/node_modules/.bin/tsup-node +21 -0
- package/packages/react-scene/node_modules/.bin/tsx +21 -0
- package/packages/scene/dist/index.d.ts +46 -0
- package/packages/scene/dist/index.js +54 -0
- package/packages/scene/node_modules/.bin/jiti +21 -0
- package/packages/scene/node_modules/.bin/tsc +21 -0
- package/packages/scene/node_modules/.bin/tsserver +21 -0
- package/packages/scene/node_modules/.bin/tsup +21 -0
- package/packages/scene/node_modules/.bin/tsup-node +21 -0
- package/packages/scene/node_modules/.bin/tsx +21 -0
- package/packages/signal/dist/index.d.ts +54 -0
- package/packages/signal/dist/index.js +169 -0
- package/packages/signal/node_modules/.bin/jiti +21 -0
- package/packages/signal/node_modules/.bin/tsc +21 -0
- package/packages/signal/node_modules/.bin/tsserver +21 -0
- package/packages/signal/node_modules/.bin/tsup +21 -0
- package/packages/signal/node_modules/.bin/tsup-node +21 -0
- package/packages/signal/node_modules/.bin/tsx +21 -0
- package/packages/site/dist/index.d.ts +31 -0
- package/packages/site/dist/index.js +62 -0
- package/packages/site/node_modules/.bin/jiti +21 -0
- package/packages/site/node_modules/.bin/tsc +21 -0
- package/packages/site/node_modules/.bin/tsserver +21 -0
- package/packages/site/node_modules/.bin/tsup +21 -0
- package/packages/site/node_modules/.bin/tsup-node +21 -0
- package/packages/site/node_modules/.bin/tsx +21 -0
- package/packages/solid/dist/index.d.ts +30 -0
- package/packages/solid/dist/index.js +174 -0
- package/packages/solid/node_modules/.bin/jiti +21 -0
- package/packages/solid/node_modules/.bin/tsc +21 -0
- package/packages/solid/node_modules/.bin/tsserver +21 -0
- package/packages/solid/node_modules/.bin/tsup +21 -0
- package/packages/solid/node_modules/.bin/tsup-node +21 -0
- package/packages/solid/node_modules/.bin/tsx +21 -0
- package/packages/surface/dist/index.d.ts +8 -0
- package/packages/surface/dist/index.js +14 -0
- package/packages/surface/node_modules/.bin/jiti +21 -0
- package/packages/surface/node_modules/.bin/tsc +21 -0
- package/packages/surface/node_modules/.bin/tsserver +21 -0
- package/packages/surface/node_modules/.bin/tsup +21 -0
- package/packages/surface/node_modules/.bin/tsup-node +21 -0
- package/packages/surface/node_modules/.bin/tsx +21 -0
- package/packages/svelte/dist/index.d.ts +12 -0
- package/packages/svelte/dist/index.js +15 -0
- package/packages/svelte/node_modules/.bin/acorn +21 -0
- package/packages/svelte/node_modules/.bin/jiti +21 -0
- package/packages/svelte/node_modules/.bin/svelte-check +21 -0
- package/packages/svelte/node_modules/.bin/tsc +21 -0
- package/packages/svelte/node_modules/.bin/tsserver +21 -0
- package/packages/svelte/node_modules/.bin/tsup +21 -0
- package/packages/svelte/node_modules/.bin/tsup-node +21 -0
- package/packages/svelte/node_modules/.bin/tsx +21 -0
- package/packages/svelte/node_modules/.bin/vite +21 -0
- package/packages/ui/dist/index.d.ts +200 -0
- package/packages/ui/dist/index.js +429 -0
- package/packages/ui/node_modules/.bin/jiti +21 -0
- package/packages/ui/node_modules/.bin/tsc +21 -0
- package/packages/ui/node_modules/.bin/tsserver +21 -0
- package/packages/ui/node_modules/.bin/tsup +21 -0
- package/packages/ui/node_modules/.bin/tsup-node +21 -0
- package/packages/ui/node_modules/.bin/tsx +21 -0
- package/packages/ui/src/select.tsx +3 -4
- package/packages/vue/dist/index.d.ts +71 -0
- package/packages/vue/dist/index.js +193 -0
- package/packages/vue/node_modules/.bin/jiti +21 -0
- package/packages/vue/node_modules/.bin/tsc +21 -0
- package/packages/vue/node_modules/.bin/tsserver +21 -0
- package/packages/vue/node_modules/.bin/tsup +21 -0
- package/packages/vue/node_modules/.bin/tsup-node +21 -0
- package/packages/vue/node_modules/.bin/tsx +21 -0
- package/scripts/vite-aliases.mjs +125 -0
- package/.changeset/README.md +0 -23
- package/.changeset/combobox-and-changesets.md +0 -9
- package/.changeset/config.json +0 -30
- package/.changeset/framework-adapters.md +0 -12
- package/.changeset/scene-3d.md +0 -6
- package/.changeset/scene-plane.md +0 -8
- package/.changeset/site-og.md +0 -5
- package/.cursor/rules/aeon-ui.mdc +0 -22
- package/ACCESSIBILITY.md +0 -32
- package/AGENTS.md +0 -226
- package/COMPONENTS.md +0 -41
- package/FRAMEWORKS.md +0 -57
- package/PHILOSOPHY.md +0 -71
- package/PUBLISHING.md +0 -85
- package/SCENE.md +0 -113
- package/STATES.md +0 -243
- package/apps/demo/index.html +0 -31
- package/apps/demo/og.config.mjs +0 -20
- package/apps/demo/package.json +0 -41
- package/apps/demo/public/favicon.svg +0 -16
- package/apps/demo/public/og-aeon-ui-engine.png +0 -0
- package/apps/demo/public/og.svg +0 -35
- package/apps/demo/scripts/generate-og-png.mjs +0 -62
- package/apps/demo/src/App.tsx +0 -31
- package/apps/demo/src/aeonDiagrams.ts +0 -42
- package/apps/demo/src/app.css +0 -16
- package/apps/demo/src/components/ActionCluster.tsx +0 -20
- package/apps/demo/src/components/AsyncMachineDemo.tsx +0 -97
- package/apps/demo/src/components/ButtonLifecycleDemo.tsx +0 -63
- package/apps/demo/src/components/CodeExample.tsx +0 -7
- package/apps/demo/src/components/ComboboxDemo.tsx +0 -30
- package/apps/demo/src/components/DiagramsSection.tsx +0 -37
- package/apps/demo/src/components/FieldStateDemo.tsx +0 -51
- package/apps/demo/src/components/GridMesh.tsx +0 -8
- package/apps/demo/src/components/HeroInstall.tsx +0 -13
- package/apps/demo/src/components/LandingFaq.tsx +0 -29
- package/apps/demo/src/components/LandingFooter.tsx +0 -30
- package/apps/demo/src/components/LandingHeader.tsx +0 -62
- package/apps/demo/src/components/LandingHero.tsx +0 -55
- package/apps/demo/src/components/LayersSection.tsx +0 -47
- package/apps/demo/src/components/MermaidDiagram.tsx +0 -86
- package/apps/demo/src/components/PhilosophySection.tsx +0 -31
- package/apps/demo/src/components/PlaygroundBlock.tsx +0 -18
- package/apps/demo/src/components/PlaygroundControlsDemo.tsx +0 -63
- package/apps/demo/src/components/PlaygroundSection.tsx +0 -120
- package/apps/demo/src/components/ScrollRegionDemo.tsx +0 -74
- package/apps/demo/src/components/ThemeSwitcher.tsx +0 -79
- package/apps/demo/src/demo-layout.css +0 -293
- package/apps/demo/src/landing.css +0 -1151
- package/apps/demo/src/main.tsx +0 -14
- package/apps/demo/src/nav.ts +0 -9
- package/apps/demo/src/site.ts +0 -218
- package/apps/demo/tsconfig.json +0 -17
- package/apps/demo/vite-plugins/og-meta.ts +0 -30
- package/apps/demo/vite.config.ts +0 -69
- package/docs/API_PATTERNS.md +0 -234
- package/docs/ARCHITECTURE.md +0 -125
- package/docs/COMPONENT_CHECKLIST.md +0 -103
- package/docs/FILE_MAP.md +0 -122
- package/docs/GLOSSARY.md +0 -125
- package/docs/INDEX.md +0 -53
- package/docs/LAYOUT_COORDINATES.md +0 -178
- package/docs/MACHINES.md +0 -171
- package/docs/MIGRATION_FROM_ARK.md +0 -295
- package/docs/VITE_CONSUMER.md +0 -114
- package/pnpm-workspace.yaml +0 -3
- package/vercel.json +0 -12
package/AGENTS.md
DELETED
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
# Aeon UI — agent instructions
|
|
2
|
-
|
|
3
|
-
**Audience:** Cursor, Copilot, Claude, or any coding agent working in this repo.
|
|
4
|
-
**Goal:** Follow Aeon conventions without guessing. When in doubt, read the linked doc — do not invent patterns.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## North star (memorize this)
|
|
9
|
-
|
|
10
|
-
**State is defined first. UI represents the totality of that definition.**
|
|
11
|
-
|
|
12
|
-
- Behavior → XState snapshot (or explicit derived state like Scroll).
|
|
13
|
-
- DOM → `data-aeon-scope`, `data-aeon-part`, `data-aeon-state` from `@aeon-ui/core`.
|
|
14
|
-
- Style → Panda slot recipes keyed on those attributes.
|
|
15
|
-
- **UI = f(snapshot)** — not f(ad hoc React flags).
|
|
16
|
-
|
|
17
|
-
Source: [PHILOSOPHY.md](./PHILOSOPHY.md) · Code: `packages/core/src/philosophy.ts`
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Read order (first time in repo)
|
|
22
|
-
|
|
23
|
-
| Order | File | Why |
|
|
24
|
-
|-------|------|-----|
|
|
25
|
-
| 1 | This file (`AGENTS.md`) | Rules, maps, workflows |
|
|
26
|
-
| 2 | [docs/MACHINES.md](./docs/MACHINES.md) | **Which components use machines vs props** — avoid wrong wiring |
|
|
27
|
-
| 3 | [STATES.md](./STATES.md) | Attribute contract, async/button/field/scroll |
|
|
28
|
-
| 4 | [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) | Packages, layers, build |
|
|
29
|
-
| 5 | [docs/COMPONENT_CHECKLIST.md](./docs/COMPONENT_CHECKLIST.md) | Adding or changing a component |
|
|
30
|
-
| 6 | [COMPONENTS.md](./COMPONENTS.md) | Shipped catalog |
|
|
31
|
-
| 7 | [INTEGRATION.md](./INTEGRATION.md) | Headless / Panda / styled |
|
|
32
|
-
| 8 | [FRAMEWORKS.md](./FRAMEWORKS.md) | Vue / Solid / Svelte porting |
|
|
33
|
-
| — | [docs/LAYOUT_COORDINATES.md](./docs/LAYOUT_COORDINATES.md) | **Responsive play surfaces — norm coords + layout modes** |
|
|
34
|
-
| — | [docs/API_PATTERNS.md](./docs/API_PATTERNS.md) | Copy-paste snippets |
|
|
35
|
-
|
|
36
|
-
Scene plane (optional): [SCENE.md](./SCENE.md). Publishing: [PUBLISHING.md](./PUBLISHING.md). A11y: [ACCESSIBILITY.md](./ACCESSIBILITY.md).
|
|
37
|
-
|
|
38
|
-
Full index: [docs/INDEX.md](./docs/INDEX.md).
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## Non-negotiable rules
|
|
43
|
-
|
|
44
|
-
1. **Do not add `useState` for open/checked/lifecycle** on components that already have a machine in `@aeon-ui/primitives` unless you are intentionally replacing the headless layer (rare).
|
|
45
|
-
2. **Button `status` is a prop projection**, not the machine. `buttonLifecycleMachine` exists for demos and app logic via `useAeonMachine`; headless `Button.Root` sets `data-aeon-state` from the `status` prop. Wire chart → prop yourself when needed.
|
|
46
|
-
3. **Select** shares `popoverMachine` (do not fork another open/closed chart). **Combobox** and **Tooltip** still use React state — do not add duplicate floating-surface machines without [COMPONENT_CHECKLIST.md](./docs/COMPONENT_CHECKLIST.md).
|
|
47
|
-
4. **Scroll** uses `getScrollSnapshot()` from core — **no** XState machine.
|
|
48
|
-
5. **Every new scope** needs anatomy in `packages/core/src/anatomy.ts`, headless in `packages/react/src/<name>/`, recipe in `packages/panda/src/recipes/`, styled in `packages/ui/src/<name>.tsx`, demo in `apps/demo`.
|
|
49
|
-
6. **After any Panda recipe or token change**, run from repo root: `pnpm codegen` (then build if verifying).
|
|
50
|
-
7. **ESM**: TypeScript sources use **`.js` extensions** in relative imports (`import { x } from './foo.js'`).
|
|
51
|
-
8. **Panda package is private** — apps consume CSS via `@aeon-ui/ui` or direct `@aeon-ui/panda/styles.css` imports; do not publish `@aeon-ui/panda` as a separate product without maintainer intent.
|
|
52
|
-
9. **Totality**: If the machine lists N stable states, the demo must show all N (e.g. `Async.Track` segments).
|
|
53
|
-
10. **Do not style with ad hoc class names for state** in product code inside this repo — use `data-aeon-state` + recipes or documented `globalCss`.
|
|
54
|
-
|
|
55
|
-
---
|
|
56
|
-
|
|
57
|
-
## Decision tree: which package to edit?
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
Changing behavior / transitions?
|
|
61
|
-
└─> packages/primitives/src/machines/<topic>.ts
|
|
62
|
-
└─> Update apps/demo/src/aeonDiagrams.ts if diagram exists
|
|
63
|
-
|
|
64
|
-
Changing DOM contract / part names?
|
|
65
|
-
└─> packages/core/src/anatomy.ts
|
|
66
|
-
└─> packages/core/src/attrs.ts (partAttrs, stateToAttr)
|
|
67
|
-
|
|
68
|
-
Changing React API / a11y / events?
|
|
69
|
-
└─> packages/react/src/<component>/
|
|
70
|
-
|
|
71
|
-
Changing default look?
|
|
72
|
-
└─> packages/panda/src/recipes/<component>.ts
|
|
73
|
-
└─> pnpm codegen
|
|
74
|
-
|
|
75
|
-
Shipping styled export?
|
|
76
|
-
└─> packages/ui/src/<component>.tsx
|
|
77
|
-
|
|
78
|
-
Showing behavior to humans?
|
|
79
|
-
└─> apps/demo/src/ (playground sections)
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## Decision tree: which layer should the user import?
|
|
85
|
-
|
|
86
|
-
```
|
|
87
|
-
Need full Aeon styling + themes?
|
|
88
|
-
└─> @aeon-ui/ui (+ panda CSS imports — see INTEGRATION.md)
|
|
89
|
-
|
|
90
|
-
Custom design system, same behavior?
|
|
91
|
-
└─> @aeon-ui/react + CSS on [data-aeon-*]
|
|
92
|
-
|
|
93
|
-
Own XState app machines?
|
|
94
|
-
└─> useAeonMachine from @aeon-ui/react + primitives machines or app machines
|
|
95
|
-
|
|
96
|
-
Only tokens/recipes?
|
|
97
|
-
└─> @aeon-ui/panda/styled-system/recipes (workspace/private; codegen required)
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Repo map (high signal paths)
|
|
103
|
-
|
|
104
|
-
| Path | Contents |
|
|
105
|
-
|------|----------|
|
|
106
|
-
| `packages/core/src/anatomy.ts` | All `*Anatomy` scopes and part keys |
|
|
107
|
-
| `packages/core/src/attrs.ts` | `partAttrs`, `scopeAttrs`, `stateToAttr` |
|
|
108
|
-
| `packages/primitives/src/machines/` | XState machines |
|
|
109
|
-
| `packages/react/src/<component>/` | Headless compound components |
|
|
110
|
-
| `packages/react/src/hooks/use-aeon-machine.ts` | `useAeonMachine` wrapper |
|
|
111
|
-
| `packages/panda/panda.config.ts` | Recipe registration, `aeon*` conditions |
|
|
112
|
-
| `packages/panda/src/recipes/` | Slot + plain recipes |
|
|
113
|
-
| `packages/ui/src/*.tsx` | Styled wrappers (`aeon*` + `cn`) |
|
|
114
|
-
| `apps/demo/src/` | Marketing + playgrounds |
|
|
115
|
-
| `apps/demo/src/aeonDiagrams.ts` | Mermaid ↔ machines (keep in sync) |
|
|
116
|
-
|
|
117
|
-
Detailed map: [docs/FILE_MAP.md](./docs/FILE_MAP.md).
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## Naming conventions (copy exactly)
|
|
122
|
-
|
|
123
|
-
| Artifact | Pattern | Example |
|
|
124
|
-
|----------|---------|---------|
|
|
125
|
-
| npm package | `@aeon-ui/<name>` | `@aeon-ui/react` |
|
|
126
|
-
| Anatomy export | `{scope}Anatomy` | `asyncAnatomy` |
|
|
127
|
-
| Scope string | lowercase family | `'async'`, `'button'` |
|
|
128
|
-
| Machine export | `{name}Machine` or `create{Name}Machine` | `fieldMachine`, `createAsyncMachine` |
|
|
129
|
-
| Panda recipe key | `aeon{Pascal}` | `aeonAsync`, `aeonButton` |
|
|
130
|
-
| Recipe export | `{name}Recipe` | `asyncRegionRecipe` |
|
|
131
|
-
| React folder | `packages/react/src/<component>/` | `async/`, `dialog/` |
|
|
132
|
-
| Styled file | `packages/ui/src/<component>.tsx` | `button.tsx` |
|
|
133
|
-
| Compound parts | `Root`, `Trigger`, `Content`, … | `Dialog.Root` |
|
|
134
|
-
| Data attrs | `data-aeon-scope`, `data-aeon-part`, `data-aeon-state` | always via `partAttrs` |
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Common workflows
|
|
139
|
-
|
|
140
|
-
### Fix a styling bug on a component
|
|
141
|
-
|
|
142
|
-
1. Inspect DOM for `data-aeon-scope`, `data-aeon-part`, `data-aeon-state`.
|
|
143
|
-
2. Find slot recipe: `packages/panda/src/recipes/<component>.ts`.
|
|
144
|
-
3. Check conditions in `packages/panda/panda.config.ts` (`aeonOpen`, `aeonPending`, …).
|
|
145
|
-
4. `pnpm codegen` → verify in `apps/demo`.
|
|
146
|
-
|
|
147
|
-
### Add a new primitive component
|
|
148
|
-
|
|
149
|
-
Follow **[docs/COMPONENT_CHECKLIST.md](./docs/COMPONENT_CHECKLIST.md)** — all 10 steps. Do not skip anatomy or demo rail.
|
|
150
|
-
|
|
151
|
-
### Port to Vue / Solid / Svelte
|
|
152
|
-
|
|
153
|
-
Follow **[FRAMEWORKS.md](./FRAMEWORKS.md)** — copy React `partAttrs` usage; use `useAeonMachine` equivalent per adapter.
|
|
154
|
-
|
|
155
|
-
### Change async / field / button lifecycle
|
|
156
|
-
|
|
157
|
-
1. Machine in `packages/primitives/src/machines/`.
|
|
158
|
-
2. React projection in `packages/react/src/<async|field|button>/`.
|
|
159
|
-
3. Mermaid in `apps/demo/src/aeonDiagrams.ts`.
|
|
160
|
-
4. STATES.md section if user-facing contract changes.
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## Machine vs implementation (cheat sheet)
|
|
165
|
-
|
|
166
|
-
See full table and events in **[docs/MACHINES.md](./docs/MACHINES.md)**.
|
|
167
|
-
|
|
168
|
-
| Component | Runtime driver |
|
|
169
|
-
|-----------|----------------|
|
|
170
|
-
| Dialog, Tabs, Accordion, Switch, Checkbox | `useAeonMachine` + primitives |
|
|
171
|
-
| Async, Field | `useAeonMachine` + primitives |
|
|
172
|
-
| Menu, Popover | `popoverMachine` |
|
|
173
|
-
| Toast (item) | `toastMachine` |
|
|
174
|
-
| Button | **`status` prop** (machine optional in app) |
|
|
175
|
-
| Select, Combobox, Tooltip | **React `useState`** |
|
|
176
|
-
| Scroll | **`getScrollSnapshot()`** |
|
|
177
|
-
|
|
178
|
-
---
|
|
179
|
-
|
|
180
|
-
## Build & verify
|
|
181
|
-
|
|
182
|
-
```bash
|
|
183
|
-
pnpm install # from repo root
|
|
184
|
-
pnpm codegen # after panda changes
|
|
185
|
-
pnpm dev # demo app
|
|
186
|
-
pnpm build # codegen + all packages
|
|
187
|
-
pnpm typecheck # all packages
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Node ≥ 20. Package manager: **pnpm** (workspace: `packages/*`, `apps/*`).
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## What not to do
|
|
195
|
-
|
|
196
|
-
- Do not duplicate state in React and XState for the same concern.
|
|
197
|
-
- Do not add Tailwind inside `@aeon-ui/ui` — Panda recipes only.
|
|
198
|
-
- Do not export unstyled components from `@aeon-ui/ui`.
|
|
199
|
-
- Do not change `data-aeon-*` names without updating panda conditions and STATES.md.
|
|
200
|
-
- Do not assume COMPONENTS.md “Machine” column is accurate for Select/Combobox — see [docs/MACHINES.md](./docs/MACHINES.md).
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
## Package READMEs (API entry points)
|
|
205
|
-
|
|
206
|
-
| Package | Doc |
|
|
207
|
-
|---------|-----|
|
|
208
|
-
| `@aeon-ui/core` | [packages/core/README.md](./packages/core/README.md) |
|
|
209
|
-
| `@aeon-ui/primitives` | [packages/primitives/README.md](./packages/primitives/README.md) |
|
|
210
|
-
| `@aeon-ui/react` | [packages/react/README.md](./packages/react/README.md) |
|
|
211
|
-
| `@aeon-ui/panda` | [packages/panda/README.md](./packages/panda/README.md) |
|
|
212
|
-
| `@aeon-ui/ui` | [packages/ui/README.md](./packages/ui/README.md) |
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## Glossary
|
|
217
|
-
|
|
218
|
-
[docs/GLOSSARY.md](./docs/GLOSSARY.md)
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
|
-
## Human docs (same truth)
|
|
223
|
-
|
|
224
|
-
[README.md](./README.md) · [PHILOSOPHY.md](./PHILOSOPHY.md) · [STATES.md](./STATES.md) · [COMPONENTS.md](./COMPONENTS.md)
|
|
225
|
-
|
|
226
|
-
When agents and human docs disagree, **source code wins** — then fix the doc in the same PR.
|
package/COMPONENTS.md
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# Component catalog
|
|
2
|
-
|
|
3
|
-
Status key: **Headless** (`@aeon-ui/react`) · **Styled** (`@aeon-ui/ui`) · **State driver** (how runtime state is chosen)
|
|
4
|
-
|
|
5
|
-
**Agents:** authoritative wiring table → [docs/MACHINES.md](./docs/MACHINES.md).
|
|
6
|
-
|
|
7
|
-
| Component | Headless | Styled | State driver | Stable states / notes |
|
|
8
|
-
|-----------|----------|--------|--------------|------------------------|
|
|
9
|
-
| Button | ✓ | ✓ | **`status` prop** (machine optional in app) | idle, pending, success, failure, disabled |
|
|
10
|
-
| Switch | ✓ | ✓ | `toggleMachine` | checked / unchecked |
|
|
11
|
-
| Checkbox | ✓ | ✓ | `toggleMachine` | checked / unchecked |
|
|
12
|
-
| Dialog | ✓ | ✓ | `dialogMachine` | open / closed |
|
|
13
|
-
| Tabs | ✓ | ✓ | `tabsMachine` | per-tab selected |
|
|
14
|
-
| Accordion | ✓ | ✓ | `accordionMachine` | per-item open / closed |
|
|
15
|
-
| Select | ✓ | ✓ | `popoverMachine` | open / closed listbox; keyboard highlight in React |
|
|
16
|
-
| Combobox | ✓ | ✓ | **React state** | open / closed + filter |
|
|
17
|
-
| Async | ✓ | ✓ | `createAsyncMachine` | idle, loading, success, failure, empty + stale |
|
|
18
|
-
| Field | ✓ | ✓ | `fieldMachine` (parallel) | interaction × validation × submission; `Control` + `Textarea` |
|
|
19
|
-
| Scroll | ✓ | ✓ | **`getScrollSnapshot`** | overflow axis + edge position |
|
|
20
|
-
| Menu | ✓ | ✓ | `popoverMachine` | open / closed |
|
|
21
|
-
| Popover | ✓ | ✓ | `popoverMachine` | open / closed |
|
|
22
|
-
| Tooltip | ✓ | ✓ | **React state** | open / closed; tap-to-toggle on touch |
|
|
23
|
-
| Toast | ✓ | ✓ | `toastMachine` | hidden / visible |
|
|
24
|
-
| Avatar | ✓ | — | **React state** | idle / loading / loaded / error |
|
|
25
|
-
| Separator | ✓ | ✓ | **static** | horizontal / vertical orientation |
|
|
26
|
-
| Progress | ✓ | ✓ | **props** | idle / loading / complete |
|
|
27
|
-
| RadioGroup | ✓ | ✓ | `tabsMachine` | one selected item |
|
|
28
|
-
| Slider | ✓ | ✓ | `sliderMachine` | idle / dragging + value |
|
|
29
|
-
| PinInput | ✓ | ✓ | **React state** | idle / complete |
|
|
30
|
-
|
|
31
|
-
## Planned (not shipped)
|
|
32
|
-
|
|
33
|
-
Number Input, Date Picker, Tree View, File Upload, Carousel, Toggle Group — tracked as the catalog grows; prefer explicit machines per component.
|
|
34
|
-
|
|
35
|
-
## Choosing a layer
|
|
36
|
-
|
|
37
|
-
- **App logic & tests** → define or extend machines in `@aeon-ui/primitives`, or app-level XState.
|
|
38
|
-
- **Custom design system** → `@aeon-ui/react` + your CSS targeting `data-aeon-*`.
|
|
39
|
-
- **Ship fast with Aeon look** → `@aeon-ui/ui` + `@aeon-ui/panda` themes.
|
|
40
|
-
|
|
41
|
-
See [INTEGRATION.md](./INTEGRATION.md) for styling without Panda.
|
package/FRAMEWORKS.md
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
# Framework support
|
|
2
|
-
|
|
3
|
-
**Agents:** [AGENTS.md](./AGENTS.md) · porting steps mirror React — [docs/COMPONENT_CHECKLIST.md](./docs/COMPONENT_CHECKLIST.md)
|
|
4
|
-
|
|
5
|
-
## Today
|
|
6
|
-
|
|
7
|
-
| Runtime | Package | Status |
|
|
8
|
-
|---------|---------|--------|
|
|
9
|
-
| React 18+ | `@aeon-ui/react`, `@aeon-ui/ui` | **Full catalog** (Button, Dialog, Select, Combobox, overlays, …) |
|
|
10
|
-
| Vue 3 | `@aeon-ui/vue` | **Adapter v0.1** — `useAeonMachine`, `Switch` |
|
|
11
|
-
| Solid 1.8+ | `@aeon-ui/solid` | **Adapter v0.1** — `useAeonMachine`, `Switch` |
|
|
12
|
-
| Svelte 4/5 | `@aeon-ui/svelte` | **Adapter v0.1** — `useAeonMachine`, `Switch` (`.svelte` parts) |
|
|
13
|
-
|
|
14
|
-
Styled Panda recipes (`@aeon-ui/ui`) remain **React-only** until a second framework needs them.
|
|
15
|
-
|
|
16
|
-
## Install
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
# Vue
|
|
20
|
-
pnpm add @aeon-ui/vue @aeon-ui/core @aeon-ui/primitives xstate vue
|
|
21
|
-
|
|
22
|
-
# Solid
|
|
23
|
-
pnpm add @aeon-ui/solid @aeon-ui/core @aeon-ui/primitives xstate solid-js
|
|
24
|
-
|
|
25
|
-
# Svelte
|
|
26
|
-
pnpm add @aeon-ui/svelte @aeon-ui/core @aeon-ui/primitives xstate svelte
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Headless contract (all adapters)
|
|
30
|
-
|
|
31
|
-
Any port must preserve:
|
|
32
|
-
|
|
33
|
-
1. **Machines** from `@aeon-ui/primitives` (XState) — single source of behavior.
|
|
34
|
-
2. **Anatomy** from `@aeon-ui/core` — `data-aeon-scope`, `data-aeon-part`, `data-aeon-state`.
|
|
35
|
-
3. **Compound parts** — same names as React (`Root`, `Trigger`, `Content`, …).
|
|
36
|
-
4. **Controlled APIs** — `open`, `onOpenChange`, `checked`, `onCheckedChange` where applicable.
|
|
37
|
-
|
|
38
|
-
Framework packages bind machine snapshots to their reactivity model (via `@xstate/vue`, `@xstate/solid`, or actor `subscribe` in Svelte). They do **not** reimplement transition tables.
|
|
39
|
-
|
|
40
|
-
## Porting checklist (new component)
|
|
41
|
-
|
|
42
|
-
1. Copy behavior from `packages/react/src/<component>/`.
|
|
43
|
-
2. Reuse `partAttrs` / anatomy from `@aeon-ui/core`.
|
|
44
|
-
3. Wire `useAeonMachine` (or framework binding) to the primitive machine.
|
|
45
|
-
4. Add a minimal demo or test in that framework when the API stabilizes.
|
|
46
|
-
|
|
47
|
-
## Why React stayed first
|
|
48
|
-
|
|
49
|
-
- Largest catalog and Panda styled layer.
|
|
50
|
-
- Demo and docs target JSX.
|
|
51
|
-
- Adapters prove the contract before duplicating every component three times.
|
|
52
|
-
|
|
53
|
-
## Comparison to Ark / Zag
|
|
54
|
-
|
|
55
|
-
[Ark UI](https://ark-ui.com) ships many frameworks via [Zag.js](https://zag-js.com) with broad component coverage. Aeon optimizes for **explicit XState charts** and **full lifecycle states** on fewer, deeper primitives. Adapters close the framework gap incrementally; they do not yet match Ark’s breadth.
|
|
56
|
-
|
|
57
|
-
Contributors: open a PR adding the next React component port to `@aeon-ui/vue` / `solid` / `svelte` using **Switch** as the template.
|
package/PHILOSOPHY.md
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# Aeon UI — Founding Philosophy
|
|
2
|
-
|
|
3
|
-
Aeon UI is infrastructure for the web, built for interfaces that remain clear as products grow.
|
|
4
|
-
|
|
5
|
-
## North star
|
|
6
|
-
|
|
7
|
-
**State is defined first. UI represents the totality of that definition.**
|
|
8
|
-
|
|
9
|
-
A region’s behavior is modeled as an explicit set of conditions — named, mutually exclusive at a given depth, with known transitions. The interface’s job is to **fully express** that model: every stable state the chart allows should be visible in the UI (via structure, copy, and `data-aeon-state`), and the UI should never imply a condition the chart does not define (no mystery spinners, no ambiguous half-states, no styling that drifts from the snapshot).
|
|
10
|
-
|
|
11
|
-
In short: **UI = f(state)** — not f(props), not f(local React flags), but f(the executable statechart).
|
|
12
|
-
|
|
13
|
-
## Primary source
|
|
14
|
-
|
|
15
|
-
**Thanh Nguyen**, *Statecharts for modern web application state management* (Metropolia, 2020).
|
|
16
|
-
[Theseus thesis PDF](https://www.theseus.fi/bitstream/handle/10024/334118/Thanh_Nguyen.pdf?sequence=2&isAllowed=y)
|
|
17
|
-
|
|
18
|
-
## Core tenets
|
|
19
|
-
|
|
20
|
-
### 1. Define state, then project UI
|
|
21
|
-
|
|
22
|
-
Separate **behavior** (state evolution in a machine) from **presentation** (markup, style, anatomy). Components read a snapshot and render the corresponding face of the model. When the snapshot changes, the whole affordance updates — trigger, labels, indicators, and `data-aeon-state` together.
|
|
23
|
-
|
|
24
|
-
### 2. Totality, not fragments
|
|
25
|
-
|
|
26
|
-
If the machine has `idle`, `loading`, `success`, and `failure`, the product surface should account for all four — in layout, messaging, and styling — even when only one is active. Users and developers see the same complete map; nothing is left implicit.
|
|
27
|
-
|
|
28
|
-
### 3. Explicit, coherent states
|
|
29
|
-
|
|
30
|
-
Application regions benefit from **mutually exclusive states** at a given depth — one stable condition the team can name, test, and extend. That clarity keeps complex flows maintainable as features accumulate.
|
|
31
|
-
|
|
32
|
-
### 4. Statecharts for lasting complexity
|
|
33
|
-
|
|
34
|
-
When requirements grow, flat state diagrams become hard to follow. Statecharts add:
|
|
35
|
-
|
|
36
|
-
- **Hierarchy** — cluster related states; share transitions at the right level of abstraction
|
|
37
|
-
- **Orthogonality** — independent regions (e.g. playback and shuffle) without combinatorial sprawl
|
|
38
|
-
- **Guards** — conditional transitions that document business rules in the model
|
|
39
|
-
- **Transient states** — routing steps that keep flows readable
|
|
40
|
-
- **Actions and activities** — entry, exit, and transition effects with defined ordering
|
|
41
|
-
|
|
42
|
-
### 5. Deterministic, diagrammable behavior
|
|
43
|
-
|
|
44
|
-
Every interactive primitive can own an **executable statechart** (via [XState](https://xstate.js.org)). Models can be visualized, reviewed, and extended alongside designers and stakeholders — a shared map for how the product behaves.
|
|
45
|
-
|
|
46
|
-
### 6. Design systems in control
|
|
47
|
-
|
|
48
|
-
Aeon provides **unstyled headless primitives** with explicit anatomy (`data-aeon-scope`, `data-aeon-part`, `data-aeon-state`) so your team owns every surface. The styled layer (`@aeon-ui/ui`) ships intentional defaults you can adopt or replace — **your brand, fully yours**.
|
|
49
|
-
|
|
50
|
-
## Production-ready patterns
|
|
51
|
-
|
|
52
|
-
| Concern | Approach |
|
|
53
|
-
|---------|----------|
|
|
54
|
-
| Structure & API | Compound components, part-based anatomy (`data-aeon-scope`, `data-aeon-part`, `data-aeon-state`), accessibility |
|
|
55
|
-
| Styling | Panda CSS slot recipes on headless primitives — tokens and variants keyed to machine state |
|
|
56
|
-
| Execution | XState statecharts (thesis case study) — explicit states and transitions in the browser |
|
|
57
|
-
|
|
58
|
-
## Library shape
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
@aeon-ui/core — philosophy, anatomy, machine helpers
|
|
62
|
-
@aeon-ui/primitives — headless, statechart-backed parts
|
|
63
|
-
@aeon-ui/react — React bindings (snapshot → DOM)
|
|
64
|
-
@aeon-ui/ui — styled components with intentional tokens
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**Guideline:** Model the statechart first — list every stable state and transition. Then build UI that expresses the **whole** definition at once (track, readout, parts), with exactly one active condition per region.
|
|
68
|
-
|
|
69
|
-
See **[STATES.md](./STATES.md)** for states traditional UI often omits (async empty/stale, button pending/success/failure, orthogonal field regions) and the corresponding Aeon primitives.
|
|
70
|
-
|
|
71
|
-
**Coding agents:** [AGENTS.md](./AGENTS.md) · [docs/INDEX.md](./docs/INDEX.md)
|
package/PUBLISHING.md
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
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/SCENE.md
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
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.
|