@antadesign/anta 0.2.1 → 0.3.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 (85) hide show
  1. package/README.md +14 -0
  2. package/dist/anta_helpers.d.ts +39 -1
  3. package/dist/anta_helpers.js +30 -2
  4. package/dist/components/Button.d.ts +7 -4
  5. package/dist/components/Button.js +12 -14
  6. package/dist/components/Checkbox.d.ts +97 -0
  7. package/dist/components/Checkbox.js +77 -0
  8. package/dist/components/Expander.d.ts +74 -0
  9. package/dist/components/Expander.js +53 -0
  10. package/dist/components/Input.d.ts +159 -0
  11. package/dist/components/Input.js +150 -0
  12. package/dist/components/Menu.d.ts +70 -0
  13. package/dist/components/Menu.js +42 -0
  14. package/dist/components/MenuGroup.d.ts +24 -0
  15. package/dist/components/MenuGroup.js +19 -0
  16. package/dist/components/MenuItem.d.ts +50 -0
  17. package/dist/components/MenuItem.js +41 -0
  18. package/dist/components/MenuSeparator.d.ts +14 -0
  19. package/dist/components/MenuSeparator.js +7 -0
  20. package/dist/components/Progress.d.ts +12 -6
  21. package/dist/components/Progress.js +7 -4
  22. package/dist/components/Radio.d.ts +37 -0
  23. package/dist/components/Radio.js +33 -0
  24. package/dist/components/RadioGroup.d.ts +119 -0
  25. package/dist/components/RadioGroup.js +108 -0
  26. package/dist/components/Tag.d.ts +38 -5
  27. package/dist/components/Tag.js +9 -5
  28. package/dist/components/Text.d.ts +27 -12
  29. package/dist/components/Text.js +6 -3
  30. package/dist/components/Title.d.ts +10 -1
  31. package/dist/components/Tooltip.d.ts +19 -9
  32. package/dist/components/Tooltip.js +2 -2
  33. package/dist/elements/a-button.css +1 -1
  34. package/dist/elements/a-button.d.ts +56 -0
  35. package/dist/elements/a-button.js +13 -11
  36. package/dist/elements/a-checkbox.css +1 -0
  37. package/dist/elements/a-checkbox.d.ts +52 -0
  38. package/dist/elements/a-checkbox.js +130 -0
  39. package/dist/elements/a-expander.css +1 -0
  40. package/dist/elements/a-expander.d.ts +28 -0
  41. package/dist/elements/a-expander.js +237 -0
  42. package/dist/elements/a-icon.d.ts +14 -0
  43. package/dist/elements/a-icon.shapes.css +1 -1
  44. package/dist/elements/a-icon.shapes.d.ts +10 -2
  45. package/dist/elements/a-icon.shapes.js +12 -3
  46. package/dist/elements/a-input.css +1 -0
  47. package/dist/elements/a-input.d.ts +68 -0
  48. package/dist/elements/a-input.js +511 -0
  49. package/dist/elements/a-menu-group.css +1 -0
  50. package/dist/elements/a-menu-group.d.ts +13 -0
  51. package/dist/elements/a-menu-group.js +15 -0
  52. package/dist/elements/a-menu-item.css +1 -0
  53. package/dist/elements/a-menu-item.d.ts +47 -0
  54. package/dist/elements/a-menu-item.js +30 -0
  55. package/dist/elements/a-menu-separator.css +1 -0
  56. package/dist/elements/a-menu-separator.d.ts +13 -0
  57. package/dist/elements/a-menu-separator.js +15 -0
  58. package/dist/elements/a-menu.css +1 -0
  59. package/dist/elements/a-menu.d.ts +171 -0
  60. package/dist/elements/a-menu.js +714 -0
  61. package/dist/elements/a-progress.css +1 -1
  62. package/dist/elements/a-progress.d.ts +12 -0
  63. package/dist/elements/a-progress.js +1 -0
  64. package/dist/elements/a-radio-group.css +1 -0
  65. package/dist/elements/a-radio-group.d.ts +33 -0
  66. package/dist/elements/a-radio-group.js +160 -0
  67. package/dist/elements/a-radio.css +1 -0
  68. package/dist/elements/a-radio.d.ts +14 -0
  69. package/dist/elements/a-radio.js +46 -0
  70. package/dist/elements/a-tag.css +1 -1
  71. package/dist/elements/a-text.css +1 -1
  72. package/dist/elements/a-text.d.ts +42 -3
  73. package/dist/elements/a-text.js +73 -33
  74. package/dist/elements/a-title.css +1 -1
  75. package/dist/elements/a-tooltip.d.ts +65 -15
  76. package/dist/elements/a-tooltip.js +155 -115
  77. package/dist/elements/index.d.ts +9 -0
  78. package/dist/elements/index.js +27 -0
  79. package/dist/general_types.d.ts +471 -19
  80. package/dist/index.d.ts +16 -0
  81. package/dist/index.js +16 -0
  82. package/dist/jsx-runtime.d.ts +42 -7
  83. package/dist/jsx-runtime.js +14 -2
  84. package/dist/tokens.css +1 -1
  85. package/package.json +1 -1
@@ -18,10 +18,105 @@ export interface BaseProps {
18
18
  /** Any `aria-*` attribute is forwarded to the rendered element. */
19
19
  [key: `aria-${string}`]: unknown;
20
20
  }
