@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.
- package/dist/anta_helpers.d.ts +97 -0
- package/dist/anta_helpers.js +70 -0
- package/dist/calendar-core.d.ts +126 -0
- package/dist/calendar-core.js +289 -0
- package/dist/components/Button.d.ts +9 -1
- package/dist/components/Button.js +5 -2
- package/dist/components/Calendar.d.ts +85 -0
- package/dist/components/Calendar.js +226 -0
- package/dist/components/Checkbox.d.ts +16 -11
- package/dist/components/Checkbox.js +13 -7
- package/dist/components/Expander.d.ts +7 -1
- package/dist/components/Expander.js +4 -2
- package/dist/components/Input.d.ts +13 -5
- package/dist/components/Input.js +14 -6
- package/dist/components/InputDate.d.ts +89 -0
- package/dist/components/InputDate.js +273 -0
- package/dist/components/InputDate.module.css +1 -0
- package/dist/components/Menu.d.ts +14 -1
- package/dist/components/Menu.js +6 -2
- package/dist/components/MenuItem.d.ts +48 -7
- package/dist/components/MenuItem.js +72 -14
- package/dist/components/MenuSeparator.d.ts +13 -2
- package/dist/components/MenuSeparator.js +12 -2
- package/dist/components/Progress.d.ts +4 -1
- package/dist/components/Progress.js +4 -3
- package/dist/components/RadioGroup.d.ts +12 -10
- package/dist/components/RadioGroup.js +5 -5
- package/dist/components/Select.d.ts +319 -0
- package/dist/components/Select.js +341 -0
- package/dist/components/Select.module.css +1 -0
- package/dist/components/Tab.d.ts +3 -0
- package/dist/components/Tab.js +2 -1
- package/dist/components/TabPanel.d.ts +21 -13
- package/dist/components/TabPanel.js +13 -1
- package/dist/components/Tabs.d.ts +75 -40
- package/dist/components/Tabs.js +20 -88
- package/dist/components/Tag.d.ts +10 -9
- package/dist/components/Tag.js +2 -2
- package/dist/components/Text.d.ts +6 -5
- package/dist/components/Title.d.ts +4 -2
- package/dist/components/Tooltip.d.ts +4 -1
- package/dist/components/Tooltip.js +5 -0
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-calendar.css +1 -0
- package/dist/elements/a-calendar.d.ts +76 -0
- package/dist/elements/a-calendar.js +190 -0
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-checkbox.d.ts +1 -2
- package/dist/elements/a-checkbox.js +5 -5
- package/dist/elements/a-expander.css +1 -1
- package/dist/elements/a-expander.d.ts +16 -5
- package/dist/elements/a-expander.js +59 -8
- package/dist/elements/a-icon.shapes.css +1 -1
- package/dist/elements/a-icon.shapes.d.ts +6 -1
- package/dist/elements/a-icon.shapes.js +9 -0
- package/dist/elements/a-input.css +1 -1
- package/dist/elements/a-input.d.ts +6 -0
- package/dist/elements/a-input.js +28 -8
- package/dist/elements/a-menu-group.css +1 -1
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.d.ts +22 -10
- package/dist/elements/a-menu-item.js +17 -0
- package/dist/elements/a-menu-separator.css +1 -1
- package/dist/elements/a-menu.css +1 -1
- package/dist/elements/a-menu.d.ts +61 -20
- package/dist/elements/a-menu.js +337 -58
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-radio-group.d.ts +1 -3
- package/dist/elements/a-radio-group.js +13 -13
- package/dist/elements/a-radio.css +1 -1
- package/dist/elements/a-radio.d.ts +3 -11
- package/dist/elements/a-radio.js +3 -34
- package/dist/elements/a-tab.css +1 -1
- package/dist/elements/a-tab.d.ts +3 -11
- package/dist/elements/a-tab.js +3 -34
- package/dist/elements/a-tabpanel.css +1 -1
- package/dist/elements/a-tabpanel.d.ts +17 -0
- package/dist/elements/a-tabpanel.js +66 -0
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tabs.d.ts +1 -4
- package/dist/elements/a-tabs.js +14 -14
- package/dist/elements/a-tag.css +1 -1
- package/dist/elements/a-text.d.ts +14 -13
- package/dist/elements/a-text.js +53 -23
- package/dist/elements/a-tooltip.css +1 -1
- package/dist/elements/a-tooltip.d.ts +1 -11
- package/dist/elements/a-tooltip.js +20 -19
- package/dist/elements/index.d.ts +2 -1
- package/dist/elements/index.js +6 -1
- package/dist/general_types.d.ts +158 -42
- package/dist/index.d.ts +10 -4
- package/dist/index.js +38 -3
- package/dist/jsx-runtime.d.ts +16 -7
- package/dist/jsx-runtime.js +6 -0
- package/dist/reset.css +1 -1
- package/package.json +4 -2
package/dist/anta_helpers.d.ts
CHANGED
|
@@ -31,6 +31,52 @@ export declare const NAMED_TONES: Set<string>;
|
|
|
31
31
|
* derives the fill/text/border curve in oklch. Named tones return `base` unchanged.
|
|
32
32
|
*/
|
|
33
33
|
export declare function toneStyle(tone: string | undefined, varName: string, base?: React.CSSProperties): React.CSSProperties | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Inline-style helper for a valued `round` — the polymorphic corner-radius prop
|
|
36
|
+
* (`true` = fully round, a `number`/length = a custom radius). Mirrors `toneStyle`:
|
|
37
|
+
* a custom value is handed to the element via `varName` (e.g. `--button-round`), so
|
|
38
|
+
* the element's CSS resolves `border-radius: var(--{c}-round, <default>)`. This is
|
|
39
|
+
* the portable path — the element's `attr(round type(<length>), …)` default only
|
|
40
|
+
* resolves on newer engines, exactly like the tone-source `attr()`.
|
|
41
|
+
*
|
|
42
|
+
* A `number` becomes `<n>px`; a non-empty `string` is used verbatim (so `'1rem'` /
|
|
43
|
+
* `'50%'` work). `true` / `false` / `undefined` add nothing (presence alone → the
|
|
44
|
+
* element's default full-round). Returns `base` unchanged when there's no value.
|
|
45
|
+
*/
|
|
46
|
+
export declare function roundStyle(round: boolean | number | string | undefined, varName: string, base?: React.CSSProperties): React.CSSProperties | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* The rect a floating-element anchor advertises for positioning. Any element may
|
|
49
|
+
* implement `getAnchorRect(): DOMRect` to point positioners (`a-menu`,
|
|
50
|
+
* `a-tooltip`) at a sub-region of itself — e.g. `a-input` returns its `.field`
|
|
51
|
+
* box rather than the host, whose box also spans the label / hint, so a menu or
|
|
52
|
+
* tooltip lines up with the field itself. Elements without it fall back to their
|
|
53
|
+
* border box (`getBoundingClientRect`), so this is opt-in and back-compatible.
|
|
54
|
+
* Shared by a-menu and a-tooltip.
|
|
55
|
+
*/
|
|
56
|
+
export declare function anchorRect(el: Element): DOMRect;
|
|
57
|
+
/**
|
|
58
|
+
* Menu ↔ Tooltip presence coordinator — in-memory only, no DOM. `a-menu`
|
|
59
|
+
* publishes whether a menu system is open and whether a node sits inside it;
|
|
60
|
+
* `a-tooltip` reads this to suppress a tooltip anchored *outside* an open menu.
|
|
61
|
+
* (Menu and tooltip are both top-layer popovers, stacked by show order, so a
|
|
62
|
+
* tooltip opened while a menu is up would paint over it — z-index can't reorder
|
|
63
|
+
* the top layer.) Decoupled on purpose: neither element imports the other, and
|
|
64
|
+
* if `a-menu` never loads the provider stays null and every tooltip shows.
|
|
65
|
+
*/
|
|
66
|
+
export interface MenuPresence {
|
|
67
|
+
/** Is any `a-menu` open? */
|
|
68
|
+
isOpen(): boolean;
|
|
69
|
+
/** Is `node` inside the open menu system — a menu surface, a slotted item, or
|
|
70
|
+
* an open trigger? (A tooltip there is a menu-item tooltip and still shows,
|
|
71
|
+
* above the menu.) */
|
|
72
|
+
contains(node: Node): boolean;
|
|
73
|
+
}
|
|
74
|
+
/** `a-menu` registers its live open-state provider here (once, on load). */
|
|
75
|
+
export declare function setMenuPresence(p: MenuPresence | null): void;
|
|
76
|
+
/** True while any `a-menu` is open. */
|
|
77
|
+
export declare function isMenuOpen(): boolean;
|
|
78
|
+
/** True if `node` sits inside the open menu system. */
|
|
79
|
+
export declare function isInsideOpenMenu(node: Node): boolean;
|
|
34
80
|
/**
|
|
35
81
|
* `HTMLElement` in browsers, a noop class in Node/Worker environments.
|
|
36
82
|
* Use this as the base for custom element classes so importing the
|
|
@@ -54,4 +100,55 @@ export declare class HTMLElementBase extends NativeHTMLElement {
|
|
|
54
100
|
/** This element's own document (the iframe's document when nested). */
|
|
55
101
|
protected get doc(): Document;
|
|
56
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Base for a coordinated presentational child — one option in a control whose
|
|
105
|
+
* parent owns the selection (`<a-radio>` in `<a-radio-group>`, `<a-tab>` in
|
|
106
|
+
* `<a-tabs>`). The parent is the single source of truth and pushes selection down
|
|
107
|
+
* by setting the `selected` *property* (never an attribute — that would mutate the
|
|
108
|
+
* child's DOM, which app-DOM-in-a-worker forbids). This child's only job is to
|
|
109
|
+
* reflect that into a `:state(selected)` custom state (the CSS hook) and one ARIA
|
|
110
|
+
* property — `aria-checked` for radios, `aria-selected` for tabs — through its OWN
|
|
111
|
+
* ElementInternals. It owns no selection *logic*: the `internals` bit is a render
|
|
112
|
+
* latch, not authoritative state.
|
|
113
|
+
*
|
|
114
|
+
* The `selected` attribute is a hand-author / raw-assembly seed for the initial
|
|
115
|
+
* paint only. `connectedCallback` reads it **ON-only, never OFF**: under eager
|
|
116
|
+
* element registration the parent connects first (parent-before-child tree order)
|
|
117
|
+
* and has already set the property by the time this runs, so forcing OFF for an
|
|
118
|
+
* absent attribute would silently clobber that initial selection (state right,
|
|
119
|
+
* nothing painted). The resting latch is already off, so seeding only-ON loses
|
|
120
|
+
* nothing. After connect, both the property setter and `attributeChangedCallback`
|
|
121
|
+
* drive selection two-way. Encoding the guard here (not per element) is what makes
|
|
122
|
+
* the clobber bug impossible by construction for every child that extends this.
|
|
123
|
+
*
|
|
124
|
+
* Subclasses set `ariaProp` to the ARIA reflection property their role needs.
|
|
125
|
+
*/
|
|
126
|
+
export declare class SelectableChildElement extends HTMLElementBase {
|
|
127
|
+
static observedAttributes: string[];
|
|
128
|
+
/** ARIA property this element reflects selection into. Subclass sets it. */
|
|
129
|
+
protected ariaProp: 'ariaChecked' | 'ariaSelected';
|
|
130
|
+
private internals?;
|
|
131
|
+
connectedCallback(): void;
|
|
132
|
+
attributeChangedCallback(name: string): void;
|
|
133
|
+
get selected(): boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Live selection, held off the DOM as `:state(selected)` (mirrored to `ariaProp`).
|
|
136
|
+
* The parent `a-radio-group` / `a-tabs` drives it by assigning the *property* a real
|
|
137
|
+
* boolean from its `sync()` (`el.selected = r === selectedEl`), so a genuine boolean
|
|
138
|
+
* is the only input the setter sees in practice.
|
|
139
|
+
*
|
|
140
|
+
* `!!on` is deliberate and matches native IDL booleans: `el.selected = ''` yields
|
|
141
|
+
* `false`, exactly like `input.disabled = '' → false`. Empty string is a falsy
|
|
142
|
+
* *value*; "presence means true" is an attribute-world rule (it governs `hasAttribute`
|
|
143
|
+
* in `attributeChangedCallback` and CSS `[selected]` matching) and does not carry to
|
|
144
|
+
* property assignment. React 19 assigns element props as properties, so a hand-written
|
|
145
|
+
* `<a-radio selected="">` there reads as `false` while the same markup in plain HTML
|
|
146
|
+
* reads as `true` — the split every boolean IDL property has. Write bare `selected` /
|
|
147
|
+
* `selected={true}` for on; both paths agree. Do not "fix" `!!on` to treat `''` as true.
|
|
148
|
+
*/
|
|
149
|
+
set selected(on: boolean);
|
|
150
|
+
get value(): string;
|
|
151
|
+
set value(v: string);
|
|
152
|
+
protected applyState(on: boolean): void;
|
|
153
|
+
}
|
|
57
154
|
export {};
|
package/dist/anta_helpers.js
CHANGED
|
@@ -27,6 +27,25 @@ const NAMED_TONES = /* @__PURE__ */ new Set([
|
|
|
27
27
|
function toneStyle(tone, varName, base) {
|
|
28
28
|
return tone != null && !NAMED_TONES.has(tone) ? { ...base, [varName]: tone } : base;
|
|
29
29
|
}
|
|
30
|
+
function roundStyle(round, varName, base) {
|
|
31
|
+
if (typeof round === "number") return { ...base, [varName]: `${round}px` };
|
|
32
|
+
if (typeof round === "string" && round !== "") return { ...base, [varName]: round };
|
|
33
|
+
return base;
|
|
34
|
+
}
|
|
35
|
+
function anchorRect(el) {
|
|
36
|
+
const fn = el.getAnchorRect;
|
|
37
|
+
return typeof fn === "function" ? fn.call(el) : el.getBoundingClientRect();
|
|
38
|
+
}
|
|
39
|
+
let menuPresence = null;
|
|
40
|
+
function setMenuPresence(p) {
|
|
41
|
+
menuPresence = p;
|
|
42
|
+
}
|
|
43
|
+
function isMenuOpen() {
|
|
44
|
+
return menuPresence?.isOpen() ?? false;
|
|
45
|
+
}
|
|
46
|
+
function isInsideOpenMenu(node) {
|
|
47
|
+
return menuPresence?.contains(node) ?? false;
|
|
48
|
+
}
|
|
30
49
|
const NativeHTMLElement = typeof HTMLElement !== "undefined" ? HTMLElement : class {
|
|
31
50
|
};
|
|
32
51
|
class HTMLElementBase extends NativeHTMLElement {
|
|
@@ -39,11 +58,62 @@ class HTMLElementBase extends NativeHTMLElement {
|
|
|
39
58
|
return this.ownerDocument ?? document;
|
|
40
59
|
}
|
|
41
60
|
}
|
|
61
|
+
class SelectableChildElement extends HTMLElementBase {
|
|
62
|
+
static observedAttributes = ["selected"];
|
|
63
|
+
/** ARIA property this element reflects selection into. Subclass sets it. */
|
|
64
|
+
ariaProp = "ariaChecked";
|
|
65
|
+
internals = this.attachInternals?.();
|
|
66
|
+
connectedCallback() {
|
|
67
|
+
if (this.hasAttribute("selected")) this.applyState(true);
|
|
68
|
+
}
|
|
69
|
+
attributeChangedCallback(name) {
|
|
70
|
+
if (name === "selected") this.applyState(this.hasAttribute("selected"));
|
|
71
|
+
}
|
|
72
|
+
get selected() {
|
|
73
|
+
return this.internals?.states.has("selected") ?? false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Live selection, held off the DOM as `:state(selected)` (mirrored to `ariaProp`).
|
|
77
|
+
* The parent `a-radio-group` / `a-tabs` drives it by assigning the *property* a real
|
|
78
|
+
* boolean from its `sync()` (`el.selected = r === selectedEl`), so a genuine boolean
|
|
79
|
+
* is the only input the setter sees in practice.
|
|
80
|
+
*
|
|
81
|
+
* `!!on` is deliberate and matches native IDL booleans: `el.selected = ''` yields
|
|
82
|
+
* `false`, exactly like `input.disabled = '' → false`. Empty string is a falsy
|
|
83
|
+
* *value*; "presence means true" is an attribute-world rule (it governs `hasAttribute`
|
|
84
|
+
* in `attributeChangedCallback` and CSS `[selected]` matching) and does not carry to
|
|
85
|
+
* property assignment. React 19 assigns element props as properties, so a hand-written
|
|
86
|
+
* `<a-radio selected="">` there reads as `false` while the same markup in plain HTML
|
|
87
|
+
* reads as `true` — the split every boolean IDL property has. Write bare `selected` /
|
|
88
|
+
* `selected={true}` for on; both paths agree. Do not "fix" `!!on` to treat `''` as true.
|
|
89
|
+
*/
|
|
90
|
+
set selected(on) {
|
|
91
|
+
this.applyState(!!on);
|
|
92
|
+
}
|
|
93
|
+
get value() {
|
|
94
|
+
return this.getAttribute("value") ?? "";
|
|
95
|
+
}
|
|
96
|
+
set value(v) {
|
|
97
|
+
this.setAttribute("value", v);
|
|
98
|
+
}
|
|
99
|
+
applyState(on) {
|
|
100
|
+
if (!this.internals) return;
|
|
101
|
+
if (on) this.internals.states.add("selected");
|
|
102
|
+
else this.internals.states.delete("selected");
|
|
103
|
+
this.internals[this.ariaProp] = on ? "true" : "false";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
42
106
|
export {
|
|
43
107
|
HTMLElementBase,
|
|
44
108
|
NAMED_TONES,
|
|
109
|
+
SelectableChildElement,
|
|
110
|
+
anchorRect,
|
|
45
111
|
hasChildren,
|
|
112
|
+
isInsideOpenMenu,
|
|
113
|
+
isMenuOpen,
|
|
46
114
|
nativeStateChange,
|
|
115
|
+
roundStyle,
|
|
116
|
+
setMenuPresence,
|
|
47
117
|
toneStyle,
|
|
48
118
|
wrapLabel
|
|
49
119
|
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Temporal } from 'temporal-polyfill';
|
|
2
|
+
/** One day cell in the rendered grid. */
|
|
3
|
+
export interface CalendarDay {
|
|
4
|
+
/** The date this cell represents. */
|
|
5
|
+
date: Temporal.PlainDate;
|
|
6
|
+
/** ISO `YYYY-MM-DD`. */
|
|
7
|
+
iso: string;
|
|
8
|
+
/** Day of month, 1–31. */
|
|
9
|
+
day: number;
|
|
10
|
+
/** Day of week, 1 (Mon) – 7 (Sun), matching Temporal. */
|
|
11
|
+
weekday: number;
|
|
12
|
+
/** True when the day belongs to an adjacent month (grid spill-over). */
|
|
13
|
+
outside: boolean;
|
|
14
|
+
/** True when the day is outside `[min, max]` (not selectable). */
|
|
15
|
+
disabled: boolean;
|
|
16
|
+
/** True when the day is the current date. */
|
|
17
|
+
today: boolean;
|
|
18
|
+
/** True when the day is the selected date. */
|
|
19
|
+
selected: boolean;
|
|
20
|
+
/** Localized full-date label incl. weekday, e.g. "Sunday, June 28, 2026"
|
|
21
|
+
* (for each day button's `aria-label`, since there's no column-header row). */
|
|
22
|
+
label: string;
|
|
23
|
+
}
|
|
24
|
+
/** A weekday column header, localized. */
|
|
25
|
+
export interface CalendarWeekday {
|
|
26
|
+
/** One-letter-ish narrow form (here trimmed to two: "Mo", "Tu", …). */
|
|
27
|
+
narrow: string;
|
|
28
|
+
/** Locale short form ("Mon", "lun.", …). */
|
|
29
|
+
short: string;
|
|
30
|
+
/** Locale long form ("Monday") — for the column header's accessible name. */
|
|
31
|
+
long: string;
|
|
32
|
+
/** Saturday or Sunday (locale-independent — by Temporal `dayOfWeek` 6/7). */
|
|
33
|
+
weekend: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** A fully-computed month: heading, ordered weekday headers, and the week rows. */
|
|
36
|
+
export interface CalendarMonth {
|
|
37
|
+
/** Displayed year. */
|
|
38
|
+
year: number;
|
|
39
|
+
/** Displayed month, 1–12. */
|
|
40
|
+
month: number;
|
|
41
|
+
/** Localized "June 2026" heading. */
|
|
42
|
+
heading: string;
|
|
43
|
+
/** Seven weekday headers, ordered from the locale's first day of week. */
|
|
44
|
+
weekdays: CalendarWeekday[];
|
|
45
|
+
/** Week rows (6 by default), each seven `CalendarDay`s. */
|
|
46
|
+
weeks: CalendarDay[][];
|
|
47
|
+
}
|
|
48
|
+
export interface BuildMonthOptions {
|
|
49
|
+
/** Any date within the month to display. */
|
|
50
|
+
anchor: Temporal.PlainDate;
|
|
51
|
+
/** BCP-47 locale. @defaultValue 'en-US' */
|
|
52
|
+
locale?: string;
|
|
53
|
+
/** Earliest selectable date (inclusive). */
|
|
54
|
+
min?: Temporal.PlainDate | null;
|
|
55
|
+
/** Latest selectable date (inclusive). */
|
|
56
|
+
max?: Temporal.PlainDate | null;
|
|
57
|
+
/** The currently-selected date, if any. */
|
|
58
|
+
selected?: Temporal.PlainDate | null;
|
|
59
|
+
/** The date to mark as "today". @defaultValue Temporal.Now.plainDateISO() */
|
|
60
|
+
today?: Temporal.PlainDate | null;
|
|
61
|
+
/** Number of week rows. @defaultValue 6 */
|
|
62
|
+
weeks?: number;
|
|
63
|
+
}
|
|
64
|
+
/** Parse an ISO `YYYY-MM-DD` string to a `Temporal.PlainDate`, or `null` if
|
|
65
|
+
* it's empty or malformed. */
|
|
66
|
+
export declare function parseISODate(value: string | null | undefined): Temporal.PlainDate | null;
|
|
67
|
+
/** First weekday for a locale, `1`=Monday … `7`=Sunday (matches Temporal's
|
|
68
|
+
* `dayOfWeek`). Reads `Intl.Locale#getWeekInfo()` (or the `weekInfo` getter on
|
|
69
|
+
* engines that expose it that way); falls back to Monday — never hard-codes
|
|
70
|
+
* Sunday. */
|
|
71
|
+
export declare function firstDayOfWeek(locale: string): number;
|
|
72
|
+
/** Clamp a date into the inclusive `[min, max]` range. */
|
|
73
|
+
export declare function clampDate(d: Temporal.PlainDate, min?: Temporal.PlainDate | null, max?: Temporal.PlainDate | null): Temporal.PlainDate;
|
|
74
|
+
/** Whether a date falls outside the inclusive `[min, max]` range. */
|
|
75
|
+
export declare function isOutOfRange(d: Temporal.PlainDate, min?: Temporal.PlainDate | null, max?: Temporal.PlainDate | null): boolean;
|
|
76
|
+
/** The seven weekday headers, ordered from the locale's first day of week. */
|
|
77
|
+
export declare function getWeekdays(locale: string, firstDay?: number): CalendarWeekday[];
|
|
78
|
+
/** Build a fully-resolved month grid for rendering. */
|
|
79
|
+
export declare function buildMonth(opts: BuildMonthOptions): CalendarMonth;
|
|
80
|
+
/** The placeholder mask for a locale: `MM/DD/YYYY` (en-US), `DD.MM.YYYY` (de-DE),
|
|
81
|
+
* `YYYY/MM/DD` (ja-JP). Built from the locale's own separators and field order. */
|
|
82
|
+
export declare function dateFormatPattern(locale: string): string;
|
|
83
|
+
/** A date in the locale's canonical numeric form (2-digit month/day, 4-digit year,
|
|
84
|
+
* latin digits) — what the field shows once a typed or picked date resolves. */
|
|
85
|
+
export declare function formatDateInput(date: Temporal.PlainDate, locale: string): string;
|
|
86
|
+
/** Options for {@link parseDateInput}. */
|
|
87
|
+
export interface ParseDateOptions {
|
|
88
|
+
/** Earliest acceptable date; earlier input resolves to `null`. */
|
|
89
|
+
min?: Temporal.PlainDate | null;
|
|
90
|
+
/** Latest acceptable date; later input resolves to `null`. */
|
|
91
|
+
max?: Temporal.PlainDate | null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Recognize a date from free-form text, or return `null` when it can't. Lenient
|
|
95
|
+
* by design (the field lets you type anything, then resolves on blur):
|
|
96
|
+
*
|
|
97
|
+
* - ISO `YYYY-MM-DD`.
|
|
98
|
+
* - Numbers in any separator, mapped to day/month/year by the locale's order —
|
|
99
|
+
* `06/07/2026` is June 7 in en-US, July 6 in de-DE.
|
|
100
|
+
* - A month name plus a day and year (`15 Jun 2026`, `June 15 2026`).
|
|
101
|
+
* - Eight run-together digits, split by the locale order (`06152026` en-US).
|
|
102
|
+
* - Two numbers (day + month) take the current year; two-digit years pivot at 70.
|
|
103
|
+
*
|
|
104
|
+
* A real but out-of-`[min, max]` date returns `null` — the value stays uncommitted.
|
|
105
|
+
*/
|
|
106
|
+
export declare function parseDateInput(text: string, locale: string, opts?: ParseDateOptions): Temporal.PlainDate | null;
|
|
107
|
+
/** Recognize a wall-clock time from free-form text, or `null`. Accepts `14:30`,
|
|
108
|
+
* `9:5`, `230` / `1430` (run-together), and a 12-hour form with a meridiem
|
|
109
|
+
* (`2:30 pm`, `12am`), normalized to 24-hour. Minutes only (no seconds). */
|
|
110
|
+
export declare function parseTimeInput(text: string): Temporal.PlainTime | null;
|
|
111
|
+
/** Recognize a date-time from free-form text, or `null`. Peels a trailing time
|
|
112
|
+
* token that follows whitespace (`06/15/2026 14:30`, `June 15 2026 2:30pm`),
|
|
113
|
+
* parsing the rest as the date via {@link parseDateInput}; with no time token the
|
|
114
|
+
* time defaults to midnight. `min` / `max` bound the date (day-level). */
|
|
115
|
+
export declare function parseDateTimeInput(text: string, locale: string, opts?: ParseDateOptions): Temporal.PlainDateTime | null;
|
|
116
|
+
/** Whether a locale writes time in 12-hour form (AM/PM). `en-US` is `true`; most
|
|
117
|
+
* others (`en-GB`, `de-DE`, `ja-JP`, …) are `false`. Read from `Intl`'s resolved
|
|
118
|
+
* `hourCycle` (`h11`/`h12` → 12-hour). */
|
|
119
|
+
export declare function usesHour12(locale: string): boolean;
|
|
120
|
+
/** A date-time in the canonical display form: the locale's date plus the time in
|
|
121
|
+
* the given cycle — 24-hour `HH:mm` (`06/15/2026 14:30`) or 12-hour `hh:mm AM/PM`
|
|
122
|
+
* (`06/15/2026 02:30 PM`). `hour12` defaults to the locale's convention. */
|
|
123
|
+
export declare function formatDateTimeInput(dt: Temporal.PlainDateTime, locale: string, hour12?: boolean): string;
|
|
124
|
+
/** The placeholder mask for a date-time field: the date mask plus the time mask
|
|
125
|
+
* (`HH:MM`, or `HH:MM AM` in 12-hour locales). `hour12` defaults to the locale. */
|
|
126
|
+
export declare function dateTimeFormatPattern(locale: string, hour12?: boolean): string;
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { Temporal } from "temporal-polyfill";
|
|
2
|
+
const cmp = Temporal.PlainDate.compare;
|
|
3
|
+
const dtfCache = /* @__PURE__ */ new Map();
|
|
4
|
+
function dtf(locale, opts) {
|
|
5
|
+
const key = `${locale}|${JSON.stringify(opts)}`;
|
|
6
|
+
let f = dtfCache.get(key);
|
|
7
|
+
if (!f) {
|
|
8
|
+
f = new Intl.DateTimeFormat(locale, opts);
|
|
9
|
+
dtfCache.set(key, f);
|
|
10
|
+
}
|
|
11
|
+
return f;
|
|
12
|
+
}
|
|
13
|
+
const asUTCDate = (d) => new Date(Date.UTC(d.year, d.month - 1, d.day));
|
|
14
|
+
function parseISODate(value) {
|
|
15
|
+
if (!value) return null;
|
|
16
|
+
try {
|
|
17
|
+
return Temporal.PlainDate.from(value);
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function firstDayOfWeek(locale) {
|
|
23
|
+
try {
|
|
24
|
+
const loc = new Intl.Locale(locale);
|
|
25
|
+
const info = loc.getWeekInfo?.() ?? loc.weekInfo;
|
|
26
|
+
const fd = info?.firstDay;
|
|
27
|
+
if (typeof fd === "number" && fd >= 1 && fd <= 7) return fd;
|
|
28
|
+
} catch {
|
|
29
|
+
}
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
function clampDate(d, min, max) {
|
|
33
|
+
if (min && cmp(d, min) < 0) return min;
|
|
34
|
+
if (max && cmp(d, max) > 0) return max;
|
|
35
|
+
return d;
|
|
36
|
+
}
|
|
37
|
+
function isOutOfRange(d, min, max) {
|
|
38
|
+
return min != null && cmp(d, min) < 0 || max != null && cmp(d, max) > 0;
|
|
39
|
+
}
|
|
40
|
+
const twoLetter = (s) => Array.from(s).slice(0, 2).join("");
|
|
41
|
+
function getWeekdays(locale, firstDay = firstDayOfWeek(locale)) {
|
|
42
|
+
const ref = Temporal.PlainDate.from("2021-02-01");
|
|
43
|
+
const start = ref.add({ days: (firstDay - ref.dayOfWeek + 7) % 7 });
|
|
44
|
+
const shortFmt = dtf(locale, { weekday: "short", timeZone: "UTC" });
|
|
45
|
+
const longFmt = dtf(locale, { weekday: "long", timeZone: "UTC" });
|
|
46
|
+
const out = [];
|
|
47
|
+
for (let i = 0; i < 7; i++) {
|
|
48
|
+
const d = start.add({ days: i });
|
|
49
|
+
const short = shortFmt.format(asUTCDate(d));
|
|
50
|
+
out.push({
|
|
51
|
+
short,
|
|
52
|
+
narrow: twoLetter(short),
|
|
53
|
+
long: longFmt.format(asUTCDate(d)),
|
|
54
|
+
weekend: d.dayOfWeek === 6 || d.dayOfWeek === 7
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
function buildMonth(opts) {
|
|
60
|
+
const {
|
|
61
|
+
anchor,
|
|
62
|
+
locale = "en-US",
|
|
63
|
+
min = null,
|
|
64
|
+
max = null,
|
|
65
|
+
selected = null,
|
|
66
|
+
today = Temporal.Now.plainDateISO(),
|
|
67
|
+
weeks = 6
|
|
68
|
+
} = opts;
|
|
69
|
+
const fd = firstDayOfWeek(locale);
|
|
70
|
+
const year = anchor.year;
|
|
71
|
+
const month = anchor.month;
|
|
72
|
+
const firstOfMonth = anchor.with({ day: 1 });
|
|
73
|
+
const lead = (firstOfMonth.dayOfWeek - fd + 7) % 7;
|
|
74
|
+
const start = firstOfMonth.subtract({ days: lead });
|
|
75
|
+
const labelFmt = dtf(locale, {
|
|
76
|
+
weekday: "long",
|
|
77
|
+
year: "numeric",
|
|
78
|
+
month: "long",
|
|
79
|
+
day: "numeric",
|
|
80
|
+
timeZone: "UTC"
|
|
81
|
+
});
|
|
82
|
+
const grid = [];
|
|
83
|
+
for (let w = 0; w < weeks; w++) {
|
|
84
|
+
const row = [];
|
|
85
|
+
for (let i = 0; i < 7; i++) {
|
|
86
|
+
const date = start.add({ days: w * 7 + i });
|
|
87
|
+
row.push({
|
|
88
|
+
date,
|
|
89
|
+
iso: date.toString(),
|
|
90
|
+
day: date.day,
|
|
91
|
+
weekday: date.dayOfWeek,
|
|
92
|
+
outside: date.month !== month || date.year !== year,
|
|
93
|
+
disabled: isOutOfRange(date, min, max),
|
|
94
|
+
today: today != null && cmp(date, today) === 0,
|
|
95
|
+
selected: selected != null && cmp(date, selected) === 0,
|
|
96
|
+
label: labelFmt.format(asUTCDate(date))
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
grid.push(row);
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
year,
|
|
103
|
+
month,
|
|
104
|
+
heading: dtf(locale, { month: "long", year: "numeric", timeZone: "UTC" }).format(asUTCDate(anchor)),
|
|
105
|
+
weekdays: getWeekdays(locale, fd),
|
|
106
|
+
weeks: grid
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const FMT_SAMPLE = new Date(Date.UTC(2026, 5, 15));
|
|
110
|
+
const NUMERIC_DATE = {
|
|
111
|
+
year: "numeric",
|
|
112
|
+
month: "2-digit",
|
|
113
|
+
day: "2-digit",
|
|
114
|
+
timeZone: "UTC",
|
|
115
|
+
numberingSystem: "latn"
|
|
116
|
+
};
|
|
117
|
+
function fieldOrder(locale) {
|
|
118
|
+
try {
|
|
119
|
+
return dtf(locale, NUMERIC_DATE).formatToParts(FMT_SAMPLE).filter((p) => p.type === "year" || p.type === "month" || p.type === "day").map((p) => p.type);
|
|
120
|
+
} catch {
|
|
121
|
+
return ["year", "month", "day"];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function dateFormatPattern(locale) {
|
|
125
|
+
try {
|
|
126
|
+
return dtf(locale, NUMERIC_DATE).formatToParts(FMT_SAMPLE).map(
|
|
127
|
+
(p) => p.type === "year" ? "YYYY" : p.type === "month" ? "MM" : p.type === "day" ? "DD" : p.value
|
|
128
|
+
).join("");
|
|
129
|
+
} catch {
|
|
130
|
+
return "YYYY-MM-DD";
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function formatDateInput(date, locale) {
|
|
134
|
+
return dtf(locale, NUMERIC_DATE).format(asUTCDate(date));
|
|
135
|
+
}
|
|
136
|
+
function matchMonthName(text, locale) {
|
|
137
|
+
const alpha = text.toLowerCase().match(/[^\d\s.,/-]+/g);
|
|
138
|
+
if (!alpha) return null;
|
|
139
|
+
const long = dtf(locale, { month: "long", timeZone: "UTC" });
|
|
140
|
+
const short = dtf(locale, { month: "short", timeZone: "UTC" });
|
|
141
|
+
for (let mo = 1; mo <= 12; mo++) {
|
|
142
|
+
const d = new Date(Date.UTC(2020, mo - 1, 1));
|
|
143
|
+
const l = long.format(d).toLowerCase();
|
|
144
|
+
const s = short.format(d).toLowerCase().replace(/\.$/, "");
|
|
145
|
+
if (alpha.some((a) => a === l || a === s || a.length >= 3 && l.startsWith(a))) return mo;
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
function parseDateInput(text, locale, opts = {}) {
|
|
150
|
+
const accept = (d2) => isOutOfRange(d2, opts.min ?? null, opts.max ?? null) ? null : d2;
|
|
151
|
+
const s = (text ?? "").trim();
|
|
152
|
+
if (!s) return null;
|
|
153
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(s)) {
|
|
154
|
+
const iso = parseISODate(s);
|
|
155
|
+
return iso ? accept(iso) : null;
|
|
156
|
+
}
|
|
157
|
+
const order = fieldOrder(locale);
|
|
158
|
+
const month = matchMonthName(s, locale);
|
|
159
|
+
const nums = (s.match(/\d+/g) ?? []).map(Number);
|
|
160
|
+
let y;
|
|
161
|
+
let m;
|
|
162
|
+
let d;
|
|
163
|
+
if (month != null) {
|
|
164
|
+
m = month;
|
|
165
|
+
if (nums.length === 1) {
|
|
166
|
+
d = nums[0];
|
|
167
|
+
y = Temporal.Now.plainDateISO().year;
|
|
168
|
+
} else if (nums.length >= 2) {
|
|
169
|
+
const [a, b] = nums;
|
|
170
|
+
if (a > 31) [y, d] = [a, b];
|
|
171
|
+
else if (b > 31) [y, d] = [b, a];
|
|
172
|
+
else [d, y] = [a, b];
|
|
173
|
+
} else return null;
|
|
174
|
+
} else if (nums.length === 1) {
|
|
175
|
+
const digits = s.replace(/\D/g, "");
|
|
176
|
+
if (digits.length !== 8) return null;
|
|
177
|
+
let i = 0;
|
|
178
|
+
const seg = {};
|
|
179
|
+
for (const f of order) {
|
|
180
|
+
const w = f === "year" ? 4 : 2;
|
|
181
|
+
seg[f] = Number(digits.slice(i, i + w));
|
|
182
|
+
i += w;
|
|
183
|
+
}
|
|
184
|
+
;
|
|
185
|
+
({ year: y, month: m, day: d } = seg);
|
|
186
|
+
} else if (nums.length === 2) {
|
|
187
|
+
const dm = order.filter((f) => f !== "year");
|
|
188
|
+
const seg = {};
|
|
189
|
+
dm.forEach((f, i) => seg[f] = nums[i]);
|
|
190
|
+
m = seg.month;
|
|
191
|
+
d = seg.day;
|
|
192
|
+
y = Temporal.Now.plainDateISO().year;
|
|
193
|
+
} else if (nums.length >= 3) {
|
|
194
|
+
const seg = {};
|
|
195
|
+
order.forEach((f, i) => seg[f] = nums[i]);
|
|
196
|
+
y = seg.year;
|
|
197
|
+
m = seg.month;
|
|
198
|
+
d = seg.day;
|
|
199
|
+
} else return null;
|
|
200
|
+
if (y != null && y < 100) y = y < 70 ? 2e3 + y : 1900 + y;
|
|
201
|
+
try {
|
|
202
|
+
return accept(Temporal.PlainDate.from({ year: y, month: m, day: d }, { overflow: "reject" }));
|
|
203
|
+
} catch {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function parseTimeInput(text) {
|
|
208
|
+
let s = (text ?? "").trim().toLowerCase();
|
|
209
|
+
if (!s) return null;
|
|
210
|
+
let meridiem = null;
|
|
211
|
+
const mer = s.match(/([ap])\.?m?\.?$/);
|
|
212
|
+
if (mer) {
|
|
213
|
+
meridiem = mer[1] === "p" ? "pm" : "am";
|
|
214
|
+
s = s.slice(0, mer.index).trim();
|
|
215
|
+
}
|
|
216
|
+
let h;
|
|
217
|
+
let min;
|
|
218
|
+
if (/[:.]/.test(s)) {
|
|
219
|
+
const [hp, mp] = s.split(/[:.]/);
|
|
220
|
+
h = Number(hp);
|
|
221
|
+
min = Number(mp ?? "0");
|
|
222
|
+
} else {
|
|
223
|
+
const digits = s.replace(/\D/g, "");
|
|
224
|
+
if (!digits) return null;
|
|
225
|
+
if (digits.length <= 2) {
|
|
226
|
+
h = Number(digits);
|
|
227
|
+
min = 0;
|
|
228
|
+
} else {
|
|
229
|
+
const cut = digits.length - 2;
|
|
230
|
+
h = Number(digits.slice(0, cut));
|
|
231
|
+
min = Number(digits.slice(cut));
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (meridiem === "pm" && h < 12) h += 12;
|
|
235
|
+
if (meridiem === "am" && h === 12) h = 0;
|
|
236
|
+
try {
|
|
237
|
+
return Temporal.PlainTime.from({ hour: h, minute: min }, { overflow: "reject" });
|
|
238
|
+
} catch {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function parseDateTimeInput(text, locale, opts = {}) {
|
|
243
|
+
const s = (text ?? "").trim();
|
|
244
|
+
if (!s) return null;
|
|
245
|
+
const tm = s.match(/\s+(\d{1,2}[:.]\d{1,2}(?:\s*[ap]\.?m?\.?)?|\d{1,2}\s*[ap]\.?m\.?)\s*$/i);
|
|
246
|
+
let dateStr = s;
|
|
247
|
+
let time = null;
|
|
248
|
+
if (tm) {
|
|
249
|
+
time = parseTimeInput(tm[1]);
|
|
250
|
+
if (time) dateStr = s.slice(0, tm.index).trim();
|
|
251
|
+
}
|
|
252
|
+
const date = parseDateInput(dateStr, locale, opts);
|
|
253
|
+
if (!date) return null;
|
|
254
|
+
return date.toPlainDateTime(time ?? Temporal.PlainTime.from("00:00"));
|
|
255
|
+
}
|
|
256
|
+
function usesHour12(locale) {
|
|
257
|
+
try {
|
|
258
|
+
const hc = dtf(locale, { hour: "numeric" }).resolvedOptions().hourCycle;
|
|
259
|
+
return hc === "h11" || hc === "h12";
|
|
260
|
+
} catch {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function formatDateTimeInput(dt, locale, hour12 = usesHour12(locale)) {
|
|
265
|
+
const date = formatDateInput(dt.toPlainDate(), locale);
|
|
266
|
+
const mm = String(dt.minute).padStart(2, "0");
|
|
267
|
+
if (!hour12) return `${date} ${String(dt.hour).padStart(2, "0")}:${mm}`;
|
|
268
|
+
const h12 = (dt.hour + 11) % 12 + 1;
|
|
269
|
+
return `${date} ${String(h12).padStart(2, "0")}:${mm} ${dt.hour < 12 ? "AM" : "PM"}`;
|
|
270
|
+
}
|
|
271
|
+
function dateTimeFormatPattern(locale, hour12 = usesHour12(locale)) {
|
|
272
|
+
return `${dateFormatPattern(locale)} HH:MM${hour12 ? " AM" : ""}`;
|
|
273
|
+
}
|
|
274
|
+
export {
|
|
275
|
+
buildMonth,
|
|
276
|
+
clampDate,
|
|
277
|
+
dateFormatPattern,
|
|
278
|
+
dateTimeFormatPattern,
|
|
279
|
+
firstDayOfWeek,
|
|
280
|
+
formatDateInput,
|
|
281
|
+
formatDateTimeInput,
|
|
282
|
+
getWeekdays,
|
|
283
|
+
isOutOfRange,
|
|
284
|
+
parseDateInput,
|
|
285
|
+
parseDateTimeInput,
|
|
286
|
+
parseISODate,
|
|
287
|
+
parseTimeInput,
|
|
288
|
+
usesHour12
|
|
289
|
+
};
|
|
@@ -20,6 +20,10 @@ export type BaseButtonProps = {
|
|
|
20
20
|
disabled?: boolean;
|
|
21
21
|
/** Toggled-on / pressed state, e.g. for filter chips. */
|
|
22
22
|
selected?: boolean;
|
|
23
|
+
/** Fully-round corners — a pill for text buttons, a circle for icon-only ones
|
|
24
|
+
* (`border-radius: 999px`, clamped to the element's height). Pass a `number`
|
|
25
|
+
* (px) or a CSS length string (`'1rem'`) for a custom radius instead. */
|
|
26
|
+
round?: boolean | number | string;
|
|
23
27
|
/** Click handler. */
|
|
24
28
|
onClick?: (e: any) => void;
|
|
25
29
|
/** Tab order. The button is keyboard-focusable by default (`0`) and
|
|
@@ -29,6 +33,10 @@ export type BaseButtonProps = {
|
|
|
29
33
|
* fire it mid-flight.
|
|
30
34
|
* @defaultValue 0 */
|
|
31
35
|
tabIndex?: number;
|
|
36
|
+
/** ARIA role override (e.g. `'gridcell'` when a button is a cell in a grid).
|
|
37
|
+
* Forwarded to the underlying element.
|
|
38
|
+
* @defaultValue button */
|
|
39
|
+
role?: string;
|
|
32
40
|
};
|
|
33
41
|
/** Content axis — slots render in this order inside the button:
|
|
34
42
|
* `icon` → `label` → `children` → `iconTrailing`. Pass `icon` alone
|
|
@@ -113,4 +121,4 @@ export type ButtonProps = BaseButtonProps & PriorityMode & ContentMode & SubmitM
|
|
|
113
121
|
* <Button href="/docs" target="_blank" label="Read the docs" />
|
|
114
122
|
* ```
|
|
115
123
|
*/
|
|
116
|
-
export declare const Button: ({ priority, tone, underline, icon, iconTrailing, paddingless, label, size, loading, disabled, selected, href, type, form, className, style, children, ...rest }: ButtonProps) => any;
|
|
124
|
+
export declare const Button: ({ priority, tone, underline, icon, iconTrailing, paddingless, label, size, loading, disabled, selected, round, href, type, form, className, style, children, ...rest }: ButtonProps) => any;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { toneStyle, wrapLabel } from "../anta_helpers";
|
|
2
|
+
import { toneStyle, roundStyle, wrapLabel } from "../anta_helpers";
|
|
3
3
|
const Button = ({
|
|
4
4
|
priority,
|
|
5
5
|
tone,
|
|
@@ -12,6 +12,7 @@ const Button = ({
|
|
|
12
12
|
loading,
|
|
13
13
|
disabled,
|
|
14
14
|
selected,
|
|
15
|
+
round,
|
|
15
16
|
href,
|
|
16
17
|
type,
|
|
17
18
|
form,
|
|
@@ -21,7 +22,7 @@ const Button = ({
|
|
|
21
22
|
...rest
|
|
22
23
|
}) => {
|
|
23
24
|
const toneAttr = tone || void 0;
|
|
24
|
-
const computedStyle = toneStyle(toneAttr, "--button-tone-source", style);
|
|
25
|
+
const computedStyle = roundStyle(round, "--button-round", toneStyle(toneAttr, "--button-tone-source", style));
|
|
25
26
|
const isIconOnly = icon != null && label == null && children == null && iconTrailing == null;
|
|
26
27
|
const sharedAttrs = {
|
|
27
28
|
// `<a-button>` is a custom element with no implicit ARIA role, so AT would
|
|
@@ -41,6 +42,7 @@ const Button = ({
|
|
|
41
42
|
// presence (`[disabled]`, not `[disabled="true"]`), so any present form
|
|
42
43
|
// works. (ARIA attributes below stay string-valued — ARIA needs "true".)
|
|
43
44
|
paddingless: paddingless ? "" : void 0,
|
|
45
|
+
round: round ? "" : void 0,
|
|
44
46
|
loading: loading ? "" : void 0,
|
|
45
47
|
disabled: disabled ? "" : void 0,
|
|
46
48
|
selected: selected ? "" : void 0,
|
|
@@ -68,6 +70,7 @@ const Button = ({
|
|
|
68
70
|
"a",
|
|
69
71
|
{
|
|
70
72
|
href,
|
|
73
|
+
"data-anta": "",
|
|
71
74
|
...sharedAttrs,
|
|
72
75
|
...rest,
|
|
73
76
|
children: inner
|