aeon-ui-engine 1.3.5 → 1.5.1

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 (104) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/CONSUMER.md +67 -27
  3. package/INTEGRATION.md +1 -1
  4. package/README.md +17 -8
  5. package/package.json +4 -1
  6. package/packages/cli/README.md +13 -1
  7. package/packages/cli/dist/bin.js +50 -6
  8. package/packages/cli/dist/chunk-JMNRJCWF.js +301 -0
  9. package/packages/cli/dist/index.d.ts +31 -1
  10. package/packages/cli/dist/index.js +7 -3
  11. package/packages/cli/src/bin.ts +50 -4
  12. package/packages/cli/src/index.ts +2 -0
  13. package/packages/cli/src/init.ts +10 -4
  14. package/packages/cli/src/link.ts +61 -0
  15. package/packages/cli/src/migrate.ts +170 -0
  16. package/packages/core/dist/index.d.ts +35 -7
  17. package/packages/core/dist/index.js +102 -2
  18. package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  19. package/packages/core/src/anatomy.ts +39 -3
  20. package/packages/core/src/identicon.test.ts +39 -0
  21. package/packages/core/src/identicon.ts +79 -0
  22. package/packages/core/src/index.ts +1 -0
  23. package/packages/panda/panda.config.ts +4 -0
  24. package/packages/panda/src/recipes/composer.ts +58 -4
  25. package/packages/panda/src/recipes/file-upload.ts +100 -0
  26. package/packages/panda/src/recipes/index.ts +2 -0
  27. package/packages/panda/src/recipes/range-slider.ts +59 -0
  28. package/packages/panda/src/recipes/thread.ts +77 -2
  29. package/packages/panda/styled-system/recipes/aeon-composer.d.ts +1 -1
  30. package/packages/panda/styled-system/recipes/aeon-composer.mjs +12 -0
  31. package/packages/panda/styled-system/recipes/aeon-file-upload.d.ts +31 -0
  32. package/packages/panda/styled-system/recipes/aeon-file-upload.mjs +61 -0
  33. package/packages/panda/styled-system/recipes/aeon-range-slider.d.ts +31 -0
  34. package/packages/panda/styled-system/recipes/aeon-range-slider.mjs +49 -0
  35. package/packages/panda/styled-system/recipes/aeon-thread.d.ts +1 -1
  36. package/packages/panda/styled-system/recipes/aeon-thread.mjs +20 -0
  37. package/packages/panda/styled-system/recipes/index.d.ts +2 -0
  38. package/packages/panda/styled-system/recipes/index.mjs +2 -0
  39. package/packages/panda/styled-system/styles.css +292 -0
  40. package/packages/primitives/dist/chunk-CV4UXXZF.js +44 -0
  41. package/packages/primitives/dist/chunk-IZKQSCYU.js +164 -0
  42. package/packages/primitives/dist/{chunk-PB3LFHXU.js → chunk-VUPWYBGU.js} +14 -0
  43. package/packages/primitives/dist/index.d.ts +2 -0
  44. package/packages/primitives/dist/index.js +23 -7
  45. package/packages/primitives/dist/machines/file-upload.d.ts +39 -0
  46. package/packages/primitives/dist/machines/file-upload.js +8 -0
  47. package/packages/primitives/dist/machines/range-slider.d.ts +129 -0
  48. package/packages/primitives/dist/machines/range-slider.js +12 -0
  49. package/packages/primitives/dist/machines/slider.d.ts +22 -0
  50. package/packages/primitives/dist/machines/slider.js +1 -1
  51. package/packages/primitives/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  52. package/packages/primitives/src/__tests__/file-upload.test.ts +25 -0
  53. package/packages/primitives/src/__tests__/range-slider.test.ts +39 -0
  54. package/packages/primitives/src/index.ts +2 -0
  55. package/packages/primitives/src/machines/file-upload.ts +55 -0
  56. package/packages/primitives/src/machines/range-slider.ts +209 -0
  57. package/packages/primitives/src/machines/slider.ts +17 -0
  58. package/packages/react/dist/index.d.ts +132 -26
  59. package/packages/react/dist/index.js +1822 -1029
  60. package/packages/react/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  61. package/packages/react/src/button/index.tsx +50 -15
  62. package/packages/react/src/composer/index.tsx +58 -3
  63. package/packages/react/src/file-upload/index.tsx +322 -0
  64. package/packages/react/src/floating/FloatingPositioner.tsx +8 -0
  65. package/packages/react/src/hooks/use-anchor-position.ts +88 -17
  66. package/packages/react/src/index.ts +3 -0
  67. package/packages/react/src/menu/index.tsx +37 -3
  68. package/packages/react/src/popover/index.tsx +7 -1
  69. package/packages/react/src/prompt/index.tsx +45 -0
  70. package/packages/react/src/range-slider/index.tsx +322 -0
  71. package/packages/react/src/slider/index.tsx +54 -14
  72. package/packages/react/src/thread/index.tsx +74 -3
  73. package/packages/react/src/tooltip/index.tsx +7 -1
  74. package/packages/react/src/utils/slot.tsx +47 -0
  75. package/packages/schemas/dist/index.d.ts +4 -0
  76. package/packages/schemas/dist/index.js +67 -1
  77. package/packages/schemas/json/button.json +6 -0
  78. package/packages/schemas/json/catalog.json +333 -0
  79. package/packages/schemas/json/fileUpload.json +168 -0
  80. package/packages/schemas/json/rangeSlider.json +157 -0
  81. package/packages/schemas/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  82. package/packages/schemas/prompts/cursorrules.md +3 -1
  83. package/packages/schemas/prompts/statecharts.md +1 -1
  84. package/packages/schemas/registry/catalog.json +18 -0
  85. package/packages/schemas/registry/components/button.json +6 -0
  86. package/packages/schemas/registry/components/fileUpload.json +168 -0
  87. package/packages/schemas/registry/components/rangeSlider.json +157 -0
  88. package/packages/schemas/registry/machines/fileUpload.json +182 -0
  89. package/packages/schemas/registry/machines/rangeSlider.json +201 -0
  90. package/packages/schemas/scripts/emit.ts +4 -0
  91. package/packages/schemas/src/components.ts +70 -0
  92. package/packages/schemas/src/prompts.ts +3 -1
  93. package/packages/schemas/tsconfig.json +1 -1
  94. package/packages/ui/dist/index.d.ts +100 -46
  95. package/packages/ui/dist/index.js +463 -341
  96. package/packages/ui/src/composer.tsx +37 -11
  97. package/packages/ui/src/file-upload.tsx +36 -0
  98. package/packages/ui/src/index.ts +2 -0
  99. package/packages/ui/src/prompt.tsx +3 -0
  100. package/packages/ui/src/range-slider.tsx +24 -0
  101. package/packages/ui/src/thread.tsx +40 -0
  102. package/scripts/link-scoped-packages.mjs +206 -0
  103. package/scripts/vite-aliases.mjs +6 -8
  104. package/packages/cli/dist/chunk-IW5NT2Z2.js +0 -103
