beercss 3.6.13 → 3.7.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/src/cdn/beer.ts CHANGED
@@ -1,518 +1,60 @@
1
+ import { updateAllFields } from "./elements/fields";
2
+ import { updateAllSliders } from "./elements/sliders";
3
+ import { updateMode, updateTheme } from "./helpers/theme";
1
4
  import { type IBeerCssTheme } from "./interfaces";
5
+ import { guid, on, query, queryAll, run } from "./utils";
2
6
 
3
- let _timeoutSnackbar: ReturnType<typeof setTimeout>;
4
7
  let _timeoutMutation: ReturnType<typeof setTimeout>;
5
- let _timeoutMenu: ReturnType<typeof setTimeout>;
6
8
  let _mutation: MutationObserver | null;
7
- const _lastTheme: IBeerCssTheme = {
8
- light: "",
9
- dark: "",
10
- };
11
- const _emptyNodeList = [] as unknown as NodeListOf<Element>;
12
9
 
13
- async function wait (milliseconds: number) {
14
- await new Promise((resolve) => setTimeout(resolve, milliseconds));
15
- }
16
-
17
- function guid (): string {
18
- return "fxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c: string) => {
19
- const r = (Math.random() * 16) | 0;
20
- const v = c === "x" ? r : (r & 0x3) | 0x8;
21
- return v.toString(16);
22
- });
23
- }
24
-
25
- function query (selector: string | Element | null, element?: Element | null): Element | null {
26
- try {
27
- return (typeof selector === "string")
28
- ? (element ?? document).querySelector(selector)
29
- : selector;
30
- } catch {
31
- return null;
32
- }
33
- }
34
-
35
- function queryAll (selector: string | NodeListOf<Element> | null, element?: Element | null): NodeListOf<Element> {
36
- try {
37
- return (typeof selector === "string")
38
- ? (element ?? document).querySelectorAll(selector)
39
- : selector ?? _emptyNodeList;
40
- } catch {
41
- return _emptyNodeList;
42
- }
43
- }
44
-
45
- function hasClass (element: Element | null, name: string): boolean {
46
- return element?.classList?.contains(name) ?? false;
47
- }
48
-
49
- function hasTag (element: Element | null, name: string): boolean {
50
- return element?.tagName?.toLowerCase() === name;
51
- }
52
-
53
- function hasType (element: HTMLInputElement | null, name: string): boolean {
54
- return element?.type?.toLowerCase() === name;
55
- }
56
-
57
- function addClass (element: Element | null, name: string): void {
58
- element?.classList?.add(name);
59
- }
60
-
61
- function removeClass (element: Element | null, name: string): void {
62
- element?.classList?.remove(name);
63
- }
64
-
65
- function on (element: any, name: string, callback: any, useCapture: boolean = true): void {
66
- element?.addEventListener(name, callback, useCapture);
67
- }
68
-
69
- function off (element: any, name: string, callback: any, useCapture: boolean = true): void {
70
- element?.removeEventListener(name, callback, useCapture);
71
- }
72
-
73
- function insertBefore (newElement: Element, element: Element | null): void {
74
- element?.parentNode?.insertBefore(newElement, element);
75
- }
76
-
77
- function prev (element: Element): Element | null {
78
- return element?.previousElementSibling;
79
- }
80
-
81
- function next (element: Element): Element | null {
82
- return element?.nextElementSibling;
83
- }
84
-
85
- function parent (element: Element): Element | null {
86
- return element?.parentElement;
87
- }
88
-
89
- function create (htmlAttributesAsJson: any): HTMLElement {
90
- const element = document.createElement("div");
91
- for (let i = 0, keys = Object.keys(htmlAttributesAsJson), n = keys.length; i < n; i++) {
92
- const key = keys[i];
93
- const value = htmlAttributesAsJson[key] as string;
94
- element.setAttribute(key, value);
95
- }
96
- return element;
97
- }
98
-
99
- function updateInput (target: Element): void {
100
- const input = target as HTMLInputElement;
101
- if (hasType(input, "number") && !input.value) input.value = "";
102
- if (!input.placeholder) input.placeholder = " ";
103
- if (target.getAttribute("data-ui")) void open(target, null);
104
- }
105
-
106
- function onClickElement (e: Event): void {
107
- void open(e.currentTarget as HTMLElement, null, null, e);
108
- }
109
-
110
- function onClickLabel (e: Event): void {
111
- const target = e.currentTarget as Element;
112
- const parentTarget = parent(target);
113
- const input = query("input:not([type=file], [type=checkbox], [type=radio]), select, textarea", parentTarget) as HTMLElement;
114
- if (input) input.focus();
115
- }
116
-
117
- function onFocusInput (e: Event): void {
118
- const target = e.currentTarget as Element;
119
- updateInput(target);
120
- }
121
-
122
- function onBlurInput (e: Event): void {
123
- const target = e.currentTarget as Element;
124
- updateInput(target);
125
- }
126
-
127
- function onClickDocument (e: Event): void {
128
- off(document.body, "click", onClickDocument);
129
- const target = e.target as Element;
130
- const menus = queryAll("menu.active");
131
- for (let i = 0, n = menus.length; i < n; i++) menu(target, menus[i], e);
132
- }
133
-
134
- function onClickSnackbar (e: Event): void {
135
- const target = e.currentTarget as Element;
136
- removeClass(target, "active");
137
-
138
- if (_timeoutSnackbar) clearTimeout(_timeoutSnackbar);
139
- }
140
-
141
- function onChangeFile (e: Event): void {
142
- const target = e.currentTarget as HTMLInputElement;
143
- updateFile(target);
144
- }
145
-
146
- function onChangeColor (e: Event): void {
147
- const target = e.currentTarget as HTMLInputElement;
148
- updateColor(target);
149
- }
150
-
151
- function onKeydownFile (e: KeyboardEvent): void {
152
- const target = e.currentTarget as HTMLInputElement;
153
- updateFile(target, e);
154
- }
155
-
156
- function onKeydownColor (e: KeyboardEvent): void {
157
- const target = e.currentTarget as HTMLInputElement;
158
- updateColor(target, e);
159
- }
160
-
161
- function onInputTextarea (e: Event): void {
162
- const target = e.currentTarget as Element;
163
- updateTextarea(target);
164
- }
165
-
166
- function onMutation (): void {
10
+ function onMutation() {
167
11
  if (_timeoutMutation) clearTimeout(_timeoutMutation);
168
- _timeoutMutation = setTimeout(() => { void ui(); }, 180);
169
- }
170
-
171
- function updateFile (target: Element, e?: KeyboardEvent): void {
172
- if (e && e.key === "Enter") {
173
- const previousTarget = prev(target) as HTMLInputElement;
174
- if (!hasType(previousTarget, "file")) return;
175
- previousTarget.click(); return;
176
- }
177
-
178
- const currentTarget = target as HTMLInputElement;
179
- const nextTarget = next(target) as HTMLInputElement;
180
- if (!hasType(nextTarget, "text")) return;
181
- nextTarget.value = currentTarget.files ? Array.from(currentTarget.files).map((x) => x.name).join(", ") : "";
182
- nextTarget.readOnly = true;
183
- on(nextTarget, "keydown", onKeydownFile, false);
184
- updateInput(nextTarget);
185
- }
186
-
187
- function updateColor (target: Element, e?: KeyboardEvent): void {
188
- if (e && e.key === "Enter") {
189
- const previousTarget = prev(target) as HTMLInputElement;
190
- if (!hasType(previousTarget, "color")) return;
191
- previousTarget.click(); return;
192
- }
193
-
194
- const currentTarget = target as HTMLInputElement;
195
- const nextTarget = next(target) as HTMLInputElement;
196
- if (!hasType(nextTarget, "text")) return;
197
- nextTarget.readOnly = true;
198
- nextTarget.value = currentTarget.value;
199
- on(nextTarget, "keydown", onKeydownColor, false);
200
- updateInput(nextTarget);
12
+ _timeoutMutation = setTimeout(async () => await ui(), 180);
201
13
  }
202
14
 
203
- function updateTextarea (target: Element): void {
204
- const parentTarget = parent(target) as HTMLElement;
205
- const currentTarget = parent(target) as HTMLElement;
206
- parentTarget.removeAttribute("style");
207
- if (hasClass(parentTarget, "min")) parentTarget.style.setProperty("---size", `${Math.max(target.scrollHeight, currentTarget.offsetHeight)}px`);
15
+ function onClickElement(e: Event) {
16
+ run(e.currentTarget as HTMLElement, null, null, e);
208
17
  }
209
18
 
210
- function updateRange (target: Element): void {
211
- const parentTarget = parent(target) as HTMLElement;
212
- const bar = query("span", parentTarget) as HTMLElement;
213
- const inputs = queryAll("input", parentTarget) as NodeListOf<HTMLInputElement>;
214
- if (!inputs.length || !bar) return;
215
-
216
- const rootSize = parseInt(getComputedStyle(document.documentElement).getPropertyValue("--size")) || 16;
217
- const thumb = hasClass(parentTarget, "max") ? 0 : 0.25 * rootSize * 100 / inputs[0].offsetWidth;
218
- const percents: Array<number> = [];
219
- const values: Array<number> = [];
220
- for (let i = 0, n = inputs.length; i < n; i++) {
221
- const min = parseFloat(inputs[i].min) || 0;
222
- const max = parseFloat(inputs[i].max) || 100;
223
- const value = parseFloat(inputs[i].value) || 0;
224
- const percent = (value - min) * 100 / (max - min);
225
- const fix = thumb / 2 - thumb * percent / 100;
226
- percents.push(percent + fix);
227
- values.push(value);
228
- }
229
-
230
- let percent = percents[0];
231
- let start = 0;
232
- let end = 100 - start - percent;
233
- let value1 = values[0];
234
- let value2 = values[1] || 0;
235
- if (inputs.length > 1) {
236
- percent = Math.abs(percents[1] - percents[0]);
237
- start = percents[1] > percents[0] ? percents[0] : percents[1];
238
- end = 100 - start - percent;
239
-
240
- if (value2 > value1) {
241
- value1 = values[1] || 0;
242
- value2 = values[0];
243
- }
244
- }
245
-
246
- parentTarget.style.setProperty("---start", `${start}%`);
247
- parentTarget.style.setProperty("---end", `${end}%`);
248
- parentTarget.style.setProperty("---value1", `'${value1}'`);
249
- parentTarget.style.setProperty("---value2", `'${value2}'`);
250
- }
251
-
252
- function updateAllRanges (e?: Event) {
253
- if (e) {
254
- const input = e.target as HTMLInputElement;
255
- if (input.type === "range") { updateRange(input); return; }
256
- }
257
-
258
- const ranges = queryAll(".slider > input[type=range]") as NodeListOf<HTMLInputElement>;
259
- if (!ranges.length) off(globalThis, "input", updateAllRanges, false);
260
- else on(globalThis, "input", updateAllRanges, false);
261
- for (let i = 0, n = ranges.length; i < n; i++) updateRange(ranges[i]);
262
- }
263
-
264
- async function open (from: Element, to: Element | null, options?: any, e?: Event): Promise<void> {
265
- if (!to) {
266
- to = query(from.getAttribute("data-ui"));
267
- if (!to) return;
268
- }
269
-
270
- if (hasTag(to, "dialog")) { await dialog(from, to); return; }
271
- if (hasTag(to, "menu")) { menu(from, to, e); return; }
272
- if (hasClass(to, "snackbar")) { snackbar(from, to, options as number); return; }
273
- if (hasClass(to, "page")) { page(from, to); return; }
274
-
275
- tab(from);
276
-
277
- if (hasClass(to, "active")) { removeClass(to, "active"); return; }
278
-
279
- addClass(to, "active");
280
- }
281
-
282
- function tab (from: Element): void {
283
- if (from.id && hasClass(from, "page")) from = query(`[data-ui="#${from.id}"]`) ?? from;
284
-
285
- const container = parent(from);
286
- if (!hasClass(container, "tabs")) return;
287
- const tabs = queryAll("a", container);
288
- for (let i = 0, n = tabs.length; i < n; i++) removeClass(tabs[i], "active");
289
- addClass(from, "active");
290
- }
291
-
292
- function page (from: Element, to: Element): void {
293
- tab(from);
294
- const container = parent(to);
295
- if (container) {
296
- for (let i = 0, n = container.children.length; i < n; i++) {
297
- if (hasClass(container.children[i], "page")) removeClass(container.children[i], "active");
298
- }
299
- }
300
- addClass(to, "active");
301
- }
302
-
303
- function menu (from: Element, to: Element, e?: Event) {
304
- if (_timeoutMenu) clearTimeout(_timeoutMenu);
305
-
306
- _timeoutMenu = setTimeout(() => {
307
- on(document.body, "click", onClickDocument);
308
- const activeElement = document.activeElement as HTMLElement;
309
- if (!hasTag(activeElement, "input")) activeElement?.blur();
310
- tab(from);
311
-
312
- const isActive = hasClass(to, "active");
313
- const isEvent = !!(e?.target === from);
314
- const isChild = !!from.closest("menu");
315
-
316
- if ((!isActive && isChild) || (isActive && isEvent)) {
317
- removeClass(to, "active");
318
- return;
319
- }
320
-
321
- const menus = queryAll("menu.active");
322
- for (let i = 0, n = menus.length; i < n; i++) removeClass(menus[i], "active");
323
- addClass(to, "active");
324
- }, 90);
325
- }
326
-
327
- async function dialog (from: Element, to: Element): Promise<void> {
328
- (document.activeElement as HTMLElement)?.blur();
329
- tab(from);
330
-
331
- let overlay = prev(to) as HTMLElement;
332
- const target = to as HTMLDialogElement;
333
- const isActive = hasClass(to, "active") || target.open;
334
- const isModal = hasClass(to, "modal");
335
- const container = parent(to);
336
- const isNav = hasTag(container, "nav");
337
-
338
- if (!hasClass(overlay, "overlay")) {
339
- overlay = create({ class: "overlay" });
340
- insertBefore(overlay, to);
341
- await wait(90);
342
- }
343
-
344
- overlay.onclick = () => {
345
- if (isModal) return;
346
-
347
- removeClass(from, "active");
348
- removeClass(to, "active");
349
- removeClass(overlay, "active");
350
- target.close();
351
- };
352
-
353
- if (isNav) {
354
- const elements = queryAll("dialog, a, .overlay", container);
355
- for (let i = 0, n = elements.length; i < n; i++) {
356
- const element = elements[i] as any;
357
- removeClass(element, "active");
358
- if (element.open) element.close();
359
- }
360
- }
361
-
362
- if (isActive) {
363
- removeClass(from, "active");
364
- removeClass(overlay, "active");
365
- removeClass(to, "active");
366
- target.close();
367
- } else {
368
- if (!hasTag(from, "button") && !hasClass(from, "button") && !hasClass(from, "chip")) addClass(from, "active");
369
- addClass(overlay, "active");
370
- addClass(to, "active");
371
-
372
- if (isModal) target.showModal();
373
- else target.show();
374
- }
375
- }
376
-
377
- function snackbar (from: Element, to: Element, milliseconds?: number): void {
378
- (document.activeElement as HTMLElement)?.blur();
379
- tab(from);
380
-
381
- const elements = queryAll(".snackbar.active");
382
- for (let i = 0, n = elements.length; i < n; i++) removeClass(elements[i], "active");
383
- addClass(to, "active");
384
- on(to, "click", onClickSnackbar);
385
-
386
- if (_timeoutSnackbar) clearTimeout(_timeoutSnackbar);
387
-
388
- if (milliseconds === -1) return;
389
-
390
- _timeoutSnackbar = setTimeout(() => {
391
- removeClass(to, "active");
392
- }, milliseconds ?? 6000);
393
- }
394
-
395
- function lastTheme (): IBeerCssTheme {
396
- if (_lastTheme.light && _lastTheme.dark) return _lastTheme;
397
-
398
- const light = document.createElement("body");
399
- light.className = "light";
400
- document.body.appendChild(light);
401
-
402
- const dark = document.createElement("body");
403
- dark.className = "dark";
404
- document.body.appendChild(dark);
405
-
406
- const fromLight = getComputedStyle(light);
407
- const fromDark = getComputedStyle(dark);
408
- const variables = ["--primary", "--on-primary", "--primary-container", "--on-primary-container", "--secondary", "--on-secondary", "--secondary-container", "--on-secondary-container", "--tertiary", "--on-tertiary", "--tertiary-container", "--on-tertiary-container", "--error", "--on-error", "--error-container", "--on-error-container", "--background", "--on-background", "--surface", "--on-surface", "--surface-variant", "--on-surface-variant", "--outline", "--outline-variant", "--shadow", "--scrim", "--inverse-surface", "--inverse-on-surface", "--inverse-primary", "--surface-dim", "--surface-bright", "--surface-container-lowest", "--surface-container-low", "--surface-container", "--surface-container-high", "--surface-container-highest"];
409
- for (let i = 0, n = variables.length; i < n; i++) {
410
- _lastTheme.light += variables[i] + ":" + fromLight.getPropertyValue(variables[i]) + ";";
411
- _lastTheme.dark += variables[i] + ":" + fromDark.getPropertyValue(variables[i]) + ";";
412
- }
413
-
414
- document.body.removeChild(light);
415
- document.body.removeChild(dark);
416
- return _lastTheme;
417
- }
418
-
419
- function theme (source?: IBeerCssTheme | any): IBeerCssTheme | Promise<IBeerCssTheme> {
420
- if (!source || !(globalThis as any).materialDynamicColors) return lastTheme();
421
-
422
- const mode = /dark/i.test(document.body.className) ? "dark" : "light";
423
- if (source.light && source.dark) {
424
- _lastTheme.light = source.light;
425
- _lastTheme.dark = source.dark;
426
- document.body.setAttribute("style", source[mode]);
427
- return source;
428
- }
429
-
430
- return (globalThis as any).materialDynamicColors(source).then((theme: IBeerCssTheme) => {
431
- const toCss = (data: any) => {
432
- let style = "";
433
- for (let i = 0, keys = Object.keys(data), n = keys.length; i < n; i++) {
434
- const key = keys[i];
435
- const value = data[key] as string;
436
- const kebabCase = key.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, "$1-$2").toLowerCase();
437
- style += "--" + kebabCase + ":" + value + ";";
438
- }
439
- return style;
440
- };
441
-
442
- _lastTheme.light = toCss(theme.light);
443
- _lastTheme.dark = toCss(theme.dark);
444
- document.body.setAttribute("style", _lastTheme[mode]);
445
- return _lastTheme;
446
- });
447
- }
448
-
449
- function mode (value: string): string {
450
- if (!value) return /dark/i.test(document.body.className) ? "dark" : "light";
451
- document.body.classList.remove("light", "dark");
452
- document.body.classList.add(value);
453
- const lastThemeStyle = value === "light" ? _lastTheme.light : _lastTheme.dark;
454
- if ((globalThis as any).materialDynamicColors) document.body.setAttribute("style", lastThemeStyle);
455
- return value;
456
- }
457
-
458
- function setup () {
19
+ function setup() {
459
20
  if (_mutation) return;
460
21
  _mutation = new MutationObserver(onMutation);
461
22
  _mutation.observe(document.body, { childList: true, subtree: true });
462
23
  onMutation();
463
24
  }
464
25
 
465
- function ui (selector?: string | Element, options?: string | number | IBeerCssTheme): string | IBeerCssTheme | Promise<IBeerCssTheme> | undefined {
26
+ function updateAllDataUis() {
27
+ const elements = queryAll("[data-ui]");
28
+ for (let i = 0, n = elements.length; i < n; i++) on(elements[i], "click", onClickElement);
29
+ }
30
+
31
+ function ui(selector?: string | Element, options?: string | number | IBeerCssTheme): string | IBeerCssTheme | Promise<IBeerCssTheme> | undefined {
466
32
  if (selector) {
467
33
  if (selector === "setup") { setup(); return; }
468
34
  if (selector === "guid") return guid();
469
- if (selector === "mode") return mode(options as string);
470
- if (selector === "theme") return theme(options);
35
+ if (selector === "mode") return updateMode(options as string);
36
+ if (selector === "theme") return updateTheme(options);
471
37
 
472
38
  const to = query(selector);
473
39
  if (!to) return;
474
- void open(to, to, options);
475
- }
476
-
477
- const elements = queryAll("[data-ui]");
478
- for (let i = 0, n = elements.length; i < n; i++) on(elements[i], "click", onClickElement);
479
-
480
- const labels = queryAll(".field > label");
481
- for (let i = 0, n = labels.length; i < n; i++) on(labels[i], "click", onClickLabel);
482
-
483
- const inputs = queryAll(".field > input:not([type=file], [type=color], [type=range]), .field > select, .field > textarea");
484
- for (let i = 0, n = inputs.length; i < n; i++) {
485
- const input = inputs[i];
486
- on(input, "focus", onFocusInput);
487
- on(input, "blur", onBlurInput);
488
- updateInput(input);
489
- }
490
-
491
- const files = queryAll(".field > input[type=file]");
492
- for (let i = 0, n = files.length; i < n; i++) {
493
- const file = files[i];
494
- on(file, "change", onChangeFile);
495
- updateFile(file);
40
+ run(to, to, options);
496
41
  }
497
42
 
498
- const colors = queryAll(".field > input[type=color]");
499
- for (let i = 0, n = colors.length; i < n; i++) {
500
- const color = colors[i];
501
- on(color, "change", onChangeColor);
502
- updateColor(color);
503
- }
504
-
505
- const textareas = queryAll(".field.textarea > textarea");
506
- for (let i = 0, n = textareas.length; i < n; i++) {
507
- const textarea = textareas[i];
508
- on(textarea, "input", onInputTextarea);
509
- updateTextarea(textarea);
510
- }
43
+ updateAllDataUis();
44
+ updateAllFields();
45
+ updateAllSliders();
46
+ }
511
47
 
512
- updateAllRanges();
48
+ function start() {
49
+ const context = (globalThis as any);
50
+ const body = context?.document?.body;
51
+
52
+ if (body && !body.classList.contains("dark") && !body.classList.contains("light")) updateMode("auto");
53
+
54
+ on(context, "load", setup, false);
55
+ context.beercss = ui;
56
+ context.ui = ui;
513
57
  }
514
58
 
515
- if ((globalThis as any).addEventListener) (globalThis as any).addEventListener("load", async () => await ui("setup"));
516
- (globalThis as any).beercss = ui;
517
- (globalThis as any).ui = ui;
59
+ start();
518
60
  export default ui;
@@ -18,6 +18,7 @@ dialog {
18
18
  transition: all var(--speed3), 0s background-color;
19
19
  border-radius: 1.75rem;
20
20
  transform: translate(-50%, -4rem);
21
+ outline: none;
21
22
  }
22
23
 
23
24
  dialog::backdrop {
@@ -0,0 +1,68 @@
1
+ import { addClass, next, prev, hasTag, insertBefore, wait, create, hasClass, removeClass, on, off, queryAllDataUi, isTouchable, blurActiveElement } from "../utils";
2
+
3
+ const _dialogs: Array<HTMLDialogElement> = [];
4
+
5
+ function onKeydownDialog(e: KeyboardEvent) {
6
+ if (e.key === "Escape") {
7
+ const dialog = e.currentTarget as HTMLDialogElement;
8
+ updateDialog(dialog, dialog);
9
+ }
10
+ }
11
+
12
+ function closeDialog(dialog: HTMLDialogElement, overlay: Element) {
13
+ removeClass(queryAllDataUi(dialog.id), "active");
14
+ removeClass(dialog, "active");
15
+ removeClass(overlay, "active");
16
+
17
+ dialog.close();
18
+ _dialogs.pop();
19
+
20
+ const previousDialog = _dialogs[_dialogs.length - 1];
21
+ if (previousDialog) previousDialog.focus();
22
+ else if (isTouchable()) document.body.classList.remove("no-scroll");
23
+ }
24
+
25
+ async function openDialog(dialog: HTMLDialogElement, overlay: Element, isModal: boolean, from: Element) {
26
+ if (!hasTag(from, "button") && !hasClass(from, "button") && !hasClass(from, "chip")) addClass(from, "active");
27
+ addClass(overlay, "active");
28
+ addClass(dialog, "active");
29
+
30
+ if (isModal) dialog.showModal();
31
+ else dialog.show();
32
+
33
+ await wait(90);
34
+
35
+ if (!isModal) on(dialog, "keydown", onKeydownDialog, false);
36
+
37
+ _dialogs.push(dialog);
38
+ dialog.focus();
39
+
40
+ if (isTouchable()) document.body.classList.add("no-scroll");
41
+ }
42
+
43
+ function onClickOverlay(e: Event) {
44
+ const overlay = e.currentTarget as Element;
45
+ const dialog = next(overlay) as HTMLDialogElement;
46
+ if (hasTag(dialog, "dialog")) closeDialog(dialog, overlay);
47
+ }
48
+
49
+ export async function updateDialog(from: Element, dialog: HTMLDialogElement): Promise<void> {
50
+ blurActiveElement();
51
+
52
+ let overlay = prev(dialog) as HTMLElement;
53
+ const isActive = hasClass(dialog, "active") || dialog.open;
54
+ const isModal = hasClass(dialog, "modal");
55
+
56
+ if (!isModal) off(dialog, "keydown", onKeydownDialog, false);
57
+
58
+ if (!hasClass(overlay, "overlay")) {
59
+ overlay = create({ class: "overlay" });
60
+ insertBefore(overlay, dialog);
61
+ await wait(90);
62
+ }
63
+
64
+ if (!isModal) on(overlay, "click", onClickOverlay, false);
65
+
66
+ if (isActive) closeDialog(dialog, overlay);
67
+ else openDialog(dialog, overlay, isModal, from);
68
+ }
@@ -129,7 +129,7 @@ input::-webkit-date-and-time-value {
129
129
 
130
130
  :is(input, select, textarea):-webkit-autofill {
131
131
  -webkit-background-clip: text;
132
- -webkit-text-fill-color: inherit;
132
+ -webkit-text-fill-color: var(--on-surface);
133
133
  }
134
134
 
135
135
  .field > :is(input, textarea, select):focus {
@@ -141,6 +141,7 @@ input::-webkit-date-and-time-value {
141
141
  overflow: hidden;
142
142
  position: absolute;
143
143
  inset: 0;
144
+ max-block-size: 12rem;
144
145
  }
145
146
 
146
147
  input[type=file],