@m3e/menu 1.1.10 → 1.2.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/dist/index.js CHANGED
@@ -3,8 +3,8 @@
3
3
  * Copyright (c) 2025 matraic
4
4
  * See LICENSE file in the project root for full license text.
5
5
  */
6
- import { LitElement, nothing, html, css, unsafeCSS } from 'lit';
7
- import { KeyboardClick, Focusable, AttachInternals, Disabled, isLinkButtonMixin, renderPseudoLink, DesignToken, HtmlFor, ActionElementBase, LinkButton, Role, HoverController, hasAssignedNodes, ScrollController, Checked } from '@m3e/core';
6
+ import { LitElement, nothing, html, unsafeCSS, css } from 'lit';
7
+ import { KeyboardClick, Focusable, AttachInternals, Disabled, isLinkButtonMixin, renderPseudoLink, DesignToken, HtmlFor, ActionElementBase, LinkButton, Role, HoverController, hasAssignedNodes, ScrollController, Checked, prefersReducedMotion } from '@m3e/core';
8
8
  import { addAriaReferencedId, removeAriaReferencedId, RovingTabIndexManager } from '@m3e/core/a11y';
9
9
  import { positionAnchor } from '@m3e/core/anchoring';
10
10
  import { M3eDirectionality } from '@m3e/core/bidi';