@@ -1,15 +1,26 @@
1
1
  import { partAttrs, scopeAttrs, threadAnatomy } from '@aeon-ui/core'
2
- import { forwardRef, type HTMLAttributes, type ReactNode } from 'react'
2
+ import {
3
+ forwardRef,
4
+ type ButtonHTMLAttributes,
5
+ type HTMLAttributes,
6
+ type ReactNode,
7
+ } from 'react'
3
8
  import { mergeProps } from '../utils/merge-props.js'
4
9
 
10
+ /** Base alignment / delivery states. */
5
11
  export type ThreadMessageState = 'mine' | 'theirs' | 'pending' | 'failed'
6
12
 
13
+ /** Structured in-thread faces (space-combinable with mine/theirs). */
14
+ export type ThreadItemFace = 'command-result' | 'payment-card' | 'request-card'
15
+
7
16
  export interface ThreadRootProps extends HTMLAttributes<HTMLElement> {
8
17
  children?: ReactNode
9
18
  }
10
19
 
11
20
  /**
12
- * Thread — message stream. Item `state` projects mine | theirs | pending | failed.
21
+ * Thread — message stream.
22
+ * Item `state` projects mine | theirs | pending | failed, optionally plus
23
+ * command-result | payment-card | request-card (e.g. `mine payment-card`).
13
24
  */
