@adia-ai/web-components 0.0.27 → 0.0.28
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/components/agent-questions/agent-questions.css +20 -1
- package/components/agent-trace/agent-trace.css +17 -12
- package/components/badge/badge.js +9 -1
- package/components/breadcrumb/breadcrumb.a2ui.json +16 -1
- package/components/breadcrumb/breadcrumb.css +27 -0
- package/components/breadcrumb/breadcrumb.js +95 -17
- package/components/breadcrumb/breadcrumb.yaml +15 -1
- package/components/chart/chart.css +20 -13
- package/components/chart/chart.js +49 -17
- package/components/chart-legend/chart-legend.css +30 -54
- package/components/chart-legend/chart-legend.js +48 -30
- package/components/command/command.js +52 -1
- package/components/feed/feed-item.yaml +50 -0
- package/components/feed/feed.a2ui.json +59 -0
- package/components/feed/feed.css +141 -0
- package/components/feed/feed.js +276 -0
- package/components/feed/feed.yaml +33 -0
- package/components/index.js +2 -0
- package/components/swatch/swatch.a2ui.json +116 -0
- package/components/swatch/swatch.css +141 -0
- package/components/swatch/swatch.js +121 -0
- package/components/swatch/swatch.yaml +101 -0
- package/components/timeline/timeline.css +5 -1
- package/components/tooltip/tooltip.css +3 -3
- package/core/provider.js +1 -0
- package/package.json +1 -1
- package/styles/components.css +1 -0
|
@@ -14,14 +14,17 @@
|
|
|
14
14
|
* override when both are provided.)
|
|
15
15
|
* items — JSON array of {key, label, slot?, pct?} legend items.
|
|
16
16
|
* Takes precedence over [for] if both are provided.
|
|
17
|
-
* shape — dot | square | line | dashed. Default: dot.
|
|
18
|
-
*
|
|
19
|
-
* '
|
|
17
|
+
* shape — dot | square | line | dashed. Default: dot. The swatch is
|
|
18
|
+
* a `[data-swatch]` span inside each badge-ui row, styled by
|
|
19
|
+
* the legend's [shape] attr. Custom span (rather than badge-
|
|
20
|
+
* ui's [icon] slot) is required because line/dashed shapes
|
|
21
|
+
* aren't representable as icon glyphs.
|
|
20
22
|
* position — top | bottom | left | right. Layout hint; actual placement
|
|
21
23
|
* is where the element is placed in the DOM. Drives
|
|
22
24
|
* flex-direction.
|
|
23
|
-
* static — when set, rows render as non-interactive
|
|
24
|
-
* is interactive
|
|
25
|
+
* static — when set, rows render as non-interactive badges (no
|
|
26
|
+
* role/tabindex/handlers). Default is interactive
|
|
27
|
+
* `role="button"` badges that toggle on click + Enter/Space.
|
|
25
28
|
* on-toggle — hide | opacity. Default hide. Escape hatch per OD-CHART-09.
|
|
26
29
|
* Reported via the `toggle` event detail; chart-ui reads it
|
|
27
30
|
* when wired via [for].
|
|
@@ -127,45 +130,59 @@ class AdiaChartLegend extends AdiaElement {
|
|
|
127
130
|
const slot = item.slot != null ? item.slot : 0;
|
|
128
131
|
const active = !this.#hiddenKeys.has(key);
|
|
129
132
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
/* Each row is a <badge-ui> chip — the canonical AdiaUI primitive for
|
|
134
|
+
legend pills (per badge.yaml's documented "chart-legend" example).
|
|
135
|
+
badge-ui carries the pill chrome (radius, padding, font-size, hover
|
|
136
|
+
affordance), the legend layers shape-specific swatch CSS + the
|
|
137
|
+
click-to-toggle behavior on top. Interactive rows get
|
|
138
|
+
role="button" + tabindex="0" + Enter/Space handlers so they're
|
|
139
|
+
keyboard-operable without a wrapping <button>. */
|
|
140
|
+
const row = document.createElement('badge-ui');
|
|
134
141
|
row.setAttribute('data-row', '');
|
|
135
|
-
row.setAttribute('role', 'listitem');
|
|
142
|
+
row.setAttribute('role', this.static ? 'listitem' : 'button');
|
|
143
|
+
row.setAttribute('text', label);
|
|
136
144
|
if (key) row.setAttribute('data-key', key);
|
|
137
145
|
if (active) row.setAttribute('data-active', '');
|
|
138
|
-
if (!this.static)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
if (!this.static) {
|
|
147
|
+
row.setAttribute('tabindex', '0');
|
|
148
|
+
row.setAttribute('aria-pressed', active ? 'true' : 'false');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Swatch — composed via `<swatch-ui>` with the legend's [shape] attr
|
|
152
|
+
passed through. Pre-2026-05-01 this was a hand-rolled `<span
|
|
153
|
+
data-swatch>` plus per-shape CSS in this file; that drift caused
|
|
154
|
+
a cascade-leak collision with the docs-shell's `[data-swatch]`
|
|
155
|
+
demo rule (token-colors page). Compose the primitive instead and
|
|
156
|
+
the swatch's dot / square / line / dashed variants live in one
|
|
157
|
+
place. Color resolves via --color-{key} with a --a-data-{slot}
|
|
158
|
+
fallback; the legend can render standalone (without a chart-ui
|
|
159
|
+
ancestor) so the fallback must reference the global data palette
|
|
160
|
+
directly, not chart-ui's scoped --chart-{N} alias. */
|
|
161
|
+
const swatchShape = this.shape || 'dot';
|
|
162
|
+
const swatch = document.createElement('swatch-ui');
|
|
163
|
+
swatch.setAttribute('shape', swatchShape);
|
|
164
|
+
swatch.setAttribute('size', 'sm');
|
|
149
165
|
const swatchColor = key
|
|
150
|
-
? `var(--color-${key}, var(--
|
|
151
|
-
: `var(--
|
|
166
|
+
? `var(--color-${key}, var(--a-data-${slot}))`
|
|
167
|
+
: `var(--a-data-${slot})`;
|
|
152
168
|
swatch.style.setProperty('--swatch-color', swatchColor);
|
|
153
169
|
row.appendChild(swatch);
|
|
154
170
|
|
|
155
|
-
const labelEl = document.createElement('span');
|
|
156
|
-
labelEl.setAttribute('data-label', '');
|
|
157
|
-
labelEl.textContent = label;
|
|
158
|
-
row.appendChild(labelEl);
|
|
159
|
-
|
|
160
171
|
if (!this.static) {
|
|
161
|
-
row.addEventListener('click', (e) => this.#
|
|
172
|
+
row.addEventListener('click', (e) => this.#onRowToggle(e, key));
|
|
173
|
+
row.addEventListener('keydown', (e) => {
|
|
174
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
175
|
+
e.preventDefault();
|
|
176
|
+
this.#onRowToggle(e, key);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
162
179
|
}
|
|
163
180
|
|
|
164
181
|
this.appendChild(row);
|
|
165
182
|
}
|
|
166
183
|
}
|
|
167
184
|
|
|
168
|
-
#
|
|
185
|
+
#onRowToggle(e, key) {
|
|
169
186
|
if (!key) return;
|
|
170
187
|
const currentlyActive = !this.#hiddenKeys.has(key);
|
|
171
188
|
const newActive = !currentlyActive;
|
|
@@ -175,6 +192,7 @@ class AdiaChartLegend extends AdiaElement {
|
|
|
175
192
|
const row = e.currentTarget;
|
|
176
193
|
if (newActive) row.setAttribute('data-active', '');
|
|
177
194
|
else row.removeAttribute('data-active');
|
|
195
|
+
row.setAttribute('aria-pressed', newActive ? 'true' : 'false');
|
|
178
196
|
|
|
179
197
|
this.dispatchEvent(new CustomEvent('toggle', {
|
|
180
198
|
bubbles: true,
|
|
@@ -29,6 +29,7 @@ class AdiaCommand extends AdiaElement {
|
|
|
29
29
|
static template = () => null;
|
|
30
30
|
|
|
31
31
|
#items = [];
|
|
32
|
+
#recents = [];
|
|
32
33
|
#activeIdx = -1;
|
|
33
34
|
#inputEl = null;
|
|
34
35
|
#listEl = null;
|
|
@@ -37,6 +38,8 @@ class AdiaCommand extends AdiaElement {
|
|
|
37
38
|
#bound = false;
|
|
38
39
|
#itemByEl = new WeakMap();
|
|
39
40
|
|
|
41
|
+
static #RECENTS_MAX = 3;
|
|
42
|
+
|
|
40
43
|
#onListClick = (e) => {
|
|
41
44
|
const el = e.target instanceof Element ? e.target.closest('[role="option"]:not([aria-disabled])') : null;
|
|
42
45
|
if (!el) return;
|
|
@@ -99,7 +102,15 @@ class AdiaCommand extends AdiaElement {
|
|
|
99
102
|
// ── Public API ──
|
|
100
103
|
|
|
101
104
|
get value() { return this.#inputEl?.value || ''; }
|
|
102
|
-
set value(v) {
|
|
105
|
+
set value(v) {
|
|
106
|
+
if (!this.#inputEl) return;
|
|
107
|
+
const next = v ?? '';
|
|
108
|
+
this.#inputEl.value = next;
|
|
109
|
+
// Keep the rendered list in sync with the visible input — the host
|
|
110
|
+
// commonly clears value on (re)open, and consumers expect to see the
|
|
111
|
+
// full list (plus recents) rather than the previous filter's residue.
|
|
112
|
+
this.#renderItems(next);
|
|
113
|
+
}
|
|
103
114
|
|
|
104
115
|
focus() { this.#inputEl?.focus(); }
|
|
105
116
|
|
|
@@ -148,6 +159,26 @@ class AdiaCommand extends AdiaElement {
|
|
|
148
159
|
const flat = this.#items;
|
|
149
160
|
let visibleCount = 0;
|
|
150
161
|
|
|
162
|
+
// Recents — only when no filter is applied. Resolved against the
|
|
163
|
+
// current item set so a stale recent (item removed via setItems)
|
|
164
|
+
// is silently dropped.
|
|
165
|
+
if (!q && this.#recents.length) {
|
|
166
|
+
const resolved = this.#recents
|
|
167
|
+
.map(v => this.#findItem(v))
|
|
168
|
+
.filter(it => it && !it.disabled);
|
|
169
|
+
if (resolved.length) {
|
|
170
|
+
const groupEl = document.createElement('div');
|
|
171
|
+
groupEl.setAttribute('data-group', '');
|
|
172
|
+
groupEl.setAttribute('data-recent', '');
|
|
173
|
+
groupEl.innerHTML = `<div data-group-label>Recent</div>`;
|
|
174
|
+
for (const item of resolved) {
|
|
175
|
+
groupEl.appendChild(this.#createItemEl(item, visibleCount));
|
|
176
|
+
visibleCount++;
|
|
177
|
+
}
|
|
178
|
+
this.#listEl.appendChild(groupEl);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
151
182
|
for (const entry of flat) {
|
|
152
183
|
if (entry.items) {
|
|
153
184
|
// Group
|
|
@@ -182,6 +213,24 @@ class AdiaCommand extends AdiaElement {
|
|
|
182
213
|
if (visibleCount > 0) this.#activate(0);
|
|
183
214
|
}
|
|
184
215
|
|
|
216
|
+
#findItem(value) {
|
|
217
|
+
for (const entry of this.#items) {
|
|
218
|
+
if (entry.items) {
|
|
219
|
+
const hit = entry.items.find(i => i.value === value);
|
|
220
|
+
if (hit) return hit;
|
|
221
|
+
} else if (entry.value === value) {
|
|
222
|
+
return entry;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
#pushRecent(value) {
|
|
229
|
+
if (!value) return;
|
|
230
|
+
this.#recents = [value, ...this.#recents.filter(v => v !== value)]
|
|
231
|
+
.slice(0, AdiaCommand.#RECENTS_MAX);
|
|
232
|
+
}
|
|
233
|
+
|
|
185
234
|
#createItemEl(item, idx) {
|
|
186
235
|
const el = document.createElement('div');
|
|
187
236
|
el.setAttribute('role', 'option');
|
|
@@ -235,6 +284,7 @@ class AdiaCommand extends AdiaElement {
|
|
|
235
284
|
}
|
|
236
285
|
|
|
237
286
|
#select(item) {
|
|
287
|
+
this.#pushRecent(item.value);
|
|
238
288
|
this.dispatchEvent(new CustomEvent('select', {
|
|
239
289
|
bubbles: true,
|
|
240
290
|
detail: { value: item.value, label: item.label },
|
|
@@ -246,6 +296,7 @@ class AdiaCommand extends AdiaElement {
|
|
|
246
296
|
if (!active) return;
|
|
247
297
|
const value = active.dataset.value;
|
|
248
298
|
const label = active.querySelector('[data-text]')?.textContent || '';
|
|
299
|
+
this.#pushRecent(value);
|
|
249
300
|
this.dispatchEvent(new CustomEvent('select', {
|
|
250
301
|
bubbles: true,
|
|
251
302
|
detail: { value, label },
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
2
|
+
name: AdiaFeedItem
|
|
3
|
+
tag: feed-item-ui
|
|
4
|
+
component: FeedItem
|
|
5
|
+
category: feedback
|
|
6
|
+
version: 1
|
|
7
|
+
description: >-
|
|
8
|
+
Atomic feed entry inside a `<feed-ui>` lane. Three dismiss policies
|
|
9
|
+
are inferred from the prop shape — auto-fade (duration > 0 + no
|
|
10
|
+
action), sticky-dismissible (duration null/0), action-required
|
|
11
|
+
(duration null/0 + action; future phase). Posted via
|
|
12
|
+
`AdiaFeed.post()` rather than authored directly.
|
|
13
|
+
props:
|
|
14
|
+
text:
|
|
15
|
+
description: Body copy
|
|
16
|
+
type: string
|
|
17
|
+
default: ""
|
|
18
|
+
heading:
|
|
19
|
+
description: Optional emphasis line above text
|
|
20
|
+
type: string
|
|
21
|
+
default: ""
|
|
22
|
+
icon:
|
|
23
|
+
description: Optional leading icon name
|
|
24
|
+
type: string
|
|
25
|
+
default: ""
|
|
26
|
+
variant:
|
|
27
|
+
description: Semantic variant
|
|
28
|
+
type: string
|
|
29
|
+
default: default
|
|
30
|
+
enum:
|
|
31
|
+
- default
|
|
32
|
+
- info
|
|
33
|
+
- success
|
|
34
|
+
- warning
|
|
35
|
+
- danger
|
|
36
|
+
duration:
|
|
37
|
+
description: Auto-fade timer in ms; null/0 = sticky (requires user input)
|
|
38
|
+
type: number
|
|
39
|
+
default: 4000
|
|
40
|
+
dismissible:
|
|
41
|
+
description: Render an x close button (default true for sticky, false for auto-fade)
|
|
42
|
+
type: boolean
|
|
43
|
+
default: false
|
|
44
|
+
events:
|
|
45
|
+
close:
|
|
46
|
+
description: Fired after the item finishes its exit animation
|
|
47
|
+
slots:
|
|
48
|
+
body:
|
|
49
|
+
description: Default content slot (also accepts the `text` / `heading` props)
|
|
50
|
+
states: {}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://adiaui.dev/a2ui/v0_9/components/Feed.json",
|
|
4
|
+
"title": "Feed",
|
|
5
|
+
"description": "Shared top-layer feed channel. Per docs/specs/feed-channel.md (SPEC-FEED-CHANNEL-001). Per-position singletons mounted lazily into document.body via Popover API; consumers post via the static API (`AdiaFeed.post()`) or the global 'feed' CustomEvent.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"allOf": [
|
|
8
|
+
{
|
|
9
|
+
"$ref": "common_types.json#/$defs/ComponentCommon"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"$ref": "common_types.json#/$defs/CatalogComponentCommon"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"component": {
|
|
17
|
+
"const": "Feed"
|
|
18
|
+
},
|
|
19
|
+
"max": {
|
|
20
|
+
"description": "Cap on simultaneously visible items per lane",
|
|
21
|
+
"type": "number",
|
|
22
|
+
"default": 5
|
|
23
|
+
},
|
|
24
|
+
"position": {
|
|
25
|
+
"description": "Lane the feed renders into",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"enum": [
|
|
28
|
+
"top-left",
|
|
29
|
+
"top-center",
|
|
30
|
+
"top-right",
|
|
31
|
+
"bottom-left",
|
|
32
|
+
"bottom-center",
|
|
33
|
+
"bottom-right",
|
|
34
|
+
"inline"
|
|
35
|
+
],
|
|
36
|
+
"default": "bottom-right"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"required": [
|
|
40
|
+
"component"
|
|
41
|
+
],
|
|
42
|
+
"unevaluatedProperties": false,
|
|
43
|
+
"x-adiaui": {
|
|
44
|
+
"anti_patterns": [],
|
|
45
|
+
"category": "container",
|
|
46
|
+
"events": {},
|
|
47
|
+
"examples": [],
|
|
48
|
+
"keywords": [],
|
|
49
|
+
"name": "AdiaFeedContainer",
|
|
50
|
+
"related": [],
|
|
51
|
+
"slots": {},
|
|
52
|
+
"states": {},
|
|
53
|
+
"synonyms": {},
|
|
54
|
+
"tag": "feed-ui",
|
|
55
|
+
"tokens": {},
|
|
56
|
+
"traits": [],
|
|
57
|
+
"version": 1
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
2
|
+
FEED-UI — Shared top-layer feed channel.
|
|
3
|
+
Per docs/specs/feed-channel.md (SPEC-FEED-CHANNEL-001).
|
|
4
|
+
═══════════════════════════════════════════════════════════════ */
|
|
5
|
+
|
|
6
|
+
/* Safari 17.x bug — same as toast: `:scope[data-open]` flavor B
|
|
7
|
+
doesn't reliably restyle on attribute toggling inside @scope.
|
|
8
|
+
Selectors moved out as plain feed-item-ui[data-…] rules. */
|
|
9
|
+
feed-item-ui[data-open] {
|
|
10
|
+
transition: transform var(--feed-item-duration) var(--feed-item-easing),
|
|
11
|
+
opacity var(--feed-item-duration) var(--feed-item-easing);
|
|
12
|
+
transform: translateY(0);
|
|
13
|
+
opacity: 1;
|
|
14
|
+
}
|
|
15
|
+
feed-item-ui[data-closing] {
|
|
16
|
+
transition: transform var(--feed-item-duration) var(--feed-item-easing),
|
|
17
|
+
opacity var(--feed-item-duration) var(--feed-item-easing);
|
|
18
|
+
opacity: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Container — per-position lane, mounted into document.body via
|
|
22
|
+
Popover API for top-layer placement. */
|
|
23
|
+
@scope (feed-ui) {
|
|
24
|
+
:where(:scope) {
|
|
25
|
+
--feed-gap: var(--a-space-2);
|
|
26
|
+
--feed-padding: var(--a-space-3);
|
|
27
|
+
--feed-max-width: 22rem;
|
|
28
|
+
--feed-offset: var(--a-space-4);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:scope {
|
|
32
|
+
position: fixed;
|
|
33
|
+
z-index: 9999;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
gap: var(--feed-gap);
|
|
37
|
+
padding: 0;
|
|
38
|
+
background: transparent;
|
|
39
|
+
border: 0;
|
|
40
|
+
pointer-events: none; /* Items re-enable pointer-events. */
|
|
41
|
+
width: max-content;
|
|
42
|
+
max-width: var(--feed-max-width);
|
|
43
|
+
}
|
|
44
|
+
/* Reset native popover defaults so the lane is invisible until
|
|
45
|
+
items render. */
|
|
46
|
+
:scope[popover] { background: none; color: inherit; }
|
|
47
|
+
|
|
48
|
+
/* Position variants. Default = bottom-right. */
|
|
49
|
+
:scope,
|
|
50
|
+
:scope[position="bottom-right"] {
|
|
51
|
+
bottom: var(--feed-offset); right: var(--feed-offset);
|
|
52
|
+
}
|
|
53
|
+
:scope[position="bottom-left"] {
|
|
54
|
+
bottom: var(--feed-offset); left: var(--feed-offset); right: auto;
|
|
55
|
+
}
|
|
56
|
+
:scope[position="bottom-center"] {
|
|
57
|
+
bottom: var(--feed-offset);
|
|
58
|
+
left: 50%; right: auto;
|
|
59
|
+
transform: translateX(-50%);
|
|
60
|
+
}
|
|
61
|
+
:scope[position="top-right"] {
|
|
62
|
+
top: var(--feed-offset); right: var(--feed-offset); bottom: auto;
|
|
63
|
+
flex-direction: column-reverse;
|
|
64
|
+
}
|
|
65
|
+
:scope[position="top-left"] {
|
|
66
|
+
top: var(--feed-offset); left: var(--feed-offset); right: auto; bottom: auto;
|
|
67
|
+
flex-direction: column-reverse;
|
|
68
|
+
}
|
|
69
|
+
:scope[position="top-center"] {
|
|
70
|
+
top: var(--feed-offset); bottom: auto;
|
|
71
|
+
left: 50%; right: auto;
|
|
72
|
+
transform: translateX(-50%);
|
|
73
|
+
flex-direction: column-reverse;
|
|
74
|
+
}
|
|
75
|
+
:scope[position="inline"] {
|
|
76
|
+
position: relative;
|
|
77
|
+
inset: auto;
|
|
78
|
+
z-index: 1;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Item — atomic feed entry. */
|
|
83
|
+
@scope (feed-item-ui) {
|
|
84
|
+
:where(:scope) {
|
|
85
|
+
--feed-item-bg: var(--a-bg);
|
|
86
|
+
--feed-item-fg: var(--a-fg);
|
|
87
|
+
--feed-item-border: var(--a-border-subtle);
|
|
88
|
+
--feed-item-radius: var(--a-radius-md);
|
|
89
|
+
--feed-item-px: var(--a-space-3);
|
|
90
|
+
--feed-item-py: var(--a-space-2-5);
|
|
91
|
+
--feed-item-shadow: var(--a-shadow-md);
|
|
92
|
+
--feed-item-icon-size: var(--a-icon-size);
|
|
93
|
+
--feed-item-duration: var(--a-duration);
|
|
94
|
+
--feed-item-easing: var(--a-easing-out);
|
|
95
|
+
--feed-item-gap: var(--a-space-3);
|
|
96
|
+
--feed-item-max-width: var(--a-feed-max-width, 22rem);
|
|
97
|
+
}
|
|
98
|
+
:scope[variant="info"] { --feed-item-fg: var(--a-info-fg); --feed-item-bg: var(--a-info-muted); }
|
|
99
|
+
:scope[variant="success"] { --feed-item-fg: var(--a-success-fg); --feed-item-bg: var(--a-success-muted); }
|
|
100
|
+
:scope[variant="warning"] { --feed-item-fg: var(--a-warning-fg); --feed-item-bg: var(--a-warning-muted); }
|
|
101
|
+
:scope[variant="danger"] { --feed-item-fg: var(--a-danger-fg); --feed-item-bg: var(--a-danger-muted); }
|
|
102
|
+
|
|
103
|
+
:scope {
|
|
104
|
+
box-sizing: border-box;
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
gap: var(--feed-item-gap);
|
|
108
|
+
max-width: var(--feed-item-max-width);
|
|
109
|
+
padding: var(--feed-item-py) var(--feed-item-px);
|
|
110
|
+
background: var(--feed-item-bg);
|
|
111
|
+
color: var(--feed-item-fg);
|
|
112
|
+
border: 1px solid var(--feed-item-border);
|
|
113
|
+
border-radius: var(--feed-item-radius);
|
|
114
|
+
box-shadow: var(--feed-item-shadow);
|
|
115
|
+
opacity: 0;
|
|
116
|
+
transform: translateY(0.5rem);
|
|
117
|
+
pointer-events: auto;
|
|
118
|
+
}
|
|
119
|
+
:scope > [slot="body"] {
|
|
120
|
+
flex: 1;
|
|
121
|
+
min-width: 0;
|
|
122
|
+
display: flex;
|
|
123
|
+
flex-direction: column;
|
|
124
|
+
gap: 0.125rem;
|
|
125
|
+
}
|
|
126
|
+
:scope > [slot="body"] strong {
|
|
127
|
+
font-weight: var(--a-font-weight-strong, 600);
|
|
128
|
+
}
|
|
129
|
+
:scope > [data-feed-close] {
|
|
130
|
+
flex-shrink: 0;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Reduced-motion: skip slide-in/out, keep opacity. */
|
|
135
|
+
@media (prefers-reduced-motion: reduce) {
|
|
136
|
+
feed-item-ui[data-open],
|
|
137
|
+
feed-item-ui[data-closing] {
|
|
138
|
+
transition: opacity var(--feed-item-duration) var(--feed-item-easing);
|
|
139
|
+
transform: none !important;
|
|
140
|
+
}
|
|
141
|
+
}
|