@ponchia/ui 0.6.0 → 0.6.4
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 +82 -4
- package/README.md +1 -1
- package/annotations/index.d.ts.map +1 -1
- package/annotations/index.js +36 -33
- package/behaviors/carousel.d.ts +28 -0
- package/behaviors/carousel.d.ts.map +1 -0
- package/behaviors/carousel.js +3 -0
- package/behaviors/combobox.d.ts +40 -0
- package/behaviors/combobox.d.ts.map +1 -0
- package/behaviors/combobox.js +71 -20
- package/behaviors/command.d.ts +41 -0
- package/behaviors/command.d.ts.map +1 -0
- package/behaviors/command.js +9 -0
- package/behaviors/connectors.d.ts +17 -0
- package/behaviors/connectors.d.ts.map +1 -0
- package/behaviors/connectors.js +3 -0
- package/behaviors/crosshair.d.ts +42 -0
- package/behaviors/crosshair.d.ts.map +1 -0
- package/behaviors/crosshair.js +19 -1
- package/behaviors/dialog.d.ts +20 -0
- package/behaviors/dialog.d.ts.map +1 -0
- package/behaviors/dialog.js +3 -0
- package/behaviors/disclosure.d.ts +10 -0
- package/behaviors/disclosure.d.ts.map +1 -0
- package/behaviors/disclosure.js +3 -0
- package/behaviors/dismissible.d.ts +10 -0
- package/behaviors/dismissible.d.ts.map +1 -0
- package/behaviors/dismissible.js +3 -0
- package/behaviors/forms.d.ts +27 -0
- package/behaviors/forms.d.ts.map +1 -0
- package/behaviors/forms.js +18 -5
- package/behaviors/glyph.d.ts +21 -0
- package/behaviors/glyph.d.ts.map +1 -0
- package/behaviors/glyph.js +82 -4
- package/behaviors/index.d.ts +31 -237
- package/behaviors/index.d.ts.map +1 -0
- package/behaviors/index.js +17 -0
- package/behaviors/inert.d.ts +20 -0
- package/behaviors/inert.d.ts.map +1 -0
- package/behaviors/inert.js +46 -0
- package/behaviors/internal.d.ts +25 -0
- package/behaviors/internal.d.ts.map +1 -0
- package/behaviors/internal.js +30 -1
- package/behaviors/legend.d.ts +35 -0
- package/behaviors/legend.d.ts.map +1 -0
- package/behaviors/legend.js +9 -0
- package/behaviors/menu.d.ts +16 -0
- package/behaviors/menu.d.ts.map +1 -0
- package/behaviors/menu.js +3 -0
- package/behaviors/modal.d.ts +41 -0
- package/behaviors/modal.d.ts.map +1 -0
- package/behaviors/modal.js +124 -0
- package/behaviors/popover.d.ts +28 -0
- package/behaviors/popover.d.ts.map +1 -0
- package/behaviors/popover.js +17 -17
- package/behaviors/spotlight.d.ts +17 -0
- package/behaviors/spotlight.d.ts.map +1 -0
- package/behaviors/spotlight.js +3 -0
- package/behaviors/table.d.ts +36 -0
- package/behaviors/table.d.ts.map +1 -0
- package/behaviors/table.js +48 -8
- package/behaviors/tabs.d.ts +20 -0
- package/behaviors/tabs.d.ts.map +1 -0
- package/behaviors/tabs.js +3 -0
- package/behaviors/theme.d.ts +54 -0
- package/behaviors/theme.d.ts.map +1 -0
- package/behaviors/theme.js +17 -0
- package/behaviors/toast.d.ts +49 -0
- package/behaviors/toast.d.ts.map +1 -0
- package/behaviors/toast.js +34 -2
- package/classes/classes.json +747 -15
- package/classes/index.d.ts +118 -3
- package/classes/index.js +264 -66
- package/connectors/index.d.ts +12 -0
- package/connectors/index.d.ts.map +1 -1
- package/connectors/index.js +23 -2
- package/css/app.css +26 -0
- package/css/bullet.css +108 -0
- package/css/code.css +98 -0
- package/css/content.css +15 -2
- package/css/crosshair.css +7 -7
- package/css/diff.css +153 -0
- package/css/disclosure.css +18 -4
- package/css/dots.css +246 -9
- package/css/feedback.css +39 -7
- package/css/forms.css +71 -3
- package/css/legend.css +5 -2
- package/css/motion.css +79 -14
- package/css/overlay.css +59 -2
- package/css/primitives.css +67 -8
- package/css/report.css +43 -4
- package/css/sidenote.css +67 -0
- package/css/skins.css +9 -0
- package/css/spark.css +76 -0
- package/css/table.css +16 -3
- package/css/term.css +110 -0
- package/css/textref.css +63 -0
- package/css/toc.css +91 -0
- package/css/tokens.css +14 -1
- package/css/tree.css +134 -0
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -1
- package/dist/css/app.css +1 -1
- package/dist/css/bullet.css +1 -0
- package/dist/css/code.css +1 -0
- package/dist/css/content.css +1 -1
- package/dist/css/crosshair.css +1 -1
- package/dist/css/diff.css +1 -0
- package/dist/css/disclosure.css +1 -1
- package/dist/css/dots.css +1 -1
- package/dist/css/feedback.css +1 -1
- package/dist/css/forms.css +1 -1
- package/dist/css/legend.css +1 -1
- package/dist/css/motion.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/primitives.css +1 -1
- package/dist/css/report.css +1 -1
- package/dist/css/sidenote.css +1 -0
- package/dist/css/skins.css +1 -1
- package/dist/css/spark.css +1 -0
- package/dist/css/table.css +1 -1
- package/dist/css/term.css +1 -0
- package/dist/css/textref.css +1 -0
- package/dist/css/toc.css +1 -0
- package/dist/css/tokens.css +1 -1
- package/dist/css/tree.css +1 -0
- package/docs/annotations.md +39 -0
- package/docs/architecture.md +2 -3
- package/docs/bullet.md +78 -0
- package/docs/code.md +76 -0
- package/docs/d2.md +4 -3
- package/docs/diff.md +146 -0
- package/docs/dots.md +146 -0
- package/docs/glyphs.md +114 -0
- package/docs/legends.md +8 -4
- package/docs/mermaid.md +21 -4
- package/docs/reference.md +168 -8
- package/docs/reporting.md +49 -17
- package/docs/sidenote.md +64 -0
- package/docs/spark.md +78 -0
- package/docs/stability.md +1 -0
- package/docs/term.md +81 -0
- package/docs/textref.md +78 -0
- package/docs/theming.md +44 -5
- package/docs/toc.md +83 -0
- package/docs/tree.md +74 -0
- package/docs/usage.md +264 -23
- package/docs/vega.md +22 -3
- package/glyphs/glyphs.d.ts +61 -0
- package/glyphs/glyphs.js +600 -31
- package/llms.txt +169 -15
- package/package.json +51 -7
- package/qwik/index.d.ts +4 -2
- package/qwik/index.d.ts.map +1 -1
- package/qwik/index.js +10 -0
- package/react/index.d.ts +4 -2
- package/react/index.d.ts.map +1 -1
- package/react/index.js +6 -0
- package/solid/index.d.ts +6 -2
- package/solid/index.d.ts.map +1 -1
- package/solid/index.js +6 -0
- package/tokens/skins.js +22 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,87 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
|> **Versioning:** pre-1.0, breaking changes ship in the _minor_. Pin to the
|
|
4
|
+
|> minor — `~0.4.0` (equivalently `^0.4.0`) resolves to `>=0.4.0 <0.5.0`; a bare
|
|
5
|
+
|> `^0` / `*` wildcard does **not** protect you. See README → Versioning, and
|
|
6
|
+
|> the deprecation policy in CONTRIBUTING.md.
|
|
7
|
+
|
|
8
|
+
## 0.6.4 — 2026-06-08
|
|
9
|
+
|
|
10
|
+
Patch release for the dot-matrix expansion and static report hardening shipped
|
|
11
|
+
in #116. No breaking changes, no `MIGRATIONS.json` entry.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Dot-matrix/glyph expansion** — adds the generated glyph metadata surface,
|
|
16
|
+
docs, and contract tests for the expanded dot/readout vocabulary.
|
|
17
|
+
- **Report authoring guidance** — documents the static report grammar around
|
|
18
|
+
captions, alert bodies, table wrapping, and local/CDN asset handling.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **Static report print/layout behavior** — hardens report print margins and
|
|
23
|
+
table wrapping so standalone HTML reports and PDF exports degrade more
|
|
24
|
+
predictably across long tokens and normal prose.
|
|
25
|
+
|
|
26
|
+
## 0.6.3 — 2026-06-08
|
|
27
|
+
|
|
28
|
+
Patch release to publish the WebKit release fix after the `v0.6.1` and `v0.6.2`
|
|
29
|
+
tag runs failed before npm publish. No public API change, no class contract
|
|
30
|
+
change, no `MIGRATIONS.json` entry.
|
|
31
|
+
|
|
32
|
+
The 0.6.2 test-only diagnosis was incomplete: WebKit does not reliably honor
|
|
33
|
+
the unprefixed `user-select: none` on the generated line-number affordances.
|
|
34
|
+
The actual fix is CSS-side. `css/diff.css` and `css/code.css` now include the
|
|
35
|
+
legacy `-webkit-user-select: none` declaration alongside the standard property,
|
|
36
|
+
and the built `dist/css/diff.css` / `dist/css/code.css` leaves were regenerated.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- **Diff/code line numbers in WebKit** — `.ui-diff__ln`,
|
|
41
|
+
`.ui-diff__code::before`, and `.ui-code--numbered .ui-code__line::before`
|
|
42
|
+
now opt out of selection in WebKit as well as chromium/firefox.
|
|
43
|
+
|
|
44
|
+
### Internal
|
|
45
|
+
|
|
46
|
+
- **`test/e2e/diff.spec.mjs`** — reads the CSSOM `-webkit-user-select` value
|
|
47
|
+
before the standard property so the assertion verifies the prefixed WebKit
|
|
48
|
+
path directly.
|
|
49
|
+
|
|
50
|
+
## 0.6.2 — 2026-06-07
|
|
51
|
+
|
|
52
|
+
Release attempt: test-only WebKit e2e patch for the `0.6.1` publish blocker. The
|
|
53
|
+
tag was cut but the release still did not publish. The diagnosis here was
|
|
54
|
+
superseded by `0.6.3`, which fixes the CSS rule itself.
|
|
55
|
+
|
|
56
|
+
### Internal
|
|
57
|
+
|
|
58
|
+
- **`test/e2e/diff.spec.mjs`** — read `getComputedStyle(el).userSelect ||
|
|
59
|
+
getComputedStyle(el).webkitUserSelect` for the line-number
|
|
60
|
+
`user-select: none` assertion, so the test passes on WebKit (where
|
|
61
|
+
`userSelect` is `undefined` even when the standard CSS rule is
|
|
62
|
+
applied) as well as chromium + firefox.
|
|
63
|
+
|
|
64
|
+
## 0.6.1 — 2026-06-07
|
|
65
|
+
|
|
66
|
+
Dev-only patch: refreshes the SHA-pinned GitHub Actions used by CI
|
|
67
|
+
([`actions/checkout`](https://github.com/actions/checkout) 6.0.2 → 6.0.3 —
|
|
68
|
+
SHA-256 repository init fix, expanded SHA regex; and
|
|
69
|
+
[`github/codeql-action`](https://github.com/github/codeql-action) 4.36.0 →
|
|
70
|
+
4.36.2 — CLI version caching, exponential-backoff SARIF polling, CodeQL
|
|
71
|
+
bundle 2.25.6) plus a small DevDeps bump ([react](https://github.com/facebook/react)
|
|
72
|
+
/[react-dom](https://github.com/facebook/react) 19.2.6 → 19.2.7 — Server
|
|
73
|
+
Components `FormData` fix; [stylelint](https://github.com/stylelint/stylelint)
|
|
74
|
+
17.12.0 → 17.13.0). No public API, no published CSS/JS, no `MIGRATIONS.json`
|
|
75
|
+
entry. All bumps were authored by Dependabot and landed through #109 + #110.
|
|
76
|
+
|
|
77
|
+
### Internal
|
|
78
|
+
|
|
79
|
+
- Bump the **actions** Dependabot group: `actions/checkout` 6.0.2 → 6.0.3 and
|
|
80
|
+
`github/codeql-action` 4.36.0 → 4.36.2 (CI only, SHA-pinned in
|
|
81
|
+
`.github/workflows/*.yml`).
|
|
82
|
+
- Bump the **dev** Dependabot group: `react`/`react-dom` 19.2.6 → 19.2.7 and
|
|
83
|
+
`stylelint` 17.12.0 → 17.13.0 (devDependencies only — the package itself
|
|
84
|
+
ships zero runtime deps).
|
|
7
85
|
|
|
8
86
|
## 0.6.0 — 2026-06-03
|
|
9
87
|
|
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ and the accent is a spotlight, not a paint bucket. Because everything lives in a
|
|
|
41
41
|
single `@layer bronto`, your own un-layered CSS overrides the framework with no
|
|
42
42
|
specificity fight and no `!important`.
|
|
43
43
|
|
|
44
|
-
It ships a complete, accessible **standard component set
|
|
44
|
+
It ships a complete, accessible **standard component set**, but that's not where it competes — its differentiator is the opt-in **analytical & communication layer** sketched above. The line that holds it together: each primitive owns only its visual grammar and pure geometry — no chart engine, no state, no hit-testing. See **[docs/frontier-primitives.md](https://github.com/Ponchia/bronto-ui/blob/main/docs/frontier-primitives.md)** for the thesis.
|
|
45
45
|
|
|
46
46
|
## Install
|
|
47
47
|
|
|
@@ -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
|
@@ -211,25 +211,19 @@ import {
|
|
|
211
211
|
angleBetween,
|
|
212
212
|
// Shared scalar/geometry kernel — single source of truth (was copy-pasted,
|
|
213
213
|
// and the local clamp had silently diverged from the connectors one).
|
|
214
|
-
|
|
214
|
+
roundNumber,
|
|
215
215
|
finite,
|
|
216
216
|
dimension,
|
|
217
217
|
fmt,
|
|
218
218
|
point,
|
|
219
219
|
clamp,
|
|
220
|
+
rectPath,
|
|
220
221
|
} from '../connectors/index.js';
|
|
221
222
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return Object.is(rounded, -0) ? 0 : rounded;
|
|
225
|
-
}
|
|
226
|
-
|
|
223
|
+
// A circle subject is just a filled dot at (x, y) — delegate to the kernel's
|
|
224
|
+
// dotMark so the arc geometry/precision can't diverge. (code-quality audit Q5.)
|
|
227
225
|
function circlePathAt(x, y, radius) {
|
|
228
|
-
|
|
229
|
-
if (r === 0) return '';
|
|
230
|
-
return `M${point(x, y - r)}A${fmt(r)},${fmt(r)} 0 1 1 ${point(x, y + r)}A${fmt(r)},${fmt(
|
|
231
|
-
r,
|
|
232
|
-
)} 0 1 1 ${point(x, y - r)}Z`;
|
|
226
|
+
return dotMark({ x, y }, radius);
|
|
233
227
|
}
|
|
234
228
|
|
|
235
229
|
function samePoint(a, b) {
|
|
@@ -400,8 +394,8 @@ export function notePlacement({
|
|
|
400
394
|
const rect = noteRect(anchorX, anchorY, w, h, placement);
|
|
401
395
|
if (rect.left >= minX && rect.top >= minY && rect.right <= maxX && rect.bottom <= maxY) {
|
|
402
396
|
return {
|
|
403
|
-
dx:
|
|
404
|
-
dy:
|
|
397
|
+
dx: roundNumber(placement.dx),
|
|
398
|
+
dy: roundNumber(placement.dy),
|
|
405
399
|
align: placement.align,
|
|
406
400
|
valign: placement.valign,
|
|
407
401
|
transform: noteTransform({ ...placement, width: w, height: h }),
|
|
@@ -413,8 +407,8 @@ export function notePlacement({
|
|
|
413
407
|
const rect = noteRect(anchorX, anchorY, w, h, fallback);
|
|
414
408
|
const left = clamp(rect.left, minX, maxX - w);
|
|
415
409
|
const top = clamp(rect.top, minY, maxY - h);
|
|
416
|
-
const dx =
|
|
417
|
-
const dy =
|
|
410
|
+
const dx = roundNumber(left - anchorX);
|
|
411
|
+
const dy = roundNumber(top - anchorY);
|
|
418
412
|
return {
|
|
419
413
|
dx,
|
|
420
414
|
dy,
|
|
@@ -445,7 +439,7 @@ export function rectSubjectPath({ width, height, x, y, padding = 0 } = {}) {
|
|
|
445
439
|
const top = finite('y', y, -h / 2) - p;
|
|
446
440
|
const right = left + w + p * 2;
|
|
447
441
|
const bottom = top + h + p * 2;
|
|
448
|
-
return
|
|
442
|
+
return rectPath(left, top, right, bottom);
|
|
449
443
|
}
|
|
450
444
|
|
|
451
445
|
/**
|
|
@@ -586,7 +580,7 @@ export function evidenceMarkerPath({ x = 0, y = 0, width = 36, height = 36, padd
|
|
|
586
580
|
const top = cy - h / 2 - p;
|
|
587
581
|
const right = left + w + p * 2;
|
|
588
582
|
const bottom = top + h + p * 2;
|
|
589
|
-
return
|
|
583
|
+
return rectPath(left, top, right, bottom);
|
|
590
584
|
}
|
|
591
585
|
|
|
592
586
|
/**
|
|
@@ -658,6 +652,22 @@ export function connectorCurve(opts = {}) {
|
|
|
658
652
|
return curvePath(start, end, { curvature: 0.35 });
|
|
659
653
|
}
|
|
660
654
|
|
|
655
|
+
// subject.type → its path builder. A flat dispatch table (replaces an 11-arm
|
|
656
|
+
// if/else) keyed by the SubjectType union; an unknown type throws below. (Q10.)
|
|
657
|
+
const SUBJECT_BUILDERS = {
|
|
658
|
+
circle: circleSubjectPath,
|
|
659
|
+
rect: rectSubjectPath,
|
|
660
|
+
threshold: thresholdPath,
|
|
661
|
+
bracket: bracketSubjectPath,
|
|
662
|
+
band: bandSubjectPath,
|
|
663
|
+
slope: slopeSubjectPath,
|
|
664
|
+
compare: comparisonBracePath,
|
|
665
|
+
cluster: outlierClusterPath,
|
|
666
|
+
axis: axisThresholdPath,
|
|
667
|
+
timeline: timelineEventPath,
|
|
668
|
+
evidence: evidenceMarkerPath,
|
|
669
|
+
};
|
|
670
|
+
|
|
661
671
|
/**
|
|
662
672
|
* @param {AnnotationPartsOptions} [opts]
|
|
663
673
|
* @returns {AnnotationParts}
|
|
@@ -678,18 +688,11 @@ export function annotationParts(opts = {}) {
|
|
|
678
688
|
const note = noteTransform({ dx, dy });
|
|
679
689
|
let subject = '';
|
|
680
690
|
|
|
681
|
-
if (opts.subject
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
else if (opts.subject?.type === 'slope') subject = slopeSubjectPath(opts.subject);
|
|
687
|
-
else if (opts.subject?.type === 'compare') subject = comparisonBracePath(opts.subject);
|
|
688
|
-
else if (opts.subject?.type === 'cluster') subject = outlierClusterPath(opts.subject);
|
|
689
|
-
else if (opts.subject?.type === 'axis') subject = axisThresholdPath(opts.subject);
|
|
690
|
-
else if (opts.subject?.type === 'timeline') subject = timelineEventPath(opts.subject);
|
|
691
|
-
else if (opts.subject?.type === 'evidence') subject = evidenceMarkerPath(opts.subject);
|
|
692
|
-
else if (opts.subject != null) throw new TypeError('unsupported subject.type');
|
|
691
|
+
if (opts.subject != null) {
|
|
692
|
+
const build = SUBJECT_BUILDERS[opts.subject.type];
|
|
693
|
+
if (!build) throw new TypeError('unsupported subject.type');
|
|
694
|
+
subject = build(opts.subject);
|
|
695
|
+
}
|
|
693
696
|
|
|
694
697
|
return { transform, subject, connector, note };
|
|
695
698
|
}
|
|
@@ -736,7 +739,7 @@ export function declutterLabels(items, opts = {}) {
|
|
|
736
739
|
}
|
|
737
740
|
|
|
738
741
|
const out = new Array(nodes.length);
|
|
739
|
-
for (const n of nodes) out[n.index] =
|
|
742
|
+
for (const n of nodes) out[n.index] = roundNumber(n.pos);
|
|
740
743
|
return out;
|
|
741
744
|
}
|
|
742
745
|
|
|
@@ -782,9 +785,9 @@ export function directLabels(items, opts = {}) {
|
|
|
782
785
|
? ''
|
|
783
786
|
: connectorPath({ from: a.anchor, to: labelPoint, shape });
|
|
784
787
|
return {
|
|
785
|
-
x:
|
|
786
|
-
y:
|
|
787
|
-
anchor: { x:
|
|
788
|
+
x: roundNumber(labelPoint.x),
|
|
789
|
+
y: roundNumber(labelPoint.y),
|
|
790
|
+
anchor: { x: roundNumber(a.anchor.x), y: roundNumber(a.anchor.y) },
|
|
788
791
|
key: a.key,
|
|
789
792
|
d,
|
|
790
793
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image carousel / gallery, built on CSS scroll-snap so touch + trackpad
|
|
3
|
+
* swipe (and momentum) are the browser's, not hand-rolled. This wires the
|
|
4
|
+
* parts scroll-snap can't do alone: prev/next buttons, keyboard nav, a
|
|
5
|
+
* thumbnail strip, the position counter, and ARIA — keeping a JS index in
|
|
6
|
+
* sync with the scroll position both ways.
|
|
7
|
+
*
|
|
8
|
+
* Markup: `[data-bronto-carousel]` containing a `.ui-carousel__viewport`
|
|
9
|
+
* of `.ui-carousel__slide` children; optionally
|
|
10
|
+
* `[data-bronto-carousel-prev]` / `[data-bronto-carousel-next]` controls,
|
|
11
|
+
* a `.ui-carousel__thumbs` list of `.ui-carousel__thumb` buttons, and a
|
|
12
|
+
* `.ui-carousel__status` counter slot. Add `data-bronto-carousel-loop` to
|
|
13
|
+
* wrap at the ends, `data-bronto-carousel-label` to name the region.
|
|
14
|
+
*
|
|
15
|
+
* A full-screen **lightbox** is the same markup inside a native
|
|
16
|
+
* `<dialog class="ui-lightbox">` opened by {@link initDialog}: the
|
|
17
|
+
* `<dialog>` provides the top layer, focus-trap, Escape and focus-return,
|
|
18
|
+
* so this behavior never touches focus management.
|
|
19
|
+
*
|
|
20
|
+
* Emits `bronto:change` ({ detail: { index } }) on every index change
|
|
21
|
+
* (button, key, thumbnail, or swipe). SSR-safe, idempotent per carousel;
|
|
22
|
+
* returns a cleanup function.
|
|
23
|
+
*
|
|
24
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
25
|
+
* @returns {import('./internal.js').Cleanup}
|
|
26
|
+
*/
|
|
27
|
+
export function initCarousel({ root }?: import("./internal.js").DelegateOpts): import("./internal.js").Cleanup;
|
|
28
|
+
//# sourceMappingURL=carousel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["carousel.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wCAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CAuK3C"}
|
package/behaviors/carousel.js
CHANGED
|
@@ -29,6 +29,9 @@ import {
|
|
|
29
29
|
* Emits `bronto:change` ({ detail: { index } }) on every index change
|
|
30
30
|
* (button, key, thumbnail, or swipe). SSR-safe, idempotent per carousel;
|
|
31
31
|
* returns a cleanup function.
|
|
32
|
+
*
|
|
33
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
34
|
+
* @returns {import('./internal.js').Cleanup}
|
|
32
35
|
*/
|
|
33
36
|
export function initCarousel({ root } = {}) {
|
|
34
37
|
if (!hasDom()) return noop;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editable combobox with a filtered listbox popup, implementing the
|
|
3
|
+
* WAI-ARIA APG combobox pattern (the widget the framework most lacked
|
|
4
|
+
* and consumers most often build badly). Dependency-free, no
|
|
5
|
+
* positioning library — the list is CSS-anchored under the input.
|
|
6
|
+
*
|
|
7
|
+
* The input MUST have an accessible name — a `<label>`, `aria-label`, or
|
|
8
|
+
* `aria-labelledby` (a placeholder does not count). A nameless `role="combobox"`
|
|
9
|
+
* is a silent screen-reader failure, so the behavior warns at dev time when it
|
|
10
|
+
* finds one, and mirrors the input's name onto the listbox.
|
|
11
|
+
*
|
|
12
|
+
* Markup: `[data-bronto-combobox]` wrapping an `<input role="combobox">`
|
|
13
|
+
* (`.ui-combobox__input`) and a `<ul role="listbox">`
|
|
14
|
+
* (`.ui-combobox__list`) of `<li role="option">` (`.ui-combobox__option`,
|
|
15
|
+
* optional `data-value`). An optional `.ui-combobox__empty` (hidden at rest)
|
|
16
|
+
* shows when nothing matches. The behavior owns ids, `aria-expanded`,
|
|
17
|
+
* `aria-controls`, `aria-activedescendant`, roving active option,
|
|
18
|
+
* type-to-filter, full keyboard (Down/Up/Home/End/Enter/Escape/Tab),
|
|
19
|
+
* pointer select, and outside-click close. On select the **visible input shows
|
|
20
|
+
* the option's text label**, while the emitted `bronto:change` CustomEvent
|
|
21
|
+
* carries the option's `data-value` code: `{ detail: { value, label } }` (value
|
|
22
|
+
* falls back to the label when there is no `data-value`). SSR-safe, idempotent
|
|
23
|
+
* per instance; returns a cleanup function.
|
|
24
|
+
*
|
|
25
|
+
* Single-select APG deviations (intentional, for a filtering text combobox):
|
|
26
|
+
* ArrowDown on a CLOSED list opens + filters rather than pre-activating the
|
|
27
|
+
* first option, and Tab closes the list without committing the merely-highlighted
|
|
28
|
+
* option (only Enter/click commits). Both are safe for single-select.
|
|
29
|
+
*
|
|
30
|
+
* Options are read from the DOM at init; if you replace the listbox contents
|
|
31
|
+
* (e.g. async/remote results), either re-run initCombobox, or add
|
|
32
|
+
* `data-bronto-combobox-live` to the `[data-bronto-combobox]` host so a
|
|
33
|
+
* MutationObserver re-reads the options in place (opt-in — off by default so
|
|
34
|
+
* the common static case stays observer-free).
|
|
35
|
+
*
|
|
36
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
37
|
+
* @returns {import('./internal.js').Cleanup}
|
|
38
|
+
*/
|
|
39
|
+
export function initCombobox({ root }?: import("./internal.js").DelegateOpts): import("./internal.js").Cleanup;
|
|
40
|
+
//# sourceMappingURL=combobox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["combobox.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wCAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CAqO3C"}
|
package/behaviors/combobox.js
CHANGED
|
@@ -23,17 +23,29 @@ import {
|
|
|
23
23
|
* Markup: `[data-bronto-combobox]` wrapping an `<input role="combobox">`
|
|
24
24
|
* (`.ui-combobox__input`) and a `<ul role="listbox">`
|
|
25
25
|
* (`.ui-combobox__list`) of `<li role="option">` (`.ui-combobox__option`,
|
|
26
|
-
* optional `data-value`). An optional `.ui-combobox__empty`
|
|
27
|
-
* nothing matches. The behavior owns ids, `aria-expanded`,
|
|
26
|
+
* optional `data-value`). An optional `.ui-combobox__empty` (hidden at rest)
|
|
27
|
+
* shows when nothing matches. The behavior owns ids, `aria-expanded`,
|
|
28
28
|
* `aria-controls`, `aria-activedescendant`, roving active option,
|
|
29
29
|
* type-to-filter, full keyboard (Down/Up/Home/End/Enter/Escape/Tab),
|
|
30
|
-
* pointer select, and outside-click close
|
|
31
|
-
*
|
|
32
|
-
*
|
|
30
|
+
* pointer select, and outside-click close. On select the **visible input shows
|
|
31
|
+
* the option's text label**, while the emitted `bronto:change` CustomEvent
|
|
32
|
+
* carries the option's `data-value` code: `{ detail: { value, label } }` (value
|
|
33
|
+
* falls back to the label when there is no `data-value`). SSR-safe, idempotent
|
|
34
|
+
* per instance; returns a cleanup function.
|
|
35
|
+
*
|
|
36
|
+
* Single-select APG deviations (intentional, for a filtering text combobox):
|
|
37
|
+
* ArrowDown on a CLOSED list opens + filters rather than pre-activating the
|
|
38
|
+
* first option, and Tab closes the list without committing the merely-highlighted
|
|
39
|
+
* option (only Enter/click commits). Both are safe for single-select.
|
|
33
40
|
*
|
|
34
41
|
* Options are read from the DOM at init; if you replace the listbox contents
|
|
35
|
-
* (e.g. async/remote results)
|
|
36
|
-
*
|
|
42
|
+
* (e.g. async/remote results), either re-run initCombobox, or add
|
|
43
|
+
* `data-bronto-combobox-live` to the `[data-bronto-combobox]` host so a
|
|
44
|
+
* MutationObserver re-reads the options in place (opt-in — off by default so
|
|
45
|
+
* the common static case stays observer-free).
|
|
46
|
+
*
|
|
47
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
48
|
+
* @returns {import('./internal.js').Cleanup}
|
|
37
49
|
*/
|
|
38
50
|
export function initCombobox({ root } = {}) {
|
|
39
51
|
if (!hasDom()) return noop;
|
|
@@ -47,21 +59,28 @@ export function initCombobox({ root } = {}) {
|
|
|
47
59
|
const list = box.querySelector('[role="listbox"], .ui-combobox__list');
|
|
48
60
|
if (!input || !list) continue;
|
|
49
61
|
const empty = box.querySelector('.ui-combobox__empty');
|
|
50
|
-
const options = [...list.querySelectorAll('[role="option"], .ui-combobox__option')];
|
|
51
|
-
|
|
52
62
|
const listId = list.id || (list.id = `bronto-cb-list-${nextFieldUid()}`);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
63
|
+
// Re-readable so the opt-in MutationObserver (`data-bronto-combobox-live`)
|
|
64
|
+
// can pick up async/replaced option nodes without a full re-init. `visible`,
|
|
65
|
+
// `filter`, `move`, etc. close over this binding, so reassigning it is enough.
|
|
66
|
+
let options = [];
|
|
67
|
+
const syncOptions = () => {
|
|
68
|
+
options = [...list.querySelectorAll('[role="option"], .ui-combobox__option')];
|
|
69
|
+
options.forEach((o, i) => {
|
|
70
|
+
if (!o.id) o.id = `${listId}-opt-${i}`;
|
|
71
|
+
o.setAttribute('role', 'option');
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
syncOptions();
|
|
57
75
|
list.setAttribute('role', 'listbox');
|
|
58
76
|
// Give the listbox its own accessible name (a bare role=listbox is unnamed
|
|
59
|
-
// to a screen reader) by mirroring the input's name. (a11y review C30.)
|
|
77
|
+
// to a screen reader) by mirroring the input's REAL name. (a11y review C30.)
|
|
78
|
+
// The placeholder is deliberately NOT in this chain: the input warning below
|
|
79
|
+
// already rejects a placeholder as an inadequate name, so papering the
|
|
80
|
+
// listbox over with it would contradict that — if there's no real name the
|
|
81
|
+
// listbox stays unnamed and the warning is the signal. (component audit C28.)
|
|
60
82
|
if (!list.hasAttribute('aria-label') && !list.hasAttribute('aria-labelledby')) {
|
|
61
|
-
const name =
|
|
62
|
-
input.getAttribute('aria-label') ||
|
|
63
|
-
input.labels?.[0]?.textContent?.trim() ||
|
|
64
|
-
input.getAttribute('placeholder');
|
|
83
|
+
const name = input.getAttribute('aria-label') || input.labels?.[0]?.textContent?.trim();
|
|
65
84
|
if (name) list.setAttribute('aria-label', name);
|
|
66
85
|
}
|
|
67
86
|
// A `role="combobox"` with no accessible name is a silent AT failure. A
|
|
@@ -84,6 +103,15 @@ export function initCombobox({ root } = {}) {
|
|
|
84
103
|
input.setAttribute('aria-expanded', 'false');
|
|
85
104
|
input.setAttribute('autocomplete', 'off');
|
|
86
105
|
list.hidden = true;
|
|
106
|
+
// Hide the empty-state at rest: it must only appear once a filter yields no
|
|
107
|
+
// matches, never on an idle combobox. Without this an author who omits
|
|
108
|
+
// `hidden` on `.ui-combobox__empty` ships a box that reads "No matches"
|
|
109
|
+
// before the user has typed anything. (component audit C10.) Make it a
|
|
110
|
+
// status live region so its appearance is announced. (component audit C38.)
|
|
111
|
+
if (empty) {
|
|
112
|
+
empty.hidden = true;
|
|
113
|
+
if (!empty.hasAttribute('role')) empty.setAttribute('role', 'status');
|
|
114
|
+
}
|
|
87
115
|
|
|
88
116
|
let active = -1;
|
|
89
117
|
const visible = () => options.filter((o) => !o.hidden);
|
|
@@ -130,13 +158,19 @@ export function initCombobox({ root } = {}) {
|
|
|
130
158
|
};
|
|
131
159
|
|
|
132
160
|
const select = (opt) => {
|
|
133
|
-
input
|
|
161
|
+
// Show the human LABEL in the input; emit the `data-value` CODE in the
|
|
162
|
+
// event. The natural pattern is code in `data-value`, label in the text —
|
|
163
|
+
// putting the code in the visible input silently shows the user a raw code.
|
|
164
|
+
// (component audit C10.)
|
|
165
|
+
const label = opt.textContent.trim();
|
|
166
|
+
const value = opt.dataset.value ?? label;
|
|
167
|
+
input.value = label;
|
|
134
168
|
options.forEach((o) => o.setAttribute('aria-selected', String(o === opt)));
|
|
135
169
|
close();
|
|
136
170
|
input.focus();
|
|
137
171
|
box.dispatchEvent(
|
|
138
172
|
new CustomEvent('bronto:change', {
|
|
139
|
-
detail: { value
|
|
173
|
+
detail: { value, label },
|
|
140
174
|
bubbles: true,
|
|
141
175
|
}),
|
|
142
176
|
);
|
|
@@ -169,6 +203,15 @@ export function initCombobox({ root } = {}) {
|
|
|
169
203
|
return true;
|
|
170
204
|
};
|
|
171
205
|
|
|
206
|
+
// Live re-sync after the option nodes change under us. The active option may
|
|
207
|
+
// be gone, so drop it; re-filter against the current input only while open.
|
|
208
|
+
const relist = () => {
|
|
209
|
+
syncOptions();
|
|
210
|
+
active = -1;
|
|
211
|
+
setActive(null);
|
|
212
|
+
if (!list.hidden) filter();
|
|
213
|
+
};
|
|
214
|
+
|
|
172
215
|
const onInput = () => filter();
|
|
173
216
|
const onKey = (e) => {
|
|
174
217
|
switch (e.key) {
|
|
@@ -212,7 +255,15 @@ export function initCombobox({ root } = {}) {
|
|
|
212
255
|
input.addEventListener('keydown', onKey);
|
|
213
256
|
list.addEventListener('click', onOptionClick);
|
|
214
257
|
document.addEventListener('click', onDocClick);
|
|
258
|
+
// Opt-in: keep options in sync with a list mutated after init (async /
|
|
259
|
+
// remote results). Off by default so the common static case stays free.
|
|
260
|
+
const observer =
|
|
261
|
+
box.hasAttribute('data-bronto-combobox-live') && typeof MutationObserver === 'function'
|
|
262
|
+
? new MutationObserver(relist)
|
|
263
|
+
: null;
|
|
264
|
+
observer?.observe(list, { childList: true, subtree: true });
|
|
215
265
|
return () => {
|
|
266
|
+
observer?.disconnect();
|
|
216
267
|
input.removeEventListener('input', onInput);
|
|
217
268
|
input.removeEventListener('keydown', onKey);
|
|
218
269
|
list.removeEventListener('click', onOptionClick);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} CommandSelectDetail
|
|
3
|
+
* @property {string} value The chosen command's value.
|
|
4
|
+
* @property {string} label The chosen command's visible label.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Command palette — filter + keyboard-navigate a DOM-authored command list.
|
|
8
|
+
* The CSS shell (`.ui-command`) is opt-in; this wires the listbox behavior the
|
|
9
|
+
* shell needs. Bronto filters and navigates; the HOST owns the action registry,
|
|
10
|
+
* permission checks, routing, async effects, and command execution (it listens
|
|
11
|
+
* for `bronto:command:select`). There is no global Cmd/Ctrl+K — open the palette
|
|
12
|
+
* yourself (e.g. a `<dialog>` via `initDialog`).
|
|
13
|
+
*
|
|
14
|
+
* Markup: `[data-bronto-command]` wrapping an `<input>` (`.ui-command__input`)
|
|
15
|
+
* and a list (`.ui-command__list`) of `.ui-command__item` rows (optional
|
|
16
|
+
* `data-value`), interleaved with `.ui-command__group` labels and an optional
|
|
17
|
+
* `.ui-command__empty`. The behavior owns ids, `role=combobox/listbox/option`,
|
|
18
|
+
* `aria-activedescendant`, a roving active item, substring filtering (hiding
|
|
19
|
+
* empty groups), full keyboard (Down/Up/Home/End/Enter/Escape), and pointer
|
|
20
|
+
* select. It emits `bronto:command:select` ({ detail: { value, label } }) on
|
|
21
|
+
* choose and `bronto:command:close` on Escape. SSR-safe, idempotent per
|
|
22
|
+
* instance; returns a cleanup function.
|
|
23
|
+
*
|
|
24
|
+
* Items are read from the DOM at init; re-run initCommand after replacing the
|
|
25
|
+
* command list so filtering/navigation see the current nodes.
|
|
26
|
+
*
|
|
27
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
28
|
+
* @returns {import('./internal.js').Cleanup}
|
|
29
|
+
*/
|
|
30
|
+
export function initCommand({ root }?: import("./internal.js").DelegateOpts): import("./internal.js").Cleanup;
|
|
31
|
+
export type CommandSelectDetail = {
|
|
32
|
+
/**
|
|
33
|
+
* The chosen command's value.
|
|
34
|
+
*/
|
|
35
|
+
value: string;
|
|
36
|
+
/**
|
|
37
|
+
* The chosen command's visible label.
|
|
38
|
+
*/
|
|
39
|
+
label: string;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["command.js"],"names":[],"mappings":"AAWA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,uCAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CA+J3C;;;;;WAzLa,MAAM;;;;WACN,MAAM"}
|
package/behaviors/command.js
CHANGED
|
@@ -9,6 +9,12 @@ import {
|
|
|
9
9
|
wrapIndex,
|
|
10
10
|
} from './internal.js';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {object} CommandSelectDetail
|
|
14
|
+
* @property {string} value The chosen command's value.
|
|
15
|
+
* @property {string} label The chosen command's visible label.
|
|
16
|
+
*/
|
|
17
|
+
|
|
12
18
|
/**
|
|
13
19
|
* Command palette — filter + keyboard-navigate a DOM-authored command list.
|
|
14
20
|
* The CSS shell (`.ui-command`) is opt-in; this wires the listbox behavior the
|
|
@@ -29,6 +35,9 @@ import {
|
|
|
29
35
|
*
|
|
30
36
|
* Items are read from the DOM at init; re-run initCommand after replacing the
|
|
31
37
|
* command list so filtering/navigation see the current nodes.
|
|
38
|
+
*
|
|
39
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
40
|
+
* @returns {import('./internal.js').Cleanup}
|
|
32
41
|
*/
|
|
33
42
|
export function initCommand({ root } = {}) {
|
|
34
43
|
if (!hasDom()) return noop;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Draw + keep leader lines in sync. Each `[data-bronto-connector]` is an
|
|
3
|
+
* `.ui-connector` SVG overlaying a positioned container; `data-from`/`data-to`
|
|
4
|
+
* are the ids of the elements to connect. Optional `data-shape`
|
|
5
|
+
* (`straight`|`elbow`|`curve`), `data-from-side`/`data-to-side`
|
|
6
|
+
* (`top`|`right`|`bottom`|`left`|`center`), and `data-end` (`arrow`|`dot`|`none`).
|
|
7
|
+
*
|
|
8
|
+
* Bronto computes the geometry (the pure `@ponchia/ui/connectors` helpers) and
|
|
9
|
+
* sets the path; it owns no layout. Redraws on resize/scroll via a
|
|
10
|
+
* ResizeObserver + listeners. SSR-safe, idempotent per host; returns a cleanup
|
|
11
|
+
* that disconnects everything. Re-run after adding/removing connectors.
|
|
12
|
+
*
|
|
13
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
14
|
+
* @returns {import('./internal.js').Cleanup}
|
|
15
|
+
*/
|
|
16
|
+
export function initConnectors({ root }?: import("./internal.js").DelegateOpts): import("./internal.js").Cleanup;
|
|
17
|
+
//# sourceMappingURL=connectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectors.d.ts","sourceRoot":"","sources":["connectors.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;GAcG;AACH,0CAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CA+E3C"}
|
package/behaviors/connectors.js
CHANGED
|
@@ -14,6 +14,9 @@ const SVGNS = 'http://www.w3.org/2000/svg';
|
|
|
14
14
|
* sets the path; it owns no layout. Redraws on resize/scroll via a
|
|
15
15
|
* ResizeObserver + listeners. SSR-safe, idempotent per host; returns a cleanup
|
|
16
16
|
* that disconnects everything. Re-run after adding/removing connectors.
|
|
17
|
+
*
|
|
18
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
19
|
+
* @returns {import('./internal.js').Cleanup}
|
|
17
20
|
*/
|
|
18
21
|
export function initConnectors({ root } = {}) {
|
|
19
22
|
if (!hasDom()) return noop;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} CrosshairMoveDetail
|
|
3
|
+
* @property {number} x Pointer x within the plot, in pixels.
|
|
4
|
+
* @property {number} y Pointer y within the plot, in pixels.
|
|
5
|
+
* @property {number} fx Pointer x as a 0..1 fraction of the plot width.
|
|
6
|
+
* @property {number} fy Pointer y as a 0..1 fraction of the plot height.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Track the pointer over a plot and drive a crosshair. Each
|
|
10
|
+
* `[data-bronto-crosshair]` is the plot; it contains a `.ui-crosshair` overlay.
|
|
11
|
+
* On pointer move the behavior sets `--crosshair-x/y` (pixels within the plot)
|
|
12
|
+
* on the overlay, marks it `.is-active`, and dispatches
|
|
13
|
+
* `bronto:crosshair:move` with `{ x, y, fx, fy }` (px + 0..1 fractions);
|
|
14
|
+
* `bronto:crosshair:leave` on exit.
|
|
15
|
+
*
|
|
16
|
+
* Bronto reports WHERE the pointer is — it does not find the nearest datum or
|
|
17
|
+
* map pixels to data values (that needs the host's scales). SSR-safe,
|
|
18
|
+
* idempotent per plot; returns a cleanup function.
|
|
19
|
+
*
|
|
20
|
+
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
21
|
+
* @returns {import('./internal.js').Cleanup}
|
|
22
|
+
*/
|
|
23
|
+
export function initCrosshair({ root }?: import("./internal.js").DelegateOpts): import("./internal.js").Cleanup;
|
|
24
|
+
export type CrosshairMoveDetail = {
|
|
25
|
+
/**
|
|
26
|
+
* Pointer x within the plot, in pixels.
|
|
27
|
+
*/
|
|
28
|
+
x: number;
|
|
29
|
+
/**
|
|
30
|
+
* Pointer y within the plot, in pixels.
|
|
31
|
+
*/
|
|
32
|
+
y: number;
|
|
33
|
+
/**
|
|
34
|
+
* Pointer x as a 0..1 fraction of the plot width.
|
|
35
|
+
*/
|
|
36
|
+
fx: number;
|
|
37
|
+
/**
|
|
38
|
+
* Pointer y as a 0..1 fraction of the plot height.
|
|
39
|
+
*/
|
|
40
|
+
fy: number;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=crosshair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crosshair.d.ts","sourceRoot":"","sources":["crosshair.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;GAcG;AACH,yCAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CAmD3C;;;;;OAtEa,MAAM;;;;OACN,MAAM;;;;QACN,MAAM;;;;QACN,MAAM"}
|