14
25
  const Root = forwardRef<HTMLElement, ThreadRootProps>(function ThreadRoot(
15
26
  { children, ...rest },
@@ -40,7 +51,7 @@ const List = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(function
40
51
  })
41
52
 
42
53
  export interface ThreadItemProps extends HTMLAttributes<HTMLDivElement> {
43
- state?: ThreadMessageState | `${ThreadMessageState} ${string}`
54
+ state?: ThreadMessageState | ThreadItemFace | `${ThreadMessageState} ${ThreadItemFace}` | string
44
55
  }
45
56
 
46
57
  const Item = forwardRef<HTMLDivElement, ThreadItemProps>(function ThreadItem(
@@ -85,6 +96,61 @@ const Day = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(function
85
96
  )
86
97
  })
87
98
 
99
+ /** Reply / message-binding control — must be touch-reachable (BRC-218 §4.10). */
100
+ const Bind = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>(
101
+ function ThreadBind(props, ref) {
102
+ return (
103
+ <button
104
+ ref={ref}
105
+ type="button"
106
+ {...mergeProps(partAttrs(threadAnatomy.scope, threadAnatomy.bind), props)}
107
+ />
108
+ )
109
+ },
110
+ )
111
+
112
+ const Card = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(function ThreadCard(
113
+ props,
114
+ ref,
115
+ ) {
116
+ return (
117
+ <div ref={ref} {...mergeProps(partAttrs(threadAnatomy.scope, threadAnatomy.card), props)} />
118
+ )
119
+ })
120
+
121
+ const CardTitle = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
122
+ function ThreadCardTitle(props, ref) {
123
+ return (
124
+ <div
125
+ ref={ref}
126
+ {...mergeProps(partAttrs(threadAnatomy.scope, threadAnatomy.cardTitle), props)}
127
+ />
128
+ )
129
+ },
130
+ )
131
+
132
+ const CardBody = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
133
+ function ThreadCardBody(props, ref) {
134
+ return (
135
+ <div
136
+ ref={ref}
137
+ {...mergeProps(partAttrs(threadAnatomy.scope, threadAnatomy.cardBody), props)}
138
+ />
139
+ )
140
+ },
141
+ )
142
+
143
+ const CardActions = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
144
+ function ThreadCardActions(props, ref) {
145
+ return (
146
+ <div
147
+ ref={ref}
148
+ {...mergeProps(partAttrs(threadAnatomy.scope, threadAnatomy.cardActions), props)}
149
+ />
150
+ )
151
+ },
152
+ )
153
+
88
154
  export const Thread = {
89
155
  Root,
90
156
  List,
@@ -92,4 +158,9 @@ export const Thread = {
92
158
  Bubble,
93
159
  Meta,
94
160
  Day,
161
+ Bind,
162
+ Card,
163
+ CardTitle,
164
+ CardBody,
165
+ CardActions,
95
166
  }
@@ -272,11 +272,15 @@ export interface TooltipPositionerProps extends HTMLAttributes<HTMLDivElement> {
272
272
  /** Mount tooltip in document.body (default true). */
273
273
  portalled?: boolean
274
274
  placement?: AnchorPlacement
275
+ /** Gap between trigger and tip (default 4). */
276
+ gutter?: number
277
+ /** Stack level for the portalled surface (default 50). */
278
+ zIndex?: number
275
279
  children?: ReactNode
276
280
  }
277
281
 
278
282
  const Positioner = forwardRef<HTMLDivElement, TooltipPositionerProps>(function TooltipPositioner(
279
- { portalled = true, placement = 'top-start', children, className, ...rest },
283
+ { portalled = true, placement = 'top-start', gutter, zIndex, children, className, ...rest },
280
284
  ref,
281
285
  ) {
282
286
  const { open, triggerRef, positionerRef } = useTooltipCtx()
@@ -291,6 +295,8 @@ const Positioner = forwardRef<HTMLDivElement, TooltipPositionerProps>(function T
291
295
  positionerRef={positionerRef}
292
296
  portalled={portalled}
293
297
  placement={placement}
298
+ gutter={gutter}
299
+ zIndex={zIndex}
294
300
  className={className}
295
301
  {...rest}
296
302
  >
@@ -0,0 +1,47 @@
1
+ import {
2
+ Children,
3
+ cloneElement,
4
+ forwardRef,
5
+ isValidElement,
6
+ type HTMLAttributes,
7
+ type ReactElement,
8
+ type ReactNode,
9
+ type Ref,
10
+ } from 'react'
11
+ import { mergeProps } from './merge-props.js'
12
+
13
+ function mergeRefs<T>(...refs: Array<Ref<T> | undefined>) {
14
+ return (node: T) => {
15
+ for (const ref of refs) {
16
+ if (!ref) continue
17
+ if (typeof ref === 'function') ref(node)
18
+ else (ref as { current: T }).current = node
19
+ }
20
+ }
21
+ }
22
+
23
+ export type SlotProps = HTMLAttributes<HTMLElement> & {
24
+ children?: ReactNode
25
+ }
26
+
27
+ /**
28
+ * Radix-style Slot — merges Aeon attrs onto a single child element
29
+ * (e.g. Next.js Link) instead of rendering a wrapper.
30
+ */
31
+ export const Slot = forwardRef<HTMLElement, SlotProps>(function Slot(
32
+ { children, ...props },
33
+ forwardedRef,
34
+ ) {
35
+ const child = Children.only(children)
36
+ if (!isValidElement(child)) {
37
+ throw new Error('Slot expects a single React element child')
38
+ }
39
+
40
+ const childElement = child as ReactElement<HTMLAttributes<HTMLElement> & { ref?: Ref<HTMLElement> }>
41
+ const childProps = childElement.props
42
+
43
+ return cloneElement(childElement, {
44
+ ...mergeProps(props, childProps),
45
+ ref: mergeRefs(forwardedRef, childProps.ref),
46
+ } as HTMLAttributes<HTMLElement>)
47
+ })
@@ -37,6 +37,8 @@ declare const componentSchemas: {
37
37
  readonly progress: JsonSchema;
38
38
  readonly radioGroup: JsonSchema;
39
39
  readonly slider: JsonSchema;
40
+ readonly rangeSlider: JsonSchema;
41
+ readonly fileUpload: JsonSchema;
40
42
  readonly pinInput: JsonSchema;
41
43
  readonly avatar: JsonSchema;
42
44
  readonly content: JsonSchema;
@@ -87,6 +89,8 @@ declare const catalog: {
87
89
  readonly progress: JsonSchema;
88
90
  readonly radioGroup: JsonSchema;
89
91
  readonly slider: JsonSchema;
92
+ readonly rangeSlider: JsonSchema;
93
+ readonly fileUpload: JsonSchema;
90
94
  readonly pinInput: JsonSchema;
91
95
  readonly avatar: JsonSchema;
92
96
  readonly content: JsonSchema;
@@ -89,11 +89,16 @@ var componentSchemas = {
89
89
  },
90
90
  variant: { type: "string", enum: ["solid", "outline", "ghost", "link"] },
91
91
  size: { type: "string", enum: ["sm", "md", "lg"] },
92
- disabled: { type: "boolean" }
92
+ disabled: { type: "boolean" },
93
+ asChild: {
94
+ type: "boolean",
95
+ description: "Merge button attrs onto a single child element (Link, a)."
96
+ }
93
97
  },
94
98
  slots: { Root: "button.root", Group: "button.group", Label: "button.label", Icon: "button.icon" },
95
99
  examples: [
96
100
  '<Button.Root status="pending" aria-busy>Saving\u2026</Button.Root>',
101
+ '<Button.Root asChild variant="solid"><a href="/upload">Upload</a></Button.Root>',
97
102
  "const [snap, send] = useAeonMachine(buttonLifecycleMachine)\n<Button.Root status={snap.value as ButtonStatus} onClick={() => send({ type: 'PRESS' })} />"
98
103
  ]
99
104
  }),
@@ -378,6 +383,67 @@ var componentSchemas = {
378
383
  ValueText: "slider.valueText"
379
384
  }
380
385
  }),
386
+ rangeSlider: componentSchema({
387
+ id: "https://aeon-ui.com/schemas/rangeSlider.json",
388
+ title: "RangeSlider",
389
+ description: "Two-thumb range via rangeSliderMachine \u2014 idle | dragging with values pair and minStepsBetween gap.",
390
+ scope: "rangeSlider",
391
+ parts: ["root", "track", "range", "thumb", "valueText"],
392
+ states: ["idle", "dragging"],
393
+ machine: "rangeSliderMachine",
394
+ runtime: "useAeonMachine",
395
+ events: [
396
+ "SET_VALUES",
397
+ "SET_BOUNDS",
398
+ "SET_DISABLED",
399
+ "POINTER_DOWN",
400
+ "POINTER_MOVE",
401
+ "POINTER_UP",
402
+ "STEP",
403
+ "HOME",
404
+ "END"
405
+ ],
406
+ slots: {
407
+ Root: "rangeSlider.root",
408
+ Track: "rangeSlider.track",
409
+ Range: "rangeSlider.range",
410
+ Thumb: "rangeSlider.thumb",
411
+ ValueText: "rangeSlider.valueText"
412
+ },
413
+ examples: [
414
+ "<RangeSlider.Root defaultValue={[20, 80]} minStepsBetween={1}>\n <RangeSlider.Track /><RangeSlider.Range />\n <RangeSlider.Thumb index={0} /><RangeSlider.Thumb index={1} />\n</RangeSlider.Root>"
415
+ ]
416
+ }),
417
+ fileUpload: componentSchema({
418
+ id: "https://aeon-ui.com/schemas/fileUpload.json",
419
+ title: "FileUpload",
420
+ description: "Drag-drop surface via fileUploadMachine \u2014 idle | dragging | rejected. File bytes stay in React callbacks.",
421
+ scope: "fileUpload",
422
+ parts: [
423
+ "root",
424
+ "dropzone",
425
+ "input",
426
+ "label",
427
+ "hint",
428
+ "preview",
429
+ "clearTrigger",
430
+ "rejectionMessage"
431
+ ],
432
+ states: ["idle", "dragging", "rejected"],
433
+ machine: "fileUploadMachine",
434
+ runtime: "useAeonMachine",
435
+ events: ["DRAG_OVER", "DRAG_LEAVE", "DROP_ACCEPT", "DROP_REJECT", "RESET"],
436
+ slots: {
437
+ Root: "fileUpload.root",
438
+ Dropzone: "fileUpload.dropzone",
439
+ Input: "fileUpload.input",
440
+ Label: "fileUpload.label",
441
+ Hint: "fileUpload.hint",
442
+ Preview: "fileUpload.preview",
443
+ ClearTrigger: "fileUpload.clearTrigger",
444
+ RejectionMessage: "fileUpload.rejectionMessage"
445
+ }
446
+ }),
381
447
  pinInput: componentSchema({
382
448
  id: "https://aeon-ui.com/schemas/pinInput.json",
383
449
  title: "PinInput",
@@ -79,6 +79,10 @@
79
79
  },
80
80
  "disabled": {
81
81
  "type": "boolean"
82
+ },
83
+ "asChild": {
84
+ "type": "boolean",
85
+ "description": "Merge button attrs onto a single child element (Link, a)."
82
86
  }
83
87
  }
84
88
  },
