@expressivecss/expressive 0.9.1 → 0.10.0
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 +157 -1
- package/README.md +178 -25
- package/dist/css/expressive.css +365 -1222
- package/dist/css/expressive.css.map +1 -1
- package/dist/css/expressive.min.css +1 -1
- package/dist/css/expressive.min.css.map +1 -1
- package/dist/fonts/material-symbols-outlined.woff2 +0 -0
- package/dist/fonts/material-symbols-rounded.woff2 +0 -0
- package/dist/fonts/material-symbols-sharp.woff2 +0 -0
- package/dist/js/chunks/chunk-7MM4VJJO.mjs +509 -0
- package/dist/js/chunks/chunk-7MM4VJJO.mjs.map +7 -0
- package/dist/js/chunks/chunk-7UXHSYIA.mjs +183 -0
- package/dist/js/chunks/chunk-7UXHSYIA.mjs.map +7 -0
- package/dist/js/chunks/chunk-A3BJA7V4.mjs +28 -0
- package/dist/js/chunks/chunk-A3BJA7V4.mjs.map +7 -0
- package/dist/js/chunks/chunk-AOGFNMXS.mjs +691 -0
- package/dist/js/chunks/chunk-AOGFNMXS.mjs.map +7 -0
- package/dist/js/chunks/chunk-D4UZ4HFN.mjs +560 -0
- package/dist/js/chunks/chunk-D4UZ4HFN.mjs.map +7 -0
- package/dist/js/chunks/chunk-EP3CVKB5.mjs +88 -0
- package/dist/js/chunks/chunk-EP3CVKB5.mjs.map +7 -0
- package/dist/js/chunks/chunk-G576EP5O.mjs +459 -0
- package/dist/js/chunks/chunk-G576EP5O.mjs.map +7 -0
- package/dist/js/chunks/chunk-GY2Z5CJ2.mjs +320 -0
- package/dist/js/chunks/chunk-GY2Z5CJ2.mjs.map +7 -0
- package/dist/js/chunks/chunk-JKNPQQWY.mjs +191 -0
- package/dist/js/chunks/chunk-JKNPQQWY.mjs.map +7 -0
- package/dist/js/chunks/chunk-JNPIWFJT.mjs +365 -0
- package/dist/js/chunks/chunk-JNPIWFJT.mjs.map +7 -0
- package/dist/js/chunks/chunk-JODJAGFS.mjs +267 -0
- package/dist/js/chunks/chunk-JODJAGFS.mjs.map +7 -0
- package/dist/js/chunks/chunk-JR24UB4X.mjs +100 -0
- package/dist/js/chunks/chunk-JR24UB4X.mjs.map +7 -0
- package/dist/js/chunks/chunk-KR44BSYQ.mjs +55 -0
- package/dist/js/chunks/chunk-KR44BSYQ.mjs.map +7 -0
- package/dist/js/chunks/chunk-LZVBJ33S.mjs +102 -0
- package/dist/js/chunks/chunk-LZVBJ33S.mjs.map +7 -0
- package/dist/js/chunks/chunk-MISGHDUU.mjs +326 -0
- package/dist/js/chunks/chunk-MISGHDUU.mjs.map +7 -0
- package/dist/js/chunks/chunk-N3UHGN3N.mjs +175 -0
- package/dist/js/chunks/chunk-N3UHGN3N.mjs.map +7 -0
- package/dist/js/chunks/chunk-PB5L3EXF.mjs +7 -0
- package/dist/js/chunks/chunk-PB5L3EXF.mjs.map +7 -0
- package/dist/js/chunks/chunk-PIIAEYAJ.mjs +85 -0
- package/dist/js/chunks/chunk-PIIAEYAJ.mjs.map +7 -0
- package/dist/js/chunks/chunk-QSQ24FYT.mjs +59 -0
- package/dist/js/chunks/chunk-QSQ24FYT.mjs.map +7 -0
- package/dist/js/chunks/chunk-QYCYP443.mjs +1111 -0
- package/dist/js/chunks/chunk-QYCYP443.mjs.map +7 -0
- package/dist/js/chunks/chunk-SLFNPY5M.mjs +78 -0
- package/dist/js/chunks/chunk-SLFNPY5M.mjs.map +7 -0
- package/dist/js/chunks/chunk-TK6PX2GC.mjs +663 -0
- package/dist/js/chunks/chunk-TK6PX2GC.mjs.map +7 -0
- package/dist/js/chunks/chunk-TYM6U5DY.mjs +76 -0
- package/dist/js/chunks/chunk-TYM6U5DY.mjs.map +7 -0
- package/dist/js/chunks/chunk-TZZ24ZQS.mjs +154 -0
- package/dist/js/chunks/chunk-TZZ24ZQS.mjs.map +7 -0
- package/dist/js/chunks/chunk-VAS6JQ6P.mjs +94 -0
- package/dist/js/chunks/chunk-VAS6JQ6P.mjs.map +7 -0
- package/dist/js/chunks/chunk-WWPAPHMA.mjs +1 -0
- package/dist/js/chunks/chunk-WWPAPHMA.mjs.map +7 -0
- package/dist/js/chunks/chunk-XDB3G6RL.mjs +114 -0
- package/dist/js/chunks/chunk-XDB3G6RL.mjs.map +7 -0
- package/dist/js/chunks/chunk-XO5WX3TK.mjs +226 -0
- package/dist/js/chunks/chunk-XO5WX3TK.mjs.map +7 -0
- package/dist/js/chunks/chunk-YFXEJ7GR.mjs +286 -0
- package/dist/js/chunks/chunk-YFXEJ7GR.mjs.map +7 -0
- package/dist/js/chunks/chunk-ZIZVUWRL.mjs +120 -0
- package/dist/js/chunks/chunk-ZIZVUWRL.mjs.map +7 -0
- package/dist/js/chunks/chunk-ZZBZI2XN.mjs +338 -0
- package/dist/js/chunks/chunk-ZZBZI2XN.mjs.map +7 -0
- package/dist/js/expressive.cjs +747 -754
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +747 -754
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +11 -15
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +83 -7490
- package/dist/js/expressive.mjs.map +4 -4
- package/dist/js/internal/behaviors/bottomSheets.mjs +9 -0
- package/dist/js/internal/behaviors/bottomSheets.mjs.map +7 -0
- package/dist/js/internal/behaviors/dialogs.mjs +8 -0
- package/dist/js/internal/behaviors/dialogs.mjs.map +7 -0
- package/dist/js/internal/behaviors/forms.mjs +8 -0
- package/dist/js/internal/behaviors/forms.mjs.map +7 -0
- package/dist/js/internal/behaviors/sheetDrag.mjs +8 -0
- package/dist/js/internal/behaviors/sheetDrag.mjs.map +7 -0
- package/dist/js/internal/behaviors/sideSheets.mjs +9 -0
- package/dist/js/internal/behaviors/sideSheets.mjs.map +7 -0
- package/dist/js/internal/components/appBar.mjs +8 -0
- package/dist/js/internal/components/appBar.mjs.map +7 -0
- package/dist/js/internal/components/autocomplete.mjs +10 -0
- package/dist/js/internal/components/autocomplete.mjs.map +7 -0
- package/dist/js/internal/components/buttonGroup.mjs +8 -0
- package/dist/js/internal/components/buttonGroup.mjs.map +7 -0
- package/dist/js/internal/components/buttons.mjs +9 -0
- package/dist/js/internal/components/buttons.mjs.map +7 -0
- package/dist/js/internal/components/cards.mjs +13 -0
- package/dist/js/internal/components/cards.mjs.map +7 -0
- package/dist/js/internal/components/carousel.mjs +9 -0
- package/dist/js/internal/components/carousel.mjs.map +7 -0
- package/dist/js/internal/components/characterCounter.mjs +8 -0
- package/dist/js/internal/components/characterCounter.mjs.map +7 -0
- package/dist/js/internal/components/chips.mjs +11 -0
- package/dist/js/internal/components/chips.mjs.map +7 -0
- package/dist/js/internal/components/datepicker.mjs +12 -0
- package/dist/js/internal/components/datepicker.mjs.map +7 -0
- package/dist/js/internal/components/expandingCard.mjs +11 -0
- package/dist/js/internal/components/expandingCard.mjs.map +7 -0
- package/dist/js/internal/components/index.mjs +88 -0
- package/dist/js/internal/components/index.mjs.map +7 -0
- package/dist/js/internal/components/lightbox.mjs +9 -0
- package/dist/js/internal/components/lightbox.mjs.map +7 -0
- package/dist/js/internal/components/menu.mjs +9 -0
- package/dist/js/internal/components/menu.mjs.map +7 -0
- package/dist/js/internal/components/navigationRail.mjs +8 -0
- package/dist/js/internal/components/navigationRail.mjs.map +7 -0
- package/dist/js/internal/components/registry.mjs +33 -0
- package/dist/js/internal/components/registry.mjs.map +7 -0
- package/dist/js/internal/components/scrollspy.mjs +8 -0
- package/dist/js/internal/components/scrollspy.mjs.map +7 -0
- package/dist/js/internal/components/select.mjs +10 -0
- package/dist/js/internal/components/select.mjs.map +7 -0
- package/dist/js/internal/components/slider.mjs +9 -0
- package/dist/js/internal/components/slider.mjs.map +7 -0
- package/dist/js/internal/components/snackbar.mjs +8 -0
- package/dist/js/internal/components/snackbar.mjs.map +7 -0
- package/dist/js/internal/components/tabs.mjs +10 -0
- package/dist/js/internal/components/tabs.mjs.map +7 -0
- package/dist/js/internal/components/timepicker.mjs +10 -0
- package/dist/js/internal/components/timepicker.mjs.map +7 -0
- package/dist/js/internal/components/tooltip.mjs +9 -0
- package/dist/js/internal/components/tooltip.mjs.map +7 -0
- package/dist/js/internal/core/component.mjs +7 -0
- package/dist/js/internal/core/component.mjs.map +7 -0
- package/dist/js/internal/core/utils.mjs +7 -0
- package/dist/js/internal/core/utils.mjs.map +7 -0
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +8 -0
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs.map +7 -0
- package/dist/js/modular.mjs +113 -0
- package/dist/js/modular.mjs.map +7 -0
- package/dist/types/behaviors/sheetDrag.d.ts +1 -1
- package/dist/types/components/appBar.d.ts +1 -1
- package/dist/types/components/autocomplete.d.ts +9 -0
- package/dist/types/components/buttons.d.ts +4 -39
- package/dist/types/components/carousel.d.ts +10 -1
- package/dist/types/components/chips.d.ts +1 -0
- package/dist/types/components/datepicker.d.ts +7 -0
- package/dist/types/components/index.d.ts +0 -2
- package/dist/types/components/lightbox.d.ts +12 -0
- package/dist/types/components/menu.d.ts +3 -0
- package/dist/types/components/registry.d.ts +0 -4
- package/dist/types/components/select.d.ts +4 -0
- package/dist/types/components/slider.d.ts +2 -1
- package/dist/types/components/snackbar.d.ts +4 -2
- package/dist/types/components/tabs.d.ts +2 -1
- package/dist/types/components/timepicker.d.ts +5 -3
- package/dist/types/components/tooltip.d.ts +5 -3
- package/dist/types/index.d.ts +1 -8
- package/dist/types/modular.d.ts +28 -0
- package/package.json +16 -4
- package/src/sass/README.md +8 -0
- package/src/sass/components/_badges.scss +1 -6
- package/src/sass/components/_button-groups.scss +5 -1
- package/src/sass/components/_buttons.scss +8 -287
- package/src/sass/components/_chips.scss +17 -2
- package/src/sass/components/_dialog.scss +9 -4
- package/src/sass/components/_fab-menu.scss +11 -9
- package/src/sass/components/_icon-buttons.scss +0 -5
- package/src/sass/components/_index.scss +0 -5
- package/src/sass/components/_menu.scss +2 -2
- package/src/sass/components/_navigation-rail.scss +1 -1
- package/src/sass/components/_panes.scss +50 -78
- package/src/sass/components/_progress.scss +73 -13
- package/src/sass/components/_scrim.scss +4 -4
- package/src/sass/components/_side-sheet.scss +22 -12
- package/src/sass/components/_toolbar.scss +1 -4
- package/src/sass/components/_tooltip.scss +20 -2
- package/src/sass/components/forms/_input-fields.scss +5 -1
- package/src/sass/components/forms/_select.scss +1 -0
- package/src/sass/components/forms/_slider.scss +81 -25
- package/src/sass/custom.scss +38 -0
- package/dist/types/components/navigationDrawer.d.ts +0 -110
- package/src/sass/components/_banners.scss +0 -298
- package/src/sass/components/_bottom-app-bar.scss +0 -180
- package/src/sass/components/_floating-sheet.scss +0 -86
- package/src/sass/components/_navigation-drawer.scss +0 -476
- package/src/sass/components/_segmented-buttons.scss +0 -188
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
// src/ts/core/utils.ts
|
|
2
|
+
var _Utils = class _Utils {
|
|
3
|
+
/**
|
|
4
|
+
* Run `callback` once the document is parsed.
|
|
5
|
+
*
|
|
6
|
+
* The document-level behaviors all used a bare DOMContentLoaded listener,
|
|
7
|
+
* which never fires if the bundle is loaded after that event - an async or
|
|
8
|
+
* deferred script tag, or a dynamic import. Checking readyState first covers
|
|
9
|
+
* both orders.
|
|
10
|
+
*/
|
|
11
|
+
static onDocumentReady(callback) {
|
|
12
|
+
if (typeof document === "undefined") return;
|
|
13
|
+
if (document.readyState === "loading") {
|
|
14
|
+
document.addEventListener("DOMContentLoaded", callback, { once: true });
|
|
15
|
+
} else {
|
|
16
|
+
callback();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Generates a unique string identifier. Every caller prefixes the result and
|
|
21
|
+
* uses it as an element id, and a UUID is valid in that position.
|
|
22
|
+
*
|
|
23
|
+
* `randomUUID` is exposed only in secure contexts, and a dev server on a
|
|
24
|
+
* plain-HTTP LAN address - the usual way a page is opened on a phone - is
|
|
25
|
+
* not one. Without the fallback every component that stamps an id would
|
|
26
|
+
* throw there. The ids only have to be unique within one document, so the
|
|
27
|
+
* fallback does not need to be cryptographic.
|
|
28
|
+
*/
|
|
29
|
+
static guid() {
|
|
30
|
+
return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Where an element created at runtime has to be appended to stay in the same
|
|
34
|
+
* tree as `el`. A stylesheet adopted into a shadow root cannot match a node
|
|
35
|
+
* in the document, so a portal that lands on `document.body` is unstyled
|
|
36
|
+
* whenever its origin lives in a shadow root (adr/0002).
|
|
37
|
+
*
|
|
38
|
+
* Light-DOM elements still get `document.body`, which is what escapes an
|
|
39
|
+
* ancestor's `overflow: hidden` and stacking context. Inside a shadow root
|
|
40
|
+
* both hazards come back: the host's own ancestors still form the containing
|
|
41
|
+
* block, so a transformed ancestor re-anchors `position: fixed` and a
|
|
42
|
+
* positioned one re-anchors `position: absolute`.
|
|
43
|
+
*/
|
|
44
|
+
static portalRoot(el) {
|
|
45
|
+
const root = el.getRootNode();
|
|
46
|
+
return root.host ? root : document.body;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `getElementById` against the tree `el` lives in. The mirror of
|
|
50
|
+
* `portalRoot`: an id in a shadow root is invisible to
|
|
51
|
+
* `document.getElementById`, so a trigger and its target inside the same
|
|
52
|
+
* root could not find each other at all.
|
|
53
|
+
*
|
|
54
|
+
* Falls back to the document for a detached `el`, whose root is a plain
|
|
55
|
+
* element with no lookup of its own.
|
|
56
|
+
*/
|
|
57
|
+
static getElementById(el, id) {
|
|
58
|
+
const root = el.getRootNode();
|
|
59
|
+
return root.getElementById ? root.getElementById(id) : document.getElementById(id);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Checks for exceeded edges
|
|
63
|
+
* @param container Container element.
|
|
64
|
+
* @param bounding Bounding rect.
|
|
65
|
+
* @param offset Element offset.
|
|
66
|
+
*/
|
|
67
|
+
static checkWithinContainer(container, bounding, offset) {
|
|
68
|
+
const edges = {
|
|
69
|
+
top: false,
|
|
70
|
+
right: false,
|
|
71
|
+
bottom: false,
|
|
72
|
+
left: false
|
|
73
|
+
};
|
|
74
|
+
const containerRect = container.getBoundingClientRect();
|
|
75
|
+
const containerBottom = container === document.body ? Math.max(containerRect.bottom, window.innerHeight) : containerRect.bottom;
|
|
76
|
+
const scrollLeft = container.scrollLeft;
|
|
77
|
+
const scrollTop = container.scrollTop;
|
|
78
|
+
const scrolledX = bounding.left - scrollLeft;
|
|
79
|
+
const scrolledY = bounding.top - scrollTop;
|
|
80
|
+
if (scrolledX < containerRect.left + offset || scrolledX < offset) {
|
|
81
|
+
edges.left = true;
|
|
82
|
+
}
|
|
83
|
+
if (scrolledX + bounding.width > containerRect.right - offset || scrolledX + bounding.width > window.innerWidth - offset) {
|
|
84
|
+
edges.right = true;
|
|
85
|
+
}
|
|
86
|
+
if (scrolledY < containerRect.top + offset || scrolledY < offset) {
|
|
87
|
+
edges.top = true;
|
|
88
|
+
}
|
|
89
|
+
if (scrolledY + bounding.height > containerBottom - offset || scrolledY + bounding.height > window.innerHeight - offset) {
|
|
90
|
+
edges.bottom = true;
|
|
91
|
+
}
|
|
92
|
+
return edges;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Checks if element can be aligned in multiple directions.
|
|
96
|
+
* @param el Element to be inspected.
|
|
97
|
+
* @param container Container element.
|
|
98
|
+
* @param bounding Bounding rect.
|
|
99
|
+
* @param offset Element offset.
|
|
100
|
+
*/
|
|
101
|
+
static checkPossibleAlignments(el, container, bounding, offset) {
|
|
102
|
+
const canAlign = {
|
|
103
|
+
top: true,
|
|
104
|
+
right: true,
|
|
105
|
+
bottom: true,
|
|
106
|
+
left: true,
|
|
107
|
+
spaceOnTop: null,
|
|
108
|
+
spaceOnRight: null,
|
|
109
|
+
spaceOnBottom: null,
|
|
110
|
+
spaceOnLeft: null
|
|
111
|
+
};
|
|
112
|
+
const containerAllowsOverflow = getComputedStyle(container).overflow === "visible";
|
|
113
|
+
const containerRect = container.getBoundingClientRect();
|
|
114
|
+
const containerHeight = Math.min(containerRect.height, window.innerHeight);
|
|
115
|
+
const containerWidth = Math.min(containerRect.width, window.innerWidth);
|
|
116
|
+
const elOffsetRect = el.getBoundingClientRect();
|
|
117
|
+
const scrollLeft = container.scrollLeft;
|
|
118
|
+
const scrollTop = container.scrollTop;
|
|
119
|
+
const scrolledX = bounding.left - scrollLeft;
|
|
120
|
+
const scrolledYTopEdge = bounding.top - scrollTop;
|
|
121
|
+
const scrolledYBottomEdge = bounding.top + elOffsetRect.height - scrollTop;
|
|
122
|
+
canAlign.spaceOnRight = !containerAllowsOverflow ? containerWidth - (scrolledX + bounding.width) : window.innerWidth - (elOffsetRect.left + bounding.width);
|
|
123
|
+
if (canAlign.spaceOnRight < 0) {
|
|
124
|
+
canAlign.left = false;
|
|
125
|
+
}
|
|
126
|
+
canAlign.spaceOnLeft = !containerAllowsOverflow ? scrolledX - bounding.width + elOffsetRect.width : elOffsetRect.right - bounding.width;
|
|
127
|
+
if (canAlign.spaceOnLeft < 0) {
|
|
128
|
+
canAlign.right = false;
|
|
129
|
+
}
|
|
130
|
+
canAlign.spaceOnBottom = !containerAllowsOverflow ? containerHeight - (scrolledYTopEdge + bounding.height + offset) : window.innerHeight - (elOffsetRect.top + bounding.height + offset);
|
|
131
|
+
if (canAlign.spaceOnBottom < 0) {
|
|
132
|
+
canAlign.top = false;
|
|
133
|
+
}
|
|
134
|
+
canAlign.spaceOnTop = !containerAllowsOverflow ? scrolledYBottomEdge - (bounding.height - offset) : elOffsetRect.bottom - (bounding.height + offset);
|
|
135
|
+
if (canAlign.spaceOnTop < 0) {
|
|
136
|
+
canAlign.bottom = false;
|
|
137
|
+
}
|
|
138
|
+
return canAlign;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Retrieves target element id from trigger.
|
|
142
|
+
* @param trigger Trigger element.
|
|
143
|
+
*/
|
|
144
|
+
static getIdFromTrigger(trigger) {
|
|
145
|
+
let id = trigger.dataset.target;
|
|
146
|
+
if (!id) {
|
|
147
|
+
id = trigger.getAttribute("href");
|
|
148
|
+
return id ? id.slice(1) : "";
|
|
149
|
+
}
|
|
150
|
+
return id;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Retrieves document scroll postion from top.
|
|
154
|
+
*/
|
|
155
|
+
static getDocumentScrollTop() {
|
|
156
|
+
return window.scrollY;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Retrieves document scroll postion from left.
|
|
160
|
+
*/
|
|
161
|
+
static getDocumentScrollLeft() {
|
|
162
|
+
return window.scrollX;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Trailing-edge throttle: run `func` now, then at most once per `wait` ms
|
|
166
|
+
* with the most recent arguments.
|
|
167
|
+
*
|
|
168
|
+
* This used to carry its underscore ancestor's whole configuration - leading
|
|
169
|
+
* and trailing switches, a result passthrough - and both call sites are
|
|
170
|
+
* resize handlers passing nothing but a function and a delay.
|
|
171
|
+
*
|
|
172
|
+
* Assign the return value once. `x = Utils.throttle(fn, 200)` is right;
|
|
173
|
+
* wrapping it in an arrow builds a fresh closure per event and never calls
|
|
174
|
+
* it, which is how resize handling was dead in three components.
|
|
175
|
+
*/
|
|
176
|
+
static throttle(func, wait) {
|
|
177
|
+
let timeout = null;
|
|
178
|
+
let lastArgs = null;
|
|
179
|
+
let previous = 0;
|
|
180
|
+
return (...args) => {
|
|
181
|
+
const now = Date.now();
|
|
182
|
+
const remaining = wait - (now - previous);
|
|
183
|
+
if (remaining <= 0) {
|
|
184
|
+
clearTimeout(timeout);
|
|
185
|
+
timeout = null;
|
|
186
|
+
previous = now;
|
|
187
|
+
lastArgs = null;
|
|
188
|
+
func(...args);
|
|
189
|
+
} else if (!timeout) {
|
|
190
|
+
lastArgs = args;
|
|
191
|
+
timeout = setTimeout(() => {
|
|
192
|
+
previous = Date.now();
|
|
193
|
+
timeout = null;
|
|
194
|
+
func(...lastArgs ?? []);
|
|
195
|
+
lastArgs = null;
|
|
196
|
+
}, remaining);
|
|
197
|
+
} else {
|
|
198
|
+
lastArgs = args;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Renders confirm/close buttons with callback function
|
|
204
|
+
*/
|
|
205
|
+
static createConfirmationContainer(container, confirmText, cancelText, onConfirm, onCancel) {
|
|
206
|
+
const confirmationButtonsContainer = document.createElement("div");
|
|
207
|
+
confirmationButtonsContainer.classList.add("confirmation-btns");
|
|
208
|
+
container.append(confirmationButtonsContainer);
|
|
209
|
+
this.createButton(confirmationButtonsContainer, cancelText, ["btn-cancel"], true, onCancel);
|
|
210
|
+
this.createButton(confirmationButtonsContainer, confirmText, ["btn-confirm"], true, onConfirm);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Renders a button with optional callback function
|
|
214
|
+
*/
|
|
215
|
+
static createButton(container, text, className = [], visibility = true, callback = null) {
|
|
216
|
+
className = className.concat(["text"]);
|
|
217
|
+
const button = document.createElement("button");
|
|
218
|
+
button.className = className.join(" ");
|
|
219
|
+
button.style.visibility = visibility ? "visible" : "hidden";
|
|
220
|
+
button.type = "button";
|
|
221
|
+
button.tabIndex = !!visibility ? 0 : -1;
|
|
222
|
+
button.innerText = text;
|
|
223
|
+
if (typeof callback === "function") {
|
|
224
|
+
button.addEventListener("click", callback);
|
|
225
|
+
button.addEventListener("keypress", (e) => {
|
|
226
|
+
if (e.key === _Utils.keys.ENTER) callback(e);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
container.append(button);
|
|
230
|
+
}
|
|
231
|
+
static _setAbsolutePosition(origin, container, position, margin, transitionMovement, align = "center") {
|
|
232
|
+
const originHeight = origin.offsetHeight, originWidth = origin.offsetWidth, containerHeight = container.offsetHeight, containerWidth = container.offsetWidth, originRect = origin.getBoundingClientRect();
|
|
233
|
+
let xMovement = 0, yMovement = 0, targetTop = originRect.top + _Utils.getDocumentScrollTop(), targetLeft = originRect.left + _Utils.getDocumentScrollLeft();
|
|
234
|
+
if (position === "top") {
|
|
235
|
+
targetTop += -containerHeight - margin;
|
|
236
|
+
if (align === "center") {
|
|
237
|
+
targetLeft += originWidth / 2 - containerWidth / 2;
|
|
238
|
+
}
|
|
239
|
+
yMovement = -transitionMovement;
|
|
240
|
+
} else if (position === "right") {
|
|
241
|
+
targetTop += originHeight / 2 - containerHeight / 2;
|
|
242
|
+
targetLeft = originWidth + margin;
|
|
243
|
+
xMovement = transitionMovement;
|
|
244
|
+
} else if (position === "left") {
|
|
245
|
+
targetTop += originHeight / 2 - containerHeight / 2;
|
|
246
|
+
targetLeft = -containerWidth - margin;
|
|
247
|
+
xMovement = -transitionMovement;
|
|
248
|
+
} else {
|
|
249
|
+
targetTop += originHeight + margin;
|
|
250
|
+
if (align === "center") {
|
|
251
|
+
targetLeft += originWidth / 2 - containerWidth / 2;
|
|
252
|
+
}
|
|
253
|
+
yMovement = transitionMovement;
|
|
254
|
+
}
|
|
255
|
+
if (align === "right") {
|
|
256
|
+
targetLeft += originWidth - containerWidth - margin;
|
|
257
|
+
}
|
|
258
|
+
const newCoordinates = _Utils._repositionWithinScreen(
|
|
259
|
+
targetLeft,
|
|
260
|
+
targetTop,
|
|
261
|
+
containerWidth,
|
|
262
|
+
containerHeight,
|
|
263
|
+
margin,
|
|
264
|
+
transitionMovement,
|
|
265
|
+
align
|
|
266
|
+
);
|
|
267
|
+
container.style.top = newCoordinates.y + "px";
|
|
268
|
+
container.style.left = newCoordinates.x + "px";
|
|
269
|
+
return { x: xMovement, y: yMovement };
|
|
270
|
+
}
|
|
271
|
+
static _repositionWithinScreen(x, y, width, height, margin, transitionMovement, align) {
|
|
272
|
+
const scrollLeft = _Utils.getDocumentScrollLeft();
|
|
273
|
+
const scrollTop = _Utils.getDocumentScrollTop();
|
|
274
|
+
let newX = x - scrollLeft;
|
|
275
|
+
let newY = y - scrollTop;
|
|
276
|
+
const bounding = {
|
|
277
|
+
left: newX,
|
|
278
|
+
top: newY,
|
|
279
|
+
width,
|
|
280
|
+
height
|
|
281
|
+
};
|
|
282
|
+
let offset;
|
|
283
|
+
if (align === "left" || align == "center") {
|
|
284
|
+
offset = margin + transitionMovement;
|
|
285
|
+
} else if (align === "right") {
|
|
286
|
+
offset = margin - transitionMovement;
|
|
287
|
+
}
|
|
288
|
+
const edges = _Utils.checkWithinContainer(document.body, bounding, offset);
|
|
289
|
+
if (edges.left) {
|
|
290
|
+
newX = offset;
|
|
291
|
+
} else if (edges.right) {
|
|
292
|
+
newX -= newX + width - window.innerWidth;
|
|
293
|
+
}
|
|
294
|
+
if (edges.top) {
|
|
295
|
+
newY = offset;
|
|
296
|
+
} else if (edges.bottom) {
|
|
297
|
+
newY -= newY + height - window.innerHeight;
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
x: newX + scrollLeft,
|
|
301
|
+
y: newY + scrollTop
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Key maps. One `KeyboardEvent.key` value each: the second entries these used
|
|
307
|
+
* to carry (`Esc`, `Up`, `Del`, ...) were IE and Edge Legacy spellings, and
|
|
308
|
+
* the support baseline excludes both.
|
|
309
|
+
*/
|
|
310
|
+
_Utils.keys = {
|
|
311
|
+
TAB: "Tab",
|
|
312
|
+
ENTER: "Enter",
|
|
313
|
+
ESC: "Escape",
|
|
314
|
+
BACKSPACE: "Backspace",
|
|
315
|
+
ARROW_UP: "ArrowUp",
|
|
316
|
+
ARROW_DOWN: "ArrowDown",
|
|
317
|
+
ARROW_LEFT: "ArrowLeft",
|
|
318
|
+
ARROW_RIGHT: "ArrowRight",
|
|
319
|
+
DELETE: "Delete"
|
|
320
|
+
};
|
|
321
|
+
var Utils = _Utils;
|
|
322
|
+
|
|
323
|
+
export {
|
|
324
|
+
Utils
|
|
325
|
+
};
|
|
326
|
+
//# sourceMappingURL=chunk-MISGHDUU.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/core/utils.ts"],
|
|
4
|
+
"sourcesContent": ["/** The part of a `DOMRect` the positioning helpers below actually read. */\ntype Bounding = Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>;\n\n/** Which edges of a container a box has crossed. */\ntype Edges = { top: boolean; right: boolean; bottom: boolean; left: boolean };\n\n/**\n * Class with utilitary functions for global usage.\n */\nexport class Utils {\n /**\n * Key maps. One `KeyboardEvent.key` value each: the second entries these used\n * to carry (`Esc`, `Up`, `Del`, ...) were IE and Edge Legacy spellings, and\n * the support baseline excludes both.\n */\n static keys = {\n TAB: 'Tab',\n ENTER: 'Enter',\n ESC: 'Escape',\n BACKSPACE: 'Backspace',\n ARROW_UP: 'ArrowUp',\n ARROW_DOWN: 'ArrowDown',\n ARROW_LEFT: 'ArrowLeft',\n ARROW_RIGHT: 'ArrowRight',\n DELETE: 'Delete'\n };\n\n /**\n * Run `callback` once the document is parsed.\n *\n * The document-level behaviors all used a bare DOMContentLoaded listener,\n * which never fires if the bundle is loaded after that event - an async or\n * deferred script tag, or a dynamic import. Checking readyState first covers\n * both orders.\n */\n static onDocumentReady(callback: () => void): void {\n if (typeof document === 'undefined') return;\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', callback, { once: true });\n } else {\n callback();\n }\n }\n\n /**\n * Generates a unique string identifier. Every caller prefixes the result and\n * uses it as an element id, and a UUID is valid in that position.\n *\n * `randomUUID` is exposed only in secure contexts, and a dev server on a\n * plain-HTTP LAN address - the usual way a page is opened on a phone - is\n * not one. Without the fallback every component that stamps an id would\n * throw there. The ids only have to be unique within one document, so the\n * fallback does not need to be cryptographic.\n */\n static guid(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n );\n }\n\n /**\n * Where an element created at runtime has to be appended to stay in the same\n * tree as `el`. A stylesheet adopted into a shadow root cannot match a node\n * in the document, so a portal that lands on `document.body` is unstyled\n * whenever its origin lives in a shadow root (adr/0002).\n *\n * Light-DOM elements still get `document.body`, which is what escapes an\n * ancestor's `overflow: hidden` and stacking context. Inside a shadow root\n * both hazards come back: the host's own ancestors still form the containing\n * block, so a transformed ancestor re-anchors `position: fixed` and a\n * positioned one re-anchors `position: absolute`.\n */\n static portalRoot(el: Node): HTMLElement | ShadowRoot {\n const root = el.getRootNode() as ShadowRoot;\n // Only a ShadowRoot has a host; a Document or a detached subtree does not.\n return root.host ? root : document.body;\n }\n\n /**\n * `getElementById` against the tree `el` lives in. The mirror of\n * `portalRoot`: an id in a shadow root is invisible to\n * `document.getElementById`, so a trigger and its target inside the same\n * root could not find each other at all.\n *\n * Falls back to the document for a detached `el`, whose root is a plain\n * element with no lookup of its own.\n */\n static getElementById(el: Node, id: string): HTMLElement {\n const root = el.getRootNode() as Document | ShadowRoot;\n return (root.getElementById ? root.getElementById(id) : document.getElementById(id)) as HTMLElement;\n }\n\n /**\n * Checks for exceeded edges\n * @param container Container element.\n * @param bounding Bounding rect.\n * @param offset Element offset.\n */\n static checkWithinContainer(container: HTMLElement, bounding: Bounding, offset: number): Edges {\n const edges = {\n top: false,\n right: false,\n bottom: false,\n left: false\n };\n\n const containerRect = container.getBoundingClientRect();\n // If body element is smaller than viewport, use viewport height instead.\n const containerBottom =\n container === document.body\n ? Math.max(containerRect.bottom, window.innerHeight)\n : containerRect.bottom;\n\n const scrollLeft = container.scrollLeft;\n const scrollTop = container.scrollTop;\n\n const scrolledX = bounding.left - scrollLeft;\n const scrolledY = bounding.top - scrollTop;\n\n // Check for container and viewport for each edge\n if (scrolledX < containerRect.left + offset || scrolledX < offset) {\n edges.left = true;\n }\n\n if (\n scrolledX + bounding.width > containerRect.right - offset ||\n scrolledX + bounding.width > window.innerWidth - offset\n ) {\n edges.right = true;\n }\n\n if (scrolledY < containerRect.top + offset || scrolledY < offset) {\n edges.top = true;\n }\n\n if (\n scrolledY + bounding.height > containerBottom - offset ||\n scrolledY + bounding.height > window.innerHeight - offset\n ) {\n edges.bottom = true;\n }\n\n return edges;\n }\n\n /**\n * Checks if element can be aligned in multiple directions.\n * @param el Element to be inspected.\n * @param container Container element.\n * @param bounding Bounding rect.\n * @param offset Element offset.\n */\n static checkPossibleAlignments(\n el: HTMLElement,\n container: HTMLElement,\n bounding: Bounding,\n offset: number\n ) {\n const canAlign: {\n top: boolean;\n right: boolean;\n bottom: boolean;\n left: boolean;\n spaceOnTop: number;\n spaceOnRight: number;\n spaceOnBottom: number;\n spaceOnLeft: number;\n } = {\n top: true,\n right: true,\n bottom: true,\n left: true,\n spaceOnTop: null,\n spaceOnRight: null,\n spaceOnBottom: null,\n spaceOnLeft: null\n };\n\n const containerAllowsOverflow = getComputedStyle(container).overflow === 'visible';\n const containerRect = container.getBoundingClientRect();\n const containerHeight = Math.min(containerRect.height, window.innerHeight);\n const containerWidth = Math.min(containerRect.width, window.innerWidth);\n const elOffsetRect = el.getBoundingClientRect();\n\n const scrollLeft = container.scrollLeft;\n const scrollTop = container.scrollTop;\n\n const scrolledX = bounding.left - scrollLeft;\n const scrolledYTopEdge = bounding.top - scrollTop;\n const scrolledYBottomEdge = bounding.top + elOffsetRect.height - scrollTop;\n\n // Check for container and viewport for left\n canAlign.spaceOnRight = !containerAllowsOverflow\n ? containerWidth - (scrolledX + bounding.width)\n : window.innerWidth - (elOffsetRect.left + bounding.width);\n if (canAlign.spaceOnRight < 0) {\n canAlign.left = false;\n }\n\n // Check for container and viewport for Right\n canAlign.spaceOnLeft = !containerAllowsOverflow\n ? scrolledX - bounding.width + elOffsetRect.width\n : elOffsetRect.right - bounding.width;\n if (canAlign.spaceOnLeft < 0) {\n canAlign.right = false;\n }\n\n // Check for container and viewport for Top\n canAlign.spaceOnBottom = !containerAllowsOverflow\n ? containerHeight - (scrolledYTopEdge + bounding.height + offset)\n : window.innerHeight - (elOffsetRect.top + bounding.height + offset);\n if (canAlign.spaceOnBottom < 0) {\n canAlign.top = false;\n }\n\n // Check for container and viewport for Bottom\n canAlign.spaceOnTop = !containerAllowsOverflow\n ? scrolledYBottomEdge - (bounding.height - offset)\n : elOffsetRect.bottom - (bounding.height + offset);\n if (canAlign.spaceOnTop < 0) {\n canAlign.bottom = false;\n }\n\n return canAlign;\n }\n\n /**\n * Retrieves target element id from trigger.\n * @param trigger Trigger element.\n */\n static getIdFromTrigger(trigger: HTMLElement): string {\n let id = trigger.dataset.target;\n if (!id) {\n id = trigger.getAttribute('href');\n return id ? id.slice(1) : '';\n }\n return id;\n }\n\n /**\n * Retrieves document scroll postion from top.\n */\n static getDocumentScrollTop(): number {\n return window.scrollY;\n }\n\n /**\n * Retrieves document scroll postion from left.\n */\n static getDocumentScrollLeft(): number {\n return window.scrollX;\n }\n\n /**\n * Trailing-edge throttle: run `func` now, then at most once per `wait` ms\n * with the most recent arguments.\n *\n * This used to carry its underscore ancestor's whole configuration - leading\n * and trailing switches, a result passthrough - and both call sites are\n * resize handlers passing nothing but a function and a delay.\n *\n * Assign the return value once. `x = Utils.throttle(fn, 200)` is right;\n * wrapping it in an arrow builds a fresh closure per event and never calls\n * it, which is how resize handling was dead in three components.\n */\n static throttle(func: (...args: unknown[]) => void, wait: number) {\n let timeout: ReturnType<typeof setTimeout> = null;\n let lastArgs: unknown[] = null;\n let previous = 0;\n\n return (...args: unknown[]) => {\n const now = Date.now();\n const remaining = wait - (now - previous);\n if (remaining <= 0) {\n clearTimeout(timeout);\n timeout = null;\n previous = now;\n lastArgs = null;\n func(...args);\n } else if (!timeout) {\n // The trailing call replays the most recent arguments; without this it\n // used to fire with none at all.\n lastArgs = args;\n timeout = setTimeout(() => {\n previous = Date.now();\n timeout = null;\n func(...(lastArgs ?? []));\n lastArgs = null;\n }, remaining);\n } else {\n lastArgs = args;\n }\n };\n }\n\n /**\n * Renders confirm/close buttons with callback function\n */\n static createConfirmationContainer(\n container: HTMLElement,\n confirmText: string,\n cancelText: string,\n onConfirm: (Function: object) => void,\n onCancel: (Function: object) => void\n ): void {\n const confirmationButtonsContainer = document.createElement('div');\n confirmationButtonsContainer.classList.add('confirmation-btns');\n container.append(confirmationButtonsContainer);\n\n this.createButton(confirmationButtonsContainer, cancelText, ['btn-cancel'], true, onCancel);\n this.createButton(confirmationButtonsContainer, confirmText, ['btn-confirm'], true, onConfirm);\n }\n\n /**\n * Renders a button with optional callback function\n */\n static createButton(\n container: HTMLElement,\n text: string,\n className: string[] = [],\n visibility: boolean = true,\n callback: (Function: object) => void = null\n ): void {\n className = className.concat(['text']);\n const button = document.createElement('button');\n button.className = className.join(' ');\n button.style.visibility = visibility ? 'visible' : 'hidden';\n button.type = 'button';\n button.tabIndex = !!visibility ? 0 : -1;\n button.innerText = text;\n // The keypress handler used to call `callback` unconditionally, so a\n // button created without one threw on Enter.\n if (typeof callback === 'function') {\n button.addEventListener('click', callback);\n button.addEventListener('keypress', (e) => {\n if (e.key === Utils.keys.ENTER) callback(e);\n });\n }\n container.append(button);\n }\n\n static _setAbsolutePosition(\n origin: HTMLElement,\n container: HTMLElement,\n position: string,\n margin: number,\n transitionMovement: number,\n align: string = 'center'\n ) {\n const originHeight = origin.offsetHeight,\n originWidth = origin.offsetWidth,\n containerHeight = container.offsetHeight,\n containerWidth = container.offsetWidth,\n originRect = origin.getBoundingClientRect(); // one rect, read twice below\n let xMovement = 0,\n yMovement = 0,\n targetTop = originRect.top + Utils.getDocumentScrollTop(),\n targetLeft = originRect.left + Utils.getDocumentScrollLeft();\n\n if (position === 'top') {\n targetTop += -containerHeight - margin;\n if (align === 'center') {\n targetLeft += originWidth / 2 - containerWidth / 2; // This is center align\n }\n yMovement = -transitionMovement;\n } else if (position === 'right') {\n targetTop += originHeight / 2 - containerHeight / 2;\n targetLeft = originWidth + margin;\n xMovement = transitionMovement;\n } else if (position === 'left') {\n targetTop += originHeight / 2 - containerHeight / 2;\n targetLeft = -containerWidth - margin;\n xMovement = -transitionMovement;\n } else {\n targetTop += originHeight + margin;\n if (align === 'center') {\n targetLeft += originWidth / 2 - containerWidth / 2; // This is center align\n }\n yMovement = transitionMovement;\n }\n if (align === 'right') {\n targetLeft += originWidth - containerWidth - margin;\n }\n\n const newCoordinates = Utils._repositionWithinScreen(\n targetLeft,\n targetTop,\n containerWidth,\n containerHeight,\n margin,\n transitionMovement,\n align\n );\n\n container.style.top = newCoordinates.y + 'px';\n container.style.left = newCoordinates.x + 'px';\n\n return {x: xMovement, y: yMovement};\n }\n\n static _repositionWithinScreen(\n x: number,\n y: number,\n width: number,\n height: number,\n margin: number,\n transitionMovement: number,\n align: string\n ) {\n const scrollLeft = Utils.getDocumentScrollLeft();\n const scrollTop = Utils.getDocumentScrollTop();\n let newX = x - scrollLeft;\n let newY = y - scrollTop;\n\n const bounding: Bounding = {\n left: newX,\n top: newY,\n width: width,\n height: height\n };\n let offset: number;\n if (align === 'left' || align == 'center') {\n offset = margin + transitionMovement;\n } else if (align === 'right') {\n offset = margin - transitionMovement;\n }\n const edges = Utils.checkWithinContainer(document.body, bounding, offset);\n\n if (edges.left) {\n newX = offset;\n } else if (edges.right) {\n newX -= newX + width - window.innerWidth;\n }\n if (edges.top) {\n newY = offset;\n } else if (edges.bottom) {\n newY -= newY + height - window.innerHeight;\n }\n return {\n x: newX + scrollLeft,\n y: newY + scrollTop\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Utils
|
|
3
|
+
} from "./chunk-MISGHDUU.mjs";
|
|
4
|
+
import {
|
|
5
|
+
Component
|
|
6
|
+
} from "./chunk-QSQ24FYT.mjs";
|
|
7
|
+
|
|
8
|
+
// src/ts/components/expandingCard.ts
|
|
9
|
+
var _defaults = {
|
|
10
|
+
onOpen: null,
|
|
11
|
+
onClose: null
|
|
12
|
+
};
|
|
13
|
+
var EXPANDING_CARD_SELECTOR = "article.expanding-card:has(> dialog.expanding-card-dialog)";
|
|
14
|
+
var ExpandingCard = class _ExpandingCard extends Component {
|
|
15
|
+
constructor(el, options) {
|
|
16
|
+
super(el, options, _ExpandingCard);
|
|
17
|
+
this.isOpen = false;
|
|
18
|
+
this.closeGeneration = 0;
|
|
19
|
+
this._setupEventHandlers = () => {
|
|
20
|
+
this.trigger?.addEventListener("click", this.open);
|
|
21
|
+
this.trigger?.addEventListener("keypress", this._handleTriggerKeypress);
|
|
22
|
+
this.closeButton?.addEventListener("click", this.close);
|
|
23
|
+
this.dialog?.addEventListener("cancel", this._handleCancel);
|
|
24
|
+
this.dialog?.addEventListener("close", this._handleNativeClose);
|
|
25
|
+
};
|
|
26
|
+
this._removeEventHandlers = () => {
|
|
27
|
+
this.trigger?.removeEventListener("click", this.open);
|
|
28
|
+
this.trigger?.removeEventListener("keypress", this._handleTriggerKeypress);
|
|
29
|
+
this.closeButton?.removeEventListener("click", this.close);
|
|
30
|
+
this.dialog?.removeEventListener("cancel", this._handleCancel);
|
|
31
|
+
this.dialog?.removeEventListener("close", this._handleNativeClose);
|
|
32
|
+
};
|
|
33
|
+
this._handleTriggerKeypress = (event) => {
|
|
34
|
+
if (event.key === Utils.keys.ENTER || event.key === " ") {
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
this.open();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
this._handleCancel = (event) => {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
this.close();
|
|
42
|
+
};
|
|
43
|
+
this._handleNativeClose = () => {
|
|
44
|
+
if (this.dialog.open) return;
|
|
45
|
+
this.closeGeneration++;
|
|
46
|
+
this.isOpen = false;
|
|
47
|
+
this.trigger.ariaExpanded = "false";
|
|
48
|
+
this.dialog.ariaExpanded = "false";
|
|
49
|
+
this.dialog.classList.remove("expanded");
|
|
50
|
+
};
|
|
51
|
+
this._setTransitionOrigin = () => {
|
|
52
|
+
if (!this.dialog) return;
|
|
53
|
+
const card = this.el.getBoundingClientRect();
|
|
54
|
+
const media = this.el.querySelector(
|
|
55
|
+
":scope > figure, :scope > img"
|
|
56
|
+
);
|
|
57
|
+
const mediaRect = media?.getBoundingClientRect();
|
|
58
|
+
this.dialog.style.setProperty(
|
|
59
|
+
"--md-comp-expanding-card-from-top",
|
|
60
|
+
`${Math.max(0, card.top)}px`
|
|
61
|
+
);
|
|
62
|
+
this.dialog.style.setProperty(
|
|
63
|
+
"--md-comp-expanding-card-from-right",
|
|
64
|
+
`${Math.max(0, window.innerWidth - card.right)}px`
|
|
65
|
+
);
|
|
66
|
+
this.dialog.style.setProperty(
|
|
67
|
+
"--md-comp-expanding-card-from-bottom",
|
|
68
|
+
`${Math.max(0, window.innerHeight - card.bottom)}px`
|
|
69
|
+
);
|
|
70
|
+
this.dialog.style.setProperty(
|
|
71
|
+
"--md-comp-expanding-card-from-left",
|
|
72
|
+
`${Math.max(0, card.left)}px`
|
|
73
|
+
);
|
|
74
|
+
this.dialog.style.setProperty(
|
|
75
|
+
"--md-comp-expanding-card-from-media-height",
|
|
76
|
+
`${Math.max(0, mediaRect?.height ?? 0)}px`
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
this.open = () => {
|
|
80
|
+
if (this.isOpen || !this.dialog || !this.trigger) return;
|
|
81
|
+
this.closeGeneration++;
|
|
82
|
+
this._setTransitionOrigin();
|
|
83
|
+
this.isOpen = true;
|
|
84
|
+
this.trigger.ariaExpanded = "true";
|
|
85
|
+
this.dialog.ariaExpanded = "true";
|
|
86
|
+
this.dialog.showModal();
|
|
87
|
+
void this.dialog.offsetWidth;
|
|
88
|
+
this.dialog.classList.add("expanded");
|
|
89
|
+
this.closeButton?.focus();
|
|
90
|
+
if (typeof this.options.onOpen === "function") {
|
|
91
|
+
this.options.onOpen.call(this, this.el);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
this.close = () => {
|
|
95
|
+
if (!this.isOpen || !this.dialog || !this.trigger) return;
|
|
96
|
+
const generation = ++this.closeGeneration;
|
|
97
|
+
this._setTransitionOrigin();
|
|
98
|
+
this.isOpen = false;
|
|
99
|
+
this.trigger.ariaExpanded = "false";
|
|
100
|
+
this.dialog.ariaExpanded = "false";
|
|
101
|
+
this.dialog.classList.remove("expanded");
|
|
102
|
+
if (typeof this.options.onClose === "function") {
|
|
103
|
+
this.options.onClose.call(this, this.el);
|
|
104
|
+
}
|
|
105
|
+
const finish = () => {
|
|
106
|
+
if (generation !== this.closeGeneration || this.isOpen || !this.dialog.open) return;
|
|
107
|
+
this.dialog.close();
|
|
108
|
+
if (this.dialog.isConnected && this.trigger.isConnected) this.trigger.focus();
|
|
109
|
+
};
|
|
110
|
+
const reducedMotion = window.matchMedia(
|
|
111
|
+
"(prefers-reduced-motion: reduce)"
|
|
112
|
+
).matches;
|
|
113
|
+
const transitions = reducedMotion ? [] : (this.dialog.getAnimations?.() ?? []).filter((animation) => animation.transitionProperty === "clip-path");
|
|
114
|
+
if (transitions.length === 0) finish();
|
|
115
|
+
else void Promise.allSettled(transitions.map((animation) => animation.finished)).then(finish);
|
|
116
|
+
};
|
|
117
|
+
this.el["Expressive_ExpandingCard"] = this;
|
|
118
|
+
this.options = {
|
|
119
|
+
..._ExpandingCard.defaults,
|
|
120
|
+
...options
|
|
121
|
+
};
|
|
122
|
+
this.dialog = this.el.querySelector(
|
|
123
|
+
":scope > dialog.expanding-card-dialog"
|
|
124
|
+
);
|
|
125
|
+
this.trigger = this.el.querySelector(
|
|
126
|
+
":scope > .expanding-card-trigger, :scope > figure > .expanding-card-trigger"
|
|
127
|
+
);
|
|
128
|
+
this.closeButton = this.dialog?.querySelector(".expanding-card-close") ?? null;
|
|
129
|
+
if (this.trigger && this.dialog) {
|
|
130
|
+
this.trigger.ariaExpanded = "false";
|
|
131
|
+
if (this.dialog.id)
|
|
132
|
+
this.trigger.setAttribute("aria-controls", this.dialog.id);
|
|
133
|
+
if (!this.trigger.matches("a[href], button, input, select, textarea")) {
|
|
134
|
+
this.trigger.tabIndex = 0;
|
|
135
|
+
this.trigger.setAttribute("role", "button");
|
|
136
|
+
}
|
|
137
|
+
this.dialog.ariaExpanded = "false";
|
|
138
|
+
this._setupEventHandlers();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
static get defaults() {
|
|
142
|
+
return _defaults;
|
|
143
|
+
}
|
|
144
|
+
static init(els, options) {
|
|
145
|
+
return super.init(els, options, _ExpandingCard);
|
|
146
|
+
}
|
|
147
|
+
static getInstance(el) {
|
|
148
|
+
return el["Expressive_ExpandingCard"];
|
|
149
|
+
}
|
|
150
|
+
destroy() {
|
|
151
|
+
this._removeEventHandlers();
|
|
152
|
+
this.closeGeneration++;
|
|
153
|
+
this.isOpen = false;
|
|
154
|
+
if (this.trigger) this.trigger.ariaExpanded = "false";
|
|
155
|
+
if (this.dialog) this.dialog.ariaExpanded = "false";
|
|
156
|
+
this.dialog?.classList.remove("expanded");
|
|
157
|
+
if (this.dialog?.open) this.dialog.close();
|
|
158
|
+
this.el["Expressive_ExpandingCard"] = void 0;
|
|
159
|
+
}
|
|
160
|
+
static Init() {
|
|
161
|
+
Utils.onDocumentReady(() => {
|
|
162
|
+
document.querySelectorAll(EXPANDING_CARD_SELECTOR).forEach((el) => {
|
|
163
|
+
if (el && el["Expressive_ExpandingCard"] == void 0) {
|
|
164
|
+
this.init(el);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export {
|
|
172
|
+
EXPANDING_CARD_SELECTOR,
|
|
173
|
+
ExpandingCard
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=chunk-N3UHGN3N.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/components/expandingCard.ts"],
|
|
4
|
+
"sourcesContent": ["import { Utils } from \"../core/utils\";\nimport {\n Component,\n BaseOptions,\n InitElements,\n InitElement,\n Openable,\n} from \"../core/component\";\n\nexport interface ExpandingCardOptions extends BaseOptions {\n onOpen: (el: Element) => void;\n onClose: (el: Element) => void;\n}\n\nconst _defaults: ExpandingCardOptions = {\n onOpen: null,\n onClose: null,\n};\n\nexport const EXPANDING_CARD_SELECTOR =\n \"article.expanding-card:has(> dialog.expanding-card-dialog)\";\n\n/**\n * Morphs a compact card into a full-screen modal detail surface.\n */\nexport class ExpandingCard\n extends Component<ExpandingCardOptions>\n implements Openable\n{\n isOpen: boolean = false;\n private readonly trigger: HTMLElement | null;\n private readonly dialog: HTMLDialogElement | null;\n private readonly closeButton: HTMLElement | null;\n private closeGeneration = 0;\n\n constructor(el: HTMLElement, options: Partial<ExpandingCardOptions>) {\n super(el, options, ExpandingCard);\n this.el[\"Expressive_ExpandingCard\"] = this;\n\n this.options = {\n ...ExpandingCard.defaults,\n ...options,\n };\n\n this.dialog = this.el.querySelector(\n \":scope > dialog.expanding-card-dialog\",\n );\n this.trigger = this.el.querySelector(\n \":scope > .expanding-card-trigger, :scope > figure > .expanding-card-trigger\",\n );\n this.closeButton =\n this.dialog?.querySelector(\".expanding-card-close\") ?? null;\n\n if (this.trigger && this.dialog) {\n this.trigger.ariaExpanded = \"false\";\n if (this.dialog.id)\n this.trigger.setAttribute(\"aria-controls\", this.dialog.id);\n if (!this.trigger.matches(\"a[href], button, input, select, textarea\")) {\n this.trigger.tabIndex = 0;\n this.trigger.setAttribute(\"role\", \"button\");\n }\n this.dialog.ariaExpanded = \"false\";\n this._setupEventHandlers();\n }\n }\n\n static get defaults(): ExpandingCardOptions {\n return _defaults;\n }\n\n static init(\n el: HTMLElement,\n options?: Partial<ExpandingCardOptions>,\n ): ExpandingCard;\n static init(\n els: InitElements<InitElement>,\n options?: Partial<ExpandingCardOptions>,\n ): ExpandingCard[];\n static init(\n els: HTMLElement | InitElements<InitElement>,\n options?: Partial<ExpandingCardOptions>,\n ): ExpandingCard | ExpandingCard[] {\n return super.init(els, options, ExpandingCard);\n }\n\n static getInstance(el: HTMLElement): ExpandingCard {\n return el[\"Expressive_ExpandingCard\"];\n }\n\n destroy() {\n this._removeEventHandlers();\n this.closeGeneration++;\n this.isOpen = false;\n if (this.trigger) this.trigger.ariaExpanded = \"false\";\n if (this.dialog) this.dialog.ariaExpanded = \"false\";\n this.dialog?.classList.remove(\"expanded\");\n if (this.dialog?.open) this.dialog.close();\n this.el[\"Expressive_ExpandingCard\"] = undefined;\n }\n\n private _setupEventHandlers = () => {\n this.trigger?.addEventListener(\"click\", this.open);\n this.trigger?.addEventListener(\"keypress\", this._handleTriggerKeypress);\n this.closeButton?.addEventListener(\"click\", this.close);\n this.dialog?.addEventListener(\"cancel\", this._handleCancel);\n this.dialog?.addEventListener(\"close\", this._handleNativeClose);\n };\n\n private _removeEventHandlers = () => {\n this.trigger?.removeEventListener(\"click\", this.open);\n this.trigger?.removeEventListener(\"keypress\", this._handleTriggerKeypress);\n this.closeButton?.removeEventListener(\"click\", this.close);\n this.dialog?.removeEventListener(\"cancel\", this._handleCancel);\n this.dialog?.removeEventListener(\"close\", this._handleNativeClose);\n };\n\n private _handleTriggerKeypress = (event: KeyboardEvent) => {\n if (event.key === Utils.keys.ENTER || event.key === \" \") {\n event.preventDefault();\n this.open();\n }\n };\n\n private _handleCancel = (event: Event) => {\n event.preventDefault();\n this.close();\n };\n\n private _handleNativeClose = () => {\n // A queued close event can arrive after a caller has reopened the dialog.\n if (this.dialog.open) return;\n this.closeGeneration++;\n this.isOpen = false;\n this.trigger.ariaExpanded = \"false\";\n this.dialog.ariaExpanded = \"false\";\n this.dialog.classList.remove(\"expanded\");\n };\n\n private _setTransitionOrigin = () => {\n if (!this.dialog) return;\n const card = this.el.getBoundingClientRect();\n const media = this.el.querySelector<HTMLElement>(\n \":scope > figure, :scope > img\",\n );\n const mediaRect = media?.getBoundingClientRect();\n\n this.dialog.style.setProperty(\n \"--md-comp-expanding-card-from-top\",\n `${Math.max(0, card.top)}px`,\n );\n this.dialog.style.setProperty(\n \"--md-comp-expanding-card-from-right\",\n `${Math.max(0, window.innerWidth - card.right)}px`,\n );\n this.dialog.style.setProperty(\n \"--md-comp-expanding-card-from-bottom\",\n `${Math.max(0, window.innerHeight - card.bottom)}px`,\n );\n this.dialog.style.setProperty(\n \"--md-comp-expanding-card-from-left\",\n `${Math.max(0, card.left)}px`,\n );\n this.dialog.style.setProperty(\n \"--md-comp-expanding-card-from-media-height\",\n `${Math.max(0, mediaRect?.height ?? 0)}px`,\n );\n };\n\n open: () => void = () => {\n if (this.isOpen || !this.dialog || !this.trigger) return;\n this.closeGeneration++;\n\n this._setTransitionOrigin();\n this.isOpen = true;\n this.trigger.ariaExpanded = \"true\";\n this.dialog.ariaExpanded = \"true\";\n this.dialog.showModal();\n // Commit the clipped start frame before asking CSS to expand it.\n void this.dialog.offsetWidth;\n this.dialog.classList.add(\"expanded\");\n this.closeButton?.focus();\n\n if (typeof this.options.onOpen === \"function\") {\n this.options.onOpen.call(this, this.el);\n }\n };\n\n close: () => void = () => {\n if (!this.isOpen || !this.dialog || !this.trigger) return;\n const generation = ++this.closeGeneration;\n this._setTransitionOrigin();\n this.isOpen = false;\n this.trigger.ariaExpanded = \"false\";\n this.dialog.ariaExpanded = \"false\";\n this.dialog.classList.remove(\"expanded\");\n\n if (typeof this.options.onClose === \"function\") {\n this.options.onClose.call(this, this.el);\n }\n\n const finish = () => {\n if (generation !== this.closeGeneration || this.isOpen || !this.dialog.open) return;\n this.dialog.close();\n if (this.dialog.isConnected && this.trigger.isConnected) this.trigger.focus();\n };\n const reducedMotion = window.matchMedia(\n \"(prefers-reduced-motion: reduce)\",\n ).matches;\n // Wait only for the container's actual clip transition, not arbitrary\n // animations in consumer content. Cancellation also completes cleanup.\n const transitions = reducedMotion ? [] : (this.dialog.getAnimations?.() ?? [])\n .filter((animation) => (animation as CSSTransition).transitionProperty === \"clip-path\");\n if (transitions.length === 0) finish();\n else void Promise.allSettled(transitions.map((animation) => animation.finished)).then(finish);\n };\n\n static Init() {\n Utils.onDocumentReady(() => {\n document.querySelectorAll(EXPANDING_CARD_SELECTOR).forEach((el) => {\n if (el && el[\"Expressive_ExpandingCard\"] == undefined) {\n this.init(el as HTMLElement);\n }\n });\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/ts/modular.ts"],
|
|
4
|
+
"sourcesContent": ["export * from './components';\nexport { Dialogs } from './behaviors/dialogs';\nexport { BottomSheets } from './behaviors/bottomSheets';\nexport { SideSheets } from './behaviors/sideSheets';\nexport { Forms } from './behaviors/forms';\nexport { AutoInit } from './components/registry';\nexport type { AutoInitOptions } from './components/registry';\n\nexport const version = '0.10.0';\n\nexport type * from './components/autocomplete';\nexport type * from './components/appBar';\nexport type * from './components/buttons';\nexport type * from './components/buttonGroup';\nexport type * from './components/cards';\nexport type * from './components/expandingCard';\nexport type * from './components/carousel';\nexport type * from './components/characterCounter';\nexport type * from './components/chips';\nexport type * from './components/datepicker';\nexport type * from './components/menu';\nexport type * from './components/lightbox';\nexport type * from './components/slider';\nexport type * from './components/scrollspy';\nexport type * from './components/select';\nexport type * from './components/navigationRail';\nexport type * from './components/tabs';\nexport type * from './components/timepicker';\nexport type * from './components/snackbar';\nexport type * from './components/tooltip';\n"],
|
|
5
|
+
"mappings": ";AAQO,IAAM,UAAU;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|