@urbicon-ui/blocks 6.39.0 → 6.40.1
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/dist/components/Calendar/calendar.variants.d.ts +63 -63
- package/dist/components/Chat/A2UIView/A2UINode.svelte +121 -0
- package/dist/components/Chat/A2UIView/A2UIView.svelte +22 -1
- package/dist/components/Chat/A2UIView/a2ui-prompt.js +8 -2
- package/dist/components/Chat/A2UIView/a2ui-registry.d.ts +3 -3
- package/dist/components/Chat/A2UIView/a2ui-registry.js +47 -5
- package/dist/components/Chat/A2UIView/a2ui-validate.js +11 -0
- package/dist/components/Chat/A2UIView/a2ui-view.variants.d.ts +6 -0
- package/dist/components/Chat/A2UIView/a2ui-view.variants.js +4 -0
- package/dist/components/Chat/A2UIView/a2ui.types.d.ts +2 -0
- package/dist/components/Chat/A2UIView/a2ui.types.js +2 -0
- package/dist/components/Chat/A2UIView/index.d.ts +2 -2
- package/dist/components/CopyButton/copy-button.variants.d.ts +4 -4
- package/dist/i18n/index.d.ts +398 -2
- package/dist/primitives/Alert/alert.variants.d.ts +8 -8
- package/dist/primitives/JourneyTimeline/journey-timeline.variants.d.ts +22 -22
- package/dist/primitives/JourneyTimeline/journey-timeline.variants.js +3 -1
- package/dist/primitives/Spinner/spinner.variants.d.ts +16 -16
- package/dist/primitives/Stepper/stepper.variants.d.ts +11 -11
- package/dist/primitives/Toast/toast.variants.d.ts +12 -12
- package/dist/primitives/Tooltip/tooltip.variants.d.ts +3 -3
- package/dist/style/semantic.css +11 -3
- package/package.json +3 -3
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
} from '../../../primitives';
|
|
14
14
|
import { resolveIcon } from '../../../icons';
|
|
15
15
|
import DangerCircleIconDefault from '../../../icons/DangerCircleIcon.svelte';
|
|
16
|
+
import { fromDateInputValue, toDateInputValue } from '../../../utils/date';
|
|
16
17
|
import type { Snippet } from 'svelte';
|
|
18
|
+
import DatePicker from '../../DatePicker/DatePicker.svelte';
|
|
19
|
+
import TimeInput from '../../TimeInput/TimeInput.svelte';
|
|
17
20
|
import StreamingMarkdown from '../StreamingMarkdown/StreamingMarkdown.svelte';
|
|
18
21
|
import { checkImageUrl, checkLinkUrl } from '../markdown/url-policy.js';
|
|
19
22
|
import type { A2uiActionEvent } from './a2ui.types';
|
|
@@ -340,6 +343,71 @@
|
|
|
340
343
|
}
|
|
341
344
|
|
|
342
345
|
const buttonStyle = $derived(BUTTON_STYLE[enumOr('variant', 'default')] ?? BUTTON_STYLE.default);
|
|
346
|
+
|
|
347
|
+
// ── DateTimeInput ────────────────────────────────────────────────────────
|
|
348
|
+
// The spec's value is one ISO 8601 STRING covering date, time, or both. The
|
|
349
|
+
// renderer treats it as a timezone-NAIVE literal: a trailing offset/Z is
|
|
350
|
+
// stripped for display and never re-attached on write — timezone semantics
|
|
351
|
+
// belong to the agent, not to a UI renderer without timezone context.
|
|
352
|
+
const dtMode = $derived.by<'date' | 'time' | 'datetime'>(() => {
|
|
353
|
+
const enableDate = raw('enableDate') === true;
|
|
354
|
+
const enableTime = raw('enableTime') === true;
|
|
355
|
+
if (enableDate && enableTime) return 'datetime';
|
|
356
|
+
if (enableTime) return 'time';
|
|
357
|
+
// Includes the neither-flag payload: read tolerantly as a date input (the
|
|
358
|
+
// validator already reported DATETIME_NO_MODE).
|
|
359
|
+
return 'date';
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
function normalizeTimePart(value: string): string {
|
|
363
|
+
const match = /^(\d{2}:\d{2}(?::\d{2})?)/.exec(value);
|
|
364
|
+
return match ? match[1] : '';
|
|
365
|
+
}
|
|
366
|
+
function splitDateTime(value: string): { date: string; time: string } {
|
|
367
|
+
const trimmed = value.trim();
|
|
368
|
+
if (trimmed === '') return { date: '', time: '' };
|
|
369
|
+
const tIndex = trimmed.indexOf('T');
|
|
370
|
+
if (tIndex !== -1) {
|
|
371
|
+
return {
|
|
372
|
+
date: trimmed.slice(0, tIndex),
|
|
373
|
+
time: normalizeTimePart(trimmed.slice(tIndex + 1))
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
if (trimmed.includes(':')) return { date: '', time: normalizeTimePart(trimmed) };
|
|
377
|
+
return { date: trimmed, time: '' };
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const dtParts = $derived(splitDateTime(textValue));
|
|
381
|
+
const dtMinParts = $derived(splitDateTime(text(resolved('min'))));
|
|
382
|
+
const dtMaxParts = $derived(splitDateTime(text(resolved('max'))));
|
|
383
|
+
const dtMinDate = $derived(
|
|
384
|
+
dtMinParts.date ? (fromDateInputValue(dtMinParts.date) ?? undefined) : undefined
|
|
385
|
+
);
|
|
386
|
+
const dtMaxDate = $derived(
|
|
387
|
+
dtMaxParts.date ? (fromDateInputValue(dtMaxParts.date) ?? undefined) : undefined
|
|
388
|
+
);
|
|
389
|
+
// Time bounds apply only when the bound itself is time-only: on a date-time
|
|
390
|
+
// bound the time limit would depend on the picked date — deliberately out of
|
|
391
|
+
// scope for this renderer (the date part is still enforced above).
|
|
392
|
+
const dtMinTime = $derived(dtMinParts.time && !dtMinParts.date ? dtMinParts.time : undefined);
|
|
393
|
+
const dtMaxTime = $derived(dtMaxParts.time && !dtMaxParts.date ? dtMaxParts.time : undefined);
|
|
394
|
+
|
|
395
|
+
function writeDateTime(nextDate: string, nextTime: string): void {
|
|
396
|
+
// Partial fills stay valid partial ISO: date-only / time-only / "".
|
|
397
|
+
const next = nextDate && nextTime ? `${nextDate}T${nextTime}` : nextDate || nextTime || '';
|
|
398
|
+
const pointer = valuePointer();
|
|
399
|
+
if (pointer) context.write(pointer, next);
|
|
400
|
+
else localText = next;
|
|
401
|
+
}
|
|
402
|
+
function onDtDateChange(picked: Date | undefined): void {
|
|
403
|
+
writeDateTime(
|
|
404
|
+
picked ? toDateInputValue(picked) : '',
|
|
405
|
+
dtMode === 'datetime' ? dtParts.time : ''
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
function onDtTimeChange(nextTime: string | null): void {
|
|
409
|
+
writeDateTime(dtMode === 'datetime' ? dtParts.date : '', nextTime ?? '');
|
|
410
|
+
}
|
|
343
411
|
</script>
|
|
344
412
|
|
|
345
413
|
{#snippet faultChip(label: string)}
|
|
@@ -579,4 +647,57 @@
|
|
|
579
647
|
style={weightStyle}
|
|
580
648
|
aria-label={ariaLabel}
|
|
581
649
|
/>
|
|
650
|
+
{:else if component === 'DateTimeInput'}
|
|
651
|
+
{@const label = text(resolved('label'))}
|
|
652
|
+
{#if dtMode === 'datetime'}
|
|
653
|
+
<!-- The visible label sits on the date field; the group name gives the
|
|
654
|
+
time segments their context (TimeInput's segments are self-labelled). -->
|
|
655
|
+
<div
|
|
656
|
+
class={[context.classes.row, 'flex-wrap']}
|
|
657
|
+
style={weightStyle}
|
|
658
|
+
role="group"
|
|
659
|
+
aria-label={ariaLabel || label || undefined}
|
|
660
|
+
>
|
|
661
|
+
<DatePicker
|
|
662
|
+
label={label || undefined}
|
|
663
|
+
value={dtParts.date || null}
|
|
664
|
+
onValueChange={onDtDateChange}
|
|
665
|
+
minDate={dtMinDate}
|
|
666
|
+
maxDate={dtMaxDate}
|
|
667
|
+
/>
|
|
668
|
+
<TimeInput
|
|
669
|
+
value={dtParts.time || null}
|
|
670
|
+
onValueChange={onDtTimeChange}
|
|
671
|
+
withSeconds={dtParts.time.length > 5}
|
|
672
|
+
min={dtMinTime}
|
|
673
|
+
max={dtMaxTime}
|
|
674
|
+
/>
|
|
675
|
+
</div>
|
|
676
|
+
{:else if dtMode === 'time'}
|
|
677
|
+
<!-- TimeInput has no style/aria passthrough — weight + accessibility label
|
|
678
|
+
live on a wrapper (role=group only when it actually carries a name). -->
|
|
679
|
+
<div style={weightStyle} role={ariaLabel ? 'group' : undefined} aria-label={ariaLabel}>
|
|
680
|
+
<TimeInput
|
|
681
|
+
label={label || undefined}
|
|
682
|
+
value={dtParts.time || null}
|
|
683
|
+
onValueChange={onDtTimeChange}
|
|
684
|
+
withSeconds={dtParts.time.length > 5}
|
|
685
|
+
min={dtMinTime}
|
|
686
|
+
max={dtMaxTime}
|
|
687
|
+
/>
|
|
688
|
+
</div>
|
|
689
|
+
{:else}
|
|
690
|
+
<!-- The accessibility label becomes the field label when no visible label
|
|
691
|
+
is given: DatePicker spreads an aria-label onto its role-less root div
|
|
692
|
+
(AT-ignored, axe aria-prohibited-attr), so the name must travel
|
|
693
|
+
through `label` to reach the actual input. -->
|
|
694
|
+
<DatePicker
|
|
695
|
+
label={label || ariaLabel || undefined}
|
|
696
|
+
value={dtParts.date || null}
|
|
697
|
+
onValueChange={onDtDateChange}
|
|
698
|
+
minDate={dtMinDate}
|
|
699
|
+
maxDate={dtMaxDate}
|
|
700
|
+
style={weightStyle}
|
|
701
|
+
/>
|
|
702
|
+
{/if}
|
|
582
703
|
{/if}
|
|
@@ -249,6 +249,20 @@
|
|
|
249
249
|
<A2UINode {node} {context} renderChild={renderNode} />
|
|
250
250
|
{/snippet}
|
|
251
251
|
|
|
252
|
+
<!--
|
|
253
|
+
Streaming skeleton: while the model is still emitting the (often large)
|
|
254
|
+
updateComponents envelope, the surface exists without a root — show a quiet
|
|
255
|
+
pulse instead of nothing so the wait is visible.
|
|
256
|
+
-->
|
|
257
|
+
{#snippet pendingSkeleton()}
|
|
258
|
+
<div class={classes.pendingSurface} role="status">
|
|
259
|
+
<span class="sr-only">{pendingLabel}</span>
|
|
260
|
+
<div class={[classes.pendingBar, 'w-1/3']} aria-hidden="true"></div>
|
|
261
|
+
<div class={[classes.pendingBar, 'w-full']} aria-hidden="true"></div>
|
|
262
|
+
<div class={[classes.pendingBar, 'w-2/3']} aria-hidden="true"></div>
|
|
263
|
+
</div>
|
|
264
|
+
{/snippet}
|
|
265
|
+
|
|
252
266
|
<div class={rootClass} {...restProps}>
|
|
253
267
|
{#if view.summaryIssues.length}
|
|
254
268
|
<Alert intent="danger" title={errorTitle}>
|
|
@@ -264,9 +278,16 @@
|
|
|
264
278
|
<div class={classes.surface}>
|
|
265
279
|
{#if surface.root}
|
|
266
280
|
{@render renderNode(surface.root, surface.context)}
|
|
267
|
-
{:else if
|
|
281
|
+
{:else if streamingProp}
|
|
282
|
+
{@render pendingSkeleton()}
|
|
283
|
+
{:else}
|
|
268
284
|
<span class={classes.errorChip}>{errorTitle}</span>
|
|
269
285
|
{/if}
|
|
270
286
|
</div>
|
|
271
287
|
{/each}
|
|
288
|
+
|
|
289
|
+
{#if streamingProp && view.surfaces.length === 0 && !view.summaryIssues.length}
|
|
290
|
+
<!-- Fence opened but no envelope has completed yet — same quiet pulse. -->
|
|
291
|
+
{@render pendingSkeleton()}
|
|
292
|
+
{/if}
|
|
272
293
|
</div>
|
|
@@ -75,7 +75,9 @@ export function a2uiSystemPrompt(options) {
|
|
|
75
75
|
sections.push([
|
|
76
76
|
'## Envelopes',
|
|
77
77
|
'',
|
|
78
|
-
'Emit one JSON envelope per line (JSONL)
|
|
78
|
+
'Emit one JSON envelope per line (JSONL), as COMPACT single-line JSON — never',
|
|
79
|
+
'pretty-print or wrap one envelope across multiple lines, even a large',
|
|
80
|
+
'updateComponents. Every envelope is an object with a',
|
|
79
81
|
'"version" of "v0.9.1" and EXACTLY ONE of these operations:',
|
|
80
82
|
'',
|
|
81
83
|
`- createSurface: { surfaceId, catalogId: "${catalogId}" } — send this FIRST.`,
|
|
@@ -91,7 +93,11 @@ export function a2uiSystemPrompt(options) {
|
|
|
91
93
|
'- A multi-child container (Row, Column, List) uses "children": either an',
|
|
92
94
|
' array of ids, or a template { componentId, path } that repeats one',
|
|
93
95
|
' component over a data-model array.',
|
|
94
|
-
'-
|
|
96
|
+
'- Stream components incrementally: send SEVERAL updateComponents envelopes',
|
|
97
|
+
' ("root" and its top-level containers in the FIRST one, then a few',
|
|
98
|
+
' components per envelope) so the UI renders progressively while you write.',
|
|
99
|
+
' The client buffers until "root" exists and shows placeholders for',
|
|
100
|
+
' children that have not arrived yet.'
|
|
95
101
|
].join('\n'));
|
|
96
102
|
sections.push([
|
|
97
103
|
'## Data bindings',
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* (`a2ui-prompt.ts`). No Svelte imports: this module must be importable
|
|
5
5
|
* standalone (a server building the system prompt has no DOM).
|
|
6
6
|
*
|
|
7
|
-
* The subset
|
|
8
|
-
* (Modal, Tabs, Video, AudioPlayer,
|
|
9
|
-
*
|
|
7
|
+
* The subset covers the v0.9.1 `basic` components except the deliberately
|
|
8
|
+
* excluded ones (Modal, Tabs, Video, AudioPlayer), which validate to a visible
|
|
9
|
+
* error chip; see `UNSUPPORTED_A2UI_COMPONENTS`.
|
|
10
10
|
*
|
|
11
11
|
* Prop names, kinds, `required`, defaults and enum sets mirror
|
|
12
12
|
* `catalogs/basic/catalog.json` **case-sensitively**. Every `description` here
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* (`a2ui-prompt.ts`). No Svelte imports: this module must be importable
|
|
5
5
|
* standalone (a server building the system prompt has no DOM).
|
|
6
6
|
*
|
|
7
|
-
* The subset
|
|
8
|
-
* (Modal, Tabs, Video, AudioPlayer,
|
|
9
|
-
*
|
|
7
|
+
* The subset covers the v0.9.1 `basic` components except the deliberately
|
|
8
|
+
* excluded ones (Modal, Tabs, Video, AudioPlayer), which validate to a visible
|
|
9
|
+
* error chip; see `UNSUPPORTED_A2UI_COMPONENTS`.
|
|
10
10
|
*
|
|
11
11
|
* Prop names, kinds, `required`, defaults and enum sets mirror
|
|
12
12
|
* `catalogs/basic/catalog.json` **case-sensitively**. Every `description` here
|
|
@@ -25,8 +25,7 @@ export const UNSUPPORTED_A2UI_COMPONENTS = new Set([
|
|
|
25
25
|
'Modal',
|
|
26
26
|
'Tabs',
|
|
27
27
|
'Video',
|
|
28
|
-
'AudioPlayer'
|
|
29
|
-
'DateTimeInput'
|
|
28
|
+
'AudioPlayer'
|
|
30
29
|
]);
|
|
31
30
|
/**
|
|
32
31
|
* Mapped `Icon.name` values. A name outside this set degrades to a fallback
|
|
@@ -342,6 +341,49 @@ export const A2UI_REGISTRY = Object.freeze({
|
|
|
342
341
|
description: 'An optional label for the slider.'
|
|
343
342
|
}
|
|
344
343
|
})
|
|
344
|
+
},
|
|
345
|
+
DateTimeInput: {
|
|
346
|
+
description: 'A date and/or time input. `value` is an ISO 8601 STRING ("" when unset) — date ' +
|
|
347
|
+
'(YYYY-MM-DD), time (HH:MM), or both (YYYY-MM-DDTHH:MM). ALWAYS set enableDate and/or ' +
|
|
348
|
+
'enableTime explicitly (both default to false). Bind `value` to a data-model path for ' +
|
|
349
|
+
'two-way binding and initialize that path with "".',
|
|
350
|
+
props: withCommon({
|
|
351
|
+
value: {
|
|
352
|
+
kind: 'string',
|
|
353
|
+
required: true,
|
|
354
|
+
dynamic: true,
|
|
355
|
+
description: 'The ISO 8601 date/time string ("" when unset). Bind with { path } for two-way binding.'
|
|
356
|
+
},
|
|
357
|
+
enableDate: {
|
|
358
|
+
kind: 'boolean',
|
|
359
|
+
default: false,
|
|
360
|
+
description: 'Allow picking a calendar date (the YYYY-MM-DD part).'
|
|
361
|
+
},
|
|
362
|
+
enableTime: {
|
|
363
|
+
kind: 'boolean',
|
|
364
|
+
default: false,
|
|
365
|
+
description: 'Allow picking a time of day (the HH:MM part).'
|
|
366
|
+
},
|
|
367
|
+
label: {
|
|
368
|
+
kind: 'string',
|
|
369
|
+
dynamic: true,
|
|
370
|
+
description: 'The field label.'
|
|
371
|
+
},
|
|
372
|
+
min: {
|
|
373
|
+
kind: 'string',
|
|
374
|
+
dynamic: true,
|
|
375
|
+
description: 'Minimum allowed value, ISO 8601. The DATE part is enforced; a TIME bound is ' +
|
|
376
|
+
'enforced only when the bound is time-only (the time part of a date-time bound ' +
|
|
377
|
+
'is not enforced).'
|
|
378
|
+
},
|
|
379
|
+
max: {
|
|
380
|
+
kind: 'string',
|
|
381
|
+
dynamic: true,
|
|
382
|
+
description: 'Maximum allowed value, ISO 8601. The DATE part is enforced; a TIME bound is ' +
|
|
383
|
+
'enforced only when the bound is time-only (the time part of a date-time bound ' +
|
|
384
|
+
'is not enforced).'
|
|
385
|
+
}
|
|
386
|
+
})
|
|
345
387
|
}
|
|
346
388
|
});
|
|
347
389
|
/** Props recognized anywhere but intentionally ignored (validation only, dropped before render). */
|
|
@@ -390,6 +390,17 @@ function validateComponent(surface, raw, envelopeIndex, compIndex, idsSeen) {
|
|
|
390
390
|
}));
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
|
+
if (componentName === 'DateTimeInput') {
|
|
394
|
+
// Both flags default to false in the spec — a DateTimeInput without either
|
|
395
|
+
// would have no input UI at all. We read tolerantly (render a date input)
|
|
396
|
+
// and report loudly so the agent fixes the payload.
|
|
397
|
+
if (props.get('enableDate') !== true && props.get('enableTime') !== true) {
|
|
398
|
+
surface.issues.push(issue('warning', A2UI_ISSUE_CODES.DATETIME_NO_MODE, `DateTimeInput "${id}" sets neither enableDate nor enableTime; rendering a date input`, {
|
|
399
|
+
surfaceId,
|
|
400
|
+
path: base
|
|
401
|
+
}));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
393
404
|
surface.components.set(id, { id, component: componentName, props, sourceIndex: envelopeIndex });
|
|
394
405
|
}
|
|
395
406
|
// ── Envelope handlers ────────────────────────────────────────────────────────
|
|
@@ -27,6 +27,12 @@ export declare const a2uiViewVariants: ((props?: {} | undefined) => {
|
|
|
27
27
|
pending: (props?: ({} & {
|
|
28
28
|
class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
|
|
29
29
|
}) | undefined) => string;
|
|
30
|
+
pendingSurface: (props?: ({} & {
|
|
31
|
+
class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
|
|
32
|
+
}) | undefined) => string;
|
|
33
|
+
pendingBar: (props?: ({} & {
|
|
34
|
+
class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
|
|
35
|
+
}) | undefined) => string;
|
|
30
36
|
column: (props?: ({} & {
|
|
31
37
|
class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
|
|
32
38
|
}) | undefined) => string;
|
|
@@ -25,6 +25,10 @@ export const a2uiViewVariants = tv({
|
|
|
25
25
|
errorIcon: 'shrink-0',
|
|
26
26
|
/** Streaming placeholder wrapper for a not-yet-defined reference. */
|
|
27
27
|
pending: 'inline-flex items-center gap-1.5',
|
|
28
|
+
/** Skeleton shown while streaming before a surface has received its root. */
|
|
29
|
+
pendingSurface: 'flex min-w-0 flex-col gap-2 rounded-contain border border-border-subtle p-4',
|
|
30
|
+
/** One shimmering placeholder bar inside the streaming skeleton. */
|
|
31
|
+
pendingBar: 'h-4 animate-pulse rounded-modify bg-neutral-subtle motion-reduce:animate-none',
|
|
28
32
|
/** Column layout container (flex-col); justify/align appended per instance. */
|
|
29
33
|
column: 'flex min-w-0 flex-col gap-2',
|
|
30
34
|
/** Row layout container (flex-row); justify/align appended per instance. */
|
|
@@ -79,6 +79,8 @@ export declare const A2UI_ISSUE_CODES: {
|
|
|
79
79
|
readonly DUPLICATE_ID: "DUPLICATE_ID";
|
|
80
80
|
/** Two `ChoicePicker` options share a `value` — the second is dropped (values must be unique). */
|
|
81
81
|
readonly DUPLICATE_OPTION: "DUPLICATE_OPTION";
|
|
82
|
+
/** `DateTimeInput` with neither `enableDate` nor `enableTime` — rendered as a date input. */
|
|
83
|
+
readonly DATETIME_NO_MODE: "DATETIME_NO_MODE";
|
|
82
84
|
/** More surfaces than the engine renders at once — the extra `createSurface` is refused. */
|
|
83
85
|
readonly MAX_SURFACES: "MAX_SURFACES";
|
|
84
86
|
/** A single `updateComponents` exceeds the per-message component cap — the surplus is dropped. */
|
|
@@ -46,6 +46,8 @@ export const A2UI_ISSUE_CODES = {
|
|
|
46
46
|
DUPLICATE_ID: 'DUPLICATE_ID',
|
|
47
47
|
/** Two `ChoicePicker` options share a `value` — the second is dropped (values must be unique). */
|
|
48
48
|
DUPLICATE_OPTION: 'DUPLICATE_OPTION',
|
|
49
|
+
/** `DateTimeInput` with neither `enableDate` nor `enableTime` — rendered as a date input. */
|
|
50
|
+
DATETIME_NO_MODE: 'DATETIME_NO_MODE',
|
|
49
51
|
/** More surfaces than the engine renders at once — the extra `createSurface` is refused. */
|
|
50
52
|
MAX_SURFACES: 'MAX_SURFACES',
|
|
51
53
|
/** A single `updateComponents` exceeds the per-message component cap — the surplus is dropped. */
|
|
@@ -5,8 +5,8 @@ import type { A2UIViewSlots } from './a2ui-view.variants.js';
|
|
|
5
5
|
/**
|
|
6
6
|
* @description Renders a trusted-catalog A2UI (Agent-to-UI, v0.9.1 `basic`
|
|
7
7
|
* subset) payload into live, interactive Urbicon components. Fail-loud and
|
|
8
|
-
* whitelist-only: only the
|
|
9
|
-
* reach the DOM — unknown components/props, prototype-pollution keys and
|
|
8
|
+
* whitelist-only: only the mapped catalog components and their declared props
|
|
9
|
+
* ever reach the DOM — unknown components/props, prototype-pollution keys and
|
|
10
10
|
* function-call bindings are rejected, never rendered, and surfaced through
|
|
11
11
|
* `onValidationError` (spec-compatible issues a consumer can relay to the agent
|
|
12
12
|
* as a `VALIDATION_FAILED` error). Inputs are two-way (typing writes into the
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { type SlotNames, type VariantProps } from '../../utils/variants.js';
|
|
2
2
|
export declare const copyButtonVariants: ((props?: {
|
|
3
3
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xs" | undefined;
|
|
4
|
-
state?: "
|
|
4
|
+
state?: "copied" | "error" | "idle" | undefined;
|
|
5
5
|
} | undefined) => {
|
|
6
6
|
base: (props?: ({
|
|
7
7
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xs" | undefined;
|
|
8
|
-
state?: "
|
|
8
|
+
state?: "copied" | "error" | "idle" | undefined;
|
|
9
9
|
} & {
|
|
10
10
|
class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
|
|
11
11
|
}) | undefined) => string;
|
|
12
12
|
icon: (props?: ({
|
|
13
13
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xs" | undefined;
|
|
14
|
-
state?: "
|
|
14
|
+
state?: "copied" | "error" | "idle" | undefined;
|
|
15
15
|
} & {
|
|
16
16
|
class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
|
|
17
17
|
}) | undefined) => string;
|
|
18
18
|
label: (props?: ({
|
|
19
19
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xs" | undefined;
|
|
20
|
-
state?: "
|
|
20
|
+
state?: "copied" | "error" | "idle" | undefined;
|
|
21
21
|
} & {
|
|
22
22
|
class?: string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | (string | number | false | /*elided*/ any | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined)[] | Record<string, boolean | null | undefined> | null | undefined;
|
|
23
23
|
}) | undefined) => string;
|