@expressivecss/expressive 0.8.0 → 0.9.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 (50) hide show
  1. package/CHANGELOG.md +48 -1
  2. package/README.md +69 -26
  3. package/dist/css/expressive.css +657 -85
  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/LICENSE-material-symbols +93 -0
  8. package/dist/fonts/LICENSE-noto-sans +93 -0
  9. package/dist/fonts/LICENSE-roboto +93 -0
  10. package/dist/fonts/material-symbols-outlined.woff2 +0 -0
  11. package/dist/fonts/material-symbols-rounded.woff2 +0 -0
  12. package/dist/fonts/material-symbols-sharp.woff2 +0 -0
  13. package/dist/fonts/noto-sans-latin-400.woff2 +0 -0
  14. package/dist/fonts/noto-sans-latin-500.woff2 +0 -0
  15. package/dist/fonts/roboto-latin-400.woff2 +0 -0
  16. package/dist/fonts/roboto-latin-500.woff2 +0 -0
  17. package/dist/js/expressive.cjs +501 -144
  18. package/dist/js/expressive.cjs.map +4 -4
  19. package/dist/js/expressive.js +501 -144
  20. package/dist/js/expressive.js.map +4 -4
  21. package/dist/js/expressive.min.js +10 -10
  22. package/dist/js/expressive.min.js.map +4 -4
  23. package/dist/js/expressive.mjs +501 -144
  24. package/dist/js/expressive.mjs.map +4 -4
  25. package/dist/types/components/appBar.d.ts +26 -0
  26. package/dist/types/components/buttonGroup.d.ts +39 -0
  27. package/dist/types/components/cards.d.ts +11 -13
  28. package/dist/types/components/expandingCard.d.ts +1 -1
  29. package/dist/types/components/index.d.ts +2 -0
  30. package/dist/types/components/menu.d.ts +4 -0
  31. package/dist/types/components/registry.d.ts +10 -0
  32. package/dist/types/components/timepicker.d.ts +0 -1
  33. package/dist/types/components/tooltip.d.ts +1 -0
  34. package/dist/types/index.d.ts +1 -1
  35. package/package.json +25 -3
  36. package/src/sass/abstracts/_mixins.scss +52 -0
  37. package/src/sass/abstracts/_variables.scss +19 -0
  38. package/src/sass/base/_fonts.scss +63 -0
  39. package/src/sass/components/_badges.scss +1 -2
  40. package/src/sass/components/_button-groups.scss +252 -80
  41. package/src/sass/components/_cards.scss +108 -93
  42. package/src/sass/components/_expanding-card.scss +1 -35
  43. package/src/sass/components/_icon-buttons.scss +2 -24
  44. package/src/sass/components/_icons-material-design.scss +6 -6
  45. package/src/sass/components/_navbar.scss +180 -27
  46. package/src/sass/components/_navigation-bar.scss +9 -1
  47. package/src/sass/components/_navigation-rail.scss +9 -1
  48. package/src/sass/components/_transitions.scss +8 -1
  49. package/src/sass/components/forms/_select.scss +38 -0
  50. package/src/sass/expressive.scss +5 -0
@@ -19,9 +19,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/ts/index.ts
20
20
  var index_exports = {};
