@antadesign/anta 0.3.7 → 0.3.8

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.
@@ -1,211 +1 @@
1
- @layer anta {
2
- /* Host + token definitions for <a-card>. The visible box lives here (not in the
3
- shadow) so plain consumer CSS overrides it and it paints before the element
4
- upgrades; the shadow <style> owns layout + region typography and only
5
- REFERENCES these --card-* tokens with literal fallbacks. Named tones use
6
- Anta's theme-aware role tokens, so dark mode is mostly free (same as
7
- <a-expander> / <a-tag>); only the custom-tone branch needs a .dark re-tune. */
8
-
9
- a-card {
10
- /* Text roles: title = the strong foreground, text = the body (a step softer). */
11
- --card-title: var(--text-1);
12
- --card-text: var(--text-2);
13
-
14
- /* Surface pairs per priority. `primary` (the default) is a clean sheet —
15
- bg-1 in light, bg-4 in dark (see the `.dark` neutral rule), and
16
- bg-4-{tone} for a toned card; `secondary` is a subtle fill (bg-2);
17
- `tertiary` is a frosted panel (the primary surface, semi-transparent, +
18
- a backdrop blur — see below). */
19
- --card-bg-secondary: var(--bg-2);
20
- --card-bg-primary: var(--bg-1);
21
-
22
- /* `primary` is the default surface. */
23
- --card-bg: var(--card-bg-primary);
24
- /* Neutral edge hairline: text-2 at 10% (via --card-text). Toned cards override
25
- this with their border-4-{tone} in the tone rules below. Flat across
26
- priorities. */
27
- --card-border: color-mix(in oklch, var(--card-text) 10%, transparent);
28
-
29
- /* Selected ring (a 2px inset stroke) — the tone's strongest border. */
30
- --card-selected-ring: var(--border-1);
31
-
32
- /* Closed-surface hover lift for link cards: an oklch lightness bump that keeps
33
- hue + chroma, so it works for every priority and tone in light and dark
34
- (a transparent tertiary surface keeps zero alpha). Tune the amount here. */
35
- --card-bg-hover-lift: 0.01;
36
-
37
- --card-radius: 8px;
38
- --card-padding: 16px;
39
-
40
- display: block;
41
- box-sizing: border-box;
42
- /* Fill the container (grid cell / flex item / block) so width is always
43
- definite. This is also what keeps `container-type` below from collapsing
44
- the card to zero width in a shrink-to-fit context (a query container can't
45
- size to its own content). Same as <a-expander>. */
46
- width: 100%;
47
- /* Establish the card as a query container so both the shadow layout and
48
- consumer slotted content can `@container card (…)` on its width. */
49
- container-type: inline-size;
50
- container-name: card;
51
-
52
- color: var(--card-text);
53
- background: var(--card-bg);
54
- /* The edge is a 1px OUTSET shadow ring (spread 1px, no blur), not a border:
55
- it sits outside the box so full-bleed media reaches the very edge (no 1px
56
- border inset) and it never adds to layout. `overflow: clip` doesn't clip an
57
- element's own outset shadow, so the ring shows while the media still clips
58
- to the rounded corners. */
59
- box-shadow: 0 0 0 1px var(--card-border);
60
- border-radius: var(--card-radius);
61
- /* Clip full-bleed media to the rounded corners. */
62
- overflow: clip;
63
- }
64
-
65
- a-card[priority="secondary"] {
66
- --card-bg: var(--card-bg-secondary);
67
- }
68
-
69
- /* `round` re-points --card-radius, so both the host clip-radius and the shadow
70
- container's ring follow. Bare `round` → 999px (fully round, clamped to the
71
- box); a length (`round="16px"`, or the wrapper's `round={16}` → inline
72
- --card-round) sets a custom radius. The typed attr() covers raw-HTML authors. */
73
- a-card[round] {
74
- --card-round: attr(round type(<length>));
75
- --card-radius: var(--card-round, 999px);
76
- }
77
- a-card[priority="tertiary"] {
78
- /* Frosted glass: the primary surface at 1% over a backdrop blur, so the card
79
- reads over busy / colored / image backgrounds. It keeps the same hairline
80
- ring as the other priorities (no --card-border override). The blur only
81
- shows where there's detail behind it; the translucency reads everywhere. */
82
- --card-bg: color-mix(in oklch, var(--card-bg-primary) 1%, transparent);
83
- backdrop-filter: blur(8px);
84
- -webkit-backdrop-filter: blur(8px);
85
- }
86
-
87
- /* Neutral dark: bg-1 (primary's light surface) is pure black in dark mode, so
88
- step neutral primary up to bg-4. Secondary stays bg-2 via its token, and a
89
- toned card's --bg-*-{tone} tokens self-flip, so this is scoped to neutral. */
90
- .dark a-card:not([tone]),
91
- .dark a-card[tone="neutral"] {
92
- --card-bg-primary: var(--bg-4);
93
- }
94
-
95
- /* Hover lift, link cards only — gated so it doesn't stick after a tap. */
96
- @media (hover: hover) and (pointer: fine) {
97
- a-card[href]:not([loading]):hover {
98
- background: oklch(from var(--card-bg) calc(l + var(--card-bg-hover-lift)) c h);
99
- }
100
- }
101
-
102
- /* Pre-upgrade skeleton: the host border / background / radius already paint
103
- (they're defined here, not in the shadow), so only the content inset is
104
- missing before the shadow's .content exists — supply it here, then the
105
- shadow owns padding once :defined. */
106
- a-card:not(:defined) {
107
- padding: var(--card-padding);
108
- }
109
-
110
- /* A slotted heading node — <a-title> (any level) or a raw <h1>–<h6> — carries a
111
- document TOP margin (Title level 4 is 20px) that would add a leading gap in the
112
- header; zero it. The BOTTOM margin stays, so a heading header keeps its gap to
113
- the body. (A plain-STRING header has no margin of its own, so the `<Card>`
114
- wrapper wraps it in a div with the matching 8px bottom margin — CSS can't tell
115
- a string from a styled node, so that split lives in the wrapper.) Specificity
116
- is bumped past `a-title[level="N"]` (0,1,1) and the reset's `hN` (0,0,1);
117
- `@layer anta` keeps it overridable by un-layered CSS. */
118
- a-card :is(h1, h2, h3, h4, h5, h6),
119
- a-card a-title[level] {
120
- margin-block-start: 0;
121
- }
122
-
123
- /* Named tones — re-point the text roles + the per-priority surface pairs to the
124
- matching theme tokens (which self-flip for dark mode). */
125
- a-card[tone="brand"] {
126
- --card-title: var(--text-1-brand);
127
- --card-text: var(--text-2-brand);
128
- --card-bg-secondary: var(--bg-2-brand);
129
- --card-bg-primary: var(--bg-4-brand);
130
- --card-border: var(--border-4-brand);
131
- --card-selected-ring: var(--border-1-brand);
132
- }
133
- a-card[tone="info"] {
134
- --card-title: var(--text-1-info);
135
- --card-text: var(--text-2-info);
136
- --card-bg-secondary: var(--bg-2-info);
137
- --card-bg-primary: var(--bg-4-info);
138
- --card-border: var(--border-4-info);
139
- --card-selected-ring: var(--border-1-info);
140
- }
141
- a-card[tone="success"] {
142
- --card-title: var(--text-1-success);
143
- --card-text: var(--text-2-success);
144
- --card-bg-secondary: var(--bg-2-success);
145
- --card-bg-primary: var(--bg-4-success);
146
- --card-border: var(--border-4-success);
147
- --card-selected-ring: var(--border-1-success);
148
- }
149
- a-card[tone="warning"] {
150
- --card-title: var(--text-1-warning);
151
- --card-text: var(--text-2-warning);
152
- --card-bg-secondary: var(--bg-2-warning);
153
- --card-bg-primary: var(--bg-4-warning);
154
- --card-border: var(--border-4-warning);
155
- --card-selected-ring: var(--border-1-warning);
156
- }
157
- a-card[tone="critical"] {
158
- --card-title: var(--text-1-critical);
159
- --card-text: var(--text-2-critical);
160
- --card-bg-secondary: var(--bg-2-critical);
161
- --card-bg-primary: var(--bg-4-critical);
162
- --card-border: var(--border-4-critical);
163
- --card-selected-ring: var(--border-1-critical);
164
- }
165
-
166
- /* Custom tone — any non-named `tone` value keeps the source hue while
167
- lightness/chroma are pinned per token in oklch, the <a-expander> mechanism.
168
- The JSX wrapper writes --card-tone-source inline; the typed attr() fallback
169
- picks up raw <a-card tone="…"> on engines that support it. */
170
- a-card[tone]:not(
171
- [tone="neutral"],
172
- [tone="brand"],
173
- [tone="info"],
174
- [tone="success"],
175
- [tone="warning"],
176
- [tone="critical"]
177
- ) {
178
- --card-tone-source: attr(tone type(<color>), currentColor);
179
-
180
- --card-text: oklch(from var(--card-tone-source) 0.41 0.15 h);
181
- --card-title: oklch(from var(--card-tone-source) 0.33 0.15 h);
182
- --card-bg-secondary: oklch(from var(--card-tone-source) 0.99 0.006 h);
183
- --card-bg-primary: oklch(from var(--card-tone-source) 0.955 0.02 h);
184
- --card-border: oklch(from var(--card-tone-source) 0.895 0.045 h);
185
- --card-selected-ring: oklch(from var(--card-tone-source) 0.6 0.15 h);
186
- }
187
-
188
- .dark a-card[tone]:not(
189
- [tone="neutral"],
190
- [tone="brand"],
191
- [tone="info"],
192
- [tone="success"],
193
- [tone="warning"],
194
- [tone="critical"]
195
- ) {
196
- --card-text: oklch(from var(--card-tone-source) 0.75 0.11 h);
197
- --card-title: oklch(from var(--card-tone-source) 0.82 0.10 h);
198
- --card-bg-secondary: oklch(from var(--card-tone-source) 0.13 0.02 h);
199
- --card-bg-primary: oklch(from var(--card-tone-source) 0.19 0.04 h);
200
- --card-border: oklch(from var(--card-tone-source) 0.26 0.07 h);
201
- --card-selected-ring: oklch(from var(--card-tone-source) 0.7 0.13 h);
202
- }
203
-
204
- /* Size — padding scale (medium is the default, set on the base rule). */
205
- a-card[size="small"] {
206
- --card-padding: 12px;
207
- }
208
- a-card[size="large"] {
209
- --card-padding: 20px;
210
- }
211
- }
1
+ @layer anta{a-card{--card-text: var(--text-2);--card-bg-secondary: var(--bg-2);--card-bg-primary: var(--bg-1);--card-bg: var(--card-bg-primary);--card-border: var(--border-4);--card-border-hover: var(--border-3);--card-selected-ring: var(--border-1);--card-bg-hover-lift: .01;--card-radius: 8px;--card-padding: 12px;--card-content-fs: 15px;--card-content-lh: 20px;--card-icon-size: 40px;--card-icon-bg: var(--bg-4);--card-header-nudge: 2px;display:block;box-sizing:border-box;position:relative;width:100%;container-type:inline-size;container-name:card;color:var(--card-text);background:var(--card-bg);box-shadow:0 0 0 1px var(--card-border);border-radius:var(--card-radius);overflow:clip;transition:background-color .15s ease,box-shadow .15s ease,opacity .18s ease}a-card[priority=secondary]{--card-bg: var(--card-bg-secondary);--card-icon-blend: multiply}.dark a-card:not([priority=tertiary]){--card-icon-blend: exclusion}a-card[round]{--card-round: attr(round type(<length>));--card-radius: var(--card-round, 999px)}a-card[priority=tertiary]{--card-bg: color-mix(in oklch, var(--card-bg-primary) 1%, transparent);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.dark a-card:not([tone]),.dark a-card[tone=neutral]{--card-bg-primary: var(--bg-4);--card-icon-bg: var(--bg-5)}@media(hover:hover)and (pointer:fine){a-card[href]:not([loading]):hover{background:oklch(from var(--card-bg) calc(l + var(--card-bg-hover-lift)) c h)}a-card:not([loading]):hover{box-shadow:0 0 0 1px var(--card-border-hover)}}a-card[href]:not([loading]):active{box-shadow:0 0 0 1px var(--card-border)}@media(prefers-reduced-motion:reduce){a-card{transition:none}}a-card:not(:defined){padding:var(--card-padding);opacity:0}a-card:not(:has(>[slot=media]))::part(media),a-card:not(:has(>[slot=header])):not(:has(>[slot=icon]))::part(header),a-card:not(:has(>[slot=icon]))::part(icon),a-card:not(:has(>[slot=footer]))::part(footer),a-card:not(:has(>:not([slot])))::part(body){display:none}a-card:is(:has(>[slot=header]),:has(>[slot=icon]))::part(body){padding-block-start:0}a-card:has(>[slot=footer])::part(body){padding-block-end:0}a-card :is(h1,h2,h3,h4,h5,h6),a-card a-title[level]{margin-block-start:0}a-card>:is(h1,h2,h3,h4,h5,h6)[slot=header],a-card>a-title[slot=header]{margin-block-end:0}a-card>a-title[slot=header]+a-text[slot=header],a-card>:is(h1,h2,h3,h4,h5,h6)[slot=header]+a-text[slot=header]{margin-block-start:1px}a-card[size=large]>a-title[slot=header]+a-text[slot=header],a-card[size=large]>:is(h1,h2,h3,h4,h5,h6)[slot=header]+a-text[slot=header]{margin-block-start:2px}a-card[tone=brand]{--card-text: var(--text-2-brand);--card-bg-secondary: var(--bg-4-brand);--card-bg-primary: var(--bg-2-brand);--card-border: var(--border-4-brand);--card-border-hover: var(--border-3-brand);--card-icon-bg: var(--bg-5-brand);--card-selected-ring: var(--border-1-brand)}a-card[tone=info]{--card-text: var(--text-2-info);--card-bg-secondary: var(--bg-4-info);--card-bg-primary: var(--bg-2-info);--card-border: var(--border-4-info);--card-border-hover: var(--border-3-info);--card-icon-bg: var(--bg-5-info);--card-selected-ring: var(--border-1-info)}a-card[tone=success]{--card-text: var(--text-2-success);--card-bg-secondary: var(--bg-4-success);--card-bg-primary: var(--bg-2-success);--card-border: var(--border-4-success);--card-border-hover: var(--border-3-success);--card-icon-bg: var(--bg-5-success);--card-selected-ring: var(--border-1-success)}a-card[tone=warning]{--card-text: var(--text-2-warning);--card-bg-secondary: var(--bg-4-warning);--card-bg-primary: var(--bg-2-warning);--card-border: var(--border-4-warning);--card-border-hover: var(--border-3-warning);--card-icon-bg: var(--bg-5-warning);--card-selected-ring: var(--border-1-warning)}a-card[tone=critical]{--card-text: var(--text-2-critical);--card-bg-secondary: var(--bg-4-critical);--card-bg-primary: var(--bg-2-critical);--card-border: var(--border-4-critical);--card-border-hover: var(--border-3-critical);--card-icon-bg: var(--bg-5-critical);--card-selected-ring: var(--border-1-critical)}.dark a-card[tone=brand]{--card-bg-primary: var(--bg-4-brand);--card-bg-secondary: var(--bg-2-brand)}.dark a-card[tone=info]{--card-bg-primary: var(--bg-4-info);--card-bg-secondary: var(--bg-2-info)}.dark a-card[tone=success]{--card-bg-primary: var(--bg-4-success);--card-bg-secondary: var(--bg-2-success)}.dark a-card[tone=warning]{--card-bg-primary: var(--bg-4-warning);--card-bg-secondary: var(--bg-2-warning)}.dark a-card[tone=critical]{--card-bg-primary: var(--bg-4-critical);--card-bg-secondary: var(--bg-2-critical)}a-card[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--card-tone-source: attr(tone type(<color>), currentColor);--card-text: oklch(from var(--card-tone-source) .41 .15 h);--card-bg-secondary: oklch(from var(--card-tone-source) .955 .02 h);--card-bg-primary: oklch(from var(--card-tone-source) .99 .006 h);--card-icon-bg: oklch(from var(--card-tone-source) .925 .03 h);--card-border: oklch(from var(--card-tone-source) .895 .045 h);--card-border-hover: oklch(from var(--card-tone-source) .85 .06 h);--card-selected-ring: oklch(from var(--card-tone-source) .6 .15 h)}.dark a-card[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--card-text: oklch(from var(--card-tone-source) .75 .11 h);--card-bg-secondary: oklch(from var(--card-tone-source) .13 .02 h);--card-bg-primary: oklch(from var(--card-tone-source) .19 .04 h);--card-icon-bg: oklch(from var(--card-tone-source) .22 .05 h);--card-border: oklch(from var(--card-tone-source) .26 .07 h);--card-border-hover: oklch(from var(--card-tone-source) .32 .09 h);--card-selected-ring: oklch(from var(--card-tone-source) .7 .13 h)}a-card[priority=tertiary]{--card-icon-bg: var(--bg-3)}a-card[tone=brand][priority=tertiary]{--card-icon-bg: var(--bg-3-brand)}a-card[tone=info][priority=tertiary]{--card-icon-bg: var(--bg-3-info)}a-card[tone=success][priority=tertiary]{--card-icon-bg: var(--bg-3-success)}a-card[tone=warning][priority=tertiary]{--card-icon-bg: var(--bg-3-warning)}a-card[tone=critical][priority=tertiary]{--card-icon-bg: var(--bg-3-critical)}a-card[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=tertiary]{--card-icon-bg: oklch(from var(--card-tone-source) .97 .014 h)}.dark a-card[tone=brand][priority=tertiary]{--card-icon-bg: color-mix(in oklch, var(--bg-5-brand), white 10%)}.dark a-card[tone=info][priority=tertiary]{--card-icon-bg: color-mix(in oklch, var(--bg-5-info), white 10%)}.dark a-card[tone=success][priority=tertiary]{--card-icon-bg: color-mix(in oklch, var(--bg-5-success), white 10%)}.dark a-card[tone=warning][priority=tertiary]{--card-icon-bg: color-mix(in oklch, var(--bg-5-warning), white 10%)}.dark a-card[tone=critical][priority=tertiary]{--card-icon-bg: color-mix(in oklch, var(--bg-5-critical), white 10%)}.dark a-card:not([tone])[priority=tertiary],.dark a-card[tone=neutral][priority=tertiary]{--card-icon-bg: color-mix(in oklch, var(--bg-5), white 10%)}.dark a-card[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=tertiary]{--card-icon-bg: color-mix(in oklch, oklch(from var(--card-tone-source) .22 .05 h), white 10%)}a-card[size=small]{--card-padding: 8px;--card-header-nudge: 1px;--card-icon-size: 32px;--card-content-fs: 13px;--card-content-lh: 16px}a-card[size=large]{--card-padding: 16px;--card-header-nudge: 4px;--card-icon-size: 44px;--card-content-fs: 17px;--card-content-lh: 24px}}
@@ -26,10 +26,9 @@ const SHADOW_STYLE = `
26
26
  box-shadow: inset 0 0 0 1px transparent, inset 0 0 0 2px var(--focus-ring);
27
27
  }
28
28
 
29
- [part="media"] { display: none; }
30
- [part="media"].has-content { display: block; }
31
- :host([media-position="left"]) [part="media"].has-content,
32
- :host([media-position="right"]) [part="media"].has-content { flex: none; }
29
+ [part="media"] { display: block; }
30
+ :host([media-position="left"]) [part="media"],
31
+ :host([media-position="right"]) [part="media"] { flex: none; }
33
32
 
34
33
  .content {
35
34
  display: flex;
@@ -37,55 +36,49 @@ const SHADOW_STYLE = `
37
36
  flex: 1 1 auto;
38
37
  min-width: 0;
39
38
  min-height: 0;
40
- padding: var(--card-padding, 16px);
39
+ /* Base type for the content zone, matching the body <a-text> at this size. The
40
+ title / subtitle / body all set their own font, so this changes nothing
41
+ visible \u2014 it defines the em/ch base so the header gap (in ch) resolves against
42
+ the body's type size. */
43
+ font-size: var(--card-content-fs, 15px);
44
+ line-height: var(--card-content-lh, 20px);
41
45
  }