@@ -134,6 +138,7 @@
134
138
  },
135
139
  "default": [
136
140
  "<Button.Root status=\"pending\" aria-busy>Saving…</Button.Root>",
141
+ "<Button.Root asChild variant=\"solid\"><a href=\"/upload\">Upload</a></Button.Root>",
137
142
  "const [snap, send] = useAeonMachine(buttonLifecycleMachine)\n<Button.Root status={snap.value as ButtonStatus} onClick={() => send({ type: 'PRESS' })} />"
138
143
  ]
139
144
  }
@@ -164,6 +169,7 @@
164
169
  },
165
170
  "examples": [
166
171
  "<Button.Root status=\"pending\" aria-busy>Saving…</Button.Root>",
172
+ "<Button.Root asChild variant=\"solid\"><a href=\"/upload\">Upload</a></Button.Root>",
167
173
  "const [snap, send] = useAeonMachine(buttonLifecycleMachine)\n<Button.Root status={snap.value as ButtonStatus} onClick={() => send({ type: 'PRESS' })} />"
168
174
  ]
169
175
  }
@@ -29,6 +29,8 @@
29
29
  "progress",
30
30
  "radioGroup",
31
31
  "slider",
32
+ "rangeSlider",
33
+ "fileUpload",
32
34
  "pinInput",
