@antadesign/anta 0.3.2 → 0.3.4

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 (96) hide show
  1. package/dist/anta_helpers.d.ts +97 -0
  2. package/dist/anta_helpers.js +70 -0
  3. package/dist/calendar-core.d.ts +126 -0
  4. package/dist/calendar-core.js +289 -0
  5. package/dist/components/Button.d.ts +9 -1
  6. package/dist/components/Button.js +5 -2
  7. package/dist/components/Calendar.d.ts +85 -0
  8. package/dist/components/Calendar.js +226 -0
  9. package/dist/components/Checkbox.d.ts +16 -11
  10. package/dist/components/Checkbox.js +13 -7
  11. package/dist/components/Expander.d.ts +7 -1
  12. package/dist/components/Expander.js +4 -2
  13. package/dist/components/Input.d.ts +13 -5
  14. package/dist/components/Input.js +14 -6
  15. package/dist/components/InputDate.d.ts +89 -0
  16. package/dist/components/InputDate.js +273 -0
  17. package/dist/components/InputDate.module.css +1 -0
  18. package/dist/components/Menu.d.ts +14 -1
  19. package/dist/components/Menu.js +6 -2
  20. package/dist/components/MenuItem.d.ts +48 -7
  21. package/dist/components/MenuItem.js +72 -14
  22. package/dist/components/MenuSeparator.d.ts +13 -2
  23. package/dist/components/MenuSeparator.js +12 -2
  24. package/dist/components/Progress.d.ts +4 -1
  25. package/dist/components/Progress.js +4 -3
  26. package/dist/components/RadioGroup.d.ts +12 -10
  27. package/dist/components/RadioGroup.js +5 -5
  28. package/dist/components/Select.d.ts +319 -0
  29. package/dist/components/Select.js +341 -0
  30. package/dist/components/Select.module.css +1 -0
  31. package/dist/components/Tab.d.ts +3 -0
  32. package/dist/components/Tab.js +2 -1
  33. package/dist/components/TabPanel.d.ts +21 -13
  34. package/dist/components/TabPanel.js +13 -1
  35. package/dist/components/Tabs.d.ts +75 -40
  36. package/dist/components/Tabs.js +20 -88
  37. package/dist/components/Tag.d.ts +10 -9
  38. package/dist/components/Tag.js +2 -2
  39. package/dist/components/Text.d.ts +6 -5
  40. package/dist/components/Title.d.ts +4 -2
  41. package/dist/components/Tooltip.d.ts +4 -1
  42. package/dist/components/Tooltip.js +5 -0
  43. package/dist/elements/a-button.css +1 -1
  44. package/dist/elements/a-calendar.css +1 -0
  45. package/dist/elements/a-calendar.d.ts +76 -0
  46. package/dist/elements/a-calendar.js +190 -0
  47. package/dist/elements/a-checkbox.css +1 -1
  48. package/dist/elements/a-checkbox.d.ts +1 -2
  49. package/dist/elements/a-checkbox.js +5 -5
  50. package/dist/elements/a-expander.css +1 -1
  51. package/dist/elements/a-expander.d.ts +16 -5
  52. package/dist/elements/a-expander.js +59 -8
  53. package/dist/elements/a-icon.shapes.css +1 -1
  54. package/dist/elements/a-icon.shapes.d.ts +6 -1
  55. package/dist/elements/a-icon.shapes.js +9 -0
  56. package/dist/elements/a-input.css +1 -1
  57. package/dist/elements/a-input.d.ts +6 -0
  58. package/dist/elements/a-input.js +28 -8
  59. package/dist/elements/a-menu-group.css +1 -1
  60. package/dist/elements/a-menu-item.css +1 -1
  61. package/dist/elements/a-menu-item.d.ts +22 -10
  62. package/dist/elements/a-menu-item.js +17 -0
  63. package/dist/elements/a-menu-separator.css +1 -1
  64. package/dist/elements/a-menu.css +1 -1
  65. package/dist/elements/a-menu.d.ts +61 -20
  66. package/dist/elements/a-menu.js +337 -58
  67. package/dist/elements/a-progress.css +1 -1
  68. package/dist/elements/a-radio-group.d.ts +1 -3
  69. package/dist/elements/a-radio-group.js +13 -13
  70. package/dist/elements/a-radio.css +1 -1
  71. package/dist/elements/a-radio.d.ts +3 -11
  72. package/dist/elements/a-radio.js +3 -34
  73. package/dist/elements/a-tab.css +1 -1
  74. package/dist/elements/a-tab.d.ts +3 -11
  75. package/dist/elements/a-tab.js +3 -34
  76. package/dist/elements/a-tabpanel.css +1 -1
  77. package/dist/elements/a-tabpanel.d.ts +17 -0
  78. package/dist/elements/a-tabpanel.js +66 -0
  79. package/dist/elements/a-tabs.css +1 -1
  80. package/dist/elements/a-tabs.d.ts +1 -4
  81. package/dist/elements/a-tabs.js +14 -14
  82. package/dist/elements/a-tag.css +1 -1
  83. package/dist/elements/a-text.d.ts +14 -13
  84. package/dist/elements/a-text.js +53 -23
  85. package/dist/elements/a-tooltip.css +1 -1
  86. package/dist/elements/a-tooltip.d.ts +1 -11
  87. package/dist/elements/a-tooltip.js +20 -19
  88. package/dist/elements/index.d.ts +2 -1
  89. package/dist/elements/index.js +6 -1
  90. package/dist/general_types.d.ts +158 -42
  91. package/dist/index.d.ts +10 -4
  92. package/dist/index.js +38 -3
  93. package/dist/jsx-runtime.d.ts +16 -7
  94. package/dist/jsx-runtime.js +6 -0
  95. package/dist/reset.css +1 -1
  96. package/package.json +4 -2
