aeon-ui-engine 1.3.5 → 1.4.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.
- package/CHANGELOG.md +25 -0
- package/package.json +1 -1
- package/packages/cli/README.md +13 -1
- package/packages/cli/dist/bin.js +23 -5
- package/packages/cli/dist/chunk-5L47SLNV.js +247 -0
- package/packages/cli/dist/index.d.ts +17 -1
- package/packages/cli/dist/index.js +5 -3
- package/packages/cli/src/bin.ts +21 -3
- package/packages/cli/src/index.ts +1 -0
- package/packages/cli/src/migrate.ts +170 -0
- package/packages/core/dist/index.d.ts +35 -7
- package/packages/core/dist/index.js +102 -2
- package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/core/src/anatomy.ts +39 -3
- package/packages/core/src/identicon.test.ts +39 -0
- package/packages/core/src/identicon.ts +79 -0
- package/packages/core/src/index.ts +1 -0
- package/packages/panda/panda.config.ts +4 -0
- package/packages/panda/src/recipes/composer.ts +58 -4
- package/packages/panda/src/recipes/file-upload.ts +100 -0
- package/packages/panda/src/recipes/index.ts +2 -0
- package/packages/panda/src/recipes/range-slider.ts +59 -0
- package/packages/panda/src/recipes/thread.ts +77 -2
- package/packages/panda/styled-system/recipes/aeon-composer.d.ts +1 -1
- package/packages/panda/styled-system/recipes/aeon-composer.mjs +12 -0
- package/packages/panda/styled-system/recipes/aeon-file-upload.d.ts +31 -0
- package/packages/panda/styled-system/recipes/aeon-file-upload.mjs +61 -0
- package/packages/panda/styled-system/recipes/aeon-range-slider.d.ts +31 -0
- package/packages/panda/styled-system/recipes/aeon-range-slider.mjs +49 -0
- package/packages/panda/styled-system/recipes/aeon-thread.d.ts +1 -1
- package/packages/panda/styled-system/recipes/aeon-thread.mjs +20 -0
- package/packages/panda/styled-system/recipes/index.d.ts +2 -0
- package/packages/panda/styled-system/recipes/index.mjs +2 -0
- package/packages/panda/styled-system/styles.css +292 -0
- package/packages/primitives/dist/chunk-CV4UXXZF.js +44 -0
- package/packages/primitives/dist/chunk-IZKQSCYU.js +164 -0
- package/packages/primitives/dist/index.d.ts +2 -0
- package/packages/primitives/dist/index.js +22 -6
- package/packages/primitives/dist/machines/file-upload.d.ts +39 -0
- package/packages/primitives/dist/machines/file-upload.js +8 -0
- package/packages/primitives/dist/machines/range-slider.d.ts +129 -0
- package/packages/primitives/dist/machines/range-slider.js +12 -0
- package/packages/primitives/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/primitives/src/__tests__/file-upload.test.ts +25 -0
- package/packages/primitives/src/__tests__/range-slider.test.ts +39 -0
- package/packages/primitives/src/index.ts +2 -0
- package/packages/primitives/src/machines/file-upload.ts +55 -0
- package/packages/primitives/src/machines/range-slider.ts +209 -0
- package/packages/react/dist/index.d.ts +117 -25
- package/packages/react/dist/index.js +1731 -1006
- package/packages/react/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/react/src/button/index.tsx +50 -15
- package/packages/react/src/composer/index.tsx +58 -3
- package/packages/react/src/file-upload/index.tsx +322 -0
- package/packages/react/src/index.ts +3 -0
- package/packages/react/src/prompt/index.tsx +45 -0
- package/packages/react/src/range-slider/index.tsx +322 -0
- package/packages/react/src/thread/index.tsx +74 -3
- package/packages/react/src/utils/slot.tsx +47 -0
- package/packages/schemas/dist/index.d.ts +4 -0
- package/packages/schemas/dist/index.js +67 -1
- package/packages/schemas/json/button.json +6 -0
- package/packages/schemas/json/catalog.json +333 -0
- package/packages/schemas/json/fileUpload.json +168 -0
- package/packages/schemas/json/rangeSlider.json +157 -0
- package/packages/schemas/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/schemas/registry/catalog.json +18 -0
- package/packages/schemas/registry/components/button.json +6 -0
- package/packages/schemas/registry/components/fileUpload.json +168 -0
- package/packages/schemas/registry/components/rangeSlider.json +157 -0
- package/packages/schemas/registry/machines/fileUpload.json +182 -0
- package/packages/schemas/registry/machines/rangeSlider.json +201 -0
- package/packages/schemas/scripts/emit.ts +4 -0
- package/packages/schemas/src/components.ts +70 -0
- package/packages/schemas/tsconfig.json +1 -1
- package/packages/ui/dist/index.d.ts +100 -46
- package/packages/ui/dist/index.js +463 -341
- package/packages/ui/src/composer.tsx +37 -11
- package/packages/ui/src/file-upload.tsx +36 -0
- package/packages/ui/src/index.ts +2 -0
- package/packages/ui/src/prompt.tsx +3 -0
- package/packages/ui/src/range-slider.tsx +24 -0
- package/packages/ui/src/thread.tsx +40 -0
- package/packages/cli/dist/chunk-IW5NT2Z2.js +0 -103
|
@@ -5,23 +5,49 @@ import { cn } from './cn.js'
|
|
|
5
5
|
|
|
6
6
|
type RootProps = ComponentProps<typeof Headless.Root>
|
|
7
7
|
type InputProps = ComponentProps<typeof Headless.Input>
|
|
8
|
-
type
|
|
8
|
+
type ActionsProps = ComponentProps<typeof Headless.Actions>
|
|
9
|
+
type SendProps = ComponentProps<typeof Headless.Send>
|
|
10
|
+
type ToolbarProps = ComponentProps<typeof Headless.Toolbar>
|
|
11
|
+
type SuggestionsProps = ComponentProps<typeof Headless.Suggestions>
|
|
12
|
+
type SuggestionProps = ComponentProps<typeof Headless.Suggestion>
|
|
13
|
+
|
|
14
|
+
type Styles = ReturnType<typeof aeonComposer> & {
|
|
15
|
+
toolbar?: string
|
|
16
|
+
suggestions?: string
|
|
17
|
+
suggestion?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function styles(): Styles {
|
|
21
|
+
return aeonComposer() as Styles
|
|
22
|
+
}
|
|
9
23
|
|
|
10
24
|
export const Composer = {
|
|
11
25
|
Root: ({ className, ...props }: RootProps) => {
|
|
12
|
-
const
|
|
13
|
-
return <Headless.Root className={cn(
|
|
26
|
+
const s = styles()
|
|
27
|
+
return <Headless.Root className={cn(s.root, className)} {...props} />
|
|
14
28
|
},
|
|
15
29
|
Input: ({ className, ...props }: InputProps) => {
|
|
16
|
-
const
|
|
17
|
-
return <Headless.Input className={cn(
|
|
30
|
+
const s = styles()
|
|
31
|
+
return <Headless.Input className={cn(s.input, className)} {...props} />
|
|
32
|
+
},
|
|
33
|
+
Actions: ({ className, ...props }: ActionsProps) => {
|
|
34
|
+
const s = styles()
|
|
35
|
+
return <Headless.Actions className={cn(s.actions, className)} {...props} />
|
|
36
|
+
},
|
|
37
|
+
Send: ({ className, ...props }: SendProps) => {
|
|
38
|
+
const s = styles()
|
|
39
|
+
return <Headless.Send className={cn(s.send, className)} {...props} />
|
|
40
|
+
},
|
|
41
|
+
Toolbar: ({ className, ...props }: ToolbarProps) => {
|
|
42
|
+
const s = styles()
|
|
43
|
+
return <Headless.Toolbar className={cn(s.toolbar ?? s.actions, className)} {...props} />
|
|
18
44
|
},
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
return <Headless.
|
|
45
|
+
Suggestions: ({ className, ...props }: SuggestionsProps) => {
|
|
46
|
+
const s = styles()
|
|
47
|
+
return <Headless.Suggestions className={cn(s.suggestions, className)} {...props} />
|
|
22
48
|
},
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
return <Headless.
|
|
49
|
+
Suggestion: ({ className, ...props }: SuggestionProps) => {
|
|
50
|
+
const s = styles()
|
|
51
|
+
return <Headless.Suggestion className={cn(s.suggestion, className)} {...props} />
|
|
26
52
|
},
|
|
27
53
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { FileUpload as Headless } from '@aeon-ui/react'
|
|
2
|
+
import { aeonFileUpload } from '@aeon-ui/panda/styled-system/recipes'
|
|
3
|
+
import type { ComponentProps } from 'react'
|
|
4
|
+
import { cn } from './cn.js'
|
|
5
|
+
|
|
6
|
+
const recipe = aeonFileUpload()
|
|
7
|
+
|
|
8
|
+
export const FileUpload = {
|
|
9
|
+
Root: ({ className, ...props }: ComponentProps<typeof Headless.Root>) => (
|
|
10
|
+
<Headless.Root className={cn(recipe.root, className)} {...props} />
|
|
11
|
+
),
|
|
12
|
+
Label: ({ className, ...props }: ComponentProps<typeof Headless.Label>) => (
|
|
13
|
+
<Headless.Label className={cn(recipe.label, className)} {...props} />
|
|
14
|
+
),
|
|
15
|
+
Dropzone: ({ className, ...props }: ComponentProps<typeof Headless.Dropzone>) => (
|
|
16
|
+
<Headless.Dropzone className={cn(recipe.dropzone, className)} {...props} />
|
|
17
|
+
),
|
|
18
|
+
Input: ({ className, ...props }: ComponentProps<typeof Headless.Input>) => (
|
|
19
|
+
<Headless.Input className={cn(recipe.input, className)} {...props} />
|
|
20
|
+
),
|
|
21
|
+
Hint: ({ className, ...props }: ComponentProps<typeof Headless.Hint>) => (
|
|
22
|
+
<Headless.Hint className={cn(recipe.hint, className)} {...props} />
|
|
23
|
+
),
|
|
24
|
+
Preview: ({ className, ...props }: ComponentProps<typeof Headless.Preview>) => (
|
|
25
|
+
<Headless.Preview className={cn(recipe.preview, className)} {...props} />
|
|
26
|
+
),
|
|
27
|
+
ClearTrigger: ({ className, ...props }: ComponentProps<typeof Headless.ClearTrigger>) => (
|
|
28
|
+
<Headless.ClearTrigger className={cn(recipe.clearTrigger, className)} {...props} />
|
|
29
|
+
),
|
|
30
|
+
RejectionMessage: ({
|
|
31
|
+
className,
|
|
32
|
+
...props
|
|
33
|
+
}: ComponentProps<typeof Headless.RejectionMessage>) => (
|
|
34
|
+
<Headless.RejectionMessage className={cn(recipe.rejectionMessage, className)} {...props} />
|
|
35
|
+
),
|
|
36
|
+
}
|
package/packages/ui/src/index.ts
CHANGED
|
@@ -22,6 +22,8 @@ export { Separator } from './separator.js'
|
|
|
22
22
|
export { Progress } from './progress.js'
|
|
23
23
|
export { RadioGroup } from './radio-group.js'
|
|
24
24
|
export { Slider } from './slider.js'
|
|
25
|
+
export { RangeSlider } from './range-slider.js'
|
|
26
|
+
export { FileUpload } from './file-upload.js'
|
|
25
27
|
export { PinInput } from './pin-input.js'
|
|
26
28
|
export { Accordion } from './accordion.js'
|
|
27
29
|
export { Badge } from './badge.js'
|
|
@@ -19,6 +19,9 @@ export const Prompt = {
|
|
|
19
19
|
),
|
|
20
20
|
Meta: Headless.Meta,
|
|
21
21
|
Amount: Headless.Amount,
|
|
22
|
+
Verb: Headless.Verb,
|
|
23
|
+
Recipient: Headless.Recipient,
|
|
24
|
+
Effect: Headless.Effect,
|
|
22
25
|
Actions: Headless.Actions,
|
|
23
26
|
Primary: ({ className, ...props }: ComponentProps<typeof Headless.Primary>) => (
|
|
24
27
|
<Headless.Primary className={cn(className)} {...props} />
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RangeSlider as Headless } from '@aeon-ui/react'
|
|
2
|
+
import { aeonRangeSlider } from '@aeon-ui/panda/styled-system/recipes'
|
|
3
|
+
import type { ComponentProps } from 'react'
|
|
4
|
+
import { cn } from './cn.js'
|
|
5
|
+
|
|
6
|
+
const recipe = aeonRangeSlider()
|
|
7
|
+
|
|
8
|
+
export const RangeSlider = {
|
|
9
|
+
Root: ({ className, ...props }: ComponentProps<typeof Headless.Root>) => (
|
|
10
|
+
<Headless.Root className={cn(recipe.root, className)} {...props} />
|
|
11
|
+
),
|
|
12
|
+
Track: ({ className, ...props }: ComponentProps<typeof Headless.Track>) => (
|
|
13
|
+
<Headless.Track className={cn(recipe.track, className)} {...props} />
|
|
14
|
+
),
|
|
15
|
+
Range: ({ className, ...props }: ComponentProps<typeof Headless.Range>) => (
|
|
16
|
+
<Headless.Range className={cn(recipe.range, className)} {...props} />
|
|
17
|
+
),
|
|
18
|
+
Thumb: ({ className, ...props }: ComponentProps<typeof Headless.Thumb>) => (
|
|
19
|
+
<Headless.Thumb className={cn(recipe.thumb, className)} {...props} />
|
|
20
|
+
),
|
|
21
|
+
ValueText: ({ className, ...props }: ComponentProps<typeof Headless.ValueText>) => (
|
|
22
|
+
<Headless.ValueText className={cn(recipe.valueText, className)} {...props} />
|
|
23
|
+
),
|
|
24
|
+
}
|
|
@@ -6,6 +6,7 @@ import { cn } from './cn.js'
|
|
|
6
6
|
type RootProps = ComponentProps<typeof Headless.Root>
|
|
7
7
|
type ItemProps = ComponentProps<typeof Headless.Item>
|
|
8
8
|
type PartProps = ComponentProps<typeof Headless.Bubble>
|
|
9
|
+
type BindProps = ComponentProps<typeof Headless.Bind>
|
|
9
10
|
|
|
10
11
|
export const Thread = {
|
|
11
12
|
Root: ({ className, ...props }: RootProps) => {
|
|
@@ -32,4 +33,43 @@ export const Thread = {
|
|
|
32
33
|
const styles = aeonThread()
|
|
33
34
|
return <Headless.Day className={cn(styles.day, className)} {...props} />
|
|
34
35
|
},
|
|
36
|
+
Bind: ({ className, ...props }: BindProps) => {
|
|
37
|
+
const styles = aeonThread()
|
|
38
|
+
return (
|
|
39
|
+
<Headless.Bind className={cn((styles as { bind?: string }).bind, className)} {...props} />
|
|
40
|
+
)
|
|
41
|
+
},
|
|
42
|
+
Card: ({ className, ...props }: PartProps) => {
|
|
43
|
+
const styles = aeonThread()
|
|
44
|
+
return (
|
|
45
|
+
<Headless.Card className={cn((styles as { card?: string }).card ?? styles.bubble, className)} {...props} />
|
|
46
|
+
)
|
|
47
|
+
},
|
|
48
|
+
CardTitle: ({ className, ...props }: PartProps) => {
|
|
49
|
+
const styles = aeonThread()
|
|
50
|
+
return (
|
|
51
|
+
<Headless.CardTitle
|
|
52
|
+
className={cn((styles as { cardTitle?: string }).cardTitle, className)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
)
|
|
56
|
+
},
|
|
57
|
+
CardBody: ({ className, ...props }: PartProps) => {
|
|
58
|
+
const styles = aeonThread()
|
|
59
|
+
return (
|
|
60
|
+
<Headless.CardBody
|
|
61
|
+
className={cn((styles as { cardBody?: string }).cardBody, className)}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
)
|
|
65
|
+
},
|
|
66
|
+
CardActions: ({ className, ...props }: PartProps) => {
|
|
67
|
+
const styles = aeonThread()
|
|
68
|
+
return (
|
|
69
|
+
<Headless.CardActions
|
|
70
|
+
className={cn((styles as { cardActions?: string }).cardActions, className)}
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
)
|
|
74
|
+
},
|
|
35
75
|
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
// src/init.ts
|
|
2
|
-
import { mkdirSync, writeFileSync, existsSync } from "fs";
|
|
3
|
-
import { join } from "path";
|
|
4
|
-
import {
|
|
5
|
-
CURSOR_RULES_SNIPPET,
|
|
6
|
-
AEON_SYSTEM_PROMPT,
|
|
7
|
-
catalog,
|
|
8
|
-
componentSchemas
|
|
9
|
-
} from "@aeon-ui/schemas";
|
|
10
|
-
var STARTER = `/**
|
|
11
|
-
* Aeon UI starter \u2014 generated by \`npx aeon-ui init\`
|
|
12
|
-
* Headless: @aeon-ui/react \xB7 Styled: @aeon-ui/ui \xB7 Schemas: @aeon-ui/schemas
|
|
13
|
-
*/
|
|
14
|
-
import { Button, Field } from '@aeon-ui/ui'
|
|
15
|
-
|
|
16
|
-
export function AeonStarter() {
|
|
17
|
-
return (
|
|
18
|
-
<div>
|
|
19
|
-
<Field.Root>
|
|
20
|
-
<Field.Label>Email</Field.Label>
|
|
21
|
-
<Field.Control type="email" placeholder="you@example.com" />
|
|
22
|
-
<Field.Message />
|
|
23
|
-
</Field.Root>
|
|
24
|
-
<Button.Root status="idle">Continue</Button.Root>
|
|
25
|
-
</div>
|
|
26
|
-
)
|
|
27
|
-
}
|
|
28
|
-
`;
|
|
29
|
-
function initAeon(options = {}) {
|
|
30
|
-
const cwd = options.cwd ?? process.cwd();
|
|
31
|
-
const force = options.force ?? false;
|
|
32
|
-
const written = [];
|
|
33
|
-
const write = (rel, body) => {
|
|
34
|
-
const path = join(cwd, rel);
|
|
35
|
-
if (existsSync(path) && !force) {
|
|
36
|
-
written.push(`skip ${rel} (exists)`);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
mkdirSync(join(path, ".."), { recursive: true });
|
|
40
|
-
writeFileSync(path, body.endsWith("\n") ? body : `${body}
|
|
41
|
-
`);
|
|
42
|
-
written.push(`write ${rel}`);
|
|
43
|
-
};
|
|
44
|
-
write(".cursor/rules/aeon-ui.mdc", `---
|
|
45
|
-
description: Aeon UI \u2014 statechart-driven components for AI agents
|
|
46
|
-
globs: **/*.{tsx,ts,jsx,js}
|
|
47
|
-
alwaysApply: true
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
${CURSOR_RULES_SNIPPET.trim()}
|
|
51
|
-
`);
|
|
52
|
-
write("aeon.cursorrules.md", `${CURSOR_RULES_SNIPPET.trim()}
|
|
53
|
-
`);
|
|
54
|
-
write("aeon.system-prompt.md", `${AEON_SYSTEM_PROMPT.trim()}
|
|
55
|
-
`);
|
|
56
|
-
write(
|
|
57
|
-
"aeon.schemas/catalog.json",
|
|
58
|
-
`${JSON.stringify(
|
|
59
|
-
{
|
|
60
|
-
$id: catalog.$id,
|
|
61
|
-
title: catalog.title,
|
|
62
|
-
description: catalog.description,
|
|
63
|
-
version: catalog.version,
|
|
64
|
-
principle: catalog.principle,
|
|
65
|
-
attributes: catalog.attributes,
|
|
66
|
-
components: catalog.components,
|
|
67
|
-
note: "Full schemas live under aeon.schemas/components/*.json"
|
|
68
|
-
},
|
|
69
|
-
null,
|
|
70
|
-
2
|
|
71
|
-
)}
|
|
72
|
-
`
|
|
73
|
-
);
|
|
74
|
-
for (const [id, schema] of Object.entries(componentSchemas)) {
|
|
75
|
-
write(`aeon.schemas/components/${id}.json`, `${JSON.stringify(schema, null, 2)}
|
|
76
|
-
`);
|
|
77
|
-
}
|
|
78
|
-
write("src/components/AeonStarter.tsx", STARTER);
|
|
79
|
-
write(
|
|
80
|
-
"AEON_AI.md",
|
|
81
|
-
`# Aeon UI \u2014 AI agent setup
|
|
82
|
-
|
|
83
|
-
Generated by \`npx aeon-ui init\`.
|
|
84
|
-
|
|
85
|
-
## Next steps
|
|
86
|
-
|
|
87
|
-
1. Install: \`npm install aeon-ui-engine react react-dom xstate @xstate/react\`
|
|
88
|
-
2. CSS: \`import 'aeon-ui-engine/aeon.css'\`
|
|
89
|
-
3. Vite: add \`aeonUiVitePlugin()\` from \`aeon-ui-engine/vite\`
|
|
90
|
-
4. Paste \`aeon.cursorrules.md\` into Cursor rules / system prompt (already mirrored to \`.cursor/rules/aeon-ui.mdc\`)
|
|
91
|
-
5. Constrain generation with JSON under \`aeon.schemas/\`
|
|
92
|
-
|
|
93
|
-
## Principle
|
|
94
|
-
|
|
95
|
-
**UI = f(state)** \u2014 never invent boolean combinations for states the schema does not list.
|
|
96
|
-
`
|
|
97
|
-
);
|
|
98
|
-
return { cwd, written };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export {
|
|
102
|
-
initAeon
|
|
103
|
-
};
|