33
35
  "avatar",
34
36
  "content",
@@ -132,6 +134,10 @@
132
134
  },
133
135
  "disabled": {
134
136
  "type": "boolean"
137
+ },
138
+ "asChild": {
139
+ "type": "boolean",
140
+ "description": "Merge button attrs onto a single child element (Link, a)."
135
141
  }
136
142
  }
137
143
  },
@@ -187,6 +193,7 @@
187
193
  },
188
194
  "default": [
189
195
  "<Button.Root status=\"pending\" aria-busy>Saving…</Button.Root>",
196
+ "<Button.Root asChild variant=\"solid\"><a href=\"/upload\">Upload</a></Button.Root>",
190
197
  "const [snap, send] = useAeonMachine(buttonLifecycleMachine)\n<Button.Root status={snap.value as ButtonStatus} onClick={() => send({ type: 'PRESS' })} />"
191
198
  ]
192
199
  }
@@ -217,6 +224,7 @@
217
224
  },
218
225
  "examples": [
219
226
  "<Button.Root status=\"pending\" aria-busy>Saving…</Button.Root>",
227
+ "<Button.Root asChild variant=\"solid\"><a href=\"/upload\">Upload</a></Button.Root>",
220
228
  "const [snap, send] = useAeonMachine(buttonLifecycleMachine)\n<Button.Root status={snap.value as ButtonStatus} onClick={() => send({ type: 'PRESS' })} />"
221
229
  ]
