@adia-ai/web-components 0.5.4 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/accordion/accordion-item.a2ui.json +50 -0
- package/components/accordion/accordion-item.yaml +27 -0
- package/components/action-list/action-item.a2ui.json +63 -0
- package/components/action-list/action-item.yaml +37 -0
- package/components/agent-feedback-bar/class.js +9 -3
- package/components/avatar/avatar-group.a2ui.json +50 -0
- package/components/avatar/avatar-group.yaml +26 -0
- package/components/avatar/avatar.a2ui.json +4 -1
- package/components/avatar/avatar.yaml +7 -0
- package/components/button/class.js +39 -0
- package/components/chart/chart.a2ui.json +4 -2
- package/components/list/list-item.a2ui.json +53 -0
- package/components/list/list-item.yaml +29 -0
- package/components/segmented/segmented.d.ts +3 -3
- package/components/select/class.js +14 -0
- package/components/select/select.a2ui.json +5 -0
- package/components/select/select.css +10 -0
- package/components/select/select.d.ts +3 -3
- package/components/select/select.yaml +5 -0
- package/components/slider/class.js +58 -0
- package/components/slider/slider.a2ui.json +10 -0
- package/components/slider/slider.css +13 -0
- package/components/slider/slider.yaml +10 -0
- package/components/switch/class.js +18 -4
- package/components/switch/switch.css +10 -0
- package/components/switch/switch.d.ts +3 -3
- package/components/tabs/tab.a2ui.json +58 -0
- package/components/tabs/tab.yaml +33 -0
- package/components/timeline/timeline-item.a2ui.json +76 -0
- package/components/timeline/timeline-item.yaml +47 -0
- package/components/toast/toast.d.ts +35 -0
- package/components/tree/class.js +91 -0
- package/components/tree/tree-item.a2ui.json +65 -0
- package/components/tree/tree-item.yaml +41 -0
- package/components/tree/tree.a2ui.json +15 -0
- package/components/tree/tree.css +18 -0
- package/components/tree/tree.yaml +10 -0
- package/core/anchor.d.ts +71 -0
- package/core/controller.d.ts +171 -0
- package/core/markdown.d.ts +26 -0
- package/core/polyfills.d.ts +31 -0
- package/core/provider.d.ts +82 -0
- package/core/streams-bridge.d.ts +78 -0
- package/core/template.js +21 -3
- package/core/transport.d.ts +78 -0
- package/package.json +2 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://adiaui.dev/a2ui/v0_9/components/TreeItem.json",
|
|
4
|
+
"title": "TreeItem",
|
|
5
|
+
"description": "Child of <tree-ui>. One tree row with optional icon + text + trailing badge, plus nested tree-item-ui children for the collapsible hierarchy. Use inside <tree-ui> only.",
|
|
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
|
+
"badge": {
|
|
17
|
+
"description": "Optional trailing badge text (count, label, etc.). Renders muted + small + right-aligned alongside the row, mirroring the nav-item-ui badge API. When empty, the badge slot stays empty.\n\nAdded in §184 (v0.5.5, FEEDBACK-08 §1).",
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"component": {
|
|
21
|
+
"const": "TreeItem"
|
|
22
|
+
},
|
|
23
|
+
"icon": {
|
|
24
|
+
"description": "Optional leading icon name (Phosphor).",
|
|
25
|
+
"type": "string"
|
|
26
|
+
},
|
|
27
|
+
"open": {
|
|
28
|
+
"description": "When true, the item's children render expanded. Single-instance state; the parent `<tree-ui>` toggles this on click + Enter/Space + ArrowRight/ArrowLeft per tree-view APG.",
|
|
29
|
+
"type": "boolean"
|
|
30
|
+
},
|
|
31
|
+
"selected": {
|
|
32
|
+
"description": "Reflects the currently-selected item. Exactly one tree-item is selected per `<tree-ui>` parent (managed by the parent).",
|
|
33
|
+
"type": "boolean"
|
|
34
|
+
},
|
|
35
|
+
"text": {
|
|
36
|
+
"description": "Primary text rendered in the row.",
|
|
37
|
+
"type": "string"
|
|
38
|
+
},
|
|
39
|
+
"value": {
|
|
40
|
+
"description": "Stable value emitted in `tree-select` event detail.",
|
|
41
|
+
"type": "string"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"required": [
|
|
45
|
+
"component"
|
|
46
|
+
],
|
|
47
|
+
"unevaluatedProperties": false,
|
|
48
|
+
"x-adiaui": {
|
|
49
|
+
"anti_patterns": [],
|
|
50
|
+
"category": "data",
|
|
51
|
+
"composes": [],
|
|
52
|
+
"events": {},
|
|
53
|
+
"examples": [],
|
|
54
|
+
"keywords": [],
|
|
55
|
+
"name": "UITreeItem",
|
|
56
|
+
"related": [],
|
|
57
|
+
"slots": {},
|
|
58
|
+
"states": [],
|
|
59
|
+
"synonyms": {},
|
|
60
|
+
"tag": "tree-item-ui",
|
|
61
|
+
"tokens": {},
|
|
62
|
+
"traits": [],
|
|
63
|
+
"version": 1
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Edit this file; run `npm run build:components` to regenerate a2ui.json.
|
|
2
|
+
#
|
|
3
|
+
# §184 (v0.5.5): authored to close FEEDBACK-08 §1 — tree-item-ui badge
|
|
4
|
+
# attribute + general orphan-class catalog gap. tree-item-ui has shipped
|
|
5
|
+
# since v0.0.x co-located in tree/class.js (UITreeItem) but never had its
|
|
6
|
+
# own catalog entry. With §172 sibling-yaml scanner, this file is picked
|
|
7
|
+
# up next to the parent yaml. Mirrors the v0.5.5 §176 sibling-yaml
|
|
8
|
+
# baseline-orphan closure pattern.
|
|
9
|
+
|
|
10
|
+
# Child component of <tree-ui>. Surface only inside that parent.
|
|
11
|
+
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
12
|
+
name: UITreeItem
|
|
13
|
+
tag: tree-item-ui
|
|
14
|
+
component: TreeItem
|
|
15
|
+
category: data
|
|
16
|
+
version: 1
|
|
17
|
+
description: |-
|
|
18
|
+
Child of <tree-ui>. One tree row with optional icon + text + trailing badge, plus nested tree-item-ui children for the collapsible hierarchy. Use inside <tree-ui> only.
|
|
19
|
+
|
|
20
|
+
props:
|
|
21
|
+
text:
|
|
22
|
+
description: Primary text rendered in the row.
|
|
23
|
+
type: string
|
|
24
|
+
icon:
|
|
25
|
+
description: Optional leading icon name (Phosphor).
|
|
26
|
+
type: string
|
|
27
|
+
value:
|
|
28
|
+
description: Stable value emitted in `tree-select` event detail.
|
|
29
|
+
type: string
|
|
30
|
+
open:
|
|
31
|
+
description: When true, the item's children render expanded. Single-instance state; the parent `<tree-ui>` toggles this on click + Enter/Space + ArrowRight/ArrowLeft per tree-view APG.
|
|
32
|
+
type: boolean
|
|
33
|
+
selected:
|
|
34
|
+
description: Reflects the currently-selected item. Exactly one tree-item is selected per `<tree-ui>` parent (managed by the parent).
|
|
35
|
+
type: boolean
|
|
36
|
+
badge:
|
|
37
|
+
description: |-
|
|
38
|
+
Optional trailing badge text (count, label, etc.). Renders muted + small + right-aligned alongside the row, mirroring the nav-item-ui badge API. When empty, the badge slot stays empty.
|
|
39
|
+
|
|
40
|
+
Added in §184 (v0.5.5, FEEDBACK-08 §1).
|
|
41
|
+
type: string
|
|
@@ -84,6 +84,21 @@
|
|
|
84
84
|
"--tree-actions-gap": {
|
|
85
85
|
"description": "Gap between action icons"
|
|
86
86
|
},
|
|
87
|
+
"--tree-badge-bg": {
|
|
88
|
+
"description": "Background color for the trailing badge (§184)."
|
|
89
|
+
},
|
|
90
|
+
"--tree-badge-fg": {
|
|
91
|
+
"description": "Foreground color for the trailing badge (§184)."
|
|
92
|
+
},
|
|
93
|
+
"--tree-badge-px": {
|
|
94
|
+
"description": "Inline padding for the trailing badge (§184)."
|
|
95
|
+
},
|
|
96
|
+
"--tree-badge-radius": {
|
|
97
|
+
"description": "Border radius for the trailing badge (§184)."
|
|
98
|
+
},
|
|
99
|
+
"--tree-badge-size": {
|
|
100
|
+
"description": "Font size for the trailing badge (§184)."
|
|
101
|
+
},
|
|
87
102
|
"--tree-bg-hover": {
|
|
88
103
|
"description": "Background color on hover"
|
|
89
104
|
},
|
package/components/tree/tree.css
CHANGED
|
@@ -127,6 +127,24 @@
|
|
|
127
127
|
text-overflow: ellipsis;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
/* ── Badge (§184, v0.5.5, FEEDBACK-08 §1) ──
|
|
131
|
+
Optional trailing badge for counts/labels (e.g. "Colors (7)" →
|
|
132
|
+
text="Colors" badge="7"). Empty span renders nothing (no padding,
|
|
133
|
+
no chrome). Sits before the [slot="actions"] hover-revealed slot. */
|
|
134
|
+
[slot="badge"] {
|
|
135
|
+
flex-shrink: 0;
|
|
136
|
+
font-size: var(--tree-badge-size, var(--a-fine-size));
|
|
137
|
+
color: var(--tree-badge-fg, var(--tree-fg-muted));
|
|
138
|
+
background: var(--tree-badge-bg, transparent);
|
|
139
|
+
padding: 0 var(--tree-badge-px, var(--a-space-1));
|
|
140
|
+
border-radius: var(--tree-badge-radius, var(--a-radius-sm));
|
|
141
|
+
line-height: 1;
|
|
142
|
+
font-variant-numeric: tabular-nums;
|
|
143
|
+
}
|
|
144
|
+
[slot="badge"]:empty {
|
|
145
|
+
display: none;
|
|
146
|
+
}
|
|
147
|
+
|
|
130
148
|
/* ── Actions (right side) ── */
|
|
131
149
|
[slot="actions"] {
|
|
132
150
|
display: flex;
|
|
@@ -66,6 +66,16 @@ tokens:
|
|
|
66
66
|
description: Inline-end padding of each row
|
|
67
67
|
--tree-row-radius:
|
|
68
68
|
description: Border radius of each row
|
|
69
|
+
--tree-badge-bg:
|
|
70
|
+
description: Background color for the trailing badge (§184).
|
|
71
|
+
--tree-badge-fg:
|
|
72
|
+
description: Foreground color for the trailing badge (§184).
|
|
73
|
+
--tree-badge-px:
|
|
74
|
+
description: Inline padding for the trailing badge (§184).
|
|
75
|
+
--tree-badge-radius:
|
|
76
|
+
description: Border radius for the trailing badge (§184).
|
|
77
|
+
--tree-badge-size:
|
|
78
|
+
description: Font size for the trailing badge (§184).
|
|
69
79
|
requiredIcons:
|
|
70
80
|
- caret-right
|
|
71
81
|
a2ui:
|
package/core/anchor.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anchor positioning — positions a popover/panel relative to an anchor
|
|
3
|
+
* element. Uses native CSS Anchor Positioning when supported (Chrome
|
|
4
|
+
* 125+), falls back to a JS implementation (`getBoundingClientRect()` +
|
|
5
|
+
* `position: fixed`) otherwise.
|
|
6
|
+
*
|
|
7
|
+
* Works with the Popover API: the popover renders in the top layer via
|
|
8
|
+
* `showPopover()` on a `popover="manual"` or `popover="auto"` element,
|
|
9
|
+
* and the position is wired with either `anchor()` + `position-area` or
|
|
10
|
+
* manual coords.
|
|
11
|
+
*
|
|
12
|
+
* Runtime exports mirror `core/anchor.js`. `.d.ts` authored in v0.5.6
|
|
13
|
+
* §191 to close the §178 audit-script baseline missing-sibling gap.
|
|
14
|
+
*
|
|
15
|
+
* @see ./anchor.js (runtime SoT)
|
|
16
|
+
* @see ../USAGE.md (consumer guide)
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Placement vocabulary for {@link anchorPopover}. Mirrors a subset of
|
|
21
|
+
* the floating-ui / Popper conventions. `-start` aligns the popover's
|
|
22
|
+
* leading edge to the anchor's leading edge along the perpendicular
|
|
23
|
+
* axis; `-end` aligns the trailing edges; bare (no suffix) centers.
|
|
24
|
+
*/
|
|
25
|
+
export type Placement =
|
|
26
|
+
| 'bottom'
|
|
27
|
+
| 'bottom-start'
|
|
28
|
+
| 'bottom-end'
|
|
29
|
+
| 'top'
|
|
30
|
+
| 'top-start'
|
|
31
|
+
| 'top-end'
|
|
32
|
+
| 'left'
|
|
33
|
+
| 'left-start'
|
|
34
|
+
| 'left-end'
|
|
35
|
+
| 'right'
|
|
36
|
+
| 'right-start'
|
|
37
|
+
| 'right-end';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Options for {@link anchorPopover}.
|
|
41
|
+
*/
|
|
42
|
+
export interface AnchorOptions {
|
|
43
|
+
/** Where to place the popover relative to its anchor. Default: `bottom-start`. */
|
|
44
|
+
placement?: Placement;
|
|
45
|
+
/** Pixel gap on the main (anchor-adjacent) axis. Default: 4. */
|
|
46
|
+
gap?: number;
|
|
47
|
+
/**
|
|
48
|
+
* When true, the popover's `width` is constrained to match the
|
|
49
|
+
* anchor's width — useful for combobox-style listboxes.
|
|
50
|
+
*/
|
|
51
|
+
matchWidth?: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* `true` when the current browser supports the CSS Anchor Positioning
|
|
56
|
+
* primitives the native path uses (`anchor-name`, `position-area`).
|
|
57
|
+
* `false` otherwise (browser falls back to the JS positioning path).
|
|
58
|
+
*/
|
|
59
|
+
export const supportsAnchorCSS: boolean;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Position `popover` relative to `anchor`. Picks the native CSS Anchor
|
|
63
|
+
* Positioning path when available, otherwise the JS fallback. Returns a
|
|
64
|
+
* cleanup function — call it to detach listeners / restore inline
|
|
65
|
+
* styles.
|
|
66
|
+
*/
|
|
67
|
+
export function anchorPopover(
|
|
68
|
+
anchor: Element,
|
|
69
|
+
popover: HTMLElement,
|
|
70
|
+
options?: AnchorOptions,
|
|
71
|
+
): () => void;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controller pattern — host-attached state objects that reflect into
|
|
3
|
+
* the DOM + notify subscribers on change. `BaseController` is the
|
|
4
|
+
* minimal contract; `RouteController` is the canonical routing-state
|
|
5
|
+
* implementation used by `<router-ui>` (see `core/provider.js`).
|
|
6
|
+
*
|
|
7
|
+
* Runtime exports mirror `core/controller.js`. `.d.ts` authored in
|
|
8
|
+
* v0.5.6 §191 to close the §178 audit-script baseline missing-sibling
|
|
9
|
+
* gap.
|
|
10
|
+
*
|
|
11
|
+
* @see ./controller.js (runtime SoT)
|
|
12
|
+
* @see ./provider.js (`<router-ui>` consumer of `RouteController`)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Static schema each {@link BaseController} subclass should declare so
|
|
17
|
+
* the dev-warn at `connect()` time can identify the controller in
|
|
18
|
+
* diagnostics. Optional but conventional.
|
|
19
|
+
*/
|
|
20
|
+
export interface ControllerSchema {
|
|
21
|
+
/** Stable lowercase controller identifier (e.g. `"route"`). */
|
|
22
|
+
name: string;
|
|
23
|
+
/** Map of public state field names → human-readable type label. */
|
|
24
|
+
state?: Record<string, string>;
|
|
25
|
+
/** List of canonical command names available on the controller. */
|
|
26
|
+
commands?: ReadonlyArray<string>;
|
|
27
|
+
/** Host attributes the controller writes via `reflect()`. */
|
|
28
|
+
attributes?: ReadonlyArray<string>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Base class for host-attached controllers.
|
|
33
|
+
*
|
|
34
|
+
* Subclasses MUST implement `getState()` and SHOULD declare a static
|
|
35
|
+
* `schema`; the constructor warns when these are missing the first
|
|
36
|
+
* time the controller is connected.
|
|
37
|
+
*/
|
|
38
|
+
export class BaseController {
|
|
39
|
+
/** Optional schema (subclasses declare via `static schema = …`). */
|
|
40
|
+
static schema?: ControllerSchema;
|
|
41
|
+
|
|
42
|
+
/** The host element this controller is attached to, or `null`. */
|
|
43
|
+
readonly host: Element | null;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Wire the controller to a host element. Calls
|
|
47
|
+
* {@link onConnect} + {@link reflect} once.
|
|
48
|
+
*/
|
|
49
|
+
connect(host: Element): void;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Detach from `host` (or the currently-connected host if omitted).
|
|
53
|
+
* Calls {@link onDisconnect}.
|
|
54
|
+
*/
|
|
55
|
+
disconnect(host?: Element): void;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Subscribe to state-change notifications. Returns an unsubscribe
|
|
59
|
+
* function.
|
|
60
|
+
*/
|
|
61
|
+
subscribe(fn: () => void): () => void;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Run subscriber callbacks + `reflect()` after a state mutation.
|
|
65
|
+
* Subclasses call this from their command implementations.
|
|
66
|
+
*/
|
|
67
|
+
notify(): void;
|
|
68
|
+
|
|
69
|
+
/** Lifecycle hook — override to wire listeners at connect time. */
|
|
70
|
+
onConnect(host: Element): void;
|
|
71
|
+
|
|
72
|
+
/** Lifecycle hook — override to release listeners at disconnect time. */
|
|
73
|
+
onDisconnect(host: Element): void;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Override to write controller state into the host (attributes,
|
|
77
|
+
* data-* properties, etc.). Called on every {@link notify} + at
|
|
78
|
+
* `connect()`.
|
|
79
|
+
*/
|
|
80
|
+
reflect(): void;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Return the controller's current public state. Subclasses MUST
|
|
84
|
+
* override. The default implementation throws.
|
|
85
|
+
*/
|
|
86
|
+
getState(): unknown;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* A single route declaration consumed by {@link RouteController}.
|
|
91
|
+
*/
|
|
92
|
+
export interface Route {
|
|
93
|
+
/**
|
|
94
|
+
* Path pattern. Static segments match literally; segments prefixed
|
|
95
|
+
* with `:` are captured into `params`. e.g. `/users/:id`.
|
|
96
|
+
*/
|
|
97
|
+
path: string;
|
|
98
|
+
/** Optional content URL for `<router-ui>` to fetch + inject. */
|
|
99
|
+
content?: string;
|
|
100
|
+
/** Optional document title to set when the route matches. */
|
|
101
|
+
title?: string;
|
|
102
|
+
/** Optional section identifier (consumer-defined). */
|
|
103
|
+
section?: string;
|
|
104
|
+
/** Open-ended — route definitions can carry arbitrary metadata. */
|
|
105
|
+
[key: string]: unknown;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Public state shape returned by {@link RouteController.getState}.
|
|
110
|
+
*/
|
|
111
|
+
export interface RouteState {
|
|
112
|
+
/** Current pathname being matched. */
|
|
113
|
+
path: string;
|
|
114
|
+
/** Captured `:param` values from the matched route. */
|
|
115
|
+
params: Record<string, string>;
|
|
116
|
+
/** The matched route declaration, or `null` if no match. */
|
|
117
|
+
route: Route | null;
|
|
118
|
+
/** Previous pathname (before the most recent navigation). */
|
|
119
|
+
previous: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Imperative commands exposed by {@link RouteController}. Wire-up
|
|
124
|
+
* stable across both code-driven navigation + DOM-driven link clicks
|
|
125
|
+
* (the latter via `<router-ui>`'s click delegation).
|
|
126
|
+
*/
|
|
127
|
+
export interface RouteCommands {
|
|
128
|
+
/** Push a new pathname onto the history stack + re-match routes. */
|
|
129
|
+
navigate(path: string): void;
|
|
130
|
+
/** Replace the current history entry's pathname + re-match. */
|
|
131
|
+
replace(path: string): void;
|
|
132
|
+
/** Equivalent to `history.back()` when `historySync` is on. */
|
|
133
|
+
back(): void;
|
|
134
|
+
/** Equivalent to `history.forward()` when `historySync` is on. */
|
|
135
|
+
forward(): void;
|
|
136
|
+
/** Swap the routes table at runtime (re-matches the current path). */
|
|
137
|
+
setRoutes(routes: ReadonlyArray<Route>): void;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Constructor options for {@link RouteController}.
|
|
142
|
+
*/
|
|
143
|
+
export interface RouteControllerOptions {
|
|
144
|
+
/** Initial routes table. May be empty + updated later via `setRoutes`. */
|
|
145
|
+
routes?: ReadonlyArray<Route>;
|
|
146
|
+
/** Initial pathname (defaults to `location.pathname`). */
|
|
147
|
+
initial?: string;
|
|
148
|
+
/**
|
|
149
|
+
* When `true` (default), navigate/replace push to History API +
|
|
150
|
+
* `popstate` syncs state on browser back/forward.
|
|
151
|
+
*/
|
|
152
|
+
historySync?: boolean;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Routing-state controller. Used by `<router-ui>` (see
|
|
157
|
+
* `core/provider.js`) as the canonical history-syncing route matcher.
|
|
158
|
+
* Can also be used standalone — `notify()` fires whenever the path
|
|
159
|
+
* changes; `getState()` returns the current match.
|
|
160
|
+
*/
|
|
161
|
+
export class RouteController extends BaseController {
|
|
162
|
+
static schema: ControllerSchema;
|
|
163
|
+
|
|
164
|
+
constructor(options?: RouteControllerOptions);
|
|
165
|
+
|
|
166
|
+
/** Public state — path, params, matched route, previous path. */
|
|
167
|
+
getState(): RouteState;
|
|
168
|
+
|
|
169
|
+
/** Imperative API; wire from command palette / link handlers. */
|
|
170
|
+
commands: RouteCommands;
|
|
171
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal markdown → HTML renderer for LLM output. Handles fenced code
|
|
3
|
+
* blocks, inline code, bold, italic, links, lists, headings, and
|
|
4
|
+
* paragraphs. No external dependencies.
|
|
5
|
+
*
|
|
6
|
+
* Fenced code blocks with a language identifier emit `<code-ui
|
|
7
|
+
* language="…">…</code-ui>` so the syntax-highlight upgrade picks them
|
|
8
|
+
* up automatically (see SPEC-CODE-EDITOR-001). Unlabeled fences keep
|
|
9
|
+
* the bare `<pre><code>…</code></pre>` form.
|
|
10
|
+
*
|
|
11
|
+
* Runtime exports mirror `core/markdown.js`. `.d.ts` authored in v0.5.6
|
|
12
|
+
* §191 to close the §178 audit-script baseline missing-sibling gap.
|
|
13
|
+
*
|
|
14
|
+
* @see ./markdown.js (runtime SoT)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Render a markdown source string to HTML.
|
|
19
|
+
*
|
|
20
|
+
* The output is a sanitized HTML string suitable for direct
|
|
21
|
+
* `element.innerHTML` assignment — text content is HTML-escaped before
|
|
22
|
+
* inline formatting is applied. Consumer is responsible for any
|
|
23
|
+
* additional context-specific sanitization (e.g. URL-scheme allowlisting
|
|
24
|
+
* for the link targets).
|
|
25
|
+
*/
|
|
26
|
+
export function renderMarkdown(src: string): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional polyfills — for consumers extending BELOW the library's
|
|
3
|
+
* stated baseline (Chromium 125+, Safari 17.4+, Firefox 129+).
|
|
4
|
+
*
|
|
5
|
+
* **Side-effect-only module.** Importing this file runs feature checks
|
|
6
|
+
* at module-evaluation time and dynamically loads polyfills only when
|
|
7
|
+
* the runtime lacks support:
|
|
8
|
+
*
|
|
9
|
+
* - Popover API (consumers extending to Firefox < 125 / Safari < 17)
|
|
10
|
+
* - CSS Anchor Positioning (consumers extending to Safari < 26 /
|
|
11
|
+
* Firefox < 147)
|
|
12
|
+
*
|
|
13
|
+
* Browsers with native support skip the download. The polyfill
|
|
14
|
+
* packages (`@oddbird/popover-polyfill`, `@oddbird/css-anchor-positioning`)
|
|
15
|
+
* are optional — if not installed, the import silently fails.
|
|
16
|
+
*
|
|
17
|
+
* Consumers on the stated baseline should NOT import this module — the
|
|
18
|
+
* runtime checks resolve to no-op, but skipping the file avoids the
|
|
19
|
+
* conditional `import()` setup entirely.
|
|
20
|
+
*
|
|
21
|
+
* Runtime mirror: `core/polyfills.js`. `.d.ts` authored in v0.5.6 §191
|
|
22
|
+
* to close the §178 audit-script baseline missing-sibling gap.
|
|
23
|
+
*
|
|
24
|
+
* @see ./polyfills.js (runtime SoT)
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
// Side-effect-only module — no exports. The empty `export {}` marks
|
|
28
|
+
// the file as an ES module so TypeScript treats `import '...polyfills.js'`
|
|
29
|
+
// as a valid module side-effect import without complaining about a
|
|
30
|
+
// missing module shape.
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<router-ui>` provider — declarative + imperative client-side
|
|
3
|
+
* routing built on {@link RouteController} (re-declared here for
|
|
4
|
+
* historical reasons; the canonical export lives in `core/controller.js`).
|
|
5
|
+
*
|
|
6
|
+
* Two consumer paths:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Declarative** — assign `router.routes = [...]` and the provider
|
|
9
|
+
* instantiates its own controller, wires `popstate`, intercepts
|
|
10
|
+
* same-origin link clicks, fetches each matched route's `content`
|
|
11
|
+
* URL, and injects into the host element.
|
|
12
|
+
*
|
|
13
|
+
* 2. **Controller-driven** — construct a {@link RouteController}
|
|
14
|
+
* yourself + assign to `router.controller`. Useful when multiple
|
|
15
|
+
* UI surfaces need to share routing state.
|
|
16
|
+
*
|
|
17
|
+
* Side-effect: importing this module calls
|
|
18
|
+
* `customElements.define('router-ui', UIRouter)`.
|
|
19
|
+
*
|
|
20
|
+
* Runtime exports mirror `core/provider.js`. `.d.ts` authored in v0.5.6
|
|
21
|
+
* §191 to close the §178 audit-script baseline missing-sibling gap.
|
|
22
|
+
*
|
|
23
|
+
* @see ./provider.js (runtime SoT — also defines `customElements`)
|
|
24
|
+
* @see ./controller.d.ts (canonical `RouteController` typing)
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { UIElement } from './element.js';
|
|
28
|
+
import type { Route, RouteCommands, RouteState, ControllerSchema, RouteControllerOptions } from './controller.js';
|
|
29
|
+
import { BaseController } from './controller.js';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Routing-state controller. Re-declared from `core/controller.js` for
|
|
33
|
+
* historical compatibility — both files define the same class shape;
|
|
34
|
+
* consumers can import either. New code should prefer
|
|
35
|
+
* `import { RouteController } from '@adia-ai/web-components/core/controller'`
|
|
36
|
+
* for the canonical path.
|
|
37
|
+
*/
|
|
38
|
+
export class RouteController extends BaseController {
|
|
39
|
+
static schema: ControllerSchema;
|
|
40
|
+
constructor(options?: RouteControllerOptions);
|
|
41
|
+
getState(): RouteState;
|
|
42
|
+
commands: RouteCommands;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Optional async transform applied to fetched route content before
|
|
47
|
+
* injection. Useful for wrapping content in a layout shell.
|
|
48
|
+
*/
|
|
49
|
+
export type TemplateResolver = (html: string, route: Route) => string | Promise<string>;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* `<router-ui>` custom element. Side-effect-registered on module load.
|
|
53
|
+
*/
|
|
54
|
+
export class UIRouter extends UIElement {
|
|
55
|
+
/** Currently-bound controller (declarative-mode controller is auto-created). */
|
|
56
|
+
controller?: RouteController;
|
|
57
|
+
|
|
58
|
+
/** Optional template wrapper hook — see {@link TemplateResolver}. */
|
|
59
|
+
templateResolver?: TemplateResolver;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Declarative-mode setter — assigning routes auto-creates an
|
|
63
|
+
* internal {@link RouteController} on first assignment, or
|
|
64
|
+
* `setRoutes`-replaces the table on subsequent ones.
|
|
65
|
+
*/
|
|
66
|
+
set routes(list: ReadonlyArray<Route>);
|
|
67
|
+
|
|
68
|
+
/** Shortcut for `controller.commands.navigate(path)`. */
|
|
69
|
+
navigate(path: string): void;
|
|
70
|
+
|
|
71
|
+
/** Shortcut for `controller.commands.replace(path)`. */
|
|
72
|
+
replace(path: string): void;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* `router-ui` is registered as a side-effect of module load.
|
|
77
|
+
*/
|
|
78
|
+
declare global {
|
|
79
|
+
interface HTMLElementTagNameMap {
|
|
80
|
+
'router-ui': UIRouter;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* streams-bridge — proxy data-stream signals into A2UI surface data
|
|
3
|
+
* models (per OD-CHART-16 option b).
|
|
4
|
+
*
|
|
5
|
+
* The bridge duck-types the renderer (it needs `.process()`, nothing
|
|
6
|
+
* else), so it works with any A2UI-protocol consumer — the actual
|
|
7
|
+
* `A2UIRenderer` from `@adia-ai/a2ui-runtime`, a custom renderer, or
|
|
8
|
+
* a test stub.
|
|
9
|
+
*
|
|
10
|
+
* Contract:
|
|
11
|
+
* - One-way only: stream → data model. A2UI writes back to its model
|
|
12
|
+
* (e.g. via `update-data-model` wiring actions) do NOT propagate
|
|
13
|
+
* into the stream signal.
|
|
14
|
+
* - Tear down with the returned dispose function. Dispose detaches
|
|
15
|
+
* the effect; it does NOT release the stream's refcount.
|
|
16
|
+
* - `select` uses dot-separated path syntax (matches
|
|
17
|
+
* `data-stream-path` on the trait). `path` uses slash-separated
|
|
18
|
+
* syntax (matches A2UI bindings).
|
|
19
|
+
*
|
|
20
|
+
* Runtime exports mirror `core/streams-bridge.js`. `.d.ts` authored in
|
|
21
|
+
* v0.5.6 §191 to close the §178 audit-script baseline missing-sibling
|
|
22
|
+
* gap.
|
|
23
|
+
*
|
|
24
|
+
* @see ./streams-bridge.js (runtime SoT)
|
|
25
|
+
* @see ./data-stream.js (the stream registry the bridge reads from)
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Minimal renderer contract the bridge requires. The actual
|
|
30
|
+
* `A2UIRenderer` from `@adia-ai/a2ui-runtime` satisfies this surface,
|
|
31
|
+
* as does any custom renderer that handles
|
|
32
|
+
* `{ type: 'updateDataModel', ... }` actions.
|
|
33
|
+
*/
|
|
34
|
+
export interface BridgeRenderer {
|
|
35
|
+
process(action: {
|
|
36
|
+
type: 'updateDataModel';
|
|
37
|
+
surfaceId: string;
|
|
38
|
+
path: string;
|
|
39
|
+
value: unknown;
|
|
40
|
+
}): void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Bridge options shared by {@link bridgeStream} and
|
|
45
|
+
* {@link bridgeStreamAsync}.
|
|
46
|
+
*/
|
|
47
|
+
export interface BridgeOptions {
|
|
48
|
+
/** Target surface ID inside the renderer's data model. */
|
|
49
|
+
surfaceId: string;
|
|
50
|
+
/** Stream registry ID (the same string passed to `acquireStream`). */
|
|
51
|
+
streamId: string;
|
|
52
|
+
/** Slash-separated A2UI data-model path inside the surface. */
|
|
53
|
+
path: string;
|
|
54
|
+
/** Optional dot-separated path to a sub-value within the stream's signal value. */
|
|
55
|
+
select?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Bridge a registered stream into a renderer's surface data model.
|
|
60
|
+
*
|
|
61
|
+
* If the stream is not yet registered, logs a warning and returns a
|
|
62
|
+
* no-op dispose. Use {@link bridgeStreamAsync} when the stream might
|
|
63
|
+
* register after this call (e.g. DOM source connecting on the same
|
|
64
|
+
* tick as the bridge wiring).
|
|
65
|
+
*
|
|
66
|
+
* Returns a dispose function — call it to detach the effect.
|
|
67
|
+
*/
|
|
68
|
+
export function bridgeStream(renderer: BridgeRenderer, opts: BridgeOptions): () => void;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Async variant — awaits the stream's registration before attaching
|
|
72
|
+
* the effect. Resolves once the bridge is wired (the resolved value
|
|
73
|
+
* is the dispose function).
|
|
74
|
+
*/
|
|
75
|
+
export function bridgeStreamAsync(
|
|
76
|
+
renderer: BridgeRenderer,
|
|
77
|
+
opts: BridgeOptions,
|
|
78
|
+
): Promise<() => void>;
|
package/core/template.js
CHANGED
|
@@ -137,14 +137,32 @@ function scan(fragment, count) {
|
|
|
137
137
|
// bug. Hot template paths fire many times, so warn (not throw):
|
|
138
138
|
// a thrown error would crash render; warn surfaces the bug class.
|
|
139
139
|
if (attr.value.includes('{{p:')) {
|
|
140
|
+
// §184 (v0.5.5, FEEDBACK-08 §5): `class` is special-cased
|
|
141
|
+
// in the hint because `.class=${expr}` sets a JS expando
|
|
142
|
+
// property (`element.class = "foo"`) — NOT the `class`
|
|
143
|
+
// attribute / className. Consumers following the original
|
|
144
|
+
// §152 generic hint silently lost CSS classes. For class,
|
|
145
|
+
// suggest `.className=${expr}`; for style suggest the
|
|
146
|
+
// canonical style-object path; for everything else keep
|
|
147
|
+
// the generic property-assignment recipe.
|
|
148
|
+
const a = attr.name;
|
|
149
|
+
const specific =
|
|
150
|
+
a === 'class'
|
|
151
|
+
? ` .className=\${expression} ← write to the className property (NOT .class, which is an expando)\n` +
|
|
152
|
+
` class="\${expression}" ← full replacement (whole class string is the expression)\n` +
|
|
153
|
+
` .classList=\${{foo: true, bar: false}} ← if/when implemented; verify in USAGE.md\n`
|
|
154
|
+
: a === 'style'
|
|
155
|
+
? ` .style.cssText=\${expression} ← write CSS text to .style.cssText\n` +
|
|
156
|
+
` style="\${expression}" ← full replacement of the style string\n`
|
|
157
|
+
: ` ${a}="\${expression}" ← full replacement (whole attr is the placeholder)\n` +
|
|
158
|
+
` .${a}=\${expression} ← property assignment (preferred for objects/functions)\n`;
|
|
140
159
|
// eslint-disable-next-line no-console
|
|
141
160
|
console.warn(
|
|
142
161
|
`[template] Partial attribute interpolation is not supported.\n` +
|
|
143
162
|
` Element: <${n.tagName.toLowerCase()}>\n` +
|
|
144
|
-
` Attribute: ${
|
|
163
|
+
` Attribute: ${a}="${attr.value.slice(0, 80)}${attr.value.length > 80 ? '…' : ''}"\n` +
|
|
145
164
|
` Use one of:\n` +
|
|
146
|
-
|
|
147
|
-
` .${attr.name}=\${expression} ← property assignment (preferred for objects/functions)\n` +
|
|
165
|
+
specific +
|
|
148
166
|
` Compute the full attr value as a single expression and interpolate the whole.`
|
|
149
167
|
);
|
|
150
168
|
}
|