@adia-ai/web-components 0.7.9 → 0.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog — @adia-ai/web-components
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [0.7.10] — 2026-06-03
6
+
7
+ ### Added
8
+
9
+ - **New `<frame-ui>` layout primitive — sticky-header / scroll-body / sticky-footer frame.** The chrome-less app-shell skeleton: a flex column that fills its parent; native `<header>` / `<footer>` children pin (`flex: 0 0 auto`), `<section>` scrolls (`flex: 1; min-block-size: 0; overflow: auto`) — the only overflow region. Regions are positioned by tag + DOM order (Light DOM, no slot projection — ADR-0033). CSS-only `category: layout` component (no props). Common shape `<frame-ui><section>…</section><footer>…</footer></frame-ui>`; add `<header>` only for a panel title/toolbar. Distinct from `<card-ui>` (border + elevation + rich header grid), `<drawer-ui>` / `<modal-ui>` (backdrop + dismiss), and the page shells — those layer chrome over the same region contract (a future cut extracts the shared frame `@layer` they compose). Requires a definite-height parent. Files: `components/frame/{frame.yaml,frame.css,frame.class.js,frame.js,frame.html}`.
10
+
11
+ ### Changed
12
+
13
+ - **`[verse]` register: bare-verse prose type bumped one tier (`sm` → `md`).** A bare `[verse]` context now resolves its prose type to the `md` tier instead of `sm` — `--a-display-size` / `--a-title-size` / `--a-heading-size` / `--a-section-size` re-point `sm`→`md` (display 18→23, title 16→19, heading 13→14, section 13→14px). `--a-radius-max` tightened `1rem`→`0.75rem` (12px). **Behavior change** — prose-ish text in a compact `[verse]` surface renders one tier larger; controls + the `[verse][size]` sub-tiers are unaffected. File: `styles/verse.css`.
14
+ - **CDN bundles rebuilt** — `dist/web-components.min.css` + `dist/web-components.min.js` regenerated so `<frame-ui>` (CSS + registration), the `list-item-ui` grid fix, and the `[verse]` type bump reach `@adia-ai/web-components@0.7` CDN consumers.
15
+
16
+ ### Fixed
17
+
18
+ - **`list-item-ui` description now spans the full content width.** `[slot="description"]` was pinned to `grid-column: 2`, so when a `[slot="action"]` was present (the 3-column `icon | content | action` grid) a multi-line description was boxed into the content column — it wrapped early and left dead space under the action. The grid is now a **header-row model**: `[slot="icon"]` · `[slot="text"]` · `[slot="action"]` align on row 1, and `[slot="description"]` spans `grid-column: 2 / -1` on row 2 (flowing under the action). The icon + action `grid-row` changed `1 / -1` → `1`, which is identical for single-row items (icon + text only) — so nav menus / simple lists are unchanged; only rows carrying a description are affected (e.g. `onboarding-checklist-ui` rows gain full-width descriptions + title-aligned action buttons). File: `components/list/list.css`.
19
+
3
20
  ## [0.7.9] — 2026-06-03
4
21
 