21
+ /**
22
+ * Standard DOM event handlers Anta forwards to the rendered element. These are
23
+ * **enumerated on purpose** — rather than an open `on${string}` index signature
24
+ * — so a typo like `onClik` is a type error instead of silently accepted. They
25
+ * stay `(e: any) => void` to remain React/Preact-agnostic (we don't commit to
26
+ * either framework's event types). Standard events bubble/compose, so a handler
27
+ * on an `<a-*>` host fires for interactions inside its shadow DOM. Component-
28
+ * specific events (e.g. `oninput`/`onclearclick` on `<a-input>`) are declared on
29
+ * that element's own attributes. This enumerates the full standard (bubble-phase)
30
+ * DOM event set; add a `…Capture` variant here if one is ever needed.
31
+ */
32
+ export interface DOMEventHandlers {
33
+ onClick?: (e: any) => void;
34
+ onDoubleClick?: (e: any) => void;
35
+ onAuxClick?: (e: any) => void;
36
+ onContextMenu?: (e: any) => void;
37
+ onMouseDown?: (e: any) => void;
38
+ onMouseUp?: (e: any) => void;
39
+ onMouseEnter?: (e: any) => void;
40
+ onMouseLeave?: (e: any) => void;
41
+ onMouseMove?: (e: any) => void;
42
+ onMouseOver?: (e: any) => void;
43
+ onMouseOut?: (e: any) => void;
44
+ onPointerDown?: (e: any) => void;
45
+ onPointerUp?: (e: any) => void;
46
+ onPointerMove?: (e: any) => void;
47
+ onPointerEnter?: (e: any) => void;
48
+ onPointerLeave?: (e: any) => void;
49
+ onPointerOver?: (e: any) => void;
50
+ onPointerOut?: (e: any) => void;
51
+ onPointerCancel?: (e: any) => void;
52
+ onGotPointerCapture?: (e: any) => void;
53
+ onLostPointerCapture?: (e: any) => void;
54
+ onTouchStart?: (e: any) => void;
55
+ onTouchEnd?: (e: any) => void;
56
+ onTouchMove?: (e: any) => void;
57
+ onTouchCancel?: (e: any) => void;
58
+ onKeyDown?: (e: any) => void;
59
+ onKeyUp?: (e: any) => void;
60
+ onFocus?: (e: any) => void;
61
+ onBlur?: (e: any) => void;
62
+ onChange?: (e: any) => void;
63
+ onInput?: (e: any) => void;
64
+ onBeforeInput?: (e: any) => void;
65
+ onInvalid?: (e: any) => void;
66
+ onReset?: (e: any) => void;
67
+ onSubmit?: (e: any) => void;
68
+ onSelect?: (e: any) => void;
69
+ onCopy?: (e: any) => void;
70
+ onCut?: (e: any) => void;
71
+ onPaste?: (e: any) => void;
72
+ onCompositionStart?: (e: any) => void;
73
+ onCompositionUpdate?: (e: any) => void;
74
+ onCompositionEnd?: (e: any) => void;
75
+ onDrag?: (e: any) => void;
76
+ onDragStart?: (e: any) => void;
77
+ onDragEnd?: (e: any) => void;
78
+ onDragEnter?: (e: any) => void;
79
+ onDragLeave?: (e: any) => void;
80
+ onDragOver?: (e: any) => void;
81
+ onDrop?: (e: any) => void;
82
+ onScroll?: (e: any) => void;
83
+ onWheel?: (e: any) => void;
84
+ onAnimationStart?: (e: any) => void;
85
+ onAnimationEnd?: (e: any) => void;
86
+ onAnimationIteration?: (e: any) => void;
87
+ onTransitionEnd?: (e: any) => void;
88
+ onLoad?: (e: any) => void;
89
+ onError?: (e: any) => void;
90
+ onAbort?: (e: any) => void;
91
+ onToggle?: (e: any) => void;
92
+ onBeforeToggle?: (e: any) => void;
93
+ onCanPlay?: (e: any) => void;
94
+ onCanPlayThrough?: (e: any) => void;
95
+ onDurationChange?: (e: any) => void;
96
+ onEmptied?: (e: any) => void;
97
+ onEnded?: (e: any) => void;
98
+ onLoadedData?: (e: any) => void;
99
+ onLoadedMetadata?: (e: any) => void;
100
+ onLoadStart?: (e: any) => void;
101
+ onPause?: (e: any) => void;
102
+ onPlay?: (e: any) => void;
103
+ onPlaying?: (e: any) => void;
104
+ onProgress?: (e: any) => void;
105
+ onRateChange?: (e: any) => void;
106
+ onSeeked?: (e: any) => void;
107
+ onSeeking?: (e: any) => void;
108
+ onStalled?: (e: any) => void;
109
+ onSuspend?: (e: any) => void;
110
+ onTimeUpdate?: (e: any) => void;
111
+ onVolumeChange?: (e: any) => void;
112
+ onWaiting?: (e: any) => void;
113
+ }
21
114
  /** Attributes for intrinsic custom elements (`<a-*>` tags) in JSX. */