@@ -13,6 +13,9 @@ export interface BaseProps {
13
13
  title?: string;
14
14
  /** Tab order. Set to `-1` to skip the element when tabbing. */
15
15
  tabIndex?: number;
16
+ /** React/Preact reconciliation key when rendered inside a list. Consumed by the
17
+ * JSX runtime (not forwarded as a DOM attribute). */
18
+ key?: string | number | null;
16
19
  /** Any `data-*` attribute is forwarded to the rendered element. */
17
20
  [key: `data-${string}`]: unknown;
18
21
  /** Any `aria-*` attribute is forwarded to the rendered element. */
@@ -145,6 +148,9 @@ export interface AProgressAttributes extends BaseAttributes {
145
148
  /** Colour variant, or any literal CSS colour for a custom tone (derived in
146
149
  * oklch). Named tones track light/dark automatically. */
147
150
  tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
151
+ /** Fully-round track (`border-radius: 999px`), or a custom radius via a length
152
+ * value (`round="6px"`). Presence-based for the boolean form. */
153
+ round?: boolean | number | string;
148
154
  /** ARIA role — the JSX wrapper sets this to `'progressbar'`. */
149
155
  role?: string;
150
156
  /** ARIA value-now (current). */
@@ -165,8 +171,9 @@ export interface AProgressAttributes extends BaseAttributes {
165
171
  export interface ATextAttributes extends BaseAttributes {
166
172
  /** Visual priority. Maps to text-1..text-5. */
167
173
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
168
- /** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
169
- tone?: 'brand' | 'info' | 'success' | 'warning' | 'critical';
174
+ /** Color tint. `neutral` (default) is the untinted `--text-{N}` scale;
175
+ * the others apply the matching `--text-{N}-{tone}` palette. */
176
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
170
177
  /** Type scale. `small` = 13/16, `medium` (default) = 15/20, `large` = 17/24. */
171
178
  size?: 'small' | 'medium' | 'large';
172
179
  /** Render as inline-block instead of the default block. */
@@ -198,8 +205,9 @@ export interface ATitleAttributes extends BaseAttributes {
198
205
  level?: string;
199
206
  /** Visual priority. Maps to text-1..text-5. */
200
207
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
201
- /** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
202
- tone?: 'brand' | 'info' | 'success' | 'warning' | 'critical';
208
+ /** Color tint. `neutral` (default) is the untinted `--text-{N}` scale;
209
+ * the others apply the matching `--text-{N}-{tone}` palette. */
210
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
203
211
  /** ARIA role — the JSX wrapper sets this to `'heading'`. */
204
212
  role?: string;
205
213
  /** ARIA heading level — the JSX wrapper sets this to match `level`. */
@@ -224,9 +232,9 @@ export interface ATagAttributes extends BaseAttributes {
224
232
  /** Size variant. `small` = 16px tall, `medium` (default) = 20px,
225
233
  * `large` = 24px. */
226
234
  size?: 'small' | 'medium' | 'large';
227
- /** Render in normal case instead of the default uppercase.
235
+ /** Render in all-caps instead of the default normal (mixed) case.
228
236
  * Presence-based (`''` on, omit off). */
229
- nocaps?: boolean | '';
237
+ allcaps?: boolean | '';
230
238
  }
231
239
  /**
232
240
  * Attributes for the `<a-expander>` collapsible disclosure.
@@ -258,6 +266,11 @@ export interface AExpanderAttributes extends BaseAttributes {
258
266
  /** Disables the header: not clickable or focusable, hover affordance
259
267
  * off, text dimmed. The open state freezes as-is. Presence-based. */
260
268
  disabled?: boolean | '';
269
+ /** Round corners sized to half the folded (header) height — a pill when folded,
270
+ * the same radius when expanded (the element measures the header and publishes
271
+ * `--_expander-round-radius`). A length value (`round="12px"`) is a fixed radius
272
+ * that overrides the measurement. Presence-based for the boolean form. */
273
+ round?: boolean | number | string;
261
274
  /** Semantic tone, or any literal CSS color for a one-off custom tone.
262
275
  * Named tones re-point the text + filled surface palette; a custom
263
276
  * color keeps its hue with lightness/chroma pinned. `'neutral'` is the
@@ -326,6 +339,9 @@ export interface ATooltipAttributes extends BaseAttributes {
326
339
  * nearest Anta ellipsizing label part (`a-tab-label` / `a-button-label`) in the
327
340
  * anchor, then the anchor itself. Presence-based (`''` on, omit off). */
328
341
  'truncated-only'?: boolean | '';
342
+ /** Round the bubble (20px radius), or a custom radius via a length value
343
+ * (`round="12px"`). Presence-based for the boolean form. */
344
+ round?: boolean | number | string;
329
345
  /** CSS selector (resolved within the anchor) for the element whose overflow a
330
346
  * `truncated-only` tooltip measures. */
331
347
  'truncated-selector'?: string;
@@ -343,15 +359,15 @@ export interface ATooltipAttributes extends BaseAttributes {
343
359
  * `@antadesign/anta`.
344
360
  */
345
361
  export interface ACheckboxAttributes extends BaseAttributes {
346
- /** Mark colour (checked fill + unselected box border), or any literal CSS color
347
- * for a one-off custom tone. Named tones track light/dark mode automatically via
348
- * the theme-aware role tokens. `'neutral'` is the default (same as omitting it).
349
- * The label + hint stay neutral use `tone-text` for those. */
362
+ /** Mark colour in every state — checked fill *and* unselected box border or any
363
+ * literal CSS color for a one-off custom tone. Named tones track light/dark mode
364
+ * automatically. `'neutral'` is the default (same as omitting it). The label + hint
365
+ * stay neutral recolour them in plain CSS via the `--text-N-{tone}` tokens. */
350
366
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
351
- /** Text colour (label + hint), independent of `tone`. A named tone or any literal
352
- * CSS color; named tones track light/dark via the `--text-*` role tokens. Omit
353
- * (or `'neutral'`) to leave the text neutral. */
354
- 'tone-text'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
367
+ /** Like `tone`, but coloured onto the checked mark only the empty box stays
368
+ * neutral grey. Same value set as `tone`; if both are set, `tone` governs the
369
+ * off-state border and `tone-selected` the checked fill. */
370
+ 'tone-selected'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
355
371
  /** Size variant. `small` = 14px, `medium` (default) = 16px, `large` = 18px box. */
356
372
  size?: 'small' | 'medium' | 'large';
357
373
  /** Controlled state — the element reflects changes to this attribute. Use this
@@ -363,6 +379,9 @@ export interface ACheckboxAttributes extends BaseAttributes {
363
379
  'default-state'?: 'checked' | 'unchecked' | 'indeterminate';
364
380
  /** Disabled state. Presence-based (`''` on, omit off). */
365
381
  disabled?: boolean | '';
382
+ /** Round the mark to a circle (`::before` `border-radius: 999px`), or a rounded
383
+ * square via a length value (`round="5px"`). Presence-based for the boolean form. */
384
+ round?: boolean | number | string;
366
385
  /** Form field name — the key this checkbox submits under inside a `<form>`. */
367
386
  name?: string;
368
387
  /** Value submitted when checked. Defaults to `"on"`. */
@@ -423,6 +442,9 @@ export interface AInputAttributes extends BaseAttributes {
423
442
  /** Dim the leading/trailing adornments at rest (0.6); they brighten to full
424
443
  * when the field is hovered or focused. Presence-based. */
425
444
  'dim-actions'?: boolean | '';
445
+ /** Fully-round field (`border-radius: 999px`), or a custom radius via a length
446
+ * value (`round="10px"`). Presence-based for the boolean form. */
447
+ round?: boolean | number | string;
426
448
  /** Size variant. small=24px, medium (default)=28px, large=32px. */
427
449
  size?: 'small' | 'medium' | 'large';
428
450
  /** Single-line input type (ignored when multiline). `search` is intentionally
@@ -456,6 +478,60 @@ export interface AInputAttributes extends BaseAttributes {
456
478
  'aria-invalid'?: 'true' | 'false' | boolean;
457
479
  'aria-label'?: string;
458
480
  }
481
+ /**
482
+ * Attributes for the `<a-calendar>` custom element — a **light-DOM,
483
+ * form-associated** month grid, and the **interaction authority** for it. The
484
+ * element is the grid (a flat 7-column CSS grid whose children are the weekday
485
+ * headers + day cells), owns the submitted form value, and **dispatches the
486
+ * selection (`statechange` / `change`) and navigation (`navigate`) events** plus
487
+ * manages keyboard focus — so it works for a vanilla consumer, not only via the
488
+ * wrapper. It does **not** build or mutate its own contents: whoever renders into
489
+ * it (the `Calendar` JSX wrapper, or a vanilla consumer using the exported
490
+ * `buildMonth` engine) fills it with day cells and *re-renders on its events* —
491
+ * the `<a-radio-group>` model. Controlled by the presence of `value` (a pick only
492
+ * *requests* a change); uncontrolled with `defaultvalue` (a pick self-applies).
493
+ * For the typed, batteries-included wrapper use `Calendar` from `@antadesign/anta`.
494
+ *
495
+ * `:state(filled)` is the styling hook for "has a selection".
496
+ */
497
+ export interface ACalendarAttributes extends BaseAttributes {
498
+ /** Controlled selected date — ISO `YYYY-MM-DD`. Present → controlled (a pick
499
+ * only requests a change). Mirrored to the owning form via `ElementInternals`. */
500
+ value?: string;
501
+ /** Uncontrolled initial date / reset baseline — ISO `YYYY-MM-DD`. */
502
+ defaultvalue?: string;
503
+ /** Form field name — the selected ISO date submits under this key. */
504
+ name?: string;
505
+ /** Disable the whole calendar. Presence-based (`''` on, omit off). */
506
+ disabled?: boolean | '';
507
+ /** Focus signal — `"<iso>#<nonce>"`. When it changes, the element focuses the
508
+ * day cell whose `data-date` matches `<iso>` (set by the renderer after a
509
+ * month-changing keyboard move). */
510
+ 'data-focus'?: string;
511
+ /** Cancelable, bubbling `statechange` fired BEFORE a pick applies. `detail` is
512
+ * `{ next, prev, reason }` — ISO strings (or `null`); `reason` ∈
513
+ * `'user' | 'reset' | 'restore'`. `preventDefault()` vetoes a `'user'` pick in
514
+ * uncontrolled mode. */
515
+ onstatechange?: (e: CustomEvent<{
516
+ next: string | null;
517
+ prev: string | null;
518
+ reason: 'user' | 'reset' | 'restore';
519
+ }>) => void;
520
+ /** Native `change`, fired AFTER a selection applies (uncontrolled) and on
521
+ * reset/restore. */
522
+ onchange?: (e: Event) => void;
523
+ /** Keyboard navigation request — the element handles arrow / Home / End /
524
+ * PageUp / PageDown, focuses the target cell when it's rendered, and emits this
525
+ * bubbling `navigate` `CustomEvent` (`detail: { date }`, ISO) so the renderer can
526
+ * move the roving tab stop and flip the displayed month when needed. */
527
+ onnavigate?: (e: CustomEvent<{
528
+ date: string;
529
+ }>) => void;
530
+ /** ARIA — `role="group"` and the accessible name are set by the renderer (the
531
+ * `Calendar` wrapper wires `aria-labelledby` to the month heading). */
532
+ 'aria-label'?: string;
533
+ 'aria-labelledby'?: string;
534
+ }
459
535
  /**
460
536
  * Attributes for the `<a-menu>` custom element. Placed immediately after the
461
537
  * trigger it anchors to (root menu), or nested inside an `<a-menu-item>`
@@ -476,6 +552,10 @@ export interface AMenuAttributes extends BaseAttributes {
476
552
  * default; this opts out, making the submenu click-only. Presence-based
477
553
  * (`''` on, omit off). */
478
554
  nohover?: boolean | '';
555
+ /** Round: container softens to a 20px radius and its items go fully round. A
556
+ * length value (`round="12px"`) tunes the container radius only (items stay
557
+ * pills). Presence-based for the boolean form. */
558
+ round?: boolean | number | string;
479
559
  /** Gap in pixels between the trigger and the menu. Defaults to 4. */
480
560
  offset?: number | string;
481
561
  /** Controlled open state (`'open'` / `'closed'`). Omit for uncontrolled;
@@ -492,6 +572,15 @@ export interface AMenuAttributes extends BaseAttributes {
492
572
  next: 'open' | 'closed';
493
573
  prev: 'open' | 'closed';
494
574
  }>) => void;
575
+ /** Combobox-mode cursor report — fired when the active option changes (arrow
576
+ * keys, or the list re-filtering), with `detail.id` the active option's `id`
577
+ * (`null` when none). The element owns the keyboard cursor but must NOT write
578
+ * `aria-activedescendant` on the (light-DOM) filter field itself; the reactive
579
+ * layer that owns the field (e.g. `Select`) listens here and reflects it.
580
+ * All-lowercase so React/Preact bind it to the CustomEvent. */
581
+ onactivedescendant?: (e: CustomEvent<{
582
+ id: string | null;
583
+ }>) => void;
495
584
  /** ARIA role — the JSX wrapper sets this to `'menu'`. */
496
585
  role?: string;
497
586
  'aria-orientation'?: 'vertical' | 'horizontal';
@@ -503,9 +592,15 @@ export interface AMenuAttributes extends BaseAttributes {
503
592
  export interface AMenuItemAttributes extends BaseAttributes {
504
593
  /** Disabled state. Presence-based (`''` on, omit off). */
505
594
  disabled?: boolean | '';
506
- /** Semantic tone. Colors the label, icon, and hover tint. `'neutral'`
507
- * (the default) is the same as omitting it. */
508
- tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
595
+ /** Marks the item as selected a persistent background tint (the same
596
+ * resting look a pressed row shows), for building single- / multi-select
597
+ * menus. Presence-based (`''` on, omit off). */
598
+ selected?: boolean | '';
599
+ /** Semantic tone. Colors the label, icon, and hover/selected tint. A named tone,
600
+ * or any literal CSS color for a one-off custom tone (resolved through
601
+ * `--menu-item-tone-source`, hue/chroma kept, lightness pinned to the brand
602
+ * text). `'neutral'` (the default) is the same as omitting it. */
603
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
509
604
  /** Keep the menu open after this item is chosen (toggles / multi-select),
510
605
  * instead of the default close-on-select. Presence-based (`''` on, omit
511
606
  * off). The universal form is `data-menu-open` (works on any element). */
@@ -516,10 +611,20 @@ export interface AMenuItemAttributes extends BaseAttributes {
516
611
  /** ARIA role — `'menuitem'`. */
517
612
  role?: string;
518
613
  'aria-haspopup'?: 'menu' | 'true' | 'false' | boolean;
519
- /** Submenu-parent expanded state. Render `'false'` as the resting baseline;
520
- * the nested `<a-menu>` element reflects the live open state. */
614
+ /** Available for hand-authored markup, but the `MenuItem` wrapper does NOT set
615
+ * it: keeping it in sync would need a light-DOM mutation (desyncs the
616
+ * worker-thread reactive model) or reactive state for one attribute, and a
617
+ * static value would lie once the submenu opens. `aria-haspopup` announces the
618
+ * submenu; the open branch's visual rides the nested `<a-menu>`'s `:state(open)`. */
521
619
  'aria-expanded'?: 'true' | 'false' | boolean;
522
620
  'aria-disabled'?: 'true' | 'false' | boolean;
621
+ /** Fired when this row is genuinely activated (click / Enter / Space). The
622
+ * parent `<a-menu>` owns click delegation and dispatches this — already
623
+ * filtered so it never fires on a submenu parent or from a bubbled child
624
+ * click — so the `MenuItem` wrapper's `onSelect` needs no DOM traversal. It's
625
+ * a `MouseEvent`, carrying the modifier keys (e.g. `altKey`). All-lowercase so
626
+ * React/Preact bind it to the CustomEvent. */
627
+ onmenuselect?: (e: MouseEvent) => void;
523
628
  }
524
629
  /**
525
630
  * Attributes for the `<a-menu-group>` styled element. For the typed JSX
@@ -554,6 +659,9 @@ export interface AButtonAttributes extends BaseAttributes {
554
659
  disabled?: boolean | '';
555
660
  /** Toggled-on / pressed state. Presence-based (`''` on, omit off). */
556
661
  selected?: boolean | '';
662
+ /** Fully-round (pill / circle) — `border-radius: 999px` — or a custom radius via
663
+ * a length value (`round="20px"`). Presence-based for the boolean form. */
664
+ round?: boolean | number | string;
557
665
  /** Submit/reset semantics. */
558
666
  type?: 'button' | 'submit' | 'reset';
559
667
  /** Associate with a form by id when not nested inside it. */
@@ -574,15 +682,15 @@ export interface AButtonAttributes extends BaseAttributes {
574
682
  export interface ARadioAttributes extends BaseAttributes {
575
683
  /** This option's identity / submitted value. */
576
684
  value?: string;
577
- /** Mark colour (selected ring fill + dot, unselected ring border), or any literal
578
- * CSS color for a one-off custom tone. Named tones track light/dark mode via the
579
- * theme-aware role tokens. `'neutral'` is the default. The label + hint stay
580
- * neutral use `tone-text` for those. */
685
+ /** Mark colour in every state — selected ring fill + dot *and* unselected ring
686
+ * border — or any literal CSS color for a one-off custom tone. Named tones track
687
+ * light/dark mode. `'neutral'` is the default. The label + hint stay neutral —
688
+ * recolour them in plain CSS via the `--text-N-{tone}` tokens. */
581
689
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
582
- /** Text colour (label + hint), independent of `tone`. A named tone or any literal
583
- * CSS color; named tones track light/dark via the `--text-*` role tokens. Omit
584
- * (or `'neutral'`) to leave the text neutral. */
585
- 'tone-text'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
690
+ /** Like `tone`, but coloured onto the selected mark only an unselected ring stays
691
+ * neutral grey. Same value set as `tone`; if both are set, `tone` governs the
692
+ * off-state border and `tone-selected` the selected fill. */
693
+ 'tone-selected'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
586
694
  /** Size variant. small=14px, medium=16px, large=18px control. */
587
695
  size?: 'small' | 'medium' | 'large';
588
696
  /** Disabled state. Presence-based (`''` on, omit off). */
@@ -625,13 +733,13 @@ export interface ARadioGroupAttributes extends BaseAttributes {
625
733
  /** Form field name — the group submits `name=value`. */
626
734
  name?: string;
627
735
  /** Mark tone cascaded to children that don't set their own, or any literal CSS
628
- * color for a one-off custom tone. Inherits through CSS so every child
629
- * `<a-radio>` picks up the same fill curve. The option text stays neutral —
630
- * use `tone-text`. */
736
+ * color for a one-off custom tone. Colours every child's ring fill + dot *and*
737
+ * unselected border. The option text stays neutral — recolour it in plain CSS via
738
+ * the `--text-N-{tone}` tokens. */
631
739
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
632
- /** Text tone cascaded to children's label + hint, independent of `tone`. A named
633
- * tone or any literal CSS color. Omit (or `'neutral'`) to leave the text neutral. */
634
- 'tone-text'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
740
+ /** Like `tone`, but coloured onto the selected option only every unselected ring
741
+ * stays neutral grey. Cascaded to children that don't set their own. */
742
+ 'tone-selected'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
635
743
  /** Size cascaded to children that don't set their own. */
636
744
  size?: 'small' | 'medium' | 'large';
637
745
  /** Validation/feedback tone for the group hint — same set as `<a-input>`'s
@@ -691,6 +799,9 @@ export interface ATabAttributes extends BaseAttributes {
691
799
  selected?: boolean | '';
692
800
  /** Disabled state. Presence-based (`''` on, omit off). */
693
801
  disabled?: boolean | '';
802
+ /** Fully-round this tab's box (`--tab-radius: 999px`). `<a-tabs round>` sets it
803
+ * strip-wide instead. Presence-based (`''` on, omit off) — no custom value. */
804
+ round?: boolean | '';
694
805
  /** ARIA — `role="tab"` is set by the consumer (`Tabs` on each tab, or a hand-author),
695
806
  * and `aria-controls` points at the paired panel. `aria-selected` is published by
696
807
  * the element through `ElementInternals` (off the DOM), driven by the `selected`
@@ -740,6 +851,10 @@ export interface ATabsAttributes extends BaseAttributes {
740
851
  noslide?: boolean | '';
741
852
  /** Disable the whole strip. Presence-based (`''` on, omit off). */
742
853
  disabled?: boolean | '';
854
+ /** Fully-round tabs + sliding indicator (via `--tab-radius: 999px`) and the primary
855
+ * track well. A length value (`round="10px"`) applies to the top-level track well
856
+ * only (pills + indicator stay full). Presence-based for the boolean form. */
857
+ round?: boolean | number | string;
743
858
  /** Fires whenever the active tab changes. `detail` carries `{ next, prev }` (values;
744
859
  * `null` = none). Cancelable: a synchronous `preventDefault()` vetoes the pick in
745
860
  * uncontrolled mode. All-lowercase to bind across both renderers (like
@@ -771,14 +886,15 @@ export interface ATabsAttributes extends BaseAttributes {
771
886
  * from `@antadesign/anta`.
772
887
  */
773
888
  export interface ATabpanelAttributes extends BaseAttributes {
774
- /** Hidden via `display:none`. Presence-based (`''` on, omit off). */
775
- hidden?: boolean | '';
776
- /** Hidden via `visibility:hidden` (keeps the layout box). The `Tabs` wrapper sets
777
- * this for `mounting="visibility"`. */
778
- 'data-hide'?: 'visibility';
779
- /** Removes the hidden panel from focus + the a11y tree. Presence-based. */
780
- inert?: boolean | '';
781
- /** ARIA — set by the `Tabs` wrapper. */
889
+ /** Pairs the panel with the tab of the same value. The element reads its
890
+ * `<a-tabs>` and shows itself when this is the active value. */
891
+ value?: string;
892
+ /** How the panel hides while inactive: omit for `display:none` (removed from
893
+ * layout + the a11y tree), or `'visibility'` to keep its layout box. The
894
+ * element toggles its own `:state(active)`; this only picks the hide style. */
895
+ 'hide-mode'?: 'display' | 'visibility';
896
+ /** ARIA — set statically by the `TabPanel` wrapper. `aria-labelledby` is NOT an
897
+ * attribute here: the element points at its tab off-DOM via
898
+ * `internals.ariaLabelledByElements`. */
782
899
  role?: 'tabpanel';
783
- 'aria-labelledby'?: string;
784
900
  }
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@
19
19
  export { Progress } from './components/Progress';
20
20
  export type { ProgressProps } from './components/Progress';
21
21
  export { Text } from './components/Text';
22
- export type { TextProps } from './components/Text';
22
+ export type { TextProps, ExpandMode } from './components/Text';
23
23
  export { Title } from './components/Title';
24
24
  export type { TitleProps } from './components/Title';
25
25
  export { Tag } from './components/Tag';
@@ -45,12 +45,18 @@ export { Expander } from './components/Expander';
45
45
  export type { ExpanderProps } from './components/Expander';
46
46
  export { Input } from './components/Input';
47
47
  export type { InputProps, InputChangeAttrs } from './components/Input';
48
+ export { Calendar } from './components/Calendar';
49
+ export type { CalendarProps, CalendarChangeAttrs } from './components/Calendar';
50
+ export { InputDate } from './components/InputDate';
51
+ export type { InputDateProps, InputDateChangeAttrs } from './components/InputDate';
52
+ export { buildMonth, getWeekdays, firstDayOfWeek, clampDate, isOutOfRange, parseISODate, parseDateInput, formatDateInput, dateFormatPattern, parseTimeInput, parseDateTimeInput, formatDateTimeInput, dateTimeFormatPattern, usesHour12, } from './calendar-core';
53
+ export type { CalendarDay, CalendarWeekday, CalendarMonth, BuildMonthOptions, ParseDateOptions, } from './calendar-core';
48
54
  export { RadioGroup } from './components/RadioGroup';
49
55
  export type { RadioGroupProps, RadioOption } from './components/RadioGroup';
56
+ export { Select, optionsWithSelection } from './components/Select';
57
+ export type { SelectProps, SelectCommonProps, SelectOption, SelectGroup, SelectSubmenu, SelectItem, SelectChangeAttrs, OptionState, TriggerState, EmptyState, SelectionState, SelectedOption, SelectedGroup, SelectedSubmenu, SelectedItem, } from './components/Select';
50
58
  export { Tabs } from './components/Tabs';
51
- export type { TabsProps, TabsMounting, TabsChangeAttrs } from './components/Tabs';
52
- export { Tab } from './components/Tab';
53
- export type { TabProps } from './components/Tab';
59
+ export type { TabsProps, TabOption, TabsChangeAttrs } from './components/Tabs';
54
60
  export { TabPanel } from './components/TabPanel';
55
61
  export type { TabPanelProps } from './components/TabPanel';
56
62
  export type { BaseProps, BaseAttributes } from './general_types';
package/dist/index.js CHANGED
@@ -13,31 +13,66 @@ import { MenuSeparator } from "./components/MenuSeparator";
13
13
  import { MenuGroup } from "./components/MenuGroup";
14
14
  import { Expander } from "./components/Expander";
15
15
  import { Input } from "./components/Input";
16
+ import { Calendar } from "./components/Calendar";
17
+ import { InputDate } from "./components/InputDate";
18
+ import {
19
+ buildMonth,
20
+ getWeekdays,
21
+ firstDayOfWeek,
22
+ clampDate,
23
+ isOutOfRange,
24
+ parseISODate,
25
+ parseDateInput,
26
+ formatDateInput,
27
+ dateFormatPattern,
28
+ parseTimeInput,
29
+ parseDateTimeInput,
30
+ formatDateTimeInput,
31
+ dateTimeFormatPattern,
32
+ usesHour12
33
+ } from "./calendar-core";
16
34
  import { RadioGroup } from "./components/RadioGroup";
35
+ import { Select, optionsWithSelection } from "./components/Select";
17
36
  import { Tabs } from "./components/Tabs";
18
- import { Tab } from "./components/Tab";
19
37
  import { TabPanel } from "./components/TabPanel";
20
38
  import { configure } from "./jsx-runtime";
21
39
  export {
22
40
  Button,
41
+ Calendar,
23
42
  Checkbox,
24
43
  Expander,
25
44
  ICON_SHAPES,
26
45
  ICON_SYNONYMS,
27
46
  Icon,
28
47
  Input,
48
+ InputDate,
29
49
  Menu,
30
50
  MenuGroup,
31
51
  MenuItem,
32
52
  MenuSeparator,
33
53
  Progress,
34
54
  RadioGroup,
35
- Tab,
55
+ Select,
36
56
  TabPanel,
37
57
  Tabs,
38
58
  Tag,
39
59
  Text,
40
60
  Title,
41
61
  Tooltip,
42
- configure
62
+ buildMonth,
63
+ clampDate,
64
+ configure,
65
+ dateFormatPattern,
66
+ dateTimeFormatPattern,
67
+ firstDayOfWeek,
68
+ formatDateInput,
69
+ formatDateTimeInput,
70
+ getWeekdays,
71
+ isOutOfRange,
72
+ optionsWithSelection,
73
+ parseDateInput,
74
+ parseDateTimeInput,
75
+ parseISODate,
76
+ parseTimeInput,
77
+ usesHour12
43
78
  };
@@ -3,10 +3,11 @@ type ComponentType = string | Function | symbol;
3
3
  type JsxFunction = {
4
4
  h(type: ComponentType, props: Record<string, unknown> | null, ...children: unknown[]): unknown;
5
5
  }['h'];
6
- /** The two hooks the stateful wrappers (currently only `RadioGroup`) need. Typed
7
- * loosely to stay renderer-agnostic — any React-compatible hook implementation. */
6
+ /** The hooks the stateful wrappers need. Typed loosely to stay renderer-agnostic —
7
+ * any React-compatible hook implementation. */
8
8
  type UseState = <S>(initial: S | (() => S)) => [S, (next: S | ((prev: S) => S)) => void];
9
9
  type UseId = () => string;
10
+ type UseMemo = <T>(factory: () => T, deps: unknown[]) => T;
10
11
  declare let _Fragment: ComponentType;
11
12
  /**
12
13
  * Swap the underlying JSX factory (and, optionally, the hooks) used by all anta
@@ -15,32 +16,37 @@ declare let _Fragment: ComponentType;
15
16
  * Not needed for React or Preact-with-compat — those work automatically. Call this
16
17
  * before rendering any anta components when using Preact without compat aliasing,
17
18
  * or a custom JSX runtime. Pass `hooks` when your runtime's hooks don't resolve via
18
- * the `react` specifier (the stateful wrappers — `RadioGroup` — need `useState` /
19
- * `useId`); omit it and they default to whatever `react` resolves to.
19
+ * the `react` specifier (the stateful wrappers — `RadioGroup`, `Calendar`,
20
+ * `InputDate` — need `useState` / `useId` / `useMemo`); omit it and they default
21
+ * to whatever `react` resolves to.
20
22
  *
21
23
  * @example Preact without compat
22
24
  * ```ts
23
25
  * import { configure } from '@antadesign/anta'
24
26
  * import { h, Fragment } from 'preact'
25
- * import { useState, useId } from 'preact/hooks'
26
- * configure(h, Fragment, { useState, useId })
27
+ * import { useState, useId, useMemo } from 'preact/hooks'
28
+ * configure(h, Fragment, { useState, useId, useMemo })
27
29
  * ```
28
30
  */
29
31
  export declare function configure(jsx: JsxFunction, Fragment?: ComponentType, hooks?: {
30
32
  useState?: UseState;
31
33
  useId?: UseId;
34
+ useMemo?: UseMemo;
32
35
  }): void;
33
36
  /** Hooks indirection so wrappers depend on the configured renderer, not a hard
34
37
  * `import … from 'react'`. Call these exactly like the React hooks. */
35
38
  export declare function useState<S>(initial: S | (() => S)): [S, (next: S | ((prev: S) => S)) => void];
36
39
  export declare function useId(): string;
40
+ export declare function useMemo<T>(factory: () => T, deps: unknown[]): T;
37
41
  export declare function jsx(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
38
42
  export declare function jsxs(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
39
43
  export { _Fragment as Fragment };
40
- import type { AProgressAttributes, ATextAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACheckboxAttributes, ATooltipAttributes, AInputAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, BaseAttributes } from './general_types';
44
+ import type { AProgressAttributes, ATextAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACheckboxAttributes, ATooltipAttributes, AInputAttributes, ACalendarAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, BaseAttributes } from './general_types';
41
45
  export declare namespace JSX {
42
46
  interface IntrinsicElements extends React.JSX.IntrinsicElements, AntaIntrinsicElements {
43
47
  }
48
+ interface IntrinsicAttributes extends React.JSX.IntrinsicAttributes {
49
+ }
44
50
  }
45
51
  export interface AntaIntrinsicElements {
46
52
  'a-progress': AProgressAttributes;
@@ -64,6 +70,7 @@ export interface AntaIntrinsicElements {
64
70
  'a-checkbox-hint': BaseAttributes;
65
71
  'a-tooltip': ATooltipAttributes;
66
72
  'a-input': AInputAttributes;
73
+ 'a-calendar': ACalendarAttributes;
67
74
  'a-radio': ARadioAttributes;
68
75
  'a-radio-group': ARadioGroupAttributes;
69
76
  'a-radio-group-label': BaseAttributes;
@@ -74,6 +81,8 @@ export interface AntaIntrinsicElements {
74
81
  'a-menu': AMenuAttributes;
75
82
  'a-menu-item': AMenuItemAttributes;
76
83
  'a-menu-item-label': BaseAttributes;
84
+ 'a-menu-item-hint': BaseAttributes;
85
+ 'a-menu-item-text': BaseAttributes;
77
86
  'a-menu-separator': BaseAttributes;
78
87
  'a-menu-group': AMenuGroupAttributes;
79
88
  'a-menu-group-label': BaseAttributes;
@@ -3,11 +3,13 @@ let _jsx = React.createElement;
3
3
  let _Fragment = React.Fragment;
4
4
  let _useState = React.useState;
5
5
  let _useId = React.useId;
6
+ let _useMemo = React.useMemo;
6
7
  function configure(jsx2, Fragment, hooks) {
7
8
  _jsx = jsx2;
8
9
  if (Fragment !== void 0) _Fragment = Fragment;
9
10
  if (hooks?.useState) _useState = hooks.useState;
10
11
  if (hooks?.useId) _useId = hooks.useId;
12
+ if (hooks?.useMemo) _useMemo = hooks.useMemo;
11
13
  }
12
14
  function useState(initial) {
13
15
  return _useState(initial);
@@ -15,6 +17,9 @@ function useState(initial) {
15
17
  function useId() {
16
18
  return _useId();
17
19
  }
20
+ function useMemo(factory, deps) {
21
+ return _useMemo(factory, deps);
22
+ }
18
23
  function jsx(type, props, key) {
19
24
  const { children, ...rest } = props ?? {};
20
25
  const p = key !== void 0 ? { ...rest, key } : rest;
@@ -37,5 +42,6 @@ export {
37
42
  jsx,
38
43
  jsxs,
39
44
  useId,
45
+ useMemo,
40
46
  useState
41
47
  };
package/dist/reset.css CHANGED
@@ -1 +1 @@
1
- @layer anta{*,*:before,*:after{box-sizing:border-box}*{margin:0}img,picture,video,canvas,svg{display:block;max-width:100%}input,button,textarea,select{font:inherit}p,h1,h2,h3,h4,h5,h6{overflow-wrap:break-word}p{text-wrap:pretty}h1,h2,h3,h4,h5,h6{text-wrap:balance}h1,h2,h3,h4,h5,h6{color:var(--text-1);font-weight:584.62;letter-spacing:0}h1{font-size:28px;line-height:32px;margin-block:0 16px}h2{font-size:24px;line-height:28px;margin-block:32px 12px}h3{font-size:20px;line-height:24px;margin-block:24px 12px}h4{font-size:17px;line-height:20px;margin-block:20px 8px}h5{font-size:15px;line-height:20px;margin-block:16px 8px}h6{font-size:13px;line-height:16px;margin-block:16px 4px}strong{font-weight:600}code{line-height:1em}code,kbd,samp,pre{letter-spacing:0}ul,ol{padding-left:3ch}:is(ul,ol)>li{margin-bottom:.5em}:is(ul,ol)>li::marker{color:var(--text-5)}menu{list-style:none;padding:0;margin:0}menu>li{margin:0}a:not(:where([role=button])),a:not(:where([role=button])):link,a:not(:where([role=button])):visited{color:var(--link-color);text-decoration:underline;text-decoration-style:solid;text-decoration-color:color-mix(in srgb,currentColor 75%,transparent);text-decoration-thickness:.5px;text-underline-offset:3px}@media(hover:hover)and (pointer:fine){a:not(:where([role=button])):hover{color:var(--link-color-hover);text-decoration-thickness:1px}}a:not(:where([role=button])):active{text-decoration-color:color-mix(in srgb,currentColor 75%,transparent)}::selection{background:color-mix(in srgb,var(--text-1-brand),transparent 85%)}table{border-collapse:collapse;font-variant-numeric:tabular-nums}caption{text-align:left;color:var(--text-3);padding-left:10px;margin-bottom:.25em}th,td{padding:5px 10px;text-align:left;vertical-align:top;border-bottom:1px solid var(--border-4)}thead th{font-weight:600}tfoot tr:last-child>:is(th,td),table:not(:has(tfoot)) tbody tr:last-child>:is(th,td){border-bottom:none}table[data-bordered]{border-collapse:separate;border-spacing:0;border:1px solid var(--border-4);border-radius:3px}table[data-bordered] :is(th,td){border-right:1px solid var(--border-4)}table[data-bordered] tr>:is(th,td):last-child{border-right:0}}
1
+ @layer anta{*,*:before,*:after{box-sizing:border-box}*{margin:0}img,picture,video,canvas,svg{display:block;max-width:100%}input,button,textarea,select{font:inherit}p,h1,h2,h3,h4,h5,h6{overflow-wrap:break-word}p{text-wrap:pretty}h1,h2,h3,h4,h5,h6{text-wrap:balance}h1,h2,h3,h4,h5,h6{color:var(--text-1);font-weight:584.62;letter-spacing:0}h1{font-size:28px;line-height:32px;margin-block:0 16px}h2{font-size:24px;line-height:28px;margin-block:32px 12px}h3{font-size:20px;line-height:24px;margin-block:24px 12px}h4{font-size:17px;line-height:20px;margin-block:20px 8px}h5{font-size:15px;line-height:20px;margin-block:16px 8px}h6{font-size:13px;line-height:16px;margin-block:16px 4px}strong{font-weight:600}code{line-height:1em}code,kbd,samp,pre{letter-spacing:0}ul,ol{padding-left:3ch}:is(ul,ol)>li{margin-bottom:.5em}:is(ul,ol)>li::marker{color:var(--text-5)}menu{list-style:none;padding:0;margin:0}menu>li{margin:0}a:not(:where([role=button])),a:not(:where([role=button])):link,a:not(:where([role=button])):visited{color:var(--link-color);text-decoration:underline;text-decoration-style:solid;text-decoration-color:color-mix(in srgb,currentColor 75%,transparent);text-decoration-thickness:.5px;text-underline-offset:3px}@media(hover:hover)and (pointer:fine){a:not(:where([role=button])):hover{color:var(--link-color-hover);text-decoration-thickness:1px}}a:not(:where([role=button])):active{text-decoration-color:color-mix(in srgb,currentColor 75%,transparent)}::selection{background:color-mix(in srgb,var(--text-1-brand),transparent 85%)}table{border-collapse:collapse;font-variant-numeric:lining-nums tabular-nums}caption{text-align:left;color:var(--text-3);padding-left:10px;margin-bottom:.25em}th,td{padding:5px 10px;text-align:left;vertical-align:top;border-bottom:1px solid var(--border-4)}thead th{font-weight:600}tfoot tr:last-child>:is(th,td),table:not(:has(tfoot)) tbody tr:last-child>:is(th,td){border-bottom:none}table[data-bordered]{border-collapse:separate;border-spacing:0;border:1px solid var(--border-4);border-radius:3px}table[data-bordered] :is(th,td){border-right:1px solid var(--border-4)}table[data-bordered] tr>:is(th,td):last-child{border-right:0}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antadesign/anta",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -52,6 +52,7 @@
52
52
  "dev": "echo $$ > .dev.pid; trap 'rm -f .dev.pid' EXIT; nodemon -w src -w stickers/src -e ts,tsx,css -x 'pnpm run build:dev && pnpm --filter @antadesign/stickers run build:dev && pnpm --filter anta-site run docs' & pnpm --filter anta-site run dev & wait",
53
53
  "stop": "node scripts/dev-stop.mjs",
54
54
  "typecheck": "tsc --noEmit -p src/tsconfig.json",
55
+ "lint": "node scripts/lint-getters.mjs",
55
56
  "icons": "node scripts/generate-icons.mjs --input src/elements/icons --output src/elements --name a-icon.shapes --internal",
56
57
  "clean": "rm -rf dist",
57
58
  "prepare": "pnpm run build",
@@ -65,7 +66,8 @@
65
66
  },
66
67
  "dependencies": {
67
68
  "clsx": "^2.1.0",
68
- "es-toolkit": "1.47.0"
69
+ "es-toolkit": "1.47.0",
70
+ "temporal-polyfill": "^1.0.1"
69
71
  },
70
72
  "peerDependencies": {
71
73
  "react": "^18.0.0 || ^19.0.0"