@adia-ai/web-components 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/USAGE.md +42 -0
- package/components/accordion/accordion.a2ui.json +8 -2
- package/components/accordion/accordion.d.ts +7 -2
- package/components/accordion/accordion.yaml +8 -2
- package/components/accordion/class.js +6 -0
- package/components/agent-questions/agent-questions.yaml +2 -0
- package/components/agent-questions/class.js +6 -0
- package/components/agent-reasoning/agent-reasoning.yaml +5 -0
- package/components/agent-reasoning/class.js +6 -0
- package/components/agent-trace/agent-trace.js +6 -0
- package/components/agent-trace/agent-trace.yaml +3 -0
- package/components/calendar-picker/calendar-picker.yaml +4 -0
- package/components/calendar-picker/class.js +7 -0
- package/components/canvas/canvas.a2ui.json +1 -10
- package/components/canvas/canvas.d.ts +0 -6
- package/components/canvas/canvas.yaml +1 -7
- package/components/card/card.a2ui.json +1 -5
- package/components/card/card.d.ts +0 -9
- package/components/card/card.yaml +1 -3
- package/components/chat-thread/chat-input.a2ui.json +158 -0
- package/components/chat-thread/chat-input.yaml +251 -0
- package/components/check/class.js +1 -0
- package/components/color-picker/class.js +6 -0
- package/components/color-picker/color-picker.yaml +2 -0
- package/components/command/class.js +6 -0
- package/components/command/command.yaml +2 -0
- package/components/drawer/class.js +25 -3
- package/components/drawer/drawer.a2ui.json +13 -1
- package/components/drawer/drawer.d.ts +6 -1
- package/components/drawer/drawer.yaml +11 -1
- package/components/feed/feed-item.a2ui.json +86 -0
- package/components/pane/class.js +6 -0
- package/components/pane/pane.yaml +2 -0
- package/components/radio/class.js +1 -0
- package/components/row/row.a2ui.json +1 -5
- package/components/row/row.d.ts +0 -9
- package/components/row/row.yaml +1 -3
- package/components/select/class.js +7 -0
- package/components/select/select.yaml +2 -0
- package/components/slider/class.js +25 -0
- package/components/switch/class.js +1 -0
- package/components/table/class.js +6 -0
- package/components/table/table.a2ui.json +13 -0
- package/components/table/table.d.ts +9 -0
- package/components/table/table.yaml +13 -0
- package/components/tag/class.js +6 -0
- package/components/tag/tag.yaml +2 -0
- package/components/textarea/class.js +1 -0
- package/components/tree/class.js +6 -0
- package/components/tree/tree.yaml +2 -0
- package/components/upload/class.js +1 -0
- package/core/icons.d.ts +148 -0
- package/core/icons.js +148 -5
- package/core/icons.test.js +187 -0
- package/core/template.js +59 -3
- package/package.json +16 -2
package/USAGE.md
CHANGED
|
@@ -134,6 +134,33 @@ const tpl3 = html`<slider-ui .value=${minL.value * 100} min="0" max="100"></slid
|
|
|
134
134
|
|
|
135
135
|
The `.prop=` syntax sets the JS property (not the attribute). The `attr=` syntax sets an attribute. Both round-trip through the signal-backed setter, so either works for reactive updates from your side.
|
|
136
136
|
|
|
137
|
+
### Template attribute bindings — full / property / no-partial (§152, v0.5.3)
|
|
138
|
+
|
|
139
|
+
The `html\`` template literal supports three attribute-binding modes:
|
|
140
|
+
|
|
141
|
+
| Syntax | Behavior |
|
|
142
|
+
|---|---|
|
|
143
|
+
| `attr="${value}"` (or just `attr=${value}`) | **Full attribute replacement.** The entire attribute value is the placeholder. The string `value` becomes the attribute value via `setAttribute()`. Works for any string-typed attribute. |
|
|
144
|
+
| `.prop=${value}` (leading dot) | **Property assignment.** Sets `element.prop = value` directly (bypasses attributes). Preferred for objects, functions, arrays, signals — anything that doesn't serialize to a string. |
|
|
145
|
+
| `attr="prefix-${value}-suffix"` | **NOT SUPPORTED.** Partial interpolation is not implemented — the attribute-part contract is whole-value-only. The framework will `console.warn` at scan time. Compute the full attribute value as a single expression and interpolate the whole. |
|
|
146
|
+
|
|
147
|
+
Example of the partial-interpolation pitfall and its fix:
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
// ❌ NOT SUPPORTED — partial attribute interpolation
|
|
151
|
+
// Will console.warn at scan time + the `{{p:0}}` placeholder text reaches the DOM as literal.
|
|
152
|
+
html`<div style="background:${bgCss}; color:${labelColor}">…</div>`;
|
|
153
|
+
|
|
154
|
+
// ✅ Compute the full attribute as one expression
|
|
155
|
+
const swatchStyle = `background:${bgCss}; color:${labelColor};`;
|
|
156
|
+
html`<div style="${swatchStyle}">…</div>`;
|
|
157
|
+
|
|
158
|
+
// ✅ Or use property binding with an object (CSSStyleDeclaration-like)
|
|
159
|
+
html`<div .style=${{ background: bgCss, color: labelColor }}>…</div>`;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Why the constraint exists**: the engine pre-processes static-string chunks to insert placeholder markers (`{{p:N}}` for attribute positions, `<!--p:N-->` for content positions). At scan time, the post-substitution attribute value must match `^\{\{p:N\}\}$` for the placeholder-to-part mapping to register. Sub-string placeholders break this contract. The runtime guard (added v0.5.3 §152) makes the failure mode explicit instead of silent.
|
|
163
|
+
|
|
137
164
|
### Using React, Lit, Vue, Svelte, etc.
|
|
138
165
|
|
|
139
166
|
When the binding system isn't AdiaUI's `html` tag, the rule generalizes:
|
|
@@ -186,6 +213,21 @@ html`<slider-ui .value=${(v) => v * 100} />`
|
|
|
186
213
|
|
|
187
214
|
The rule: **inside `.prop=${…}`, anything that reads `.value` directly is a snapshot. Wrap in `() => …` to get reactivity.**
|
|
188
215
|
|
|
216
|
+
**Dev-mode guard (v0.5.3 §153 / FEEDBACK-07 §3):** primitives that read their value synchronously (e.g. `<slider-ui>`) emit a `console.warn` when their `.value` is assigned a function — this catches the case where the function wasn't wrapped by the template engine (e.g. assigned imperatively `sliderEl.value = fn`, or returned by a framework binding that doesn't recognize the AdiaUI reactivity contract). The warn names the two correct patterns:
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
[slider-ui] .value received a function. Did you mean:
|
|
220
|
+
.value=${fn()} ← call the function to get the current value
|
|
221
|
+
.value=${signal.value} ← read the signal's current value
|
|
222
|
+
Functions are not auto-invoked at render time; the slider reads
|
|
223
|
+
.value synchronously. See USAGE.md "Reactive binding" for the
|
|
224
|
+
parent-template-re-read pattern that works across frameworks.
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
If you see this warn in dev console, either:
|
|
228
|
+
1. You're using AdiaUI's `html\``: ensure the function reads at least one signal value (otherwise the function isn't reactive, just expensive). Pattern A above with `() => signal.value * 100` is correct.
|
|
229
|
+
2. You're using a different framework (React/Lit/Vue): the binding system isn't AdiaUI's `html` engine, so functions don't auto-wrap. Use Pattern B from the parent-template-re-read recipe — read the signal in the parent's render, pass the extracted value imperatively or via your framework's binding.
|
|
230
|
+
|
|
189
231
|
For more complex derived values, `computed()` gives you a named reactive holder you can pass directly or read in templates:
|
|
190
232
|
|
|
191
233
|
```js
|
|
@@ -33,8 +33,14 @@
|
|
|
33
33
|
"icon-ui"
|
|
34
34
|
],
|
|
35
35
|
"events": {
|
|
36
|
-
"
|
|
37
|
-
"description": "Fired when the
|
|
36
|
+
"toggle": {
|
|
37
|
+
"description": "Fired when the accordion panel opens or closes (single-pane accordion-ui dispatch — multi-pane group emits the same event per child).",
|
|
38
|
+
"detail": {
|
|
39
|
+
"open": {
|
|
40
|
+
"description": "New open state of the panel.",
|
|
41
|
+
"type": "boolean"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
38
44
|
}
|
|
39
45
|
},
|
|
40
46
|
"examples": [
|
|
@@ -12,7 +12,12 @@
|
|
|
12
12
|
|
|
13
13
|
import { UIElement } from '../../core/element.js';
|
|
14
14
|
|
|
15
|
-
export
|
|
15
|
+
export interface AccordionToggleEventDetail {
|
|
16
|
+
/** New open state of the panel. */
|
|
17
|
+
open: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type AccordionToggleEvent = CustomEvent<AccordionToggleEventDetail>;
|
|
16
21
|
|
|
17
22
|
export class UIAccordion extends UIElement {
|
|
18
23
|
/** Allow multiple panels to be open simultaneously */
|
|
@@ -23,5 +28,5 @@ export class UIAccordion extends UIElement {
|
|
|
23
28
|
listener: (this: UIAccordion, ev: HTMLElementEventMap[K]) => unknown,
|
|
24
29
|
options?: boolean | AddEventListenerOptions,
|
|
25
30
|
): void;
|
|
26
|
-
addEventListener(type: '
|
|
31
|
+
addEventListener(type: 'toggle', listener: (ev: AccordionToggleEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
27
32
|
}
|
|
@@ -17,8 +17,12 @@ props:
|
|
|
17
17
|
type: boolean
|
|
18
18
|
default: false
|
|
19
19
|
events:
|
|
20
|
-
|
|
21
|
-
description: Fired when the
|
|
20
|
+
toggle:
|
|
21
|
+
description: Fired when the accordion panel opens or closes (single-pane accordion-ui dispatch — multi-pane group emits the same event per child).
|
|
22
|
+
detail:
|
|
23
|
+
open:
|
|
24
|
+
type: boolean
|
|
25
|
+
description: New open state of the panel.
|
|
22
26
|
slots:
|
|
23
27
|
default:
|
|
24
28
|
description: pane-ui children
|
|
@@ -27,6 +31,8 @@ states:
|
|
|
27
31
|
description: Default, ready for interaction.
|
|
28
32
|
traits: []
|
|
29
33
|
tokens: {}
|
|
34
|
+
requiredIcons:
|
|
35
|
+
- caret-down
|
|
30
36
|
a2ui:
|
|
31
37
|
rules: []
|
|
32
38
|
anti_patterns: []
|
|
@@ -30,6 +30,12 @@ import { UIElement } from '../../core/element.js';
|
|
|
30
30
|
// ── Accordion Container ────────────────────────────────────────
|
|
31
31
|
|
|
32
32
|
export class UIAccordion extends UIElement {
|
|
33
|
+
// §154 (v0.5.3): Phosphor icons this primitive auto-stamps (without
|
|
34
|
+
// consumer markup). Aggregated by installIconLoadersForRegistered()
|
|
35
|
+
// across all defined elements. Audited by check-required-icons.mjs
|
|
36
|
+
// (slot 11). Per FEEDBACK-06 §4 + FEEDBACK-07 §4.
|
|
37
|
+
static requiredIcons = ['caret-down'];
|
|
38
|
+
|
|
33
39
|
static properties = {
|
|
34
40
|
multiple: { type: Boolean, default: false, reflect: true },
|
|
35
41
|
};
|
|
@@ -50,6 +50,12 @@ function escapeAttr(s) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export class UIAgentQuestions extends UIElement {
|
|
53
|
+
// §154 (v0.5.3): Phosphor icons this primitive auto-stamps (without
|
|
54
|
+
// consumer markup). Aggregated by installIconLoadersForRegistered()
|
|
55
|
+
// across all defined elements. Audited by check-required-icons.mjs
|
|
56
|
+
// (slot 11). Per FEEDBACK-06 §4 + FEEDBACK-07 §4.
|
|
57
|
+
static requiredIcons = ['check'];
|
|
58
|
+
|
|
53
59
|
static properties = {
|
|
54
60
|
multi: { type: Boolean, default: false, reflect: true },
|
|
55
61
|
question: { type: String, default: '', reflect: true },
|
|
@@ -77,6 +77,12 @@ function formatDuration(ms) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export class UIAgentReasoning extends UIElement {
|
|
80
|
+
// §154 (v0.5.3): Phosphor icons this primitive auto-stamps (without
|
|
81
|
+
// consumer markup). Aggregated by installIconLoadersForRegistered()
|
|
82
|
+
// across all defined elements. Audited by check-required-icons.mjs
|
|
83
|
+
// (slot 11). Per FEEDBACK-06 §4 + FEEDBACK-07 §4.
|
|
84
|
+
static requiredIcons = ['check-circle', 'circle', 'warning', 'warning-circle'];
|
|
85
|
+
|
|
80
86
|
static properties = {
|
|
81
87
|
collapsed: { type: Boolean, default: false, reflect: true },
|
|
82
88
|
noAutocollapse: { type: Boolean, default: false, reflect: true, attribute: 'no-autocollapse' },
|
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
import { UIElement } from '../../core/element.js';
|
|
38
38
|
|
|
39
39
|
class UIAgentTrace extends UIElement {
|
|
40
|
+
// §154 (v0.5.3): Phosphor icons this primitive auto-stamps (without
|
|
41
|
+
// consumer markup). Aggregated by installIconLoadersForRegistered()
|
|
42
|
+
// across all defined elements. Audited by check-required-icons.mjs
|
|
43
|
+
// (slot 11). Per FEEDBACK-06 §4 + FEEDBACK-07 §4.
|
|
44
|
+
static requiredIcons = ['caret-right', 'circle-fill'];
|
|
45
|
+
|
|
40
46
|
static properties = {
|
|
41
47
|
// agent-* family is default-visible disclosure (see component-token-contract.md
|
|
42
48
|
// §"Toggle state naming"). Use `collapsed` to hide; bare element shows.
|
|
@@ -53,6 +53,13 @@ function sameDay(a, b) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export class UICalendarPicker extends UIFormElement {
|
|
56
|
+
static labelDeprecated = false; // §170 (v0.5.4): label is first-class per calendar-picker.yaml
|
|
57
|
+
// §154 (v0.5.3): Phosphor icons this primitive auto-stamps (without
|
|
58
|
+
// consumer markup). Aggregated by installIconLoadersForRegistered()
|
|
59
|
+
// across all defined elements. Audited by check-required-icons.mjs
|
|
60
|
+
// (slot 11). Per FEEDBACK-06 §4 + FEEDBACK-07 §4.
|
|
61
|
+
static requiredIcons = ['calendar', 'caret-left', 'caret-right'];
|
|
62
|
+
|
|
56
63
|
static properties = {
|
|
57
64
|
...UIFormElement.properties,
|
|
58
65
|
label: { type: String, default: '', reflect: true },
|
|
@@ -32,16 +32,7 @@
|
|
|
32
32
|
"composes": [],
|
|
33
33
|
"events": {
|
|
34
34
|
"canvas-interaction": {
|
|
35
|
-
"description": "Fired on canvas
|
|
36
|
-
},
|
|
37
|
-
"change": {
|
|
38
|
-
"description": "Fired when the value changes (on blur for inputs, on selection for pickers)."
|
|
39
|
-
},
|
|
40
|
-
"click": {
|
|
41
|
-
"description": "Fired on pointer click."
|
|
42
|
-
},
|
|
43
|
-
"input": {
|
|
44
|
-
"description": "Fired on each input change during typing."
|
|
35
|
+
"description": "Fired on canvas interactions (focus, blur, pointer events). Dispatched at canvas.js:50 + :167."
|
|
45
36
|
}
|
|
46
37
|
},
|
|
47
38
|
"examples": [
|
|
@@ -13,9 +13,6 @@
|
|
|
13
13
|
import { UIElement } from '../../core/element.js';
|
|
14
14
|
|
|
15
15
|
export type CanvasInteractionEvent = CustomEvent<unknown>;
|
|
16
|
-
export type CanvasChangeEvent = CustomEvent<unknown>;
|
|
17
|
-
export type CanvasClickEvent = CustomEvent<unknown>;
|
|
18
|
-
export type CanvasInputEvent = CustomEvent<unknown>;
|
|
19
16
|
|
|
20
17
|
export class UICanvas extends UIElement {
|
|
21
18
|
/** Component property: theme. */
|
|
@@ -27,7 +24,4 @@ export class UICanvas extends UIElement {
|
|
|
27
24
|
options?: boolean | AddEventListenerOptions,
|
|
28
25
|
): void;
|
|
29
26
|
addEventListener(type: 'canvas-interaction', listener: (ev: CanvasInteractionEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
30
|
-
addEventListener(type: 'change', listener: (ev: CanvasChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
31
|
-
addEventListener(type: 'click', listener: (ev: CanvasClickEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
32
|
-
addEventListener(type: 'input', listener: (ev: CanvasInputEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
33
27
|
}
|
|
@@ -24,13 +24,7 @@ props:
|
|
|
24
24
|
default: ''
|
|
25
25
|
events:
|
|
26
26
|
canvas-interaction:
|
|
27
|
-
description: Fired on canvas
|
|
28
|
-
change:
|
|
29
|
-
description: Fired when the value changes (on blur for inputs, on selection for pickers).
|
|
30
|
-
click:
|
|
31
|
-
description: Fired on pointer click.
|
|
32
|
-
input:
|
|
33
|
-
description: Fired on each input change during typing.
|
|
27
|
+
description: Fired on canvas interactions (focus, blur, pointer events). Dispatched at canvas.js:50 + :167.
|
|
34
28
|
slots:
|
|
35
29
|
default:
|
|
36
30
|
description: Default slot — primary child content.
|
|
@@ -76,11 +76,7 @@
|
|
|
76
76
|
"anti_patterns": [],
|
|
77
77
|
"category": "container",
|
|
78
78
|
"composes": [],
|
|
79
|
-
"events": {
|
|
80
|
-
"drag-end": {
|
|
81
|
-
"description": "Fired when a drag completes."
|
|
82
|
-
}
|
|
83
|
-
},
|
|
79
|
+
"events": {},
|
|
84
80
|
"examples": [
|
|
85
81
|
{
|
|
86
82
|
"description": "Chat interface with message bubbles containing avatar and text pairs, plus an input footer.",
|
|
@@ -12,8 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
import { UIElement } from '../../core/element.js';
|
|
14
14
|
|
|
15
|
-
export type CardDragEndEvent = CustomEvent<unknown>;
|
|
16
|
-
|
|
17
15
|
export class UICard extends UIElement {
|
|
18
16
|
/** Enables drag handle + cursor:grab. Wires the draggable trait; dispatches drag-end. */
|
|
19
17
|
draggable: boolean;
|
|
@@ -27,11 +25,4 @@ export class UICard extends UIElement {
|
|
|
27
25
|
size: 'sm' | 'md' | 'lg';
|
|
28
26
|
/** Visual style. `outline` is an alias for `outlined`; `flat` removes shadow; `soft`/`primary` apply tinted surfaces. */
|
|
29
27
|
variant: 'default' | 'outlined' | 'outline' | 'filled' | 'ghost' | 'flat' | 'soft' | 'primary';
|
|
30
|
-
|
|
31
|
-
addEventListener<K extends keyof HTMLElementEventMap>(
|
|
32
|
-
type: K,
|
|
33
|
-
listener: (this: UICard, ev: HTMLElementEventMap[K]) => unknown,
|
|
34
|
-
options?: boolean | AddEventListenerOptions,
|
|
35
|
-
): void;
|
|
36
|
-
addEventListener(type: 'drag-end', listener: (ev: CardDragEndEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
37
28
|
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://adiaui.dev/a2ui/v0_9/components/ChatInput.json",
|
|
4
|
+
"title": "ChatInput",
|
|
5
|
+
"description": "Composable chat input bar — a self-contained chat-message composer\nthat stamps its OWN inner structure (textarea + model picker + send\nbutton) when authored as a bare `<chat-input-ui>` tag.\n\nIMPORTANT (closes the 2026-05-14 redundant-send-button class): the\ncomponent stamps a built-in send button (paper-plane-right icon,\nprimary variant). DO NOT add a separate Button sibling for \"send\" —\nthe user gets two send buttons. The submit event fires on Enter or\nsend-button click; `detail` is `{ text, model }`.\n\nInner stamped structure (default):\n <chat-input-ui>\n <textarea-ui placeholder=\"Type a message...\" rows=\"1\"></textarea-ui>\n <div slot=\"toolbar\">\n <select-ui slot=\"model\" placeholder=\"Model\">...</select-ui>\n <button-ui icon=\"paper-plane-right\" variant=\"primary\" slot=\"send\"></button-ui>\n </div>\n </chat-input-ui>\n\nLayout:\n ┌──────────────────────────────────┐\n │ textarea (grows vertically) │\n ├──────────────────────────────────┤\n │ [model ▾] [⏎ send] │ ← toolbar (model picker + built-in send)\n └──────────────────────────────────┘\n\nComposite wrapper, not a form field itself. The inner textarea-ui\nis form-associated via UIFormElement and submits through the parent\nform. `chat-input-ui`'s `disabled` / `placeholder` props propagate\nto the inner textarea.\n\nFor module-tier composer surfaces (slot vocabulary for file attach,\nautocomplete, trailing/leading controls), wrap inside\n`<chat-composer>` — see ChatComposer for the module-tier shape.\n",
|
|
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": "ChatInput"
|
|
18
|
+
},
|
|
19
|
+
"disabled": {
|
|
20
|
+
"description": "Disable the entire input. Textarea becomes contenteditable=false;\nsend button disabled.\n",
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"default": false
|
|
23
|
+
},
|
|
24
|
+
"loading": {
|
|
25
|
+
"description": "In-flight / streaming state. Send button disabled, submit events\nsuppressed, but textarea stays editable so the user can draft a\nfollow-up while the model is still responding.\n",
|
|
26
|
+
"type": "boolean",
|
|
27
|
+
"default": false
|
|
28
|
+
},
|
|
29
|
+
"model": {
|
|
30
|
+
"description": "Currently selected model value (reflected, two-way with inner\n`<select-ui slot=\"model\">`). Empty when no model picker is shown.\n",
|
|
31
|
+
"type": "string",
|
|
32
|
+
"default": ""
|
|
33
|
+
},
|
|
34
|
+
"models": {
|
|
35
|
+
"description": "JSON array of model options for the inner model picker —\n[{value, label}] or [{label, options: [...]}] groups. Empty array\nhides the model picker.\n",
|
|
36
|
+
"type": "array",
|
|
37
|
+
"default": []
|
|
38
|
+
},
|
|
39
|
+
"placeholder": {
|
|
40
|
+
"description": "Textarea placeholder. Defaults to \"Type a message...\".",
|
|
41
|
+
"type": "string",
|
|
42
|
+
"default": "Type a message..."
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"required": [
|
|
46
|
+
"component"
|
|
47
|
+
],
|
|
48
|
+
"unevaluatedProperties": false,
|
|
49
|
+
"x-adiaui": {
|
|
50
|
+
"anti_patterns": [
|
|
51
|
+
{
|
|
52
|
+
"description": "Adding a separate Button(primary) sibling next to ChatInput for \"send\". The component stamps its own send button (paper-plane-right icon). Two send buttons render side-by-side, confusing users."
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"description": "Stamping a Select next to ChatInput for model picker. The component has a built-in model picker driven by the `models` prop. Set `models=[{value, label}, ...]` instead of stamping a separate Select."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"description": "Wrapping ChatInput inside <field-ui label=\"...\"> for label association. ChatInput is a composite container, not a form field. For a labeled composer surface, use <chat-composer> + slot label markup."
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"category": "agent",
|
|
62
|
+
"composes": [],
|
|
63
|
+
"events": {
|
|
64
|
+
"submit": {
|
|
65
|
+
"description": "Fires when the user presses Enter (without Shift) in the textarea OR clicks the built-in send button. The composer suppresses submission while `[loading]` is set.",
|
|
66
|
+
"detail": {
|
|
67
|
+
"model": {
|
|
68
|
+
"description": "Currently selected model value (empty if no model picker).",
|
|
69
|
+
"type": "string"
|
|
70
|
+
},
|
|
71
|
+
"text": {
|
|
72
|
+
"description": "Submitted message text from the inner textarea.",
|
|
73
|
+
"type": "string"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"examples": [
|
|
79
|
+
{
|
|
80
|
+
"description": "Minimal chat input — placeholder, no model picker. Sits inside a chat shell footer.",
|
|
81
|
+
"a2ui": "[\n {\"id\": \"root\", \"component\": \"ChatInput\", \"placeholder\": \"Ask me anything...\"}\n]",
|
|
82
|
+
"name": "basic-chat-input"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"description": "Chat input with model selection. The `models` prop drives the built-in model picker — DO NOT add a separate Select sibling.",
|
|
86
|
+
"a2ui": "[\n {\n \"id\": \"root\",\n \"component\": \"ChatInput\",\n \"placeholder\": \"Type a message...\",\n \"model\": \"claude-opus-4-7\",\n \"models\": [\n {\"value\": \"claude-opus-4-7\", \"label\": \"Claude Opus 4.7\"},\n {\"value\": \"claude-haiku-4-5\", \"label\": \"Claude Haiku 4.5\"},\n {\"value\": \"claude-sonnet-4-5\", \"label\": \"Claude Sonnet 4.5\"}\n ]\n }\n]",
|
|
87
|
+
"name": "chat-input-with-models"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"description": "Streaming response state. `[loading]` reflects on the host; send button disables; textarea stays editable so the user can draft a follow-up while the LLM is responding.",
|
|
91
|
+
"a2ui": "[\n {\n \"id\": \"root\",\n \"component\": \"ChatInput\",\n \"placeholder\": \"Drafting follow-up while streaming...\",\n \"loading\": true\n }\n]",
|
|
92
|
+
"name": "chat-input-loading-state"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"description": "Full chat shell — header + thread + ChatInput in the footer. Note: ChatInput is the sole footer child; no separate send button.",
|
|
96
|
+
"a2ui": "[\n {\"id\": \"root\", \"component\": \"ChatShell\", \"children\": [\"header\", \"thread\", \"input\"]},\n {\"id\": \"header\", \"component\": \"ChatHeader\", \"title\": \"Chat\"},\n {\"id\": \"thread\", \"component\": \"ChatThread\"},\n {\"id\": \"input\", \"component\": \"ChatInput\", \"placeholder\": \"Send a message...\"}\n]",
|
|
97
|
+
"name": "chat-shell-with-chat-input"
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"keywords": [
|
|
101
|
+
"chat-input",
|
|
102
|
+
"chat",
|
|
103
|
+
"message-input",
|
|
104
|
+
"composer",
|
|
105
|
+
"send-message",
|
|
106
|
+
"conversation",
|
|
107
|
+
"prompt",
|
|
108
|
+
"submit"
|
|
109
|
+
],
|
|
110
|
+
"name": "UIChatInput",
|
|
111
|
+
"related": [
|
|
112
|
+
"ChatShell",
|
|
113
|
+
"ChatThread",
|
|
114
|
+
"ChatComposer",
|
|
115
|
+
"ChatHeader",
|
|
116
|
+
"TextArea",
|
|
117
|
+
"Input"
|
|
118
|
+
],
|
|
119
|
+
"slots": {
|
|
120
|
+
"model": {
|
|
121
|
+
"description": "Override slot for the model picker. Most authors should NOT override this — set the `models` prop instead."
|
|
122
|
+
},
|
|
123
|
+
"send": {
|
|
124
|
+
"description": "Override slot for the send button only. The default stamped send button has `[icon=\"paper-plane-right\"] [variant=\"primary\"]`. Most authors should NOT override this — the built-in send button IS the send control. Adding a separate Button sibling for \"send\" duplicates this functionality."
|
|
125
|
+
},
|
|
126
|
+
"toolbar": {
|
|
127
|
+
"description": "Override slot for the entire toolbar row (model picker + send button). Most authors should NOT override this — the built-in toolbar handles model selection + send. Use this only when custom toolbar layout is required."
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"states": [
|
|
131
|
+
{
|
|
132
|
+
"description": "Default, accepting input. Send button enabled when textarea has content.",
|
|
133
|
+
"name": "idle"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"description": "Input fully disabled (typically during initial form setup).",
|
|
137
|
+
"attribute": "disabled",
|
|
138
|
+
"name": "disabled"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"description": "LLM is responding. Send button disabled + submit events suppressed, but textarea stays editable for follow-up drafts.",
|
|
142
|
+
"attribute": "loading",
|
|
143
|
+
"name": "loading"
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"synonyms": {
|
|
147
|
+
"message-input": [
|
|
148
|
+
"conversation-input",
|
|
149
|
+
"prompt-input",
|
|
150
|
+
"send-bar"
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
"tag": "chat-input-ui",
|
|
154
|
+
"tokens": {},
|
|
155
|
+
"traits": [],
|
|
156
|
+
"version": 1
|
|
157
|
+
}
|
|
158
|
+
}
|