222
230
  }
@@ -2620,6 +2628,331 @@
2620
2628
  "examples": []
2621
2629
  }
2622
2630
  },
2631
+ "rangeSlider": {
2632
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
2633
+ "$id": "https://aeon-ui.com/schemas/rangeSlider.json",
2634
+ "title": "RangeSlider",
2635
+ "description": "Two-thumb range via rangeSliderMachine — idle | dragging with values pair and minStepsBetween gap.",
2636
+ "type": "object",
2637
+ "additionalProperties": false,
2638
+ "required": [
2639
+ "component",
2640
+ "scope"
2641
+ ],
2642
+ "properties": {
2643
+ "component": {
2644
+ "const": "RangeSlider"
2645
+ },
2646
+ "scope": {
2647
+ "const": "rangeSlider"
2648
+ },
2649
+ "parts": {
2650
+ "type": "array",
2651
+ "description": "Anatomy part keys — map to data-aeon-part",
2652
+ "items": {
2653
+ "type": "string",
2654
+ "enum": [
2655
+ "root",
2656
+ "track",
2657
+ "range",
2658
+ "thumb",
2659
+ "valueText"
2660
+ ]
2661
+ },
2662
+ "uniqueItems": true
2663
+ },
2664
+ "states": {
2665
+ "type": "array",
2666
+ "description": "Allowed data-aeon-state values (stable states only)",
2667
+ "items": {
2668
+ "type": "string",
2669
+ "enum": [
2670
+ "idle",
2671
+ "dragging"
2672
+ ]
2673
+ },
2674
+ "uniqueItems": true
2675
+ },
2676
+ "props": {
2677
+ "type": "object",
2678
+ "additionalProperties": false,
2679
+ "properties": {}
2680
+ },
2681
+ "slots": {
2682
+ "type": "object",
2683
+ "description": "Named composition slots / compound parts",
2684
+ "additionalProperties": {
2685
+ "type": "string"
2686
+ },
2687
+ "properties": {
2688
+ "Root": {
2689
+ "const": "rangeSlider.root",
2690
+ "description": "rangeSlider.root"
2691
+ },
2692
+ "Track": {
2693
+ "const": "rangeSlider.track",
2694
+ "description": "rangeSlider.track"
2695
+ },
2696
+ "Range": {
2697
+ "const": "rangeSlider.range",
2698
+ "description": "rangeSlider.range"
2699
+ },
2700
+ "Thumb": {
2701
+ "const": "rangeSlider.thumb",
2702
+ "description": "rangeSlider.thumb"
2703
+ },
2704
+ "ValueText": {
2705
+ "const": "rangeSlider.valueText",
2706
+ "description": "rangeSlider.valueText"
2707
+ }
2708
+ }
2709
+ },
2710
+ "machine": {
2711
+ "type": [
2712
+ "string",
2713
+ "null"
2714
+ ],
2715
+ "description": "XState machine export from @aeon-ui/primitives, or null if prop/React driven",
2716
+ "const": "rangeSliderMachine"
2717
+ },
2718
+ "runtime": {
2719
+ "type": "string",
2720
+ "description": "How headless state is driven at runtime",
2721
+ "const": "useAeonMachine"
2722
+ },
2723
+ "events": {
2724
+ "type": "array",
2725
+ "items": {
2726
+ "type": "string",
2727
+ "enum": [
2728
+ "SET_VALUES",
2729
+ "SET_BOUNDS",
2730
+ "SET_DISABLED",
2731
+ "POINTER_DOWN",
2732
+ "POINTER_MOVE",
2733
+ "POINTER_UP",
2734
+ "STEP",
2735
+ "HOME",
2736
+ "END"
2737
+ ]
2738
+ }
2739
+ },
2740
+ "examples": {
2741
+ "type": "array",
2742
+ "items": {
2743
+ "type": "string"
2744
+ },
2745
+ "default": [
2746
+ "<RangeSlider.Root defaultValue={[20, 80]} minStepsBetween={1}>\n <RangeSlider.Track /><RangeSlider.Range />\n <RangeSlider.Thumb index={0} /><RangeSlider.Thumb index={1} />\n</RangeSlider.Root>"
2747
+ ]
2748
+ }
2749
+ },
2750
+ "x-aeon": {
2751
+ "scope": "rangeSlider",
2752
+ "parts": [
2753
+ "root",
2754
+ "track",
2755
+ "range",
2756
+ "thumb",
2757
+ "valueText"
2758
+ ],
2759
+ "states": [
2760
+ "idle",
2761
+ "dragging"
2762
+ ],
2763
+ "machine": "rangeSliderMachine",
2764
+ "runtime": "useAeonMachine",
2765
+ "events": [
2766
+ "SET_VALUES",
2767
+ "SET_BOUNDS",
2768
+ "SET_DISABLED",
2769
+ "POINTER_DOWN",
2770
+ "POINTER_MOVE",
2771
+ "POINTER_UP",
2772
+ "STEP",
2773
+ "HOME",
2774
+ "END"
2775
+ ],
2776
+ "slots": {
2777
+ "Root": "rangeSlider.root",
2778
+ "Track": "rangeSlider.track",
2779
+ "Range": "rangeSlider.range",
2780
+ "Thumb": "rangeSlider.thumb",
2781
+ "ValueText": "rangeSlider.valueText"
2782
+ },
2783
+ "examples": [
2784
+ "<RangeSlider.Root defaultValue={[20, 80]} minStepsBetween={1}>\n <RangeSlider.Track /><RangeSlider.Range />\n <RangeSlider.Thumb index={0} /><RangeSlider.Thumb index={1} />\n</RangeSlider.Root>"
2785
+ ]
2786
+ }
2787
+ },
2788
+ "fileUpload": {
2789
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
2790
+ "$id": "https://aeon-ui.com/schemas/fileUpload.json",
2791
+ "title": "FileUpload",
2792
+ "description": "Drag-drop surface via fileUploadMachine — idle | dragging | rejected. File bytes stay in React callbacks.",
2793
+ "type": "object",
2794
+ "additionalProperties": false,
2795
+ "required": [
2796
+ "component",
2797
+ "scope"
2798
+ ],
2799
+ "properties": {
2800
+ "component": {
2801
+ "const": "FileUpload"
2802
+ },
2803
+ "scope": {
2804
+ "const": "fileUpload"
2805
+ },
2806
+ "parts": {
2807
+ "type": "array",
2808
+ "description": "Anatomy part keys — map to data-aeon-part",
2809
+ "items": {
2810
+ "type": "string",
2811
+ "enum": [
2812
+ "root",
2813
+ "dropzone",
2814
+ "input",
2815
+ "label",
2816
+ "hint",
2817
+ "preview",
2818
+ "clearTrigger",
2819
+ "rejectionMessage"
2820
+ ]
2821
+ },
2822
+ "uniqueItems": true
2823
+ },
2824
+ "states": {
2825
+ "type": "array",
2826
+ "description": "Allowed data-aeon-state values (stable states only)",
2827
+ "items": {
2828
+ "type": "string",
2829
+ "enum": [
2830
+ "idle",
2831
+ "dragging",
2832
+ "rejected"
2833
+ ]
2834
+ },
2835
+ "uniqueItems": true
2836
+ },
2837
+ "props": {
2838
+ "type": "object",
2839
+ "additionalProperties": false,
2840
+ "properties": {}
2841
+ },
2842
+ "slots": {
2843
+ "type": "object",
2844
+ "description": "Named composition slots / compound parts",
2845
+ "additionalProperties": {
2846
+ "type": "string"
2847
+ },
2848
+ "properties": {
2849
+ "Root": {
2850
+ "const": "fileUpload.root",
2851
+ "description": "fileUpload.root"
2852
+ },
2853
+ "Dropzone": {
2854
+ "const": "fileUpload.dropzone",
2855
+ "description": "fileUpload.dropzone"
2856
+ },
2857
+ "Input": {
2858
+ "const": "fileUpload.input",
2859
+ "description": "fileUpload.input"
2860
+ },
2861
+ "Label": {
2862
+ "const": "fileUpload.label",
2863
+ "description": "fileUpload.label"
2864
+ },
2865
+ "Hint": {
2866
+ "const": "fileUpload.hint",
2867
+ "description": "fileUpload.hint"
2868
+ },
2869
+ "Preview": {
2870
+ "const": "fileUpload.preview",
2871
+ "description": "fileUpload.preview"
2872
+ },
2873
+ "ClearTrigger": {
2874
+ "const": "fileUpload.clearTrigger",
2875
+ "description": "fileUpload.clearTrigger"
2876
+ },
2877
+ "RejectionMessage": {
2878
+ "const": "fileUpload.rejectionMessage",
2879
+ "description": "fileUpload.rejectionMessage"
2880
+ }
2881
+ }
2882
+ },
2883
+ "machine": {
2884
+ "type": [
2885
+ "string",
2886
+ "null"
2887
+ ],
2888
+ "description": "XState machine export from @aeon-ui/primitives, or null if prop/React driven",
2889
+ "const": "fileUploadMachine"
2890
+ },
2891
+ "runtime": {
2892
+ "type": "string",
2893
+ "description": "How headless state is driven at runtime",
2894
+ "const": "useAeonMachine"
2895
+ },
2896
+ "events": {
2897
+ "type": "array",
2898
+ "items": {
2899
+ "type": "string",
2900
+ "enum": [
2901
+ "DRAG_OVER",
2902
+ "DRAG_LEAVE",
2903
+ "DROP_ACCEPT",
2904
+ "DROP_REJECT",
2905
+ "RESET"
2906
+ ]
2907
+ }
2908
+ },
2909
+ "examples": {
2910
+ "type": "array",
2911
+ "items": {
2912
+ "type": "string"
2913
+ },
2914
+ "default": []
2915
+ }
2916
+ },
2917
+ "x-aeon": {
2918
+ "scope": "fileUpload",
2919
+ "parts": [
2920
+ "root",
2921
+ "dropzone",
2922
+ "input",
2923
+ "label",
2924
+ "hint",
2925
+ "preview",
2926
+ "clearTrigger",
2927
+ "rejectionMessage"
2928
+ ],
2929
+ "states": [
2930
+ "idle",
2931
+ "dragging",
2932
+ "rejected"
2933
+ ],
2934
+ "machine": "fileUploadMachine",
2935
+ "runtime": "useAeonMachine",
2936
+ "events": [
2937
+ "DRAG_OVER",
2938
+ "DRAG_LEAVE",
2939
+ "DROP_ACCEPT",
2940
+ "DROP_REJECT",
2941
+ "RESET"
2942
+ ],
2943
+ "slots": {
2944
+ "Root": "fileUpload.root",
2945
+ "Dropzone": "fileUpload.dropzone",
2946
+ "Input": "fileUpload.input",
2947
+ "Label": "fileUpload.label",
2948
+ "Hint": "fileUpload.hint",
2949
+ "Preview": "fileUpload.preview",
2950
+ "ClearTrigger": "fileUpload.clearTrigger",
2951
+ "RejectionMessage": "fileUpload.rejectionMessage"
2952
+ },
2953
+ "examples": []
2954
+ }
2955
+ },
2623
2956
  "pinInput": {
2624
2957
  "$schema": "https://json-schema.org/draft/2020-12/schema",
2625
2958
  "$id": "https://aeon-ui.com/schemas/pinInput.json",