42
46
 
43
- .header-row { display: none; }
44
- .header-row.has-content {
47
+ .header {
45
48
  display: flex;
46
- align-items: flex-start;
47
- gap: 8px;
49
+ align-items: center;
50
+ gap: 1ch;
51
+ padding: var(--card-padding, 12px);
52
+ padding-block-start: calc(var(--card-padding, 12px) - var(--card-header-nudge, 1px));
53
+ padding-block-end: calc(var(--card-padding, 12px) / 2);
48
54
  }
49
-
50
- slot[name="header"] { display: none; }
51
- slot[name="header"].has-content {
55
+ slot[name="icon"] {
56
+ flex: none;
57
+ display: flex;
58
+ align-items: center;
59
+ /* Off by default; secondary cards in light multiply the chip into the deeper
60
+ surface (see --card-icon-blend in the external sheet). */
61
+ mix-blend-mode: var(--card-icon-blend, normal);
62
+ }
63
+ slot[name="header"] {
52
64
  display: block;
53
65
  flex: 1 1 auto;
54
66
  min-width: 0;
55
- font-size: 17px;
56
- line-height: 20px;
57
- font-weight: 584.62;
58
- letter-spacing: 0;
59
- font-feature-settings: 'ss02', 'ss05', 'tnum';
60
- color: var(--card-title, var(--text-1));
61
67
  }
62
-
63
- slot[name="actions"] { display: none; }
64
- slot[name="actions"].has-content {
65
- display: flex;
66
- align-items: center;
67
- gap: 4px;
68
- flex: none;
69
- }
70
-
71
68
  slot[part="body"] {
72
69
  display: block;
73
70
  flex: 1 1 auto;
74
71
  min-width: 0;
75
72
  min-height: 0;
76
- font-size: 15px;
77
- line-height: 20px;
78
- color: var(--card-text, var(--text-2));
73
+ padding: var(--card-padding, 12px);
79
74
  }
80
-
81
- slot[name="footer"] { display: none; }
82
- slot[name="footer"].has-content {
75
+ slot[name="footer"] {
83
76
  display: flex;
84
77
  align-items: center;
85
78
  gap: 8px;
86
79
  flex-wrap: wrap;
87
80
  justify-content: flex-start;
88
- padding-block-start: var(--card-padding, 16px);
81
+ padding: var(--card-padding, 12px);
89
82
  }
90
83
 
91
84
  :host([selected]) .container { box-shadow: inset 0 0 0 2px var(--card-selected-ring, var(--focus-ring)); }
@@ -100,12 +93,8 @@ const SHADOW_STYLE = `
100
93
  class ACardElement extends HTMLElementBase {
101
94
  static observedAttributes = ["href", "target", "rel", "ping", "loading", "aria-label"];
102
95
  #container;
103
- #mediaSlot;
104
- #headerRow;
105
96
  #headerSlot;
106
- #actionsSlot;
107
97
  #bodySlot;
108
- #footerSlot;
109
98
  constructor() {
110
99
  super();
111
100
  const shadow = this.attachShadow({ mode: "open" });
@@ -114,56 +103,39 @@ class ACardElement extends HTMLElementBase {
114
103
  this.#container = document.createElement("a");
115
104
  this.#container.className = "container";
116
105
  this.#container.setAttribute("part", "container");
117
- this.#mediaSlot = document.createElement("slot");
118
- this.#mediaSlot.name = "media";
119
- this.#mediaSlot.setAttribute("part", "media");
106
+ const mediaSlot = document.createElement("slot");
107
+ mediaSlot.name = "media";
108
+ mediaSlot.setAttribute("part", "media");
120
109
  const content = document.createElement("div");
121
110
  content.className = "content";
122
111
  content.setAttribute("part", "content");
123
- this.#headerRow = document.createElement("div");
124
- this.#headerRow.className = "header-row";
112
+ const headerSection = document.createElement("div");
113
+ headerSection.className = "header";
114
+ headerSection.setAttribute("part", "header");
115
+ const iconSlot = document.createElement("slot");
116
+ iconSlot.name = "icon";
117
+ iconSlot.setAttribute("part", "icon");
125
118
  this.#headerSlot = document.createElement("slot");
126
119
  this.#headerSlot.name = "header";
127
- this.#headerSlot.setAttribute("part", "header");
128
- this.#actionsSlot = document.createElement("slot");
129
- this.#actionsSlot.name = "actions";
130
- this.#actionsSlot.setAttribute("part", "actions");
120
+ this.#headerSlot.setAttribute("part", "title");
121
+ headerSection.append(iconSlot, this.#headerSlot);
131
122
  this.#bodySlot = document.createElement("slot");
132
123
  this.#bodySlot.setAttribute("part", "body");
133
- this.#footerSlot = document.createElement("slot");
134
- this.#footerSlot.name = "footer";
135
- this.#footerSlot.setAttribute("part", "footer");
136
- this.#headerRow.append(this.#headerSlot, this.#actionsSlot);
137
- content.append(this.#headerRow, this.#bodySlot, this.#footerSlot);
138
- this.#container.append(this.#mediaSlot, content);
124
+ const footerSlot = document.createElement("slot");
125
+ footerSlot.name = "footer";
126
+ footerSlot.setAttribute("part", "footer");
127
+ content.append(headerSection, this.#bodySlot, footerSlot);
128
+ this.#container.append(mediaSlot, content);
139
129
  shadow.append(style, this.#container);
140
- this.#mediaSlot.addEventListener("slotchange", () => this.#syncHasContent());
141
- this.#footerSlot.addEventListener("slotchange", () => this.#syncHasContent());
142
- this.#actionsSlot.addEventListener("slotchange", () => this.#syncHasContent());
143
- this.#headerSlot.addEventListener("slotchange", () => {
144
- this.#syncHasContent();
145
- this.#syncName();
146
- });
130
+ this.#headerSlot.addEventListener("slotchange", () => this.#syncName());
147
131
  this.#bodySlot.addEventListener("slotchange", () => this.#syncName());
148
132
  }
149
133
  connectedCallback() {
150
- this.#syncHasContent();
151
134
  this.#syncLink();
152
135
  }
153
136
  attributeChangedCallback() {
154
137
  this.#syncLink();
155
138
  }
156
- /** Toggle the per-zone `has-content` classes (empty zones reserve no box). */
157
- #syncHasContent() {
158
- const set = (el, has) => el.classList.toggle("has-content", has);
159
- set(this.#mediaSlot, this.#mediaSlot.assignedNodes().length > 0);
160
- set(this.#footerSlot, this.#footerSlot.assignedNodes().length > 0);
161
- const header = this.#headerSlot.assignedNodes().length > 0;
162
- const actions = this.#actionsSlot.assignedNodes().length > 0;
163
- set(this.#headerSlot, header);
164
- set(this.#actionsSlot, actions);
165
- set(this.#headerRow, header || actions);
166
- }
167
139
  /** Mirror the link attributes onto the shadow anchor — but drop `href` while
168
140
  * `loading` so a loading card can't navigate. Also reflects `aria-busy`. */
169
141
  #syncLink() {
@@ -80,8 +80,6 @@ class ACheckboxElement extends HTMLElementBase {
80
80
  const ok = this.dispatchEvent(
81
81
  new CustomEvent("statechange", {
82
82
  cancelable: true,
83
- bubbles: true,
84
- composed: true,
85
83
  detail: { next, prev }
86
84
  })
87
85
  );
@@ -23,7 +23,9 @@ export declare class ARadioGroupElement extends HTMLElementBase {
23
23
  private emitChange;
24
24
  /** Dispatch the shared `statechange` event. `reason` lets a controller tell a
25
25
  * user pick (cancelable) apart from a form `reset` / bfcache `restore` (not).
26
- * `next` is `null` when nothing is selected (no default / reset-to-none). */
26
+ * `next` is `null` when nothing is selected (no default / reset-to-none).
27
+ * Neither bubbles nor composed — a point-to-point request to this element's
28
+ * own wrapper, not a notification (see STATEFUL-COMPONENTS.md). */
27
29
  private emitStateChange;
28
30
  private onClick;
29
31
  private onKeyDown;
@@ -102,13 +102,13 @@ class ARadioGroupElement extends HTMLElementBase {
102
102
  }
103
103
  /** Dispatch the shared `statechange` event. `reason` lets a controller tell a
104
104
  * user pick (cancelable) apart from a form `reset` / bfcache `restore` (not).
105
- * `next` is `null` when nothing is selected (no default / reset-to-none). */
105
+ * `next` is `null` when nothing is selected (no default / reset-to-none).
106
+ * Neither bubbles nor composed — a point-to-point request to this element's
107
+ * own wrapper, not a notification (see STATEFUL-COMPONENTS.md). */
106
108
  emitStateChange(next, prev, reason, cancelable) {
107
109
  return this.dispatchEvent(
108
110
  new CustomEvent("statechange", {
109
111
  cancelable,
110
- bubbles: true,
111
- composed: true,
112
112
  detail: { next, prev, reason }
113
113
  })
114
114
  );
@@ -20,7 +20,9 @@ export declare class ATabsElement extends HTMLElementBase {
20
20
  private requestSelect;
21
21
  private emitChange;
22
22
  /** Dispatch the shared cancelable `statechange`. `next`/`prev` are values
23
- * (`null` when nothing is selected). Returns false if a listener vetoed. */
23
+ * (`null` when nothing is selected). Returns false if a listener vetoed.
24
+ * Neither bubbles nor composed — a point-to-point request to this element's
25
+ * own wrapper, not a notification (see STATEFUL-COMPONENTS.md). */
24
26
  private emitStateChange;
25
27
  private onClick;
26
28
  private onKeyDown;
@@ -96,13 +96,13 @@ class ATabsElement extends HTMLElementBase {
96
96
  this.dispatchEvent(new Event("change", { bubbles: true }));
97
97
  }
98
98
  /** Dispatch the shared cancelable `statechange`. `next`/`prev` are values
99
- * (`null` when nothing is selected). Returns false if a listener vetoed. */
99
+ * (`null` when nothing is selected). Returns false if a listener vetoed.
100
+ * Neither bubbles nor composed — a point-to-point request to this element's
101
+ * own wrapper, not a notification (see STATEFUL-COMPONENTS.md). */
100
102
  emitStateChange(next, prev) {
101
103
  return this.dispatchEvent(
102
104
  new CustomEvent("statechange", {
103
105
  cancelable: true,
104
- bubbles: true,
105
- composed: true,
106
106
  detail: { next, prev }
107
107
  })
108
108
  );
@@ -1 +1 @@
1
- @layer anta{a-text{--text-color: var(--text-2);--text-link-color: var(--link-color);--text-link-hover: var(--link-color-hover);display:block;color:var(--text-color);font-size:15px;line-height:20px;text-wrap:pretty;font-feature-settings:"ss02","ss05","tnum"}a-text[size=small]{font-size:13px;line-height:16px}a-text[size=medium]{font-size:15px;line-height:20px}a-text[size=large]{font-size:17px;line-height:24px}a-text[inline]{display:inline-block}a-text[truncate]{min-width:0}a-text[priority=primary]{--text-color: var(--text-1)}a-text[priority=tertiary]{--text-color: var(--text-3);--text-link-color: currentColor;--text-link-hover: var(--text-2)}a-text[priority=quaternary]{--text-color: var(--text-4);--text-link-color: currentColor;--text-link-hover: var(--text-3)}a-text[priority=quinary]{--text-color: var(--text-5);--text-link-color: currentColor;--text-link-hover: var(--text-4)}a-text[tone=brand]{--text-color: var(--text-2-brand);--text-link-color: currentColor;--text-link-hover: var(--text-1-brand)}a-text[tone=brand][priority=primary]{--text-color: var(--text-1-brand)}a-text[tone=brand][priority=tertiary]{--text-color: var(--text-3-brand);--text-link-hover: var(--text-2-brand)}a-text[tone=brand][priority=quaternary]{--text-color: var(--text-4-brand);--text-link-hover: var(--text-3-brand)}a-text[tone=brand][priority=quinary]{--text-color: var(--text-5-brand);--text-link-hover: var(--text-4-brand)}a-text[tone=success]{--text-color: var(--text-2-success);--text-link-color: currentColor;--text-link-hover: var(--text-1-success)}a-text[tone=success][priority=primary]{--text-color: var(--text-1-success)}a-text[tone=success][priority=tertiary]{--text-color: var(--text-3-success);--text-link-hover: var(--text-2-success)}a-text[tone=success][priority=quaternary]{--text-color: var(--text-4-success);--text-link-hover: var(--text-3-success)}a-text[tone=success][priority=quinary]{--text-color: var(--text-5-success);--text-link-hover: var(--text-4-success)}a-text[tone=critical]{--text-color: var(--text-2-critical);--text-link-color: currentColor;--text-link-hover: var(--text-1-critical)}a-text[tone=critical][priority=primary]{--text-color: var(--text-1-critical)}a-text[tone=critical][priority=tertiary]{--text-color: var(--text-3-critical);--text-link-hover: var(--text-2-critical)}a-text[tone=critical][priority=quaternary]{--text-color: var(--text-4-critical);--text-link-hover: var(--text-3-critical)}a-text[tone=critical][priority=quinary]{--text-color: var(--text-5-critical);--text-link-hover: var(--text-4-critical)}a-text[tone=warning]{--text-color: var(--text-2-warning);--text-link-color: currentColor;--text-link-hover: var(--text-1-warning)}a-text[tone=warning][priority=primary]{--text-color: var(--text-1-warning)}a-text[tone=warning][priority=tertiary]{--text-color: var(--text-3-warning);--text-link-hover: var(--text-2-warning)}a-text[tone=warning][priority=quaternary]{--text-color: var(--text-4-warning);--text-link-hover: var(--text-3-warning)}a-text[tone=warning][priority=quinary]{--text-color: var(--text-5-warning);--text-link-hover: var(--text-4-warning)}a-text[tone=info]{--text-color: var(--text-2-info);--text-link-color: currentColor;--text-link-hover: var(--text-1-info)}a-text[tone=info][priority=primary]{--text-color: var(--text-1-info)}a-text[tone=info][priority=tertiary]{--text-color: var(--text-3-info);--text-link-hover: var(--text-2-info)}a-text[tone=info][priority=quaternary]{--text-color: var(--text-4-info);--text-link-hover: var(--text-3-info)}a-text[tone=info][priority=quinary]{--text-color: var(--text-5-info);--text-link-hover: var(--text-4-info)}a-text a,a-text a:link,a-text a:visited{color:var(--text-link-color)}@media(hover:hover)and (pointer:fine){a-text a:hover{color:var(--text-link-hover);text-decoration-color:var(--text-link-hover)}}}
1
+ @layer anta{a-text{--text-color: var(--text-2);--text-link-color: var(--link-color);--text-link-hover: var(--link-color-hover);display:block;color:var(--text-color);font-size:15px;line-height:20px;text-wrap:pretty;font-feature-settings:"ss02","ss05","tnum"}a-text[size=small]{font-size:13px;line-height:16px}a-text[size=medium]{font-size:15px;line-height:20px}a-text[size=large]{font-size:17px;line-height:24px}a-text[inline]{display:inline-block}a-text[truncate]{min-width:0}a-text[priority=primary]{--text-color: var(--text-1)}a-text[priority=tertiary]{--text-color: var(--text-3);--text-link-color: currentColor;--text-link-hover: var(--text-2)}a-text[priority=quaternary]{--text-color: var(--text-4);--text-link-color: currentColor;--text-link-hover: var(--text-3)}a-text[priority=quinary]{--text-color: var(--text-5);--text-link-color: currentColor;--text-link-hover: var(--text-4)}a-text[tone=brand]{--text-color: var(--text-2-brand);--text-link-color: currentColor;--text-link-hover: var(--text-1-brand)}a-text[tone=brand][priority=primary]{--text-color: var(--text-1-brand)}a-text[tone=brand][priority=tertiary]{--text-color: var(--text-3-brand);--text-link-hover: var(--text-2-brand)}a-text[tone=brand][priority=quaternary]{--text-color: var(--text-4-brand);--text-link-hover: var(--text-3-brand)}a-text[tone=brand][priority=quinary]{--text-color: var(--text-5-brand);--text-link-hover: var(--text-4-brand)}a-text[tone=success]{--text-color: var(--text-2-success);--text-link-color: currentColor;--text-link-hover: var(--text-1-success)}a-text[tone=success][priority=primary]{--text-color: var(--text-1-success)}a-text[tone=success][priority=tertiary]{--text-color: var(--text-3-success);--text-link-hover: var(--text-2-success)}a-text[tone=success][priority=quaternary]{--text-color: var(--text-4-success);--text-link-hover: var(--text-3-success)}a-text[tone=success][priority=quinary]{--text-color: var(--text-5-success);--text-link-hover: var(--text-4-success)}a-text[tone=critical]{--text-color: var(--text-2-critical);--text-link-color: currentColor;--text-link-hover: var(--text-1-critical)}a-text[tone=critical][priority=primary]{--text-color: var(--text-1-critical)}a-text[tone=critical][priority=tertiary]{--text-color: var(--text-3-critical);--text-link-hover: var(--text-2-critical)}a-text[tone=critical][priority=quaternary]{--text-color: var(--text-4-critical);--text-link-hover: var(--text-3-critical)}a-text[tone=critical][priority=quinary]{--text-color: var(--text-5-critical);--text-link-hover: var(--text-4-critical)}a-text[tone=warning]{--text-color: var(--text-2-warning);--text-link-color: currentColor;--text-link-hover: var(--text-1-warning)}a-text[tone=warning][priority=primary]{--text-color: var(--text-1-warning)}a-text[tone=warning][priority=tertiary]{--text-color: var(--text-3-warning);--text-link-hover: var(--text-2-warning)}a-text[tone=warning][priority=quaternary]{--text-color: var(--text-4-warning);--text-link-hover: var(--text-3-warning)}a-text[tone=warning][priority=quinary]{--text-color: var(--text-5-warning);--text-link-hover: var(--text-4-warning)}a-text[tone=info]{--text-color: var(--text-2-info);--text-link-color: currentColor;--text-link-hover: var(--text-1-info)}a-text[tone=info][priority=primary]{--text-color: var(--text-1-info)}a-text[tone=info][priority=tertiary]{--text-color: var(--text-3-info);--text-link-hover: var(--text-2-info)}a-text[tone=info][priority=quaternary]{--text-color: var(--text-4-info);--text-link-hover: var(--text-3-info)}a-text[tone=info][priority=quinary]{--text-color: var(--text-5-info);--text-link-hover: var(--text-4-info)}a-text[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--text-tone-source: attr(tone type(<color>), currentColor);--_text-tone: oklch(from var(--text-tone-source) .41 .15 h);--text-color: var(--_text-tone);--text-link-color: currentColor;--text-link-hover: oklch(from var(--text-tone-source) .33 .15 h)}a-text[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=primary]{--text-color: oklch(from var(--text-tone-source) .33 .15 h)}a-text[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=tertiary]{--text-color: color-mix(in oklch, var(--_text-tone) 80%, transparent);--text-link-hover: var(--_text-tone)}a-text[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=quaternary]{--text-color: color-mix(in oklch, var(--_text-tone) 60%, transparent)}a-text[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=quinary]{--text-color: color-mix(in oklch, var(--_text-tone) 40%, transparent)}.dark a-text[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--_text-tone: oklch(from var(--text-tone-source) .75 .11 h);--text-link-hover: oklch(from var(--text-tone-source) .82 .1 h)}.dark a-text[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=primary]{--text-color: oklch(from var(--text-tone-source) .82 .1 h)}a-text a,a-text a:link,a-text a:visited{color:var(--text-link-color)}@media(hover:hover)and (pointer:fine){a-text a:hover{color:var(--text-link-hover);text-decoration-color:var(--text-link-hover)}}}
@@ -1 +1 @@
1
- @layer anta{a-title{display:block;color:var(--text-1);font-weight:584.62;letter-spacing:0;text-wrap:balance;font-feature-settings:"ss02","ss05","tnum"}a-title a-icon{transform:translateY(-.05em)}a-title[level="1"]{font-size:28px;line-height:32px;margin-block-start:0;margin-block-end:16px}a-title[level="2"]{font-size:24px;line-height:28px;margin-block-start:32px;margin-block-end:12px}a-title[level="3"]{font-size:20px;line-height:24px;margin-block-start:24px;margin-block-end:12px}a-title[level="4"]{font-size:17px;line-height:20px;margin-block-start:20px;margin-block-end:8px}a-title[level="5"]{font-size:15px;line-height:20px;margin-block-start:16px;margin-block-end:8px}a-title[level="6"]{font-size:13px;line-height:16px;margin-block-start:16px;margin-block-end:4px}a-title[priority=secondary]{color:var(--text-2)}a-title[priority=tertiary]{color:var(--text-3)}a-title[priority=quaternary]{color:var(--text-4)}a-title[priority=quinary]{color:var(--text-5)}a-title[tone=brand]{color:var(--text-1-brand)}a-title[tone=brand][priority=secondary]{color:var(--text-2-brand)}a-title[tone=brand][priority=tertiary]{color:var(--text-3-brand)}a-title[tone=brand][priority=quaternary]{color:var(--text-4-brand)}a-title[tone=brand][priority=quinary]{color:var(--text-5-brand)}a-title[tone=success]{color:var(--text-1-success)}a-title[tone=success][priority=secondary]{color:var(--text-2-success)}a-title[tone=success][priority=tertiary]{color:var(--text-3-success)}a-title[tone=success][priority=quaternary]{color:var(--text-4-success)}a-title[tone=success][priority=quinary]{color:var(--text-5-success)}a-title[tone=critical]{color:var(--text-1-critical)}a-title[tone=critical][priority=secondary]{color:var(--text-2-critical)}a-title[tone=critical][priority=tertiary]{color:var(--text-3-critical)}a-title[tone=critical][priority=quaternary]{color:var(--text-4-critical)}a-title[tone=critical][priority=quinary]{color:var(--text-5-critical)}a-title[tone=warning]{color:var(--text-1-warning)}a-title[tone=warning][priority=secondary]{color:var(--text-2-warning)}a-title[tone=warning][priority=tertiary]{color:var(--text-3-warning)}a-title[tone=warning][priority=quaternary]{color:var(--text-4-warning)}a-title[tone=warning][priority=quinary]{color:var(--text-5-warning)}a-title[tone=info]{color:var(--text-1-info)}a-title[tone=info][priority=secondary]{color:var(--text-2-info)}a-title[tone=info][priority=tertiary]{color:var(--text-3-info)}a-title[tone=info][priority=quaternary]{color:var(--text-4-info)}a-title[tone=info][priority=quinary]{color:var(--text-5-info)}}
1
+ @layer anta{a-title{display:block;color:var(--text-1);font-weight:584.62;letter-spacing:0;text-wrap:balance;font-feature-settings:"ss02","ss05","tnum"}a-title a-icon{transform:translateY(-.05em)}a-title[level="1"]{font-size:28px;line-height:32px;margin-block-start:0;margin-block-end:16px}a-title[level="2"]{font-size:24px;line-height:28px;margin-block-start:32px;margin-block-end:12px}a-title[level="3"]{font-size:20px;line-height:24px;margin-block-start:24px;margin-block-end:12px}a-title[level="4"]{font-size:17px;line-height:20px;margin-block-start:20px;margin-block-end:8px}a-title[level="5"]{font-size:15px;line-height:20px;margin-block-start:16px;margin-block-end:8px}a-title[level="6"]{font-size:13px;line-height:16px;margin-block-start:16px;margin-block-end:4px}a-title[priority=secondary]{color:var(--text-2)}a-title[priority=tertiary]{color:var(--text-3)}a-title[priority=quaternary]{color:var(--text-4)}a-title[priority=quinary]{color:var(--text-5)}a-title[tone=brand]{color:var(--text-1-brand)}a-title[tone=brand][priority=secondary]{color:var(--text-2-brand)}a-title[tone=brand][priority=tertiary]{color:var(--text-3-brand)}a-title[tone=brand][priority=quaternary]{color:var(--text-4-brand)}a-title[tone=brand][priority=quinary]{color:var(--text-5-brand)}a-title[tone=success]{color:var(--text-1-success)}a-title[tone=success][priority=secondary]{color:var(--text-2-success)}a-title[tone=success][priority=tertiary]{color:var(--text-3-success)}a-title[tone=success][priority=quaternary]{color:var(--text-4-success)}a-title[tone=success][priority=quinary]{color:var(--text-5-success)}a-title[tone=critical]{color:var(--text-1-critical)}a-title[tone=critical][priority=secondary]{color:var(--text-2-critical)}a-title[tone=critical][priority=tertiary]{color:var(--text-3-critical)}a-title[tone=critical][priority=quaternary]{color:var(--text-4-critical)}a-title[tone=critical][priority=quinary]{color:var(--text-5-critical)}a-title[tone=warning]{color:var(--text-1-warning)}a-title[tone=warning][priority=secondary]{color:var(--text-2-warning)}a-title[tone=warning][priority=tertiary]{color:var(--text-3-warning)}a-title[tone=warning][priority=quaternary]{color:var(--text-4-warning)}a-title[tone=warning][priority=quinary]{color:var(--text-5-warning)}a-title[tone=info]{color:var(--text-1-info)}a-title[tone=info][priority=secondary]{color:var(--text-2-info)}a-title[tone=info][priority=tertiary]{color:var(--text-3-info)}a-title[tone=info][priority=quaternary]{color:var(--text-4-info)}a-title[tone=info][priority=quinary]{color:var(--text-5-info)}a-title[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--title-tone-source: attr(tone type(<color>), currentColor);--_title-tone: oklch(from var(--title-tone-source) .41 .15 h);color:oklch(from var(--title-tone-source) .33 .15 h)}a-title[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=secondary]{color:var(--_title-tone)}a-title[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=tertiary]{color:color-mix(in oklch,var(--_title-tone) 80%,transparent)}a-title[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=quaternary]{color:color-mix(in oklch,var(--_title-tone) 60%,transparent)}a-title[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical])[priority=quinary]{color:color-mix(in oklch,var(--_title-tone) 40%,transparent)}.dark a-title[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--_title-tone: oklch(from var(--title-tone-source) .75 .11 h);color:oklch(from var(--title-tone-source) .82 .1 h)}}
@@ -33,5 +33,6 @@ export { ATabElement, register_a_tab } from './a-tab';
33
33
  export { ATabsElement, register_a_tabs } from './a-tabs';
34
34
  export { ATabPanelElement, register_a_tabpanel } from './a-tabpanel';
35
35
  export { ADialogElement, register_a_dialog } from './a-dialog';
36
+ export { ACardElement, register_a_card } from './a-card';
36
37
  import './a-title.css';
37
38
  import './a-tag.css';
@@ -18,11 +18,13 @@ import { ATabElement, register_a_tab } from "./a-tab";
18
18
  import { ATabsElement, register_a_tabs } from "./a-tabs";
19
19
  import { ATabPanelElement, register_a_tabpanel } from "./a-tabpanel";
20
20
  import { ADialogElement, register_a_dialog } from "./a-dialog";
21
+ import { ACardElement, register_a_card } from "./a-card";
21
22
  import "./a-title.css";
22
23
  import "./a-tag.css";
23
24
  export {
24
25
  AButtonElement,
25
26
  ACalendarElement,
27
+ ACardElement,
26
28
  ACheckboxElement,
27
29
  ADialogElement,
28
30
  AExpanderElement,
@@ -43,6 +45,7 @@ export {
43
45
  ATooltipElement,
44
46
  register_a_button,
45
47
  register_a_calendar,
48
+ register_a_card,
46
49
  register_a_checkbox,
47
50
  register_a_dialog,
48
51
  register_a_expander,
@@ -11,6 +11,9 @@ export interface BaseProps {
11
11
  id?: string;
12
12
  /** HTML `title` attribute — native browser tooltip on hover. */
13
13
  title?: string;
14
+ /** Assigns the element to a named `<slot>` of a parent web component (e.g.
15
+ * `slot="header"` inside a `<Card>`, `slot="footer"` inside a `<Dialog>`). */
16
+ slot?: string;
14
17
  /** Tab order. Set to `-1` to skip the element when tabbing. */
15
18
  tabIndex?: number;
16
19
  /** React/Preact reconciliation key when rendered inside a list. Consumed by the
@@ -171,9 +174,10 @@ export interface AProgressAttributes extends BaseAttributes {
171
174
  export interface ATextAttributes extends BaseAttributes {
172
175
  /** Visual priority. Maps to text-1..text-5. */
173
176
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
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';
177
+ /** Color tint. `neutral` (default) is the untinted `--text-{N}` scale; a named
178
+ * tone applies the matching `--text-{N}-{tone}` palette; any literal CSS color
179
+ * is a custom tone (hue kept, lightness/chroma pinned per priority in oklch). */
180
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
177
181
  /** Type scale. `small` = 13/16, `medium` (default) = 15/20, `large` = 17/24. */
178
182
  size?: 'small' | 'medium' | 'large';
179
183
  /** Render as inline-block instead of the default block. */
@@ -205,9 +209,10 @@ export interface ATitleAttributes extends BaseAttributes {
205
209
  level?: string;
206
210
  /** Visual priority. Maps to text-1..text-5. */
207
211
  priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
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';
212
+ /** Color tint. `neutral` (default) is the untinted `--text-{N}` scale; a named
213
+ * tone applies the matching `--text-{N}-{tone}` palette; any literal CSS color
214
+ * is a custom tone (hue kept, lightness/chroma pinned per priority in oklch). */
215
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
211
216
  /** ARIA role — the JSX wrapper sets this to `'heading'`. */
212
217
  role?: string;
213
218
  /** ARIA heading level — the JSX wrapper sets this to match `level`. */
@@ -995,3 +1000,47 @@ export interface ATabpanelAttributes extends BaseAttributes {
995
1000
  * `internals.ariaLabelledByElements`. */
996
1001
  role?: 'tabpanel';
997
1002
  }
1003
+ /**
1004
+ * Attributes for the `<a-card>` custom element — a surface container that lays out
1005
+ * an optional `media` region plus a `header` / body / `footer` stack, and becomes a
1006
+ * link when given `href`. Slots (light-DOM children): `media`, `icon`, `header`,
1007
+ * `footer`, and the default slot for the body. The element exposes
1008
+ * `::part(container | media | content | icon | header | body | footer)`. In link
1009
+ * mode it names the shadow anchor from `aria-label` → header text → body text →
1010
+ * `href`. Low-level attributes; for the typed JSX wrapper use `Card` from
1011
+ * `@antadesign/anta`.
1012
+ */
1013
+ export interface ACardAttributes extends BaseAttributes {
1014
+ /** Semantic tone, or any literal CSS color for a one-off custom tone. Named tones
1015
+ * re-point the surface + text; a custom color keeps its hue with lightness/chroma
1016
+ * pinned. `'neutral'` is the default (same as omitting it). */
1017
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
1018
+ /** Surface emphasis. `primary` (default) is a clean sheet; `secondary` a subtle
1019
+ * fill; `tertiary` a frosted, semi-transparent panel with a backdrop blur. */
1020
+ priority?: 'primary' | 'secondary' | 'tertiary';
1021
+ /** Size variant — scales the padding. `medium` is the default. */
1022
+ size?: 'small' | 'medium' | 'large';
1023
+ /** Which edge the full-bleed `media` slot sits on. `top` is the default. */
1024
+ 'media-position'?: 'top' | 'bottom' | 'left' | 'right';
1025
+ /** Selected / chosen state — an inset ring in the tone colour. Presence-based
1026
+ * (`''` on, omit off). */
1027
+ selected?: boolean | '';
1028
+ /** Loading state — skeleton pulse, `aria-busy`, and (in link mode) navigation is
1029
+ * blocked (the anchor drops its `href`). Presence-based (`''` on, omit off). */
1030
+ loading?: boolean | '';
1031
+ /** Fully-round corners (`border-radius: 999px`), or a custom radius via a length
1032
+ * value (`round="16px"`). Presence-based for the boolean form. */
1033
+ round?: boolean | number | string;
1034
+ /** Turn the whole card into a link — the shadow container becomes a focusable
1035
+ * anchor with this URL. */
1036
+ href?: string;
1037
+ /** Anchor target (only with `href`). */
1038
+ target?: string;
1039
+ /** Anchor rel (only with `href`). */
1040
+ rel?: string;
1041
+ /** Space-separated URLs pinged on navigation (only with `href`). */
1042
+ ping?: string;
1043
+ /** Explicit accessible name for the link — overrides the header → body → href
1044
+ * chain the element derives in link mode. */
1045
+ 'aria-label'?: string;
1046
+ }
package/dist/index.d.ts CHANGED
@@ -67,6 +67,8 @@ export { TabPanel } from './components/TabPanel';
67
67
  export type { TabPanelProps } from './components/TabPanel';
68
68
  export { Dialog } from './components/Dialog';
69
69
  export type { DialogProps } from './components/Dialog';
70
+ export { Card } from './components/Card';
71
+ export type { CardProps } from './components/Card';
70
72
  export type { BaseProps, BaseAttributes } from './general_types';
71
73
  export { configure } from './jsx-runtime';
72
74
  export type { AntaIntrinsicElements } from './jsx-runtime';