21
21
  __export(index_exports, {
22
+ AppBar: () => AppBar,
22
23
  AutoInit: () => AutoInit,
23
24
  Autocomplete: () => Autocomplete,
24
25
  BottomSheets: () => BottomSheets,
26
+ ButtonGroup: () => ButtonGroup,
25
27
  Cards: () => Cards,
26
28
  Carousel: () => Carousel,
27
29
  CharacterCounter: () => CharacterCounter,
@@ -431,103 +433,120 @@ var _defaults = {
431
433
  onOpen: null,
432
434
  onClose: null
433
435
  };
434
- var CARDS_SELECTOR = "article:has(> aside)";
436
+ var CARDS_SELECTOR = 'article:has(> aside[id]:not([id=""])):not(:has(> aside ~ aside)):has(> button.card-reveal-trigger[type="button"], > :not(aside) button.card-reveal-trigger[type="button"])';
437
+ var REVEAL_INITIALIZED_CLASS = "card-reveal-initialized";
438
+ function hasAccessibleName(trigger) {
439
+ const label = trigger.getAttribute("aria-label");
440
+ if (label?.trim()) return true;
441
+ const labelledBy = trigger.getAttribute("aria-labelledby");
442
+ if (labelledBy) {
443
+ const referencedText = labelledBy.trim().split(/\s+/).map((id) => trigger.ownerDocument.getElementById(id)?.textContent ?? "").join(" ").trim();
444
+ if (referencedText) return true;
445
+ }
446
+ const content = trigger.cloneNode(true);
447
+ content.querySelectorAll('[aria-hidden="true"]').forEach((node) => node.remove());
448
+ return Boolean(content.textContent?.trim());
449
+ }
450
+ function isUsableCardTrigger(trigger, card, panel) {
451
+ return trigger.closest("article") === card && !panel.contains(trigger) && !trigger.disabled && trigger.getAttribute("aria-disabled") !== "true" && hasAccessibleName(trigger);
452
+ }
453
+ function isCardReveal(el) {
454
+ if (el.tagName !== "ARTICLE") return false;
455
+ const panels = el.querySelectorAll(":scope > aside");
456
+ if (panels.length !== 1 || !panels[0].id) return false;
457
+ return Array.from(
458
+ el.querySelectorAll('button.card-reveal-trigger[type="button"]')
459
+ ).some((trigger) => isUsableCardTrigger(trigger, el, panels[0]));
460
+ }
435
461
  var Cards = class _Cards extends Component {
436
- constructor(el, options) {
462
+ constructor(el, options = {}) {
437
463
  super(el, options, _Cards);
438
464
  this.isOpen = false;
465
+ this._ownsRevealInitializedClass = false;
466
+ this._initialAriaControls = /* @__PURE__ */ new Map();
467
+ this._lastActivator = null;
439
468
  this._setupEventHandlers = () => {
440
- this._activators.forEach((el) => {
441
- el.addEventListener("click", this._handleClickInteraction);
442
- el.addEventListener("keypress", this._handleKeypressEvent);
469
+ this._activators.forEach((activator) => {
470
+ activator.addEventListener("click", this._handleClickInteraction);
443
471
  });
472
+ this.el.addEventListener("keydown", this._handleKeydownEvent);
444
473
  };
445
474
  this._removeEventHandlers = () => {
446
- this._activators.forEach((el) => {
447
- el.removeEventListener("click", this._handleClickInteraction);
448
- el.removeEventListener("keypress", this._handleKeypressEvent);
475
+ this._activators.forEach((activator) => {
476
+ activator.removeEventListener("click", this._handleClickInteraction);
449
477
  });
478
+ this.el.removeEventListener("keydown", this._handleKeydownEvent);
450
479
  };
451
- this._handleClickInteraction = () => {
480
+ this._handleClickInteraction = (event) => {
481
+ this._lastActivator = event.currentTarget;
452
482
  this._handleRevealEvent();
453
483
  };
454
- this._handleKeypressEvent = (e) => {
455
- if (e.key === Utils.keys.ENTER || e.key === " ") {
456
- e.preventDefault();
457
- this._handleRevealEvent();
458
- }
484
+ this._handleKeydownEvent = (event) => {
485
+ const target = event.target instanceof Element ? event.target.closest("article") : null;
486
+ if (target !== this.el || event.key !== "Escape" || !this.isOpen) return;
487
+ event.preventDefault();
488
+ this.close();
459
489
  };
460
490
  this._handleRevealEvent = () => {
461
491
  if (this.isOpen) this.close();
462
492
  else this.open();
463
493
  };
464
- this._setupRevealCloseEventHandlers = () => {
465
- this.cardRevealClose.addEventListener("click", this.close);
466
- this.cardRevealClose.addEventListener("keypress", this._handleKeypressCloseEvent);
467
- };
468
- this._removeRevealCloseEventHandlers = () => {
469
- this.cardRevealClose.removeEventListener("click", this.close);
470
- this.cardRevealClose.removeEventListener("keypress", this._handleKeypressCloseEvent);
471
- };
472
- this._handleKeypressCloseEvent = (e) => {
473
- if (e.key === Utils.keys.ENTER) {
474
- this.close();
475
- }
476
- };
477
494
  /**
478
495
  * Show card reveal.
479
496
  */
480
497
  this.open = () => {
481
498
  if (this.isOpen || !this.cardReveal) return;
482
499
  this.isOpen = true;
483
- this.cardReveal.ariaExpanded = "true";
484
- this._activators.forEach((el) => el.ariaExpanded = "true");
485
- if (this.cardRevealClose) this.cardRevealClose.tabIndex = 0;
500
+ this.cardReveal.classList.add("open");
501
+ this.cardReveal.inert = false;
502
+ this._activators.forEach((activator) => activator.ariaExpanded = "true");
486
503
  if (typeof this.options.onOpen === "function") {
487
- this.options.onOpen.call(this);
504
+ this.options.onOpen.call(this, this.el);
488
505
  }
489
- if (this.cardRevealClose) this._setupRevealCloseEventHandlers();
490
506
  };
491
507
  /**
492
508
  * Hide card reveal.
493
509
  */
494
510
  this.close = () => {
495
511
  if (!this.isOpen || !this.cardReveal) return;
512
+ const focusWasInside = this.cardReveal.contains(document.activeElement);
496
513
  this.isOpen = false;
497
- this.cardReveal.ariaExpanded = "false";
498
- this._activators.forEach((el) => el.ariaExpanded = "false");
499
- if (this.cardRevealClose) this.cardRevealClose.tabIndex = -1;
514
+ this.cardReveal.classList.remove("open");
515
+ this.cardReveal.inert = true;
516
+ this._activators.forEach((activator) => activator.ariaExpanded = "false");
500
517
  if (typeof this.options.onClose === "function") {
501
- this.options.onClose.call(this);
518
+ this.options.onClose.call(this, this.el);
519
+ }
520
+ if (focusWasInside) {
521
+ (this._lastActivator ?? this._activators[0])?.focus();
502
522
  }
503
- if (this.cardRevealClose) this._removeRevealCloseEventHandlers();
504
523
  };
505
524
  this.el["Expressive_Cards"] = this;
506
525
  this.options = {
507
526
  ..._Cards.defaults,
508
527
  ...options
509
528
  };
510
- this._activators = [];
511
- this.cardReveal = this.el.querySelector(":scope > aside");
529
+ const cardReveals = this.el.querySelectorAll(":scope > aside");
530
+ const cardReveal = cardReveals.length === 1 ? cardReveals[0] : null;
531
+ const activators = cardReveal ? Array.from(
532
+ this.el.querySelectorAll(
533
+ 'button.card-reveal-trigger[type="button"]'
534
+ )
535
+ ).filter(
536
+ (activator) => isUsableCardTrigger(activator, this.el, cardReveal)
537
+ ) : [];
538
+ this.cardReveal = cardReveal?.id && activators.length > 0 ? cardReveal : null;
539
+ this._activators = this.cardReveal ? activators : [];
512
540
  if (this.cardReveal) {
513
- this._activators = Array.from(
514
- this.el.querySelectorAll(".activator")
515
- ).filter(
516
- (activator) => !this.cardReveal.contains(activator)
517
- );
518
- this._activators.forEach((el2) => {
519
- if (!el2) return;
520
- el2.tabIndex = 0;
521
- el2.ariaExpanded = "false";
522
- if (!el2.matches("a[href], button, input, select, textarea")) {
523
- el2.setAttribute("role", "button");
524
- }
541
+ this._ownsRevealInitializedClass = !this.el.classList.contains(REVEAL_INITIALIZED_CLASS);
542
+ this.el.classList.add(REVEAL_INITIALIZED_CLASS);
543
+ this._activators.forEach((activator) => {
544
+ this._initialAriaControls.set(activator, activator.getAttribute("aria-controls"));
545
+ activator.ariaExpanded = "false";
546
+ activator.setAttribute("aria-controls", this.cardReveal.id);
525
547
  });
526
- this.cardRevealClose = this.cardReveal.querySelector(
527
- ":scope > :is(h1, h2, h3, h4, h5, h6)"
528
- );
529
- if (this.cardRevealClose) this.cardRevealClose.tabIndex = -1;
530
- this.cardReveal.ariaExpanded = "false";
548
+ this.cardReveal.classList.remove("open");
549
+ this.cardReveal.inert = true;
531
550
  this._setupEventHandlers();
532
551
  }
533
552
  }
@@ -550,13 +569,28 @@ var Cards = class _Cards extends Component {
550
569
  */
551
570
  destroy() {
552
571
  this._removeEventHandlers();
553
- if (this.cardRevealClose) this._removeRevealCloseEventHandlers();
572
+ if (this.cardReveal) {
573
+ this.cardReveal.classList.remove("open");
574
+ this.cardReveal.inert = false;
575
+ if (this._ownsRevealInitializedClass) this.el.classList.remove(REVEAL_INITIALIZED_CLASS);
576
+ }
577
+ this._activators.forEach((activator) => {
578
+ activator.removeAttribute("aria-expanded");
579
+ const initialAriaControls = this._initialAriaControls.get(activator);
580
+ if (initialAriaControls === null) activator.removeAttribute("aria-controls");
581
+ else if (initialAriaControls !== void 0) {
582
+ activator.setAttribute("aria-controls", initialAriaControls);
583
+ }
584
+ });
585
+ this.isOpen = false;
554
586
  this._activators = [];
587
+ this._initialAriaControls.clear();
588
+ this._lastActivator = null;
555
589
  this.el["Expressive_Cards"] = void 0;
556
590
  }
557
591
  static Init() {
558
592
  Utils.onDocumentReady(() => {
559
- const cards = document.querySelectorAll(CARDS_SELECTOR);
593
+ const cards = Array.from(document.querySelectorAll(CARDS_SELECTOR)).filter(isCardReveal);
560
594
  cards.forEach((el) => {
561
595
  if (el && el["Expressive_Cards"] == void 0) this.init(el);
562
596
  });
@@ -569,13 +603,12 @@ var _defaults2 = {
569
603
  onOpen: null,
570
604
  onClose: null
571
605
  };
572
- var MOTION_DURATION = 500;
573
606
  var EXPANDING_CARD_SELECTOR = "article.expanding-card:has(> dialog.expanding-card-dialog)";
574
607
  var ExpandingCard = class _ExpandingCard extends Component {
575
608
  constructor(el, options) {
576
609
  super(el, options, _ExpandingCard);
577
610
  this.isOpen = false;
578
- this.closeTimer = null;
611
+ this.closeGeneration = 0;
579
612
  this._setupEventHandlers = () => {
580
613
  this.trigger?.addEventListener("click", this.open);
581
614
  this.trigger?.addEventListener("keypress", this._handleTriggerKeypress);
@@ -601,7 +634,8 @@ var ExpandingCard = class _ExpandingCard extends Component {
601
634
  this.close();
602
635
  };
603
636
  this._handleNativeClose = () => {
604
- if (!this.isOpen) return;
637
+ if (this.dialog.open) return;
638
+ this.closeGeneration++;
605
639
  this.isOpen = false;
606
640
  this.trigger.ariaExpanded = "false";
607
641
  this.dialog.ariaExpanded = "false";
@@ -637,10 +671,7 @@ var ExpandingCard = class _ExpandingCard extends Component {
637
671
  };
638
672
  this.open = () => {
639
673
  if (this.isOpen || !this.dialog || !this.trigger) return;
640
- if (this.closeTimer !== null) {
641
- window.clearTimeout(this.closeTimer);
642
- this.closeTimer = null;
643
- }
674
+ this.closeGeneration++;
644
675
  this._setTransitionOrigin();
645
676
  this.isOpen = true;
646
677
  this.trigger.ariaExpanded = "true";
@@ -655,6 +686,7 @@ var ExpandingCard = class _ExpandingCard extends Component {
655
686
  };
656
687
  this.close = () => {
657
688
  if (!this.isOpen || !this.dialog || !this.trigger) return;
689
+ const generation = ++this.closeGeneration;
658
690
  this._setTransitionOrigin();
659
691
  this.isOpen = false;
660
692
  this.trigger.ariaExpanded = "false";
@@ -664,15 +696,16 @@ var ExpandingCard = class _ExpandingCard extends Component {
664
696
  this.options.onClose.call(this, this.el);
665
697
  }
666
698
  const finish = () => {
667
- this.closeTimer = null;
668
- if (this.dialog.open) this.dialog.close();
669
- this.trigger.focus();
699
+ if (generation !== this.closeGeneration || this.isOpen || !this.dialog.open) return;
700
+ this.dialog.close();
701
+ if (this.dialog.isConnected && this.trigger.isConnected) this.trigger.focus();
670
702
  };
671
703
  const reducedMotion = window.matchMedia(
672
704
  "(prefers-reduced-motion: reduce)"
673
705
  ).matches;
674
- if (reducedMotion) finish();
675
- else this.closeTimer = window.setTimeout(finish, MOTION_DURATION);
706
+ const transitions = reducedMotion ? [] : (this.dialog.getAnimations?.() ?? []).filter((animation) => animation.transitionProperty === "clip-path");
707
+ if (transitions.length === 0) finish();
708
+ else void Promise.allSettled(transitions.map((animation) => animation.finished)).then(finish);
676
709
  };
677
710
  this.el["Expressive_ExpandingCard"] = this;
678
711
  this.options = {
@@ -709,7 +742,10 @@ var ExpandingCard = class _ExpandingCard extends Component {
709
742
  }
710
743
  destroy() {
711
744
  this._removeEventHandlers();
712
- if (this.closeTimer !== null) window.clearTimeout(this.closeTimer);
745
+ this.closeGeneration++;
746
+ this.isOpen = false;
747
+ if (this.trigger) this.trigger.ariaExpanded = "false";
748
+ if (this.dialog) this.dialog.ariaExpanded = "false";
713
749
  this.dialog?.classList.remove("expanded");
714
750
  if (this.dialog?.open) this.dialog.close();
715
751
  this.el["Expressive_ExpandingCard"] = void 0;
@@ -748,6 +784,8 @@ var SPACE = " ";
748
784
  var _Menu = class _Menu extends Component {
749
785
  constructor(el, options) {
750
786
  super(el, options, _Menu);
787
+ this._pendingTimers = /* @__PURE__ */ new Set();
788
+ this._transition = 0;
751
789
  this._handleClick = (e) => {
752
790
  e.preventDefault();
753
791
  if (this.isOpen) {
@@ -781,7 +819,7 @@ var _Menu = class _Menu extends Component {
781
819
  if (this.options.closeOnClick && this.menuEl?.contains(target) && !this.isTouchMoving) {
782
820
  this.close();
783
821
  } else if (!this.menuEl?.contains(target)) {
784
- setTimeout(() => {
822
+ this._schedule(() => {
785
823
  if (this.isOpen) {
786
824
  this.close();
787
825
  }
@@ -935,16 +973,18 @@ var _Menu = class _Menu extends Component {
935
973
  * Open menu.
936
974
  */
937
975
  this.open = () => {
938
- if (this.isOpen) return;
976
+ if (this.isOpen || this.el["Expressive_Menu"] !== this) return;
977
+ const transition = this._clearPendingTimers();
939
978
  this.isOpen = true;
940
979
  if (typeof this.options.onOpenStart === "function") {
941
980
  this.options.onOpenStart.call(this, this.el);
942
981
  }
982
+ if (transition !== this._transition) return;
943
983
  this._resetMenuStyles();
944
984
  this.menuEl.style.display = "block";
945
985
  this._placeMenu();
986
+ this._schedule(() => this._setupTemporaryEventHandlers(), 0);
946
987
  this._animateIn();
947
- setTimeout(() => this._setupTemporaryEventHandlers(), 0);
948
988
  this.el.ariaExpanded = "true";
949
989
  };
950
990
  /**
@@ -952,18 +992,20 @@ var _Menu = class _Menu extends Component {
952
992
  */
953
993
  this.close = () => {
954
994
  if (!this.isOpen) return;
995
+ const transition = this._clearPendingTimers();
955
996
  this.isOpen = false;
956
997
  this.focusedIndex = -1;
957
998
  this._closeSubmenus();
958
999
  if (typeof this.options.onCloseStart === "function") {
959
1000
  this.options.onCloseStart.call(this, this.el);
960
1001
  }
1002
+ if (transition !== this._transition) return;
961
1003
  this._animateOut();
962
1004
  this._removeTemporaryEventHandlers();
1005
+ this.el.ariaExpanded = "false";
963
1006
  if (this.options.autoFocus) {
964
1007
  this.el.focus();
965
1008
  }
966
- this.el.ariaExpanded = "false";
967
1009
  };
968
1010
  /**
969
1011
  * While menu is open, you can recalculate its dimensions if its contents have changed.
@@ -1012,6 +1054,9 @@ var _Menu = class _Menu extends Component {
1012
1054
  return el["Expressive_Menu"];
1013
1055
  }
1014
1056
  destroy() {
1057
+ this._clearPendingTimers();
1058
+ this.isOpen = false;
1059
+ this.el.ariaExpanded = "false";
1015
1060
  clearTimeout(this.filterTimeout);
1016
1061
  this._resetMenuStyles();
1017
1062
  this._removeEventHandlers();
@@ -1274,18 +1319,32 @@ var _Menu = class _Menu extends Component {
1274
1319
  width: idealWidth
1275
1320
  };
1276
1321
  }
1322
+ _schedule(callback, delay) {
1323
+ const timer = setTimeout(() => {
1324
+ this._pendingTimers.delete(timer);
1325
+ callback();
1326
+ }, delay);
1327
+ this._pendingTimers.add(timer);
1328
+ }
1329
+ _clearPendingTimers() {
1330
+ for (const timer of this._pendingTimers) clearTimeout(timer);
1331
+ this._pendingTimers.clear();
1332
+ return ++this._transition;
1333
+ }
1277
1334
  _animateIn() {
1335
+ const transition = this._transition;
1278
1336
  const duration = this.options.inDuration;
1279
1337
  this.menuEl.style.transition = "none";
1280
1338
  this.menuEl.style.opacity = "0";
1281
1339
  this.menuEl.style.transform = "scale(0.85)";
1282
- setTimeout(() => {
1340
+ this._schedule(() => {
1283
1341
  this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
1284
1342
  this.menuEl.style.opacity = "1";
1285
1343
  this.menuEl.style.transform = "scale(1)";
1286
1344
  }, 1);
1287
- setTimeout(() => {
1345
+ this._schedule(() => {
1288
1346
  this._focusInitialItem();
1347
+ if (transition !== this._transition) return;
1289
1348
  if (typeof this.options.onOpenEnd === "function") this.options.onOpenEnd.call(this, this.el);
1290
1349
  }, duration);
1291
1350
  }
@@ -1294,7 +1353,7 @@ var _Menu = class _Menu extends Component {
1294
1353
  this.menuEl.style.transition = `opacity ${duration}ms ease, transform ${duration}ms ease`;
1295
1354
  this.menuEl.style.opacity = "0";
1296
1355
  this.menuEl.style.transform = "scale(0.85)";
1297
- setTimeout(() => {
1356
+ this._schedule(() => {
1298
1357
  this._resetMenuStyles();
1299
1358
  if (typeof this.options.onCloseEnd === "function")
1300
1359
  this.options.onCloseEnd.call(this, this.el);
@@ -2563,8 +2622,89 @@ var Forms = class _Forms {
2563
2622
  }
2564
2623
  };
2565
2624
 
2625
+ // src/ts/components/appBar.ts
2626
+ var _defaults7 = {};
2627
+ var AppBar = class _AppBar extends Component {
2628
+ constructor(el, options) {
2629
+ super(el, options, _AppBar);
2630
+ this._observer = null;
2631
+ this._sentinel = null;
2632
+ this._input = null;
2633
+ this._view = null;
2634
+ this._suppressSearchOpen = false;
2635
+ this._onIntersect = (entries) => {
2636
+ const entry = entries[0];
2637
+ if (!entry) return;
2638
+ this.el.classList.toggle("collapsed", !entry.isIntersecting);
2639
+ };
2640
+ this._onSearchViewClose = () => {
2641
+ this._suppressSearchOpen = true;
2642
+ };
2643
+ this._onSearchFocus = () => {
2644
+ if (!this._view) return;
2645
+ if (this._suppressSearchOpen) {
2646
+ this._suppressSearchOpen = false;
2647
+ return;
2648
+ }
2649
+ if (this._view instanceof HTMLDialogElement) {
2650
+ if (!this._view.open) this._view.showModal();
2651
+ return;
2652
+ }
2653
+ this._view.hidden = false;
2654
+ this._input?.setAttribute("aria-expanded", "true");
2655
+ };
2656
+ this.el["Expressive_AppBar"] = this;
2657
+ this.options = { ..._AppBar.defaults, ...options };
2658
+ this._setupCollapse();
2659
+ this._setupSearch();
2660
+ }
2661
+ static get defaults() {
2662
+ return _defaults7;
2663
+ }
2664
+ static init(els, options = {}) {
2665
+ return super.init(els, options, _AppBar);
2666
+ }
2667
+ static getInstance(el) {
2668
+ return el["Expressive_AppBar"];
2669
+ }
2670
+ destroy() {
2671
+ this._observer?.disconnect();
2672
+ this._observer = null;
2673
+ this._sentinel?.remove();
2674
+ this._sentinel = null;
2675
+ this._input?.removeEventListener("focus", this._onSearchFocus);
2676
+ this._view?.removeEventListener("close", this._onSearchViewClose);
2677
+ this.el.classList.remove("collapsed");
2678
+ this.el["Expressive_AppBar"] = void 0;
2679
+ }
2680
+ _setupCollapse() {
2681
+ if (!this.el.classList.contains("medium") && !this.el.classList.contains("large")) {
2682
+ return;
2683
+ }
2684
+ if (typeof IntersectionObserver === "undefined") return;
2685
+ this._sentinel = document.createElement("span");
2686
+ this._sentinel.setAttribute("aria-hidden", "true");
2687
+ this._sentinel.style.cssText = "display:block;width:100%;height:1px;margin-top:-1px;pointer-events:none;visibility:hidden";
2688
+ this.el.insertAdjacentElement("beforebegin", this._sentinel);
2689
+ this._observer = new IntersectionObserver(this._onIntersect);
2690
+ this._observer.observe(this._sentinel);
2691
+ }
2692
+ _setupSearch() {
2693
+ this._input = this.el.querySelector('input[type="search"]');
2694
+ if (!this._input) return;
2695
+ const id = this._input.getAttribute("aria-controls");
2696
+ if (id) this._view = document.getElementById(id);
2697
+ if (!this._view) this._view = this.el.querySelector(".search-view");
2698
+ if (!this._view) return;
2699
+ this._input.addEventListener("focus", this._onSearchFocus);
2700
+ if (this._view instanceof HTMLDialogElement) {
2701
+ this._view.addEventListener("close", this._onSearchViewClose);
2702
+ }
2703
+ }
2704
+ };
2705
+
2566
2706
  // src/ts/components/buttons.ts
2567
- var _defaults7 = {
2707
+ var _defaults8 = {
2568
2708
  direction: "top",
2569
2709
  hoverEnabled: true,
2570
2710
  toolbarEnabled: false
@@ -2637,7 +2777,7 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
2637
2777
  this._setupEventHandlers();
2638
2778
  }
2639
2779
  static get defaults() {
2640
- return _defaults7;
2780
+ return _defaults8;
2641
2781
  }
2642
2782
  static init(els, options = {}) {
2643
2783
  return super.init(els, options, _FloatingActionButton);
@@ -2674,8 +2814,226 @@ var FloatingActionButton = class _FloatingActionButton extends Component {
2674
2814
  }
2675
2815
  };
2676
2816
 
2817
+ // src/ts/components/buttonGroup.ts
2818
+ var _defaults9 = {};
2819
+ var VALID_SELECTION_MODES = /* @__PURE__ */ new Set(["single", "multiple"]);
2820
+ var PRESSED_CLASS = "button-group-pressed";
2821
+ var MAX_ICON_COMPRESSION = 0.15;
2822
+ var ButtonGroup = class _ButtonGroup extends Component {
2823
+ constructor(el, options = {}) {
2824
+ super(el, options, _ButtonGroup);
2825
+ this._pressedStyles = /* @__PURE__ */ new Map();
2826
+ this._releaseStyles = /* @__PURE__ */ new Map();
2827
+ this._releaseTimer = null;
2828
+ this._originalPressed = /* @__PURE__ */ new Map();
2829
+ this._activeItem = null;
2830
+ this._handleClick = (event) => {
2831
+ if (!this._selectionMode) return;
2832
+ const item = this._itemFromEvent(event);
2833
+ if (!(item instanceof HTMLButtonElement) || this._isDisabled(item)) return;
2834
+ this._rememberPressed(item);
2835
+ const willSelect = item.getAttribute("aria-pressed") !== "true";
2836
+ const selectedCount = this._toggleItems.filter(
2837
+ (button) => button.getAttribute("aria-pressed") === "true"
2838
+ ).length;
2839
+ if (!willSelect && this.el.hasAttribute("data-selection-required") && selectedCount === 1) {
2840
+ return;
2841
+ }
2842
+ if (this._selectionMode === "single" && willSelect) {
2843
+ this._toggleItems.forEach((button) => {
2844
+ this._rememberPressed(button);
2845
+ button.setAttribute("aria-pressed", "false");
2846
+ });
2847
+ }
2848
+ item.setAttribute("aria-pressed", willSelect ? "true" : "false");
2849
+ };
2850
+ this._handlePointerDown = (event) => {
2851
+ if (event.button !== 0) return;
2852
+ const item = this._itemFromEvent(event);
2853
+ if (item && !this._isDisabled(item)) this._startPress(item);
2854
+ };
2855
+ this._handleKeyDown = (event) => {
2856
+ if (event.repeat || event.key !== " " && event.key !== "Enter") return;
2857
+ const item = this._itemFromEvent(event);
2858
+ if (item && !this._isDisabled(item)) this._startPress(item);
2859
+ };
2860
+ this._handleKeyUp = (event) => {
2861
+ if (event.key === " " || event.key === "Enter") this._resetPress();
2862
+ };
2863
+ this._handleFocusOut = (event) => {
2864
+ if (event.target === this._activeItem) this._resetPress();
2865
+ };
2866
+ this._resetPress = () => {
2867
+ this._activeItem?.classList.remove(PRESSED_CLASS);
2868
+ this._activeItem = null;
2869
+ if (!this._pressedStyles.size) return;
2870
+ this._finishRelease();
2871
+ this._releaseStyles = new Map(this._pressedStyles);
2872
+ for (const [item, style] of this._releaseStyles) {
2873
+ item.style.width = `${style.baseWidth}px`;
2874
+ }
2875
+ this._pressedStyles.clear();
2876
+ this._releaseTimer = window.setTimeout(this._finishRelease, 200);
2877
+ };
2878
+ this._finishRelease = () => {
2879
+ if (this._releaseTimer !== null) window.clearTimeout(this._releaseTimer);
2880
+ this._releaseTimer = null;
2881
+ for (const [item, style] of this._releaseStyles) item.style.width = style.width;
2882
+ this._releaseStyles.clear();
2883
+ };
2884
+ this.el["Expressive_ButtonGroup"] = this;
2885
+ this.options = { ..._ButtonGroup.defaults, ...options };
2886
+ if (this._selectionMode) {
2887
+ this._normalizeSelection();
2888
+ this.el.addEventListener("click", this._handleClick, true);
2889
+ }
2890
+ this.el.addEventListener("pointerdown", this._handlePointerDown);
2891
+ this.el.addEventListener("keydown", this._handleKeyDown);
2892
+ this.el.addEventListener("focusout", this._handleFocusOut);
2893
+ document.addEventListener("pointerup", this._resetPress);
2894
+ document.addEventListener("pointercancel", this._resetPress);
2895
+ document.addEventListener("keyup", this._handleKeyUp);
2896
+ window.addEventListener("blur", this._resetPress);
2897
+ }
2898
+ static get defaults() {
2899
+ return _defaults9;
2900
+ }
2901
+ static init(els, options = {}) {
2902
+ return super.init(els, options, _ButtonGroup);
2903
+ }
2904
+ static getInstance(el) {
2905
+ return el["Expressive_ButtonGroup"];
2906
+ }
2907
+ destroy() {
2908
+ this._resetPress();
2909
+ this._finishRelease();
2910
+ this.el.removeEventListener("click", this._handleClick, true);
2911
+ this.el.removeEventListener("pointerdown", this._handlePointerDown);
2912
+ this.el.removeEventListener("keydown", this._handleKeyDown);
2913
+ this.el.removeEventListener("focusout", this._handleFocusOut);
2914
+ document.removeEventListener("pointerup", this._resetPress);
2915
+ document.removeEventListener("pointercancel", this._resetPress);
2916
+ document.removeEventListener("keyup", this._handleKeyUp);
2917
+ window.removeEventListener("blur", this._resetPress);
2918
+ for (const [item, value] of this._originalPressed) {
2919
+ if (value === null) item.removeAttribute("aria-pressed");
2920
+ else item.setAttribute("aria-pressed", value);
2921
+ }
2922
+ this._originalPressed.clear();
2923
+ this.el["Expressive_ButtonGroup"] = void 0;
2924
+ }
2925
+ get _selectionMode() {
2926
+ const mode = this.el.dataset.selection;
2927
+ return VALID_SELECTION_MODES.has(mode) ? mode : null;
2928
+ }
2929
+ get _items() {
2930
+ return Array.from(this.el.children).filter(
2931
+ (child) => child instanceof HTMLButtonElement || child instanceof HTMLAnchorElement && child.classList.contains("button")
2932
+ );
2933
+ }
2934
+ get _toggleItems() {
2935
+ return this._items.filter(
2936
+ (item) => item instanceof HTMLButtonElement
2937
+ );
2938
+ }
2939
+ _normalizeSelection() {
2940
+ const items = this._toggleItems;
2941
+ items.forEach((item) => {
2942
+ this._rememberPressed(item);
2943
+ if (!["true", "false"].includes(item.getAttribute("aria-pressed") || "")) {
2944
+ item.setAttribute("aria-pressed", "false");
2945
+ }
2946
+ });
2947
+ if (this._selectionMode === "single") {
2948
+ const selected = items.filter((item) => item.getAttribute("aria-pressed") === "true");
2949
+ selected.slice(1).forEach((item) => item.setAttribute("aria-pressed", "false"));
2950
+ }
2951
+ if (this.el.hasAttribute("data-selection-required") && !items.some((item) => item.getAttribute("aria-pressed") === "true")) {
2952
+ items.find((item) => !this._isDisabled(item))?.setAttribute("aria-pressed", "true");
2953
+ }
2954
+ }
2955
+ _itemFromEvent(event) {
2956
+ if (!(event.target instanceof Element)) return null;
2957
+ const item = event.target.closest("button, a.button");
2958
+ return item instanceof HTMLElement && item.parentElement === this.el ? item : null;
2959
+ }
2960
+ _isDisabled(item) {
2961
+ return item instanceof HTMLButtonElement && item.disabled || item.getAttribute("aria-disabled") === "true" || item.classList.contains("disabled");
2962
+ }
2963
+ _rememberPressed(item) {
2964
+ if (!this._originalPressed.has(item)) {
2965
+ this._originalPressed.set(item, item.getAttribute("aria-pressed"));
2966
+ }
2967
+ }
2968
+ _startPress(item) {
2969
+ if (this._activeItem) return;
2970
+ this._finishRelease();
2971
+ const items = this._items;
2972
+ const activeIndex = items.indexOf(item);
2973
+ if (activeIndex < 0) return;
2974
+ this._activeItem = item;
2975
+ item.classList.add(PRESSED_CLASS);
2976
+ if (this.el.classList.contains("connected") || items.length < 2) return;
2977
+ const rects = items.map((candidate) => candidate.getBoundingClientRect());
2978
+ const activeWidth = rects[activeIndex].width;
2979
+ if (activeWidth <= 0) return;
2980
+ const parsedMultiplier = Number.parseFloat(
2981
+ getComputedStyle(this.el).getPropertyValue(
2982
+ "--md-comp-button-group-pressed-item-width-multiplier"
2983
+ )
2984
+ );
2985
+ const multiplier = Number.isFinite(parsedMultiplier) ? parsedMultiplier : 0.15;
2986
+ const desiredGrowth = activeWidth * multiplier;
2987
+ const neighborIndexes = [activeIndex - 1, activeIndex + 1].filter(
2988
+ (index) => index >= 0 && index < items.length
2989
+ );
2990
+ const compression = /* @__PURE__ */ new Map();
2991
+ if (neighborIndexes.length === 1) {
2992
+ const index = neighborIndexes[0];
2993
+ compression.set(
2994
+ index,
2995
+ Math.min(desiredGrowth, this._compressionCapacity(items[index], rects[index]))
2996
+ );
2997
+ } else {
2998
+ const half = desiredGrowth / 2;
2999
+ for (const index of neighborIndexes) {
3000
+ compression.set(
3001
+ index,
3002
+ Math.min(half, this._compressionCapacity(items[index], rects[index]))
3003
+ );
3004
+ }
3005
+ let remaining = desiredGrowth - [...compression.values()].reduce((sum, value) => sum + value, 0);
3006
+ for (const index of neighborIndexes) {
3007
+ if (remaining <= 0) break;
3008
+ const capacity = this._compressionCapacity(items[index], rects[index]) - compression.get(index);
3009
+ const extra = Math.min(remaining, capacity);
3010
+ compression.set(index, compression.get(index) + extra);
3011
+ remaining -= extra;
3012
+ }
3013
+ }
3014
+ const actualGrowth = [...compression.values()].reduce((sum, value) => sum + value, 0);
3015
+ if (actualGrowth <= 0) return;
3016
+ items.forEach((candidate, index) => {
3017
+ this._pressedStyles.set(candidate, {
3018
+ width: candidate.style.width,
3019
+ baseWidth: rects[index].width
3020
+ });
3021
+ candidate.style.width = `${rects[index].width}px`;
3022
+ });
3023
+ void this.el.offsetWidth;
3024
+ items.forEach((candidate, index) => {
3025
+ const adjustment = index === activeIndex ? actualGrowth : -(compression.get(index) || 0);
3026
+ candidate.style.width = `${rects[index].width + adjustment}px`;
3027
+ });
3028
+ }
3029
+ _compressionCapacity(item, rect) {
3030
+ const minimumWidth = item.classList.contains("icon-button") ? rect.width * (1 - MAX_ICON_COMPRESSION) : rect.height;
3031
+ return Math.max(0, rect.width - minimumWidth);
3032
+ }
3033
+ };
3034
+
2677
3035
  // src/ts/components/carousel.ts
2678
- var _defaults8 = {
3036
+ var _defaults10 = {
2679
3037
  duration: 200,
2680
3038
  fullWidth: false,
2681
3039
  indicators: false,
@@ -2918,7 +3276,7 @@ var _Carousel = class _Carousel extends Component {
2918
3276
  return this._trackEl ?? this.el;
2919
3277
  }
2920
3278
  static get defaults() {
2921
- return _defaults8;
3279
+ return _defaults10;
2922
3280
  }
2923
3281
  static init(els, options = {}) {
2924
3282
  return super.init(els, options, _Carousel);
@@ -3314,7 +3672,7 @@ _Carousel._onResize = Utils.throttle(() => {
3314
3672
  var Carousel = _Carousel;
3315
3673
 
3316
3674
  // src/ts/components/characterCounter.ts
3317
- var _defaults9 = Object.freeze({});
3675
+ var _defaults11 = Object.freeze({});
3318
3676
  var CharacterCounter = class _CharacterCounter extends Component {
3319
3677
  constructor(el, options) {
3320
3678
  super(el, {}, _CharacterCounter);
@@ -3339,7 +3697,7 @@ var CharacterCounter = class _CharacterCounter extends Component {
3339
3697
  this._setupEventHandlers();
3340
3698
  }
3341
3699
  static get defaults() {
3342
- return _defaults9;
3700
+ return _defaults11;
3343
3701
  }
3344
3702
  /**
3345
3703
  * Initializes instances of CharacterCounter.
@@ -3391,7 +3749,7 @@ var CharacterCounter = class _CharacterCounter extends Component {
3391
3749
  };
3392
3750
 
3393
3751
  // src/ts/components/select.ts
3394
- var _defaults10 = {
3752
+ var _defaults12 = {
3395
3753
  classes: "",
3396
3754
  menuOptions: {}
3397
3755
  };
@@ -3440,7 +3798,7 @@ var FormSelect = class _FormSelect extends Component {
3440
3798
  this._setupEventHandlers();
3441
3799
  }
3442
3800
  static get defaults() {
3443
- return _defaults10;
3801
+ return _defaults12;
3444
3802
  }
3445
3803
  /**
3446
3804
  * Initializes instances of FormSelect.
@@ -3571,7 +3929,7 @@ var FormSelect = class _FormSelect extends Component {
3571
3929
  _buildInput() {
3572
3930
  this.input = document.createElement("input");
3573
3931
  this.input.id = "select-input-" + Utils.guid();
3574
- this.input.classList.add("menu-trigger");
3932
+ this.input.classList.add("menu-trigger", "no-autoinit");
3575
3933
  this.input.type = "text";
3576
3934
  this.input.readOnly = true;
3577
3935
  this.input.setAttribute("data-target", this.menuEl.id);
@@ -3812,7 +4170,7 @@ var FormSelect = class _FormSelect extends Component {
3812
4170
  };
3813
4171
 
3814
4172
  // src/ts/plugins/dockedDisplayPlugin.ts
3815
- var _defaults11 = {
4173
+ var _defaults13 = {
3816
4174
  margin: 5,
3817
4175
  transition: 10,
3818
4176
  duration: 250,
@@ -3861,7 +4219,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
3861
4219
  };
3862
4220
  this.el = el;
3863
4221
  this.options = {
3864
- ..._defaults11,
4222
+ ..._defaults13,
3865
4223
  ...options
3866
4224
  };
3867
4225
  this.container = document.createElement("div");
@@ -3882,7 +4240,7 @@ var DockedDisplayPlugin = class _DockedDisplayPlugin {
3882
4240
  };
3883
4241
 
3884
4242
  // src/ts/components/datepicker.ts
3885
- var _defaults12 = {
4243
+ var _defaults14 = {
3886
4244
  // the default output format for the input field value
3887
4245
  format: "mmm dd, yyyy",
3888
4246
  // Used to create date object from current input string
@@ -4147,7 +4505,7 @@ var _Datepicker = class _Datepicker extends Component {
4147
4505
  }
4148
4506
  }
4149
4507
  static get defaults() {
4150
- return _defaults12;
4508
+ return _defaults14;
4151
4509
  }
4152
4510
  /**
4153
4511
  * Initializes instances of Datepicker.
@@ -4865,7 +5223,7 @@ _Datepicker._template = `
4865
5223
  var Datepicker = _Datepicker;
4866
5224
 
4867
5225
  // src/ts/components/lightbox.ts
4868
- var _defaults13 = {
5226
+ var _defaults15 = {
4869
5227
  inDuration: 275,
4870
5228
  outDuration: 200,
4871
5229
  onOpenStart: null,
@@ -4984,7 +5342,7 @@ var Lightbox = class _Lightbox extends Component {
4984
5342
  this._setupEventHandlers();
4985
5343
  }
4986
5344
  static get defaults() {
4987
- return _defaults13;
5345
+ return _defaults15;
4988
5346
  }
4989
5347
  /**
4990
5348
  * Initializes instances of Lightbox.
@@ -5150,7 +5508,7 @@ var Lightbox = class _Lightbox extends Component {
5150
5508
 
5151
5509
  // src/ts/components/scrollspy.ts
5152
5510
  var _defaultGetActiveElement = (id) => `a[href="#${id}"]`;
5153
- var _defaults14 = {
5511
+ var _defaults16 = {
5154
5512
  scrollOffset: 200,
5155
5513
  activeClass: "active",
5156
5514
  getActiveElement: _defaultGetActiveElement,
@@ -5173,7 +5531,7 @@ var _ScrollSpy = class _ScrollSpy extends Component {
5173
5531
  _ScrollSpy._observer?.observe(this.el);
5174
5532
  }
5175
5533
  static get defaults() {
5176
- return _defaults14;
5534
+ return _defaults16;
5177
5535
  }
5178
5536
  static init(els, options = {}) {
5179
5537
  return super.init(els, options, _ScrollSpy);
@@ -5295,7 +5653,7 @@ _ScrollSpy._onIntersect = (entries) => {
5295
5653
  var ScrollSpy = _ScrollSpy;
5296
5654
 
5297
5655
  // src/ts/components/navigationDrawer.ts
5298
- var _defaults15 = {
5656
+ var _defaults17 = {
5299
5657
  edge: "left",
5300
5658
  draggable: true,
5301
5659
  dragTargetWidth: "10px",
@@ -5438,7 +5796,7 @@ var _NavigationDrawer = class _NavigationDrawer extends Component {
5438
5796
  _NavigationDrawer._sidenavs.push(this);
5439
5797
  }
5440
5798
  static get defaults() {
5441
- return _defaults15;
5799
+ return _defaults17;
5442
5800
  }
5443
5801
  /**
5444
5802
  * Initializes instances of NavigationDrawer.
@@ -5629,7 +5987,7 @@ _NavigationDrawer._sidenavs = [];
5629
5987
  var NavigationDrawer = _NavigationDrawer;
5630
5988
 
5631
5989
  // src/ts/components/navigationRail.ts
5632
- var _defaults16 = {
5990
+ var _defaults18 = {
5633
5991
  onOpenStart: null,
5634
5992
  onOpenEnd: null,
5635
5993
  onCloseStart: null,
@@ -5705,7 +6063,7 @@ var NavigationRail = class _NavigationRail extends Component {
5705
6063
  document.addEventListener("keydown", this._onKeyDown);
5706
6064
  }
5707
6065
  static get defaults() {
5708
- return _defaults16;
6066
+ return _defaults18;
5709
6067
  }
5710
6068
  static init(els, options = {}) {
5711
6069
  return super.init(els, options, _NavigationRail);
@@ -5735,7 +6093,7 @@ var NavigationRail = class _NavigationRail extends Component {
5735
6093
  };
5736
6094
 
5737
6095
  // src/ts/components/tabs.ts
5738
- var _defaults17 = {
6096
+ var _defaults19 = {
5739
6097
  duration: 300,
5740
6098
  onShow: null,
5741
6099
  swipeable: false,
@@ -5811,7 +6169,7 @@ var Tabs = class _Tabs extends Component {
5811
6169
  this._setupEventHandlers();
5812
6170
  }
5813
6171
  static get defaults() {
5814
- return _defaults17;
6172
+ return _defaults19;
5815
6173
  }
5816
6174
  /**
5817
6175
  * Initializes instances of Tabs.
@@ -5998,7 +6356,7 @@ var Tabs = class _Tabs extends Component {
5998
6356
  };
5999
6357
 
6000
6358
  // src/ts/components/timepicker.ts
6001
- var _defaults18 = {
6359
+ var _defaults20 = {
6002
6360
  dialRadius: 135,
6003
6361
  outerRadius: 105,
6004
6362
  innerRadius: 70,
@@ -6051,12 +6409,6 @@ var _Timepicker = class _Timepicker extends Component {
6051
6409
  if (this.displayPlugin) this.displayPlugin.show();
6052
6410
  }
6053
6411
  };
6054
- this._handleTimeInputEnterKey = (e) => {
6055
- if (e.key === Utils.keys.ENTER) {
6056
- e.preventDefault();
6057
- this._inputFromTextField();
6058
- }
6059
- };
6060
6412
  this._handleClockClickStart = (e) => {
6061
6413
  if (!e.isPrimary) return;
6062
6414
  if (e.pointerType === "mouse" && e.button !== 0) return;
@@ -6211,7 +6563,7 @@ var _Timepicker = class _Timepicker extends Component {
6211
6563
  }
6212
6564
  }
6213
6565
  static get defaults() {
6214
- return _defaults18;
6566
+ return _defaults20;
6215
6567
  }
6216
6568
  /**
6217
6569
  * Initializes instances of Timepicker.
@@ -6561,7 +6913,7 @@ _Timepicker._template = `<div class="timepicker-container">
6561
6913
  var Timepicker = _Timepicker;
6562
6914
 
6563
6915
  // src/ts/components/snackbar.ts
6564
- var _defaults19 = {
6916
+ var _defaults21 = {
6565
6917
  text: "",
6566
6918
  action: "",
6567
6919
  onAction: null,
@@ -6608,7 +6960,7 @@ var _Snackbar = class _Snackbar {
6608
6960
  this._setTimer();
6609
6961
  }
6610
6962
  static get defaults() {
6611
- return _defaults19;
6963
+ return _defaults21;
6612
6964
  }
6613
6965
  static getInstance(el) {
6614
6966
  return el["Expressive_Snackbar"];
@@ -6843,7 +7195,7 @@ _Snackbar._draggedSnackbar = null;
6843
7195
  var Snackbar = _Snackbar;
6844
7196
 
6845
7197
  // src/ts/components/tooltip.ts
6846
- var _defaults20 = {
7198
+ var _defaults22 = {
6847
7199
  exitDelay: 200,
6848
7200
  enterDelay: 0,
6849
7201
  text: "",
@@ -6913,7 +7265,7 @@ var Tooltip = class _Tooltip extends Component {
6913
7265
  this._setupEventHandlers();
6914
7266
  }
6915
7267
  static get defaults() {
6916
- return _defaults20;
7268
+ return _defaults22;
6917
7269
  }
6918
7270
  /**
6919
7271
  * Initializes instances of Tooltip.
@@ -6927,6 +7279,12 @@ var Tooltip = class _Tooltip extends Component {
6927
7279
  return el["Expressive_Tooltip"];
6928
7280
  }
6929
7281
  destroy() {
7282
+ clearTimeout(this._enterDelayTimeout);
7283
+ clearTimeout(this._exitDelayTimeout);
7284
+ clearTimeout(this._animationTimeout);
7285
+ this.isOpen = false;
7286
+ this.isHovered = false;
7287
+ this.isFocused = false;
6930
7288
  if (this.el.getAttribute("aria-describedby") === this.tooltipEl.id) {
6931
7289
  this.el.removeAttribute("aria-describedby");
6932
7290
  }
@@ -7018,32 +7376,15 @@ var Tooltip = class _Tooltip extends Component {
7018
7376
  tooltip.style.left = newCoordinates.x + "px";
7019
7377
  }
7020
7378
  _repositionWithinScreen(x, y, width, height) {
7021
- const scrollLeft = Utils.getDocumentScrollLeft();
7022
- const scrollTop = Utils.getDocumentScrollTop();
7023
- let newX = x - scrollLeft;
7024
- let newY = y - scrollTop;
7025
- const bounding = {
7026
- left: newX,
7027
- top: newY,
7379
+ return Utils._repositionWithinScreen(
7380
+ x,
7381
+ y,
7028
7382
  width,
7029
- height
7030
- };
7031
- const offset = this.options.margin + this.options.transitionMovement;
7032
- const edges = Utils.checkWithinContainer(document.body, bounding, offset);
7033
- if (edges.left) {
7034
- newX = offset;
7035
- } else if (edges.right) {
7036
- newX -= newX + width - window.innerWidth;
7037
- }
7038
- if (edges.top) {
7039
- newY = offset;
7040
- } else if (edges.bottom) {
7041
- newY -= newY + height - window.innerHeight;
7042
- }
7043
- return {
7044
- x: newX + scrollLeft,
7045
- y: newY + scrollTop
7046
- };
7383
+ height,
7384
+ this.options.margin,
7385
+ this.options.transitionMovement,
7386
+ "center"
7387
+ );
7047
7388
  }
7048
7389
  _animateIn() {
7049
7390
  this._positionTooltip();
@@ -7052,7 +7393,8 @@ var Tooltip = class _Tooltip extends Component {
7052
7393
  this.tooltipEl.style.transition = `
7053
7394
  transform ${duration}ms ease-out,
7054
7395
  opacity ${duration}ms ease-out`;
7055
- setTimeout(() => {
7396
+ clearTimeout(this._animationTimeout);
7397
+ this._animationTimeout = setTimeout(() => {
7056
7398
  this.tooltipEl.style.transform = `translateX(${this.xMovement}px) translateY(${this.yMovement}px)`;
7057
7399
  this.tooltipEl.style.opacity = (this.options.opacity || 1).toString();
7058
7400
  }, 1);
@@ -7062,7 +7404,8 @@ var Tooltip = class _Tooltip extends Component {
7062
7404
  this.tooltipEl.style.transition = `
7063
7405
  transform ${duration}ms ease-out,
7064
7406
  opacity ${duration}ms ease-out`;
7065
- setTimeout(() => {
7407
+ clearTimeout(this._animationTimeout);
7408
+ this._animationTimeout = setTimeout(() => {
7066
7409
  this.tooltipEl.style.transform = `translateX(0px) translateY(0px)`;
7067
7410
  this.tooltipEl.style.opacity = "0";
7068
7411
  }, 1);
@@ -7087,13 +7430,21 @@ var Tooltip = class _Tooltip extends Component {
7087
7430
 
7088
7431
  // src/ts/components/registry.ts
7089
7432
  var AUTO_INIT_COMPONENTS = {
7433
+ AppBar: {
7434
+ component: AppBar,
7435
+ selector: "header.medium, header.large, header:has(> :is(nav:not(.tabs, .navigation-bar, .navigation-rail), .bar) > :is(.search-bar, .searchbar))"
7436
+ },
7090
7437
  Autocomplete: {
7091
7438
  component: Autocomplete,
7092
7439
  selector: ".autocomplete"
7093
7440
  },
7441
+ ButtonGroup: {
7442
+ component: ButtonGroup,
7443
+ selector: ".button-group"
7444
+ },
7094
7445
  // Shared with Cards.Init() - see CARDS_SELECTOR. This entry used to read
7095
7446
  // '.cards', which no card markup uses.
7096
- Cards: { component: Cards, selector: CARDS_SELECTOR },
7447
+ Cards: { component: Cards, selector: CARDS_SELECTOR, filter: isCardReveal },
7097
7448
  ExpandingCard: {
7098
7449
  component: ExpandingCard,
7099
7450
  selector: EXPANDING_CARD_SELECTOR
@@ -7129,14 +7480,20 @@ var AUTO_INIT_COMPONENTS = {
7129
7480
  };
7130
7481
  function AutoInit(context = document.body, options) {
7131
7482
  for (const name of Object.keys(AUTO_INIT_COMPONENTS)) {
7132
- const { component, selector } = AUTO_INIT_COMPONENTS[name];
7483
+ const { component, selector, filter } = AUTO_INIT_COMPONENTS[name];
7133
7484
  const els = context.querySelectorAll(`:is(${selector}):not(.no-autoinit)`);
7134
- component.init(els, options?.[name] ?? {});
7485
+ if (filter) {
7486
+ els.forEach((el) => {
7487
+ if (filter(el)) component.init(el, options?.[name] ?? {});
7488
+ });
7489
+ } else {
7490
+ component.init(els, options?.[name] ?? {});
7491
+ }
7135
7492
  }
7136
7493
  }
7137
7494
 
7138
7495
  // src/ts/index.ts
7139
- var version = "0.8.0";
7496
+ var version = "0.9.0";
7140
7497
  Forms.Init();
7141
7498
  Chips.Init();
7142
7499
  Slider.Init();