@ponchia/ui 0.6.4 → 0.6.5
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 +35 -0
- package/README.md +7 -7
- package/behaviors/index.d.ts +2 -0
- package/behaviors/index.d.ts.map +1 -1
- package/behaviors/index.js +2 -0
- package/behaviors/sources.d.ts +28 -0
- package/behaviors/sources.d.ts.map +1 -0
- package/behaviors/sources.js +158 -0
- package/classes/classes.json +146 -2
- package/classes/index.d.ts +63 -0
- package/classes/index.js +80 -0
- package/css/report.css +356 -3
- package/css/sources.css +18 -0
- package/css/tokens.css +8 -1
- package/dist/bronto.css +1 -1
- package/dist/css/report.css +1 -1
- package/dist/css/sources.css +1 -1
- package/dist/css/tokens.css +1 -1
- package/docs/frontier-primitives.md +262 -0
- package/docs/package-contract.md +263 -0
- package/docs/reference.md +74 -1
- package/docs/reporting.md +282 -13
- package/docs/sources.md +32 -0
- package/docs/stability.md +6 -3
- package/llms.txt +69 -23
- package/package.json +9 -3
- package/qwik/index.d.ts +1 -0
- package/qwik/index.d.ts.map +1 -1
- package/qwik/index.js +5 -0
- package/react/index.d.ts +1 -0
- package/react/index.d.ts.map +1 -1
- package/react/index.js +3 -0
- package/solid/index.d.ts +2 -0
- package/solid/index.d.ts.map +1 -1
- package/solid/index.js +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,41 @@
|
|
|
5
5
|
|> `^0` / `*` wildcard does **not** protect you. See README → Versioning, and
|
|
6
6
|
|> the deprecation policy in CONTRIBUTING.md.
|
|
7
7
|
|
|
8
|
+
## 0.6.5 — 2026-06-09
|
|
9
|
+
|
|
10
|
+
Patch release: the source-backref behavior, the report decision/evidence
|
|
11
|
+
grammar, and package/release hardening. No breaking changes, no
|
|
12
|
+
`MIGRATIONS.json` entry.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`initSources` behavior** — optional citation→source backref focus:
|
|
17
|
+
inside a `data-bronto-sources` host, a `.ui-citation[href^="#"]` (or an
|
|
18
|
+
explicit `data-bronto-source-ref`) click scrolls to its source card and
|
|
19
|
+
marks it `is-source-active`, emitting a cancellable focus event with the
|
|
20
|
+
`SourceFocusDetail` payload. Progressive enhancement over authored ids —
|
|
21
|
+
no DOM is generated; framework bindings re-export it.
|
|
22
|
+
- **Report decision/evidence grammar** — adds public, static report primitives
|
|
23
|
+
for decision blocks, severity-labelled findings, compact evidence packets and
|
|
24
|
+
follow-up action rows.
|
|
25
|
+
- **Claim and action-register grammar** — adds claim status blocks, structured
|
|
26
|
+
finding parts, evidence-method parts, evidence ledgers, decision detail rows,
|
|
27
|
+
and action owner/due/criteria/source parts for more auditable reports.
|
|
28
|
+
- **Package contract doc** — `docs/package-contract.md` pins the published
|
|
29
|
+
surface (exports map, files allowlist, generated-artifact freshness) that
|
|
30
|
+
`check:pack`/`check:publint`/`check:attw` enforce.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- **Report fixtures and local guardrails** — expands the standalone and full
|
|
35
|
+
report demos with source/provenance examples, SVG accessibility details and a
|
|
36
|
+
local-only public-boundary terms gate for `check:report`.
|
|
37
|
+
- **Report shape checks** — `check:report` now parses report demos with a DOM
|
|
38
|
+
instead of regexes and validates the public claim/action contracts.
|
|
39
|
+
- **Release observability** — the release workflow gains a metadata gate and
|
|
40
|
+
theme-axis verification; the examples consumer build broadens its smoke
|
|
41
|
+
coverage.
|
|
42
|
+
|
|
8
43
|
## 0.6.4 — 2026-06-08
|
|
9
44
|
|
|
10
45
|
Patch release for the dot-matrix expansion and static report hardening shipped
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@ponchia/ui)
|
|
4
4
|
[](https://www.npmjs.com/package/@ponchia/ui#provenance)
|
|
5
5
|
[](https://github.com/Ponchia/bronto-ui/blob/main/package.json)
|
|
6
|
-
[](https://github.com/Ponchia/bronto-ui/blob/main/scripts/check-dist.mjs)
|
|
7
7
|
[](https://github.com/Ponchia/bronto-ui/actions/workflows/ci.yml)
|
|
8
8
|
[](https://scorecard.dev/viewer/?uri=github.com/Ponchia/bronto-ui)
|
|
9
9
|
[](https://github.com/Ponchia/bronto-ui/blob/main/LICENSE)
|
|
@@ -57,7 +57,7 @@ Or drop it in with no build step, straight from a CDN:
|
|
|
57
57
|
|
|
58
58
|
## Quick start
|
|
59
59
|
|
|
60
|
-
**1. Load the CSS.** One flattened, minified bundle — the whole standard component set, one request (~
|
|
60
|
+
**1. Load the CSS.** One flattened, minified bundle — the whole standard component set, one request (~87 kB raw / ~15 kB gzip):
|
|
61
61
|
|
|
62
62
|
```css
|
|
63
63
|
@import '@ponchia/ui'; /* via a bundler */
|
|
@@ -102,7 +102,7 @@ initDialog(); // native <dialog> glue: [data-bronto-open] / [data-bronto-
|
|
|
102
102
|
toast('Saved', { tone: 'success' }); // body-anchored stack, no markup needed
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
-
Behaviors cover theme persistence, disclosure, dropdown menus, native-`<dialog>` modals/drawers, tabs, combobox, form validation, table sort, carousel and toasts — wired by `data-bronto-*` attributes.
|
|
105
|
+
Behaviors cover theme persistence, disclosure, dropdown menus, native-`<dialog>` modals/drawers, tabs, combobox, form validation, table sort, carousel, source backrefs and toasts — wired by `data-bronto-*` attributes.
|
|
106
106
|
|
|
107
107
|
**5. (Optional) display glyphs — a 48-glyph dot-matrix icon set:**
|
|
108
108
|
|
|
@@ -126,7 +126,7 @@ Arrows, chevrons, check/close/plus/minus, search/menu/gear, info/warning/bell/lo
|
|
|
126
126
|
- **Shells** — an admin dashboard shell (`ui-app-*`) and a content/marketing site shell (`ui-site*`, `ui-container`).
|
|
127
127
|
- **Prose** — `.ui-prose` styles raw, unclassed semantic HTML (Markdown / CMS / LLM output) with zero classes.
|
|
128
128
|
- **Analytical & communication primitives** _(opt-in)_ — `@ponchia/ui/css/analytical.css`: SVG **annotations** (subject/connector/note), standalone **legends**/data-keys, text/evidence **marks**, leader-line **connectors** (+ a pure `@ponchia/ui/connectors` geometry kernel), a guided-focus **spotlight**, a **crosshair**/readout, and a cross-cutting **selection** vocabulary. Each owns its visual grammar + pure geometry and refuses scales/state/hit-testing — figures that explain themselves, not a chart engine. Plus standalone **`source`/provenance** (trust) and **lifecycle `state`** leaves.
|
|
129
|
-
- **Reports** _(opt-in)_ — `@ponchia/ui/css/report.css`, a static/PDF-first report grammar for LLM-authored HTML: covers, sections, findings, evidence, figures, chart wrappers and print utilities.
|
|
129
|
+
- **Reports** _(opt-in)_ — `@ponchia/ui/css/report.css`, a static/PDF-first report grammar for LLM-authored HTML: covers, decisions, claims, sections, severity-labelled findings, evidence packets, evidence ledgers, action registers, source-card bindings, figures, chart wrappers and print utilities.
|
|
130
130
|
- **Motion & dots** — the dot-matrix motif kit: dot grid, status dots, dot loaders, the orbital spinner, matrix reveal — all reduced-motion aware.
|
|
131
131
|
- **Glyphs** — `@ponchia/ui/glyphs`, a 48-glyph dot-matrix icon set on the `.ui-dotmatrix` primitive (display marks + crisp `solid` inline icons + one-node `.ui-icon` mask rendering).
|
|
132
132
|
- **Colorways** _(opt-in)_ — `data-bronto-skin="amber-crt | phosphor-green | e-ink"`: a root-level recolour of the one accent (OKLCH, per-theme, contrast-gated), never in the default bundle.
|
|
@@ -173,13 +173,13 @@ Per-framework getting-started guides + runnable example apps live in the repo:
|
|
|
173
173
|
|
|
174
174
|
- **Tokens as data** — `import tokens, { themeColor, cssVars } from '@ponchia/ui/tokens'` (plus `tokens.json`, W3C DTCG `tokens.dtcg.json`, and `tokens/resolved.json` — concrete hex per theme for canvas/SVG/MapLibre).
|
|
175
175
|
- **Chart colours for dashboards** — `import charts from '@ponchia/ui/charts.json' with { type: 'json' }` in Node ESM, or the same path through a bundler JSON import (resolved hex per theme; series 1 = your accent) plus the opt-in `@ponchia/ui/css/dataviz.css`.
|
|
176
|
-
- **Static reports for LLMs** — add `@ponchia/ui/css/report.css` for report structure and print utilities; pair with `@ponchia/ui/css/dataviz.css` only when the report contains charts. Full cookbook: `docs/reporting.md`.
|
|
176
|
+
- **Static reports for LLMs** — add `@ponchia/ui/css/report.css` for report structure, claim/evidence/action grammar, source-card bindings, and print utilities; pair with `@ponchia/ui/css/dataviz.css` only when the report contains charts. Full cookbook: `docs/reporting.md`.
|
|
177
177
|
- **Modern-platform motion** — overlays (modal/drawer/popover), toasts and the `<details>` accordion animate **in and out** with zero JS (`@starting-style` + `allow-discrete`, `::details-content` + `interpolate-size`). Progressive-enhancement extras: `.ui-scroll-progress` / `.ui-scroll-reveal` (scroll-driven, no JS) and `.ui-vt` for View Transitions. All degrade to a static end-state and respect `prefers-reduced-motion`. For smooth **cross-document** navigations, add the document-global one-liner to your own top-level (unlayered) CSS: `@view-transition { navigation: auto; }`.
|
|
178
178
|
- **Editor IntelliSense** — point VS Code at the shipped custom-data file so every token autocompletes in `var(--…)`:
|
|
179
179
|
```json
|
|
180
180
|
{ "css.customData": ["node_modules/@ponchia/ui/classes/vscode.css-custom-data.json"] }
|
|
181
181
|
```
|
|
182
|
-
- **For AI coding agents** — the package ships `llms.txt` at its root plus `docs/reference.md`, `docs/usage.md`, `docs/reporting.md`, `docs/theming.md`, `docs/contrast.md`, `docs/stability.md`, the color constitution `docs/adr/0001-color-system.md` and the `CHANGELOG` inside the tarball, so an offline agent has the full API and rationale without guessing.
|
|
182
|
+
- **For AI coding agents** — the package ships `llms.txt` at its root plus `docs/reference.md`, `docs/usage.md`, `docs/reporting.md`, `docs/theming.md`, `docs/contrast.md`, `docs/stability.md`, `docs/package-contract.md`, the color constitution `docs/adr/0001-color-system.md` and the `CHANGELOG` inside the tarball, so an offline agent has the full API and rationale without guessing.
|
|
183
183
|
|
|
184
184
|
> The package root is **CSS-only**. Use `@import '@ponchia/ui'` in CSS, or `import '@ponchia/ui'` only as a CSS side-effect import in a CSS-aware bundler (Vite, Astro, SvelteKit, webpack). Do not import the package root from Node/runtime JS. JS entrypoints are explicit subpaths: `/tokens`, `/classes`, `/behaviors`, `/glyphs`, `/react`, `/solid`, `/qwik`, `/skins`, and `/charts`.
|
|
185
185
|
> JS subpaths are **ESM-only**. CommonJS consumers should use dynamic
|
|
@@ -193,7 +193,7 @@ Recent-evergreen, by design. The framework targets the modern web platform — c
|
|
|
193
193
|
|
|
194
194
|
Pre-1.0 and deliberately so. **Until `1.0.0`, breaking changes ship in the _minor_** (`0.x.0`); patches (`0.x.y`) are always non-breaking. Pin with the patch range — at `0.x`, `~0.6.0` (and equivalently `^0.6.0`) resolves to `>=0.6.0 <0.7.0`, giving you safe patches while holding back the next breaking minor. Every breaking change is called out under a **BREAKING** heading in the **[CHANGELOG](https://github.com/Ponchia/bronto-ui/blob/main/CHANGELOG.md)** with a migration note.
|
|
195
195
|
|
|
196
|
-
Contractual (changes are breaking): token **names** and documented token roles, `.ui-*` class and recipe names, `data-bronto-*` attributes, exported behavior/glyph/binding function names and each behavior's cleanup contract. Not contractual (may change any release): exact token **values** and generated colour math outputs (visual tuning) unless a doc explicitly says the value is stable, plus internal leaf-file / `@layer` boundaries. See **[docs/stability.md](https://github.com/Ponchia/bronto-ui/blob/main/docs/stability.md)** for the
|
|
196
|
+
Contractual (changes are breaking): token **names** and documented token roles, `.ui-*` class and recipe names, `data-bronto-*` attributes, exported behavior/glyph/binding function names and each behavior's cleanup contract. Not contractual (may change any release): exact token **values** and generated colour math outputs (visual tuning) unless a doc explicitly says the value is stable, plus internal leaf-file / `@layer` boundaries. See **[docs/stability.md](https://github.com/Ponchia/bronto-ui/blob/main/docs/stability.md)** for the semantic public-surface matrix and **[docs/package-contract.md](https://github.com/Ponchia/bronto-ui/blob/main/docs/package-contract.md)** for the generated export/file/provenance inventory.
|
|
197
197
|
|
|
198
198
|
Release candidates publish to the `next` dist-tag, never to `latest` — opt in with `npm i @ponchia/ui@next` to try an upcoming version early. A plain `npm i @ponchia/ui` only ever resolves a stable release.
|
|
199
199
|
|
package/behaviors/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export { initConnectors } from "./connectors.js";
|
|
|
17
17
|
export { initSpotlight } from "./spotlight.js";
|
|
18
18
|
export { initCrosshair } from "./crosshair.js";
|
|
19
19
|
export { initCommand } from "./command.js";
|
|
20
|
+
export { initSources } from "./sources.js";
|
|
20
21
|
export type Cleanup = import("./internal.js").Cleanup;
|
|
21
22
|
export type DelegateOpts = import("./internal.js").DelegateOpts;
|
|
22
23
|
export type ThemeStorageOpts = import("./theme.js").ThemeStorageOpts;
|
|
@@ -27,5 +28,6 @@ export type ModalCloseDetail = import("./modal.js").ModalCloseDetail;
|
|
|
27
28
|
export type LegendToggleDetail = import("./legend.js").LegendToggleDetail;
|
|
28
29
|
export type CrosshairMoveDetail = import("./crosshair.js").CrosshairMoveDetail;
|
|
29
30
|
export type CommandSelectDetail = import("./command.js").CommandSelectDetail;
|
|
31
|
+
export type SourceFocusDetail = import("./sources.js").SourceFocusDetail;
|
|
30
32
|
export { applyStoredTheme, initThemeToggle } from "./theme.js";
|
|
31
33
|
//# sourceMappingURL=index.d.ts.map
|
package/behaviors/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;sBAmBa,OAAO,eAAe,EAAE,OAAO;2BAC/B,OAAO,eAAe,EAAE,YAAY;+BACpC,OAAO,YAAY,EAAE,gBAAgB;6BACrC,OAAO,YAAY,EAAE,cAAc;gCACnC,OAAO,YAAY,EAAE,iBAAiB;wBACtC,OAAO,YAAY,EAAE,SAAS;+BAC9B,OAAO,YAAY,EAAE,gBAAgB;iCACrC,OAAO,aAAa,EAAE,kBAAkB;kCACxC,OAAO,gBAAgB,EAAE,mBAAmB;kCAC5C,OAAO,cAAc,EAAE,mBAAmB;gCAC1C,OAAO,cAAc,EAAE,iBAAiB"}
|
package/behaviors/index.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* @typedef {import('./legend.js').LegendToggleDetail} LegendToggleDetail
|
|
28
28
|
* @typedef {import('./crosshair.js').CrosshairMoveDetail} CrosshairMoveDetail
|
|
29
29
|
* @typedef {import('./command.js').CommandSelectDetail} CommandSelectDetail
|
|
30
|
+
* @typedef {import('./sources.js').SourceFocusDetail} SourceFocusDetail
|
|
30
31
|
*/
|
|
31
32
|
export { applyStoredTheme, initThemeToggle } from './theme.js';
|
|
32
33
|
export { dismissible } from './dismissible.js';
|
|
@@ -48,3 +49,4 @@ export { initConnectors } from './connectors.js';
|
|
|
48
49
|
export { initSpotlight } from './spotlight.js';
|
|
49
50
|
export { initCrosshair } from './crosshair.js';
|
|
50
51
|
export { initCommand } from './command.js';
|
|
52
|
+
export { initSources } from './sources.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source/citation affordances for the `sources.css` trust layer. The behavior
|
|
3
|
+
* is deliberately small: within each `[data-bronto-sources]` island it resolves
|
|
4
|
+
* `.ui-citation[href^="#"]` and `[data-bronto-source-ref]` controls to source
|
|
5
|
+
* cards, adds non-visual preview metadata (`title` + `aria-describedby`), and
|
|
6
|
+
* on activation moves focus to the source card with a temporary
|
|
7
|
+
* `.is-source-active` highlight. The host still owns fetching, numbering,
|
|
8
|
+
* trust decisions, and any rich preview UI.
|
|
9
|
+
*
|
|
10
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
11
|
+
* @returns {import('./internal.js').Cleanup}
|
|
12
|
+
*/
|
|
13
|
+
export function initSources({ root }?: import("./internal.js").DelegateOpts): import("./internal.js").Cleanup;
|
|
14
|
+
export type SourceFocusDetail = {
|
|
15
|
+
/**
|
|
16
|
+
* The focused source-card id.
|
|
17
|
+
*/
|
|
18
|
+
id: string;
|
|
19
|
+
/**
|
|
20
|
+
* The citation/control that requested the source.
|
|
21
|
+
*/
|
|
22
|
+
citation: Element;
|
|
23
|
+
/**
|
|
24
|
+
* The target source card or source element.
|
|
25
|
+
*/
|
|
26
|
+
source: Element;
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["sources.js"],"names":[],"mappings":"AA2CA;;;;;;;;;;;GAWG;AACH,uCAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CAwG3C;;;;;QAjJa,MAAM;;;;cACN,OAAO;;;;YACP,OAAO"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hasDom,
|
|
3
|
+
resolveHost,
|
|
4
|
+
noop,
|
|
5
|
+
bindOnce,
|
|
6
|
+
byIdInHost,
|
|
7
|
+
collectHosts,
|
|
8
|
+
scrollIntoViewSafe,
|
|
9
|
+
} from './internal.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {object} SourceFocusDetail
|
|
13
|
+
* @property {string} id The focused source-card id.
|
|
14
|
+
* @property {Element} citation The citation/control that requested the source.
|
|
15
|
+
* @property {Element} source The target source card or source element.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const REF_SELECTOR = '[data-bronto-source-ref], .ui-citation[href^="#"]';
|
|
19
|
+
const ACTIVE = 'is-source-active';
|
|
20
|
+
|
|
21
|
+
function sourceId(ref) {
|
|
22
|
+
const explicit = ref.getAttribute('data-bronto-source-ref');
|
|
23
|
+
if (explicit) return explicit.replace(/^#/, '');
|
|
24
|
+
const href = ref.getAttribute('href') || '';
|
|
25
|
+
if (!href.startsWith('#') || href === '#') return '';
|
|
26
|
+
try {
|
|
27
|
+
return decodeURIComponent(href.slice(1));
|
|
28
|
+
} catch {
|
|
29
|
+
return href.slice(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function sourcePreview(source) {
|
|
34
|
+
const text = (selector) =>
|
|
35
|
+
source.querySelector(selector)?.textContent?.replace(/\s+/g, ' ').trim() || '';
|
|
36
|
+
const title = text('.ui-source-card__title');
|
|
37
|
+
const meta = [text('.ui-source-card__origin'), text('.ui-source-card__time')]
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
.join(' · ');
|
|
40
|
+
const excerpt = text('.ui-source-card__excerpt');
|
|
41
|
+
return [title, meta, excerpt].filter(Boolean).join(' — ');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Source/citation affordances for the `sources.css` trust layer. The behavior
|
|
46
|
+
* is deliberately small: within each `[data-bronto-sources]` island it resolves
|
|
47
|
+
* `.ui-citation[href^="#"]` and `[data-bronto-source-ref]` controls to source
|
|
48
|
+
* cards, adds non-visual preview metadata (`title` + `aria-describedby`), and
|
|
49
|
+
* on activation moves focus to the source card with a temporary
|
|
50
|
+
* `.is-source-active` highlight. The host still owns fetching, numbering,
|
|
51
|
+
* trust decisions, and any rich preview UI.
|
|
52
|
+
*
|
|
53
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
54
|
+
* @returns {import('./internal.js').Cleanup}
|
|
55
|
+
*/
|
|
56
|
+
export function initSources({ root } = {}) {
|
|
57
|
+
if (!hasDom()) return noop;
|
|
58
|
+
const host = resolveHost(root);
|
|
59
|
+
if (!host) return noop;
|
|
60
|
+
|
|
61
|
+
const islands = collectHosts(host, '[data-bronto-sources]');
|
|
62
|
+
const cleanups = [];
|
|
63
|
+
|
|
64
|
+
for (const island of islands) {
|
|
65
|
+
const timers = new Set();
|
|
66
|
+
const seeded = [];
|
|
67
|
+
|
|
68
|
+
const targetFor = (ref) => {
|
|
69
|
+
const id = sourceId(ref);
|
|
70
|
+
if (!id) return null;
|
|
71
|
+
return byIdInHost(island, id);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const seed = () => {
|
|
75
|
+
for (const ref of island.querySelectorAll(REF_SELECTOR)) {
|
|
76
|
+
const source = targetFor(ref);
|
|
77
|
+
if (!source?.id) continue;
|
|
78
|
+
|
|
79
|
+
const describedBy = ref.getAttribute('aria-describedby') || '';
|
|
80
|
+
const describedIds = describedBy.split(/\s+/).filter(Boolean);
|
|
81
|
+
const title = ref.getAttribute('title');
|
|
82
|
+
const preview = sourcePreview(source);
|
|
83
|
+
const prior = {
|
|
84
|
+
ref,
|
|
85
|
+
describedBy,
|
|
86
|
+
hadDescribedBy: ref.hasAttribute('aria-describedby'),
|
|
87
|
+
title,
|
|
88
|
+
hadTitle: ref.hasAttribute('title'),
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
if (!describedIds.includes(source.id)) {
|
|
92
|
+
ref.setAttribute('aria-describedby', [...describedIds, source.id].join(' '));
|
|
93
|
+
}
|
|
94
|
+
if (!title && preview) ref.setAttribute('title', preview);
|
|
95
|
+
if (!source.hasAttribute('tabindex')) {
|
|
96
|
+
prior.source = source;
|
|
97
|
+
prior.hadTabindex = false;
|
|
98
|
+
source.setAttribute('tabindex', '-1');
|
|
99
|
+
}
|
|
100
|
+
seeded.push(prior);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const focusSource = (ref, source) => {
|
|
105
|
+
for (const card of island.querySelectorAll(`.${ACTIVE}`)) card.classList.remove(ACTIVE);
|
|
106
|
+
for (const timer of timers) clearTimeout(timer);
|
|
107
|
+
timers.clear();
|
|
108
|
+
|
|
109
|
+
source.classList.add(ACTIVE);
|
|
110
|
+
source.focus?.({ preventScroll: true });
|
|
111
|
+
scrollIntoViewSafe(source);
|
|
112
|
+
|
|
113
|
+
const timer = setTimeout(() => {
|
|
114
|
+
source.classList.remove(ACTIVE);
|
|
115
|
+
timers.delete(timer);
|
|
116
|
+
}, 1600);
|
|
117
|
+
timers.add(timer);
|
|
118
|
+
|
|
119
|
+
island.dispatchEvent(
|
|
120
|
+
new CustomEvent('bronto:source:focus', {
|
|
121
|
+
detail: { id: source.id, citation: ref, source },
|
|
122
|
+
bubbles: true,
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const onClick = (e) => {
|
|
128
|
+
const ref = e.target.closest?.(REF_SELECTOR);
|
|
129
|
+
if (!ref || !island.contains(ref)) return;
|
|
130
|
+
const source = targetFor(ref);
|
|
131
|
+
if (!source) return;
|
|
132
|
+
if (!ref.matches('a[href]')) e.preventDefault();
|
|
133
|
+
focusSource(ref, source);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const cleanup = bindOnce(island, 'sources', () => {
|
|
137
|
+
seed();
|
|
138
|
+
island.addEventListener('click', onClick);
|
|
139
|
+
return () => {
|
|
140
|
+
island.removeEventListener('click', onClick);
|
|
141
|
+
for (const timer of timers) clearTimeout(timer);
|
|
142
|
+
timers.clear();
|
|
143
|
+
for (const item of seeded.splice(0)) {
|
|
144
|
+
if (item.hadDescribedBy) item.ref.setAttribute('aria-describedby', item.describedBy);
|
|
145
|
+
else item.ref.removeAttribute('aria-describedby');
|
|
146
|
+
if (item.hadTitle) item.ref.setAttribute('title', item.title);
|
|
147
|
+
else item.ref.removeAttribute('title');
|
|
148
|
+
if (item.source && item.hadTabindex === false) item.source.removeAttribute('tabindex');
|
|
149
|
+
}
|
|
150
|
+
for (const card of island.querySelectorAll(`.${ACTIVE}`)) card.classList.remove(ACTIVE);
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
cleanups.push(cleanup);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return () => cleanups.forEach((fn) => fn());
|
|
158
|
+
}
|
package/classes/classes.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "@ponchia/ui class vocabulary as language-neutral data — validate emitted markup without executing the ESM cls map or parsing the .d.ts. Generated from classes/index.js — do not edit by hand; run `npm run classes:json:build`. Drift-checked in CI. `groups[].base` is null for a parts-only namespace (no standalone base class — do NOT emit it). A modifier whose name contains `__` (e.g. `ui-spark__bar--pos`) attaches to THAT part, not the base host. `states` is the author-applied `is-*` hooks (runtime/behavior-managed hooks are excluded); `behaviorAttributes` are the `data-bronto-*` wiring hooks the optional behaviors delegate on; `requiredAria` is the role/aria a generator must emit per component. `states` + `customProperties` are documented in docs/reference.md and ship outside `cls` by design.",
|
|
3
3
|
"counts": {
|
|
4
|
-
"classes":
|
|
5
|
-
"groups":
|
|
4
|
+
"classes": 593,
|
|
5
|
+
"groups": 171
|
|
6
6
|
},
|
|
7
7
|
"groups": {
|
|
8
8
|
"ui-accordion": {
|
|
@@ -303,6 +303,25 @@
|
|
|
303
303
|
],
|
|
304
304
|
"parts": []
|
|
305
305
|
},
|
|
306
|
+
"ui-claim": {
|
|
307
|
+
"base": "ui-claim",
|
|
308
|
+
"modifiers": [
|
|
309
|
+
"ui-claim--disputed",
|
|
310
|
+
"ui-claim--partial",
|
|
311
|
+
"ui-claim--supported",
|
|
312
|
+
"ui-claim--unknown",
|
|
313
|
+
"ui-claim--unsupported"
|
|
314
|
+
],
|
|
315
|
+
"parts": [
|
|
316
|
+
"ui-claim__basis",
|
|
317
|
+
"ui-claim__caveat",
|
|
318
|
+
"ui-claim__limits",
|
|
319
|
+
"ui-claim__refs",
|
|
320
|
+
"ui-claim__scope",
|
|
321
|
+
"ui-claim__statement",
|
|
322
|
+
"ui-claim__status"
|
|
323
|
+
]
|
|
324
|
+
},
|
|
306
325
|
"ui-cluster": {
|
|
307
326
|
"base": "ui-cluster",
|
|
308
327
|
"modifiers": [
|
|
@@ -526,6 +545,31 @@
|
|
|
526
545
|
"ui-error-summary__title"
|
|
527
546
|
]
|
|
528
547
|
},
|
|
548
|
+
"ui-evidence-grid": {
|
|
549
|
+
"base": "ui-evidence-grid",
|
|
550
|
+
"modifiers": [],
|
|
551
|
+
"parts": []
|
|
552
|
+
},
|
|
553
|
+
"ui-evidence-item": {
|
|
554
|
+
"base": "ui-evidence-item",
|
|
555
|
+
"modifiers": [],
|
|
556
|
+
"parts": [
|
|
557
|
+
"ui-evidence-item__body",
|
|
558
|
+
"ui-evidence-item__caveat",
|
|
559
|
+
"ui-evidence-item__kind",
|
|
560
|
+
"ui-evidence-item__meta",
|
|
561
|
+
"ui-evidence-item__method",
|
|
562
|
+
"ui-evidence-item__source",
|
|
563
|
+
"ui-evidence-item__title",
|
|
564
|
+
"ui-evidence-item__value",
|
|
565
|
+
"ui-evidence-item__window"
|
|
566
|
+
]
|
|
567
|
+
},
|
|
568
|
+
"ui-evidence-ledger": {
|
|
569
|
+
"base": "ui-evidence-ledger",
|
|
570
|
+
"modifiers": [],
|
|
571
|
+
"parts": []
|
|
572
|
+
},
|
|
529
573
|
"ui-eyebrow": {
|
|
530
574
|
"base": "ui-eyebrow",
|
|
531
575
|
"modifiers": [
|
|
@@ -894,15 +938,43 @@
|
|
|
894
938
|
"ui-report--compact",
|
|
895
939
|
"ui-report--numbered",
|
|
896
940
|
"ui-report__cover--compact",
|
|
941
|
+
"ui-report__finding--critical",
|
|
942
|
+
"ui-report__finding--major",
|
|
943
|
+
"ui-report__finding--minor",
|
|
944
|
+
"ui-report__finding--resolved",
|
|
897
945
|
"ui-report__section--unnumbered"
|
|
898
946
|
],
|
|
899
947
|
"parts": [
|
|
948
|
+
"ui-report__action",
|
|
949
|
+
"ui-report__action-criteria",
|
|
950
|
+
"ui-report__action-due",
|
|
951
|
+
"ui-report__action-owner",
|
|
952
|
+
"ui-report__action-priority",
|
|
953
|
+
"ui-report__action-source",
|
|
954
|
+
"ui-report__action-status",
|
|
955
|
+
"ui-report__action-title",
|
|
956
|
+
"ui-report__actions",
|
|
900
957
|
"ui-report__appendix",
|
|
901
958
|
"ui-report__caption",
|
|
902
959
|
"ui-report__cover",
|
|
960
|
+
"ui-report__decision",
|
|
961
|
+
"ui-report__decision-body",
|
|
962
|
+
"ui-report__decision-grid",
|
|
963
|
+
"ui-report__decision-item",
|
|
964
|
+
"ui-report__decision-kicker",
|
|
965
|
+
"ui-report__decision-label",
|
|
966
|
+
"ui-report__decision-meta",
|
|
967
|
+
"ui-report__decision-title",
|
|
968
|
+
"ui-report__decision-value",
|
|
903
969
|
"ui-report__evidence",
|
|
904
970
|
"ui-report__figure",
|
|
905
971
|
"ui-report__finding",
|
|
972
|
+
"ui-report__finding-caveat",
|
|
973
|
+
"ui-report__finding-claim",
|
|
974
|
+
"ui-report__finding-evidence",
|
|
975
|
+
"ui-report__finding-impact",
|
|
976
|
+
"ui-report__finding-remediation",
|
|
977
|
+
"ui-report__finding-title",
|
|
906
978
|
"ui-report__footnotes",
|
|
907
979
|
"ui-report__head",
|
|
908
980
|
"ui-report__meta",
|
|
@@ -1469,6 +1541,19 @@
|
|
|
1469
1541
|
"ui-chip--accent",
|
|
1470
1542
|
"ui-citation",
|
|
1471
1543
|
"ui-citation--chip",
|
|
1544
|
+
"ui-claim",
|
|
1545
|
+
"ui-claim--disputed",
|
|
1546
|
+
"ui-claim--partial",
|
|
1547
|
+
"ui-claim--supported",
|
|
1548
|
+
"ui-claim--unknown",
|
|
1549
|
+
"ui-claim--unsupported",
|
|
1550
|
+
"ui-claim__basis",
|
|
1551
|
+
"ui-claim__caveat",
|
|
1552
|
+
"ui-claim__limits",
|
|
1553
|
+
"ui-claim__refs",
|
|
1554
|
+
"ui-claim__scope",
|
|
1555
|
+
"ui-claim__statement",
|
|
1556
|
+
"ui-claim__status",
|
|
1472
1557
|
"ui-cluster",
|
|
1473
1558
|
"ui-cluster--between",
|
|
1474
1559
|
"ui-code",
|
|
@@ -1566,6 +1651,18 @@
|
|
|
1566
1651
|
"ui-error-summary",
|
|
1567
1652
|
"ui-error-summary__list",
|
|
1568
1653
|
"ui-error-summary__title",
|
|
1654
|
+
"ui-evidence-grid",
|
|
1655
|
+
"ui-evidence-item",
|
|
1656
|
+
"ui-evidence-item__body",
|
|
1657
|
+
"ui-evidence-item__caveat",
|
|
1658
|
+
"ui-evidence-item__kind",
|
|
1659
|
+
"ui-evidence-item__meta",
|
|
1660
|
+
"ui-evidence-item__method",
|
|
1661
|
+
"ui-evidence-item__source",
|
|
1662
|
+
"ui-evidence-item__title",
|
|
1663
|
+
"ui-evidence-item__value",
|
|
1664
|
+
"ui-evidence-item__window",
|
|
1665
|
+
"ui-evidence-ledger",
|
|
1569
1666
|
"ui-eyebrow",
|
|
1570
1667
|
"ui-eyebrow--muted",
|
|
1571
1668
|
"ui-eyebrow--sm",
|
|
@@ -1706,13 +1803,41 @@
|
|
|
1706
1803
|
"ui-report",
|
|
1707
1804
|
"ui-report--compact",
|
|
1708
1805
|
"ui-report--numbered",
|
|
1806
|
+
"ui-report__action",
|
|
1807
|
+
"ui-report__action-criteria",
|
|
1808
|
+
"ui-report__action-due",
|
|
1809
|
+
"ui-report__action-owner",
|
|
1810
|
+
"ui-report__action-priority",
|
|
1811
|
+
"ui-report__action-source",
|
|
1812
|
+
"ui-report__action-status",
|
|
1813
|
+
"ui-report__action-title",
|
|
1814
|
+
"ui-report__actions",
|
|
1709
1815
|
"ui-report__appendix",
|
|
1710
1816
|
"ui-report__caption",
|
|
1711
1817
|
"ui-report__cover",
|
|
1712
1818
|
"ui-report__cover--compact",
|
|
1819
|
+
"ui-report__decision",
|
|
1820
|
+
"ui-report__decision-body",
|
|
1821
|
+
"ui-report__decision-grid",
|
|
1822
|
+
"ui-report__decision-item",
|
|
1823
|
+
"ui-report__decision-kicker",
|
|
1824
|
+
"ui-report__decision-label",
|
|
1825
|
+
"ui-report__decision-meta",
|
|
1826
|
+
"ui-report__decision-title",
|
|
1827
|
+
"ui-report__decision-value",
|
|
1713
1828
|
"ui-report__evidence",
|
|
1714
1829
|
"ui-report__figure",
|
|
1715
1830
|
"ui-report__finding",
|
|
1831
|
+
"ui-report__finding--critical",
|
|
1832
|
+
"ui-report__finding--major",
|
|
1833
|
+
"ui-report__finding--minor",
|
|
1834
|
+
"ui-report__finding--resolved",
|
|
1835
|
+
"ui-report__finding-caveat",
|
|
1836
|
+
"ui-report__finding-claim",
|
|
1837
|
+
"ui-report__finding-evidence",
|
|
1838
|
+
"ui-report__finding-impact",
|
|
1839
|
+
"ui-report__finding-remediation",
|
|
1840
|
+
"ui-report__finding-title",
|
|
1716
1841
|
"ui-report__footnotes",
|
|
1717
1842
|
"ui-report__head",
|
|
1718
1843
|
"ui-report__meta",
|
|
@@ -1908,6 +2033,12 @@
|
|
|
1908
2033
|
"scope": ".ui-tab and other selectable items",
|
|
1909
2034
|
"effect": "active/selected state"
|
|
1910
2035
|
},
|
|
2036
|
+
{
|
|
2037
|
+
"class": "is-source-active",
|
|
2038
|
+
"scope": ".ui-source-card",
|
|
2039
|
+
"effect": "temporary source highlight after a citation/backref activation",
|
|
2040
|
+
"managed": "runtime"
|
|
2041
|
+
},
|
|
1911
2042
|
{
|
|
1912
2043
|
"class": "is-inactive",
|
|
1913
2044
|
"scope": "interactive .ui-legend__item",
|
|
@@ -2378,6 +2509,19 @@
|
|
|
2378
2509
|
"behavior": "initCommand",
|
|
2379
2510
|
"note": "wires the filter input + active-option keyboard model"
|
|
2380
2511
|
},
|
|
2512
|
+
{
|
|
2513
|
+
"name": "data-bronto-sources",
|
|
2514
|
+
"on": "a source/citation island",
|
|
2515
|
+
"behavior": "initSources",
|
|
2516
|
+
"note": "scopes citation preview metadata and source-card focus/highlight behavior; the host still owns numbering, fetching, and trust decisions."
|
|
2517
|
+
},
|
|
2518
|
+
{
|
|
2519
|
+
"name": "data-bronto-source-ref",
|
|
2520
|
+
"on": "a button/control that references a source card",
|
|
2521
|
+
"value": "id of the source card, with or without a leading #",
|
|
2522
|
+
"behavior": "initSources",
|
|
2523
|
+
"note": "button/control equivalent of a .ui-citation[href=\"#source-id\"]; activation focuses and highlights the referenced source."
|
|
2524
|
+
},
|
|
2381
2525
|
{
|
|
2382
2526
|
"name": "data-bronto-dismiss",
|
|
2383
2527
|
"on": "a button",
|
package/classes/index.d.ts
CHANGED
|
@@ -263,16 +263,69 @@ export declare const cls: {
|
|
|
263
263
|
readonly reportMeta: 'ui-report__meta';
|
|
264
264
|
readonly reportToc: 'ui-report__toc';
|
|
265
265
|
readonly reportSummary: 'ui-report__summary';
|
|
266
|
+
readonly reportDecision: 'ui-report__decision';
|
|
267
|
+
readonly reportDecisionKicker: 'ui-report__decision-kicker';
|
|
268
|
+
readonly reportDecisionTitle: 'ui-report__decision-title';
|
|
269
|
+
readonly reportDecisionBody: 'ui-report__decision-body';
|
|
270
|
+
readonly reportDecisionMeta: 'ui-report__decision-meta';
|
|
271
|
+
readonly reportDecisionGrid: 'ui-report__decision-grid';
|
|
272
|
+
readonly reportDecisionItem: 'ui-report__decision-item';
|
|
273
|
+
readonly reportDecisionLabel: 'ui-report__decision-label';
|
|
274
|
+
readonly reportDecisionValue: 'ui-report__decision-value';
|
|
266
275
|
readonly reportSection: 'ui-report__section';
|
|
267
276
|
readonly reportSectionUnnumbered: 'ui-report__section--unnumbered';
|
|
268
277
|
readonly reportSectionHead: 'ui-report__section-head';
|
|
269
278
|
readonly reportFinding: 'ui-report__finding';
|
|
279
|
+
readonly reportFindingCritical: 'ui-report__finding--critical';
|
|
280
|
+
readonly reportFindingMajor: 'ui-report__finding--major';
|
|
281
|
+
readonly reportFindingMinor: 'ui-report__finding--minor';
|
|
282
|
+
readonly reportFindingResolved: 'ui-report__finding--resolved';
|
|
283
|
+
readonly reportFindingTitle: 'ui-report__finding-title';
|
|
284
|
+
readonly reportFindingClaim: 'ui-report__finding-claim';
|
|
285
|
+
readonly reportFindingImpact: 'ui-report__finding-impact';
|
|
286
|
+
readonly reportFindingRemediation: 'ui-report__finding-remediation';
|
|
287
|
+
readonly reportFindingEvidence: 'ui-report__finding-evidence';
|
|
288
|
+
readonly reportFindingCaveat: 'ui-report__finding-caveat';
|
|
270
289
|
readonly reportEvidence: 'ui-report__evidence';
|
|
271
290
|
readonly reportFigure: 'ui-report__figure';
|
|
272
291
|
readonly reportCaption: 'ui-report__caption';
|
|
273
292
|
readonly reportSources: 'ui-report__sources';
|
|
274
293
|
readonly reportAppendix: 'ui-report__appendix';
|
|
275
294
|
readonly reportFootnotes: 'ui-report__footnotes';
|
|
295
|
+
readonly reportActions: 'ui-report__actions';
|
|
296
|
+
readonly reportAction: 'ui-report__action';
|
|
297
|
+
readonly reportActionStatus: 'ui-report__action-status';
|
|
298
|
+
readonly reportActionTitle: 'ui-report__action-title';
|
|
299
|
+
readonly reportActionOwner: 'ui-report__action-owner';
|
|
300
|
+
readonly reportActionDue: 'ui-report__action-due';
|
|
301
|
+
readonly reportActionPriority: 'ui-report__action-priority';
|
|
302
|
+
readonly reportActionCriteria: 'ui-report__action-criteria';
|
|
303
|
+
readonly reportActionSource: 'ui-report__action-source';
|
|
304
|
+
readonly claim: 'ui-claim';
|
|
305
|
+
readonly claimSupported: 'ui-claim--supported';
|
|
306
|
+
readonly claimPartial: 'ui-claim--partial';
|
|
307
|
+
readonly claimDisputed: 'ui-claim--disputed';
|
|
308
|
+
readonly claimUnsupported: 'ui-claim--unsupported';
|
|
309
|
+
readonly claimUnknown: 'ui-claim--unknown';
|
|
310
|
+
readonly claimStatement: 'ui-claim__statement';
|
|
311
|
+
readonly claimStatus: 'ui-claim__status';
|
|
312
|
+
readonly claimScope: 'ui-claim__scope';
|
|
313
|
+
readonly claimBasis: 'ui-claim__basis';
|
|
314
|
+
readonly claimLimits: 'ui-claim__limits';
|
|
315
|
+
readonly claimRefs: 'ui-claim__refs';
|
|
316
|
+
readonly claimCaveat: 'ui-claim__caveat';
|
|
317
|
+
readonly evidenceGrid: 'ui-evidence-grid';
|
|
318
|
+
readonly evidenceLedger: 'ui-evidence-ledger';
|
|
319
|
+
readonly evidenceItem: 'ui-evidence-item';
|
|
320
|
+
readonly evidenceItemTitle: 'ui-evidence-item__title';
|
|
321
|
+
readonly evidenceItemMeta: 'ui-evidence-item__meta';
|
|
322
|
+
readonly evidenceItemBody: 'ui-evidence-item__body';
|
|
323
|
+
readonly evidenceItemKind: 'ui-evidence-item__kind';
|
|
324
|
+
readonly evidenceItemMethod: 'ui-evidence-item__method';
|
|
325
|
+
readonly evidenceItemWindow: 'ui-evidence-item__window';
|
|
326
|
+
readonly evidenceItemValue: 'ui-evidence-item__value';
|
|
327
|
+
readonly evidenceItemSource: 'ui-evidence-item__source';
|
|
328
|
+
readonly evidenceItemCaveat: 'ui-evidence-item__caveat';
|
|
276
329
|
readonly compare: 'ui-compare';
|
|
277
330
|
readonly compare2up: 'ui-compare--2up';
|
|
278
331
|
readonly compareCol: 'ui-compare__col';
|
|
@@ -585,6 +638,14 @@ export interface CompareOpts {
|
|
|
585
638
|
/** Pin exactly two equal columns (hard before/after) instead of the auto-fitting set. */
|
|
586
639
|
cols?: 2;
|
|
587
640
|
}
|
|
641
|
+
export interface ReportFindingOpts {
|
|
642
|
+
/** Severity/status band. Pair with an author-written label; tone is not the only signal. */
|
|
643
|
+
severity?: 'critical' | 'major' | 'minor' | 'resolved';
|
|
644
|
+
}
|
|
645
|
+
export interface ClaimOpts {
|
|
646
|
+
/** Evidence status. Pair with written status text; tone is only a scanning aid. */
|
|
647
|
+
status?: 'supported' | 'partial' | 'disputed' | 'unsupported' | 'unknown';
|
|
648
|
+
}
|
|
588
649
|
export interface ChipOpts {
|
|
589
650
|
accent?: boolean;
|
|
590
651
|
}
|
|
@@ -787,6 +848,8 @@ export interface Ui {
|
|
|
787
848
|
num(opts?: NumOpts): string;
|
|
788
849
|
delta(opts?: DeltaOpts): string;
|
|
789
850
|
compare(opts?: CompareOpts): string;
|
|
851
|
+
reportFinding(opts?: ReportFindingOpts): string;
|
|
852
|
+
claim(opts?: ClaimOpts): string;
|
|
790
853
|
chip(opts?: ChipOpts): string;
|
|
791
854
|
link(opts?: LinkOpts): string;
|
|
792
855
|
dot(opts?: DotOpts): string;
|