5
22
  ### Changed
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://adiaui.dev/a2ui/v0_9/components/Frame.json",
4
+ "title": "Frame",
5
+ "description": "Sticky-header / scrolling-body / sticky-footer layout frame — the\nchrome-less app-shell skeleton. A flex column that fills its parent's\nblock size: a native <header> child pins to the top, a <footer> child\npins to the bottom, and the <section> child scrolls between them (the\nonly region with overflow). All three regions are OPTIONAL and positioned\nby tag + DOM order (Light DOM, no slot projection — ADR-0033), so the\ncommon shape is just <section> + <footer>. Use for tab / panel content\nwhere actions stay visible while the body scrolls. Distinct from <card-ui>\n(adds border + elevation + a rich header grid), <drawer-ui> / <modal-ui>\n(add a backdrop + dismiss), and the page shells (<admin-page> / <page-ui>) —\nthose layer chrome over this same region contract. Requires a definite-height\nparent (a flex/grid chain rooted at a viewport height) for the section to\nscroll; in a content-sized parent it collapses to its content (no scroll,\nnot broken).\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": "Frame"
18
+ }
19
+ },
20
+ "required": [
21
+ "component"
22
+ ],
23
+ "unevaluatedProperties": false,
24
+ "x-adiaui": {
25
+ "anti_patterns": [],
26
+ "category": "layout",
27
+ "composes": [],
28
+ "events": {},
29
+ "examples": [
30
+ {
31
+ "description": "Scrolling body with a pinned footer action bar (no header).",
32
+ "a2ui": "[\n { \"id\": \"root\", \"component\": \"Frame\", \"children\": [\"body\", \"actions\"] },\n { \"id\": \"body\", \"component\": \"Section\", \"children\": [\"copy\"] },\n { \"id\": \"copy\", \"component\": \"Text\", \"variant\": \"body\", \"textContent\": \"Scrollable panel content.\" },\n { \"id\": \"actions\", \"component\": \"Footer\", \"children\": [\"save\"] },\n { \"id\": \"save\", \"component\": \"Button\", \"text\": \"Save\", \"variant\": \"primary\" }\n]",
33
+ "name": "panel-with-footer"
34
+ }
35
+ ],
36
+ "keywords": [
37
+ "frame",
38
+ "panel",
39
+ "layout",
40
+ "scroll",
41
+ "sticky",
42
+ "footer",
43
+ "header",
44
+ "shell",
45
+ "app",
46
+ "sheet"
47
+ ],
48
+ "name": "UIFrame",
49
+ "related": [
50
+ "Card",
51
+ "Drawer",
52
+ "Modal",
53
+ "Col"
54
+ ],
55
+ "slots": {},
56
+ "states": [
57
+ {
58
+ "description": "Default, ready for interaction.",
59
+ "name": "idle"
60
+ }
61
+ ],
62
+ "status": "stable",
63
+ "synonyms": {
64
+ "panel": [
65
+ "panel",
66
+ "frame",
67
+ "sheet"
68
+ ],
69
+ "scroll": [
70
+ "scroll",
71
+ "frame",
72
+ "body"
73
+ ],
74
+ "shell": [
75
+ "shell",
76
+ "frame",
77
+ "app"
78
+ ]
79
+ },
80
+ "tag": "frame-ui",
81
+ "tokens": {},
82
+ "traits": [],
83
+ "version": 1
84
+ }
85
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Non-side-effect class export for `<frame-ui>`.
3
+ *
4
+ * Importing this file gives you the class without auto-registering the tag.
5
+ * The auto-register path is `@adia-ai/web-components/components/frame`
6
+ * (which imports this file + calls `defineIfFree()`).
7
+ *
8
+ * @see ../../USAGE.md#registration--auto-vs-explicit
9
+ */
10
+
11
+ import { UIElement } from '../../core/element.js';
12
+
13
+ /**
14
+ * <frame-ui> — sticky-header / scroll-body / sticky-footer layout frame.
15
+ *
16
+ * <frame-ui>
17
+ * <header>…</header> <!-- optional: pinned top -->
18
+ * <section>…</section> <!-- scrolling body (the only overflow region) -->
19
+ * <footer>…</footer> <!-- optional: pinned bottom (actions) -->
20
+ * </frame-ui>
21
+ *
22
+ * Pure-CSS layout container — no props, no template. Regions are native
23
+ * <header>/<section>/<footer> children positioned by tag + DOM order (Light
24
+ * DOM, no slot projection). The class exists only to register the tag; all
25
+ * behaviour is in frame.css. See <card-ui>/<drawer-ui>/<modal-ui> for the
26
+ * chrome'd variants that compose the same region contract.
27
+ */
28
+ export class UIFrame extends UIElement {
29
+ static properties = {};
30
+ static template = () => null;
31
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * <frame-ui> — sticky-header / scroll-body / sticky-footer layout frame.
3
+ *
4
+ * The chrome-less app-shell skeleton: a flex column that fills its parent's
5
+ * block size. A native <header> child pins to the top, a <footer> child pins
6
+ * to the bottom, and the <section> child scrolls between them (the only region
7
+ * with overflow). All three regions are OPTIONAL and positioned by tag + DOM
8
+ * order — Light DOM, no slot projection (ADR-0033). <card-ui> / <drawer-ui> /
9
+ * <modal-ui> layer chrome (border / elevation / backdrop) over this same
10
+ * region contract.
11
+ *
12
+ * Height: frame-ui fills its parent, so the parent must establish a definite
13
+ * block size (a flex/grid chain rooted at a viewport height, or an explicit
14
+ * height). In a content-sized parent it collapses to its content and the
15
+ * <section> simply doesn't scroll (graceful, not broken).
16
+ */
17
+ @scope (frame-ui) {
18
+ :where(:scope) {
19
+ display: flex;
20
+ flex-direction: column;
21
+ block-size: 100%;
22
+ min-block-size: 0;
23
+ }
24
+
25
+ /* Pinned rails — <header> tops, <footer> bottoms; fixed height, never scroll. */
26
+ :scope > :is(header, footer) {
27
+ flex: 0 0 auto;
28
+ min-block-size: 0;
29
+ }
30
+
31
+ /* The single scroll region. `min-block-size: 0` lets the flex item shrink
32
+ below its content's intrinsic size — the classic flex-scroll gotcha that
33
+ makes overflow:auto actually scroll inside a column. */
34
+ :scope > section {
35
+ flex: 1 1 auto;
36
+ min-block-size: 0;
37
+ overflow: auto;
38
+ }
39
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * `<frame-ui>` — Sticky-header / scrolling-body / sticky-footer layout frame — the
3
+ chrome-less app-shell skeleton. A flex column that fills its parent's
4
+ block size: a native <header> child pins to the top, a <footer> child
5
+ pins to the bottom, and the <section> child scrolls between them (the
6
+ only region with overflow). All three regions are OPTIONAL and positioned
7
+ by tag + DOM order (Light DOM, no slot projection — ADR-0033), so the
8
+ common shape is just <section> + <footer>. Use for tab / panel content
9
+ where actions stay visible while the body scrolls. Distinct from <card-ui>
10
+ (adds border + elevation + a rich header grid), <drawer-ui> / <modal-ui>
11
+ (add a backdrop + dismiss), and the page shells (<admin-page> / <page-ui>) —
12
+ those layer chrome over this same region contract. Requires a definite-height
13
+ parent (a flex/grid chain rooted at a viewport height) for the section to
14
+ scroll; in a content-sized parent it collapses to its content (no scroll,
15
+ not broken).
16
+
17
+ *
18
+ * @see https://ui-kit.exe.xyz/site/components/frame
19
+ *
20
+ * Type declarations generated by scripts/build/dts-codegen.mjs from
21
+ * the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
22
+ * run `npm run build:components`, then `npm run codegen:dts` to
23
+ * regenerate; or hand-author this file fully if rich event types are
24
+ * needed beyond what the yaml `events:` block can express.
25
+ */
26
+
27
+ import { UIElement } from '../../core/element.js';
28
+
29
+ export class UIFrame extends UIElement {
30
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `<frame-ui>` — auto-registers the tag on import.
3
+ *
4
+ * For non-side-effect class import (test isolation, tag override), use
5
+ * the `class` subpath:
6
+ *
7
+ * import { UIFrame } from '@adia-ai/web-components/components/frame/class';
8
+ *
9
+ * @see ../../USAGE.md#registration--auto-vs-explicit
10
+ */
11
+
12
+ import { defineIfFree } from '../../core/register.js';
13
+ import { UIFrame } from './frame.class.js';
14
+
15
+ defineIfFree('frame-ui', UIFrame);
16
+
17
+ export { UIFrame };
@@ -0,0 +1,84 @@
1
+ # Edit this file; run `npm run build:components` to regenerate a2ui.json.
2
+ $schema: ../../../../scripts/schemas/component.yaml.schema.json
3
+ name: UIFrame
4
+ tag: frame-ui
5
+ status: stable
6
+ component: Frame
7
+ category: layout
8
+ version: 1
9
+ description: |
10
+ Sticky-header / scrolling-body / sticky-footer layout frame — the
11
+ chrome-less app-shell skeleton. A flex column that fills its parent's
12
+ block size: a native <header> child pins to the top, a <footer> child
13
+ pins to the bottom, and the <section> child scrolls between them (the
14
+ only region with overflow). All three regions are OPTIONAL and positioned
15
+ by tag + DOM order (Light DOM, no slot projection — ADR-0033), so the
16
+ common shape is just <section> + <footer>. Use for tab / panel content
17
+ where actions stay visible while the body scrolls. Distinct from <card-ui>
18
+ (adds border + elevation + a rich header grid), <drawer-ui> / <modal-ui>
19
+ (add a backdrop + dismiss), and the page shells (<admin-page> / <page-ui>) —
20
+ those layer chrome over this same region contract. Requires a definite-height
21
+ parent (a flex/grid chain rooted at a viewport height) for the section to
22
+ scroll; in a content-sized parent it collapses to its content (no scroll,
23
+ not broken).
24
+ props: {}
25
+ events: {}
26
+ slots: {}
27
+ states:
28
+ - name: idle
29
+ description: Default, ready for interaction.
30
+ traits: []
31
+ tokens: {}
32
+ a2ui:
33
+ rules:
34
+ - rule: 'Use <frame-ui> for a scroll-body-with-pinned-footer panel — the <section> scrolls; <header> / <footer> stay fixed.'
35
+ reason: 'The chrome-less app-shell frame.'
36
+ - rule: 'Regions are native <header> / <section> / <footer> children, positioned by tag + DOM order. Do NOT add slot= attributes — slot is inert in Light DOM.'
37
+ reason: 'Light-DOM substrate (ADR-0033).'
38
+ - rule: 'Most panels need only <section> + <footer>; add <header> only when the panel has its own title or toolbar.'
39
+ reason: 'Header is optional.'
40
+ - rule: 'For a bordered/elevated surface use <card-ui>; for an overlay use <drawer-ui> / <modal-ui>; for routed page layout use <admin-page> / <page-ui>. frame-ui is the bare layout only.'
41
+ reason: 'Decision rule vs chrome siblings.'
42
+ - rule: 'frame-ui fills its parent — give the parent a definite height (a flex/grid chain to a viewport height) or the section will not scroll.'
43
+ reason: 'Scroll requires a bounded height.'
44
+ anti_patterns: []
45
+ examples:
46
+ - name: panel-with-footer
47
+ description: Scrolling body with a pinned footer action bar (no header).
48
+ a2ui: >-
49
+ [
50
+ { "id": "root", "component": "Frame", "children": ["body", "actions"] },
51
+ { "id": "body", "component": "Section", "children": ["copy"] },
52
+ { "id": "copy", "component": "Text", "variant": "body", "textContent": "Scrollable panel content." },
53
+ { "id": "actions", "component": "Footer", "children": ["save"] },
54
+ { "id": "save", "component": "Button", "text": "Save", "variant": "primary" }
55
+ ]
56
+ keywords:
57
+ - frame
58
+ - panel
59
+ - layout
60
+ - scroll
61
+ - sticky
62
+ - footer
63
+ - header
64
+ - shell
65
+ - app
66
+ - sheet
67
+ synonyms:
68
+ panel:
69
+ - panel
70
+ - frame
71
+ - sheet
72
+ scroll:
73
+ - scroll
74
+ - frame
75
+ - body
76
+ shell:
77
+ - shell
78
+ - frame
79
+ - app
80
+ related:
81
+ - Card
82
+ - Drawer
83
+ - Modal
84
+ - Col
@@ -74,6 +74,7 @@ export { UIFields } from './fields/fields.js';
74
74
  export { UIRow } from './row/row.js';
75
75
  export { UIGrid } from './grid/grid.js';
76
76
  export { UIStack } from './stack/stack.js';
77
+ export { UIFrame } from './frame/frame.js';
77
78
  export { UIChart } from './chart/chart.js';
78
79
  export { UIChartLegend } from './chart-legend/chart-legend.js';
79
80
  export { UIPopover } from './popover/popover.js';
@@ -106,10 +106,12 @@
106
106
  --list-item-desc-font-size: var(--a-ui-sm);
107
107
  }
108
108
 
109
- /* Anatomy:
110
- col 1 = icon (auto width; collapses to 0 when no icon)
111
- col 2 = content stack (text on row 1, description on row 2)
112
- The icon spans both rows + centers vertically with the stack.
109
+ /* Anatomy (header-row model):
110
+ row 1 = icon (col 1) · text/title (col 2) · action (col 3), all aligned
111
+ on the title row. row 2 = description, spanning col 2 / -1 (under the
112
+ action) so multi-line supporting text uses the full content width rather
113
+ than being boxed into col 2 beside the action. For icon+text-only items
114
+ there is a single row, so `grid-row: 1` is identical to the old `1 / -1`.
113
115
  `[slot="content"]` (used when consumer provides custom rendering)
114
116
  spans all columns. */
115
117
  :scope {
@@ -136,7 +138,7 @@
136
138
  authored children + template-engine-wrapped conditionals). */
137
139
  :scope [slot="icon"] {
138
140
  grid-column: 1;
139
- grid-row: 1 / -1;
141
+ grid-row: 1;
140
142
  align-self: center;
141
143
  color: var(--list-item-icon-color);
142
144
  }
@@ -147,7 +149,7 @@
147
149
  }
148
150
 
149
151
  :scope [slot="description"] {
150
- grid-column: 2;
152
+ grid-column: 2 / -1;
151
153
  grid-row: 2;
152
154
  color: var(--list-item-desc-color);
153
155
  font-size: var(--list-item-desc-font-size);
@@ -157,7 +159,8 @@
157
159
  /* When a [slot="action"] child is present, the grid becomes 3-column:
158
160
  icon | content | action. The :has() selector promotes the template
159
161
  only when an action exists, so 2-column layouts stay unaffected.
160
- Action is right-aligned + vertically centered (spans both content rows).
162
+ Action is right-aligned on the title row (row 1) so a multi-line
163
+ description below can span the full width (col 2 / -1) beneath it.
161
164
  Used by onboarding-checklist-ui item rows + any consumer that needs an
162
165
  end-aligned action button on a list-item row.
163
166
  NOTE: NOT using `> [slot="action"]` (direct-child) — the template
@@ -171,7 +174,7 @@
171
174
  }
172
175
  :scope [slot="action"] {
173
176
  grid-column: 3;
174
- grid-row: 1 / -1;
177
+ grid-row: 1;
175
178
  align-self: center;
176
179
  justify-self: end;
177
180
  }