@adia-ai/web-components 0.6.36 → 0.6.38
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 +48 -1
- package/components/accordion/accordion-item.a2ui.json +3 -0
- package/components/accordion/accordion-item.yaml +5 -0
- package/components/action-list/action-item.a2ui.json +5 -1
- package/components/action-list/action-item.yaml +7 -0
- package/components/badge/badge.a2ui.json +10 -0
- package/components/badge/badge.css +70 -0
- package/components/badge/badge.yaml +20 -0
- package/components/blockquote/blockquote.a2ui.json +121 -0
- package/components/blockquote/blockquote.class.js +68 -0
- package/components/blockquote/blockquote.css +46 -0
- package/components/blockquote/blockquote.d.ts +31 -0
- package/components/blockquote/blockquote.js +17 -0
- package/components/blockquote/blockquote.yaml +124 -0
- package/components/button/button.css +11 -3
- package/components/calendar-picker/calendar-picker.a2ui.json +15 -0
- package/components/calendar-picker/calendar-picker.class.js +7 -1
- package/components/calendar-picker/calendar-picker.yaml +14 -0
- package/components/card/card.a2ui.json +17 -1
- package/components/card/card.yaml +24 -1
- package/components/color-input/color-input.a2ui.json +2 -2
- package/components/color-input/color-input.class.js +9 -2
- package/components/color-input/color-input.yaml +2 -2
- package/components/combobox/combobox.class.js +4 -0
- package/components/context-menu/context-menu.a2ui.json +159 -0
- package/components/context-menu/context-menu.class.js +275 -0
- package/components/context-menu/context-menu.css +56 -0
- package/components/context-menu/context-menu.d.ts +70 -0
- package/components/context-menu/context-menu.js +17 -0
- package/components/context-menu/context-menu.yaml +136 -0
- package/components/date-range-picker/date-range-picker.a2ui.json +15 -0
- package/components/date-range-picker/date-range-picker.class.js +2 -0
- package/components/date-range-picker/date-range-picker.yaml +14 -0
- package/components/datetime-picker/datetime-picker.a2ui.json +15 -0
- package/components/datetime-picker/datetime-picker.class.js +3 -1
- package/components/datetime-picker/datetime-picker.d.ts +2 -0
- package/components/datetime-picker/datetime-picker.yaml +14 -0
- package/components/empty-state/empty-state.a2ui.json +9 -0
- package/components/empty-state/empty-state.class.js +2 -0
- package/components/empty-state/empty-state.yaml +15 -0
- package/components/feed/feed-item.a2ui.json +5 -0
- package/components/feed/feed-item.yaml +10 -0
- package/components/feed/feed.class.js +13 -5
- package/components/feed/feed.css +14 -0
- package/components/field/field.a2ui.json +6 -0
- package/components/field/field.yaml +10 -0
- package/components/index.js +11 -0
- package/components/inline-edit/inline-edit.a2ui.json +159 -0
- package/components/inline-edit/inline-edit.class.js +184 -0
- package/components/inline-edit/inline-edit.css +62 -0
- package/components/inline-edit/inline-edit.d.ts +52 -0
- package/components/inline-edit/inline-edit.js +12 -0
- package/components/inline-edit/inline-edit.yaml +125 -0
- package/components/integration-card/integration-card.class.js +9 -0
- package/components/integration-card/integration-card.test.js +4 -3
- package/components/list/list-item.a2ui.json +8 -1
- package/components/list/list-item.yaml +12 -0
- package/components/list/list.css +36 -6
- package/components/mark/mark.a2ui.json +109 -0
- package/components/mark/mark.class.js +22 -0
- package/components/mark/mark.css +39 -0
- package/components/mark/mark.d.ts +27 -0
- package/components/mark/mark.js +12 -0
- package/components/mark/mark.yaml +87 -0
- package/components/modal/modal.a2ui.json +9 -0
- package/components/modal/modal.yaml +14 -0
- package/components/nav-group/nav-group.a2ui.json +3 -0
- package/components/nav-group/nav-group.css +7 -1
- package/components/nav-group/nav-group.yaml +5 -0
- package/components/nav-item/nav-item.a2ui.json +3 -0
- package/components/nav-item/nav-item.yaml +5 -0
- package/components/number-format/number-format.a2ui.json +180 -0
- package/components/number-format/number-format.class.js +96 -0
- package/components/number-format/number-format.css +18 -0
- package/components/number-format/number-format.d.ts +68 -0
- package/components/number-format/number-format.js +17 -0
- package/components/number-format/number-format.yaml +204 -0
- package/components/pagination/pagination.a2ui.json +19 -2
- package/components/pagination/pagination.class.js +90 -37
- package/components/pagination/pagination.css +32 -127
- package/components/pagination/pagination.d.ts +8 -2
- package/components/pagination/pagination.test.js +195 -0
- package/components/pagination/pagination.yaml +22 -1
- package/components/password-strength/password-strength.a2ui.json +152 -0
- package/components/password-strength/password-strength.class.js +157 -0
- package/components/password-strength/password-strength.css +80 -0
- package/components/password-strength/password-strength.d.ts +59 -0
- package/components/password-strength/password-strength.js +17 -0
- package/components/password-strength/password-strength.yaml +153 -0
- package/components/popover/popover.css +43 -23
- package/components/popover/popover.yaml +8 -4
- package/components/qr-code/QR-TEST.svg +4 -0
- package/components/qr-code/qr-code.a2ui.json +154 -0
- package/components/qr-code/qr-code.class.js +129 -0
- package/components/qr-code/qr-code.css +41 -0
- package/components/qr-code/qr-code.d.ts +83 -0
- package/components/qr-code/qr-code.js +17 -0
- package/components/qr-code/qr-code.yaml +203 -0
- package/components/qr-code/qr-encoder.js +633 -0
- package/components/relative-time/relative-time.a2ui.json +120 -0
- package/components/relative-time/relative-time.class.js +136 -0
- package/components/relative-time/relative-time.css +22 -0
- package/components/relative-time/relative-time.d.ts +51 -0
- package/components/relative-time/relative-time.js +17 -0
- package/components/relative-time/relative-time.yaml +133 -0
- package/components/segmented/segmented.class.js +15 -3
- package/components/select/select.a2ui.json +3 -0
- package/components/select/select.class.js +4 -0
- package/components/select/select.yaml +5 -0
- package/components/skip-nav/skip-nav.a2ui.json +92 -0
- package/components/skip-nav/skip-nav.class.js +45 -0
- package/components/skip-nav/skip-nav.css +54 -0
- package/components/skip-nav/skip-nav.d.ts +27 -0
- package/components/skip-nav/skip-nav.js +12 -0
- package/components/skip-nav/skip-nav.yaml +68 -0
- package/components/slider/slider.a2ui.json +22 -1
- package/components/slider/slider.class.js +264 -122
- package/components/slider/slider.css +82 -2
- package/components/slider/slider.d.ts +19 -3
- package/components/slider/slider.test.js +55 -0
- package/components/slider/slider.yaml +38 -6
- package/components/stat/stat.css +18 -14
- package/components/stepper/stepper-item.a2ui.json +3 -0
- package/components/stepper/stepper-item.yaml +5 -0
- package/components/table/table.class.js +29 -6
- package/components/table/table.css +31 -4
- package/components/table-toolbar/table-toolbar.class.js +3 -1
- package/components/tag/tag.a2ui.json +3 -2
- package/components/tag/tag.css +35 -11
- package/components/tag/tag.d.ts +14 -0
- package/components/tag/tag.test.js +35 -11
- package/components/tag/tag.yaml +13 -7
- package/components/timeline/timeline-item.a2ui.json +8 -1
- package/components/timeline/timeline-item.yaml +12 -0
- package/components/toast/toast.class.js +12 -4
- package/components/toc/toc.a2ui.json +159 -0
- package/components/toc/toc.class.js +222 -0
- package/components/toc/toc.css +92 -0
- package/components/toc/toc.d.ts +61 -0
- package/components/toc/toc.js +17 -0
- package/components/toc/toc.yaml +180 -0
- package/components/toolbar/toolbar.class.js +3 -0
- package/components/tree/tree-item.a2ui.json +5 -1
- package/components/tree/tree-item.yaml +7 -0
- package/components/tree/tree.a2ui.json +3 -0
- package/components/tree/tree.yaml +5 -0
- package/components/visually-hidden/visually-hidden.a2ui.json +71 -0
- package/components/visually-hidden/visually-hidden.class.js +14 -0
- package/components/visually-hidden/visually-hidden.css +25 -0
- package/components/visually-hidden/visually-hidden.d.ts +26 -0
- package/components/visually-hidden/visually-hidden.js +12 -0
- package/components/visually-hidden/visually-hidden.yaml +54 -0
- package/core/anchor.js +19 -3
- package/dist/web-components.min.css +1 -1
- package/dist/web-components.min.js +100 -89
- package/package.json +1 -1
- package/styles/colors/semantics.css +11 -2
- package/styles/components.css +11 -0
- package/styles/resets.css +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,58 @@
|
|
|
1
1
|
# Changelog — @adia-ai/web-components
|
|
2
2
|
|
|
3
|
+
## [0.6.38] — 2026-05-26
|
|
4
|
+
|
|
5
|
+
### Added — Wave 5e cohort: 3 new primitives + slot-vocab-vs-css backlog closed
|
|
6
|
+
|
|
7
|
+
- **`<mark-ui>`** — inline highlighted text primitive (#357)
|
|
8
|
+
- **`<inline-edit-ui>`** — click-to-edit text in place (#212)
|
|
9
|
+
- **Notification deep-link demo + Mark All Read verify** for `<feed-ui>` (#344/#343)
|
|
10
|
+
|
|
11
|
+
### Fixed — substrate polish across the v0.6.38 window
|
|
12
|
+
|
|
13
|
+
- **`<list-item-ui>`**: slot selectors changed from direct-child to descendant — description row now lands on row 2 as intended
|
|
14
|
+
- **`<segmented-ui>`**: stale indicator stripping — duplicate pills on re-render eliminated
|
|
15
|
+
- **`<stat-ui>`**: chart slot bottom-aligns to value baseline; aspect 4:3
|
|
16
|
+
- **`<toolbar-ui>`** mixed-controls demo: `<segment-ui>` (not `<button-ui>`) inside `<segmented-ui>`
|
|
17
|
+
|
|
18
|
+
### Maintenance — slot-vocab-vs-css audit reached 0 critical findings
|
|
19
|
+
|
|
20
|
+
- `audit-slot-vocab-vs-css` substrate backlog closed → gate now enforced. Multi-yaml + @scope-aware pairing landed in the audit script.
|
|
21
|
+
- 5 Wave 5a/b/c/d gap-analysis flips landed (substrate-verified as covered; no new code).
|
|
22
|
+
|
|
23
|
+
## [0.6.37] — 2026-05-25
|
|
24
|
+
|
|
25
|
+
### Changed — `--a-warning-bg` redirected from `-strong` to `-20-tint` (bright caution-tape amber, scheme-independent)
|
|
26
|
+
|
|
27
|
+
- **Token-system fix for the muddy warning surface class.** Previously `--a-warning-bg` was an alias for `--a-warning-strong` (= `-50`, mid-tone amber). Paired with `--a-warning-fg` (= `-text-strong` = `-10-shade`, dark brown — per `semantics.css:309` "warning is light-colored — text on warning fills should be dark"), the pair collapsed to brown-on-brown chips. The local fix shipped in `<tag-ui>` / `<badge-ui>` (literal `--a-warning-20-tint` override) is now hoisted to the L3 token layer so every consumer benefits: progress-row, rating, password-strength, agent-artifact, text[color=warning], timeline. `<button-ui color="warning">` updated to read `--a-warning-bg` (was `-strong`) so it joins the fix. Local tag/badge `-20-tint` overrides removed — they now read the canonical `-bg` token cleanly.
|
|
28
|
+
- **`-strong` unchanged** — still the L2 saturated mid-tone, used as a foreground/icon color by alert / chart / code / empty-state / agent-trace (those use it AS a color, not as a surface to put text on, so the `light-dark` swap stays appropriate).
|
|
29
|
+
- **Why `-20-tint` is bright in both schemes**: the lightness math `l-max - 0.2*(l-max - l-min)` is scheme-independent (no `light-dark()` swap), so warning surfaces keep the caution-tape look in dark mode too. Other family `-bg` tokens stay scheme-flipping because they pair with `-fg` (= `-05-tint` near-white) which has enough contrast either way.
|
|
30
|
+
- Files: `styles/colors/semantics.css`, `components/button/button.css`, `components/tag/tag.{css,test.js}`, `components/badge/badge.css`.
|
|
31
|
+
|
|
32
|
+
### Added — `<tag-ui>` + `<badge-ui>` gain `[tone="outline"]` third chip style
|
|
33
|
+
|
|
34
|
+
- **Outline tone**: transparent bg + family-colored 1px border + family-colored text. The lightest visual weight; good in dense data tables or faceted filter rows where multiple chips would otherwise compete. Family variants resolve to `--a-{family}-text` + `--a-{family}-border`; neutral default resolves to `--a-fg-muted` + `--a-border`.
|
|
35
|
+
- **Vocabulary mirror across the two primitives**: tag-ui defaults to `solid` tone (filter chip / status pill identity); badge-ui defaults to `muted` (quiet metadata identity). Both accept all three values (`solid` | `muted` | `outline`) so authors can swap shape without learning a new prop. Badge-ui's existing `primary` variant remains as a shortcut for `<badge-ui variant="accent" tone="solid">`.
|
|
36
|
+
- New regression guards: 6 source-grep tests on tag-ui for outline-tone rules.
|
|
37
|
+
- Files: `components/tag/tag.{css,yaml,test.js,examples.html}`, `components/badge/badge.{css,yaml,examples.html}`, regenerated `.a2ui.json` sidecars.
|
|
38
|
+
|
|
3
39
|
## [0.6.36] — 2026-05-24
|
|
4
40
|
|
|
41
|
+
### Changed — `<pagination-ui>` composes `<button-ui>` for every cell + adds universal `[size]` thread-through
|
|
42
|
+
|
|
43
|
+
- **Native-primitive leak closed.** `pagination.class.js:128` previously stamped raw `<button>` for every page / prev / next cell — the exact failure mode `dogfood-sweep` mode 4 audits for, and the same shape that produced the FB-55 silent-failure trap on `<admin-shell>`. Substrate authors reading pagination as the canonical numbered-button pattern would carry the leak into downstream components. Substrate now stamps `<button-ui>` for every cell so chrome / hover / focus-ring / disabled-state / active-fill come from button-ui's token chain (the canonical surface matrix), not a pagination-tier re-impl.
|
|
44
|
+
- **`[size]` prop added** — reflected enum (`sm` | `md` | `lg`, default `md` — aligned with `<button-ui>`'s default since pagination is now a button-ui composite). Threads through to every nested `<button-ui size=…>` so pagination honors the substrate's 24/30/36 px universal size system (with `[density]` modifier). Previously pagination hardcoded `--a-size-sm` (24 px), so consumers on md/lg surfaces had no escape hatch.
|
|
45
|
+
- **Active state now `variant="primary"`** instead of a pagination-tier `[data-active]` + custom-bg-token chain. The filled-accent state inherits from button-ui's primary surface matrix — one token chain, one source of truth.
|
|
46
|
+
- **Prev / Next now use Phosphor `caret-left` / `caret-right`** via `<button-ui icon=…>` (was: `‹` / `›` Unicode glyphs). Declared in `static requiredIcons` so the audit picks them up.
|
|
47
|
+
- **`variant="button"` mode** swaps each non-active cell to `variant="outline"` (the bordered 1×1 mode). `pagination.css` shrunk from 165 → 71 lines — the 94 lines of button styling rules collapsed into button-ui composition.
|
|
48
|
+
- **Constant-width compact-mode layout** — `#buildRange` redesigned around an invariant `W = 2*siblings + 5` (= 7 cells at siblings=1; 9 at siblings=2). Three layouts (near-start / middle / near-end) each yield exactly W cells so the row width stays stable when the current page advances. When `total ≤ W`, every page renders (no ellipsis — compressing wouldn't save horizontal slots). Replaces the "bridge if only 1 is skipped" heuristic from an earlier draft, which produced asymmetric cell counts under page advances (page 3 → 6 cells, page 4 → 7 cells — visibly jumpy).
|
|
49
|
+
- **17 new DOM + source-grep regression tests** (`pagination.test.js`, NEW). Guards: no raw `<button>` in source; `requiredIcons` declared; size threads to every nested button-ui; active page is `variant="primary"`; rest variant tracks the host's `variant=` (ghost/outline); **width invariance under all page positions for total=10 siblings=1 (always 7 cells) and total=20 siblings=2 (always 9 cells)**.
|
|
50
|
+
- Files: `components/pagination/pagination.{class.js,yaml,css,test.js}`, regenerated sidecar + corpus.
|
|
51
|
+
|
|
5
52
|
### Fixed — `<tag-ui>` dismiss X + slotted icons now inherit the variant text color
|
|
6
53
|
|
|
7
54
|
- **Visible after the solid-default flip**: the dismiss X (`[slot="dismiss"]`) was hardcoded to `--a-fg-muted` (a neutral grey) regardless of the host's variant, so the X disappeared against saturated solid pills — a near-invisible grey X on the Info/Success/Warning/Error bgs. Same trap on any slotted leading icon: tag had no `currentColor` inheritance rule, so `<icon-ui>` children rendered in their own foreground color rather than the variant's.
|
|
8
|
-
- **Fix**: dismiss `color` token now defaults to `currentColor` at `opacity: 0.
|
|
55
|
+
- **Fix**: dismiss `color` token now defaults to `currentColor` at `opacity: 0.85` (quieter than the label, but tracks every variant — near-white X on saturated bg, dark X on warning amber, fg-muted X on quiet chrome). Hover restores `opacity: 1` and overlays a `color-mix(in oklch, currentColor 18%, transparent)` bg highlight — same color family as the host, not a stark neutral wash. The dismiss `<icon-ui>` now stamps with `weight="bold"` so the X reads crisply at small size on every variant (was implicit regular — too thin against bright bgs like warning amber). NEW `:scope > icon-ui { color: currentColor; flex-shrink: 0 }` rule mirrors `<badge-ui>`'s convention so leading-icon legends/status chips read as a single color-coded unit.
|
|
9
56
|
- Two new component tokens for the dismiss opacity (`--tag-dismiss-opacity`, `--tag-dismiss-opacity-hover`) replace the prior color-swap tokens (`--tag-dismiss-fg-hover` removed — opacity-driven hover instead). Files: `components/tag/tag.css`.
|
|
10
57
|
|
|
11
58
|
### Fixed — `<tag-ui variant="warning">` solid pill: bright amber bg instead of muddy mid-brown
|
|
@@ -63,6 +63,9 @@
|
|
|
63
63
|
"action": {
|
|
64
64
|
"description": "§206 (v0.5.7): action buttons inside a custom header (e.g. Copy /\nDownload / settings). Children placed at `[slot=\"action\"]` (or\n`[slot=\"actions\"]`, or marked `[data-no-toggle]`) are excluded from\nthe toggle-on-click cascade — clicking them fires their own handler\nwithout also toggling the section."
|
|
65
65
|
},
|
|
66
|
+
"body": {
|
|
67
|
+
"description": "The section's collapsible content. Renders below the header; hidden when `[open]` is unset. Author-fills with prose, lists, embedded forms, or any rich markup the panel needs."
|
|
68
|
+
},
|
|
66
69
|
"header": {
|
|
67
70
|
"description": "Custom header content. By default `[text]` renders as a plain header\nlabel, but a `[slot=\"header\"]` override lets consumers author rich\nheaders (icon + title + action buttons + caret)."
|
|
68
71
|
}
|
|
@@ -39,6 +39,11 @@ slots:
|
|
|
39
39
|
`[slot="actions"]`, or marked `[data-no-toggle]`) are excluded from
|
|
40
40
|
the toggle-on-click cascade — clicking them fires their own handler
|
|
41
41
|
without also toggling the section.
|
|
42
|
+
body:
|
|
43
|
+
description: >-
|
|
44
|
+
The section's collapsible content. Renders below the header; hidden
|
|
45
|
+
when `[open]` is unset. Author-fills with prose, lists, embedded
|
|
46
|
+
forms, or any rich markup the panel needs.
|
|
42
47
|
events:
|
|
43
48
|
toggle:
|
|
44
49
|
description: Fired when the section opens or closes.
|
|
@@ -62,7 +62,11 @@
|
|
|
62
62
|
"MenuItem",
|
|
63
63
|
"Button"
|
|
64
64
|
],
|
|
65
|
-
"slots": {
|
|
65
|
+
"slots": {
|
|
66
|
+
"icon": {
|
|
67
|
+
"description": "Override the [icon] glyph with a custom slotted element (custom icon-ui, image, avatar). Mutually exclusive with the [icon] attribute — slot child wins."
|
|
68
|
+
}
|
|
69
|
+
},
|
|
66
70
|
"states": [],
|
|
67
71
|
"status": "stable",
|
|
68
72
|
"synonyms": {
|
|
@@ -37,6 +37,13 @@ props:
|
|
|
37
37
|
type: boolean
|
|
38
38
|
default: false
|
|
39
39
|
|
|
40
|
+
slots:
|
|
41
|
+
icon:
|
|
42
|
+
description: >-
|
|
43
|
+
Override the [icon] glyph with a custom slotted element (custom
|
|
44
|
+
icon-ui, image, avatar). Mutually exclusive with the [icon]
|
|
45
|
+
attribute — slot child wins.
|
|
46
|
+
|
|
40
47
|
keywords:
|
|
41
48
|
- action-item
|
|
42
49
|
- command-row
|
|
@@ -54,6 +54,16 @@
|
|
|
54
54
|
"description": "Badge display text. Renderer routes this to the `text` attribute via CSS attr(text) on ::after.",
|
|
55
55
|
"$ref": "common_types.json#/$defs/DynamicString"
|
|
56
56
|
},
|
|
57
|
+
"tone": {
|
|
58
|
+
"description": "Fill style — orthogonal to [variant]. Badge defaults to `muted`\n(quiet metadata is the primitive's identity — counts, IDs, status\npills in dense rows). Three values:\n - `muted` (default) — tinted bg + scheme-paired text. Same as\n the existing family-variant rules.\n - `solid` — saturated bg + on-strong text. Use for hero badges\n where the badge IS the state (e.g. a single inline error). The\n existing `primary` variant is a shortcut for accent + solid.\n - `outline` — transparent bg + family-colored border + family-\n colored text. Lightest visual weight; good in dense data rows.\nVocabulary mirrors `<tag-ui>` (which defaults to solid, given its\ndifferent role as filter / autocomplete chip).\n",
|
|
59
|
+
"type": "string",
|
|
60
|
+
"enum": [
|
|
61
|
+
"muted",
|
|
62
|
+
"solid",
|
|
63
|
+
"outline"
|
|
64
|
+
],
|
|
65
|
+
"default": "muted"
|
|
66
|
+
},
|
|
57
67
|
"variant": {
|
|
58
68
|
"description": "Semantic color variant.",
|
|
59
69
|
"type": "string",
|
|
@@ -100,5 +100,75 @@
|
|
|
100
100
|
--badge-fg-default: var(--a-fg);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
/* ── Tone modifier — orthogonal to [variant] ──
|
|
104
|
+
Badge's default tone is `muted` (the rules above) — quiet metadata is
|
|
105
|
+
the primitive's identity. `[tone="solid"]` opts into the saturated-fill
|
|
106
|
+
pair (same shape <tag-ui>'s solid default uses); `[tone="outline"]`
|
|
107
|
+
into the transparent-fill + colored-ring shape. Same vocabulary as
|
|
108
|
+
<tag-ui>; different defaults reflecting each primitive's role.
|
|
109
|
+
|
|
110
|
+
Warning uses --a-warning-20-tint as bg (a bright amber, scheme-
|
|
111
|
+
independent) instead of --a-warning-bg — the latter pair collapses
|
|
112
|
+
to muddy brown-on-brown (-text-strong is dark, -bg is mid-tone).
|
|
113
|
+
See <tag-ui>'s identical workaround. Token-system follow-up planned. */
|
|
114
|
+
:scope[tone="solid"][variant="info"] {
|
|
115
|
+
--badge-bg-default: var(--a-info-bg);
|
|
116
|
+
--badge-fg-default: var(--a-info-fg);
|
|
117
|
+
}
|
|
118
|
+
:scope[tone="solid"][variant="success"] {
|
|
119
|
+
--badge-bg-default: var(--a-success-bg);
|
|
120
|
+
--badge-fg-default: var(--a-success-fg);
|
|
121
|
+
}
|
|
122
|
+
:scope[tone="solid"][variant="warning"] {
|
|
123
|
+
/* --a-warning-bg is the bright-amber step (semantics.css L3 redirect
|
|
124
|
+
to -20-tint) — see also <tag-ui>'s warning solid pair. */
|
|
125
|
+
--badge-bg-default: var(--a-warning-bg);
|
|
126
|
+
--badge-fg-default: var(--a-warning-fg);
|
|
127
|
+
}
|
|
128
|
+
:scope[tone="solid"][variant="danger"] {
|
|
129
|
+
--badge-bg-default: var(--a-danger-bg);
|
|
130
|
+
--badge-fg-default: var(--a-danger-fg);
|
|
131
|
+
}
|
|
132
|
+
:scope[tone="solid"][variant="accent"] {
|
|
133
|
+
--badge-bg-default: var(--a-accent-bg);
|
|
134
|
+
--badge-fg-default: var(--a-accent-fg);
|
|
135
|
+
}
|
|
136
|
+
/* Solid on neutral default → high-contrast inverse stamp. */
|
|
137
|
+
:scope[tone="solid"]:not([variant="info"]):not([variant="success"]):not([variant="warning"]):not([variant="danger"]):not([variant="accent"]):not([variant="primary"]) {
|
|
138
|
+
--badge-bg-default: var(--a-fg);
|
|
139
|
+
--badge-fg-default: var(--a-bg);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* ── `[tone="outline"]` — transparent bg + family-colored border + text ── */
|
|
143
|
+
:scope[tone="outline"] {
|
|
144
|
+
--badge-bg-default: transparent;
|
|
145
|
+
border: 1px solid var(--badge-border, var(--badge-border-default, transparent));
|
|
146
|
+
}
|
|
147
|
+
:scope[tone="outline"][variant="info"] {
|
|
148
|
+
--badge-fg-default: var(--a-info-text);
|
|
149
|
+
--badge-border-default: var(--a-info-border);
|
|
150
|
+
}
|
|
151
|
+
:scope[tone="outline"][variant="success"] {
|
|
152
|
+
--badge-fg-default: var(--a-success-text);
|
|
153
|
+
--badge-border-default: var(--a-success-border);
|
|
154
|
+
}
|
|
155
|
+
:scope[tone="outline"][variant="warning"] {
|
|
156
|
+
--badge-fg-default: var(--a-warning-text);
|
|
157
|
+
--badge-border-default: var(--a-warning-border);
|
|
158
|
+
}
|
|
159
|
+
:scope[tone="outline"][variant="danger"] {
|
|
160
|
+
--badge-fg-default: var(--a-danger-text);
|
|
161
|
+
--badge-border-default: var(--a-danger-border);
|
|
162
|
+
}
|
|
163
|
+
:scope[tone="outline"][variant="accent"] {
|
|
164
|
+
--badge-fg-default: var(--a-accent-text);
|
|
165
|
+
--badge-border-default: var(--a-accent-border);
|
|
166
|
+
}
|
|
167
|
+
/* Outline on neutral — fg-muted text + subtle ring. */
|
|
168
|
+
:scope[tone="outline"]:not([variant="info"]):not([variant="success"]):not([variant="warning"]):not([variant="danger"]):not([variant="accent"]):not([variant="primary"]) {
|
|
169
|
+
--badge-fg-default: var(--a-fg-muted);
|
|
170
|
+
--badge-border-default: var(--a-border);
|
|
171
|
+
}
|
|
172
|
+
|
|
103
173
|
/* Size handled by universal [size] attribute system. */
|
|
104
174
|
}
|
|
@@ -70,6 +70,26 @@ props:
|
|
|
70
70
|
- primary
|
|
71
71
|
- muted
|
|
72
72
|
- neutral
|
|
73
|
+
tone:
|
|
74
|
+
description: |
|
|
75
|
+
Fill style — orthogonal to [variant]. Badge defaults to `muted`
|
|
76
|
+
(quiet metadata is the primitive's identity — counts, IDs, status
|
|
77
|
+
pills in dense rows). Three values:
|
|
78
|
+
- `muted` (default) — tinted bg + scheme-paired text. Same as
|
|
79
|
+
the existing family-variant rules.
|
|
80
|
+
- `solid` — saturated bg + on-strong text. Use for hero badges
|
|
81
|
+
where the badge IS the state (e.g. a single inline error). The
|
|
82
|
+
existing `primary` variant is a shortcut for accent + solid.
|
|
83
|
+
- `outline` — transparent bg + family-colored border + family-
|
|
84
|
+
colored text. Lightest visual weight; good in dense data rows.
|
|
85
|
+
Vocabulary mirrors `<tag-ui>` (which defaults to solid, given its
|
|
86
|
+
different role as filter / autocomplete chip).
|
|
87
|
+
type: string
|
|
88
|
+
default: muted
|
|
89
|
+
enum:
|
|
90
|
+
- muted
|
|
91
|
+
- solid
|
|
92
|
+
- outline
|
|
73
93
|
events: {}
|
|
74
94
|
slots: {}
|
|
75
95
|
states:
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://adiaui.dev/a2ui/v0_9/components/Blockquote.json",
|
|
4
|
+
"title": "Blockquote",
|
|
5
|
+
"description": "Styled quotation block with a left visual indicator (border rule) +\nitalic body text + optional `cite` attribution line. Use for pull-quotes,\ntestimonials, or inline citations within prose. The default visual\nfollows the prose typography family — pair with `<text-ui>` body\nvariants inside, or pass raw text in the default slot. The optional\n[cite] attribute (or [slot=cite]) renders a small attribution line\nbelow the quote prefixed with an em-dash. Semantic blockquote element\nwith `role=\"blockquote\"` implied via tag name (do NOT wrap in a native\n`<blockquote>` — that produces nested-blockquote semantics).\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
|
+
"cite": {
|
|
17
|
+
"description": "Source attribution shown beneath the quote (small, muted, em-dash\nprefix). For richer attribution (links, multi-line), use the\n`[slot=\"cite\"]` content slot instead — when both are set, the slot\ncontent wins. Plain-string convenience prop for the common case.\n",
|
|
18
|
+
"type": "string",
|
|
19
|
+
"default": ""
|
|
20
|
+
},
|
|
21
|
+
"component": {
|
|
22
|
+
"const": "Blockquote"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"required": [
|
|
26
|
+
"component"
|
|
27
|
+
],
|
|
28
|
+
"unevaluatedProperties": false,
|
|
29
|
+
"x-adiaui": {
|
|
30
|
+
"anti_patterns": [],
|
|
31
|
+
"category": "display",
|
|
32
|
+
"composes": [],
|
|
33
|
+
"events": {},
|
|
34
|
+
"examples": [
|
|
35
|
+
{
|
|
36
|
+
"description": "Pull-quote with em-dash attribution.",
|
|
37
|
+
"a2ui": "[\n {\n \"id\": \"q\",\n \"component\": \"Blockquote\",\n \"cite\": \"Steve Jobs, Stanford Commencement, 2005\",\n \"content\": \"Stay hungry. Stay foolish.\"\n }\n]\n",
|
|
38
|
+
"name": "default"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"description": "Blockquote with a linked citation via slot.",
|
|
42
|
+
"a2ui": "[\n {\n \"id\": \"q\",\n \"component\": \"Blockquote\",\n \"children\": [\"body\", \"src\"]\n },\n {\n \"id\": \"body\",\n \"component\": \"Text\",\n \"textContent\": \"The best way to predict the future is to invent it.\"\n },\n {\n \"id\": \"src\",\n \"component\": \"Link\",\n \"slot\": \"cite\",\n \"href\": \"https://en.wikipedia.org/wiki/Alan_Kay\",\n \"text\": \"Alan Kay (1971)\"\n }\n]\n",
|
|
43
|
+
"name": "rich-attribution"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"keywords": [
|
|
47
|
+
"blockquote",
|
|
48
|
+
"quote",
|
|
49
|
+
"pull-quote",
|
|
50
|
+
"quotation",
|
|
51
|
+
"testimonial",
|
|
52
|
+
"citation",
|
|
53
|
+
"cite"
|
|
54
|
+
],
|
|
55
|
+
"name": "UIBlockquote",
|
|
56
|
+
"related": [
|
|
57
|
+
"text",
|
|
58
|
+
"link",
|
|
59
|
+
"card"
|
|
60
|
+
],
|
|
61
|
+
"slots": {
|
|
62
|
+
"default": {
|
|
63
|
+
"description": "The quote body. Plain text or composed `<text-ui>` / inline elements."
|
|
64
|
+
},
|
|
65
|
+
"cite": {
|
|
66
|
+
"description": "Optional citation override. Use for rich attribution (linked source,\nperson + role pairing) where [cite] string is insufficient.\n"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"states": [
|
|
70
|
+
{
|
|
71
|
+
"description": "Default, ready for reading.",
|
|
72
|
+
"name": "idle"
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"status": "stable",
|
|
76
|
+
"synonyms": {
|
|
77
|
+
"quote": [
|
|
78
|
+
"blockquote",
|
|
79
|
+
"quotation",
|
|
80
|
+
"pull-quote"
|
|
81
|
+
],
|
|
82
|
+
"testimonial": [
|
|
83
|
+
"blockquote",
|
|
84
|
+
"quote"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"tag": "blockquote-ui",
|
|
88
|
+
"tokens": {
|
|
89
|
+
"--blockquote-cite-fg": {
|
|
90
|
+
"description": "Citation text color (muted).",
|
|
91
|
+
"default": "var(--a-fg-muted)"
|
|
92
|
+
},
|
|
93
|
+
"--blockquote-cite-size": {
|
|
94
|
+
"description": "Citation font size.",
|
|
95
|
+
"default": "var(--a-ui-sm)"
|
|
96
|
+
},
|
|
97
|
+
"--blockquote-fg": {
|
|
98
|
+
"description": "Quote text color.",
|
|
99
|
+
"default": "var(--a-fg-subtle)"
|
|
100
|
+
},
|
|
101
|
+
"--blockquote-pad-block": {
|
|
102
|
+
"description": "Vertical padding inside the blockquote.",
|
|
103
|
+
"default": "var(--a-space-2)"
|
|
104
|
+
},
|
|
105
|
+
"--blockquote-pad-inline": {
|
|
106
|
+
"description": "Inline padding between the rule and the quote text.",
|
|
107
|
+
"default": "var(--a-space-3)"
|
|
108
|
+
},
|
|
109
|
+
"--blockquote-rule-color": {
|
|
110
|
+
"description": "Color of the left indicator rule.",
|
|
111
|
+
"default": "var(--a-border-strong)"
|
|
112
|
+
},
|
|
113
|
+
"--blockquote-rule-width": {
|
|
114
|
+
"description": "Width of the left indicator rule.",
|
|
115
|
+
"default": "2px"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"traits": [],
|
|
119
|
+
"version": 1
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-side-effect class export for `<blockquote-ui>`.
|
|
3
|
+
*
|
|
4
|
+
* Importing this file gives you the class without auto-registering the
|
|
5
|
+
* tag. Useful for test isolation, subclassing with tag-name override,
|
|
6
|
+
* or selective composition.
|
|
7
|
+
*
|
|
8
|
+
* The auto-register path stays at `@adia-ai/web-components/components/blockquote`
|
|
9
|
+
* (which imports this file + calls `defineIfFree()`).
|
|
10
|
+
*
|
|
11
|
+
* @see ../../USAGE.md#registration--auto-vs-explicit
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* <blockquote-ui cite="Alan Kay">
|
|
16
|
+
* The best way to predict the future is to invent it.
|
|
17
|
+
* </blockquote-ui>
|
|
18
|
+
*
|
|
19
|
+
* Layout:
|
|
20
|
+
* │ italic quote body ← left rule indicator
|
|
21
|
+
* │ — citation line ← em-dash prefix
|
|
22
|
+
*
|
|
23
|
+
* Two attribution paths:
|
|
24
|
+
* • [cite="..."] attribute → renders a small em-dashed line below
|
|
25
|
+
* • <span slot="cite">...</span> slot → richer attribution (links, etc.)
|
|
26
|
+
* Slot content overrides the attribute when both are present.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { UIElement } from '../../core/element.js';
|
|
30
|
+
|
|
31
|
+
export class UIBlockquote extends UIElement {
|
|
32
|
+
static properties = {
|
|
33
|
+
cite: { type: String, default: '', reflect: true },
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
static template = () => null;
|
|
37
|
+
|
|
38
|
+
connected() {
|
|
39
|
+
// Implicit semantic role — the tag name carries blockquote meaning,
|
|
40
|
+
// but assistive tech doesn't infer from custom-element tag names.
|
|
41
|
+
if (!this.hasAttribute('role')) this.setAttribute('role', 'blockquote');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
render() {
|
|
45
|
+
// Stamp the citation line from [cite] only when no [slot="cite"]
|
|
46
|
+
// content is provided. Slot wins on conflict (per the contract).
|
|
47
|
+
const slotted = this.querySelector('[slot="cite"]:not([data-cite-stamped])');
|
|
48
|
+
const stamped = this.querySelector('[slot="cite"][data-cite-stamped]');
|
|
49
|
+
if (slotted) {
|
|
50
|
+
// Author supplied richer attribution — drop any stamped version.
|
|
51
|
+
stamped?.remove();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (this.cite) {
|
|
55
|
+
if (stamped) {
|
|
56
|
+
stamped.textContent = this.cite;
|
|
57
|
+
} else {
|
|
58
|
+
const el = document.createElement('span');
|
|
59
|
+
el.setAttribute('slot', 'cite');
|
|
60
|
+
el.setAttribute('data-cite-stamped', '');
|
|
61
|
+
el.textContent = this.cite;
|
|
62
|
+
this.appendChild(el);
|
|
63
|
+
}
|
|
64
|
+
} else if (stamped) {
|
|
65
|
+
stamped.remove();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════
|
|
2
|
+
BLOCKQUOTE-UI — Styled quotation block with left rule + cite line.
|
|
3
|
+
═══════════════════════════════════════════════════════════════ */
|
|
4
|
+
|
|
5
|
+
@scope (blockquote-ui) {
|
|
6
|
+
:where(:scope) {
|
|
7
|
+
/* ── Tokens ── */
|
|
8
|
+
--blockquote-rule-color-default: var(--a-border-strong);
|
|
9
|
+
--blockquote-rule-width-default: 2px;
|
|
10
|
+
--blockquote-pad-inline-default: var(--a-space-3);
|
|
11
|
+
--blockquote-pad-block-default: var(--a-space-2);
|
|
12
|
+
--blockquote-fg-default: var(--a-fg-subtle);
|
|
13
|
+
--blockquote-cite-fg-default: var(--a-fg-muted);
|
|
14
|
+
--blockquote-cite-size-default: var(--a-ui-sm);
|
|
15
|
+
--blockquote-cite-mt-default: var(--a-space-2);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
:scope {
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
display: block;
|
|
21
|
+
padding-inline-start: var(--blockquote-pad-inline, var(--blockquote-pad-inline-default));
|
|
22
|
+
padding-block: var(--blockquote-pad-block, var(--blockquote-pad-block-default));
|
|
23
|
+
border-inline-start: var(--blockquote-rule-width, var(--blockquote-rule-width-default))
|
|
24
|
+
solid
|
|
25
|
+
var(--blockquote-rule-color, var(--blockquote-rule-color-default));
|
|
26
|
+
color: var(--blockquote-fg, var(--blockquote-fg-default));
|
|
27
|
+
font-style: italic;
|
|
28
|
+
/* Reset native margin if a consumer wraps in a native <blockquote>
|
|
29
|
+
(not recommended — see yaml a2ui rule #3) so nesting renders
|
|
30
|
+
reasonably. */
|
|
31
|
+
margin: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Cite line — em-dash prefix + small + muted + non-italic */
|
|
35
|
+
[slot="cite"] {
|
|
36
|
+
display: block;
|
|
37
|
+
margin-top: var(--blockquote-cite-mt, var(--blockquote-cite-mt-default));
|
|
38
|
+
font-style: normal;
|
|
39
|
+
font-size: var(--blockquote-cite-size, var(--blockquote-cite-size-default));
|
|
40
|
+
color: var(--blockquote-cite-fg, var(--blockquote-cite-fg-default));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
[slot="cite"]::before {
|
|
44
|
+
content: "— ";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<blockquote-ui>` — Styled quotation block with a left visual indicator (border rule) +
|
|
3
|
+
italic body text + optional `cite` attribution line. Use for pull-quotes,
|
|
4
|
+
testimonials, or inline citations within prose. The default visual
|
|
5
|
+
follows the prose typography family — pair with `<text-ui>` body
|
|
6
|
+
variants inside, or pass raw text in the default slot. The optional
|
|
7
|
+
[cite] attribute (or [slot=cite]) renders a small attribution line
|
|
8
|
+
below the quote prefixed with an em-dash. Semantic blockquote element
|
|
9
|
+
with `role="blockquote"` implied via tag name (do NOT wrap in a native
|
|
10
|
+
`<blockquote>` — that produces nested-blockquote semantics).
|
|
11
|
+
|
|
12
|
+
*
|
|
13
|
+
* @see https://ui-kit.exe.xyz/site/components/blockquote
|
|
14
|
+
*
|
|
15
|
+
* Type declarations generated by scripts/build/dts-codegen.mjs from
|
|
16
|
+
* the component's `.a2ui.json` sidecar(s). Edit the source `.yaml`,
|
|
17
|
+
* run `npm run build:components`, then `npm run codegen:dts` to
|
|
18
|
+
* regenerate; or hand-author this file fully if rich event types are
|
|
19
|
+
* needed beyond what the yaml `events:` block can express.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { UIElement } from '../../core/element.js';
|
|
23
|
+
|
|
24
|
+
export class UIBlockquote extends UIElement {
|
|
25
|
+
/** Source attribution shown beneath the quote (small, muted, em-dash
|
|
26
|
+
prefix). For richer attribution (links, multi-line), use the
|
|
27
|
+
`[slot="cite"]` content slot instead — when both are set, the slot
|
|
28
|
+
content wins. Plain-string convenience prop for the common case.
|
|
29
|
+
*/
|
|
30
|
+
cite: string;
|
|
31
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<blockquote-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 { UIBlockquote } from '@adia-ai/web-components/components/blockquote/class';
|
|
8
|
+
*
|
|
9
|
+
* @see ../../USAGE.md#registration--auto-vs-explicit
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { defineIfFree } from '../../core/register.js';
|
|
13
|
+
import { UIBlockquote } from './blockquote.class.js';
|
|
14
|
+
|
|
15
|
+
defineIfFree('blockquote-ui', UIBlockquote);
|
|
16
|
+
|
|
17
|
+
export { UIBlockquote };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
2
|
+
name: UIBlockquote
|
|
3
|
+
tag: blockquote-ui
|
|
4
|
+
status: stable
|
|
5
|
+
component: Blockquote
|
|
6
|
+
category: display
|
|
7
|
+
version: 1
|
|
8
|
+
description: |
|
|
9
|
+
Styled quotation block with a left visual indicator (border rule) +
|
|
10
|
+
italic body text + optional `cite` attribution line. Use for pull-quotes,
|
|
11
|
+
testimonials, or inline citations within prose. The default visual
|
|
12
|
+
follows the prose typography family — pair with `<text-ui>` body
|
|
13
|
+
variants inside, or pass raw text in the default slot. The optional
|
|
14
|
+
[cite] attribute (or [slot=cite]) renders a small attribution line
|
|
15
|
+
below the quote prefixed with an em-dash. Semantic blockquote element
|
|
16
|
+
with `role="blockquote"` implied via tag name (do NOT wrap in a native
|
|
17
|
+
`<blockquote>` — that produces nested-blockquote semantics).
|
|
18
|
+
props:
|
|
19
|
+
cite:
|
|
20
|
+
description: |
|
|
21
|
+
Source attribution shown beneath the quote (small, muted, em-dash
|
|
22
|
+
prefix). For richer attribution (links, multi-line), use the
|
|
23
|
+
`[slot="cite"]` content slot instead — when both are set, the slot
|
|
24
|
+
content wins. Plain-string convenience prop for the common case.
|
|
25
|
+
type: string
|
|
26
|
+
default: ""
|
|
27
|
+
reflect: true
|
|
28
|
+
events: {}
|
|
29
|
+
slots:
|
|
30
|
+
default:
|
|
31
|
+
description: The quote body. Plain text or composed `<text-ui>` / inline elements.
|
|
32
|
+
cite:
|
|
33
|
+
description: |
|
|
34
|
+
Optional citation override. Use for rich attribution (linked source,
|
|
35
|
+
person + role pairing) where [cite] string is insufficient.
|
|
36
|
+
states:
|
|
37
|
+
- name: idle
|
|
38
|
+
description: Default, ready for reading.
|
|
39
|
+
traits: []
|
|
40
|
+
tokens:
|
|
41
|
+
--blockquote-rule-color:
|
|
42
|
+
description: Color of the left indicator rule.
|
|
43
|
+
default: var(--a-border-strong)
|
|
44
|
+
--blockquote-rule-width:
|
|
45
|
+
description: Width of the left indicator rule.
|
|
46
|
+
default: 2px
|
|
47
|
+
--blockquote-pad-inline:
|
|
48
|
+
description: Inline padding between the rule and the quote text.
|
|
49
|
+
default: var(--a-space-3)
|
|
50
|
+
--blockquote-pad-block:
|
|
51
|
+
description: Vertical padding inside the blockquote.
|
|
52
|
+
default: var(--a-space-2)
|
|
53
|
+
--blockquote-fg:
|
|
54
|
+
description: Quote text color.
|
|
55
|
+
default: var(--a-fg-subtle)
|
|
56
|
+
--blockquote-cite-fg:
|
|
57
|
+
description: Citation text color (muted).
|
|
58
|
+
default: var(--a-fg-muted)
|
|
59
|
+
--blockquote-cite-size:
|
|
60
|
+
description: Citation font size.
|
|
61
|
+
default: var(--a-ui-sm)
|
|
62
|
+
a2ui:
|
|
63
|
+
rules:
|
|
64
|
+
- rule: "Use for pull-quotes, testimonials, or inline citations. Renders italic body text with a left rule indicator + optional em-dash attribution line."
|
|
65
|
+
reason: "Quote-display primitive with semantic chrome."
|
|
66
|
+
- rule: "Set [cite] for plain-string attribution; use [slot=\"cite\"] for rich attribution (linked source, role pairing). Slot content overrides the [cite] prop when both are set."
|
|
67
|
+
reason: "Two attribution paths — string for the common case, slot for richness."
|
|
68
|
+
- rule: "Do NOT wrap blockquote-ui in a native <blockquote> element — that produces nested-blockquote semantics. The tag IS the blockquote."
|
|
69
|
+
reason: "Avoid double-wrapping."
|
|
70
|
+
anti_patterns: []
|
|
71
|
+
examples:
|
|
72
|
+
- name: default
|
|
73
|
+
description: Pull-quote with em-dash attribution.
|
|
74
|
+
a2ui: |
|
|
75
|
+
[
|
|
76
|
+
{
|
|
77
|
+
"id": "q",
|
|
78
|
+
"component": "Blockquote",
|
|
79
|
+
"cite": "Steve Jobs, Stanford Commencement, 2005",
|
|
80
|
+
"content": "Stay hungry. Stay foolish."
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
- name: rich-attribution
|
|
84
|
+
description: Blockquote with a linked citation via slot.
|
|
85
|
+
a2ui: |
|
|
86
|
+
[
|
|
87
|
+
{
|
|
88
|
+
"id": "q",
|
|
89
|
+
"component": "Blockquote",
|
|
90
|
+
"children": ["body", "src"]
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "body",
|
|
94
|
+
"component": "Text",
|
|
95
|
+
"textContent": "The best way to predict the future is to invent it."
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"id": "src",
|
|
99
|
+
"component": "Link",
|
|
100
|
+
"slot": "cite",
|
|
101
|
+
"href": "https://en.wikipedia.org/wiki/Alan_Kay",
|
|
102
|
+
"text": "Alan Kay (1971)"
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
keywords:
|
|
106
|
+
- blockquote
|
|
107
|
+
- quote
|
|
108
|
+
- pull-quote
|
|
109
|
+
- quotation
|
|
110
|
+
- testimonial
|
|
111
|
+
- citation
|
|
112
|
+
- cite
|
|
113
|
+
synonyms:
|
|
114
|
+
quote:
|
|
115
|
+
- blockquote
|
|
116
|
+
- quotation
|
|
117
|
+
- pull-quote
|
|
118
|
+
testimonial:
|
|
119
|
+
- blockquote
|
|
120
|
+
- quote
|
|
121
|
+
related:
|
|
122
|
+
- text
|
|
123
|
+
- link
|
|
124
|
+
- card
|