22
- export interface BaseAttributes {
115
+ export interface BaseAttributes extends DOMEventHandlers {
23
116
  /** React/Preact reconciliation key when rendered inside a list. */
24
117
  key?: string | number | null;
118
+ /** HTML `id` attribute. */
119
+ id?: string;
25
120
  /** HTML `class` attribute (standard DOM). */
26
121
  class?: string;
27
122
  /** React/Preact-style class name. Alias for `class`. */
@@ -29,14 +124,12 @@ export interface BaseAttributes {
29
124
  /** Inline styles applied to the element. */
30
125
  style?: React.CSSProperties;
31
126
  children?: React.ReactNode;
127
+ /** Assigns the element to a named `<slot>` (e.g. `slot="title"`). */
128
+ slot?: string;
32
129
  /** Tab order. Set to `0` to make the element keyboard-focusable. */
33
130
  tabIndex?: number;
34
131
  /** ARIA role override. */
35
132
  role?: string;
36
- /** Keydown handler — used for keyboard-driven interactions. */
37
- onKeyDown?: (e: any) => void;
38
- /** Click handler — used for mouse / tap activation. */
39
- onClick?: (e: any) => void;
40
133
  }
41
134
  /**
42
135
  * Attributes for the `<a-progress>` custom element.
@@ -49,8 +142,9 @@ export interface AProgressAttributes extends BaseAttributes {
49
142
  value?: number | string;
50
143
  /** Maximum value. Defaults to 100. */
51
144
  max?: number | string;
52
- /** Color variant. `'neutral'` is the default gray; `'info'` is blue. */
53
- tone?: 'neutral' | 'info';
145
+ /** Colour variant, or any literal CSS colour for a custom tone (derived in
146
+ * oklch). Named tones track light/dark automatically. */
147
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
54
148
  /** ARIA role — the JSX wrapper sets this to `'progressbar'`. */
55
149
  role?: string;
56
150
  /** ARIA value-now (current). */
@@ -72,7 +166,7 @@ export interface ATextAttributes extends BaseAttributes {
72
166
  /** Visual priority. Maps to text-1..text-5. */
73
167
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
74
168
  /** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
75
- tone?: 'brand' | 'success' | 'critical' | 'warning' | 'info';
169
+ tone?: 'brand' | 'info' | 'success' | 'warning' | 'critical';
76
170
  /** Type scale. `small` = 13/16, `medium` (default) = 15/20, `large` = 17/24. */
77
171
  size?: 'small' | 'medium' | 'large';
78
172
  /** Render as inline-block instead of the default block. */
@@ -82,9 +176,13 @@ export interface ATextAttributes extends BaseAttributes {
82
176
  * available via the `--line-clamp` CSS custom property set inline. */
83
177
  truncate?: boolean | string | number;
84
178
  /** Marks the host as expandable when paired with `truncate`. Adds
85
- * the fade-out mask; the JSX wrapper renders the chevron and owns
86
- * the click/keyboard expansion logic. */
179
+ * the fade-out mask and the expand/collapse chevron button; the element
180
+ * owns the click/keyboard expansion logic. Without `collapsible`,
181
+ * expanding is one-way (the control is removed once expanded). */
87
182
  expandable?: boolean | '';
183
+ /** Paired with `expandable`: the chevron becomes a two-way "Show more" /
184
+ * "Show less" toggle that stays visible while expanded. Omit for one-way. */
185
+ collapsible?: boolean | '';
88
186
  /** ARIA disclosure state, mirrors the JSX wrapper's `expanded` flag. */
89
187
  'aria-expanded'?: boolean | 'true' | 'false';
90
188
  }
@@ -101,7 +199,7 @@ export interface ATitleAttributes extends BaseAttributes {
101
199
  /** Visual priority. Maps to text-1..text-5. */
102
200
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
103
201
  /** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
104
- tone?: 'brand' | 'success' | 'critical' | 'warning' | 'info';
202
+ tone?: 'brand' | 'info' | 'success' | 'warning' | 'critical';
105
203
  /** ARIA role — the JSX wrapper sets this to `'heading'`. */
106
204
  role?: string;
107
205
  /** ARIA heading level — the JSX wrapper sets this to match `level`. */
@@ -115,10 +213,14 @@ export interface ATitleAttributes extends BaseAttributes {
115
213
  */
116
214
  export interface ATagAttributes extends BaseAttributes {
117
215
  /** Semantic tone, or any literal CSS color for a one-off custom tone.
118
- * Named tones map to the `--text-2-{tone}` / `--bg-4-{tone}` palette;
119
- * a custom color keeps its hue with lightness/chroma pinned.
120
- * `'neutral'` is the default gray (same as omitting it). */
216
+ * Tones tint a per-tone hue; a custom color keeps its hue with
217
+ * lightness/chroma pinned. `'neutral'` is the default gray (same as
218
+ * omitting it). */
121
219
  tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
220
+ /** Emphasis level. `secondary` (default) is the subtle alpha-tint fill;
221
+ * `primary` is a solid fill with white text; `tertiary` is a transparent
222
+ * outline. */
223
+ priority?: 'primary' | 'secondary' | 'tertiary';
122
224
  /** Size variant. `small` = 16px tall, `medium` (default) = 20px,
123
225
  * `large` = 24px. */
124
226
  size?: 'small' | 'medium' | 'large';
@@ -126,6 +228,56 @@ export interface ATagAttributes extends BaseAttributes {
126
228
  * Presence-based (`''` on, omit off). */
127
229
  nocaps?: boolean | '';
128
230
  }
231
+ /**
232
+ * Attributes for the `<a-expander>` collapsible disclosure.
233
+ *
234
+ * The element builds its own shadow DOM (no native `<details>`): a
235
+ * `<button>` summary carrying `aria-expanded` plus an animated content
236
+ * region. The title is projected via `slot="title"`; header actions
237
+ * (rendered next to the trigger, outside it) via `slot="actions"`; the
238
+ * body is the default slot. Low-level attributes; for the JSX wrapper
239
+ * use `Expander` from `@antadesign/anta`.
240
+ */
241
+ export interface AExpanderAttributes extends BaseAttributes {
242
+ /** Controlled open state (`'open'` / `'closed'`). Present → controlled: the
243
+ * attribute is the source of truth, clicks only dispatch the cancelable
244
+ * `statechange` event, and the consumer answers by updating it. Absent →
245
+ * uncontrolled (use `default-state`). See STATEFUL-COMPONENTS.md. */
246
+ state?: 'open' | 'closed';
247
+ /** Initial open state for the uncontrolled mode (`'open'` / `'closed'`);
248
+ * read once when the element connects. */
249
+ 'default-state'?: 'open' | 'closed';
250
+ /** Surface emphasis. `secondary` (default) is a subtle fill; `primary`
251
+ * is a stronger raised fill; `tertiary` is transparent. */
252
+ priority?: 'primary' | 'secondary' | 'tertiary';
253
+ /** Outdent the chevron into the left gutter so the title + body sit
254
+ * flush with surrounding content (the docs-header layout). Tertiary
255
+ * only — a no-op on the filled priorities, where the container edge
256
+ * has to bound the chevron. Presence-based. */
257
+ outdent?: boolean | '';
258
+ /** Disables the header: not clickable or focusable, hover affordance
259
+ * off, text dimmed. The open state freezes as-is. Presence-based. */
260
+ disabled?: boolean | '';
261
+ /** Semantic tone, or any literal CSS color for a one-off custom tone.
262
+ * Named tones re-point the text + filled surface palette; a custom
263
+ * color keeps its hue with lightness/chroma pinned. `'neutral'` is the
264
+ * default (same as omitting it). */
265
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
266
+ /** Heading type scale for the summary, `'1'`–`'6'` (mirrors `<a-title>`
267
+ * levels). Default (omitted) ≈ level 5. */
268
+ level?: '1' | '2' | '3' | '4' | '5' | '6';
269
+ /** Fires before the open state changes — the element dispatches a
270
+ * `cancelable` `statechange` `CustomEvent` whose `detail` is
271
+ * `{ next, prev }` in the `'open'|'closed'` vocabulary. Uncontrolled,
272
+ * `preventDefault()` vetoes the transition. The all-lowercase spelling is
273
+ * deliberate — it's the one form both renderers bind to the `statechange`
274
+ * event (React 19 keeps the case after `on`, so `onStateChange` would
275
+ * listen for "StateChange"; Preact lowercases). */
276
+ onstatechange?: (e: CustomEvent<{
277
+ next: 'open' | 'closed';
278
+ prev: 'open' | 'closed';
279
+ }>) => void;
280
+ }
129
281
  /**
130
282
  * Attributes for the `<a-icon>` custom element. `shape` is typed as
131
283
  * `IconShape` (`keyof IconShapes`); the `IconShapes` interface is
@@ -163,15 +315,213 @@ export interface ATooltipAttributes extends BaseAttributes {
163
315
  delay?: number | string;
164
316
  /** Preferred side; auto-flips when there's no room. Defaults to `'bottom'`. */
165
317
  placement?: 'top' | 'bottom';
166
- /** Pin under the anchor instead of following the cursor. Presence-based
167
- * (`''` on, omit off). */
168
- static?: boolean | '';
318
+ /** Follow the cursor instead of pinning under the anchor (pinned is the
319
+ * default). Presence-based (`''` on, omit off). */
320
+ follow?: boolean | '';
169
321
  /** Make the bubble hoverable/clickable (pointer events on, stays open while
170
- * hovered). Implies `static`. Presence-based (`''` on, omit off). */
322
+ * hovered). Always pinned. Presence-based (`''` on, omit off). */
171
323
  interactive?: boolean | '';
172
324
  /** HTML `id`. */
173
325
  id?: string;
174
326
  }
327
+ /**
328
+ * Attributes for the `<a-checkbox>` custom element. `<a-checkbox>` is a light-DOM
329
+ * interactive element: its visual state lives on `ElementInternals` (styled via
330
+ * the `:state(checked)` / `:state(indeterminate)` pseudo-class, not host
331
+ * attributes), driven by the `state` attribute (controlled) or `default-state`
332
+ * (uncontrolled seed). It sets no ARIA itself — `role` / `aria-*` are the
333
+ * consumer's job (the wrapper supplies them). The label is its children.
334
+ * Low-level attributes — for the typed JSX wrapper use `Checkbox` from
335
+ * `@antadesign/anta`.
336
+ */
337
+ export interface ACheckboxAttributes extends BaseAttributes {
338
+ /** Colour variant, or any literal CSS color for a one-off custom tone.
339
+ * Named tones track light/dark mode automatically via the theme-aware role
340
+ * tokens. `'neutral'` is the default (same as omitting it). */
341
+ tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
342
+ /** Size variant. `small` = 14px, `medium` (default) = 16px, `large` = 18px box. */
343
+ size?: 'small' | 'medium' | 'large';
344
+ /** Visual priority. `primary` (default) fills the checked box with the tone
345
+ * colour and draws a white checkmark; `secondary` keeps the box unfilled and
346
+ * draws the border + checkmark in the tone colour (an outlined look). */
347
+ priority?: 'primary' | 'secondary';
348
+ /** Controlled state — the element reflects changes to this attribute. Use this
349
+ * (driven from your store) for a controlled checkbox; use `default-state` for
350
+ * an uncontrolled one. */
351
+ state?: 'checked' | 'unchecked' | 'indeterminate';
352
+ /** Uncontrolled initial state — read once at connect / form-reset, then the
353
+ * element self-manages. */
354
+ 'default-state'?: 'checked' | 'unchecked' | 'indeterminate';
355
+ /** Disabled state. Presence-based (`''` on, omit off). */
356
+ disabled?: boolean | '';
357
+ /** Form field name — the key this checkbox submits under inside a `<form>`. */
358
+ name?: string;
359
+ /** Value submitted when checked. Defaults to `"on"`. */
360
+ value?: string;
361
+ /** Fires before the element applies any change. The element dispatches a
362
+ * cancelable `statechange` `CustomEvent` whose `detail` carries
363
+ * `{ next, prev }` (the same string enum as `state`); a synchronous
364
+ * `preventDefault()` vetoes the transition. The all-lowercase spelling is
365
+ * deliberate — it's the one form both renderers bind to a custom event
366
+ * (React 19 keeps the case of whatever follows `on`; Preact lowercases). */
367
+ onstatechange?: (e: CustomEvent<{
368
+ next: 'checked' | 'unchecked' | 'indeterminate';
369
+ prev: 'checked' | 'unchecked' | 'indeterminate';
370
+ }>) => void;
371
+ /** Native `change`, fired *after* a toggle applies (post-apply counterpart to
372
+ * `onstatechange`). Lowercase so both renderers bind the native event. */
373
+ onchange?: (e: Event) => void;
374
+ /** ARIA — set by the consumer / the `Checkbox` wrapper (the element never
375
+ * touches these itself). */
376
+ 'aria-checked'?: 'true' | 'false' | 'mixed';
377
+ 'aria-disabled'?: 'true' | 'false';
378
+ 'aria-label'?: string;
379
+ }
380
+ /**
381
+ * Attributes for the `<a-input>` custom element — a form-associated text
382
+ * field whose real `<input>` / `<textarea>` lives in shadow DOM. For the
383
+ * typed JSX wrapper use `Input` from `@antadesign/anta`.
384
+ *
385
+ * Slots (light-DOM children): `label`, `leading`, `trailing`, `hint`.
386
+ * The element exposes `::part(field | input | label | leading | trailing | hint)`
387
+ * for styling, and `:state(filled)` / `:state(invalid)` as CSS hooks.
388
+ */
389
+ export interface AInputAttributes extends BaseAttributes {
390
+ /** Controlled value (string). Reflected to the shadow control only when it
391
+ * differs, so the caret survives re-renders. */
392
+ value?: string;
393
+ /** Initial value for the uncontrolled case; read once on connect. */
394
+ defaultvalue?: string;
395
+ /** Render a `<textarea>` rather than `<input>`. Presence-based. */
396
+ multiline?: boolean | '';
397
+ /** Fixed visible row count for a `<textarea>` (implies multiline). */
398
+ rows?: number | string;
399
+ /** Cap autogrow height (rows) for a multiline field with no `rows`. */
400
+ maxrows?: number | string;
401
+ /** Validation/feedback tone — colors the border + message and (via the
402
+ * wrapper) the glyph. Only `critical` carries validity weight (`aria-invalid`
403
+ * + `:state(invalid)`); the others are advisory. Omit for the neutral field. */
404
+ status?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
405
+ /** Custom accent colour (any literal CSS colour) — tints the resting + hover
406
+ * border via an oklch derivation. `status` overrides it for validation. */
407
+ tone?: string;
408
+ /** Disabled state. Presence-based. */
409
+ disabled?: boolean | '';
410
+ /** Read-only state. Presence-based. */
411
+ readonly?: boolean | '';
412
+ /** Required — drives native validity. Presence-based. */
413
+ required?: boolean | '';
414
+ /** Dim the leading/trailing adornments at rest (0.6); they brighten to full
415
+ * when the field is hovered or focused. Presence-based. */
416
+ 'dim-actions'?: boolean | '';
417
+ /** Size variant. small=24px, medium (default)=28px, large=32px. */
418
+ size?: 'small' | 'medium' | 'large';
419
+ /** Single-line input type (ignored when multiline). `search` is intentionally
420
+ * unavailable — it triggers browser-injected clear/search affordances. */
421
+ type?: 'text' | 'email' | 'password' | 'tel' | 'url' | 'number';
422
+ /** Form field name — submitted via ElementInternals. */
423
+ name?: string;
424
+ /** Placeholder shown when empty. */
425
+ placeholder?: string;
426
+ autocomplete?: string;
427
+ inputmode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
428
+ maxlength?: number | string;
429
+ minlength?: number | string;
430
+ pattern?: string;
431
+ min?: number | string;
432
+ max?: number | string;
433
+ step?: number | string;
434
+ spellcheck?: 'true' | 'false' | boolean;
435
+ /** Fires on every keystroke (`input` is composed — it reaches the host). */
436
+ oninput?: (e: any) => void;
437
+ /** Fires on commit; the element re-dispatches the control's `change` on the
438
+ * host (native `change` isn't composed). */
439
+ onchange?: (e: any) => void;
440
+ /** Fires when the built-in clear button is clicked, before clearing
441
+ * (cancelable, bubbling `clearclick` event — preventDefault keeps the
442
+ * value). All-lowercase so it binds in React *and* Preact. */
443
+ onclearclick?: (e: any) => void;
444
+ /** Fires after the field has been cleared (bubbling `clearinput` event).
445
+ * All-lowercase so it binds in React *and* Preact. */
446
+ onclearinput?: (e: any) => void;
447
+ 'aria-invalid'?: 'true' | 'false' | boolean;
448
+ 'aria-label'?: string;
449
+ }
450
+ /**
451
+ * Attributes for the `<a-menu>` custom element. Placed immediately after the
452
+ * trigger it anchors to (root menu), or nested inside an `<a-menu-item>`
453
+ * (submenu). For the typed JSX wrapper use `Menu` from `@antadesign/anta`.
454
+ */
455
+ export interface AMenuAttributes extends BaseAttributes {
456
+ /** Preferred placement relative to the trigger; auto-flips / clamps.
457
+ * Defaults to `'bottom-start'`. */
458
+ placement?: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end' | 'bottom' | 'top';
459
+ /** Open on right-click of the trigger region, positioned at the pointer.
460
+ * Presence-based (`''` on, omit off). */
461
+ context?: boolean | '';
462
+ /** Open at the pointer coordinates instead of aligned to the trigger box.
463
+ * Presence-based (`''` on, omit off). */
464
+ coord?: boolean | '';
465
+ /** For a submenu (an `<a-menu>` nested inside an `<a-menu-item>` — detected
466
+ * from that structure, no flag needed): also open on hover. Presence-based
467
+ * (`''` on, omit off). */
468
+ hover?: boolean | '';
469
+ /** Gap in pixels between the trigger and the menu. Defaults to 4. */
470
+ offset?: number | string;
471
+ /** Controlled open state (`'open'` / `'closed'`). Omit for uncontrolled;
472
+ * present → visibility follows this value, and the element never writes it
473
+ * (the consumer owns it). Listen to `statechange` to keep it in sync. See
474
+ * STATEFUL-COMPONENTS.md. */
475
+ state?: 'open' | 'closed';
476
+ /** State-change event — `cancelable`, fired before applying, with
477
+ * `detail: { next, prev }` in the `'open'|'closed'` vocabulary (plus optional
478
+ * `coord` / `originEvent`). All-lowercase so React/Preact bind it to the
479
+ * element's `statechange` CustomEvent. The `Menu` wrapper exposes this as the
480
+ * `onStateChange` prop. */
481
+ onstatechange?: (e: CustomEvent<{
482
+ next: 'open' | 'closed';
483
+ prev: 'open' | 'closed';
484
+ }>) => void;
485
+ /** ARIA role — the JSX wrapper sets this to `'menu'`. */
486
+ role?: string;
487
+ 'aria-orientation'?: 'vertical' | 'horizontal';
488
+ }
489
+ /**
490
+ * Attributes for the `<a-menu-item>` custom element. For the typed JSX
491
+ * wrapper use `MenuItem` from `@antadesign/anta`.
492
+ */
493
+ export interface AMenuItemAttributes extends BaseAttributes {
494
+ /** Disabled state. Presence-based (`''` on, omit off). */
495
+ disabled?: boolean | '';
496
+ /** Semantic tone. Colors the label, icon, and hover tint. `'neutral'`
497
+ * (the default) is the same as omitting it. */
498
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
499
+ /** Keep the menu open after this item is chosen (toggles / multi-select),
500
+ * instead of the default close-on-select. Presence-based (`''` on, omit
501
+ * off). The universal form is `data-menu-open` (works on any element). */
502
+ 'data-menu-open'?: boolean | '';
503
+ /** Marks this item as a submenu parent (renders a chevron, opens a nested
504
+ * `<a-menu>`). Presence-based (`''` on, omit off). */
505
+ submenu?: boolean | '';
506
+ /** ARIA role — `'menuitem'`. */
507
+ role?: string;
508
+ 'aria-haspopup'?: 'menu' | 'true' | 'false' | boolean;
509
+ /** Submenu-parent expanded state. Render `'false'` as the resting baseline;
510
+ * the nested `<a-menu>` element reflects the live open state. */
511
+ 'aria-expanded'?: 'true' | 'false' | boolean;
512
+ 'aria-disabled'?: 'true' | 'false' | boolean;
513
+ }
514
+ /**
515
+ * Attributes for the `<a-menu-group>` styled element. For the typed JSX
516
+ * wrapper use `MenuGroup` from `@antadesign/anta`.
517
+ */
518
+ export interface AMenuGroupAttributes extends BaseAttributes {
519
+ /** Keep the menu open after any item in this group is chosen. Presence-based
520
+ * (`''` on, omit off). The universal form is `data-menu-open`. */
521
+ 'data-menu-open'?: boolean | '';
522
+ role?: string;
523
+ 'aria-label'?: string;
524
+ }
175
525
  /**
176
526
  * Attributes for the `<a-button>` custom element. For the typed JSX
177
527
  * wrapper use `Button` from `@antadesign/anta`.
@@ -180,7 +530,7 @@ export interface AButtonAttributes extends BaseAttributes {
180
530
  /** Visual emphasis. */
181
531
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary';
182
532
  /** Semantic tone, or any literal CSS color for a one-off custom tone. */
183
- tone?: 'neutral' | 'brand' | 'critical' | 'info' | 'success' | 'warning' | (string & {});
533
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
184
534
  /** Underline style. Only renders on `priority="tertiary" | "quaternary"`. */
185
535
  underline?: 'solid' | 'dashed' | 'dotted';
186
536
  /** Size variant. small=22px, medium=26px, large=30px. */
@@ -203,3 +553,105 @@ export interface AButtonAttributes extends BaseAttributes {
203
553
  'aria-disabled'?: 'true' | 'false' | boolean;
204
554
  'aria-busy'?: 'true' | 'false' | boolean;
205
555
  }
556
+ /**
557
+ * Attributes for the `<a-radio>` custom element — one option in a radio set.
558
+ * Presentational: the parent `<a-radio-group>` owns selection, keyboard, and form
559
+ * value. The selected look comes from the element's `:state(selected)` (set by the
560
+ * group via the `selected` property), not a host attribute. There is no `Radio`
561
+ * JSX wrapper — `RadioGroup` renders these from its `options`, and hand-authors
562
+ * write `<a-radio>` directly inside an `<a-radio-group>`.
563
+ */
564
+ export interface ARadioAttributes extends BaseAttributes {
565
+ /** This option's identity / submitted value. */
566
+ value?: string;
567
+ /** Colour variant, or any literal CSS color for a one-off custom tone.
568
+ * Named tones track light/dark mode automatically via the theme-aware role
569
+ * tokens. `'neutral'` is the default (same as omitting it). */
570
+ tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
571
+ /** Size variant. small=14px, medium=16px, large=18px control. */
572
+ size?: 'small' | 'medium' | 'large';
573
+ /** Visual priority. `primary` (default) fills the selected ring with the tone
574
+ * colour and draws a white dot; `secondary` keeps the ring unfilled and draws
575
+ * the border + dot in the tone colour (an outlined look). */
576
+ priority?: 'primary' | 'secondary';
577
+ /** Disabled state. Presence-based (`''` on, omit off). */
578
+ disabled?: boolean | '';
579
+ /** Selected state — connect-time seed for the standalone render path (no
580
+ * group). In a group, the group drives `:state(selected)` directly and this
581
+ * attribute is ignored. Presence-based. */
582
+ selected?: boolean | '';
583
+ /** ARIA — `role="radio"` is set by the consumer (`RadioGroup` on each option,
584
+ * or a hand-author). `aria-checked` is published by the element through
585
+ * `ElementInternals` (off the DOM), driven by the `selected` property the group
586
+ * sets — not a DOM attribute. Roving `tabindex` (inherited from `BaseAttributes`)
587
+ * is likewise set by `RadioGroup`, not the element. */
588
+ role?: 'radio';
589
+ 'aria-disabled'?: 'true' | 'false';
590
+ }
591
+ /**
592
+ * Attributes for the `<a-radio-group>` custom element — the single-select
593
+ * coordinator. It is the form-associated element (submits one `name=value`).
594
+ * No shadow DOM: an optional group header (`<a-radio-group-label>` + an optional
595
+ * `<a-radio-group-hint>` description) sits above an `<a-radio-list>` wrapping the
596
+ * `<a-radio>` options — each option wraps its text in `<a-radio-label>` and an
597
+ * optional `<a-radio-hint>`. All plain light-DOM children, laid out by
598
+ * `a-radio-group.css`, so the arrangement is restylable with ordinary CSS
599
+ * (`a-radio-group a-radio-list { … }`). The group
600
+ * coordinates **off-DOM only** — it never writes the DOM: selection via each
601
+ * radio's `selected` property, focus via `internals.ariaActiveDescendantElement`,
602
+ * the form value via `setFormValue`. Roving `tabindex` (the JSX path) is rendered
603
+ * by the `RadioGroup` wrapper, not the element. The `RadioGroup` wrapper composes
604
+ * the label/list/hint from `label` / `hint`; hand-authors write them directly.
605
+ * For the typed JSX wrapper use `RadioGroup` from `@antadesign/anta`.
606
+ */
607
+ export interface ARadioGroupAttributes extends BaseAttributes {
608
+ /** Controlled selected value (the chosen radio's `value`). Present → controlled:
609
+ * the element reflects changes to this attribute and a pick only dispatches
610
+ * `statechange`. Absent → uncontrolled (seed with `default-state`). */
611
+ state?: string;
612
+ /** Uncontrolled initial selected value — read once on connect / form-reset. */
613
+ 'default-state'?: string;
614
+ /** Form field name — the group submits `name=value`. */
615
+ name?: string;
616
+ /** Tone cascaded to children that don't set their own, or any literal CSS
617
+ * color for a one-off custom tone. Inherits through CSS so every child
618
+ * `<a-radio>` picks up the same fill curve. */
619
+ tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
620
+ /** Size cascaded to children that don't set their own. */
621
+ size?: 'small' | 'medium' | 'large';
622
+ /** Visual priority cascaded to children that don't set their own. `primary`
623
+ * (default) fills the selected ring with the tone colour; `secondary` keeps it
624
+ * unfilled and draws the border + dot in the tone colour (an outlined look). */
625
+ priority?: 'primary' | 'secondary';
626
+ /** Validation/feedback tone for the group hint — same set as `<a-input>`'s
627
+ * `status`. Recolours `<a-radio-group-hint>`; omit for the neutral default. */
628
+ status?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
629
+ /** Disable the whole group. Presence-based. */
630
+ disabled?: boolean | '';
631
+ /** Layout + arrow-key axis. `'vertical'` is the default. */
632
+ orientation?: 'vertical' | 'horizontal';
633
+ /** Fires whenever the selection changes. `detail` carries `{ next, prev, reason }`:
634
+ * `next`/`prev` are the selected values (`null` = nothing selected), and `reason`
635
+ * is `'user'` (a pick — the event is **cancelable**; a synchronous
636
+ * `preventDefault()` vetoes it in uncontrolled mode), `'reset'` (a `<form>` reset),
637
+ * or `'restore'` (bfcache / autofill restore) — the latter two are not cancelable.
638
+ * All-lowercase to bind across both renderers (like `<a-checkbox>`). */
639
+ onstatechange?: (e: CustomEvent<{
640
+ next: string | null;
641
+ prev: string | null;
642
+ reason: 'user' | 'reset' | 'restore';
643
+ }>) => void;
644
+ /** Native `change`, fired *after* a selection applies (post-apply counterpart to
645
+ * `onstatechange`). Lowercase so both renderers bind the native event. */
646
+ onchange?: (e: Event) => void;
647
+ /** Group focus enter / leave — wired from the bubbling `focusin` / `focusout`
648
+ * (focus lands on an option, not the group). The `RadioGroup` wrapper maps its
649
+ * `onFocus` / `onBlur` props here. */
650
+ onfocusin?: (e: FocusEvent) => void;
651
+ onfocusout?: (e: FocusEvent) => void;
652
+ /** ARIA — set by the `RadioGroup` wrapper (the element never touches these). */
653
+ role?: 'radiogroup';
654
+ 'aria-disabled'?: 'true' | 'false';
655
+ 'aria-label'?: string;
656
+ 'aria-labelledby'?: string;
657
+ }
package/dist/index.d.ts CHANGED
@@ -31,6 +31,22 @@ export type { ButtonProps, BaseButtonProps, ContentMode, SubmitMode, PriorityMod
31
31
  export { ICON_SHAPES, ICON_SYNONYMS } from './elements/a-icon.shapes';
32
32
  export { Tooltip } from './components/Tooltip';
33
33
  export type { TooltipProps } from './components/Tooltip';
34
+ export { Checkbox } from './components/Checkbox';
35
+ export type { CheckboxProps, CheckboxValue } from './components/Checkbox';
36
+ export { Menu } from './components/Menu';
37
+ export type { MenuProps } from './components/Menu';
38
+ export { MenuItem } from './components/MenuItem';
39
+ export type { MenuItemProps } from './components/MenuItem';
40
+ export { MenuSeparator } from './components/MenuSeparator';
41
+ export type { MenuSeparatorProps } from './components/MenuSeparator';
42
+ export { MenuGroup } from './components/MenuGroup';
43
+ export type { MenuGroupProps } from './components/MenuGroup';
44
+ export { Expander } from './components/Expander';
45
+ export type { ExpanderProps } from './components/Expander';
46
+ export { Input } from './components/Input';
47
+ export type { InputProps, InputChangeAttrs } from './components/Input';
48
+ export { RadioGroup } from './components/RadioGroup';
49
+ export type { RadioGroupProps, RadioOption } from './components/RadioGroup';
34
50
  export type { BaseProps, BaseAttributes } from './general_types';
35
51
  export { configure } from './jsx-runtime';
36
52
  export type { AntaIntrinsicElements } from './jsx-runtime';
package/dist/index.js CHANGED
@@ -6,13 +6,29 @@ import { Icon } from "./components/Icon";
6
6
  import { Button } from "./components/Button";
7
7
  import { ICON_SHAPES, ICON_SYNONYMS } from "./elements/a-icon.shapes";
8
8
  import { Tooltip } from "./components/Tooltip";
9
+ import { Checkbox } from "./components/Checkbox";
10
+ import { Menu } from "./components/Menu";
11
+ import { MenuItem } from "./components/MenuItem";
12
+ import { MenuSeparator } from "./components/MenuSeparator";
13
+ import { MenuGroup } from "./components/MenuGroup";
14
+ import { Expander } from "./components/Expander";
15
+ import { Input } from "./components/Input";
16
+ import { RadioGroup } from "./components/RadioGroup";
9
17
  import { configure } from "./jsx-runtime";
10
18
  export {
11
19
  Button,
20
+ Checkbox,
21
+ Expander,
12
22
  ICON_SHAPES,
13
23
  ICON_SYNONYMS,
14
24
  Icon,
25
+ Input,
26
+ Menu,
27
+ MenuGroup,
28
+ MenuItem,
29
+ MenuSeparator,
15
30
  Progress,
31
+ RadioGroup,
16
32
  Tag,
17
33
  Text,
18
34
  Title,