@@ -469,11 +469,11 @@ class MenuItemElementBase extends KeyboardClick(Focusable(AttachInternals(Disabl
469
469
  }
470
470
  /** @inheritdoc */
471
471
  render() {
472
- return html`<div class="base"><m3e-state-layer class="state-layer" ?disabled="${this.disabled}"></m3e-state-layer><m3e-focus-ring class="focus-ring" inward ?disabled="${this.disabled}"></m3e-focus-ring><m3e-ripple class="ripple" ?disabled="${this.disabled}"></m3e-ripple><div class="touch" aria-hidden="true"></div>${isLinkButtonMixin(this) ? this[renderPseudoLink]() : nothing}<div class="wrapper">${this._renderContent()}</div></div>`;
472
+ return html`<div class="base"><m3e-state-layer class="state-layer" ?disabled="${this.disabled}"></m3e-state-layer><m3e-focus-ring class="focus-ring" ?disabled="${this.disabled}"></m3e-focus-ring><m3e-ripple class="ripple" ?disabled="${this.disabled}"></m3e-ripple><div class="touch" aria-hidden="true"></div>${isLinkButtonMixin(this) ? this[renderPseudoLink]() : nothing}<div class="wrapper">${this._renderContent()}</div></div>`;
473
473
  }
474
474
  }
475
475
  /** The styles of the element. */
476
- MenuItemElementBase.styles = css`:host { display: inline-block; outline: none; user-select: none; flex: none; height: var(--m3e-menu-item-container-height, 3rem); -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } :host(:not(:focus-visible)) .base { --m3e-state-layer-focus-opacity: 0; } :host(:not(:disabled):not([aria-expanded="true"])) .base { color: var(--m3e-menu-item-color, ${DesignToken.color.onSurface}); } :host(:not([aria-expanded="true"])) .base { --m3e-state-layer-hover-color: var(--m3e-menu-item-container-hover-color, ${DesignToken.color.onSurface}); --m3e-state-layer-focus-color: var(--m3e-menu-item-container-focus-color, ${DesignToken.color.onSurface}); --m3e-ripple-color: var(--m3e-menu-item-ripple-color, ${DesignToken.color.onSurface}); } :host(:not(:disabled)[checked]) .base, :host(:not(:disabled)[aria-expanded="true"]) .base { color: var(--m3e-menu-selected-color, ${DesignToken.color.onSecondaryContainer}); background-color: var(--m3e-menu-selected-container-color, ${DesignToken.color.secondaryContainer}); } :host([checked]) .base, :host([aria-expanded="true"]) .base { --m3e-state-layer-hover-color: var( --m3e-menu-item-selected-container-hover-color, ${DesignToken.color.onSecondaryContainer} ); --m3e-state-layer-focus-color: var( --m3e-menu-item-selected-container-focus-color, ${DesignToken.color.onSecondaryContainer} ); --m3e-ripple-color: var(--m3e-menu-item-selected-ripple-color, ${DesignToken.color.onSecondaryContainer}); } :host(:not(:disabled)) { cursor: pointer; } :host(:disabled) .base { color: color-mix( in srgb, var(--m3e-menu-item-disabled-color, ${DesignToken.color.onSurface}) var(--m3e-menu-item-disabled-opacity, 38%), transparent ); } .base { box-sizing: border-box; vertical-align: middle; display: inline-flex; align-items: center; position: relative; width: 100%; height: 100%; } .touch { position: absolute; height: 3rem; left: 0; right: 0; } .wrapper { display: inline-flex; align-items: center; column-gap: var(--m3e-menu-item-icon-label-space, 0.75rem); padding-inline-start: var(--m3e-menu-item-padding-start, 0.75rem); padding-inline-end: var(--m3e-menu-item-padding-end, 0.75rem); font-size: var(--m3e-menu-item-label-text-font-size, ${DesignToken.typescale.standard.label.large.fontSize}); font-weight: var( --m3e-menu-item-label-text-font-weight, ${DesignToken.typescale.standard.label.large.fontWeight} ); line-height: var( --m3e-menu-item-label-text-line-height, ${DesignToken.typescale.standard.label.large.lineHeight} ); letter-spacing: var(--m3e-menu-item-label-text-tracking, ${DesignToken.typescale.standard.label.large.tracking}); } .focus-ring { border-radius: var(--m3e-menu-item-focus-ring-shape, ${DesignToken.shape.corner.medium}); } .content { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } ::slotted([slot="icon"]), ::slotted([slot="trailing-icon"]), .trailing-icon { flex: none; width: 1em; font-size: var(--m3e-menu-item-icon-size, 1.5rem) !important; } @media (forced-colors: active) { .base { background-color: Menu; color: MenuText; } :host(:disabled) .base { color: GrayText; } }`;
476
+ MenuItemElementBase.styles = css`:host { display: inline-block; outline: none; user-select: none; flex: none; height: var(--m3e-menu-item-container-height, 2.75rem); -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } :host(:not(:disabled):not([aria-expanded="true"])) .base { color: var(--m3e-menu-item-color, ${DesignToken.color.onSurface}); } :host(:not([aria-expanded="true"])) .base { --m3e-state-layer-hover-color: var(--m3e-menu-item-container-hover-color, ${DesignToken.color.onSurface}); --m3e-state-layer-focus-color: var(--m3e-menu-item-container-focus-color, ${DesignToken.color.onSurface}); --m3e-ripple-color: var(--m3e-menu-item-ripple-color, ${DesignToken.color.onSurface}); } :host(:not(:disabled)[aria-expanded="true"]) .base { background-color: color-mix( in srgb, var(--m3e-menu-item-active-state-layer-color, ${DesignToken.color.onSurface}) var(--m3e-menu-active-state-layer-opacity, 8%), transparent ); } :host([aria-expanded="true"]) .state-layer { display: none; } :host(:not(:disabled)[checked]) .base { color: var(--m3e-menu-item-selected-color, ${DesignToken.color.onTertiaryContainer}); background-color: var(--m3e-menu-item-selected-container-color, ${DesignToken.color.tertiaryContainer}); } :host([checked]) .base { --m3e-state-layer-hover-color: var( --m3e-menu-item-selected-container-hover-color, ${DesignToken.color.onTertiaryContainer} ); --m3e-state-layer-focus-color: var( --m3e-menu-item-selected-container-focus-color, ${DesignToken.color.onTertiaryContainer} ); --m3e-ripple-color: var(--m3e-menu-item-selected-ripple-color, ${DesignToken.color.onTertiaryContainer}); } :host(:not(:disabled)) { cursor: pointer; } :host(:disabled) .base { color: color-mix( in srgb, var(--m3e-menu-item-disabled-color, ${DesignToken.color.onSurface}) var(--m3e-menu-item-disabled-opacity, 38%), transparent ); } .base { box-sizing: border-box; vertical-align: middle; display: inline-flex; align-items: center; position: relative; width: 100%; height: 100%; border-radius: var(--m3e-menu-item-shape, ${DesignToken.shape.corner.extraSmall}); transition: ${unsafeCSS(`border-radius ${DesignToken.motion.spring.fastEffects}`)}; } :host([checked]:not(.-first)) .base { border-top-left-radius: var(--m3e-menu-item-selected-shape, ${DesignToken.shape.corner.medium}); border-top-right-radius: var(--m3e-menu-item-selected-shape, ${DesignToken.shape.corner.medium}); } :host([checked]:not(.-last)) .base { border-bottom-left-radius: var(--m3e-menu-item-selected-shape, ${DesignToken.shape.corner.medium}); border-bottom-right-radius: var(--m3e-menu-item-selected-shape, ${DesignToken.shape.corner.medium}); } :host(.-first) .base { border-top-left-radius: var(--m3e-menu-item-first-child-shape, ${DesignToken.shape.corner.medium}); border-top-right-radius: var(--m3e-menu-item-first-child-shape, ${DesignToken.shape.corner.medium}); } :host(.-last) .base { border-bottom-left-radius: var(--m3e-menu-item-last-child-shape, ${DesignToken.shape.corner.medium}); border-bottom-right-radius: var(--m3e-menu-item-last-child-shape, ${DesignToken.shape.corner.medium}); } .touch { position: absolute; height: 3rem; left: 0; right: 0; } .wrapper { flex: 1 1 auto; display: inline-flex; align-items: center; column-gap: var(--m3e-menu-item-icon-label-space, 0.5rem); padding-inline-start: var(--m3e-menu-item-padding-start, 0.75rem); padding-inline-end: var(--m3e-menu-item-padding-end, 0.75rem); font-size: var(--m3e-menu-item-label-text-font-size, ${DesignToken.typescale.standard.label.large.fontSize}); font-weight: var( --m3e-menu-item-label-text-font-weight, ${DesignToken.typescale.standard.label.large.fontWeight} ); line-height: var( --m3e-menu-item-label-text-line-height, ${DesignToken.typescale.standard.label.large.lineHeight} ); letter-spacing: var(--m3e-menu-item-label-text-tracking, ${DesignToken.typescale.standard.label.large.tracking}); } .focus-ring { border-radius: var(--m3e-menu-item-focus-ring-shape, inherit); } .content { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } ::slotted([slot="icon"]), ::slotted([slot="trailing-icon"]), .trailing-icon { flex: none; width: 1em; font-size: var(--m3e-menu-item-icon-size, 1.25rem) !important; } @media (prefers-reduced-motion) { .base { transition: none; } } @media (forced-colors: active) { .base { background-color: Menu; color: MenuText; } :host(:disabled) .base { color: GrayText; } }`;
477
477
  __decorate([e(".focus-ring")], MenuItemElementBase.prototype, "_focusRing", void 0);
478
478
  __decorate([e(".state-layer")], MenuItemElementBase.prototype, "_stateLayer", void 0);
479
479
  __decorate([e(".ripple")], MenuItemElementBase.prototype, "_ripple", void 0);
@@ -659,13 +659,26 @@ var M3eMenuItemElement_1;
659
659
  * @cssprop --m3e-menu-item-container-hover-color - State layer hover color for unselected items.
660
660
  * @cssprop --m3e-menu-item-container-focus-color - State layer focus color for unselected items.
661
661
  * @cssprop --m3e-menu-item-ripple-color - Ripple color for unselected items.
662
- * @cssprop --m3e-menu-selected-color - Text color for selected or expanded items.
663
- * @cssprop --m3e-menu-selected-container-color - Background color for selected or expanded items.
662
+ * @cssprop --m3e-menu-item-selected-color - Text color for selected items.
663
+ * @cssprop --m3e-menu-item-selected-container-color - Background color for selected items.
664
664
  * @cssprop --m3e-menu-item-selected-container-hover-color - State layer hover color for selected items.
665
665
  * @cssprop --m3e-menu-item-selected-container-focus-color - State layer focus color for selected items.
666
666
  * @cssprop --m3e-menu-item-selected-ripple-color - Ripple color for selected items.
667
+ * @cssprop --m3e-menu-item-active-state-layer-color - State layer color for expanded items.
668
+ * @cssprop --m3e-menu-item-active-state-layer-opacity - State layer opacity for expanded items.
667
669
  * @cssprop --m3e-menu-item-disabled-color - Base color for disabled items.
668
670
  * @cssprop --m3e-menu-item-disabled-opacity - Opacity percentage for disabled item color mix.
671
+ * @cssprop --m3e-vibrant-menu-item-color - Text color for unselected, enabled menu items for vibrant variant.
672
+ * @cssprop --m3e-vibrant-menu-item-container-hover-color - State layer hover color for unselected items for vibrant variant.
673
+ * @cssprop --m3e-vibrant-menu-item-container-focus-color - State layer focus color for unselected items for vibrant variant.
674
+ * @cssprop --m3e-vibrant-menu-item-ripple-color - Ripple color for unselected items for vibrant variant.
675
+ * @cssprop --m3e-vibrant-menu-item-selected-color - Text color for selected items for vibrant variant.
676
+ * @cssprop --m3e-vibrant-menu-item-selected-container-color - Background color for selected items for vibrant variant.
677
+ * @cssprop --m3e-vibrant-menu-item-selected-container-hover-color - State layer hover color for selected items for vibrant variant.
678
+ * @cssprop --m3e-vibrant-menu-item-selected-container-focus-color - State layer focus color for selected items for vibrant variant.
679
+ * @cssprop --m3e-vibrant-menu-item-selected-ripple-color - Ripple color for selected items for vibrant variant.
680
+ * @cssprop --m3e-vibrant-menu-item-active-state-layer-color - State layer color for expanded items for vibrant variant.
681
+ * @cssprop --m3e-vibrant-menu-item-disabled-color - Base color for disabled items for vibrant variant.
669
682
  * @cssprop --m3e-menu-item-icon-label-space - Horizontal gap between icon and content.
670
683
  * @cssprop --m3e-menu-item-padding-start - Start padding for the item wrapper.
671
684
  * @cssprop --m3e-menu-item-padding-end - End padding for the item wrapper.
@@ -675,6 +688,9 @@ var M3eMenuItemElement_1;
675
688
  * @cssprop --m3e-menu-item-label-text-tracking - Letter spacing for menu item text.
676
689
  * @cssprop --m3e-menu-item-focus-ring-shape - Border radius for the focus ring.
677
690
  * @cssprop --m3e-menu-item-icon-size - Font size for leading and trailing icons.
691
+ * @cssprop --m3e-menu-item-shape - Base shape of the menu item.
692
+ * @cssprop --m3e-menu-item-first-child-shape - Shape for the first menu item in a menu.
693
+ * @cssprop --m3e-menu-item-last-child-shape - Shape for the last menu item in a menu.
678
694
  */
679
695
  let M3eMenuItemElement = M3eMenuItemElement_1 = class M3eMenuItemElement extends LinkButton(Role(MenuItemElementBase, "menuitem")) {
680
696
  constructor() {
@@ -774,7 +790,7 @@ _M3eMenuItemElement_handleMouseEnter = function _M3eMenuItemElement_handleMouseE
774
790
  __decorate([r()], M3eMenuItemElement.prototype, "_hasSubmenu", void 0);
775
791
  M3eMenuItemElement = M3eMenuItemElement_1 = __decorate([t$1("m3e-menu-item")], M3eMenuItemElement);
776
792
 
777
- var _M3eMenuElement_instances, _M3eMenuElement_trigger, _M3eMenuElement_anchorCleanup, _M3eMenuElement_listManager, _M3eMenuElement_keyDownHandler, _M3eMenuElement_documentClickHandler, _M3eMenuElement_scrollController, _M3eMenuElement_toggleHandler, _M3eMenuElement_handleSlotChange, _M3eMenuElement_handleKeyDown, _M3eMenuElement_handleDocumentClick, _M3eMenuElement_getAbsolutePosition;
793
+ var _M3eMenuElement_instances, _M3eMenuElement_trigger, _M3eMenuElement_anchorCleanup, _M3eMenuElement_listManager, _M3eMenuElement_keyDownHandler, _M3eMenuElement_mouseEnterHandler, _M3eMenuElement_documentClickHandler, _M3eMenuElement_scrollController, _M3eMenuElement_toggleHandler, _M3eMenuElement_handleSlotChange, _M3eMenuElement_handleKeyDown, _M3eMenuElement_handleMouseEnter, _M3eMenuElement_handleDocumentClick, _M3eMenuElement_getAbsolutePosition, _M3eMenuElement_activate, _M3eMenuElement_deactivate;
778
794
  var M3eMenuElement_1;
779
795
  /**
780
796
  * Presents a list of choices on a temporary surface.
@@ -835,18 +851,23 @@ var M3eMenuElement_1;
835
851
  *
836
852
  * @attr position-x - The position of the menu, on the x-axis.
837
853
  * @attr position-y - The position of the menu, on the y-axis.
854
+ * @attr variant - The appearance variant of the menu.
838
855
  *
839
856
  * @fires beforetoggle - Dispatched before the toggle state changes.
840
857
  * @fires toggle - Dispatched after the toggle state has changed.
841
858
  *
842
859
  * @cssprop --m3e-menu-container-shape - Controls the corner radius of the menu container.
860
+ * @cssprop --m3e-menu-active-container-shape - Controls the corner radius of the menu container when active.
843
861
  * @cssprop --m3e-menu-container-min-width - Minimum width of the menu container.
844
862
  * @cssprop --m3e-menu-container-max-width - Maximum width of the menu container.
845
863
  * @cssprop --m3e-menu-container-max-height - Maximum height of the menu container.
846
864
  * @cssprop --m3e-menu-container-padding-block - Vertical padding inside the menu container.
865
+ * @cssprop --m3e-menu-container-padding-inline - Horizontal padding inside the menu container.
847
866
  * @cssprop --m3e-menu-container-color - Background color of the menu container.
848
867
  * @cssprop --m3e-menu-container-elevation - Box shadow elevation of the menu container.
868
+ * @cssprop --m3e-vibrant-menu-container-color - Background color of the menu container for vibrant variant.
849
869
  * @cssprop --m3e-menu-divider-spacing - Vertical spacing around slotted `m3e-divider` elements.
870
+ * @cssprop --m3e-menu-gap - Gap between content in the menu.
850
871
  */
851
872
  let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends Role(LitElement, "menu") {
852
873
  constructor() {
@@ -861,6 +882,8 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends Role(LitEle
861
882
  /** @private */
862
883
  _M3eMenuElement_keyDownHandler.set(this, e => __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_handleKeyDown).call(this, e));
863
884
  /** @private */
885
+ _M3eMenuElement_mouseEnterHandler.set(this, () => __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_handleMouseEnter).call(this));
886
+ /** @private */
864
887
  _M3eMenuElement_documentClickHandler.set(this, e => __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_handleDocumentClick).call(this, e));
865
888
  /** @private */
866
889
  _M3eMenuElement_scrollController.set(this, new ScrollController(this, {
@@ -888,6 +911,11 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends Role(LitEle
888
911
  * @default "below"
889
912
  */
890
913
  this.positionY = "below";
914
+ /**
915
+ * The appearance variant of the menu.
916
+ * @default "standard"
917
+ */
918
+ this.variant = "standard";
891
919
  /** A value indicating whether the menu is a submenu. */
892
920
  this.submenu = false;
893
921
  }
@@ -906,6 +934,7 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends Role(LitEle
906
934
  this.classList.add("-no-animate");
907
935
  this.setAttribute("popover", "manual");
908
936
  this.addEventListener("keydown", __classPrivateFieldGet(this, _M3eMenuElement_keyDownHandler, "f"));
937
+ this.addEventListener("mouseenter", __classPrivateFieldGet(this, _M3eMenuElement_mouseEnterHandler, "f"));
909
938
  this.addEventListener("toggle", __classPrivateFieldGet(this, _M3eMenuElement_toggleHandler, "f"));
910
939
  document.addEventListener("click", __classPrivateFieldGet(this, _M3eMenuElement_documentClickHandler, "f"));
911
940
  }
@@ -913,8 +942,10 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends Role(LitEle
913
942
  disconnectedCallback() {
914
943
  super.disconnectedCallback();
915
944
  this.removeEventListener("keydown", __classPrivateFieldGet(this, _M3eMenuElement_keyDownHandler, "f"));
945
+ this.removeEventListener("mouseenter", __classPrivateFieldGet(this, _M3eMenuElement_mouseEnterHandler, "f"));
916
946
  this.removeEventListener("toggle", __classPrivateFieldGet(this, _M3eMenuElement_toggleHandler, "f"));
917
947
  document.removeEventListener("click", __classPrivateFieldGet(this, _M3eMenuElement_documentClickHandler, "f"));
948
+ __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_deactivate).call(this);
918
949
  }
919
950
  /**
920
951
  * Opens the menu.
@@ -952,6 +983,12 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends Role(LitEle
952
983
  }
953
984
  this.style.top = `${y}px`;
954
985
  }), "f");
986
+ const parent = trigger.closest("m3e-menu");
987
+ if (parent) {
988
+ this.variant = parent.variant;
989
+ } else {
990
+ __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_activate).call(this);
991
+ }
955
992
  this.showPopover();
956
993
  __classPrivateFieldSet(this, _M3eMenuElement_trigger, trigger, "f");
957
994
  __classPrivateFieldGet(this, _M3eMenuElement_trigger, "f").ariaExpanded = "true";
@@ -968,6 +1005,7 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends Role(LitEle
968
1005
  submenu.hide();
969
1006
  }
970
1007
  }
1008
+ __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_deactivate).call(this);
971
1009
  this.hidePopover();
972
1010
  if (__classPrivateFieldGet(this, _M3eMenuElement_trigger, "f")) {
973
1011
  __classPrivateFieldGet(this, _M3eMenuElement_trigger, "f").ariaExpanded = "false";
@@ -1008,7 +1046,7 @@ let M3eMenuElement = M3eMenuElement_1 = class M3eMenuElement extends Role(LitEle
1008
1046
  }
1009
1047
  /** @inheritdoc */
1010
1048
  render() {
1011
- return html`<slot @slotchange="${__classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_handleSlotChange)}"></slot>`;
1049
+ return html`<div class="base"><slot @slotchange="${__classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_handleSlotChange)}"></slot></div>`;
1012
1050
  }
1013
1051
  /** @inheritdoc */
1014
1052
  firstUpdated(_changedProperties) {
@@ -1020,6 +1058,7 @@ _M3eMenuElement_trigger = new WeakMap();
1020
1058
  _M3eMenuElement_anchorCleanup = new WeakMap();
1021
1059
  _M3eMenuElement_listManager = new WeakMap();
1022
1060
  _M3eMenuElement_keyDownHandler = new WeakMap();
1061
+ _M3eMenuElement_mouseEnterHandler = new WeakMap();
1023
1062
  _M3eMenuElement_documentClickHandler = new WeakMap();
1024
1063
  _M3eMenuElement_scrollController = new WeakMap();
1025
1064
  _M3eMenuElement_toggleHandler = new WeakMap();
@@ -1031,6 +1070,10 @@ _M3eMenuElement_handleSlotChange = function _M3eMenuElement_handleSlotChange() {
1031
1070
  if (!__classPrivateFieldGet(this, _M3eMenuElement_listManager, "f").activeItem) {
1032
1071
  __classPrivateFieldGet(this, _M3eMenuElement_listManager, "f").updateActiveItem(added.find(x => !x.disabled));
1033
1072
  }
1073
+ __classPrivateFieldGet(this, _M3eMenuElement_listManager, "f").items.forEach((x, i) => {
1074
+ x.classList.toggle("-first", i === 0);
1075
+ x.classList.toggle("-last", i === __classPrivateFieldGet(this, _M3eMenuElement_listManager, "f").items.length - 1);
1076
+ });
1034
1077
  };
1035
1078
  _M3eMenuElement_handleKeyDown = function _M3eMenuElement_handleKeyDown(e) {
1036
1079
  switch (e.key) {
@@ -1065,6 +1108,9 @@ _M3eMenuElement_handleKeyDown = function _M3eMenuElement_handleKeyDown(e) {
1065
1108
  break;
1066
1109
  }
1067
1110
  };
1111
+ _M3eMenuElement_handleMouseEnter = function _M3eMenuElement_handleMouseEnter() {
1112
+ __classPrivateFieldGet(this, _M3eMenuElement_instances, "m", _M3eMenuElement_activate).call(this);
1113
+ };
1068
1114
  _M3eMenuElement_handleDocumentClick = function _M3eMenuElement_handleDocumentClick(e) {
1069
1115
  if (!this.submenu && !e.composedPath().some(x => x instanceof M3eMenuElement_1 || x === __classPrivateFieldGet(this, _M3eMenuElement_trigger, "f"))) {
1070
1116
  this.hide();
@@ -1082,17 +1128,41 @@ _M3eMenuElement_getAbsolutePosition = function _M3eMenuElement_getAbsolutePositi
1082
1128
  y
1083
1129
  };
1084
1130
  };
1131
+ _M3eMenuElement_activate = function _M3eMenuElement_activate() {
1132
+ if (this !== M3eMenuElement_1.__activeMenu) {
1133
+ M3eMenuElement_1.__activeMenu?.classList.remove("-active");
1134
+ M3eMenuElement_1.__activeMenu = this;
1135
+ M3eMenuElement_1.__activeMenu?.classList.add("-active");
1136
+ }
1137
+ };
1138
+ _M3eMenuElement_deactivate = function _M3eMenuElement_deactivate() {
1139
+ if (this === M3eMenuElement_1.__activeMenu) {
1140
+ M3eMenuElement_1.__activeMenu.classList.remove("-active");
1141
+ M3eMenuElement_1.__activeMenu = undefined;
1142
+ }
1143
+ };
1144
+ (() => {
1145
+ if (document) {
1146
+ const lightDomStyle = new CSSStyleSheet();
1147
+ lightDomStyle.replaceSync(css`m3e-menu > m3e-divider { margin-block: var(--m3e-menu-divider-spacing, 0.5rem); }`.toString());
1148
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, lightDomStyle];
1149
+ }
1150
+ })();
1085
1151
  /** The styles of the element. */
1086
- M3eMenuElement.styles = css`:host { position: absolute; flex-direction: column; padding: unset; margin: unset; border: unset; overflow-y: auto; scrollbar-width: ${DesignToken.scrollbar.thinWidth}; scrollbar-color: ${DesignToken.scrollbar.color}; border-radius: var(--m3e-menu-container-shape, ${DesignToken.shape.corner.extraSmall}); min-width: var(--m3e-menu-container-min-width, 7rem); max-width: var(--m3e-menu-container-max-width, 17.5rem); max-height: var(--m3e-menu-container-max-height, 17.5rem); padding-block: var(--m3e-menu-container-padding-block, 0.5rem); background-color: var(--m3e-menu-container-color, ${DesignToken.color.surfaceContainer}); box-shadow: var(--m3e-menu-container-elevation, ${DesignToken.elevation.level3}); opacity: 0; display: none; } :host(:not(.-no-animate)) { transition: ${unsafeCSS(`opacity ${DesignToken.motion.duration.short2} ${DesignToken.motion.easing.standard},
1152
+ M3eMenuElement.styles = css`:host { position: absolute; padding: unset; margin: unset; border: unset; overflow-y: auto; overflow-x: visible; scrollbar-width: ${DesignToken.scrollbar.thinWidth}; scrollbar-color: ${DesignToken.scrollbar.color}; scroll-padding-block: calc( var(--m3e-focus-ring-thickness, 0.1875rem) + var(--m3e-menu-container-padding-block, 0.25rem) ); min-width: var(--m3e-menu-container-min-width, 7rem); max-width: var(--m3e-menu-container-max-width, 17.5rem); max-height: var(--m3e-menu-container-max-height, 17.5rem); box-shadow: var(--m3e-menu-container-elevation, ${DesignToken.elevation.level3}); opacity: 0; display: none; } .base { display: flex; flex-direction: column; row-gap: var(--m3e-menu-gap, 0.125rem); min-width: inherit; max-width: inherit; padding-block: var(--m3e-menu-container-padding-block, 0.25rem); padding-inline: var(--m3e-menu-container-padding-inline, 0.25rem); } :host(:not(.-active)) { border-radius: var(--m3e-menu-container-shape, ${DesignToken.shape.corner.small}); } :host(.-active) { border-radius: var(--m3e-menu-active-container-shape, ${DesignToken.shape.corner.large}); } :host(:not(.-no-animate)) { transition: ${unsafeCSS(`opacity ${DesignToken.motion.duration.short2} ${DesignToken.motion.easing.standard},
1087
1153
  transform ${DesignToken.motion.duration.short2} ${DesignToken.motion.easing.standard},
1088
1154
  overlay ${DesignToken.motion.duration.short2} ${DesignToken.motion.easing.standard} allow-discrete,
1089
- display ${DesignToken.motion.duration.short2} ${DesignToken.motion.easing.standard} allow-discrete`)}; } :host(:not([submenu])) { transform: scaleY(0.8); } :host(:not([submenu]):popover-open) { transform: scaleY(1); } :host::backdrop { background-color: transparent; } :host(:popover-open) { display: inline-flex; opacity: 1; } :host(.-bottom) { transform-origin: top; } :host(.-top) { transform-origin: bottom; } :host(.-shift-down) { margin-top: calc(0px - var(--m3e-menu-container-padding-block, 0.5rem)); } :host(.-shift-up) { margin-top: var(--m3e-menu-container-padding-block, 0.5rem); } ::slotted(m3e-divider) { margin-block: var(--m3e-menu-divider-spacing, 0.5rem); } @starting-style { :host(:popover-open) { opacity: 0; } :host(:not([submenu]):popover-open) { transform: scaleY(0.8); } } @media (prefers-reduced-motion) { :host(:not(.-no-animate)) { transition: none; } } @media (forced-colors: active) { :host { background-color: Menu; color: MenuText; border: 1px solid CanvasText; } }`;
1155
+ display ${DesignToken.motion.duration.short2} ${DesignToken.motion.easing.standard} allow-discrete,
1156
+ border-radius ${DesignToken.motion.spring.fastEffects}`)}; } :host(:not([submenu])) { transform: scaleY(0.8); } :host(:not([submenu]):popover-open) { transform: scaleY(1); } :host::backdrop { background-color: transparent; } :host(:popover-open) { display: block; opacity: 1; } :host(.-bottom) { transform-origin: top; } :host(.-top) { transform-origin: bottom; } :host(.-shift-down) { margin-top: calc(0px - var(--m3e-menu-container-padding-block, 0.25rem)); } :host(.-shift-up) { margin-top: var(--m3e-menu-container-padding-block, 0.25rem); } :host([variant="vibrant"]) { background-color: var(--m3e-vibrant-menu-container-color, ${DesignToken.color.tertiaryContainer}); --m3e-menu-item-color: var(--m3e-vibrant-menu-item-color, ${DesignToken.color.onTertiaryContainer}); --m3e-menu-item-container-hover-color: var( --m3e-vibrant-menu-item-container-hover-color, ${DesignToken.color.onTertiaryContainer} ); --m3e-menu-item-container-focus-color: var( --m3e-vibrant-menu-item-container-focus-color, ${DesignToken.color.onTertiaryContainer} ); --m3e-menu-item-ripple-color: var(--m3e-vibrant-menu-item-ripple-color, ${DesignToken.color.onTertiaryContainer}); --m3e-menu-item-active-state-layer-color: var( --m3e-vibrant-menu-item-active-state-layer-color, ${DesignToken.color.onTertiaryContainer} ); --m3e-menu-item-selected-color: var(--m3e-vibrant-menu-item-selected-color, ${DesignToken.color.onTertiary}); --m3e-menu-item-selected-container-color: var( --m3e-vibrant-menu-item-selected-container-color, ${DesignToken.color.tertiary} ); --m3e-menu-item-selected-container-hover-color: var( --m3e-vibrant-menu-item-selected-container-hover-color, ${DesignToken.color.onTertiary} ); --m3e-menu-item-container-selected-focus-color: var( --m3e-vibrant-menu-item-selected-container-focus-color, ${DesignToken.color.onTertiary} ); --m3e-menu-item-selected-ripple-color: var( --m3e-vibrant-menu-item-selected-ripple-color, ${DesignToken.color.onTertiary} ); --m3e-menu-item-disabled-color: var( --m3e-vibrant-menu-item-disabled-color, ${DesignToken.color.onTertiaryContainer} ); } :host([variant="standard"]) { background-color: var(--m3e-menu-container-color, ${DesignToken.color.surfaceContainer}); } @starting-style { :host(:popover-open) { opacity: 0; } :host(:not([submenu]):popover-open) { transform: scaleY(0.8); } } @media (prefers-reduced-motion) { :host(:not(.-no-animate)) { transition: none; } } @media (forced-colors: active) { :host { background-color: Menu; color: MenuText; outline: 1px solid MenuText; } }`;
1090
1157
  __decorate([n({
1091
1158
  attribute: "position-x"
1092
1159
  })], M3eMenuElement.prototype, "positionX", void 0);
1093
1160
  __decorate([n({
1094
1161
  attribute: "position-y"
1095
1162
  })], M3eMenuElement.prototype, "positionY", void 0);
1163
+ __decorate([n({
1164
+ reflect: true
1165
+ })], M3eMenuElement.prototype, "variant", void 0);
1096
1166
  __decorate([n({
1097
1167
  type: Boolean,
1098
1168
  reflect: true
@@ -1139,13 +1209,26 @@ var _M3eMenuItemCheckboxElement_instances, _M3eMenuItemCheckboxElement_clickHand
1139
1209
  * @cssprop --m3e-menu-item-container-hover-color - State layer hover color for unselected items.
1140
1210
  * @cssprop --m3e-menu-item-container-focus-color - State layer focus color for unselected items.
1141
1211
  * @cssprop --m3e-menu-item-ripple-color - Ripple color for unselected items.
1142
- * @cssprop --m3e-menu-selected-color - Text color for selected or expanded items.
1143
- * @cssprop --m3e-menu-selected-container-color - Background color for selected or expanded items.
1212
+ * @cssprop --m3e-menu-item-selected-color - Text color for selected items.
1213
+ * @cssprop --m3e-menu-item-selected-container-color - Background color for selected items.
1144
1214
  * @cssprop --m3e-menu-item-selected-container-hover-color - State layer hover color for selected items.
1145
1215
  * @cssprop --m3e-menu-item-selected-container-focus-color - State layer focus color for selected items.
1146
1216
  * @cssprop --m3e-menu-item-selected-ripple-color - Ripple color for selected items.
1217
+ * @cssprop --m3e-menu-item-active-state-layer-color - State layer color for expanded items.
1218
+ * @cssprop --m3e-menu-item-active-state-layer-opacity - State layer opacity for expanded items.
1147
1219
  * @cssprop --m3e-menu-item-disabled-color - Base color for disabled items.
1148
1220
  * @cssprop --m3e-menu-item-disabled-opacity - Opacity percentage for disabled item color mix.
1221
+ * @cssprop --m3e-vibrant-menu-item-color - Text color for unselected, enabled menu items for vibrant variant.
1222
+ * @cssprop --m3e-vibrant-menu-item-container-hover-color - State layer hover color for unselected items for vibrant variant.
1223
+ * @cssprop --m3e-vibrant-menu-item-container-focus-color - State layer focus color for unselected items for vibrant variant.
1224
+ * @cssprop --m3e-vibrant-menu-item-ripple-color - Ripple color for unselected items for vibrant variant.
1225
+ * @cssprop --m3e-vibrant-menu-item-selected-color - Text color for selected items for vibrant variant.
1226
+ * @cssprop --m3e-vibrant-menu-item-selected-container-color - Background color for selected items for vibrant variant.
1227
+ * @cssprop --m3e-vibrant-menu-item-selected-container-hover-color - State layer hover color for selected items for vibrant variant.
1228
+ * @cssprop --m3e-vibrant-menu-item-selected-container-focus-color - State layer focus color for selected items for vibrant variant.
1229
+ * @cssprop --m3e-vibrant-menu-item-selected-ripple-color - Ripple color for selected items for vibrant variant.
1230
+ * @cssprop --m3e-vibrant-menu-item-active-state-layer-color - State layer color for expanded items for vibrant variant.
1231
+ * @cssprop --m3e-vibrant-menu-item-disabled-color - Base color for disabled items for vibrant variant
1149
1232
  * @cssprop --m3e-menu-item-icon-label-space - Horizontal gap between icon and content.
1150
1233
  * @cssprop --m3e-menu-item-padding-start - Start padding for the item wrapper.
1151
1234
  * @cssprop --m3e-menu-item-padding-end - End padding for the item wrapper.
@@ -1155,6 +1238,10 @@ var _M3eMenuItemCheckboxElement_instances, _M3eMenuItemCheckboxElement_clickHand
1155
1238
  * @cssprop --m3e-menu-item-label-text-tracking - Letter spacing for menu item text.
1156
1239
  * @cssprop --m3e-menu-item-focus-ring-shape - Border radius for the focus ring.
1157
1240
  * @cssprop --m3e-menu-item-icon-size - Font size for leading and trailing icons.
1241
+ * @cssprop --m3e-menu-item-shape - Base shape of the menu item.
1242
+ * @cssprop --m3e-menu-item-selected-shape - Shape used for a selected menu item.
1243
+ * @cssprop --m3e-menu-item-first-child-shape - Shape for the first menu item in a menu.
1244
+ * @cssprop --m3e-menu-item-last-child-shape - Shape for the last menu item in a menu.
1158
1245
  */
1159
1246
  let M3eMenuItemCheckboxElement = class M3eMenuItemCheckboxElement extends Checked(Role(MenuItemElementBase, "menuitemcheckbox")) {
1160
1247
  constructor() {
@@ -1209,7 +1296,11 @@ _M3eMenuItemCheckboxElement_handleClick = function _M3eMenuItemCheckboxElement_h
1209
1296
  this.checked = !this.checked;
1210
1297
  this.performUpdate();
1211
1298
  if (!__classPrivateFieldGet(this, _M3eMenuItemCheckboxElement_spacePressed, "f")) {
1212
- this.menu?.hideAll(true);
1299
+ if (!prefersReducedMotion()) {
1300
+ setTimeout(() => this.menu?.hideAll(true), 150);
1301
+ } else {
1302
+ this.menu?.hideAll(true);
1303
+ }
1213
1304
  }
1214
1305
  }
1215
1306
  };
@@ -1227,7 +1318,7 @@ _M3eMenuItemCheckboxElement_handleMouseEnter = function _M3eMenuItemCheckboxElem
1227
1318
  });
1228
1319
  };
1229
1320
  /** The styles of the element. */
1230
- M3eMenuItemCheckboxElement.styles = [MenuItemElementBase.styles, css`.icon { display: flex; align-items: center; justify-content: center; } :host(:not(.-with-icon)) .icon { margin-inline-start: calc(0px - var(--m3e-menu-item-icon-label-space, 0.75rem)); } .check { width: 1em; font-size: var(--m3e-menu-item-icon-size, 1.5rem) !important; } :host(:not([checked])) .check { display: none; } :host([checked]) .icon { margin-inline-start: 0; } :host([checked]) ::slotted([slot="icon"]) { display: none !important; }`];
1321
+ M3eMenuItemCheckboxElement.styles = [MenuItemElementBase.styles, css`.icon { display: flex; align-items: center; justify-content: center; transition: margin-inline-start ${DesignToken.motion.spring.fastEffects}; } :host(:not(.-with-icon)) .icon { margin-inline-start: calc(0px - var(--m3e-menu-item-icon-label-space, 0.75rem)); } .check { width: 1em; font-size: var(--m3e-menu-item-icon-size, 1.25rem) !important; } :host(:not([checked])) .check { display: none; } :host([checked]) .icon { margin-inline-start: 0; } :host([checked]) ::slotted([slot="icon"]) { display: none !important; } @media (prefers-reduced-motion) { .icon { transition: none; } }`];
1231
1322
  M3eMenuItemCheckboxElement = __decorate([t$1("m3e-menu-item-checkbox")], M3eMenuItemCheckboxElement);
1232
1323
 
1233
1324
  /**
@@ -1291,13 +1382,26 @@ var _M3eMenuItemRadioElement_instances, _M3eMenuItemRadioElement_clickHandler, _
1291
1382
  * @cssprop --m3e-menu-item-container-hover-color - State layer hover color for unselected items.
1292
1383
  * @cssprop --m3e-menu-item-container-focus-color - State layer focus color for unselected items.
1293
1384
  * @cssprop --m3e-menu-item-ripple-color - Ripple color for unselected items.
1294
- * @cssprop --m3e-menu-selected-color - Text color for selected or expanded items.
1295
- * @cssprop --m3e-menu-selected-container-color - Background color for selected or expanded items.
1385
+ * @cssprop --m3e-menu-item-selected-color - Text color for selected items.
1386
+ * @cssprop --m3e-menu-item-selected-container-color - Background color for selected items.
1296
1387
  * @cssprop --m3e-menu-item-selected-container-hover-color - State layer hover color for selected items.
1297
1388
  * @cssprop --m3e-menu-item-selected-container-focus-color - State layer focus color for selected items.
1298
1389
  * @cssprop --m3e-menu-item-selected-ripple-color - Ripple color for selected items.
1390
+ * @cssprop --m3e-menu-item-active-state-layer-color - State layer color for expanded items.
1391
+ * @cssprop --m3e-menu-item-active-state-layer-opacity - State layer opacity for expanded items.
1299
1392
  * @cssprop --m3e-menu-item-disabled-color - Base color for disabled items.
1300
1393
  * @cssprop --m3e-menu-item-disabled-opacity - Opacity percentage for disabled item color mix.
1394
+ * @cssprop --m3e-vibrant-menu-item-color - Text color for unselected, enabled menu items for vibrant variant.
1395
+ * @cssprop --m3e-vibrant-menu-item-container-hover-color - State layer hover color for unselected items for vibrant variant.
1396
+ * @cssprop --m3e-vibrant-menu-item-container-focus-color - State layer focus color for unselected items for vibrant variant.
1397
+ * @cssprop --m3e-vibrant-menu-item-ripple-color - Ripple color for unselected items for vibrant variant.
1398
+ * @cssprop --m3e-vibrant-menu-item-selected-color - Text color for selected items for vibrant variant.
1399
+ * @cssprop --m3e-vibrant-menu-item-selected-container-color - Background color for selected items for vibrant variant.
1400
+ * @cssprop --m3e-vibrant-menu-item-selected-container-hover-color - State layer hover color for selected items for vibrant variant.
1401
+ * @cssprop --m3e-vibrant-menu-item-selected-container-focus-color - State layer focus color for selected items for vibrant variant.
1402
+ * @cssprop --m3e-vibrant-menu-item-selected-ripple-color - Ripple color for selected items for vibrant variant.
1403
+ * @cssprop --m3e-vibrant-menu-item-active-state-layer-color - State layer color for expanded items for vibrant variant.
1404
+ * @cssprop --m3e-vibrant-menu-item-disabled-color - Base color for disabled items for vibrant variant
1301
1405
  * @cssprop --m3e-menu-item-icon-label-space - Horizontal gap between icon and content.
1302
1406
  * @cssprop --m3e-menu-item-padding-start - Start padding for the item wrapper.
1303
1407
  * @cssprop --m3e-menu-item-padding-end - End padding for the item wrapper.
@@ -1307,6 +1411,10 @@ var _M3eMenuItemRadioElement_instances, _M3eMenuItemRadioElement_clickHandler, _
1307
1411
  * @cssprop --m3e-menu-item-label-text-tracking - Letter spacing for menu item text.
1308
1412
  * @cssprop --m3e-menu-item-focus-ring-shape - Border radius for the focus ring.
1309
1413
  * @cssprop --m3e-menu-item-icon-size - Font size for leading and trailing icons.
1414
+ * @cssprop --m3e-menu-item-shape - Base shape of the menu item.
1415
+ * @cssprop --m3e-menu-item-selected-shape - Shape used for a selected menu item.
1416
+ * @cssprop --m3e-menu-item-first-child-shape - Shape for the first menu item in a menu.
1417
+ * @cssprop --m3e-menu-item-last-child-shape - Shape for the last menu item in a menu.
1310
1418
  */
1311
1419
  let M3eMenuItemRadioElement = class M3eMenuItemRadioElement extends Checked(Role(MenuItemElementBase, "menuitemradio")) {
1312
1420
  constructor() {
@@ -1372,7 +1480,11 @@ _M3eMenuItemRadioElement_handleClick = function _M3eMenuItemRadioElement_handleC
1372
1480
  this.checked = true;
1373
1481
  this.performUpdate();
1374
1482
  if (!__classPrivateFieldGet(this, _M3eMenuItemRadioElement_spacePressed, "f")) {
1375
- this.menu?.hideAll(true);
1483
+ if (!prefersReducedMotion()) {
1484
+ setTimeout(() => this.menu?.hideAll(true), 150);
1485
+ } else {
1486
+ this.menu?.hideAll(true);
1487
+ }
1376
1488
  }
1377
1489
  }
1378
1490
  };