@adia-ai/web-components 0.5.7 → 0.5.9
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/USAGE.md +218 -0
- package/components/accordion/accordion.d.ts +22 -1
- package/components/action-list/action-list.d.ts +14 -1
- package/components/agent-artifact/agent-artifact.d.ts +1 -1
- package/components/agent-feedback-bar/agent-feedback-bar.d.ts +1 -1
- package/components/agent-questions/agent-questions.d.ts +1 -1
- package/components/agent-reasoning/agent-reasoning.d.ts +1 -1
- package/components/agent-suggestions/agent-suggestions.d.ts +1 -1
- package/components/agent-trace/agent-trace.d.ts +1 -1
- package/components/alert/alert.d.ts +1 -1
- package/components/avatar/avatar.d.ts +8 -1
- package/components/badge/badge.d.ts +1 -1
- package/components/block/block.d.ts +1 -1
- package/components/breadcrumb/breadcrumb.d.ts +1 -1
- package/components/button/button.d.ts +1 -1
- package/components/canvas/canvas.d.ts +1 -1
- package/components/card/card.d.ts +1 -1
- package/components/chart/chart.d.ts +1 -1
- package/components/chart-legend/chart-legend.d.ts +1 -1
- package/components/chat-thread/chat-thread.d.ts +40 -1
- package/components/code/code.css +1 -1
- package/components/col/col.a2ui.json +4 -4
- package/components/col/col.d.ts +2 -2
- package/components/col/col.yaml +2 -2
- package/components/command/command.d.ts +1 -1
- package/components/demo-toggle/demo-toggle.a2ui.json +3 -1
- package/components/demo-toggle/demo-toggle.d.ts +1 -1
- package/components/demo-toggle/demo-toggle.yaml +2 -0
- package/components/description-list/description-list.d.ts +1 -1
- package/components/divider/divider.d.ts +1 -1
- package/components/drawer/drawer.d.ts +1 -1
- package/components/embed/embed.d.ts +1 -1
- package/components/empty-state/class.js +10 -4
- package/components/empty-state/empty-state.a2ui.json +5 -0
- package/components/empty-state/empty-state.css +36 -0
- package/components/empty-state/empty-state.d.ts +6 -1
- package/components/empty-state/empty-state.test.js +77 -0
- package/components/empty-state/empty-state.yaml +9 -0
- package/components/feed/feed.css +2 -2
- package/components/feed/feed.d.ts +29 -5
- package/components/field/field.d.ts +1 -1
- package/components/fields/fields.a2ui.json +3 -1
- package/components/fields/fields.d.ts +1 -1
- package/components/fields/fields.yaml +2 -0
- package/components/grid/grid.d.ts +1 -1
- package/components/heatmap/heatmap.d.ts +1 -1
- package/components/icon/icon.d.ts +1 -1
- package/components/image/image.d.ts +1 -1
- package/components/input/class.js +2 -1
- package/components/input/input.a2ui.json +5 -0
- package/components/input/input.test.js +99 -0
- package/components/input/input.yaml +14 -0
- package/components/inspector/inspector.d.ts +1 -1
- package/components/kbd/kbd.d.ts +1 -1
- package/components/link/link.d.ts +1 -1
- package/components/list/list.d.ts +10 -1
- package/components/menu/menu-divider.a2ui.json +41 -0
- package/components/menu/menu-divider.yaml +15 -0
- package/components/menu/menu-item.a2ui.json +77 -0
- package/components/menu/menu-item.yaml +45 -0
- package/components/menu/menu.d.ts +17 -1
- package/components/modal/modal.d.ts +1 -1
- package/components/nav/nav.a2ui.json +6 -1
- package/components/nav/nav.css +1 -1
- package/components/nav/nav.d.ts +1 -1
- package/components/nav/nav.yaml +6 -0
- package/components/nav-group/nav-group.a2ui.json +5 -1
- package/components/nav-group/nav-group.css +1 -1
- package/components/nav-group/nav-group.d.ts +1 -1
- package/components/nav-group/nav-group.yaml +5 -0
- package/components/nav-item/nav-item.a2ui.json +4 -1
- package/components/nav-item/nav-item.css +1 -1
- package/components/nav-item/nav-item.d.ts +1 -1
- package/components/nav-item/nav-item.yaml +4 -0
- package/components/noodles/noodles.d.ts +1 -1
- package/components/page/page.d.ts +1 -1
- package/components/pagination/pagination.d.ts +1 -1
- package/components/pane/pane.d.ts +1 -1
- package/components/pipeline-status/pipeline-status.d.ts +1 -1
- package/components/popover/popover.d.ts +1 -1
- package/components/progress/progress.d.ts +1 -1
- package/components/progress-row/progress-row.d.ts +1 -1
- package/components/range/range.css +1 -1
- package/components/richtext/richtext.a2ui.json +4 -4
- package/components/richtext/richtext.d.ts +2 -2
- package/components/richtext/richtext.yaml +2 -2
- package/components/row/row.d.ts +1 -1
- package/components/segment/segment.d.ts +1 -1
- package/components/select/class.js +28 -0
- package/components/select/select.css +1 -1
- package/components/select/select.yaml +28 -0
- package/components/skeleton/skeleton.d.ts +1 -1
- package/components/slider/class.js +20 -50
- package/components/slider/slider.css +1 -1
- package/components/stack/stack.d.ts +1 -1
- package/components/step-progress/step-progress.d.ts +1 -1
- package/components/stepper/stepper-item.a2ui.json +74 -0
- package/components/stepper/stepper-item.yaml +45 -0
- package/components/stepper/stepper.d.ts +13 -1
- package/components/stream/stream.d.ts +1 -1
- package/components/swatch/swatch.css +1 -1
- package/components/swatch/swatch.d.ts +1 -1
- package/components/swiper/swiper.d.ts +1 -1
- package/components/switch/switch.css +1 -1
- package/components/table/table.d.ts +1 -1
- package/components/table-toolbar/table-toolbar.d.ts +1 -1
- package/components/tabs/tabs.d.ts +12 -1
- package/components/tag/tag.d.ts +1 -1
- package/components/text/text.d.ts +1 -1
- package/components/textarea/class.js +7 -1
- package/components/textarea/textarea.a2ui.json +5 -0
- package/components/textarea/textarea.yaml +14 -0
- package/components/timeline/timeline.d.ts +20 -1
- package/components/toast/class.js +9 -0
- package/components/toast/toast.d.ts +9 -5
- package/components/toast/toast.yaml +16 -0
- package/components/toggle-group/toggle-group.d.ts +12 -1
- package/components/toggle-group/toggle-option.a2ui.json +61 -0
- package/components/toggle-group/toggle-option.yaml +33 -0
- package/components/toggle-scheme/toggle-scheme.d.ts +1 -1
- package/components/toolbar/toolbar-group.a2ui.json +41 -0
- package/components/toolbar/toolbar-group.yaml +16 -0
- package/components/toolbar/toolbar.d.ts +4 -1
- package/components/tooltip/tooltip.css +2 -2
- package/components/tooltip/tooltip.d.ts +1 -1
- package/components/tree/tree.css +1 -1
- package/components/tree/tree.d.ts +18 -1
- package/core/form.js +93 -0
- package/core/signals.d.ts +28 -0
- package/index.d.ts +2 -2
- package/package.json +1 -1
- package/styles/colors/semantics.css +6 -0
- package/styles/tokens.css +3 -0
- package/styles/typography.css +5 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/drawer
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/embed
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -26,9 +26,13 @@ import { UIElement } from '../../core/element.js';
|
|
|
26
26
|
|
|
27
27
|
export class UIEmptyState extends UIElement {
|
|
28
28
|
static properties = {
|
|
29
|
-
icon: { type: String,
|
|
30
|
-
heading: { type: String,
|
|
31
|
-
description: { type: String,
|
|
29
|
+
icon: { type: String, default: '', reflect: true },
|
|
30
|
+
heading: { type: String, default: '', reflect: true },
|
|
31
|
+
description: { type: String, default: '', reflect: true },
|
|
32
|
+
// §223 (v0.5.9): minimal layout — single-line muted (no centered column,
|
|
33
|
+
// no padding bump, no icon-size lg). Use for inline empty-table-row /
|
|
34
|
+
// inline placeholder cells where the canvas placeholder is too loud.
|
|
35
|
+
minimal: { type: Boolean, default: false, reflect: true },
|
|
32
36
|
};
|
|
33
37
|
|
|
34
38
|
static template = () => null;
|
|
@@ -47,7 +51,9 @@ export class UIEmptyState extends UIElement {
|
|
|
47
51
|
if (!this.#iconEl) {
|
|
48
52
|
this.#iconEl = this.#stampMark(document.createElement('icon-ui'));
|
|
49
53
|
this.#iconEl.setAttribute('slot', 'icon');
|
|
50
|
-
|
|
54
|
+
// §223 (v0.5.9): minimal layout sizes the icon inline; non-minimal
|
|
55
|
+
// keeps the canonical lg badge.
|
|
56
|
+
if (!this.minimal) this.#iconEl.setAttribute('size', 'lg');
|
|
51
57
|
this.insertBefore(this.#iconEl, this.firstChild);
|
|
52
58
|
}
|
|
53
59
|
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
"description": "Icon name displayed above the heading",
|
|
31
31
|
"type": "string",
|
|
32
32
|
"default": ""
|
|
33
|
+
},
|
|
34
|
+
"minimal": {
|
|
35
|
+
"description": "§223 (v0.5.9). Single-line muted layout — drops centered-column chrome\n(no vertical padding, no row-stack, no icon-size bump). Useful for\ninline empty-table-row / inline empty-list / placeholder cells where\nthe full-canvas placeholder is too prominent.",
|
|
36
|
+
"type": "boolean",
|
|
37
|
+
"default": false
|
|
33
38
|
}
|
|
34
39
|
},
|
|
35
40
|
"required": [
|
|
@@ -55,4 +55,40 @@
|
|
|
55
55
|
[slot="action"] {
|
|
56
56
|
margin-top: var(--empty-state-action-mt);
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
/* ── §223 (v0.5.9): [minimal] — single-line muted layout ──
|
|
60
|
+
Drops centered-column chrome (no canvas-style padding, no flex-column
|
|
61
|
+
stack). Renders as `[icon] heading [description]` inline in muted-fg.
|
|
62
|
+
Useful for inline placeholder rows / cells where the full placeholder
|
|
63
|
+
would be too loud. */
|
|
64
|
+
:scope[minimal] {
|
|
65
|
+
flex-direction: row;
|
|
66
|
+
align-items: baseline;
|
|
67
|
+
text-align: start;
|
|
68
|
+
padding: var(--a-space-2) var(--a-space-3);
|
|
69
|
+
gap: var(--a-space-2);
|
|
70
|
+
color: var(--a-fg-muted);
|
|
71
|
+
font-size: var(--a-ui-size);
|
|
72
|
+
}
|
|
73
|
+
:scope[minimal] [slot="icon"] {
|
|
74
|
+
font-size: 1em;
|
|
75
|
+
color: inherit;
|
|
76
|
+
flex-shrink: 0;
|
|
77
|
+
}
|
|
78
|
+
:scope[minimal] [slot="heading"] {
|
|
79
|
+
font-size: inherit;
|
|
80
|
+
font-weight: var(--a-weight-normal);
|
|
81
|
+
color: inherit;
|
|
82
|
+
line-height: inherit;
|
|
83
|
+
}
|
|
84
|
+
:scope[minimal] [slot="description"] {
|
|
85
|
+
font-size: inherit;
|
|
86
|
+
color: inherit;
|
|
87
|
+
line-height: inherit;
|
|
88
|
+
max-width: none;
|
|
89
|
+
}
|
|
90
|
+
:scope[minimal] [slot="action"] {
|
|
91
|
+
margin-top: 0;
|
|
92
|
+
margin-inline-start: auto;
|
|
93
|
+
}
|
|
58
94
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/empty-state
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -19,4 +19,9 @@ export class UIEmptyState extends UIElement {
|
|
|
19
19
|
heading: string;
|
|
20
20
|
/** Icon name displayed above the heading */
|
|
21
21
|
icon: string;
|
|
22
|
+
/** §223 (v0.5.9). Single-line muted layout — drops centered-column chrome
|
|
23
|
+
(no vertical padding, no row-stack, no icon-size bump). Useful for
|
|
24
|
+
inline empty-table-row / inline empty-list / placeholder cells where
|
|
25
|
+
the full-canvas placeholder is too prominent. */
|
|
26
|
+
minimal: boolean;
|
|
22
27
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* empty-state-ui — focused unit tests for the §223 (v0.5.9) `minimal`
|
|
3
|
+
* boolean prop.
|
|
4
|
+
*
|
|
5
|
+
* Pre-§223 only the centered-column canvas layout existed. §223 adds
|
|
6
|
+
* an inline single-row muted layout for placeholder cells / table rows
|
|
7
|
+
* where the full-canvas placeholder is too prominent (R13 §4).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
11
|
+
import '../../core/element.js';
|
|
12
|
+
import './empty-state.js';
|
|
13
|
+
|
|
14
|
+
const tick = () => new Promise((r) => queueMicrotask(r));
|
|
15
|
+
|
|
16
|
+
function mount(html) {
|
|
17
|
+
const wrap = document.createElement('div');
|
|
18
|
+
wrap.innerHTML = html;
|
|
19
|
+
document.body.appendChild(wrap);
|
|
20
|
+
return wrap.firstElementChild;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('empty-state-ui — §223 (v0.5.9) minimal mode', () => {
|
|
24
|
+
beforeEach(() => { document.body.innerHTML = ''; });
|
|
25
|
+
|
|
26
|
+
it('defaults to non-minimal (canvas-style placeholder)', () => {
|
|
27
|
+
const el = mount('<empty-state-ui heading="No results"></empty-state-ui>');
|
|
28
|
+
expect(el.minimal).toBe(false);
|
|
29
|
+
expect(el.hasAttribute('minimal')).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('reflects [minimal] attribute to the property', () => {
|
|
33
|
+
const el = mount('<empty-state-ui minimal heading="No matches"></empty-state-ui>');
|
|
34
|
+
expect(el.minimal).toBe(true);
|
|
35
|
+
expect(el.hasAttribute('minimal')).toBe(true);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('stamps icon WITHOUT size="lg" when minimal', async () => {
|
|
39
|
+
const el = mount('<empty-state-ui minimal icon="search" heading="No matches"></empty-state-ui>');
|
|
40
|
+
await tick();
|
|
41
|
+
const icon = el.querySelector(':scope > [slot="icon"]');
|
|
42
|
+
expect(icon).not.toBeNull();
|
|
43
|
+
// Minimal layout uses 1em inherited font-size; non-minimal stamps lg.
|
|
44
|
+
expect(icon.hasAttribute('size')).toBe(false);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('stamps icon WITH size="lg" when not minimal (no regression)', async () => {
|
|
48
|
+
const el = mount('<empty-state-ui icon="search" heading="No matches"></empty-state-ui>');
|
|
49
|
+
await tick();
|
|
50
|
+
const icon = el.querySelector(':scope > [slot="icon"]');
|
|
51
|
+
expect(icon).not.toBeNull();
|
|
52
|
+
expect(icon.getAttribute('size')).toBe('lg');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('stamps heading + description slots in both modes', async () => {
|
|
56
|
+
const minimal = mount('<empty-state-ui minimal heading="Empty" description="No rows"></empty-state-ui>');
|
|
57
|
+
const canvas = mount('<empty-state-ui heading="Empty" description="No rows"></empty-state-ui>');
|
|
58
|
+
await tick();
|
|
59
|
+
|
|
60
|
+
for (const el of [minimal, canvas]) {
|
|
61
|
+
const h = el.querySelector(':scope > [slot="heading"]');
|
|
62
|
+
const d = el.querySelector(':scope > [slot="description"]');
|
|
63
|
+
expect(h?.textContent).toBe('Empty');
|
|
64
|
+
expect(d?.textContent).toBe('No rows');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('honors a consumer-provided [slot="action"] child in either mode', () => {
|
|
69
|
+
const el = mount(`
|
|
70
|
+
<empty-state-ui minimal heading="Empty">
|
|
71
|
+
<button slot="action" data-test="reset">Reset</button>
|
|
72
|
+
</empty-state-ui>
|
|
73
|
+
`);
|
|
74
|
+
const action = el.querySelector(':scope > [slot="action"][data-test="reset"]');
|
|
75
|
+
expect(action).not.toBeNull();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -24,6 +24,15 @@ props:
|
|
|
24
24
|
description: Icon name displayed above the heading
|
|
25
25
|
type: string
|
|
26
26
|
default: ""
|
|
27
|
+
minimal:
|
|
28
|
+
description: |-
|
|
29
|
+
§223 (v0.5.9). Single-line muted layout — drops centered-column chrome
|
|
30
|
+
(no vertical padding, no row-stack, no icon-size bump). Useful for
|
|
31
|
+
inline empty-table-row / inline empty-list / placeholder cells where
|
|
32
|
+
the full-canvas placeholder is too prominent.
|
|
33
|
+
type: boolean
|
|
34
|
+
default: false
|
|
35
|
+
reflect: true
|
|
27
36
|
events: {}
|
|
28
37
|
slots:
|
|
29
38
|
action:
|
package/components/feed/feed.css
CHANGED
|
@@ -102,7 +102,7 @@ feed-item-ui[data-closing] {
|
|
|
102
102
|
--feed-item-duration: var(--a-duration);
|
|
103
103
|
--feed-item-easing: var(--a-easing-out);
|
|
104
104
|
--feed-item-gap: var(--a-space-3);
|
|
105
|
-
--feed-item-max-width:
|
|
105
|
+
--feed-item-max-width: 22rem; /* §230-bundle (v0.5.9): component-local. Was orphaned --a-feed-max-width — hoisted per RESPONSE-21 guidance. */
|
|
106
106
|
}
|
|
107
107
|
:scope[variant="info"] { --feed-item-fg: var(--a-info-fg); --feed-item-bg: var(--a-info-muted); }
|
|
108
108
|
:scope[variant="success"] { --feed-item-fg: var(--a-success-fg); --feed-item-bg: var(--a-success-muted); }
|
|
@@ -133,7 +133,7 @@ feed-item-ui[data-closing] {
|
|
|
133
133
|
gap: 0.125rem;
|
|
134
134
|
}
|
|
135
135
|
:scope > [slot="body"] strong {
|
|
136
|
-
font-weight: var(--a-
|
|
136
|
+
font-weight: var(--a-weight-semibold);
|
|
137
137
|
}
|
|
138
138
|
:scope > [data-feed-close] {
|
|
139
139
|
flex-shrink: 0;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/feed
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
import { UIElement } from '../../core/element.js';
|
|
14
14
|
|
|
15
|
-
export type
|
|
15
|
+
export type FeedContainerCloseEvent = CustomEvent<unknown>;
|
|
16
16
|
|
|
17
|
-
export class
|
|
17
|
+
export class UIFeedContainer extends UIElement {
|
|
18
18
|
/** Cap on simultaneously visible items per lane */
|
|
19
19
|
max: number;
|
|
20
20
|
/** Lane the feed renders into */
|
|
@@ -22,8 +22,32 @@ export class UIFeed extends UIElement {
|
|
|
22
22
|
|
|
23
23
|
addEventListener<K extends keyof HTMLElementEventMap>(
|
|
24
24
|
type: K,
|
|
25
|
-
listener: (this:
|
|
25
|
+
listener: (this: UIFeedContainer, ev: HTMLElementEventMap[K]) => unknown,
|
|
26
26
|
options?: boolean | AddEventListenerOptions,
|
|
27
27
|
): void;
|
|
28
|
-
addEventListener(type: 'close', listener: (ev:
|
|
28
|
+
addEventListener(type: 'close', listener: (ev: FeedContainerCloseEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type FeedItemCloseEvent = CustomEvent<unknown>;
|
|
32
|
+
|
|
33
|
+
export class UIFeedItem extends UIElement {
|
|
34
|
+
/** Render an x close button (default true for sticky, false for auto-fade) */
|
|
35
|
+
dismissible: boolean;
|
|
36
|
+
/** Auto-fade timer in ms; null/0 = sticky (requires user input) */
|
|
37
|
+
duration: number;
|
|
38
|
+
/** Optional emphasis line above text */
|
|
39
|
+
heading: string;
|
|
40
|
+
/** Optional leading icon name */
|
|
41
|
+
icon: string;
|
|
42
|
+
/** Body copy */
|
|
43
|
+
text: string;
|
|
44
|
+
/** Semantic variant */
|
|
45
|
+
variant: 'default' | 'info' | 'success' | 'warning' | 'danger';
|
|
46
|
+
|
|
47
|
+
addEventListener<K extends keyof HTMLElementEventMap>(
|
|
48
|
+
type: K,
|
|
49
|
+
listener: (this: UIFeedItem, ev: HTMLElementEventMap[K]) => unknown,
|
|
50
|
+
options?: boolean | AddEventListenerOptions,
|
|
51
|
+
): void;
|
|
52
|
+
addEventListener(type: 'close', listener: (ev: FeedItemCloseEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
29
53
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/field
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/fields
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -14,6 +14,8 @@ description: >-
|
|
|
14
14
|
The grid alignment lets siblings on the same row line up cleanly —
|
|
15
15
|
consistent label columns + consistent control columns — without
|
|
16
16
|
the wrap-flex jitter of <row-ui wrap>.
|
|
17
|
+
composes:
|
|
18
|
+
- field-ui
|
|
17
19
|
props:
|
|
18
20
|
inline:
|
|
19
21
|
description: >-
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/grid
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/heatmap
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/icon
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/image
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -601,7 +601,8 @@ export class UIInput extends UIFormElement {
|
|
|
601
601
|
this.value = text;
|
|
602
602
|
if (!this.#isNativePassword) this.#textEl.toggleAttribute('data-empty', !text);
|
|
603
603
|
this.syncValue(text);
|
|
604
|
-
|
|
604
|
+
// §220 (v0.5.9, FEEDBACK-14 §3): trailing-debounce when `throttle > 0`.
|
|
605
|
+
this.scheduleThrottledInput();
|
|
605
606
|
};
|
|
606
607
|
|
|
607
608
|
#onBeforeInput = (e) => {
|
|
@@ -146,6 +146,11 @@
|
|
|
146
146
|
"type": "string",
|
|
147
147
|
"default": ""
|
|
148
148
|
},
|
|
149
|
+
"throttle": {
|
|
150
|
+
"description": "§220 (v0.5.9, FEEDBACK-14 §3). Trailing-debounce on the `input`\nevent in milliseconds. When > 0, value mutates immediately + the UI\nstays responsive, but `input` dispatch is collapsed so only the\nfinal value in the throttle window emits. Useful for expensive\n`input`-driven computation (palette regen, large list filter,\nserver-side autocomplete). `change` fires unthrottled on blur /\nEnter / stepper commit; any pending `input` flushes before `change`\nso consumers see input→input→…→input→change ordering. Default 0\npreserves synchronous emission.",
|
|
151
|
+
"type": "number",
|
|
152
|
+
"default": 0
|
|
153
|
+
},
|
|
149
154
|
"value": {
|
|
150
155
|
"description": "Current input value, synced with contenteditable text surface. For `type=\"number\"`, this is the formatted numeric string; read `el.valueAsNumber` for the parsed Number.",
|
|
151
156
|
"type": "string",
|
|
@@ -121,3 +121,102 @@ describe('input-ui — §199 leading/trailing affordance slots', () => {
|
|
|
121
121
|
expect(text.textContent).toBe('Theme 1');
|
|
122
122
|
});
|
|
123
123
|
});
|
|
124
|
+
|
|
125
|
+
describe('input-ui — §220 (v0.5.9) throttle parity', () => {
|
|
126
|
+
beforeEach(() => { document.body.innerHTML = ''; });
|
|
127
|
+
|
|
128
|
+
it('inherits `throttle` property default 0 from UIFormElement', () => {
|
|
129
|
+
const el = mount('<input-ui></input-ui>');
|
|
130
|
+
expect(el.throttle).toBe(0);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('reflects [throttle] attribute to the property', () => {
|
|
134
|
+
const el = mount('<input-ui throttle="150"></input-ui>');
|
|
135
|
+
expect(el.throttle).toBe(150);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('dispatches `input` synchronously when throttle=0 (default)', async () => {
|
|
139
|
+
const el = mount('<input-ui></input-ui>');
|
|
140
|
+
await tick();
|
|
141
|
+
let count = 0;
|
|
142
|
+
// Filter for host-emitted CustomEvents (have detail.value); surface
|
|
143
|
+
// InputEvents bubble up too but have no detail property.
|
|
144
|
+
el.addEventListener('input', (e) => {
|
|
145
|
+
if (e.detail?.value !== undefined) count++;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Simulate user typing — set value + dispatch DOM input on the
|
|
149
|
+
// contenteditable surface so the host's #onInput handler fires.
|
|
150
|
+
const surface = el.querySelector('[slot="text"]');
|
|
151
|
+
surface.textContent = 'a';
|
|
152
|
+
surface.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
153
|
+
surface.textContent = 'ab';
|
|
154
|
+
surface.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
155
|
+
surface.textContent = 'abc';
|
|
156
|
+
surface.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
157
|
+
|
|
158
|
+
expect(count).toBe(3);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('collapses burst dispatches to one trailing `input` when throttle>0', async () => {
|
|
162
|
+
const el = mount('<input-ui throttle="20"></input-ui>');
|
|
163
|
+
await tick();
|
|
164
|
+
const events = [];
|
|
165
|
+
// Filter for host-emitted CustomEvents (have detail.value); surface
|
|
166
|
+
// InputEvents bubble up too but have no detail property.
|
|
167
|
+
el.addEventListener('input', (e) => {
|
|
168
|
+
if (e.detail?.value !== undefined) events.push(e.detail.value);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const surface = el.querySelector('[slot="text"]');
|
|
172
|
+
surface.textContent = 'a';
|
|
173
|
+
surface.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
174
|
+
surface.textContent = 'ab';
|
|
175
|
+
surface.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
176
|
+
surface.textContent = 'abc';
|
|
177
|
+
surface.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
178
|
+
|
|
179
|
+
expect(events).toEqual([]);
|
|
180
|
+
|
|
181
|
+
await new Promise((r) => setTimeout(r, 35));
|
|
182
|
+
expect(events).toEqual(['abc']);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('flushPendingInput() fires the pending dispatch synchronously', async () => {
|
|
186
|
+
const el = mount('<input-ui throttle="50"></input-ui>');
|
|
187
|
+
await tick();
|
|
188
|
+
const events = [];
|
|
189
|
+
// Filter for host-emitted CustomEvents (have detail.value); surface
|
|
190
|
+
// InputEvents bubble up too but have no detail property.
|
|
191
|
+
el.addEventListener('input', (e) => {
|
|
192
|
+
if (e.detail?.value !== undefined) events.push(e.detail.value);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const surface = el.querySelector('[slot="text"]');
|
|
196
|
+
surface.textContent = 'pending';
|
|
197
|
+
surface.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
198
|
+
|
|
199
|
+
expect(events).toEqual([]);
|
|
200
|
+
el.flushPendingInput();
|
|
201
|
+
expect(events).toEqual(['pending']);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('dropPendingInput() prevents the dispatch (used by disconnected)', async () => {
|
|
205
|
+
const el = mount('<input-ui throttle="20"></input-ui>');
|
|
206
|
+
await tick();
|
|
207
|
+
const events = [];
|
|
208
|
+
// Filter for host-emitted CustomEvents (have detail.value); surface
|
|
209
|
+
// InputEvents bubble up too but have no detail property.
|
|
210
|
+
el.addEventListener('input', (e) => {
|
|
211
|
+
if (e.detail?.value !== undefined) events.push(e.detail.value);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const surface = el.querySelector('[slot="text"]');
|
|
215
|
+
surface.textContent = 'gone';
|
|
216
|
+
surface.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
217
|
+
|
|
218
|
+
el.dropPendingInput();
|
|
219
|
+
await new Promise((r) => setTimeout(r, 30));
|
|
220
|
+
expect(events).toEqual([]);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
@@ -139,6 +139,20 @@ props:
|
|
|
139
139
|
description: Suffix text rendered after the text surface (e.g., unit like 'kg')
|
|
140
140
|
type: string
|
|
141
141
|
default: ''
|
|
142
|
+
throttle:
|
|
143
|
+
description: |-
|
|
144
|
+
§220 (v0.5.9, FEEDBACK-14 §3). Trailing-debounce on the `input`
|
|
145
|
+
event in milliseconds. When > 0, value mutates immediately + the UI
|
|
146
|
+
stays responsive, but `input` dispatch is collapsed so only the
|
|
147
|
+
final value in the throttle window emits. Useful for expensive
|
|
148
|
+
`input`-driven computation (palette regen, large list filter,
|
|
149
|
+
server-side autocomplete). `change` fires unthrottled on blur /
|
|
150
|
+
Enter / stepper commit; any pending `input` flushes before `change`
|
|
151
|
+
so consumers see input→input→…→input→change ordering. Default 0
|
|
152
|
+
preserves synchronous emission.
|
|
153
|
+
type: number
|
|
154
|
+
default: 0
|
|
155
|
+
reflect: true
|
|
142
156
|
value:
|
|
143
157
|
description: Current input value, synced with contenteditable text surface. For `type="number"`, this is the formatted
|
|
144
158
|
numeric string; read `el.valueAsNumber` for the parsed Number.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/inspector
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
package/components/kbd/kbd.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/kbd
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -28,7 +28,7 @@ wiring. ARIA role is "link" (set automatically by `<a>` element).
|
|
|
28
28
|
* @see https://ui-kit.exe.xyz/site/components/link
|
|
29
29
|
*
|
|
30
30
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
31
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
31
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
32
32
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
33
33
|
* regenerate; or hand-author this file fully if rich event types are
|
|
34
34
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @see https://ui-kit.exe.xyz/site/components/list
|
|
5
5
|
*
|
|
6
6
|
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
7
|
-
* the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
|
|
7
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
8
8
|
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
9
9
|
* regenerate; or hand-author this file fully if rich event types are
|
|
10
10
|
* needed beyond what the yaml `events:` block can express.
|
|
@@ -38,3 +38,12 @@ export class UIList extends UIElement {
|
|
|
38
38
|
): void;
|
|
39
39
|
addEventListener(type: 'selection-change', listener: (ev: ListSelectionChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
export class UIListItem extends UIElement {
|
|
43
|
+
/** Secondary line below the primary text. Subtle color. */
|
|
44
|
+
description: string;
|
|
45
|
+
/** Optional leading icon name (Phosphor). */
|
|
46
|
+
icon: string;
|
|
47
|
+
/** Primary text. Renders as semibold inline body. */
|
|
48
|
+
text: string;
|
|
49
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://adiaui.dev/a2ui/v0_9/components/MenuDivider.json",
|
|
4
|
+
"title": "MenuDivider",
|
|
5
|
+
"description": "Visual separator between groups of `<menu-item-ui>` rows. Renders as a horizontal rule with role=\"separator\".",
|
|
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": "MenuDivider"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"required": [
|
|
21
|
+
"component"
|
|
22
|
+
],
|
|
23
|
+
"unevaluatedProperties": false,
|
|
24
|
+
"x-adiaui": {
|
|
25
|
+
"anti_patterns": [],
|
|
26
|
+
"category": "navigation",
|
|
27
|
+
"composes": [],
|
|
28
|
+
"events": {},
|
|
29
|
+
"examples": [],
|
|
30
|
+
"keywords": [],
|
|
31
|
+
"name": "UIMenuDivider",
|
|
32
|
+
"related": [],
|
|
33
|
+
"slots": {},
|
|
34
|
+
"states": [],
|
|
35
|
+
"synonyms": {},
|
|
36
|
+
"tag": "menu-divider-ui",
|
|
37
|
+
"tokens": {},
|
|
38
|
+
"traits": [],
|
|
39
|
+
"version": 1
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Edit this file; run `npm run build:components` to regenerate a2ui.json.
|
|
2
|
+
#
|
|
3
|
+
# §228 (v0.5.9): authored to close the §229 baseline class-export-undeclared
|
|
4
|
+
# drift for UIMenuDivider. Ships as a sibling class in menu/class.js +
|
|
5
|
+
# is registered alongside UIMenu + UIMenuItem.
|
|
6
|
+
|
|
7
|
+
# Child component of <menu-ui>. Surface only inside that parent.
|
|
8
|
+
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
9
|
+
name: UIMenuDivider
|
|
10
|
+
tag: menu-divider-ui
|
|
11
|
+
component: MenuDivider
|
|
12
|
+
category: navigation
|
|
13
|
+
version: 1
|
|
14
|
+
description: |-
|
|
15
|
+
Visual separator between groups of `<menu-item-ui>` rows. Renders as a horizontal rule with role="separator".
|