@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.
Files changed (188) hide show
  1. package/CHANGELOG.md +157 -1
  2. package/README.md +178 -25
  3. package/dist/css/expressive.css +365 -1222
  4. package/dist/css/expressive.css.map +1 -1
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -1
  7. package/dist/fonts/material-symbols-outlined.woff2 +0 -0
  8. package/dist/fonts/material-symbols-rounded.woff2 +0 -0
  9. package/dist/fonts/material-symbols-sharp.woff2 +0 -0
  10. package/dist/js/chunks/chunk-7MM4VJJO.mjs +509 -0
  11. package/dist/js/chunks/chunk-7MM4VJJO.mjs.map +7 -0
  12. package/dist/js/chunks/chunk-7UXHSYIA.mjs +183 -0
  13. package/dist/js/chunks/chunk-7UXHSYIA.mjs.map +7 -0
  14. package/dist/js/chunks/chunk-A3BJA7V4.mjs +28 -0
  15. package/dist/js/chunks/chunk-A3BJA7V4.mjs.map +7 -0
  16. package/dist/js/chunks/chunk-AOGFNMXS.mjs +691 -0
  17. package/dist/js/chunks/chunk-AOGFNMXS.mjs.map +7 -0
  18. package/dist/js/chunks/chunk-D4UZ4HFN.mjs +560 -0
  19. package/dist/js/chunks/chunk-D4UZ4HFN.mjs.map +7 -0
  20. package/dist/js/chunks/chunk-EP3CVKB5.mjs +88 -0
  21. package/dist/js/chunks/chunk-EP3CVKB5.mjs.map +7 -0
  22. package/dist/js/chunks/chunk-G576EP5O.mjs +459 -0
  23. package/dist/js/chunks/chunk-G576EP5O.mjs.map +7 -0
  24. package/dist/js/chunks/chunk-GY2Z5CJ2.mjs +320 -0
  25. package/dist/js/chunks/chunk-GY2Z5CJ2.mjs.map +7 -0
  26. package/dist/js/chunks/chunk-JKNPQQWY.mjs +191 -0
  27. package/dist/js/chunks/chunk-JKNPQQWY.mjs.map +7 -0
  28. package/dist/js/chunks/chunk-JNPIWFJT.mjs +365 -0
  29. package/dist/js/chunks/chunk-JNPIWFJT.mjs.map +7 -0
  30. package/dist/js/chunks/chunk-JODJAGFS.mjs +267 -0
  31. package/dist/js/chunks/chunk-JODJAGFS.mjs.map +7 -0
  32. package/dist/js/chunks/chunk-JR24UB4X.mjs +100 -0
  33. package/dist/js/chunks/chunk-JR24UB4X.mjs.map +7 -0
  34. package/dist/js/chunks/chunk-KR44BSYQ.mjs +55 -0
  35. package/dist/js/chunks/chunk-KR44BSYQ.mjs.map +7 -0
  36. package/dist/js/chunks/chunk-LZVBJ33S.mjs +102 -0
  37. package/dist/js/chunks/chunk-LZVBJ33S.mjs.map +7 -0
  38. package/dist/js/chunks/chunk-MISGHDUU.mjs +326 -0
  39. package/dist/js/chunks/chunk-MISGHDUU.mjs.map +7 -0
  40. package/dist/js/chunks/chunk-N3UHGN3N.mjs +175 -0
  41. package/dist/js/chunks/chunk-N3UHGN3N.mjs.map +7 -0
  42. package/dist/js/chunks/chunk-PB5L3EXF.mjs +7 -0
  43. package/dist/js/chunks/chunk-PB5L3EXF.mjs.map +7 -0
  44. package/dist/js/chunks/chunk-PIIAEYAJ.mjs +85 -0
  45. package/dist/js/chunks/chunk-PIIAEYAJ.mjs.map +7 -0
  46. package/dist/js/chunks/chunk-QSQ24FYT.mjs +59 -0
  47. package/dist/js/chunks/chunk-QSQ24FYT.mjs.map +7 -0
  48. package/dist/js/chunks/chunk-QYCYP443.mjs +1111 -0
  49. package/dist/js/chunks/chunk-QYCYP443.mjs.map +7 -0
  50. package/dist/js/chunks/chunk-SLFNPY5M.mjs +78 -0
  51. package/dist/js/chunks/chunk-SLFNPY5M.mjs.map +7 -0
  52. package/dist/js/chunks/chunk-TK6PX2GC.mjs +663 -0
  53. package/dist/js/chunks/chunk-TK6PX2GC.mjs.map +7 -0
  54. package/dist/js/chunks/chunk-TYM6U5DY.mjs +76 -0
  55. package/dist/js/chunks/chunk-TYM6U5DY.mjs.map +7 -0
  56. package/dist/js/chunks/chunk-TZZ24ZQS.mjs +154 -0
  57. package/dist/js/chunks/chunk-TZZ24ZQS.mjs.map +7 -0
  58. package/dist/js/chunks/chunk-VAS6JQ6P.mjs +94 -0
  59. package/dist/js/chunks/chunk-VAS6JQ6P.mjs.map +7 -0
  60. package/dist/js/chunks/chunk-WWPAPHMA.mjs +1 -0
  61. package/dist/js/chunks/chunk-WWPAPHMA.mjs.map +7 -0
  62. package/dist/js/chunks/chunk-XDB3G6RL.mjs +114 -0
  63. package/dist/js/chunks/chunk-XDB3G6RL.mjs.map +7 -0
  64. package/dist/js/chunks/chunk-XO5WX3TK.mjs +226 -0
  65. package/dist/js/chunks/chunk-XO5WX3TK.mjs.map +7 -0
  66. package/dist/js/chunks/chunk-YFXEJ7GR.mjs +286 -0
  67. package/dist/js/chunks/chunk-YFXEJ7GR.mjs.map +7 -0
  68. package/dist/js/chunks/chunk-ZIZVUWRL.mjs +120 -0
  69. package/dist/js/chunks/chunk-ZIZVUWRL.mjs.map +7 -0
  70. package/dist/js/chunks/chunk-ZZBZI2XN.mjs +338 -0
  71. package/dist/js/chunks/chunk-ZZBZI2XN.mjs.map +7 -0
  72. package/dist/js/expressive.cjs +747 -754
  73. package/dist/js/expressive.cjs.map +4 -4
  74. package/dist/js/expressive.js +747 -754
  75. package/dist/js/expressive.js.map +4 -4
  76. package/dist/js/expressive.min.js +11 -15
  77. package/dist/js/expressive.min.js.map +4 -4
  78. package/dist/js/expressive.mjs +83 -7490
  79. package/dist/js/expressive.mjs.map +4 -4
  80. package/dist/js/internal/behaviors/bottomSheets.mjs +9 -0
  81. package/dist/js/internal/behaviors/bottomSheets.mjs.map +7 -0
  82. package/dist/js/internal/behaviors/dialogs.mjs +8 -0
  83. package/dist/js/internal/behaviors/dialogs.mjs.map +7 -0
  84. package/dist/js/internal/behaviors/forms.mjs +8 -0
  85. package/dist/js/internal/behaviors/forms.mjs.map +7 -0
  86. package/dist/js/internal/behaviors/sheetDrag.mjs +8 -0
  87. package/dist/js/internal/behaviors/sheetDrag.mjs.map +7 -0
  88. package/dist/js/internal/behaviors/sideSheets.mjs +9 -0
  89. package/dist/js/internal/behaviors/sideSheets.mjs.map +7 -0
  90. package/dist/js/internal/components/appBar.mjs +8 -0
  91. package/dist/js/internal/components/appBar.mjs.map +7 -0
  92. package/dist/js/internal/components/autocomplete.mjs +10 -0
  93. package/dist/js/internal/components/autocomplete.mjs.map +7 -0
  94. package/dist/js/internal/components/buttonGroup.mjs +8 -0
  95. package/dist/js/internal/components/buttonGroup.mjs.map +7 -0
  96. package/dist/js/internal/components/buttons.mjs +9 -0
  97. package/dist/js/internal/components/buttons.mjs.map +7 -0
  98. package/dist/js/internal/components/cards.mjs +13 -0
  99. package/dist/js/internal/components/cards.mjs.map +7 -0
  100. package/dist/js/internal/components/carousel.mjs +9 -0
  101. package/dist/js/internal/components/carousel.mjs.map +7 -0
  102. package/dist/js/internal/components/characterCounter.mjs +8 -0
  103. package/dist/js/internal/components/characterCounter.mjs.map +7 -0
  104. package/dist/js/internal/components/chips.mjs +11 -0
  105. package/dist/js/internal/components/chips.mjs.map +7 -0
  106. package/dist/js/internal/components/datepicker.mjs +12 -0
  107. package/dist/js/internal/components/datepicker.mjs.map +7 -0
  108. package/dist/js/internal/components/expandingCard.mjs +11 -0
  109. package/dist/js/internal/components/expandingCard.mjs.map +7 -0
  110. package/dist/js/internal/components/index.mjs +88 -0
  111. package/dist/js/internal/components/index.mjs.map +7 -0
  112. package/dist/js/internal/components/lightbox.mjs +9 -0
  113. package/dist/js/internal/components/lightbox.mjs.map +7 -0
  114. package/dist/js/internal/components/menu.mjs +9 -0
  115. package/dist/js/internal/components/menu.mjs.map +7 -0
  116. package/dist/js/internal/components/navigationRail.mjs +8 -0
  117. package/dist/js/internal/components/navigationRail.mjs.map +7 -0
  118. package/dist/js/internal/components/registry.mjs +33 -0
  119. package/dist/js/internal/components/registry.mjs.map +7 -0
  120. package/dist/js/internal/components/scrollspy.mjs +8 -0
  121. package/dist/js/internal/components/scrollspy.mjs.map +7 -0
  122. package/dist/js/internal/components/select.mjs +10 -0
  123. package/dist/js/internal/components/select.mjs.map +7 -0
  124. package/dist/js/internal/components/slider.mjs +9 -0
  125. package/dist/js/internal/components/slider.mjs.map +7 -0
  126. package/dist/js/internal/components/snackbar.mjs +8 -0
  127. package/dist/js/internal/components/snackbar.mjs.map +7 -0
  128. package/dist/js/internal/components/tabs.mjs +10 -0
  129. package/dist/js/internal/components/tabs.mjs.map +7 -0
  130. package/dist/js/internal/components/timepicker.mjs +10 -0
  131. package/dist/js/internal/components/timepicker.mjs.map +7 -0
  132. package/dist/js/internal/components/tooltip.mjs +9 -0
  133. package/dist/js/internal/components/tooltip.mjs.map +7 -0
  134. package/dist/js/internal/core/component.mjs +7 -0
  135. package/dist/js/internal/core/component.mjs.map +7 -0
  136. package/dist/js/internal/core/utils.mjs +7 -0
  137. package/dist/js/internal/core/utils.mjs.map +7 -0
  138. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +8 -0
  139. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs.map +7 -0
  140. package/dist/js/modular.mjs +113 -0
  141. package/dist/js/modular.mjs.map +7 -0
  142. package/dist/types/behaviors/sheetDrag.d.ts +1 -1
  143. package/dist/types/components/appBar.d.ts +1 -1
  144. package/dist/types/components/autocomplete.d.ts +9 -0
  145. package/dist/types/components/buttons.d.ts +4 -39
  146. package/dist/types/components/carousel.d.ts +10 -1
  147. package/dist/types/components/chips.d.ts +1 -0
  148. package/dist/types/components/datepicker.d.ts +7 -0
  149. package/dist/types/components/index.d.ts +0 -2
  150. package/dist/types/components/lightbox.d.ts +12 -0
  151. package/dist/types/components/menu.d.ts +3 -0
  152. package/dist/types/components/registry.d.ts +0 -4
  153. package/dist/types/components/select.d.ts +4 -0
  154. package/dist/types/components/slider.d.ts +2 -1
  155. package/dist/types/components/snackbar.d.ts +4 -2
  156. package/dist/types/components/tabs.d.ts +2 -1
  157. package/dist/types/components/timepicker.d.ts +5 -3
  158. package/dist/types/components/tooltip.d.ts +5 -3
  159. package/dist/types/index.d.ts +1 -8
  160. package/dist/types/modular.d.ts +28 -0
  161. package/package.json +16 -4
  162. package/src/sass/README.md +8 -0
  163. package/src/sass/components/_badges.scss +1 -6
  164. package/src/sass/components/_button-groups.scss +5 -1
  165. package/src/sass/components/_buttons.scss +8 -287
  166. package/src/sass/components/_chips.scss +17 -2
  167. package/src/sass/components/_dialog.scss +9 -4
  168. package/src/sass/components/_fab-menu.scss +11 -9
  169. package/src/sass/components/_icon-buttons.scss +0 -5
  170. package/src/sass/components/_index.scss +0 -5
  171. package/src/sass/components/_menu.scss +2 -2
  172. package/src/sass/components/_navigation-rail.scss +1 -1
  173. package/src/sass/components/_panes.scss +50 -78
  174. package/src/sass/components/_progress.scss +73 -13
  175. package/src/sass/components/_scrim.scss +4 -4
  176. package/src/sass/components/_side-sheet.scss +22 -12
  177. package/src/sass/components/_toolbar.scss +1 -4
  178. package/src/sass/components/_tooltip.scss +20 -2
  179. package/src/sass/components/forms/_input-fields.scss +5 -1
  180. package/src/sass/components/forms/_select.scss +1 -0
  181. package/src/sass/components/forms/_slider.scss +81 -25
  182. package/src/sass/custom.scss +38 -0
  183. package/dist/types/components/navigationDrawer.d.ts +0 -110
  184. package/src/sass/components/_banners.scss +0 -298
  185. package/src/sass/components/_bottom-app-bar.scss +0 -180
  186. package/src/sass/components/_floating-sheet.scss +0 -86
  187. package/src/sass/components/_navigation-drawer.scss +0 -476
  188. package/src/sass/components/_segmented-buttons.scss +0 -188
