@adia-ai/web-components 0.6.31 → 0.6.33
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/CHANGELOG.md +49 -0
- package/components/accordion/accordion-item.a2ui.json +1 -0
- package/components/accordion/accordion-item.yaml +1 -0
- package/components/accordion/accordion.a2ui.json +1 -0
- package/components/accordion/accordion.yaml +1 -0
- package/components/action-list/action-item.a2ui.json +1 -0
- package/components/action-list/action-item.yaml +1 -0
- package/components/action-list/action-list.a2ui.json +1 -0
- package/components/action-list/action-list.yaml +1 -0
- package/components/agent-artifact/agent-artifact.a2ui.json +1 -0
- package/components/agent-artifact/agent-artifact.yaml +1 -0
- package/components/agent-feedback-bar/agent-feedback-bar.a2ui.json +1 -0
- package/components/agent-feedback-bar/agent-feedback-bar.yaml +1 -0
- package/components/agent-questions/agent-questions.a2ui.json +1 -0
- package/components/agent-questions/agent-questions.yaml +1 -0
- package/components/agent-reasoning/agent-reasoning.a2ui.json +1 -0
- package/components/agent-reasoning/agent-reasoning.yaml +1 -0
- package/components/agent-suggestions/agent-suggestions.a2ui.json +1 -0
- package/components/agent-suggestions/agent-suggestions.yaml +1 -0
- package/components/agent-trace/agent-trace.a2ui.json +1 -0
- package/components/agent-trace/agent-trace.yaml +1 -0
- package/components/alert/alert.a2ui.json +1 -0
- package/components/alert/alert.yaml +1 -0
- package/components/aside/aside.a2ui.json +1 -0
- package/components/aside/aside.yaml +1 -0
- package/components/avatar/avatar-group.a2ui.json +1 -0
- package/components/avatar/avatar-group.yaml +1 -0
- package/components/avatar/avatar.a2ui.json +1 -0
- package/components/avatar/avatar.yaml +1 -0
- package/components/badge/badge.a2ui.json +3 -1
- package/components/badge/badge.css +6 -1
- package/components/badge/badge.yaml +2 -0
- package/components/block/block.a2ui.json +1 -0
- package/components/block/block.yaml +1 -0
- package/components/breadcrumb/breadcrumb.a2ui.json +1 -0
- package/components/breadcrumb/breadcrumb.yaml +1 -0
- package/components/button/button.a2ui.json +1 -0
- package/components/button/button.yaml +1 -0
- package/components/calendar-picker/calendar-picker.a2ui.json +1 -0
- package/components/calendar-picker/calendar-picker.yaml +1 -0
- package/components/canvas/canvas.a2ui.json +1 -0
- package/components/canvas/canvas.yaml +1 -0
- package/components/card/card.a2ui.json +1 -0
- package/components/card/card.yaml +1 -0
- package/components/chart/chart.a2ui.json +3 -1
- package/components/chart/chart.yaml +2 -0
- package/components/chart-legend/chart-legend.a2ui.json +1 -0
- package/components/chart-legend/chart-legend.yaml +1 -0
- package/components/chat-thread/chat-input.a2ui.json +1 -0
- package/components/chat-thread/chat-input.yaml +1 -0
- package/components/chat-thread/chat-thread.a2ui.json +1 -0
- package/components/chat-thread/chat-thread.yaml +1 -0
- package/components/check/check.a2ui.json +3 -1
- package/components/check/check.yaml +2 -0
- package/components/code/code.a2ui.json +1 -0
- package/components/code/code.css +1 -1
- package/components/code/code.yaml +1 -0
- package/components/col/col.a2ui.json +1 -0
- package/components/col/col.yaml +1 -0
- package/components/color-input/color-input.a2ui.json +1 -0
- package/components/color-input/color-input.yaml +1 -0
- package/components/color-picker/color-picker.a2ui.json +1 -0
- package/components/color-picker/color-picker.yaml +1 -0
- package/components/command/command.a2ui.json +1 -0
- package/components/command/command.yaml +1 -0
- package/components/demo-toggle/demo-toggle.a2ui.json +1 -0
- package/components/demo-toggle/demo-toggle.yaml +1 -0
- package/components/description-list/description-list.a2ui.json +1 -0
- package/components/description-list/description-list.yaml +1 -0
- package/components/divider/divider.a2ui.json +1 -0
- package/components/divider/divider.yaml +1 -0
- package/components/drawer/drawer.a2ui.json +1 -0
- package/components/drawer/drawer.yaml +1 -0
- package/components/embed/embed.a2ui.json +1 -0
- package/components/embed/embed.yaml +1 -0
- package/components/empty-state/empty-state.a2ui.json +1 -0
- package/components/empty-state/empty-state.yaml +1 -0
- package/components/feed/feed-item.a2ui.json +1 -0
- package/components/feed/feed-item.yaml +1 -0
- package/components/feed/feed.a2ui.json +1 -0
- package/components/feed/feed.yaml +1 -0
- package/components/field/field.a2ui.json +3 -1
- package/components/field/field.css +10 -1
- package/components/field/field.test.js +32 -0
- package/components/field/field.yaml +2 -0
- package/components/fields/fields.a2ui.json +1 -0
- package/components/fields/fields.yaml +1 -0
- package/components/footer/footer.a2ui.json +1 -0
- package/components/footer/footer.yaml +1 -0
- package/components/grid/grid.a2ui.json +1 -0
- package/components/grid/grid.yaml +1 -0
- package/components/header/header.a2ui.json +1 -0
- package/components/header/header.yaml +1 -0
- package/components/heatmap/heatmap.a2ui.json +1 -0
- package/components/heatmap/heatmap.yaml +1 -0
- package/components/icon/icon.a2ui.json +3 -1
- package/components/icon/icon.yaml +2 -0
- package/components/image/image.a2ui.json +1 -0
- package/components/image/image.yaml +1 -0
- package/components/input/input.a2ui.json +1 -0
- package/components/input/input.yaml +1 -0
- package/components/inspector/inspector.a2ui.json +1 -0
- package/components/inspector/inspector.yaml +1 -0
- package/components/kbd/kbd.a2ui.json +1 -0
- package/components/kbd/kbd.yaml +1 -0
- package/components/link/link.a2ui.json +1 -0
- package/components/link/link.yaml +1 -0
- package/components/list/list-item.a2ui.json +1 -0
- package/components/list/list-item.yaml +1 -0
- package/components/list/list.a2ui.json +1 -0
- package/components/list/list.yaml +1 -0
- package/components/menu/menu-divider.a2ui.json +1 -0
- package/components/menu/menu-divider.yaml +1 -0
- package/components/menu/menu-item.a2ui.json +1 -0
- package/components/menu/menu-item.yaml +1 -0
- package/components/menu/menu.a2ui.json +1 -0
- package/components/menu/menu.yaml +1 -0
- package/components/modal/modal.a2ui.json +1 -0
- package/components/modal/modal.yaml +1 -0
- package/components/nav/nav.a2ui.json +1 -0
- package/components/nav/nav.yaml +1 -0
- package/components/nav-group/nav-group.a2ui.json +1 -0
- package/components/nav-group/nav-group.yaml +1 -0
- package/components/nav-item/nav-item.a2ui.json +3 -1
- package/components/nav-item/nav-item.yaml +2 -0
- package/components/noodles/noodles.a2ui.json +1 -0
- package/components/noodles/noodles.yaml +1 -0
- package/components/option-card/option-card.a2ui.json +1 -0
- package/components/option-card/option-card.yaml +1 -0
- package/components/otp-input/otp-input.a2ui.json +1 -0
- package/components/otp-input/otp-input.yaml +1 -0
- package/components/page/page.a2ui.json +1 -0
- package/components/page/page.yaml +1 -0
- package/components/pagination/pagination.a2ui.json +1 -0
- package/components/pagination/pagination.yaml +1 -0
- package/components/pane/pane.a2ui.json +1 -0
- package/components/pane/pane.yaml +1 -0
- package/components/pipeline-status/pipeline-status.a2ui.json +1 -0
- package/components/pipeline-status/pipeline-status.yaml +1 -0
- package/components/popover/popover.a2ui.json +1 -0
- package/components/popover/popover.yaml +1 -0
- package/components/progress/progress.a2ui.json +1 -0
- package/components/progress/progress.yaml +1 -0
- package/components/progress-row/progress-row.a2ui.json +1 -0
- package/components/progress-row/progress-row.yaml +1 -0
- package/components/radio/radio.a2ui.json +1 -0
- package/components/radio/radio.yaml +1 -0
- package/components/range/range.a2ui.json +1 -0
- package/components/range/range.yaml +1 -0
- package/components/rating/rating.a2ui.json +3 -1
- package/components/rating/rating.yaml +2 -0
- package/components/richtext/richtext.a2ui.json +1 -0
- package/components/richtext/richtext.yaml +1 -0
- package/components/row/row.a2ui.json +1 -0
- package/components/row/row.yaml +1 -0
- package/components/search/search.a2ui.json +1 -0
- package/components/search/search.yaml +1 -0
- package/components/section/section.a2ui.json +1 -0
- package/components/section/section.yaml +1 -0
- package/components/segment/segment.a2ui.json +1 -0
- package/components/segment/segment.css +8 -2
- package/components/segment/segment.yaml +1 -0
- package/components/segmented/segmented.a2ui.json +1 -0
- package/components/segmented/segmented.yaml +1 -0
- package/components/select/select.a2ui.json +1 -0
- package/components/select/select.yaml +1 -0
- package/components/skeleton/skeleton.a2ui.json +1 -0
- package/components/skeleton/skeleton.yaml +1 -0
- package/components/slider/slider.a2ui.json +1 -0
- package/components/slider/slider.yaml +1 -0
- package/components/stack/stack.a2ui.json +1 -0
- package/components/stack/stack.yaml +1 -0
- package/components/stat/stat.a2ui.json +4 -1
- package/components/stat/stat.yaml +3 -0
- package/components/step-progress/step-progress.a2ui.json +1 -0
- package/components/step-progress/step-progress.yaml +1 -0
- package/components/stepper/stepper-item.a2ui.json +1 -0
- package/components/stepper/stepper-item.yaml +1 -0
- package/components/stepper/stepper.a2ui.json +1 -0
- package/components/stepper/stepper.yaml +1 -0
- package/components/stream/stream.a2ui.json +1 -0
- package/components/stream/stream.yaml +1 -0
- package/components/swatch/swatch.a2ui.json +1 -0
- package/components/swatch/swatch.yaml +1 -0
- package/components/swiper/swiper.a2ui.json +1 -0
- package/components/swiper/swiper.yaml +1 -0
- package/components/switch/switch.a2ui.json +1 -0
- package/components/switch/switch.yaml +1 -0
- package/components/table/class.js +9 -0
- package/components/table/table.a2ui.json +2 -1
- package/components/table/table.d.ts +1 -1
- package/components/table/table.test.js +53 -0
- package/components/table/table.yaml +14 -1
- package/components/table-toolbar/table-toolbar.a2ui.json +1 -0
- package/components/table-toolbar/table-toolbar.yaml +1 -0
- package/components/tabs/tab.a2ui.json +1 -0
- package/components/tabs/tab.yaml +1 -0
- package/components/tabs/tabs.a2ui.json +3 -1
- package/components/tabs/tabs.css +1 -1
- package/components/tabs/tabs.yaml +2 -0
- package/components/tag/tag.a2ui.json +1 -0
- package/components/tag/tag.css +6 -1
- package/components/tag/tag.test.js +46 -0
- package/components/tag/tag.yaml +1 -0
- package/components/text/text.a2ui.json +1 -0
- package/components/text/text.yaml +1 -0
- package/components/textarea/textarea.a2ui.json +1 -0
- package/components/textarea/textarea.yaml +1 -0
- package/components/timeline/timeline-item.a2ui.json +1 -0
- package/components/timeline/timeline-item.yaml +1 -0
- package/components/timeline/timeline.a2ui.json +1 -0
- package/components/timeline/timeline.yaml +1 -0
- package/components/toast/toast.a2ui.json +1 -0
- package/components/toast/toast.yaml +1 -0
- package/components/toggle-group/toggle-group.a2ui.json +1 -0
- package/components/toggle-group/toggle-group.yaml +1 -0
- package/components/toggle-group/toggle-option.a2ui.json +1 -0
- package/components/toggle-group/toggle-option.yaml +1 -0
- package/components/toggle-scheme/toggle-scheme.a2ui.json +1 -0
- package/components/toggle-scheme/toggle-scheme.yaml +1 -0
- package/components/toolbar/toolbar-group.a2ui.json +1 -0
- package/components/toolbar/toolbar-group.yaml +1 -0
- package/components/toolbar/toolbar.a2ui.json +1 -0
- package/components/toolbar/toolbar.yaml +1 -0
- package/components/tooltip/tooltip.a2ui.json +1 -0
- package/components/tooltip/tooltip.yaml +1 -0
- package/components/tree/tree-item.a2ui.json +1 -0
- package/components/tree/tree-item.yaml +1 -0
- package/components/tree/tree.a2ui.json +1 -0
- package/components/tree/tree.yaml +1 -0
- package/components/upload/upload.a2ui.json +1 -0
- package/components/upload/upload.yaml +1 -0
- package/core/icons-phosphor.js +9 -3
- package/dist/icons-manifest.js +9091 -0
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +16 -16
- package/package.json +1 -1
- package/styles/colors/semantics.css +3 -3
|
@@ -541,6 +541,15 @@ export class UITable extends UIElement {
|
|
|
541
541
|
// ── Render ─────────────────────────────────────────────────────────────────
|
|
542
542
|
|
|
543
543
|
render() {
|
|
544
|
+
// Raw mode: visual-only passthrough. The consumer authored the entire
|
|
545
|
+
// body shape (native <table>, custom row rendering, etc.) and only wants
|
|
546
|
+
// table-ui's CSS tokens (chrome reset via :scope[raw]). The data
|
|
547
|
+
// lifecycle (header injection, body reconciliation, overlays, aggregation,
|
|
548
|
+
// pagination) MUST NOT run — otherwise `.data === []` injects a
|
|
549
|
+
// [data-empty] overlay above the consumer's content (FB-53 §2). Raw is
|
|
550
|
+
// the explicit "consumer owns layout" mode.
|
|
551
|
+
if (this.raw) return;
|
|
552
|
+
|
|
544
553
|
const visCols = this.#visibleColumns;
|
|
545
554
|
|
|
546
555
|
// Set grid template
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"default": 0
|
|
53
53
|
},
|
|
54
54
|
"raw": {
|
|
55
|
-
"description": "
|
|
55
|
+
"description": "Visual-only passthrough — applies `<table-ui>`'s chrome reset (background / border / border-radius all transparent) AND short-circuits the data lifecycle entirely. The consumer owns the body shape: no header injection, no row reconciliation from `.data`, no empty-state / loading overlays, no aggregation or pagination footers. Use raw when embedding `<table-ui>` inside surfaces that supply their own chrome (e.g. `<card-ui><section bleed>`), or when wrapping a consumer-authored native `<table>` for design-token styling without the framework's data semantics. Pre-v0.6.33 (FB-53 §2) `raw` was visual-only and the data lifecycle still ran — wrapping a `.data`-unset native table produced a phantom \"No data\" overlay. v0.6.33+ matches the documented contract.",
|
|
56
56
|
"type": "boolean",
|
|
57
57
|
"default": false
|
|
58
58
|
},
|
|
@@ -281,6 +281,7 @@
|
|
|
281
281
|
"name": "idle"
|
|
282
282
|
}
|
|
283
283
|
],
|
|
284
|
+
"status": "stable",
|
|
284
285
|
"synonyms": {
|
|
285
286
|
"admin": [
|
|
286
287
|
"dashboard",
|
|
@@ -98,7 +98,7 @@ export class UITable extends UIElement {
|
|
|
98
98
|
loading: boolean;
|
|
99
99
|
/** Rows per page. 0 = show all rows without pagination. When > 0, renders a pagination bar below the table. */
|
|
100
100
|
paginate: number;
|
|
101
|
-
/**
|
|
101
|
+
/** Visual-only passthrough — applies `<table-ui>`'s chrome reset (background / border / border-radius all transparent) AND short-circuits the data lifecycle entirely. The consumer owns the body shape: no header injection, no row reconciliation from `.data`, no empty-state / loading overlays, no aggregation or pagination footers. Use raw when embedding `<table-ui>` inside surfaces that supply their own chrome (e.g. `<card-ui><section bleed>`), or when wrapping a consumer-authored native `<table>` for design-token styling without the framework's data semantics. Pre-v0.6.33 (FB-53 §2) `raw` was visual-only and the data lifecycle still ran — wrapping a `.data`-unset native table produced a phantom "No data" overlay. v0.6.33+ matches the documented contract. */
|
|
102
102
|
raw: boolean;
|
|
103
103
|
/** Global search/filter string. Filters visible rows across all columns using case-insensitive substring matching. Resets to page 1 on change. */
|
|
104
104
|
search: string;
|
|
@@ -283,3 +283,56 @@ describe('table-ui — FB-47 keyboard: Enter activates focused body cell', () =>
|
|
|
283
283
|
expect(cellClickFired).toBe(false);
|
|
284
284
|
});
|
|
285
285
|
});
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Raw mode: visual-only passthrough — consumer owns the body shape.
|
|
289
|
+
*
|
|
290
|
+
* Pre-v0.6.33 (FB-53 §2), `<table-ui raw>` only applied the CSS chrome
|
|
291
|
+
* reset (background/border/radius transparent) but the data lifecycle
|
|
292
|
+
* still ran. With `.data === []` (the natural state when wrapping a
|
|
293
|
+
* consumer-authored native <table>), `#renderOverlays` injected a
|
|
294
|
+
* [data-empty] "No data" placeholder above the consumer's content.
|
|
295
|
+
*
|
|
296
|
+
* v0.6.33 short-circuits `render()` at the top when `this.raw` is set:
|
|
297
|
+
* no header injection, no body reconciliation, no overlays, no
|
|
298
|
+
* aggregation, no pagination.
|
|
299
|
+
*/
|
|
300
|
+
describe('table-ui — raw mode passthrough (FB-53 §2)', () => {
|
|
301
|
+
beforeEach(() => { document.body.innerHTML = ''; });
|
|
302
|
+
|
|
303
|
+
it('raw mode does NOT inject [data-empty] overlay when .data is empty', async () => {
|
|
304
|
+
const el = mount('<table-ui raw><table><tr><td>foo</td></tr></table></table-ui>');
|
|
305
|
+
// No .data set → empty by default. Without the raw early-return,
|
|
306
|
+
// #renderOverlays would create the [data-empty] placeholder.
|
|
307
|
+
await raf();
|
|
308
|
+
expect(el.querySelector(':scope > [data-empty]')).toBeNull();
|
|
309
|
+
// Consumer's native <table> survives untouched.
|
|
310
|
+
expect(el.querySelector(':scope > table')).not.toBeNull();
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('raw mode does NOT inject [data-header] or [data-body] rowgroups', async () => {
|
|
314
|
+
const el = mount('<table-ui raw><table><tr><td>x</td></tr></table></table-ui>');
|
|
315
|
+
await raf();
|
|
316
|
+
expect(el.querySelector(':scope > [data-header]')).toBeNull();
|
|
317
|
+
expect(el.querySelector(':scope > [data-body]')).toBeNull();
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it('raw mode preserves consumer markup even when .columns + .data are set', async () => {
|
|
321
|
+
const el = mount('<table-ui raw><table id="consumer"><tr><td>consumer-owned</td></tr></table></table-ui>');
|
|
322
|
+
el.columns = COLS;
|
|
323
|
+
el.data = ROWS;
|
|
324
|
+
await raf();
|
|
325
|
+
// The consumer's native <table> is still the only table-shaped child.
|
|
326
|
+
expect(el.querySelector('#consumer')).not.toBeNull();
|
|
327
|
+
expect(el.querySelectorAll(':scope > [role="rowgroup"]').length).toBe(0);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('non-raw mode (default) still injects header + body rowgroups', async () => {
|
|
331
|
+
const el = mount('<table-ui></table-ui>');
|
|
332
|
+
el.columns = COLS;
|
|
333
|
+
el.data = ROWS;
|
|
334
|
+
await raf();
|
|
335
|
+
expect(el.querySelector(':scope > [data-header]')).not.toBeNull();
|
|
336
|
+
expect(el.querySelector(':scope > [data-body]')).not.toBeNull();
|
|
337
|
+
});
|
|
338
|
+
});
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
4
4
|
name: UITable
|
|
5
5
|
tag: table-ui
|
|
6
|
+
status: stable
|
|
6
7
|
component: Table
|
|
7
8
|
category: agent
|
|
8
9
|
version: 1
|
|
@@ -54,7 +55,19 @@ props:
|
|
|
54
55
|
type: number
|
|
55
56
|
default: 0
|
|
56
57
|
raw:
|
|
57
|
-
description:
|
|
58
|
+
description: >-
|
|
59
|
+
Visual-only passthrough — applies `<table-ui>`'s chrome reset
|
|
60
|
+
(background / border / border-radius all transparent) AND
|
|
61
|
+
short-circuits the data lifecycle entirely. The consumer
|
|
62
|
+
owns the body shape: no header injection, no row reconciliation
|
|
63
|
+
from `.data`, no empty-state / loading overlays, no aggregation
|
|
64
|
+
or pagination footers. Use raw when embedding `<table-ui>` inside
|
|
65
|
+
surfaces that supply their own chrome (e.g. `<card-ui><section
|
|
66
|
+
bleed>`), or when wrapping a consumer-authored native `<table>`
|
|
67
|
+
for design-token styling without the framework's data semantics.
|
|
68
|
+
Pre-v0.6.33 (FB-53 §2) `raw` was visual-only and the data lifecycle
|
|
69
|
+
still ran — wrapping a `.data`-unset native table produced a
|
|
70
|
+
phantom "No data" overlay. v0.6.33+ matches the documented contract.
|
|
58
71
|
type: boolean
|
|
59
72
|
default: false
|
|
60
73
|
reflect: true
|
package/components/tabs/tab.yaml
CHANGED
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"required": [
|
|
43
|
-
"component"
|
|
43
|
+
"component",
|
|
44
|
+
"value"
|
|
44
45
|
],
|
|
45
46
|
"unevaluatedProperties": false,
|
|
46
47
|
"x-adiaui": {
|
|
@@ -92,6 +93,7 @@
|
|
|
92
93
|
"name": "idle"
|
|
93
94
|
}
|
|
94
95
|
],
|
|
96
|
+
"status": "stable",
|
|
95
97
|
"synonyms": {
|
|
96
98
|
"layout": [
|
|
97
99
|
"split",
|
package/components/tabs/tabs.css
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
--tabs-border: transparent;
|
|
5
5
|
--tabs-bg: transparent;
|
|
6
6
|
--tabs-radius: var(--a-radius-md);
|
|
7
|
-
--tabs-button-height:
|
|
7
|
+
--tabs-button-height: var(--a-size);
|
|
8
8
|
--tabs-button-px: var(--a-space-2);
|
|
9
9
|
--tabs-font-size: var(--a-ui-md);
|
|
10
10
|
--tabs-gap: var(--a-space-1);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
4
4
|
name: UITabs
|
|
5
5
|
tag: tabs-ui
|
|
6
|
+
status: stable
|
|
6
7
|
component: Tabs
|
|
7
8
|
category: container
|
|
8
9
|
version: 1
|
|
@@ -28,6 +29,7 @@ props:
|
|
|
28
29
|
value:
|
|
29
30
|
description: Value of the currently active tab. Set programmatically or auto-assigned to the first
|
|
30
31
|
non-disabled tab on connect.
|
|
32
|
+
required: true
|
|
31
33
|
type: string
|
|
32
34
|
default: ""
|
|
33
35
|
events:
|
package/components/tag/tag.css
CHANGED
|
@@ -55,7 +55,12 @@ tag-ui[removable]:not([disabled]):hover {
|
|
|
55
55
|
transition: background var(--tag-duration) var(--tag-easing), color var(--tag-duration) var(--tag-easing);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
/* `[text]` attribute selector gates the ::after so consumers using
|
|
59
|
+
slotted content (`<tag-ui>Beta</tag-ui>`) don't get an empty
|
|
60
|
+
pseudo-element flex item — which would otherwise inherit the
|
|
61
|
+
host's `gap` and add a phantom `--tag-gap`-wide trailing space
|
|
62
|
+
after the slotted content. Mirrors `button.css` line ~103. */
|
|
63
|
+
:scope[text]::after {
|
|
59
64
|
content: attr(text);
|
|
60
65
|
}
|
|
61
66
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tag-ui regression tests.
|
|
3
|
+
*
|
|
4
|
+
* Source-grep contract for the `content: attr(text)` gating pattern.
|
|
5
|
+
* Pre-fix (ungated `:scope::after { content: attr(text) }`), an empty
|
|
6
|
+
* `attr(text)` still generated a zero-width pseudo-element flex item,
|
|
7
|
+
* and the host's `inline-flex` + `gap` added a phantom `--tag-gap`
|
|
8
|
+
* trailing space after slotted content like `<tag-ui>Beta</tag-ui>`.
|
|
9
|
+
* The fix gates the pseudo-element on `[text]` attribute presence, so
|
|
10
|
+
* slot-content consumers don't pay the gap cost.
|
|
11
|
+
*
|
|
12
|
+
* jsdom doesn't evaluate `@scope` rules via `getComputedStyle()`, so
|
|
13
|
+
* we validate the CSS source shape directly (same recipe as
|
|
14
|
+
* description-list.test.js and text.test.js).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { describe, it, expect } from 'vitest';
|
|
18
|
+
import { readFileSync } from 'node:fs';
|
|
19
|
+
import { fileURLToPath } from 'node:url';
|
|
20
|
+
import { dirname, resolve } from 'node:path';
|
|
21
|
+
|
|
22
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const TAG_CSS = readFileSync(resolve(HERE, 'tag.css'), 'utf8');
|
|
24
|
+
|
|
25
|
+
describe('tag-ui — content: attr(text) gating', () => {
|
|
26
|
+
it('gates the ::after pseudo-element on [text] attribute presence', () => {
|
|
27
|
+
// The fixed rule: `:scope[text]::after { content: attr(text); }`
|
|
28
|
+
expect(TAG_CSS).toMatch(/:scope\[text\]::after\s*\{[^}]*content:\s*attr\(text\)/);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('does NOT carry an ungated :scope::after with content: attr(text)', () => {
|
|
32
|
+
// The pre-fix shape would add phantom flex-gap space after slotted
|
|
33
|
+
// content. Match the bare `:scope::after` form (no attribute
|
|
34
|
+
// selector chained) followed by the attr(text) declaration.
|
|
35
|
+
expect(TAG_CSS).not.toMatch(/:scope::after\s*\{[^}]*content:\s*attr\(text\)/);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('host :scope still declares the flex + gap layout (gap is real, just no longer applied to an empty pseudo)', () => {
|
|
39
|
+
// Sanity check that the fix didn't accidentally remove the host
|
|
40
|
+
// flex/gap declarations — those are still load-bearing for the
|
|
41
|
+
// [icon] + [dismiss] slot rendering and for proper :scope[text]
|
|
42
|
+
// gap rendering when text IS set.
|
|
43
|
+
expect(TAG_CSS).toMatch(/:scope\s*\{[^}]*display:\s*inline-flex/);
|
|
44
|
+
expect(TAG_CSS).toMatch(/:scope\s*\{[^}]*gap:\s*var\(--tag-gap\)/);
|
|
45
|
+
});
|
|
46
|
+
});
|
package/components/tag/tag.yaml
CHANGED
package/core/icons-phosphor.js
CHANGED
|
@@ -118,10 +118,16 @@ if (hasViteGlob) {
|
|
|
118
118
|
// never tries to pre-resolve it in dev (where the file doesn't exist).
|
|
119
119
|
const manifestSpec = './icons-manifest.js';
|
|
120
120
|
import(/* @vite-ignore */ manifestSpec).then(({ default: manifest }) => {
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
// `cdn` is an optional key added by bundle-js.mjs for CDN-distributed
|
|
122
|
+
// bundles. When present, SVGs are fetched from the CDN origin rather than
|
|
123
|
+
// /node_modules/ (which only exists on localhost / in a bundler context).
|
|
124
|
+
const { cdn: cdnBase, ...weights } = manifest;
|
|
125
|
+
const modules = Object.fromEntries(Object.entries(weights).map(([weight, names]) => {
|
|
126
|
+
const base = cdnBase
|
|
127
|
+
? `${cdnBase}${weight}/`
|
|
128
|
+
: `/node_modules/@phosphor-icons/core/assets/${weight}/`;
|
|
123
129
|
const entries = names.map(name => {
|
|
124
|
-
const path =
|
|
130
|
+
const path = base + name;
|
|
125
131
|
const loader = () => fetch(path).then(r => r.ok ? r.text() : Promise.reject(new Error(`icon fetch failed: ${path}`)));
|
|
126
132
|
return [path, loader];
|
|
127
133
|
});
|