@ponchia/ui 0.6.7 → 0.6.9
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 +129 -4
- package/README.md +4 -4
- package/annotations/index.d.ts.map +1 -1
- package/annotations/index.js +26 -9
- package/behaviors/carousel.d.ts.map +1 -1
- package/behaviors/carousel.js +145 -49
- package/behaviors/combobox.d.ts.map +1 -1
- package/behaviors/combobox.js +220 -92
- package/behaviors/command.d.ts.map +1 -1
- package/behaviors/command.js +74 -14
- package/behaviors/connectors.d.ts.map +1 -1
- package/behaviors/connectors.js +131 -32
- package/behaviors/crosshair.d.ts.map +1 -1
- package/behaviors/crosshair.js +47 -1
- package/behaviors/dialog.d.ts.map +1 -1
- package/behaviors/dialog.js +24 -9
- package/behaviors/disclosure.d.ts.map +1 -1
- package/behaviors/disclosure.js +33 -3
- package/behaviors/dismissible.d.ts.map +1 -1
- package/behaviors/dismissible.js +3 -2
- package/behaviors/forms.d.ts.map +1 -1
- package/behaviors/forms.js +211 -140
- package/behaviors/glyph.d.ts.map +1 -1
- package/behaviors/glyph.js +172 -132
- package/behaviors/inert.d.ts +1 -1
- package/behaviors/inert.d.ts.map +1 -1
- package/behaviors/inert.js +4 -3
- package/behaviors/internal.d.ts.map +1 -1
- package/behaviors/internal.js +4 -3
- package/behaviors/legend.d.ts +0 -5
- package/behaviors/legend.d.ts.map +1 -1
- package/behaviors/legend.js +45 -13
- package/behaviors/menu.d.ts.map +1 -1
- package/behaviors/menu.js +13 -8
- package/behaviors/modal.d.ts.map +1 -1
- package/behaviors/modal.js +77 -19
- package/behaviors/popover.d.ts +4 -3
- package/behaviors/popover.d.ts.map +1 -1
- package/behaviors/popover.js +94 -14
- package/behaviors/sources.d.ts.map +1 -1
- package/behaviors/sources.js +14 -2
- package/behaviors/splitter.d.ts.map +1 -1
- package/behaviors/splitter.js +149 -110
- package/behaviors/spotlight.d.ts.map +1 -1
- package/behaviors/spotlight.js +28 -2
- package/behaviors/table.d.ts +1 -1
- package/behaviors/table.d.ts.map +1 -1
- package/behaviors/table.js +108 -17
- package/behaviors/tabs.d.ts.map +1 -1
- package/behaviors/tabs.js +84 -20
- package/behaviors/theme.d.ts.map +1 -1
- package/behaviors/theme.js +25 -5
- package/behaviors/toast.js +5 -5
- package/classes/index.d.ts +15 -2
- package/classes/index.js +48 -35
- package/connectors/index.d.ts +41 -8
- package/connectors/index.d.ts.map +1 -1
- package/connectors/index.js +74 -19
- package/css/annotations.css +12 -0
- package/css/app.css +3 -4
- package/css/base.css +1 -1
- package/css/content.css +3 -3
- package/css/crosshair.css +27 -2
- package/css/disclosure.css +3 -3
- package/css/dots.css +4 -4
- package/css/feedback.css +8 -37
- package/css/forms.css +9 -12
- package/css/legend.css +1 -1
- package/css/marks.css +1 -1
- package/css/motion.css +6 -6
- package/css/navigation.css +12 -0
- package/css/overlay.css +5 -7
- package/css/primitives.css +14 -16
- package/css/sidenote.css +2 -2
- package/css/table.css +2 -2
- package/css/tokens.css +16 -0
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -1
- package/dist/css/annotations.css +1 -1
- package/dist/css/crosshair.css +1 -1
- package/dist/css/feedback.css +1 -1
- package/dist/css/navigation.css +1 -1
- package/dist/css/report-kit.css +1 -1
- package/dist/css/tokens.css +1 -1
- package/docs/adr/0001-color-system.md +3 -2
- package/docs/annotations.md +21 -1
- package/docs/architecture.md +74 -13
- package/docs/command.md +4 -1
- package/docs/connectors.md +16 -0
- package/docs/crosshair.md +1 -1
- package/docs/dots.md +4 -1
- package/docs/glyphs.md +11 -0
- package/docs/interop/react-flow.md +89 -0
- package/docs/migrations/0.2-to-0.3.md +1 -1
- package/docs/package-contract.md +7 -5
- package/docs/reporting.md +23 -12
- package/docs/stability.md +85 -9
- package/docs/theming.md +2 -2
- package/docs/usage.md +16 -2
- package/docs/vega.md +4 -4
- package/glyphs/glyphs.js +43 -33
- package/llms.txt +19 -8
- package/package.json +23 -4
- package/schemas/report-claims.v1.schema.json +1 -1
- package/svelte/index.d.ts +71 -45
- package/svelte/index.d.ts.map +1 -1
- package/svelte/index.js +29 -2
- package/tokens/index.js +2 -2
- package/vue/index.d.ts +42 -5
- package/vue/index.d.ts.map +1 -1
- package/vue/index.js +32 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,131 @@
|
|
|
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.9 — 2026-06-20
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Product doctrine and 1.0 readiness.** `CONTRIBUTING.md`, `ROADMAP.md`,
|
|
13
|
+
`docs/architecture.md`, and `docs/stability.md` now codify the
|
|
14
|
+
core-vs-opt-in surface boundary, the refusal list, registry-first gate
|
|
15
|
+
maintenance, packed-tarball proof, a gate-backed 1.0 readiness ledger, and
|
|
16
|
+
release evidence policy for public-safe downstream proof. The stability
|
|
17
|
+
matrix now includes explicit rows for every exported opt-in CSS leaf plus
|
|
18
|
+
the public machine-readable/theme subpath families.
|
|
19
|
+
- **Registry-backed gate ownership.** `check:report`,
|
|
20
|
+
`check:component-matrix`, `check:exports`, and `check:consumer-surface` now
|
|
21
|
+
share internal registries for the reporting toolbox, exported CSS leaves, and
|
|
22
|
+
optional framework peers instead of carrying separate hand-maintained lists.
|
|
23
|
+
The matrix gates also share one proof-owner helper for cached file reads,
|
|
24
|
+
owner-file existence, word matching, and required text evidence.
|
|
25
|
+
- **Native complexity budget.** `check:complexity` is now part of the
|
|
26
|
+
aggregate `npm run check` chain. It uses the existing TypeScript parser to
|
|
27
|
+
keep function-level cyclomatic complexity at 12 or lower and function size
|
|
28
|
+
under budget without carrying per-function exception baselines.
|
|
29
|
+
- **Gate-backed annotation package boundary.** The annotation docs now make the
|
|
30
|
+
split with `@ponchia/annotations` explicit: `@ponchia/ui/annotations` remains
|
|
31
|
+
the dependency-free Bronto static-helper compatibility surface, while richer
|
|
32
|
+
placement, renderer, editing, and adapter work belongs in the sibling
|
|
33
|
+
annotation package. `check:public-metadata` now guards that doctrine,
|
|
34
|
+
`check:exports` rejects packed code or declaration references to the sibling
|
|
35
|
+
package, and no runtime or public type dependency is added to `@ponchia/ui`.
|
|
36
|
+
- **Public source hygiene guard.** `check:public-hygiene` now rejects internal
|
|
37
|
+
audit-ticket markers across repository source files, and still scans the
|
|
38
|
+
packed public text files for private terms, local paths, and secret-looking
|
|
39
|
+
assignments. `check:doc-links` also rejects executable URL schemes in public
|
|
40
|
+
authoring docs. The pass also brought
|
|
41
|
+
`behaviors/inert.js` under the generated declaration emit inputs so
|
|
42
|
+
`check:dts-emit` covers its public `.d.ts` surface.
|
|
43
|
+
|
|
44
|
+
### Verified
|
|
45
|
+
|
|
46
|
+
- **Release evidence.** `npm run check` passed for `0.6.9`, including
|
|
47
|
+
`check:pack`, `check:consumer-surface`, `check:consumer-types`,
|
|
48
|
+
`check:examples`, `check:publint`, and `check:attw`. No default-bundle budget
|
|
49
|
+
movement; this release is gate/docs/declaration hardening rather than a
|
|
50
|
+
runtime surface expansion.
|
|
51
|
+
- **Downstream proof.** The packed current tarball installed into a disposable
|
|
52
|
+
copy of a real React/Vite app consumer that imports `@ponchia/ui/classes`,
|
|
53
|
+
`@ponchia/ui/behaviors`, `@ponchia/ui/tokens/resolved.json`, and
|
|
54
|
+
`@ponchia/ui/vega`; its `typecheck` and production `build` both passed.
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- **Report sidecar hash validation.** `report-claims.v1` now requires
|
|
59
|
+
`contentHash` values to use exact SHA digest lengths (`sha256`, `sha384`, or
|
|
60
|
+
`sha512`) instead of accepting any hex payload after a supported algorithm
|
|
61
|
+
prefix.
|
|
62
|
+
|
|
63
|
+
## 0.6.8 — 2026-06-16
|
|
64
|
+
|
|
65
|
+
Patch release for the deep UI-framework audit: broader browser/package gates,
|
|
66
|
+
clean-consumer verification, and runtime fixes found while hardening the public
|
|
67
|
+
surface. No breaking changes, no `MIGRATIONS.json` entry.
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
|
|
71
|
+
- **Tarball and clean-consumer gates.** `check:consumer-surface` now imports
|
|
72
|
+
public JS/JSON subpaths from the packed package, resolves concrete CSS/doc/
|
|
73
|
+
font subpaths without optional peers, and verifies behavior initializers stay
|
|
74
|
+
SSR-safe. `check:consumer-types` installs the tarball into a clean TypeScript
|
|
75
|
+
consumer and compiles every typed `@ponchia/ui/...` package subpath.
|
|
76
|
+
- **Matrix ownership gates.** `check:component-matrix`,
|
|
77
|
+
`check:behavior-matrix`, `check:helper-matrix`, and `check:binding-matrix`
|
|
78
|
+
now require shipped CSS leaves, public behavior exports, helper modules, and
|
|
79
|
+
framework bindings to have explicit docs, type, unit, or browser ownership.
|
|
80
|
+
- **Public docs and package hygiene gates.** `check:doc-links` validates local
|
|
81
|
+
links and heading anchors across shipped docs, authoring docs, and the docs
|
|
82
|
+
viewer route list. `check:schemas`, `check:visual-baselines`,
|
|
83
|
+
`check:playwright-container`, and stronger `check:contract` / `check:report`
|
|
84
|
+
coverage close stale public snippets, missing visual baselines, and invalid
|
|
85
|
+
report/schema surfaces.
|
|
86
|
+
- **Broader browser coverage.** The Playwright suite now pins docs viewer deep
|
|
87
|
+
links, cascade-layer behavior, source focusing, renderer geometry, behavior
|
|
88
|
+
cleanup/idempotency, connector transforms, annotation motion/overflow,
|
|
89
|
+
command interactions, crosshair payloads, responsive overflow, and more
|
|
90
|
+
forced-colors/reduced-motion contracts.
|
|
91
|
+
- **Packed example smoke coverage.** The example runner now builds and smokes
|
|
92
|
+
the packed examples from one registry, with richer runtime assertions,
|
|
93
|
+
desktop/mobile visual health, and optional Chromium/Firefox/WebKit coverage.
|
|
94
|
+
Astro joins the packed-tarball smoke matrix.
|
|
95
|
+
- **Renderer theme helper coverage.** Chart, Mermaid, D2, and Vega package
|
|
96
|
+
helpers now have type/runtime coverage that checks default exports,
|
|
97
|
+
theme-selection fallbacks, resolved colors, and `var()` leak prevention.
|
|
98
|
+
|
|
99
|
+
### Fixed
|
|
100
|
+
|
|
101
|
+
- **Standalone dot readouts survive `report-kit.css`.** `crosshair.css` now
|
|
102
|
+
scopes pinned readout-chip styling to `.ui-crosshair .ui-readout`, so the
|
|
103
|
+
core dot-matrix `.ui-readout` keeps its normal inline layout when a report
|
|
104
|
+
imports the full report kit.
|
|
105
|
+
- **Rendered docs deep links work.** `docs/index.html` now preserves
|
|
106
|
+
`doc.md#section` routes, generates deterministic heading IDs, keeps
|
|
107
|
+
same-page anchors inside the current doc route, and drops the invalid
|
|
108
|
+
meta-CSP `frame-ancestors` directive that browsers reported as a console
|
|
109
|
+
error.
|
|
110
|
+
- **Command adapter docs match the shipped matrix.** `docs/command.md`, the
|
|
111
|
+
stability matrix, package-contract provenance, and `llms.txt` now name the
|
|
112
|
+
Svelte action and Vue directive/plugin paths alongside the React/Solid/Qwik
|
|
113
|
+
bindings.
|
|
114
|
+
- **CodeQL review findings.** Docs slug helpers no longer use incomplete
|
|
115
|
+
regex-based tag stripping, and wildcard package-subpath expansion replaces
|
|
116
|
+
every placeholder rather than only the first one.
|
|
117
|
+
|
|
118
|
+
### Changed
|
|
119
|
+
|
|
120
|
+
- `npm run check` now owns the unit suite through `check:unit`; CI, release
|
|
121
|
+
workflow validation, PR templates, release docs, and package-contract docs
|
|
122
|
+
all describe the same aggregate gate instead of duplicating `npm test`.
|
|
123
|
+
- Release hygiene now verifies the aggregate check includes unit coverage and
|
|
124
|
+
prevents duplicate release-workflow unit runs from drifting out of sync.
|
|
125
|
+
- `check:exports` now pins package-level CSS metadata: the top-level `style`
|
|
126
|
+
field, root export targets, `files`, and CSS-preserving `sideEffects`.
|
|
127
|
+
- Type-only coverage now instantiates Svelte action and Vue directive
|
|
128
|
+
declarations from consumer-shaped code, including invalid root-shape
|
|
129
|
+
assertions.
|
|
130
|
+
- The default bundle budget is recalibrated to 91 kB raw / 15.65 kB gzip after
|
|
131
|
+
the audited bundle landed below that ceiling at 87.9 kB raw / 15.0 kB gzip.
|
|
132
|
+
|
|
8
133
|
## 0.6.7 — 2026-06-15
|
|
9
134
|
|
|
10
135
|
### Added
|
|
@@ -392,7 +517,7 @@ and D2. The data-viz **palette** (`--chart-*`, `tokens/charts.json`) and the
|
|
|
392
517
|
|
|
393
518
|
### Fixed
|
|
394
519
|
|
|
395
|
-
- **Published-type drift
|
|
520
|
+
- **Published-type drift.** `ui.meter({ tone: 'info' })` and
|
|
396
521
|
`ui.bracketNote({ tone: 'success' })` emit real classes at runtime, but the
|
|
397
522
|
generated `.d.ts` tone unions (hand-mirrored in `gen-dts.mjs`) omitted them, so
|
|
398
523
|
a TS consumer got a spurious type error for a value that renders. The unions
|
|
@@ -564,16 +689,16 @@ and D2. The data-viz **palette** (`--chart-*`, `tokens/charts.json`) and the
|
|
|
564
689
|
token source as a read-only export for foreign renderers (in-DOM ink is
|
|
565
690
|
`--button-text`). `contrast.md` now prints APCA `Lc` to one decimal so an
|
|
566
691
|
advisory shortfall (e.g. `Lc 44.9`) no longer rounds to a passing-looking `45`.
|
|
567
|
-
- Raw bundle budget 81 → 82 kB for the
|
|
692
|
+
- Raw bundle budget 81 → 82 kB for the accessibility/state
|
|
568
693
|
blocks (gzip held ~14.1 kB — the additions are repetitive media-query and
|
|
569
694
|
`:has()`/`:not()` rules that compress well).
|
|
570
|
-
- **Code-
|
|
695
|
+
- **Code-health pass — two new gates + targeted dedup, no churn.**
|
|
571
696
|
A code-health pass (complexity / duplication / AI-slop / missing-best-practice)
|
|
572
697
|
that deliberately left working, gate-protected code alone. Added:
|
|
573
698
|
`check:recipe-types` (factory↔`.d.ts` option parity, above) and `check:chain`
|
|
574
699
|
(every `check:*` script is wired into the aggregate `check` chain — closes the
|
|
575
700
|
silent-coverage-drop class; it would have caught a forgotten gate). Reconciled
|
|
576
|
-
a latent bug — `clamp()` had
|
|
701
|
+
a latent bug — `clamp()` had drifted between `connectors` and
|
|
577
702
|
`annotations`; the two now share one scalar/geometry kernel (the guarded form).
|
|
578
703
|
Dedup that removed real duplication: a shared `collectHosts()` /
|
|
579
704
|
`scrollIntoViewSafe()` / `wrapIndex()` in `behaviors/internal.js` (~9 behaviors),
|
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)
|
|
@@ -67,12 +67,12 @@ npm i @ponchia/ui
|
|
|
67
67
|
Or drop it in with no build step, straight from a CDN:
|
|
68
68
|
|
|
69
69
|
```html
|
|
70
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.6.
|
|
70
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ponchia/ui@0.6.9/dist/bronto.css">
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
## Quick start
|
|
74
74
|
|
|
75
|
-
**1. Load the CSS.** One flattened, minified bundle — the whole standard component set, one request (~
|
|
75
|
+
**1. Load the CSS.** One flattened, minified bundle — the whole standard component set, one request (~88 kB raw / ~15 kB gzip):
|
|
76
76
|
|
|
77
77
|
```css
|
|
78
78
|
@import '@ponchia/ui'; /* via a bundler */
|
|
@@ -140,7 +140,7 @@ Arrows, chevrons, check/close/plus/minus, search/menu/gear, info/warning/bell/lo
|
|
|
140
140
|
- **Disclosure & nav** — tabs, accordion, segmented, breadcrumb, pagination, `ui-steps`, `ui-timeline`, `ui-pagehead`, `ui-kbd`.
|
|
141
141
|
- **Shells** — a service/app shell (`ui-app-*`) and a content/marketing site shell (`ui-site*`, `ui-container`).
|
|
142
142
|
- **Prose** — `.ui-prose` styles raw, unclassed semantic HTML (Markdown / CMS / LLM output) with zero classes.
|
|
143
|
-
- **Analytical & communication primitives** _(opt-in)_ — `@ponchia/ui/css/analytical.css`: **figure** stages, 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, a cross-cutting **selection** vocabulary, and CSS Custom Highlight API **highlights**. 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), **interval**, **clamp**, and **lifecycle `state`** leaves.
|
|
143
|
+
- **Analytical & communication primitives** _(opt-in)_ — `@ponchia/ui/css/analytical.css`: **figure** stages, 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, a cross-cutting **selection** vocabulary, and CSS Custom Highlight API **highlights**. Each owns its visual grammar + pure geometry and refuses scales/state/hit-testing — figures that explain themselves, not a chart engine. The richer annotation engine lives in `@ponchia/annotations`; this package keeps only the dependency-free Bronto helper surface. Plus standalone **`source`/provenance** (trust), **interval**, **clamp**, and **lifecycle `state`** leaves.
|
|
144
144
|
- **Reports** _(opt-in)_ — `@ponchia/ui/css/report-kit.css` for a complete static/PDF report vocabulary, or `@ponchia/ui/css/report.css` plus only the leaves a narrow report uses. Covers, decisions, claims, sections, severity-labelled findings, evidence packets, evidence ledgers, action registers, source-card bindings, `ui-figure` composition, intervals, bounded excerpts, chart wrappers and print utilities.
|
|
145
145
|
- **Motion & dots** — the dot-matrix motif kit: dot grid, status dots, dot loaders, the orbital spinner, matrix reveal — all reduced-motion aware.
|
|
146
146
|
- **Glyphs** — `@ponchia/ui/glyphs`, a 71-glyph dot-matrix icon set on the `.ui-dotmatrix` primitive (display marks + crisp `solid` inline icons + one-node `.ui-icon` mask rendering).
|
|
@@ -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":"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"}
|
package/annotations/index.js
CHANGED
|
@@ -209,8 +209,7 @@ import {
|
|
|
209
209
|
arrowHead,
|
|
210
210
|
dotMark,
|
|
211
211
|
angleBetween,
|
|
212
|
-
// Shared scalar/geometry kernel
|
|
213
|
-
// and the local clamp had silently diverged from the connectors one).
|
|
212
|
+
// Shared scalar/geometry kernel for annotation and connector path output.
|
|
214
213
|
roundNumber,
|
|
215
214
|
finite,
|
|
216
215
|
dimension,
|
|
@@ -220,8 +219,8 @@ import {
|
|
|
220
219
|
rectPath,
|
|
221
220
|
} from '../connectors/index.js';
|
|
222
221
|
|
|
223
|
-
// A circle subject is just a filled dot at (x, y)
|
|
224
|
-
//
|
|
222
|
+
// A circle subject is just a filled dot at (x, y); delegate to the connector
|
|
223
|
+
// kernel so arc geometry and numeric precision stay aligned.
|
|
225
224
|
function circlePathAt(x, y, radius) {
|
|
226
225
|
return dotMark({ x, y }, radius);
|
|
227
226
|
}
|
|
@@ -237,6 +236,24 @@ function validateOffset(opts) {
|
|
|
237
236
|
};
|
|
238
237
|
}
|
|
239
238
|
|
|
239
|
+
function annotationConnectorType(value) {
|
|
240
|
+
const type = value ?? 'callout';
|
|
241
|
+
if (type === 'callout' || type === 'elbow' || type === 'curve') return type;
|
|
242
|
+
throw new TypeError('type must be "callout", "elbow" or "curve"');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function directLabelAxis(value) {
|
|
246
|
+
const axis = value ?? 'y';
|
|
247
|
+
if (axis === 'x' || axis === 'y') return axis;
|
|
248
|
+
throw new TypeError('axis must be "x" or "y"');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function directLabelShape(value) {
|
|
252
|
+
const shape = value ?? 'straight';
|
|
253
|
+
if (shape === 'straight' || shape === 'elbow' || shape === 'curve') return shape;
|
|
254
|
+
throw new TypeError('shape must be "straight", "elbow" or "curve"');
|
|
255
|
+
}
|
|
256
|
+
|
|
240
257
|
function trimForCircle(dx, dy, subject) {
|
|
241
258
|
const len = Math.hypot(dx, dy);
|
|
242
259
|
const radius = dimension('subject.radius', subject.radius);
|
|
@@ -652,8 +669,8 @@ export function connectorCurve(opts = {}) {
|
|
|
652
669
|
return curvePath(start, end, { curvature: 0.35 });
|
|
653
670
|
}
|
|
654
671
|
|
|
655
|
-
// subject.type → its path builder. A flat dispatch table
|
|
656
|
-
//
|
|
672
|
+
// subject.type → its path builder. A flat dispatch table keyed by the
|
|
673
|
+
// SubjectType union; an unknown type throws below.
|
|
657
674
|
const SUBJECT_BUILDERS = {
|
|
658
675
|
circle: circleSubjectPath,
|
|
659
676
|
rect: rectSubjectPath,
|
|
@@ -673,7 +690,7 @@ const SUBJECT_BUILDERS = {
|
|
|
673
690
|
* @returns {AnnotationParts}
|
|
674
691
|
*/
|
|
675
692
|
export function annotationParts(opts = {}) {
|
|
676
|
-
const type = opts.type
|
|
693
|
+
const type = annotationConnectorType(opts.type);
|
|
677
694
|
const transform = annotationTransform({ x: opts.x ?? 0, y: opts.y ?? 0 });
|
|
678
695
|
const dx = finite('dx', opts.dx, 0);
|
|
679
696
|
const dy = finite('dy', opts.dy, 0);
|
|
@@ -764,9 +781,9 @@ export function declutterLabels(items, opts = {}) {
|
|
|
764
781
|
*/
|
|
765
782
|
export function directLabels(items, opts = {}) {
|
|
766
783
|
if (!Array.isArray(items)) throw new TypeError('items must be an array');
|
|
767
|
-
const axis = opts.axis
|
|
784
|
+
const axis = directLabelAxis(opts.axis);
|
|
768
785
|
const cross = finite('cross', opts.cross, 0);
|
|
769
|
-
const shape = opts.shape
|
|
786
|
+
const shape = directLabelShape(opts.shape);
|
|
770
787
|
|
|
771
788
|
const anchors = items.map((it) => ({
|
|
772
789
|
anchor: { x: finite('anchor.x', it?.anchor?.x), y: finite('anchor.y', it?.anchor?.y) },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["carousel.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["carousel.js"],"names":[],"mappings":"AA6HA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wCAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CAsJ3C"}
|
package/behaviors/carousel.js
CHANGED
|
@@ -5,8 +5,124 @@ import {
|
|
|
5
5
|
bindOnce,
|
|
6
6
|
scrollIntoViewSafe,
|
|
7
7
|
collectHosts,
|
|
8
|
+
closestSafe,
|
|
8
9
|
} from './internal.js';
|
|
9
10
|
|
|
11
|
+
const snapshotAttrs = (el) =>
|
|
12
|
+
Array.from(el.attributes, ({ name, value }) => ({
|
|
13
|
+
name,
|
|
14
|
+
value,
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const restoreAttrs = (el, attrs) => {
|
|
18
|
+
for (const { name } of Array.from(el.attributes)) el.removeAttribute(name);
|
|
19
|
+
for (const { name, value } of attrs) el.setAttribute(name, value);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const snapshotNode = (el, { html = false } = {}) =>
|
|
23
|
+
el
|
|
24
|
+
? {
|
|
25
|
+
el,
|
|
26
|
+
attrs: snapshotAttrs(el),
|
|
27
|
+
...(html ? { innerHTML: el.innerHTML } : {}),
|
|
28
|
+
}
|
|
29
|
+
: null;
|
|
30
|
+
|
|
31
|
+
const restoreNode = (state) => {
|
|
32
|
+
if (!state) return;
|
|
33
|
+
restoreAttrs(state.el, state.attrs);
|
|
34
|
+
if ('innerHTML' in state) state.el.innerHTML = state.innerHTML;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const clampIndex = (value, max) => Math.max(0, Math.min(max, value));
|
|
38
|
+
|
|
39
|
+
const renderedStatusIndex = (status) => {
|
|
40
|
+
const match = /^(\d+)\s*\/\s*\d+$/.exec(status?.textContent?.trim() ?? '');
|
|
41
|
+
if (!match) return -1;
|
|
42
|
+
const value = Number(match[1]);
|
|
43
|
+
return Number.isInteger(value) ? value - 1 : -1;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const snapshotCarouselState = ({ viewport, slides, status, prevBtn, nextBtn, thumbs }) => ({
|
|
47
|
+
viewport: snapshotNode(viewport),
|
|
48
|
+
slides: slides.map((slide) => snapshotNode(slide)),
|
|
49
|
+
status: snapshotNode(status, { html: true }),
|
|
50
|
+
controls: [prevBtn, nextBtn, ...thumbs].filter(Boolean).map((control) => snapshotNode(control)),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
function restoreCarouselState(state) {
|
|
54
|
+
restoreNode(state.viewport);
|
|
55
|
+
state.slides.forEach(restoreNode);
|
|
56
|
+
restoreNode(state.status);
|
|
57
|
+
state.controls.forEach(restoreNode);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function setDefaultButtonType(button) {
|
|
61
|
+
if (button?.tagName === 'BUTTON' && !button.hasAttribute('type')) button.type = 'button';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function applyCarouselA11y({ box, viewport, slides, status, prevBtn, nextBtn, thumbs, n }) {
|
|
65
|
+
// ARIA scaffolding — pragmatic carousel semantics (not the full APG
|
|
66
|
+
// tablist), the same restraint initMenu takes.
|
|
67
|
+
viewport.setAttribute('role', 'group');
|
|
68
|
+
viewport.setAttribute('aria-roledescription', 'carousel');
|
|
69
|
+
if (!viewport.hasAttribute('aria-label')) {
|
|
70
|
+
viewport.setAttribute(
|
|
71
|
+
'aria-label',
|
|
72
|
+
box.getAttribute('data-bronto-carousel-label') || 'Carousel',
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
if (!viewport.hasAttribute('tabindex')) viewport.tabIndex = 0;
|
|
76
|
+
slides.forEach((slide, i) => {
|
|
77
|
+
slide.setAttribute('role', 'group');
|
|
78
|
+
slide.setAttribute('aria-roledescription', 'slide');
|
|
79
|
+
if (!slide.hasAttribute('aria-label')) slide.setAttribute('aria-label', `${i + 1} of ${n}`);
|
|
80
|
+
});
|
|
81
|
+
if (status) status.setAttribute('aria-live', 'polite');
|
|
82
|
+
[prevBtn, nextBtn, ...thumbs].forEach(setDefaultButtonType);
|
|
83
|
+
if (prevBtn && !prevBtn.hasAttribute('aria-label'))
|
|
84
|
+
prevBtn.setAttribute('aria-label', 'Previous');
|
|
85
|
+
if (nextBtn && !nextBtn.hasAttribute('aria-label')) nextBtn.setAttribute('aria-label', 'Next');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function bindCarouselLifecycle({
|
|
89
|
+
box,
|
|
90
|
+
viewport,
|
|
91
|
+
slides,
|
|
92
|
+
status,
|
|
93
|
+
prevBtn,
|
|
94
|
+
nextBtn,
|
|
95
|
+
thumbs,
|
|
96
|
+
n,
|
|
97
|
+
render,
|
|
98
|
+
onKey,
|
|
99
|
+
onClick,
|
|
100
|
+
io,
|
|
101
|
+
holdProgrammatic,
|
|
102
|
+
clearProgrammaticTimer,
|
|
103
|
+
}) {
|
|
104
|
+
const state = snapshotCarouselState({ viewport, slides, status, prevBtn, nextBtn, thumbs });
|
|
105
|
+
applyCarouselA11y({ box, viewport, slides, status, prevBtn, nextBtn, thumbs, n });
|
|
106
|
+
render();
|
|
107
|
+
viewport.addEventListener('keydown', onKey);
|
|
108
|
+
box.addEventListener('click', onClick);
|
|
109
|
+
// Observe inside the add callback so observe/disconnect pair with the
|
|
110
|
+
// binding lifecycle: a re-init tears down the prior binding (which
|
|
111
|
+
// disconnects the old observer) before this starts, so two observers
|
|
112
|
+
// never watch the same slides — even for one tick.
|
|
113
|
+
if (io) {
|
|
114
|
+
holdProgrammatic();
|
|
115
|
+
slides.forEach((slide) => io.observe(slide));
|
|
116
|
+
}
|
|
117
|
+
return () => {
|
|
118
|
+
viewport.removeEventListener('keydown', onKey);
|
|
119
|
+
box.removeEventListener('click', onClick);
|
|
120
|
+
io?.disconnect();
|
|
121
|
+
clearProgrammaticTimer();
|
|
122
|
+
restoreCarouselState(state);
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
10
126
|
/**
|
|
11
127
|
* Image carousel / gallery, built on CSS scroll-snap so touch + trackpad
|
|
12
128
|
* swipe (and momentum) are the browser's, not hand-rolled. This wires the
|
|
@@ -54,36 +170,12 @@ export function initCarousel({ root } = {}) {
|
|
|
54
170
|
const nextBtn = box.querySelector('[data-bronto-carousel-next]');
|
|
55
171
|
const loop = box.hasAttribute('data-bronto-carousel-loop');
|
|
56
172
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
'aria-label',
|
|
64
|
-
box.getAttribute('data-bronto-carousel-label') || 'Carousel',
|
|
65
|
-
);
|
|
66
|
-
if (!viewport.hasAttribute('tabindex')) viewport.tabIndex = 0;
|
|
67
|
-
slides.forEach((s, i) => {
|
|
68
|
-
s.setAttribute('role', 'group');
|
|
69
|
-
s.setAttribute('aria-roledescription', 'slide');
|
|
70
|
-
if (!s.hasAttribute('aria-label')) s.setAttribute('aria-label', `${i + 1} of ${n}`);
|
|
71
|
-
});
|
|
72
|
-
if (status) status.setAttribute('aria-live', 'polite');
|
|
73
|
-
for (const b of [prevBtn, nextBtn]) {
|
|
74
|
-
if (!b) continue;
|
|
75
|
-
if (b.tagName === 'BUTTON' && !b.hasAttribute('type')) b.type = 'button';
|
|
76
|
-
}
|
|
77
|
-
for (const b of thumbs) {
|
|
78
|
-
if (b.tagName === 'BUTTON' && !b.hasAttribute('type')) b.type = 'button';
|
|
79
|
-
}
|
|
80
|
-
if (prevBtn && !prevBtn.hasAttribute('aria-label'))
|
|
81
|
-
prevBtn.setAttribute('aria-label', 'Previous');
|
|
82
|
-
if (nextBtn && !nextBtn.hasAttribute('aria-label')) nextBtn.setAttribute('aria-label', 'Next');
|
|
83
|
-
|
|
84
|
-
let index = Math.max(
|
|
85
|
-
0,
|
|
86
|
-
slides.findIndex((s) => s.hasAttribute('data-bronto-carousel-current')),
|
|
173
|
+
const authoredIndex = slides.findIndex((s) => s.hasAttribute('data-bronto-carousel-current'));
|
|
174
|
+
const renderedThumbIndex = thumbs.findIndex((t) => t.getAttribute('aria-current') === 'true');
|
|
175
|
+
const statusIndex = renderedStatusIndex(status);
|
|
176
|
+
let index = clampIndex(
|
|
177
|
+
renderedThumbIndex >= 0 ? renderedThumbIndex : statusIndex >= 0 ? statusIndex : authoredIndex,
|
|
178
|
+
n - 1,
|
|
87
179
|
);
|
|
88
180
|
|
|
89
181
|
// While a button/keyboard nav is smooth-scrolling, the IntersectionObserver
|
|
@@ -139,15 +231,15 @@ export function initCarousel({ root } = {}) {
|
|
|
139
231
|
goTo(target);
|
|
140
232
|
};
|
|
141
233
|
const onClick = (e) => {
|
|
142
|
-
if (prevBtn && e.target
|
|
234
|
+
if (prevBtn && closestSafe(e.target, '[data-bronto-carousel-prev]')) {
|
|
143
235
|
goTo(index - 1);
|
|
144
236
|
return;
|
|
145
237
|
}
|
|
146
|
-
if (nextBtn && e.target
|
|
238
|
+
if (nextBtn && closestSafe(e.target, '[data-bronto-carousel-next]')) {
|
|
147
239
|
goTo(index + 1);
|
|
148
240
|
return;
|
|
149
241
|
}
|
|
150
|
-
const thumb = e.target
|
|
242
|
+
const thumb = closestSafe(e.target, '.ui-carousel__thumb');
|
|
151
243
|
if (thumb) {
|
|
152
244
|
const i = thumbs.indexOf(thumb);
|
|
153
245
|
if (i >= 0) goTo(i);
|
|
@@ -181,22 +273,26 @@ export function initCarousel({ root } = {}) {
|
|
|
181
273
|
);
|
|
182
274
|
}
|
|
183
275
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
276
|
+
const bound = bindOnce(box, 'carousel', () =>
|
|
277
|
+
bindCarouselLifecycle({
|
|
278
|
+
box,
|
|
279
|
+
viewport,
|
|
280
|
+
slides,
|
|
281
|
+
status,
|
|
282
|
+
prevBtn,
|
|
283
|
+
nextBtn,
|
|
284
|
+
thumbs,
|
|
285
|
+
n,
|
|
286
|
+
render,
|
|
287
|
+
onKey,
|
|
288
|
+
onClick,
|
|
289
|
+
io,
|
|
290
|
+
holdProgrammatic,
|
|
291
|
+
clearProgrammaticTimer: () => {
|
|
292
|
+
if (progTimer) clearTimeout(progTimer);
|
|
293
|
+
},
|
|
294
|
+
}),
|
|
295
|
+
);
|
|
200
296
|
cleanups.push(bound);
|
|
201
297
|
}
|
|
202
298
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["combobox.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["combobox.js"],"names":[],"mappings":"AAmIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wCAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CA6O3C"}
|