@@ -0,0 +1,320 @@
1
+ import {
2
+ Utils
3
+ } from "./chunk-MISGHDUU.mjs";
4
+
5
+ // src/ts/components/snackbar.ts
6
+ var _defaults = {
7
+ text: "",
8
+ action: "",
9
+ onAction: null,
10
+ dismissible: false,
11
+ displayLength: 4e3,
12
+ inDuration: 300,
13
+ outDuration: 375,
14
+ classes: "",
15
+ completeCallback: null,
16
+ activationPercent: 0.8,
17
+ root: null
18
+ };
19
+ var _Snackbar = class _Snackbar {
20
+ constructor(options = {}) {
21
+ this._dismissed = false;
22
+ this._returnFocus = null;
23
+ this.options = {
24
+ ..._Snackbar.defaults,
25
+ ...options
26
+ };
27
+ if (options.displayLength === void 0 && this.options.action) {
28
+ this.options.displayLength = Infinity;
29
+ }
30
+ if (options.dismissible === void 0 && this.options.action) this.options.dismissible = true;
31
+ this.message = this.options.text;
32
+ this.panning = false;
33
+ this.timeRemaining = this.options.displayLength;
34
+ while (_Snackbar._snackbars.length > 0) {
35
+ const snackbar = _Snackbar._snackbars.shift();
36
+ snackbar._dismissed = true;
37
+ clearTimeout(snackbar.counterTimeout);
38
+ snackbar._restoreFocus();
39
+ snackbar.el.remove();
40
+ }
41
+ let focused = document.activeElement;
42
+ while (focused?.shadowRoot?.activeElement) focused = focused.shadowRoot.activeElement;
43
+ this._returnFocus = focused instanceof HTMLElement ? focused : null;
44
+ const root = Utils.portalRoot(this.options.root ?? document.body);
45
+ if (!_Snackbar._container || !_Snackbar._container.isConnected || _Snackbar._container.parentNode !== root) {
46
+ if (_Snackbar._container) _Snackbar._removeContainer();
47
+ _Snackbar._createContainer(root);
48
+ }
49
+ _Snackbar._snackbars.push(this);
50
+ const snackbarElement = this._createSnackbar();
51
+ snackbarElement["Expressive_Snackbar"] = this;
52
+ this.el = snackbarElement;
53
+ this._animateIn();
54
+ this._setTimer();
55
+ }
56
+ static get defaults() {
57
+ return _defaults;
58
+ }
59
+ static getInstance(el) {
60
+ return el["Expressive_Snackbar"];
61
+ }
62
+ static _createContainer(root = document.body) {
63
+ const container = document.createElement("div");
64
+ container.setAttribute("id", "snackbar-container");
65
+ container.addEventListener("pointerdown", _Snackbar._onDragStart);
66
+ document.addEventListener("pointermove", _Snackbar._onDragMove);
67
+ document.addEventListener("pointerup", _Snackbar._onDragEnd);
68
+ document.addEventListener("pointercancel", _Snackbar._onDragCancel);
69
+ root.appendChild(container);
70
+ _Snackbar._container = container;
71
+ }
72
+ static _removeContainer() {
73
+ document.removeEventListener("pointermove", _Snackbar._onDragMove);
74
+ document.removeEventListener("pointerup", _Snackbar._onDragEnd);
75
+ document.removeEventListener("pointercancel", _Snackbar._onDragCancel);
76
+ _Snackbar._container.remove();
77
+ _Snackbar._container = null;
78
+ }
79
+ static _onDragStart(e) {
80
+ if (!e.isPrimary) return;
81
+ if (e.pointerType === "mouse" && e.button !== 0) return;
82
+ const target = e.target;
83
+ if (target && !target.closest("button, a") && target.closest(".snackbar")) {
84
+ const snackbarElem = target.closest(".snackbar");
85
+ const snackbar = snackbarElem["Expressive_Snackbar"];
86
+ if (!snackbar) return;
87
+ snackbar.panning = true;
88
+ snackbar._pauseTimer();
89
+ _Snackbar._draggedSnackbar = snackbar;
90
+ snackbar.el.classList.add("panning");
91
+ snackbar.el.style.transition = "";
92
+ _Snackbar._dragPointerId = e.pointerId;
93
+ snackbar.startingXPos = e.clientX;
94
+ snackbar.time = Date.now();
95
+ snackbar.xPos = e.clientX;
96
+ }
97
+ }
98
+ static _onDragMove(e) {
99
+ if (_Snackbar._dragPointerId !== e.pointerId) return;
100
+ if (!!_Snackbar._draggedSnackbar) {
101
+ e.preventDefault();
102
+ const snackbar = _Snackbar._draggedSnackbar;
103
+ snackbar.deltaX = Math.abs(snackbar.xPos - e.clientX);
104
+ snackbar.xPos = e.clientX;
105
+ snackbar.velocityX = snackbar.deltaX / (Date.now() - snackbar.time);
106
+ snackbar.time = Date.now();
107
+ const totalDeltaX = snackbar.xPos - snackbar.startingXPos;
108
+ const activationDistance = snackbar.el.offsetWidth * snackbar.options.activationPercent;
109
+ snackbar.el.style.transform = `translateX(${totalDeltaX}px)`;
110
+ snackbar.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString();
111
+ }
112
+ }
113
+ static _onDragEnd(e) {
114
+ if (_Snackbar._dragPointerId !== e.pointerId) return;
115
+ _Snackbar._dragPointerId = null;
116
+ if (!!_Snackbar._draggedSnackbar) {
117
+ const snackbar = _Snackbar._draggedSnackbar;
118
+ snackbar.panning = false;
119
+ snackbar.el.classList.remove("panning");
120
+ const totalDeltaX = snackbar.xPos - snackbar.startingXPos;
121
+ const activationDistance = snackbar.el.offsetWidth * snackbar.options.activationPercent;
122
+ const shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || snackbar.velocityX > 1;
123
+ if (shouldBeDismissed) {
124
+ snackbar.wasSwiped = true;
125
+ snackbar.dismiss();
126
+ } else {
127
+ snackbar.el.style.transition = "transform .2s, opacity .2s";
128
+ snackbar.el.style.transform = "";
129
+ snackbar.el.style.opacity = "";
130
+ snackbar._resumeTimer();
131
+ }
132
+ _Snackbar._draggedSnackbar = null;
133
+ }
134
+ }
135
+ /**
136
+ * A cancelled pointer is not a short swipe. Snap back and resume the timer
137
+ * without consulting the distance travelled - the browser took the gesture
138
+ * over, so the movement so far says nothing about what the user wanted.
139
+ */
140
+ static _onDragCancel(e) {
141
+ if (_Snackbar._dragPointerId !== e.pointerId) return;
142
+ _Snackbar._dragPointerId = null;
143
+ const snackbar = _Snackbar._draggedSnackbar;
144
+ if (!snackbar) return;
145
+ snackbar.panning = false;
146
+ snackbar.el.classList.remove("panning");
147
+ snackbar.el.style.transition = "transform .2s, opacity .2s";
148
+ snackbar.el.style.transform = "";
149
+ snackbar.el.style.opacity = "";
150
+ snackbar._resumeTimer();
151
+ _Snackbar._draggedSnackbar = null;
152
+ }
153
+ /**
154
+ * dismiss all snackbars.
155
+ */
156
+ static dismissAll() {
157
+ for (const snackbar of [..._Snackbar._snackbars]) {
158
+ snackbar.dismiss();
159
+ }
160
+ }
161
+ _createSnackbar() {
162
+ let snackbar = this.options.snackbarId ? Utils.getElementById(this.options.root ?? document.body, this.options.snackbarId) : document.createElement("div");
163
+ if (snackbar instanceof HTMLTemplateElement) {
164
+ const node = snackbar.content.cloneNode(true);
165
+ snackbar = node.firstElementChild;
166
+ }
167
+ snackbar.classList.add("snackbar");
168
+ snackbar.setAttribute("role", "status");
169
+ snackbar.setAttribute("aria-live", "polite");
170
+ snackbar.setAttribute("aria-atomic", "true");
171
+ snackbar.inert = false;
172
+ snackbar.addEventListener("focusin", (e) => {
173
+ if (e.relatedTarget instanceof HTMLElement && !snackbar.contains(e.relatedTarget)) {
174
+ this._returnFocus = e.relatedTarget;
175
+ }
176
+ this._pauseTimer();
177
+ });
178
+ snackbar.addEventListener("keydown", (e) => {
179
+ if (e.key !== "Escape" || e.defaultPrevented || this._dismissed) return;
180
+ e.preventDefault();
181
+ e.stopPropagation();
182
+ this.dismiss();
183
+ });
184
+ snackbar.addEventListener("focusout", () => setTimeout(() => this._resumeTimer(), 0));
185
+ snackbar.addEventListener("pointerenter", () => this._pauseTimer());
186
+ snackbar.addEventListener("pointerleave", () => this._resumeTimer());
187
+ if (this.options.classes.length > 0) {
188
+ snackbar.classList.add(...this.options.classes.split(" ").filter(Boolean));
189
+ }
190
+ if (this.message) {
191
+ const text = document.createElement("p");
192
+ text.textContent = this.message;
193
+ snackbar.replaceChildren(text);
194
+ }
195
+ if (this.options.action) {
196
+ const action = document.createElement("button");
197
+ action.type = "button";
198
+ action.textContent = this.options.action;
199
+ action.addEventListener("click", (e) => {
200
+ e.stopPropagation();
201
+ if (this._dismissed) return;
202
+ try {
203
+ if (typeof this.options.onAction === "function") this.options.onAction();
204
+ } finally {
205
+ this.dismiss();
206
+ }
207
+ });
208
+ snackbar.appendChild(action);
209
+ }
210
+ if (this.options.dismissible) {
211
+ const close = document.createElement("button");
212
+ close.type = "button";
213
+ close.className = "circle";
214
+ close.setAttribute("aria-label", "Dismiss");
215
+ const icon = document.createElement("i");
216
+ icon.className = "material-symbols";
217
+ icon.setAttribute("aria-hidden", "true");
218
+ icon.textContent = "close";
219
+ close.appendChild(icon);
220
+ close.addEventListener("click", (e) => {
221
+ e.stopPropagation();
222
+ this.dismiss();
223
+ });
224
+ snackbar.appendChild(close);
225
+ }
226
+ _Snackbar._container.appendChild(snackbar);
227
+ return snackbar;
228
+ }
229
+ _animateIn() {
230
+ this.el.style.display = "";
231
+ this.el.style.opacity = "0";
232
+ this.el.style.transform = "translateY(24px)";
233
+ this.el.style.transition = `
234
+ transform ${this.options.inDuration}ms ease,
235
+ opacity ${this.options.inDuration}ms ease
236
+ `;
237
+ setTimeout(() => {
238
+ this.el.style.transform = "";
239
+ this.el.style.opacity = "1";
240
+ }, 1);
241
+ }
242
+ /**
243
+ * Arm the dismissal timer.
244
+ *
245
+ * One timeout, not a 20ms interval ticking a counter down: the old form woke
246
+ * the page up 50 times a second per snackbar purely to subtract 20 from a
247
+ * number. Dragging pauses the countdown via _pauseTimer/_resumeTimer instead.
248
+ */
249
+ _setTimer() {
250
+ if (this.timeRemaining === Infinity) return;
251
+ this._deadline = Date.now() + this.timeRemaining;
252
+ this.counterTimeout = setTimeout(() => this.dismiss(), this.timeRemaining);
253
+ }
254
+ /** Stop the countdown, banking the time that was left on it. */
255
+ _pauseTimer() {
256
+ if (this.counterTimeout == null) return;
257
+ clearTimeout(this.counterTimeout);
258
+ this.counterTimeout = null;
259
+ this.timeRemaining = Math.max(0, this._deadline - Date.now());
260
+ }
261
+ /** Restart a countdown stopped by {@link _pauseTimer}. */
262
+ _resumeTimer() {
263
+ if (this._dismissed || this.panning || this.el.matches(":hover, :focus-within") || this.counterTimeout != null) return;
264
+ this._setTimer();
265
+ }
266
+ _restoreFocus() {
267
+ const focused = this.el.getRootNode().activeElement;
268
+ if (focused && this.el.contains(focused) && this._returnFocus?.isConnected) {
269
+ this._returnFocus.focus({ preventScroll: true });
270
+ }
271
+ this.el.inert = true;
272
+ }
273
+ /**
274
+ * Dismiss snackbar with animation.
275
+ */
276
+ dismiss() {
277
+ if (this._dismissed) return;
278
+ this._dismissed = true;
279
+ clearTimeout(this.counterTimeout);
280
+ this.counterTimeout = null;
281
+ this._restoreFocus();
282
+ const activationDistance = this.el.offsetWidth * this.options.activationPercent;
283
+ if (this.wasSwiped) {
284
+ this.el.style.transition = "transform .05s, opacity .05s";
285
+ this.el.style.transform = `translateX(${activationDistance}px)`;
286
+ this.el.style.opacity = "0";
287
+ }
288
+ this.el.style.transition = `
289
+ margin ${this.options.outDuration}ms ease,
290
+ opacity ${this.options.outDuration}ms ease`;
291
+ setTimeout(() => {
292
+ this.el.style.opacity = "0";
293
+ this.el.style.marginTop = "-40px";
294
+ }, 1);
295
+ setTimeout(() => {
296
+ if (typeof this.options.completeCallback === "function") {
297
+ this.options.completeCallback();
298
+ }
299
+ if (this.el.id != this.options.snackbarId) {
300
+ this.el.remove();
301
+ const index = _Snackbar._snackbars.indexOf(this);
302
+ if (index >= 0) _Snackbar._snackbars.splice(index, 1);
303
+ if (_Snackbar._snackbars.length === 0 && _Snackbar._container && _Snackbar._container.childElementCount === 0) {
304
+ _Snackbar._removeContainer();
305
+ }
306
+ }
307
+ }, this.options.outDuration);
308
+ }
309
+ };
310
+ /** Which pointer owns the drag in flight; a second finger is ignored. */
311
+ _Snackbar._dragPointerId = null;
312
+ _Snackbar._snackbars = [];
313
+ _Snackbar._container = null;
314
+ _Snackbar._draggedSnackbar = null;
315
+ var Snackbar = _Snackbar;
316
+
317
+ export {
318
+ Snackbar
319
+ };
320
+ //# sourceMappingURL=chunk-GY2Z5CJ2.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ts/components/snackbar.ts"],
4
+ "sourcesContent": ["import { BaseOptions } from '../core/component';\nimport { Utils } from '../core/utils';\n\nexport interface SnackbarOptions extends BaseOptions {\n /**\n * The content of the Snackbar.\n * @default \"\"\n */\n text: string;\n /**\n * Optional action label. Rendered as a trailing text button.\n * @default \"\"\n */\n action: string;\n /**\n * Called when the action button is pressed. The snackbar still dismisses.\n * @default null\n */\n onAction: () => void;\n /**\n * Show a trailing close icon button.\n * Defaults to true when action is set, otherwise false.\n */\n dismissible: boolean;\n /**\n * Element id of a `<template>` (or another element) used as the snackbar body.\n * @default \"\"\n */\n snackbarId?: string;\n /**\n * Length in ms the Snackbar stays before dismissal.\n * `Infinity` keeps it on screen until the user acts.\n * When `action` is set and this is omitted, the default is Infinity.\n * @default 4000\n */\n displayLength: number;\n /**\n * Transition in duration in milliseconds.\n * @default 300\n */\n inDuration: number;\n /**\n * Transition out duration in milliseconds.\n * @default 375\n */\n outDuration: number;\n /**\n * Classes to be added to the snackbar element.\n * @default \"\"\n */\n classes: string;\n /**\n * Callback function called when the snackbar is dismissed.\n * @default null\n */\n completeCallback: () => void;\n /**\n * The percentage of the snackbar's width it takes for a drag\n * to dismiss a Snackbar.\n * @default 0.8\n */\n activationPercent: number;\n /**\n * Any element in the tree the snackbar should render into. A Snackbar has no\n * originating element to infer this from, so pass one when the page lives in\n * a shadow root \u2014 the container is appended to that root instead of to\n * `document.body`, where a root-scoped stylesheet could not reach it.\n * @default null\n */\n root: HTMLElement;\n}\n\nconst _defaults: SnackbarOptions = {\n text: '',\n action: '',\n onAction: null,\n dismissible: false,\n displayLength: 4000,\n inDuration: 300,\n outDuration: 375,\n classes: '',\n completeCallback: null,\n activationPercent: 0.8,\n root: null\n};\n\nexport class Snackbar {\n /** The snackbar element. */\n el: HTMLElement;\n /**\n * The remaining amount of time in ms that the snackbar\n * will stay before dismissal.\n */\n timeRemaining: number;\n /**\n * Describes the current pan state of the Snackbar.\n */\n panning: boolean;\n options: SnackbarOptions;\n message: string;\n counterTimeout: ReturnType<typeof setTimeout>;\n /** Wall-clock time the snackbar is due to dismiss, for pause/resume. */\n private _deadline: number;\n wasSwiped: boolean;\n startingXPos: number;\n xPos: number;\n time: number;\n deltaX: number;\n velocityX: number;\n private _dismissed = false;\n private _returnFocus: HTMLElement | null = null;\n\n static _snackbars: Snackbar[];\n static _container: HTMLElement;\n static _draggedSnackbar: Snackbar;\n /** Which pointer owns the drag in flight; a second finger is ignored. */\n static _dragPointerId: number | null = null;\n\n constructor(options: Partial<SnackbarOptions> = {}) {\n this.options = {\n ...Snackbar.defaults,\n ...options\n };\n if (options.displayLength === undefined && this.options.action) {\n this.options.displayLength = Infinity;\n }\n if (options.dismissible === undefined && this.options.action) this.options.dismissible = true;\n this.message = this.options.text;\n this.panning = false;\n this.timeRemaining = this.options.displayLength;\n // One snackbar at a time so a new update does not stack over the page.\n while (Snackbar._snackbars.length > 0) {\n const snackbar = Snackbar._snackbars.shift();\n snackbar._dismissed = true;\n clearTimeout(snackbar.counterTimeout);\n snackbar._restoreFocus();\n snackbar.el.remove();\n }\n let focused = document.activeElement;\n while (focused?.shadowRoot?.activeElement) focused = focused.shadowRoot.activeElement;\n this._returnFocus = focused instanceof HTMLElement ? focused : null;\n // One container serves every snackbar, and only one snackbar shows at a\n // time \u2014 so it is moved rather than duplicated when the root changes.\n const root = Utils.portalRoot(this.options.root ?? document.body);\n if (\n !Snackbar._container ||\n !Snackbar._container.isConnected ||\n Snackbar._container.parentNode !== root\n ) {\n if (Snackbar._container) Snackbar._removeContainer();\n Snackbar._createContainer(root);\n }\n Snackbar._snackbars.push(this);\n const snackbarElement = this._createSnackbar();\n snackbarElement['Expressive_Snackbar'] = this;\n this.el = snackbarElement;\n this._animateIn();\n this._setTimer();\n }\n\n static get defaults(): SnackbarOptions {\n return _defaults;\n }\n\n static getInstance(el: HTMLElement): Snackbar {\n return el['Expressive_Snackbar'];\n }\n\n static _createContainer(root: HTMLElement | ShadowRoot = document.body) {\n const container = document.createElement('div');\n container.setAttribute('id', 'snackbar-container');\n // One listener per stage. These used to be a touch trio on the container\n // plus a mouse trio split across the container and the document, with a\n // helper picking `targetTouches[0].clientX` or `clientX` apart afterwards.\n // Move and up stay on the document so a drag that leaves the container\n // still completes.\n container.addEventListener('pointerdown', Snackbar._onDragStart);\n document.addEventListener('pointermove', Snackbar._onDragMove);\n document.addEventListener('pointerup', Snackbar._onDragEnd);\n document.addEventListener('pointercancel', Snackbar._onDragCancel);\n root.appendChild(container);\n Snackbar._container = container;\n }\n\n static _removeContainer() {\n document.removeEventListener('pointermove', Snackbar._onDragMove);\n document.removeEventListener('pointerup', Snackbar._onDragEnd);\n document.removeEventListener('pointercancel', Snackbar._onDragCancel);\n Snackbar._container.remove();\n Snackbar._container = null;\n }\n\n static _onDragStart(e: PointerEvent) {\n if (!e.isPrimary) return;\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n const target = e.target as HTMLElement | null;\n // Don't start a swipe from the action or close \u2014 those are buttons.\n if (target && !target.closest('button, a') && target.closest('.snackbar')) {\n const snackbarElem = target.closest('.snackbar') as HTMLElement;\n const snackbar: Snackbar = snackbarElem['Expressive_Snackbar'];\n if (!snackbar) return;\n snackbar.panning = true;\n snackbar._pauseTimer();\n Snackbar._draggedSnackbar = snackbar;\n snackbar.el.classList.add('panning');\n snackbar.el.style.transition = '';\n Snackbar._dragPointerId = e.pointerId;\n snackbar.startingXPos = e.clientX;\n snackbar.time = Date.now();\n snackbar.xPos = e.clientX;\n }\n }\n\n static _onDragMove(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n if (!!Snackbar._draggedSnackbar) {\n e.preventDefault();\n const snackbar = Snackbar._draggedSnackbar;\n snackbar.deltaX = Math.abs(snackbar.xPos - e.clientX);\n snackbar.xPos = e.clientX;\n snackbar.velocityX = snackbar.deltaX / (Date.now() - snackbar.time);\n snackbar.time = Date.now();\n\n const totalDeltaX = snackbar.xPos - snackbar.startingXPos;\n const activationDistance = snackbar.el.offsetWidth * snackbar.options.activationPercent;\n snackbar.el.style.transform = `translateX(${totalDeltaX}px)`;\n snackbar.el.style.opacity = (1 - Math.abs(totalDeltaX / activationDistance)).toString();\n }\n }\n\n static _onDragEnd(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n Snackbar._dragPointerId = null;\n if (!!Snackbar._draggedSnackbar) {\n const snackbar = Snackbar._draggedSnackbar;\n snackbar.panning = false;\n snackbar.el.classList.remove('panning');\n\n const totalDeltaX = snackbar.xPos - snackbar.startingXPos;\n const activationDistance = snackbar.el.offsetWidth * snackbar.options.activationPercent;\n const shouldBeDismissed = Math.abs(totalDeltaX) > activationDistance || snackbar.velocityX > 1;\n\n // Remove snackbar\n if (shouldBeDismissed) {\n snackbar.wasSwiped = true;\n snackbar.dismiss();\n // Animate snackbar back to original position\n } else {\n snackbar.el.style.transition = 'transform .2s, opacity .2s';\n snackbar.el.style.transform = '';\n snackbar.el.style.opacity = '';\n snackbar._resumeTimer();\n }\n Snackbar._draggedSnackbar = null;\n }\n }\n\n /**\n * A cancelled pointer is not a short swipe. Snap back and resume the timer\n * without consulting the distance travelled - the browser took the gesture\n * over, so the movement so far says nothing about what the user wanted.\n */\n static _onDragCancel(e: PointerEvent) {\n if (Snackbar._dragPointerId !== e.pointerId) return;\n Snackbar._dragPointerId = null;\n const snackbar = Snackbar._draggedSnackbar;\n if (!snackbar) return;\n snackbar.panning = false;\n snackbar.el.classList.remove('panning');\n snackbar.el.style.transition = 'transform .2s, opacity .2s';\n snackbar.el.style.transform = '';\n snackbar.el.style.opacity = '';\n snackbar._resumeTimer();\n Snackbar._draggedSnackbar = null;\n }\n\n /**\n * dismiss all snackbars.\n */\n static dismissAll() {\n // Copy first: dismiss() splices the list it is iterating.\n for (const snackbar of [...Snackbar._snackbars]) {\n snackbar.dismiss();\n }\n }\n\n _createSnackbar() {\n let snackbar: HTMLElement = this.options.snackbarId\n ? Utils.getElementById(this.options.root ?? document.body, this.options.snackbarId)\n : document.createElement('div');\n if (snackbar instanceof HTMLTemplateElement) {\n const node = (snackbar as HTMLTemplateElement).content.cloneNode(true);\n snackbar = (node as HTMLElement).firstElementChild as HTMLElement;\n }\n snackbar.classList.add('snackbar');\n snackbar.setAttribute('role', 'status');\n snackbar.setAttribute('aria-live', 'polite');\n snackbar.setAttribute('aria-atomic', 'true');\n snackbar.inert = false;\n snackbar.addEventListener('focusin', (e) => {\n if (e.relatedTarget instanceof HTMLElement && !snackbar.contains(e.relatedTarget)) {\n this._returnFocus = e.relatedTarget;\n }\n this._pauseTimer();\n });\n snackbar.addEventListener('keydown', (e) => {\n if (e.key !== 'Escape' || e.defaultPrevented || this._dismissed) return;\n e.preventDefault();\n e.stopPropagation();\n this.dismiss();\n });\n snackbar.addEventListener('focusout', () => setTimeout(() => this._resumeTimer(), 0));\n snackbar.addEventListener('pointerenter', () => this._pauseTimer());\n snackbar.addEventListener('pointerleave', () => this._resumeTimer());\n // Add custom classes onto snackbar\n if (this.options.classes.length > 0) {\n snackbar.classList.add(...this.options.classes.split(' ').filter(Boolean));\n }\n if (this.message) {\n const text = document.createElement('p');\n text.textContent = this.message;\n snackbar.replaceChildren(text);\n }\n if (this.options.action) {\n const action = document.createElement('button');\n action.type = 'button';\n action.textContent = this.options.action;\n action.addEventListener('click', (e) => {\n e.stopPropagation();\n if (this._dismissed) return;\n try {\n if (typeof this.options.onAction === 'function') this.options.onAction();\n } finally {\n this.dismiss();\n }\n });\n snackbar.appendChild(action);\n }\n if (this.options.dismissible) {\n const close = document.createElement('button');\n close.type = 'button';\n close.className = 'circle';\n close.setAttribute('aria-label', 'Dismiss');\n const icon = document.createElement('i');\n icon.className = 'material-symbols';\n icon.setAttribute('aria-hidden', 'true');\n icon.textContent = 'close';\n close.appendChild(icon);\n close.addEventListener('click', (e) => {\n e.stopPropagation();\n this.dismiss();\n });\n snackbar.appendChild(close);\n }\n Snackbar._container.appendChild(snackbar);\n return snackbar;\n }\n\n _animateIn() {\n this.el.style.display = '';\n this.el.style.opacity = '0';\n this.el.style.transform = 'translateY(24px)';\n this.el.style.transition = `\n transform ${this.options.inDuration}ms ease,\n opacity ${this.options.inDuration}ms ease\n `;\n setTimeout(() => {\n this.el.style.transform = '';\n this.el.style.opacity = '1';\n }, 1);\n }\n\n /**\n * Arm the dismissal timer.\n *\n * One timeout, not a 20ms interval ticking a counter down: the old form woke\n * the page up 50 times a second per snackbar purely to subtract 20 from a\n * number. Dragging pauses the countdown via _pauseTimer/_resumeTimer instead.\n */\n _setTimer() {\n if (this.timeRemaining === Infinity) return;\n this._deadline = Date.now() + this.timeRemaining;\n this.counterTimeout = setTimeout(() => this.dismiss(), this.timeRemaining);\n }\n\n /** Stop the countdown, banking the time that was left on it. */\n _pauseTimer() {\n if (this.counterTimeout == null) return;\n clearTimeout(this.counterTimeout);\n this.counterTimeout = null;\n this.timeRemaining = Math.max(0, this._deadline - Date.now());\n }\n\n /** Restart a countdown stopped by {@link _pauseTimer}. */\n _resumeTimer() {\n if (this._dismissed || this.panning || this.el.matches(':hover, :focus-within') || this.counterTimeout != null) return;\n this._setTimer();\n }\n\n private _restoreFocus() {\n const focused = (this.el.getRootNode() as Document | ShadowRoot).activeElement;\n if (focused && this.el.contains(focused) && this._returnFocus?.isConnected) {\n this._returnFocus.focus({ preventScroll: true });\n }\n this.el.inert = true;\n }\n\n /**\n * Dismiss snackbar with animation.\n */\n dismiss() {\n if (this._dismissed) return;\n this._dismissed = true;\n clearTimeout(this.counterTimeout);\n this.counterTimeout = null;\n this._restoreFocus();\n const activationDistance = this.el.offsetWidth * this.options.activationPercent;\n\n if (this.wasSwiped) {\n this.el.style.transition = 'transform .05s, opacity .05s';\n this.el.style.transform = `translateX(${activationDistance}px)`;\n this.el.style.opacity = '0';\n }\n\n // easeOutExpo\n this.el.style.transition = `\n margin ${this.options.outDuration}ms ease,\n opacity ${this.options.outDuration}ms ease`;\n\n setTimeout(() => {\n this.el.style.opacity = '0';\n this.el.style.marginTop = '-40px';\n }, 1);\n\n setTimeout(() => {\n // Call the optional callback\n if (typeof this.options.completeCallback === 'function') {\n this.options.completeCallback();\n }\n // Remove snackbar from DOM\n if (this.el.id != this.options.snackbarId) {\n this.el.remove();\n // Guarded: splice(-1, 1) on an already-removed snackbar would drop an\n // unrelated one off the end of the list.\n const index = Snackbar._snackbars.indexOf(this);\n if (index >= 0) Snackbar._snackbars.splice(index, 1);\n if (\n Snackbar._snackbars.length === 0 &&\n Snackbar._container &&\n Snackbar._container.childElementCount === 0\n ) {\n Snackbar._removeContainer();\n }\n }\n }, this.options.outDuration);\n }\n\n static {\n Snackbar._snackbars = [];\n Snackbar._container = null;\n Snackbar._draggedSnackbar = null;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,191 @@
1
+ import {
2
+ Utils
3
+ } from "./chunk-MISGHDUU.mjs";
4
+ import {
5
+ Component
6
+ } from "./chunk-QSQ24FYT.mjs";
7
+
8
+ // src/ts/components/slider.ts
9
+ var _defaults = {};
10
+ var Slider = class _Slider extends Component {
11
+ constructor(el, options) {
12
+ super(el, options, _Slider);
13
+ this._resizeObserver = null;
14
+ this._handleRangeChange = () => {
15
+ this._clampDual();
16
+ this._sync();
17
+ this.thumb.classList.add("active");
18
+ };
19
+ this._handleRangePointerDown = (e) => {
20
+ if (!e.isPrimary) return;
21
+ if (e.pointerType === "mouse" && e.button !== 0) return;
22
+ this._pointerDown = true;
23
+ this.el.classList.add("active");
24
+ this._clampDual();
25
+ this._sync();
26
+ this.thumb.classList.add("active");
27
+ };
28
+ this._handleRangeInputOrMove = (e) => {
29
+ if (e.type === "input" || this._pointerDown) {
30
+ this._clampDual();
31
+ this._sync();
32
+ this.thumb.classList.add("active");
33
+ }
34
+ };
35
+ this._handleRangePointerUp = (e) => {
36
+ if (!e.isPrimary) return;
37
+ this._pointerDown = false;
38
+ this.el.classList.remove("active");
39
+ };
40
+ this._handleRangeRelease = () => {
41
+ if (!this._pointerDown) {
42
+ this.thumb.classList.remove("active");
43
+ }
44
+ };
45
+ this.el["Expressive_Slider"] = this;
46
+ this.options = {
47
+ ..._Slider.defaults,
48
+ ...options
49
+ };
50
+ this._pointerDown = false;
51
+ this._setupThumb();
52
+ this._sync();
53
+ this._setupEventHandlers();
54
+ if (typeof ResizeObserver !== "undefined") {
55
+ this._resizeObserver = new ResizeObserver(() => this._sync());
56
+ this._resizeObserver.observe(this.el);
57
+ }
58
+ }
59
+ static get defaults() {
60
+ return _defaults;
61
+ }
62
+ /**
63
+ * Initializes instances of Slider.
64
+ * @param els HTML elements.
65
+ * @param options Component options.
66
+ */
67
+ static init(els, options = {}) {
68
+ return super.init(els, options, _Slider);
69
+ }
70
+ static getInstance(el) {
71
+ return el["Expressive_Slider"];
72
+ }
73
+ destroy() {
74
+ this._resizeObserver?.disconnect();
75
+ this._removeEventHandlers();
76
+ this._removeThumb();
77
+ this.el["Expressive_Slider"] = void 0;
78
+ }
79
+ // Eleven listeners used to cover four stages, because each one was written
80
+ // twice - once for mouse, once for touch. One of the touch spellings,
81
+ // `touchleave`, was never implemented by any browser at all.
82
+ _setupEventHandlers() {
83
+ this.el.addEventListener("change", this._handleRangeChange);
84
+ this.el.addEventListener("pointerdown", this._handleRangePointerDown);
85
+ this.el.addEventListener("input", this._handleRangeInputOrMove);
86
+ this.el.addEventListener("pointermove", this._handleRangeInputOrMove, { passive: true });
87
+ this.el.addEventListener("pointerup", this._handleRangePointerUp);
88
+ this.el.addEventListener("pointercancel", this._handleRangePointerUp);
89
+ this.el.addEventListener("blur", this._handleRangeRelease);
90
+ this.el.addEventListener("mouseout", this._handleRangeRelease);
91
+ }
92
+ _removeEventHandlers() {
93
+ this.el.removeEventListener("change", this._handleRangeChange);
94
+ this.el.removeEventListener("pointerdown", this._handleRangePointerDown);
95
+ this.el.removeEventListener("input", this._handleRangeInputOrMove);
96
+ this.el.removeEventListener("pointermove", this._handleRangeInputOrMove);
97
+ this.el.removeEventListener("pointerup", this._handleRangePointerUp);
98
+ this.el.removeEventListener("pointercancel", this._handleRangePointerUp);
99
+ this.el.removeEventListener("blur", this._handleRangeRelease);
100
+ this.el.removeEventListener("mouseout", this._handleRangeRelease);
101
+ }
102
+ _setupThumb() {
103
+ this.thumb = document.createElement("span");
104
+ this.value = document.createElement("span");
105
+ this.thumb.classList.add("thumb");
106
+ this.value.classList.add("value");
107
+ this.thumb.append(this.value);
108
+ this.el.after(this.thumb);
109
+ }
110
+ _removeThumb() {
111
+ this.thumb.remove();
112
+ }
113
+ _isVertical() {
114
+ return !!this.el.closest(".vertical");
115
+ }
116
+ _host() {
117
+ return this.el.closest(".slider, .range, .range-field, label");
118
+ }
119
+ _clampDual() {
120
+ const host = this._host();
121
+ const peers = host?.querySelectorAll('input[type="range"]');
122
+ if (!peers || peers.length !== 2) return;
123
+ const start = peers[0];
124
+ const end = peers[1];
125
+ if (this.el === start && +start.value > +end.value) start.value = end.value;
126
+ if (this.el === end && +end.value < +start.value) end.value = start.value;
127
+ }
128
+ _fraction(el) {
129
+ const parsedMax = parseFloat(el.max);
130
+ const max = Number.isNaN(parsedMax) ? 100 : parsedMax;
131
+ const min = parseFloat(el.min) || 0;
132
+ const val = parseFloat(el.value) || 0;
133
+ return max === min ? 0 : (val - min) / (max - min);
134
+ }
135
+ _sync() {
136
+ const percent = this._fraction(this.el);
137
+ const fraction = `${percent * 100}%`;
138
+ const left = this.el.offsetLeft;
139
+ const top = this.el.offsetTop;
140
+ const width = this.el.offsetWidth;
141
+ const height = this.el.offsetHeight;
142
+ const style = getComputedStyle(this.el);
143
+ const rtl = style.direction === "rtl";
144
+ const vertical = this._isVertical();
145
+ const handle = parseFloat(style.getPropertyValue("--md-comp-slider-handle-width")) || 4;
146
+ const length = vertical ? height : width;
147
+ const position = handle / 2 + percent * (length - handle);
148
+ this.el.style.setProperty("--md-comp-slider-active-fraction", fraction);
149
+ this.el.style.setProperty("--md-comp-slider-active-position", `${position}px`);
150
+ const host = this._host();
151
+ const peers = host?.querySelectorAll('input[type="range"]');
152
+ if (host && peers && peers.length === 2) {
153
+ const nums = Array.from(peers).map((el) => this._fraction(el));
154
+ host.style.setProperty("--md-comp-slider-start-fraction", `${Math.min(...nums) * 100}%`);
155
+ host.style.setProperty("--md-comp-slider-end-fraction", `${Math.max(...nums) * 100}%`);
156
+ host.style.setProperty("--md-comp-slider-start-position", `${handle / 2 + Math.min(...nums) * (length - handle)}px`);
157
+ host.style.setProperty("--md-comp-slider-end-position", `${handle / 2 + Math.max(...nums) * (length - handle)}px`);
158
+ }
159
+ if (host?.classList.contains("stops")) {
160
+ const parsedMax = parseFloat(this.el.max);
161
+ const max = Number.isNaN(parsedMax) ? 100 : parsedMax;
162
+ const min = parseFloat(this.el.min) || 0;
163
+ const step = parseFloat(this.el.step);
164
+ if (step > 0 && Number.isFinite(step)) {
165
+ const n = Math.round((max - min) / step) + 1;
166
+ host.style.setProperty("--md-comp-slider-stop-count", String(Math.max(2, n)));
167
+ }
168
+ }
169
+ this.value.textContent = this.el.value;
170
+ if (vertical) {
171
+ this.thumb.style.left = `${left + width / 2}px`;
172
+ this.thumb.style.top = `${top + height - position}px`;
173
+ } else {
174
+ this.thumb.style.left = `${left + (rtl ? width - position : position)}px`;
175
+ this.thumb.style.top = `${top}px`;
176
+ }
177
+ }
178
+ /**
179
+ * Initializes every range input in the current document.
180
+ */
181
+ static Init() {
182
+ Utils.onDocumentReady(() => {
183
+ _Slider.init(document.querySelectorAll("input[type=range]"), {});
184
+ });
185
+ }
186
+ };
187
+
188
+ export {
189
+ Slider
190
+ };
191
+ //# sourceMappingURL=chunk-JKNPQQWY.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ts/components/slider.ts"],
4
+ "sourcesContent": ["import { Component, BaseOptions, InitElements, InitElement } from '../core/component';\nimport { Utils } from '../core/utils';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface SliderOptions extends BaseOptions {}\n\nconst _defaults: SliderOptions = {};\n\nexport class Slider extends Component<SliderOptions> {\n declare el: HTMLInputElement;\n private _pointerDown: boolean;\n private _resizeObserver: ResizeObserver | null = null;\n value: HTMLElement;\n thumb: HTMLElement;\n\n constructor(el: HTMLInputElement, options: Partial<SliderOptions>) {\n super(el, options, Slider);\n this.el['Expressive_Slider'] = this;\n\n this.options = {\n ...Slider.defaults,\n ...options\n };\n\n this._pointerDown = false;\n this._setupThumb();\n this._sync();\n this._setupEventHandlers();\n if (typeof ResizeObserver !== 'undefined') {\n this._resizeObserver = new ResizeObserver(() => this._sync());\n this._resizeObserver.observe(this.el);\n }\n }\n\n static get defaults(): SliderOptions {\n return _defaults;\n }\n\n /**\n * Initializes instance of Slider.\n * @param el HTML element.\n * @param options Component options.\n */\n static init(el: HTMLInputElement, options?: Partial<SliderOptions>): Slider;\n /**\n * Initializes instances of Slider.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: InitElements<HTMLInputElement | InitElement>,\n options?: Partial<SliderOptions>\n ): Slider[];\n /**\n * Initializes instances of Slider.\n * @param els HTML elements.\n * @param options Component options.\n */\n static init(\n els: HTMLInputElement | InitElements<HTMLInputElement | InitElement>,\n options: Partial<SliderOptions> = {}\n ): Slider | Slider[] {\n return super.init(els, options, Slider);\n }\n\n static getInstance(el: HTMLInputElement): Slider {\n return el['Expressive_Slider'];\n }\n\n destroy() {\n this._resizeObserver?.disconnect();\n this._removeEventHandlers();\n this._removeThumb();\n this.el['Expressive_Slider'] = undefined;\n }\n\n // Eleven listeners used to cover four stages, because each one was written\n // twice - once for mouse, once for touch. One of the touch spellings,\n // `touchleave`, was never implemented by any browser at all.\n _setupEventHandlers() {\n this.el.addEventListener('change', this._handleRangeChange);\n this.el.addEventListener('pointerdown', this._handleRangePointerDown);\n this.el.addEventListener('input', this._handleRangeInputOrMove);\n // Never calls preventDefault, so it does not need to block scrolling.\n this.el.addEventListener('pointermove', this._handleRangeInputOrMove, { passive: true });\n this.el.addEventListener('pointerup', this._handleRangePointerUp);\n this.el.addEventListener('pointercancel', this._handleRangePointerUp);\n this.el.addEventListener('blur', this._handleRangeRelease);\n // `mouseout`, not `pointerout`: this used to be a `mouseout`/`touchleave`\n // pair, and `touchleave` was never implemented by any browser, so the\n // handler has only ever run for a mouse. `pointerout` also fires when a\n // touch lifts, which would clear the thumb's active state at a moment\n // nothing cleared it before.\n this.el.addEventListener('mouseout', this._handleRangeRelease);\n }\n\n _removeEventHandlers() {\n this.el.removeEventListener('change', this._handleRangeChange);\n this.el.removeEventListener('pointerdown', this._handleRangePointerDown);\n this.el.removeEventListener('input', this._handleRangeInputOrMove);\n this.el.removeEventListener('pointermove', this._handleRangeInputOrMove);\n this.el.removeEventListener('pointerup', this._handleRangePointerUp);\n this.el.removeEventListener('pointercancel', this._handleRangePointerUp);\n this.el.removeEventListener('blur', this._handleRangeRelease);\n this.el.removeEventListener('mouseout', this._handleRangeRelease);\n }\n\n _handleRangeChange = () => {\n this._clampDual();\n this._sync();\n this.thumb.classList.add('active');\n };\n\n _handleRangePointerDown = (e: PointerEvent) => {\n if (!e.isPrimary) return;\n if (e.pointerType === 'mouse' && e.button !== 0) return;\n this._pointerDown = true;\n this.el.classList.add('active');\n this._clampDual();\n this._sync();\n // An `e.type !== 'input'` guard used to sit here. This handler is only ever\n // bound to a press, so it was never anything but true.\n this.thumb.classList.add('active');\n };\n\n _handleRangeInputOrMove = (e: Event) => {\n if (e.type === 'input' || this._pointerDown) {\n this._clampDual();\n this._sync();\n this.thumb.classList.add('active');\n }\n };\n\n _handleRangePointerUp = (e: PointerEvent) => {\n if (!e.isPrimary) return;\n this._pointerDown = false;\n this.el.classList.remove('active');\n };\n\n _handleRangeRelease = () => {\n if (!this._pointerDown) {\n this.thumb.classList.remove('active');\n }\n };\n\n _setupThumb() {\n this.thumb = document.createElement('span');\n this.value = document.createElement('span');\n this.thumb.classList.add('thumb');\n this.value.classList.add('value');\n this.thumb.append(this.value);\n this.el.after(this.thumb);\n }\n\n _removeThumb() {\n this.thumb.remove();\n }\n\n _isVertical(): boolean {\n return !!this.el.closest('.vertical');\n }\n\n _host(): HTMLElement | null {\n // `.slider` is the documented host now; without it here a dual-handle\n // control could not find its wrapper, so the handles never clamped and the\n // shared start/end fractions never tracked the interval.\n return this.el.closest('.slider, .range, .range-field, label');\n }\n\n _clampDual() {\n const host = this._host();\n const peers = host?.querySelectorAll('input[type=\"range\"]');\n if (!peers || peers.length !== 2) return;\n const start = peers[0] as HTMLInputElement;\n const end = peers[1] as HTMLInputElement;\n if (this.el === start && +start.value > +end.value) start.value = end.value;\n if (this.el === end && +end.value < +start.value) end.value = start.value;\n }\n\n _fraction(el: HTMLInputElement): number {\n const parsedMax = parseFloat(el.max);\n const max = Number.isNaN(parsedMax) ? 100 : parsedMax;\n const min = parseFloat(el.min) || 0;\n const val = parseFloat(el.value) || 0;\n return max === min ? 0 : (val - min) / (max - min);\n }\n\n _sync() {\n const percent = this._fraction(this.el);\n const fraction = `${percent * 100}%`;\n\n // Read before writing. This runs on every pointer move during a drag, and\n // setting the custom property first made each of the four offset reads\n // below flush a fresh layout.\n const left = this.el.offsetLeft;\n const top = this.el.offsetTop;\n const width = this.el.offsetWidth;\n const height = this.el.offsetHeight;\n const style = getComputedStyle(this.el);\n const rtl = style.direction === 'rtl';\n const vertical = this._isVertical();\n const handle = parseFloat(style.getPropertyValue('--md-comp-slider-handle-width')) || 4;\n const length = vertical ? height : width;\n const position = handle / 2 + percent * (length - handle);\n\n this.el.style.setProperty('--md-comp-slider-active-fraction', fraction);\n this.el.style.setProperty('--md-comp-slider-active-position', `${position}px`);\n\n const host = this._host();\n const peers = host?.querySelectorAll('input[type=\"range\"]');\n if (host && peers && peers.length === 2) {\n const nums = Array.from(peers).map((el) => this._fraction(el as HTMLInputElement));\n host.style.setProperty('--md-comp-slider-start-fraction', `${Math.min(...nums) * 100}%`);\n host.style.setProperty('--md-comp-slider-end-fraction', `${Math.max(...nums) * 100}%`);\n host.style.setProperty('--md-comp-slider-start-position', `${handle / 2 + Math.min(...nums) * (length - handle)}px`);\n host.style.setProperty('--md-comp-slider-end-position', `${handle / 2 + Math.max(...nums) * (length - handle)}px`);\n }\n if (host?.classList.contains('stops')) {\n const parsedMax = parseFloat(this.el.max);\n const max = Number.isNaN(parsedMax) ? 100 : parsedMax;\n const min = parseFloat(this.el.min) || 0;\n const step = parseFloat(this.el.step);\n if (step > 0 && Number.isFinite(step)) {\n const n = Math.round((max - min) / step) + 1;\n host.style.setProperty('--md-comp-slider-stop-count', String(Math.max(2, n)));\n }\n }\n\n this.value.textContent = this.el.value;\n if (vertical) {\n this.thumb.style.left = `${left + width / 2}px`;\n this.thumb.style.top = `${top + height - position}px`;\n } else {\n this.thumb.style.left = `${left + (rtl ? width - position : position)}px`;\n this.thumb.style.top = `${top}px`;\n }\n }\n\n /**\n * Initializes every range input in the current document.\n */\n static Init() {\n // Deferred like every other Init(): this ran at import time, so a bundle\n // loaded in <head> found no inputs at all.\n Utils.onDocumentReady(() => {\n Slider.init(document.querySelectorAll('input[type=range]') as NodeListOf<HTMLInputElement>, {});\n });\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }