@awc-ui/core 1.0.0-beta.2 → 1.0.0-beta.4
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/README.md +18 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js +8 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js.map +1 -0
- package/dist/cjs/engine.wasm-9JtXME10.js +12 -0
- package/dist/cjs/engine.wasm-9JtXME10.js.map +1 -0
- package/dist/cjs/{index-DlQ_5_Mv.js → index-Bm07YAg9.js} +4 -15
- package/dist/cjs/index-Bm07YAg9.js.map +1 -0
- package/dist/cjs/lazy-loading-indicator-CoC-_DMs.js +69 -0
- package/dist/cjs/lazy-loading-indicator-CoC-_DMs.js.map +1 -0
- package/dist/cjs/loader.cjs.js +4 -3
- package/dist/cjs/loader.cjs.js.map +1 -1
- package/dist/cjs/md-accordion-item.cjs.entry.js +4 -4
- package/dist/cjs/md-accordion.cjs.entry.js +1 -1
- package/dist/cjs/md-app-bar.cjs.entry.js +2 -2
- package/dist/cjs/md-area-chart.cjs.entry.js +3 -3
- package/dist/cjs/md-autocomplete.cjs.entry.js +6 -5
- package/dist/cjs/md-autocomplete.cjs.entry.js.map +1 -1
- package/dist/cjs/md-avatar_2.cjs.entry.js +4 -4
- package/dist/cjs/md-badge.cjs.entry.js +3 -3
- package/dist/cjs/md-bar-chart.cjs.entry.js +3 -3
- package/dist/cjs/md-bottom-sheet.cjs.entry.js +5 -5
- package/dist/cjs/md-breadcrumb-item.cjs.entry.js +1 -1
- package/dist/cjs/md-breadcrumbs.cjs.entry.js +3 -3
- package/dist/cjs/md-button-group.cjs.entry.js +3 -3
- package/dist/cjs/{md-button_7.cjs.entry.js → md-button_6.cjs.entry.js} +14 -39
- package/dist/cjs/md-button_6.cjs.entry.js.map +1 -0
- package/dist/cjs/md-checkbox.cjs.entry.js +3 -3
- package/dist/cjs/md-chip.cjs.entry.js +3 -3
- package/dist/cjs/md-color-picker.cjs.entry.js +1 -1
- package/dist/cjs/md-date-picker.cjs.entry.js +2 -2
- package/dist/cjs/md-dialog.cjs.entry.js +3 -3
- package/dist/cjs/md-divider.cjs.entry.js +3 -3
- package/dist/cjs/md-fab-menu-item.cjs.entry.js +3 -3
- package/dist/cjs/md-fab-menu.cjs.entry.js +3 -3
- package/dist/cjs/md-fab.cjs.entry.js +3 -3
- package/dist/cjs/md-line-chart.cjs.entry.js +3 -3
- package/dist/cjs/md-list-item.cjs.entry.js +4 -4
- package/dist/cjs/md-list.cjs.entry.js +4 -4
- package/dist/cjs/md-loading-indicator-CmzdcYLR.js +33 -0
- package/dist/cjs/md-loading-indicator-CmzdcYLR.js.map +1 -0
- package/dist/cjs/md-loading-indicator.cjs.entry.js +11 -0
- package/dist/cjs/md-loading-indicator.cjs.entry.js.map +1 -0
- package/dist/cjs/md-menu-item-group.cjs.entry.js +1 -1
- package/dist/cjs/md-menu_2.cjs.entry.js +6 -6
- package/dist/cjs/md-meter.cjs.entry.js +1 -1
- package/dist/cjs/md-multi-select.cjs.entry.js +7 -6
- package/dist/cjs/md-multi-select.cjs.entry.js.map +1 -1
- package/dist/cjs/md-navigation-bar.cjs.entry.js +2 -2
- package/dist/cjs/md-navigation-rail-tab.cjs.entry.js +1 -1
- package/dist/cjs/md-navigation-rail.cjs.entry.js +1 -1
- package/dist/cjs/md-navigation-tab.cjs.entry.js +3 -3
- package/dist/cjs/md-number-field.cjs.entry.js +3 -3
- package/dist/cjs/md-organization-chart.cjs.entry.js +3 -3
- package/dist/cjs/md-otp-field.cjs.entry.js +4 -4
- package/dist/cjs/md-pie-chart.cjs.entry.js +1 -1
- package/dist/cjs/md-progress-indicator.cjs.entry.js +1 -1
- package/dist/cjs/md-rating.cjs.entry.js +1 -1
- package/dist/cjs/md-search.cjs.entry.js +8 -7
- package/dist/cjs/md-search.cjs.entry.js.map +1 -1
- package/dist/cjs/md-segmented-button-set.cjs.entry.js +1 -1
- package/dist/cjs/md-segmented-button.cjs.entry.js +1 -1
- package/dist/cjs/md-select-option.cjs.entry.js +2 -2
- package/dist/cjs/md-select.cjs.entry.js +7 -6
- package/dist/cjs/md-select.cjs.entry.js.map +1 -1
- package/dist/cjs/md-side-sheet.cjs.entry.js +1 -1
- package/dist/cjs/md-skeleton.cjs.entry.js +1 -1
- package/dist/cjs/md-slider.cjs.entry.js +3 -3
- package/dist/cjs/md-sparkline.cjs.entry.js +3 -3
- package/dist/cjs/md-split-button.cjs.entry.js +1 -1
- package/dist/cjs/md-status-dot.cjs.entry.js +2 -2
- package/dist/cjs/md-step.cjs.entry.js +1 -1
- package/dist/cjs/md-stepper.cjs.entry.js +1 -1
- package/dist/cjs/md-sub-menu-item.cjs.entry.js +1 -1
- package/dist/cjs/md-switch.cjs.entry.js +1 -1
- package/dist/cjs/md-tab-panel.cjs.entry.js +1 -1
- package/dist/cjs/md-tab-panels.cjs.entry.js +1 -1
- package/dist/cjs/md-tab.cjs.entry.js +1 -1
- package/dist/cjs/md-table-body.cjs.entry.js +1 -1
- package/dist/cjs/md-table-cell.cjs.entry.js +1 -1
- package/dist/cjs/md-table-container.cjs.entry.js +1 -1
- package/dist/cjs/md-table-expand-toggle.cjs.entry.js +1 -1
- package/dist/cjs/md-table-foot.cjs.entry.js +1 -1
- package/dist/cjs/md-table-head.cjs.entry.js +1 -1
- package/dist/cjs/md-table-pagination.cjs.entry.js +1 -1
- package/dist/cjs/md-table-row.cjs.entry.js +1 -1
- package/dist/cjs/md-table-sort-label.cjs.entry.js +1 -1
- package/dist/cjs/md-table-toolbar.cjs.entry.js +1 -1
- package/dist/cjs/md-table.cjs.entry.js +4 -4
- package/dist/cjs/md-tabs.cjs.entry.js +1 -1
- package/dist/cjs/md-text-field.cjs.entry.js +8 -8
- package/dist/cjs/md-time-picker.cjs.entry.js +2 -2
- package/dist/cjs/md-toolbar.cjs.entry.js +1 -1
- package/dist/cjs/md-transfer-list.cjs.entry.js +2 -2
- package/dist/cjs/md3.cjs.js +4 -3
- package/dist/cjs/md3.cjs.js.map +1 -1
- package/dist/cjs/{virtual-select-controller-CqriaZgm.js → virtual-select-controller-C5cSoKfB.js} +10 -9
- package/dist/cjs/virtual-select-controller-C5cSoKfB.js.map +1 -0
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/md-accordion-item/md-accordion-item.js +3 -3
- package/dist/collection/components/md-app-bar/md-app-bar.js +1 -1
- package/dist/collection/components/md-area-chart/md-area-chart.js +2 -2
- package/dist/collection/components/md-autocomplete/md-autocomplete.js +4 -3
- package/dist/collection/components/md-autocomplete/md-autocomplete.js.map +1 -1
- package/dist/collection/components/md-avatar/md-avatar.js +2 -2
- package/dist/collection/components/md-badge/md-badge.js +2 -2
- package/dist/collection/components/md-bar-chart/md-bar-chart.js +2 -2
- package/dist/collection/components/md-bottom-sheet/md-bottom-sheet.js +4 -4
- package/dist/collection/components/md-breadcrumbs/md-breadcrumbs.js +2 -2
- package/dist/collection/components/md-button/md-button.js +4 -3
- package/dist/collection/components/md-button/md-button.js.map +1 -1
- package/dist/collection/components/md-button-group/md-button-group.js +2 -2
- package/dist/collection/components/md-card/md-card.js +2 -2
- package/dist/collection/components/md-checkbox/md-checkbox.js +2 -2
- package/dist/collection/components/md-chip/md-chip.js +2 -2
- package/dist/collection/components/md-date-picker/md-date-picker.js +1 -1
- package/dist/collection/components/md-dialog/md-dialog.js +2 -2
- package/dist/collection/components/md-divider/md-divider.js +2 -2
- package/dist/collection/components/md-fab/md-fab.js +2 -2
- package/dist/collection/components/md-fab-menu/md-fab-menu.js +2 -2
- package/dist/collection/components/md-fab-menu-item/md-fab-menu-item.js +2 -2
- package/dist/collection/components/md-icon-button/md-icon-button.js +4 -4
- package/dist/collection/components/md-line-chart/md-line-chart.js +2 -2
- package/dist/collection/components/md-list/md-list.js +3 -3
- package/dist/collection/components/md-list-item/md-list-item.js +3 -3
- package/dist/collection/components/md-loading-indicator/md-loading-indicator.js +2 -2
- package/dist/collection/components/md-menu/md-menu.js +3 -3
- package/dist/collection/components/md-menu-item/md-menu-item.js +2 -2
- package/dist/collection/components/md-multi-select/md-multi-select.js +5 -4
- package/dist/collection/components/md-multi-select/md-multi-select.js.map +1 -1
- package/dist/collection/components/md-navigation-bar/md-navigation-bar.js +1 -1
- package/dist/collection/components/md-navigation-tab/md-navigation-tab.js +2 -2
- package/dist/collection/components/md-number-field/md-number-field.js +2 -2
- package/dist/collection/components/md-organization-chart/md-organization-chart.js +2 -2
- package/dist/collection/components/md-otp-field/md-otp-field.js +3 -3
- package/dist/collection/components/md-ripple/md-ripple.js +1 -1
- package/dist/collection/components/md-search/md-search.js +7 -6
- package/dist/collection/components/md-search/md-search.js.map +1 -1
- package/dist/collection/components/md-select/md-select.js +5 -4
- package/dist/collection/components/md-select/md-select.js.map +1 -1
- package/dist/collection/components/md-select-option/md-select-option.js +1 -1
- package/dist/collection/components/md-slider/md-slider.js +2 -2
- package/dist/collection/components/md-sparkline/md-sparkline.js +2 -2
- package/dist/collection/components/md-status-dot/md-status-dot.js +1 -1
- package/dist/collection/components/md-table/md-table.js +3 -3
- package/dist/collection/components/md-text-field/md-text-field.js +7 -7
- package/dist/collection/components/md-time-picker/md-time-picker.js +1 -1
- package/dist/collection/components/md-tooltip/md-tooltip.js +1 -1
- package/dist/collection/components/md-transfer-list/md-transfer-list.js +1 -1
- package/dist/collection/utils/lazy-loading-indicator.js +62 -0
- package/dist/collection/utils/lazy-loading-indicator.js.map +1 -0
- package/dist/collection/wasm/engine-abi.js +8 -2
- package/dist/collection/wasm/engine-abi.js.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/md-accordion-item.js +1 -1
- package/dist/components/md-accordion.js +1 -1
- package/dist/components/md-app-bar.js +1 -1
- package/dist/components/md-area-chart.js +1 -1
- package/dist/components/md-autocomplete.js +1 -1
- package/dist/components/md-autocomplete.js.map +1 -1
- package/dist/components/md-avatar.js +1 -1
- package/dist/components/md-badge.js +1 -1
- package/dist/components/md-bar-chart.js +1 -1
- package/dist/components/md-bottom-sheet.js +1 -1
- package/dist/components/md-breadcrumb-item.js +1 -1
- package/dist/components/md-breadcrumbs.js +1 -1
- package/dist/components/md-button-group.js +1 -1
- package/dist/components/md-button.js +1 -1
- package/dist/components/md-card.js +1 -1
- package/dist/components/md-checkbox.js +1 -1
- package/dist/components/md-chip.js +1 -1
- package/dist/components/md-color-picker.js +1 -1
- package/dist/components/md-date-picker.js +1 -1
- package/dist/components/md-date-picker.js.map +1 -1
- package/dist/components/md-dialog.js +1 -1
- package/dist/components/md-dialog.js.map +1 -1
- package/dist/components/md-divider.js +1 -1
- package/dist/components/md-divider.js.map +1 -1
- package/dist/components/md-fab-menu-item.js +1 -1
- package/dist/components/md-fab-menu.js +1 -1
- package/dist/components/md-fab.js +1 -1
- package/dist/components/md-icon-button.js +1 -1
- package/dist/components/md-line-chart.js +1 -1
- package/dist/components/md-line-chart.js.map +1 -1
- package/dist/components/md-list-item.js +1 -1
- package/dist/components/md-list.js +1 -1
- package/dist/components/md-loading-indicator.js +1 -1
- package/dist/components/md-menu-item-group.js +1 -1
- package/dist/components/md-menu-item.js +1 -1
- package/dist/components/md-menu.js +1 -1
- package/dist/components/md-meter.js +1 -1
- package/dist/components/md-multi-select.js +1 -1
- package/dist/components/md-multi-select.js.map +1 -1
- package/dist/components/md-navigation-bar.js +1 -1
- package/dist/components/md-navigation-rail-tab.js +1 -1
- package/dist/components/md-navigation-rail.js +1 -1
- package/dist/components/md-navigation-tab.js +1 -1
- package/dist/components/md-number-field.js +1 -1
- package/dist/components/md-organization-chart.js +1 -1
- package/dist/components/md-otp-field.js +1 -1
- package/dist/components/md-pie-chart.js +1 -1
- package/dist/components/md-progress-indicator.js +1 -1
- package/dist/components/md-radio.js +1 -1
- package/dist/components/md-rating.js +1 -1
- package/dist/components/md-ripple.js +1 -1
- package/dist/components/md-search.js +1 -1
- package/dist/components/md-search.js.map +1 -1
- package/dist/components/md-segmented-button-set.js +1 -1
- package/dist/components/md-segmented-button.js +1 -1
- package/dist/components/md-select-option.js +1 -1
- package/dist/components/md-select.js +1 -1
- package/dist/components/md-side-sheet.js +1 -1
- package/dist/components/md-skeleton.js +1 -1
- package/dist/components/md-slider.js +1 -1
- package/dist/components/md-snackbar.js +1 -1
- package/dist/components/md-snackbar.js.map +1 -1
- package/dist/components/md-sparkline.js +1 -1
- package/dist/components/md-split-button.js +1 -1
- package/dist/components/md-status-dot.js +1 -1
- package/dist/components/md-step.js +1 -1
- package/dist/components/md-step.js.map +1 -1
- package/dist/components/md-stepper.js +1 -1
- package/dist/components/md-stepper.js.map +1 -1
- package/dist/components/md-sub-menu-item.js +1 -1
- package/dist/components/md-switch.js +1 -1
- package/dist/components/md-tab-panel.js +1 -1
- package/dist/components/md-tab-panels.js +1 -1
- package/dist/components/md-tab.js +1 -1
- package/dist/components/md-table-body.js +1 -1
- package/dist/components/md-table-cell.js +1 -1
- package/dist/components/md-table-container.js +1 -1
- package/dist/components/md-table-expand-toggle.js +1 -1
- package/dist/components/md-table-foot.js +1 -1
- package/dist/components/md-table-head.js +1 -1
- package/dist/components/md-table-pagination.js +1 -1
- package/dist/components/md-table-pagination.js.map +1 -1
- package/dist/components/md-table-row.js +1 -1
- package/dist/components/md-table-sort-label.js +1 -1
- package/dist/components/md-table-toolbar.js +1 -1
- package/dist/components/md-table.js +1 -1
- package/dist/components/md-tabs.js +1 -1
- package/dist/components/md-text-field.js +1 -1
- package/dist/components/md-time-picker.js +1 -1
- package/dist/components/md-time-picker.js.map +1 -1
- package/dist/components/md-toolbar.js +1 -1
- package/dist/components/md-tooltip.js +1 -1
- package/dist/components/md-transfer-list.js +1 -1
- package/dist/components/p-1RSrsLOs.js +2 -0
- package/dist/components/p-1RSrsLOs.js.map +1 -0
- package/dist/components/p-2HV152w7.js +2 -0
- package/dist/components/p-2HV152w7.js.map +1 -0
- package/dist/components/p-6ZDAcEKN.js +2 -0
- package/dist/components/p-6ZDAcEKN.js.map +1 -0
- package/dist/components/p-B2fYoYe9.js +2 -0
- package/dist/components/p-B2fYoYe9.js.map +1 -0
- package/dist/components/p-BR6gfOQH.js +2 -0
- package/dist/components/p-BR6gfOQH.js.map +1 -0
- package/dist/components/p-Bz-JaJcA.js +2 -0
- package/dist/components/p-Bz-JaJcA.js.map +1 -0
- package/dist/components/p-C77M30dm.js +2 -0
- package/dist/components/p-C77M30dm.js.map +1 -0
- package/dist/components/p-CNgkGl_1.js +2 -0
- package/dist/components/p-CNgkGl_1.js.map +1 -0
- package/dist/components/p-CfBPnYW7.js +2 -0
- package/dist/components/p-CfBPnYW7.js.map +1 -0
- package/dist/components/p-D5Ht729E.js +2 -0
- package/dist/components/p-D5Ht729E.js.map +1 -0
- package/dist/components/p-DPqGg8C1.js +2 -0
- package/dist/components/p-DPqGg8C1.js.map +1 -0
- package/dist/components/p-De3E5Q8v.js +2 -0
- package/dist/components/p-De3E5Q8v.js.map +1 -0
- package/dist/components/p-Dm_7DA1f.js +2 -0
- package/dist/components/p-Dm_7DA1f.js.map +1 -0
- package/dist/components/p-Dz3R-2Wn.js +2 -0
- package/dist/components/p-Dz3R-2Wn.js.map +1 -0
- package/dist/components/p-Zjf9uhOr.js +2 -0
- package/dist/components/p-Zjf9uhOr.js.map +1 -0
- package/dist/components/p-ssLobpGS.js +2 -0
- package/dist/components/p-ssLobpGS.js.map +1 -0
- package/dist/components/p-tSoecrcz.js +2 -0
- package/dist/components/p-tSoecrcz.js.map +1 -0
- package/dist/components/p-zMR3UIR_.js +2 -0
- package/dist/components/p-zMR3UIR_.js.map +1 -0
- package/dist/components-csr/index.js +2 -0
- package/dist/components-csr/index.js.map +1 -0
- package/dist/components-csr/md-accordion-item.js +2 -0
- package/dist/components-csr/md-accordion-item.js.map +1 -0
- package/dist/components-csr/md-accordion.js +2 -0
- package/dist/components-csr/md-accordion.js.map +1 -0
- package/dist/components-csr/md-app-bar.js +2 -0
- package/dist/components-csr/md-app-bar.js.map +1 -0
- package/dist/components-csr/md-area-chart.js +2 -0
- package/dist/components-csr/md-area-chart.js.map +1 -0
- package/dist/components-csr/md-autocomplete.js +2 -0
- package/dist/components-csr/md-autocomplete.js.map +1 -0
- package/dist/components-csr/md-avatar.js +2 -0
- package/dist/components-csr/md-avatar.js.map +1 -0
- package/dist/components-csr/md-badge.js +2 -0
- package/dist/components-csr/md-badge.js.map +1 -0
- package/dist/components-csr/md-bar-chart.js +2 -0
- package/dist/components-csr/md-bar-chart.js.map +1 -0
- package/dist/components-csr/md-bottom-sheet.js +2 -0
- package/dist/components-csr/md-bottom-sheet.js.map +1 -0
- package/dist/components-csr/md-breadcrumb-item.js +2 -0
- package/dist/components-csr/md-breadcrumb-item.js.map +1 -0
- package/dist/components-csr/md-breadcrumbs.js +2 -0
- package/dist/components-csr/md-breadcrumbs.js.map +1 -0
- package/dist/components-csr/md-button-group.js +2 -0
- package/dist/components-csr/md-button-group.js.map +1 -0
- package/dist/components-csr/md-button.js +2 -0
- package/dist/components-csr/md-button.js.map +1 -0
- package/dist/components-csr/md-card.js +2 -0
- package/dist/components-csr/md-card.js.map +1 -0
- package/dist/components-csr/md-checkbox.js +2 -0
- package/dist/components-csr/md-checkbox.js.map +1 -0
- package/dist/components-csr/md-chip.js +2 -0
- package/dist/components-csr/md-chip.js.map +1 -0
- package/dist/components-csr/md-color-picker.js +2 -0
- package/dist/components-csr/md-color-picker.js.map +1 -0
- package/dist/components-csr/md-date-picker.js +2 -0
- package/dist/components-csr/md-date-picker.js.map +1 -0
- package/dist/components-csr/md-dialog.js +2 -0
- package/dist/components-csr/md-dialog.js.map +1 -0
- package/dist/components-csr/md-divider.js +2 -0
- package/dist/components-csr/md-divider.js.map +1 -0
- package/dist/components-csr/md-fab-menu-item.js +2 -0
- package/dist/components-csr/md-fab-menu-item.js.map +1 -0
- package/dist/components-csr/md-fab-menu.js +2 -0
- package/dist/components-csr/md-fab-menu.js.map +1 -0
- package/dist/components-csr/md-fab.js +2 -0
- package/dist/components-csr/md-fab.js.map +1 -0
- package/dist/components-csr/md-icon-button.js +2 -0
- package/dist/components-csr/md-icon-button.js.map +1 -0
- package/dist/components-csr/md-line-chart.js +2 -0
- package/dist/components-csr/md-line-chart.js.map +1 -0
- package/dist/components-csr/md-list-item.js +2 -0
- package/dist/components-csr/md-list-item.js.map +1 -0
- package/dist/components-csr/md-list.js +2 -0
- package/dist/components-csr/md-list.js.map +1 -0
- package/dist/components-csr/md-loading-indicator.js +2 -0
- package/dist/components-csr/md-loading-indicator.js.map +1 -0
- package/dist/components-csr/md-menu-item-group.js +2 -0
- package/dist/components-csr/md-menu-item-group.js.map +1 -0
- package/dist/components-csr/md-menu-item.js +2 -0
- package/dist/components-csr/md-menu-item.js.map +1 -0
- package/dist/components-csr/md-menu.js +2 -0
- package/dist/components-csr/md-menu.js.map +1 -0
- package/dist/components-csr/md-meter.js +2 -0
- package/dist/components-csr/md-meter.js.map +1 -0
- package/dist/components-csr/md-multi-select.js +2 -0
- package/dist/components-csr/md-multi-select.js.map +1 -0
- package/dist/components-csr/md-navigation-bar.js +2 -0
- package/dist/components-csr/md-navigation-bar.js.map +1 -0
- package/dist/components-csr/md-navigation-rail-tab.js +2 -0
- package/dist/components-csr/md-navigation-rail-tab.js.map +1 -0
- package/dist/components-csr/md-navigation-rail.js +2 -0
- package/dist/components-csr/md-navigation-rail.js.map +1 -0
- package/dist/components-csr/md-navigation-tab.js +2 -0
- package/dist/components-csr/md-navigation-tab.js.map +1 -0
- package/dist/components-csr/md-number-field.js +2 -0
- package/dist/components-csr/md-number-field.js.map +1 -0
- package/dist/components-csr/md-organization-chart.js +2 -0
- package/dist/components-csr/md-organization-chart.js.map +1 -0
- package/dist/components-csr/md-otp-field.js +2 -0
- package/dist/components-csr/md-otp-field.js.map +1 -0
- package/dist/components-csr/md-pie-chart.js +2 -0
- package/dist/components-csr/md-pie-chart.js.map +1 -0
- package/dist/components-csr/md-progress-indicator.js +2 -0
- package/dist/components-csr/md-progress-indicator.js.map +1 -0
- package/dist/components-csr/md-radio.js +2 -0
- package/dist/components-csr/md-radio.js.map +1 -0
- package/dist/components-csr/md-rating.js +2 -0
- package/dist/components-csr/md-rating.js.map +1 -0
- package/dist/components-csr/md-ripple.js +2 -0
- package/dist/components-csr/md-ripple.js.map +1 -0
- package/dist/components-csr/md-search.js +2 -0
- package/dist/components-csr/md-search.js.map +1 -0
- package/dist/components-csr/md-segmented-button-set.js +2 -0
- package/dist/components-csr/md-segmented-button-set.js.map +1 -0
- package/dist/components-csr/md-segmented-button.js +2 -0
- package/dist/components-csr/md-segmented-button.js.map +1 -0
- package/dist/components-csr/md-select-option.js +2 -0
- package/dist/components-csr/md-select-option.js.map +1 -0
- package/dist/components-csr/md-select.js +2 -0
- package/dist/components-csr/md-select.js.map +1 -0
- package/dist/components-csr/md-side-sheet.js +2 -0
- package/dist/components-csr/md-side-sheet.js.map +1 -0
- package/dist/components-csr/md-skeleton.js +2 -0
- package/dist/components-csr/md-skeleton.js.map +1 -0
- package/dist/components-csr/md-slider.js +2 -0
- package/dist/components-csr/md-slider.js.map +1 -0
- package/dist/components-csr/md-snackbar.js +2 -0
- package/dist/components-csr/md-snackbar.js.map +1 -0
- package/dist/components-csr/md-sparkline.js +2 -0
- package/dist/components-csr/md-sparkline.js.map +1 -0
- package/dist/components-csr/md-split-button.js +2 -0
- package/dist/components-csr/md-split-button.js.map +1 -0
- package/dist/components-csr/md-status-dot.js +2 -0
- package/dist/components-csr/md-status-dot.js.map +1 -0
- package/dist/components-csr/md-step.js +2 -0
- package/dist/components-csr/md-step.js.map +1 -0
- package/dist/components-csr/md-stepper.js +2 -0
- package/dist/components-csr/md-stepper.js.map +1 -0
- package/dist/components-csr/md-sub-menu-item.js +2 -0
- package/dist/components-csr/md-sub-menu-item.js.map +1 -0
- package/dist/components-csr/md-switch.js +2 -0
- package/dist/components-csr/md-switch.js.map +1 -0
- package/dist/components-csr/md-tab-panel.js +2 -0
- package/dist/components-csr/md-tab-panel.js.map +1 -0
- package/dist/components-csr/md-tab-panels.js +2 -0
- package/dist/components-csr/md-tab-panels.js.map +1 -0
- package/dist/components-csr/md-tab.js +2 -0
- package/dist/components-csr/md-tab.js.map +1 -0
- package/dist/components-csr/md-table-body.js +2 -0
- package/dist/components-csr/md-table-body.js.map +1 -0
- package/dist/components-csr/md-table-cell.js +2 -0
- package/dist/components-csr/md-table-cell.js.map +1 -0
- package/dist/components-csr/md-table-container.js +2 -0
- package/dist/components-csr/md-table-container.js.map +1 -0
- package/dist/components-csr/md-table-expand-toggle.js +2 -0
- package/dist/components-csr/md-table-expand-toggle.js.map +1 -0
- package/dist/components-csr/md-table-foot.js +2 -0
- package/dist/components-csr/md-table-foot.js.map +1 -0
- package/dist/components-csr/md-table-head.js +2 -0
- package/dist/components-csr/md-table-head.js.map +1 -0
- package/dist/components-csr/md-table-pagination.js +2 -0
- package/dist/components-csr/md-table-pagination.js.map +1 -0
- package/dist/components-csr/md-table-row.js +2 -0
- package/dist/components-csr/md-table-row.js.map +1 -0
- package/dist/components-csr/md-table-sort-label.js +2 -0
- package/dist/components-csr/md-table-sort-label.js.map +1 -0
- package/dist/components-csr/md-table-toolbar.js +2 -0
- package/dist/components-csr/md-table-toolbar.js.map +1 -0
- package/dist/components-csr/md-table.js +2 -0
- package/dist/components-csr/md-table.js.map +1 -0
- package/dist/components-csr/md-tabs.js +2 -0
- package/dist/components-csr/md-tabs.js.map +1 -0
- package/dist/components-csr/md-text-field.js +2 -0
- package/dist/components-csr/md-text-field.js.map +1 -0
- package/dist/components-csr/md-time-picker.js +2 -0
- package/dist/components-csr/md-time-picker.js.map +1 -0
- package/dist/components-csr/md-toolbar.js +2 -0
- package/dist/components-csr/md-toolbar.js.map +1 -0
- package/dist/components-csr/md-tooltip.js +2 -0
- package/dist/components-csr/md-tooltip.js.map +1 -0
- package/dist/components-csr/md-transfer-list.js +2 -0
- package/dist/components-csr/md-transfer-list.js.map +1 -0
- package/dist/components-csr/p-6WgHjhDg.js +2 -0
- package/dist/components-csr/p-6WgHjhDg.js.map +1 -0
- package/dist/{components/p-uTEkf0sE.js → components-csr/p-BEmwDSzw.js} +2 -2
- package/dist/{components/p-C8EP4S21.js → components-csr/p-BQKzjYcY.js} +2 -2
- package/dist/{components/p-BwXpiUsu.js → components-csr/p-BWMwewtY.js} +2 -2
- package/dist/{components/p-DXXUoRSH.js → components-csr/p-BZakoRau.js} +2 -2
- package/dist/components-csr/p-BZakoRau.js.map +1 -0
- package/dist/{md3/p-BjYKc1Ge.js → components-csr/p-BdEoSBtL.js} +2 -2
- package/dist/components-csr/p-BdEoSBtL.js.map +1 -0
- package/dist/{components/p-B0Opn6dK.js → components-csr/p-Bkt_X-6v.js} +2 -2
- package/dist/components-csr/p-Bx6--dQF.js.map +1 -0
- package/dist/components-csr/p-Bz-JaJcA.js +2 -0
- package/dist/components-csr/p-Bz-JaJcA.js.map +1 -0
- package/dist/{components/p-stybaFzj.js → components-csr/p-C3vB0Hd9.js} +2 -2
- package/dist/{components/p-B3MWYEEJ.js → components-csr/p-CF7mq5T7.js} +2 -2
- package/dist/{components/p-7fN_yCXW.js → components-csr/p-CVMM-tdC.js} +2 -2
- package/dist/components-csr/p-C_ogF68H.js.map +1 -0
- package/dist/components-csr/p-Cch_V1vi.js +2 -0
- package/dist/components-csr/p-Cch_V1vi.js.map +1 -0
- package/dist/components-csr/p-CfBPnYW7.js +2 -0
- package/dist/components-csr/p-CfBPnYW7.js.map +1 -0
- package/dist/components-csr/p-CxhZdOPw.js +2 -0
- package/dist/components-csr/p-CxhZdOPw.js.map +1 -0
- package/dist/{components/p-Ch2-tttM.js → components-csr/p-DMQ-6aj8.js} +2 -2
- package/dist/components-csr/p-DWxN44zD.js +2 -0
- package/dist/components-csr/p-DWxN44zD.js.map +1 -0
- package/dist/components-csr/p-DYBUr7K_.js +2 -0
- package/dist/components-csr/p-DYBUr7K_.js.map +1 -0
- package/dist/{components/p-e2HRV63Y.js → components-csr/p-DfcpeJAu.js} +2 -2
- package/dist/{components/p-Dp-w93ot.js → components-csr/p-DjKPc5EU.js} +2 -2
- package/dist/components-csr/p-DvOKnoqK.js.map +1 -0
- package/dist/components-csr/p-DzPKu-Ma.js.map +1 -0
- package/dist/{components/p-UdGDg2oJ.js → components-csr/p-If0JHsYV.js} +2 -2
- package/dist/components-csr/p-If0JHsYV.js.map +1 -0
- package/dist/components-csr/p-RLxbNqRv.js.map +1 -0
- package/dist/{components/p-6wZSqm_2.js → components-csr/p-R_guULjT.js} +2 -2
- package/dist/components-csr/p-bSpXNc5J.js +2 -0
- package/dist/components-csr/p-bSpXNc5J.js.map +1 -0
- package/dist/{components/p-Ddiw2Kjw.js → components-csr/p-uSMrgqAy.js} +2 -2
- package/dist/components-csr/package.json +3 -0
- package/dist/esm/{a11y-C6CRqodW.js → a11y-BckJ95d7.js} +3 -3
- package/dist/esm/{a11y-C6CRqodW.js.map → a11y-BckJ95d7.js.map} +1 -1
- package/dist/esm/app-globals-DQuL1Twl.js +6 -0
- package/dist/esm/app-globals-DQuL1Twl.js.map +1 -0
- package/dist/esm/{bar-chart-ZZrajEkM.js → bar-chart-BuTyuCbt.js} +4 -4
- package/dist/esm/{bar-chart-ZZrajEkM.js.map → bar-chart-BuTyuCbt.js.map} +1 -1
- package/dist/esm/{chart-32olae06.js → chart-ByIhkqsG.js} +4 -4
- package/dist/esm/{chart-32olae06.js.map → chart-ByIhkqsG.js.map} +1 -1
- package/dist/esm/engine.wasm-CfBPnYW7.js +10 -0
- package/dist/esm/engine.wasm-CfBPnYW7.js.map +1 -0
- package/dist/esm/{hit-test-DHldf5Lm.js → hit-test-c_hI-yCX.js} +3 -3
- package/dist/esm/{hit-test-DHldf5Lm.js.map → hit-test-c_hI-yCX.js.map} +1 -1
- package/dist/esm/{index-DTaX19_O.js → index-WmvQpZnM.js} +5 -15
- package/dist/esm/index-WmvQpZnM.js.map +1 -0
- package/dist/esm/lazy-loading-indicator-BWFcjJiK.js +67 -0
- package/dist/esm/lazy-loading-indicator-BWFcjJiK.js.map +1 -0
- package/dist/esm/loader.js +4 -3
- package/dist/esm/loader.js.map +1 -1
- package/dist/esm/md-accordion-item.entry.js +4 -4
- package/dist/esm/md-accordion.entry.js +1 -1
- package/dist/esm/md-app-bar.entry.js +2 -2
- package/dist/esm/md-area-chart.entry.js +7 -7
- package/dist/esm/md-autocomplete.entry.js +6 -5
- package/dist/esm/md-autocomplete.entry.js.map +1 -1
- package/dist/esm/md-avatar_2.entry.js +4 -4
- package/dist/esm/md-badge.entry.js +3 -3
- package/dist/esm/md-bar-chart.entry.js +7 -7
- package/dist/esm/md-bottom-sheet.entry.js +5 -5
- package/dist/esm/md-breadcrumb-item.entry.js +2 -2
- package/dist/esm/md-breadcrumbs.entry.js +3 -3
- package/dist/esm/md-button-group.entry.js +3 -3
- package/dist/esm/{md-button_7.entry.js → md-button_6.entry.js} +16 -40
- package/dist/esm/md-button_6.entry.js.map +1 -0
- package/dist/esm/md-checkbox.entry.js +3 -3
- package/dist/esm/md-chip.entry.js +3 -3
- package/dist/esm/md-color-picker.entry.js +1 -1
- package/dist/esm/md-date-picker.entry.js +2 -2
- package/dist/esm/md-dialog.entry.js +3 -3
- package/dist/esm/md-divider.entry.js +3 -3
- package/dist/esm/md-fab-menu-item.entry.js +3 -3
- package/dist/esm/md-fab-menu.entry.js +3 -3
- package/dist/esm/md-fab.entry.js +3 -3
- package/dist/esm/md-line-chart.entry.js +7 -7
- package/dist/esm/md-list-item.entry.js +5 -5
- package/dist/esm/md-list.entry.js +4 -4
- package/dist/esm/md-loading-indicator-Bf-Pt29l.js +31 -0
- package/dist/esm/md-loading-indicator-Bf-Pt29l.js.map +1 -0
- package/dist/esm/md-loading-indicator.entry.js +5 -0
- package/dist/esm/md-loading-indicator.entry.js.map +1 -0
- package/dist/esm/md-menu-item-group.entry.js +1 -1
- package/dist/esm/md-menu_2.entry.js +6 -6
- package/dist/esm/md-meter.entry.js +1 -1
- package/dist/esm/md-multi-select.entry.js +7 -6
- package/dist/esm/md-multi-select.entry.js.map +1 -1
- package/dist/esm/md-navigation-bar.entry.js +2 -2
- package/dist/esm/md-navigation-rail-tab.entry.js +2 -2
- package/dist/esm/md-navigation-rail.entry.js +1 -1
- package/dist/esm/md-navigation-tab.entry.js +4 -4
- package/dist/esm/md-number-field.entry.js +3 -3
- package/dist/esm/md-organization-chart.entry.js +3 -3
- package/dist/esm/md-otp-field.entry.js +4 -4
- package/dist/esm/md-pie-chart.entry.js +3 -3
- package/dist/esm/md-progress-indicator.entry.js +1 -1
- package/dist/esm/md-rating.entry.js +1 -1
- package/dist/esm/md-search.entry.js +8 -7
- package/dist/esm/md-search.entry.js.map +1 -1
- package/dist/esm/md-segmented-button-set.entry.js +1 -1
- package/dist/esm/md-segmented-button.entry.js +1 -1
- package/dist/esm/md-select-option.entry.js +2 -2
- package/dist/esm/md-select.entry.js +7 -6
- package/dist/esm/md-select.entry.js.map +1 -1
- package/dist/esm/md-side-sheet.entry.js +1 -1
- package/dist/esm/md-skeleton.entry.js +1 -1
- package/dist/esm/md-slider.entry.js +3 -3
- package/dist/esm/md-sparkline.entry.js +7 -7
- package/dist/esm/md-split-button.entry.js +1 -1
- package/dist/esm/md-status-dot.entry.js +2 -2
- package/dist/esm/md-step.entry.js +1 -1
- package/dist/esm/md-stepper.entry.js +1 -1
- package/dist/esm/md-sub-menu-item.entry.js +1 -1
- package/dist/esm/md-switch.entry.js +1 -1
- package/dist/esm/md-tab-panel.entry.js +1 -1
- package/dist/esm/md-tab-panels.entry.js +1 -1
- package/dist/esm/md-tab.entry.js +1 -1
- package/dist/esm/md-table-body.entry.js +1 -1
- package/dist/esm/md-table-cell.entry.js +1 -1
- package/dist/esm/md-table-container.entry.js +1 -1
- package/dist/esm/md-table-expand-toggle.entry.js +1 -1
- package/dist/esm/md-table-foot.entry.js +1 -1
- package/dist/esm/md-table-head.entry.js +1 -1
- package/dist/esm/md-table-pagination.entry.js +1 -1
- package/dist/esm/md-table-row.entry.js +1 -1
- package/dist/esm/md-table-sort-label.entry.js +1 -1
- package/dist/esm/md-table-toolbar.entry.js +1 -1
- package/dist/esm/md-table.entry.js +4 -4
- package/dist/esm/md-tabs.entry.js +1 -1
- package/dist/esm/md-text-field.entry.js +8 -8
- package/dist/esm/md-time-picker.entry.js +2 -2
- package/dist/esm/md-toolbar.entry.js +1 -1
- package/dist/esm/md-transfer-list.entry.js +2 -2
- package/dist/esm/md3.js +4 -3
- package/dist/esm/md3.js.map +1 -1
- package/dist/esm/{rtl-DvOKnoqK.js → rtl-CVFH1DkU.js} +3 -3
- package/dist/esm/{rtl-DvOKnoqK.js.map → rtl-CVFH1DkU.js.map} +1 -1
- package/dist/esm/{url-BjYKc1Ge.js → url-BdEoSBtL.js} +3 -3
- package/dist/esm/{url-BjYKc1Ge.js.map → url-BdEoSBtL.js.map} +1 -1
- package/dist/esm/{virtual-select-controller-BEWIC0pC.js → virtual-select-controller-CR60w6DO.js} +10 -9
- package/dist/esm/virtual-select-controller-CR60w6DO.js.map +1 -0
- package/dist/md3/md3.css +1 -1
- package/dist/md3/md3.esm.js +1 -1
- package/dist/md3/md3.esm.js.map +1 -1
- package/dist/md3/p-08f1c469.entry.js +2 -0
- package/dist/md3/{p-4d82132d.entry.js.map → p-08f1c469.entry.js.map} +1 -1
- package/dist/md3/{p-9ddbf247.entry.js → p-108f89d7.entry.js} +2 -2
- package/dist/md3/p-1112bffc.entry.js +2 -0
- package/dist/md3/{p-cf07e761.entry.js.map → p-1112bffc.entry.js.map} +1 -1
- package/dist/md3/{p-c6a12344.entry.js → p-114c270b.entry.js} +2 -2
- package/dist/md3/p-1835fe36.entry.js +2 -0
- package/dist/md3/{p-a3308c40.entry.js.map → p-1835fe36.entry.js.map} +1 -1
- package/dist/md3/{p-396089fd.entry.js → p-1edb5a0d.entry.js} +2 -2
- package/dist/md3/p-2ba2db3b.entry.js +2 -0
- package/dist/md3/{p-6b2871a0.entry.js.map → p-2ba2db3b.entry.js.map} +1 -1
- package/dist/md3/p-3508d0e0.entry.js +2 -0
- package/dist/md3/{p-f31ab454.entry.js.map → p-3508d0e0.entry.js.map} +1 -1
- package/dist/md3/{p-b34d385b.entry.js → p-35b05b45.entry.js} +2 -2
- package/dist/md3/{p-c2dd8c8c.entry.js → p-38e9a583.entry.js} +2 -2
- package/dist/md3/{p-be02624e.entry.js → p-3c0469aa.entry.js} +2 -2
- package/dist/md3/p-3f64a27d.entry.js +2 -0
- package/dist/md3/{p-fb61868c.entry.js.map → p-3f64a27d.entry.js.map} +1 -1
- package/dist/md3/{p-63b8c8d1.entry.js → p-408ee4be.entry.js} +2 -2
- package/dist/md3/{p-edb34a6d.entry.js → p-43c708ad.entry.js} +2 -2
- package/dist/md3/{p-3015c7e3.entry.js → p-4770b534.entry.js} +2 -2
- package/dist/md3/{p-c861d774.entry.js → p-4b7cf934.entry.js} +2 -2
- package/dist/md3/{p-2e09a7b7.entry.js → p-4f26bd60.entry.js} +2 -2
- package/dist/md3/{p-7b463fbe.entry.js → p-4f2e82cb.entry.js} +2 -2
- package/dist/md3/{p-be412e3f.entry.js → p-501bf161.entry.js} +2 -2
- package/dist/md3/{p-c063c823.entry.js → p-56c7c570.entry.js} +2 -2
- package/dist/md3/{p-2e9503d7.entry.js → p-56ca0c3c.entry.js} +2 -2
- package/dist/md3/{p-ac8762e5.entry.js → p-5b63149a.entry.js} +2 -2
- package/dist/md3/{p-c5af701b.entry.js → p-5f668b0a.entry.js} +2 -2
- package/dist/md3/p-6237ddac.entry.js +2 -0
- package/dist/md3/{p-e7dc5a32.entry.js.map → p-6237ddac.entry.js.map} +1 -1
- package/dist/md3/{p-8eb0b6a4.entry.js → p-6d65fc6a.entry.js} +2 -2
- package/dist/md3/{p-e3124e1e.entry.js → p-707b6d7c.entry.js} +2 -2
- package/dist/md3/{p-a5fee424.entry.js → p-71f1660b.entry.js} +2 -2
- package/dist/md3/{p-1a8ec5bc.entry.js → p-7501170f.entry.js} +2 -2
- package/dist/md3/p-7c8842bf.entry.js +2 -0
- package/dist/md3/{p-ba2ebde1.entry.js.map → p-7c8842bf.entry.js.map} +1 -1
- package/dist/md3/{p-4e3d6e40.entry.js → p-7d1686a7.entry.js} +2 -2
- package/dist/md3/p-7e7f0e45.entry.js +2 -0
- package/dist/md3/p-7e7f0e45.entry.js.map +1 -0
- package/dist/md3/p-80379565.entry.js +2 -0
- package/dist/md3/{p-6c44cf13.entry.js.map → p-80379565.entry.js.map} +1 -1
- package/dist/md3/p-830724e4.entry.js +2 -0
- package/dist/md3/p-830724e4.entry.js.map +1 -0
- package/dist/md3/{p-4dda4cb0.entry.js → p-845ca9cc.entry.js} +2 -2
- package/dist/md3/{p-77a01bcc.entry.js → p-87f88d62.entry.js} +2 -2
- package/dist/md3/{p-5b74694e.entry.js → p-89d47130.entry.js} +2 -2
- package/dist/md3/p-8a6fed13.entry.js +2 -0
- package/dist/md3/{p-a803da99.entry.js.map → p-8a6fed13.entry.js.map} +1 -1
- package/dist/md3/p-8a7e0297.entry.js +2 -0
- package/dist/md3/p-8a7e0297.entry.js.map +1 -0
- package/dist/md3/{p-b0431a5c.entry.js → p-8bdcda53.entry.js} +2 -2
- package/dist/md3/{p-c10a33c2.entry.js → p-8e7df348.entry.js} +2 -2
- package/dist/md3/p-9003a7d4.entry.js +2 -0
- package/dist/md3/p-9003a7d4.entry.js.map +1 -0
- package/dist/md3/{p-05ae91b6.entry.js → p-90ccf4c3.entry.js} +2 -2
- package/dist/md3/p-BdEoSBtL.js +2 -0
- package/dist/md3/{p-BjYKc1Ge.js.map → p-BdEoSBtL.js.map} +1 -1
- package/dist/md3/p-Bz-JaJcA.js +2 -0
- package/dist/md3/p-Bz-JaJcA.js.map +1 -0
- package/dist/md3/p-CGqeEMjY.js +2 -0
- package/dist/md3/{p-DzPKu-Ma.js.map → p-CGqeEMjY.js.map} +1 -1
- package/dist/md3/p-CVFH1DkU.js +2 -0
- package/dist/md3/{p-DvOKnoqK.js.map → p-CVFH1DkU.js.map} +1 -1
- package/dist/md3/p-Cch92tDM.js +2 -0
- package/dist/md3/{p-RLxbNqRv.js.map → p-Cch92tDM.js.map} +1 -1
- package/dist/md3/p-CfBPnYW7.js +2 -0
- package/dist/md3/p-CfBPnYW7.js.map +1 -0
- package/dist/md3/p-D17cVKxS.js +2 -0
- package/dist/md3/p-D17cVKxS.js.map +1 -0
- package/dist/md3/p-DGtztV3K.js +2 -0
- package/dist/md3/{p-Bx6--dQF.js.map → p-DGtztV3K.js.map} +1 -1
- package/dist/md3/p-DQuL1Twl.js +2 -0
- package/dist/md3/p-DQuL1Twl.js.map +1 -0
- package/dist/md3/p-DnKDoE8K.js +2 -0
- package/dist/md3/p-DnKDoE8K.js.map +1 -0
- package/dist/md3/p-WmvQpZnM.js +3 -0
- package/dist/md3/p-WmvQpZnM.js.map +1 -0
- package/dist/md3/p-a3623653.entry.js +2 -0
- package/dist/md3/{p-19ee9c33.entry.js.map → p-a3623653.entry.js.map} +1 -1
- package/dist/md3/{p-da4e27d4.entry.js → p-a4d4cfed.entry.js} +2 -2
- package/dist/md3/{p-5394254f.entry.js → p-a976498b.entry.js} +2 -2
- package/dist/md3/{p-6038b907.entry.js → p-ab568d1c.entry.js} +2 -2
- package/dist/md3/{p-bf7842f8.entry.js → p-adf8a415.entry.js} +2 -2
- package/dist/md3/p-ae30e899.entry.js +2 -0
- package/dist/md3/p-ae30e899.entry.js.map +1 -0
- package/dist/md3/{p-45280bf4.entry.js → p-b2d88292.entry.js} +2 -2
- package/dist/md3/{p-796f79f8.entry.js → p-b3b5247b.entry.js} +2 -2
- package/dist/md3/{p-5b799707.entry.js → p-b4266f6b.entry.js} +2 -2
- package/dist/md3/p-b54bbf88.entry.js +2 -0
- package/dist/md3/p-b54bbf88.entry.js.map +1 -0
- package/dist/md3/{p-c00f7514.entry.js → p-ba011453.entry.js} +2 -2
- package/dist/md3/{p-6ba63c73.entry.js → p-bc24f0c9.entry.js} +2 -2
- package/dist/md3/{p-0c2e824d.entry.js → p-c20fbb9e.entry.js} +2 -2
- package/dist/md3/{p-fc0b325d.entry.js → p-c2944c87.entry.js} +2 -2
- package/dist/md3/{p-4e45b2ff.entry.js → p-c58c68d0.entry.js} +2 -2
- package/dist/md3/p-cc6e8afd.entry.js +2 -0
- package/dist/md3/{p-72457a85.entry.js.map → p-cc6e8afd.entry.js.map} +1 -1
- package/dist/md3/{p-0f764a1e.entry.js → p-d2e39c6e.entry.js} +2 -2
- package/dist/md3/{p-50555bb7.entry.js → p-d8885f53.entry.js} +2 -2
- package/dist/md3/{p-c1ca6f6c.entry.js → p-db6fb4e1.entry.js} +2 -2
- package/dist/md3/{p-81843ff7.entry.js → p-dcba2857.entry.js} +2 -2
- package/dist/md3/{p-65195996.entry.js → p-e357e8ac.entry.js} +2 -2
- package/dist/md3/{p-39cb7c24.entry.js → p-e5c6795e.entry.js} +2 -2
- package/dist/md3/p-e871663b.entry.js +2 -0
- package/dist/md3/{p-aaec2698.entry.js.map → p-e871663b.entry.js.map} +1 -1
- package/dist/md3/p-f1b69181.entry.js +2 -0
- package/dist/md3/{p-a986fd24.entry.js.map → p-f1b69181.entry.js.map} +1 -1
- package/dist/md3/p-f297d786.entry.js +2 -0
- package/dist/md3/{p-3cce1de3.entry.js.map → p-f297d786.entry.js.map} +1 -1
- package/dist/md3/{p-e6d7f0ff.entry.js → p-f403ad20.entry.js} +2 -2
- package/dist/md3/p-f5399b73.entry.js +2 -0
- package/dist/md3/{p-04e97f5d.entry.js.map → p-f5399b73.entry.js.map} +1 -1
- package/dist/md3/{p-708a9313.entry.js → p-f5fd9a0b.entry.js} +2 -2
- package/dist/md3/{p-aa0e7d4d.entry.js → p-f71af38f.entry.js} +2 -2
- package/dist/md3/{p-757e3aaf.entry.js → p-fac6da4c.entry.js} +2 -2
- package/dist/md3/{p-134b670a.entry.js → p-fc864f96.entry.js} +2 -2
- package/dist/md3/{p-32bdd439.entry.js → p-fd686966.entry.js} +2 -2
- package/dist/md3/p-nhfFYWzy.js +2 -0
- package/dist/md3/{p-C_ogF68H.js.map → p-nhfFYWzy.js.map} +1 -1
- package/dist/types/utils/lazy-loading-indicator.d.ts +7 -0
- package/dist/types/wasm/engine-abi.d.ts +14 -0
- package/hydrate/index.js +191 -113
- package/hydrate/index.mjs +191 -113
- package/package.json +30 -5
- package/dist/cjs/index-DlQ_5_Mv.js.map +0 -1
- package/dist/cjs/md-button_7.cjs.entry.js.map +0 -1
- package/dist/cjs/virtual-select-controller-CqriaZgm.js.map +0 -1
- package/dist/components/p-BEWIC0pC.js +0 -2
- package/dist/components/p-BEWIC0pC.js.map +0 -1
- package/dist/components/p-DXXUoRSH.js.map +0 -1
- package/dist/components/p-MWBNn6Lj.js +0 -2
- package/dist/components/p-MWBNn6Lj.js.map +0 -1
- package/dist/components/p-UdGDg2oJ.js.map +0 -1
- package/dist/esm/index-DTaX19_O.js.map +0 -1
- package/dist/esm/md-button_7.entry.js.map +0 -1
- package/dist/esm/virtual-select-controller-BEWIC0pC.js.map +0 -1
- package/dist/md3/p-04e97f5d.entry.js +0 -2
- package/dist/md3/p-19ee9c33.entry.js +0 -2
- package/dist/md3/p-21772851.entry.js +0 -2
- package/dist/md3/p-21772851.entry.js.map +0 -1
- package/dist/md3/p-3cce1de3.entry.js +0 -2
- package/dist/md3/p-47af9819.entry.js +0 -2
- package/dist/md3/p-47af9819.entry.js.map +0 -1
- package/dist/md3/p-4d82132d.entry.js +0 -2
- package/dist/md3/p-6b2871a0.entry.js +0 -2
- package/dist/md3/p-6c44cf13.entry.js +0 -2
- package/dist/md3/p-72457a85.entry.js +0 -2
- package/dist/md3/p-BEWIC0pC.js +0 -2
- package/dist/md3/p-BEWIC0pC.js.map +0 -1
- package/dist/md3/p-DTaX19_O.js +0 -3
- package/dist/md3/p-DTaX19_O.js.map +0 -1
- package/dist/md3/p-a3308c40.entry.js +0 -2
- package/dist/md3/p-a7ffb779.entry.js +0 -2
- package/dist/md3/p-a7ffb779.entry.js.map +0 -1
- package/dist/md3/p-a803da99.entry.js +0 -2
- package/dist/md3/p-a986fd24.entry.js +0 -2
- package/dist/md3/p-aaec2698.entry.js +0 -2
- package/dist/md3/p-ac35ac5f.entry.js +0 -2
- package/dist/md3/p-ac35ac5f.entry.js.map +0 -1
- package/dist/md3/p-b4631a55.entry.js +0 -2
- package/dist/md3/p-b4631a55.entry.js.map +0 -1
- package/dist/md3/p-ba2ebde1.entry.js +0 -2
- package/dist/md3/p-cf07e761.entry.js +0 -2
- package/dist/md3/p-e7dc5a32.entry.js +0 -2
- package/dist/md3/p-f31ab454.entry.js +0 -2
- package/dist/md3/p-fb61868c.entry.js +0 -2
- /package/dist/{components/p-uTEkf0sE.js.map → components-csr/p-BEmwDSzw.js.map} +0 -0
- /package/dist/{components/p-C8EP4S21.js.map → components-csr/p-BQKzjYcY.js.map} +0 -0
- /package/dist/{components/p-BwXpiUsu.js.map → components-csr/p-BWMwewtY.js.map} +0 -0
- /package/dist/{components/p-B0Opn6dK.js.map → components-csr/p-Bkt_X-6v.js.map} +0 -0
- /package/dist/{md3 → components-csr}/p-Bx6--dQF.js +0 -0
- /package/dist/{components/p-stybaFzj.js.map → components-csr/p-C3vB0Hd9.js.map} +0 -0
- /package/dist/{components/p-B3MWYEEJ.js.map → components-csr/p-CF7mq5T7.js.map} +0 -0
- /package/dist/{components/p-7fN_yCXW.js.map → components-csr/p-CVMM-tdC.js.map} +0 -0
- /package/dist/{md3 → components-csr}/p-C_ogF68H.js +0 -0
- /package/dist/{components/p-Ch2-tttM.js.map → components-csr/p-DMQ-6aj8.js.map} +0 -0
- /package/dist/{components/p-e2HRV63Y.js.map → components-csr/p-DfcpeJAu.js.map} +0 -0
- /package/dist/{components/p-Dp-w93ot.js.map → components-csr/p-DjKPc5EU.js.map} +0 -0
- /package/dist/{md3 → components-csr}/p-DvOKnoqK.js +0 -0
- /package/dist/{md3 → components-csr}/p-DzPKu-Ma.js +0 -0
- /package/dist/{md3 → components-csr}/p-RLxbNqRv.js +0 -0
- /package/dist/{components/p-6wZSqm_2.js.map → components-csr/p-R_guULjT.js.map} +0 -0
- /package/dist/{components/p-Ddiw2Kjw.js.map → components-csr/p-uSMrgqAy.js.map} +0 -0
- /package/dist/md3/{p-9ddbf247.entry.js.map → p-108f89d7.entry.js.map} +0 -0
- /package/dist/md3/{p-c6a12344.entry.js.map → p-114c270b.entry.js.map} +0 -0
- /package/dist/md3/{p-396089fd.entry.js.map → p-1edb5a0d.entry.js.map} +0 -0
- /package/dist/md3/{p-b34d385b.entry.js.map → p-35b05b45.entry.js.map} +0 -0
- /package/dist/md3/{p-c2dd8c8c.entry.js.map → p-38e9a583.entry.js.map} +0 -0
- /package/dist/md3/{p-be02624e.entry.js.map → p-3c0469aa.entry.js.map} +0 -0
- /package/dist/md3/{p-63b8c8d1.entry.js.map → p-408ee4be.entry.js.map} +0 -0
- /package/dist/md3/{p-edb34a6d.entry.js.map → p-43c708ad.entry.js.map} +0 -0
- /package/dist/md3/{p-3015c7e3.entry.js.map → p-4770b534.entry.js.map} +0 -0
- /package/dist/md3/{p-c861d774.entry.js.map → p-4b7cf934.entry.js.map} +0 -0
- /package/dist/md3/{p-2e09a7b7.entry.js.map → p-4f26bd60.entry.js.map} +0 -0
- /package/dist/md3/{p-7b463fbe.entry.js.map → p-4f2e82cb.entry.js.map} +0 -0
- /package/dist/md3/{p-be412e3f.entry.js.map → p-501bf161.entry.js.map} +0 -0
- /package/dist/md3/{p-c063c823.entry.js.map → p-56c7c570.entry.js.map} +0 -0
- /package/dist/md3/{p-2e9503d7.entry.js.map → p-56ca0c3c.entry.js.map} +0 -0
- /package/dist/md3/{p-ac8762e5.entry.js.map → p-5b63149a.entry.js.map} +0 -0
- /package/dist/md3/{p-c5af701b.entry.js.map → p-5f668b0a.entry.js.map} +0 -0
- /package/dist/md3/{p-8eb0b6a4.entry.js.map → p-6d65fc6a.entry.js.map} +0 -0
- /package/dist/md3/{p-e3124e1e.entry.js.map → p-707b6d7c.entry.js.map} +0 -0
- /package/dist/md3/{p-a5fee424.entry.js.map → p-71f1660b.entry.js.map} +0 -0
- /package/dist/md3/{p-1a8ec5bc.entry.js.map → p-7501170f.entry.js.map} +0 -0
- /package/dist/md3/{p-4e3d6e40.entry.js.map → p-7d1686a7.entry.js.map} +0 -0
- /package/dist/md3/{p-4dda4cb0.entry.js.map → p-845ca9cc.entry.js.map} +0 -0
- /package/dist/md3/{p-77a01bcc.entry.js.map → p-87f88d62.entry.js.map} +0 -0
- /package/dist/md3/{p-5b74694e.entry.js.map → p-89d47130.entry.js.map} +0 -0
- /package/dist/md3/{p-b0431a5c.entry.js.map → p-8bdcda53.entry.js.map} +0 -0
- /package/dist/md3/{p-c10a33c2.entry.js.map → p-8e7df348.entry.js.map} +0 -0
- /package/dist/md3/{p-05ae91b6.entry.js.map → p-90ccf4c3.entry.js.map} +0 -0
- /package/dist/md3/{p-da4e27d4.entry.js.map → p-a4d4cfed.entry.js.map} +0 -0
- /package/dist/md3/{p-5394254f.entry.js.map → p-a976498b.entry.js.map} +0 -0
- /package/dist/md3/{p-6038b907.entry.js.map → p-ab568d1c.entry.js.map} +0 -0
- /package/dist/md3/{p-bf7842f8.entry.js.map → p-adf8a415.entry.js.map} +0 -0
- /package/dist/md3/{p-45280bf4.entry.js.map → p-b2d88292.entry.js.map} +0 -0
- /package/dist/md3/{p-796f79f8.entry.js.map → p-b3b5247b.entry.js.map} +0 -0
- /package/dist/md3/{p-5b799707.entry.js.map → p-b4266f6b.entry.js.map} +0 -0
- /package/dist/md3/{p-c00f7514.entry.js.map → p-ba011453.entry.js.map} +0 -0
- /package/dist/md3/{p-6ba63c73.entry.js.map → p-bc24f0c9.entry.js.map} +0 -0
- /package/dist/md3/{p-0c2e824d.entry.js.map → p-c20fbb9e.entry.js.map} +0 -0
- /package/dist/md3/{p-fc0b325d.entry.js.map → p-c2944c87.entry.js.map} +0 -0
- /package/dist/md3/{p-4e45b2ff.entry.js.map → p-c58c68d0.entry.js.map} +0 -0
- /package/dist/md3/{p-0f764a1e.entry.js.map → p-d2e39c6e.entry.js.map} +0 -0
- /package/dist/md3/{p-50555bb7.entry.js.map → p-d8885f53.entry.js.map} +0 -0
- /package/dist/md3/{p-c1ca6f6c.entry.js.map → p-db6fb4e1.entry.js.map} +0 -0
- /package/dist/md3/{p-81843ff7.entry.js.map → p-dcba2857.entry.js.map} +0 -0
- /package/dist/md3/{p-65195996.entry.js.map → p-e357e8ac.entry.js.map} +0 -0
- /package/dist/md3/{p-39cb7c24.entry.js.map → p-e5c6795e.entry.js.map} +0 -0
- /package/dist/md3/{p-e6d7f0ff.entry.js.map → p-f403ad20.entry.js.map} +0 -0
- /package/dist/md3/{p-708a9313.entry.js.map → p-f5fd9a0b.entry.js.map} +0 -0
- /package/dist/md3/{p-aa0e7d4d.entry.js.map → p-f71af38f.entry.js.map} +0 -0
- /package/dist/md3/{p-757e3aaf.entry.js.map → p-fac6da4c.entry.js.map} +0 -0
- /package/dist/md3/{p-134b670a.entry.js.map → p-fc864f96.entry.js.map} +0 -0
- /package/dist/md3/{p-32bdd439.entry.js.map → p-fd686966.entry.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["mdMenuCss","CLOSE_ANIMATION_MS","TYPEAHEAD_TIMEOUT_MS","VIEWPORT_MARGIN","COMPACT_BREAKPOINT","EXPANDABLE_ANCHOR_ROLES","Set","NATIVE_EXPANDABLE_TAGS","menuIdCounter","MdMenu","constructor","hostRef","this","open","anchor","placement","quick","variant","layout","useGap","emptyText","matchAnchorWidth","responsive","persistent","autoFocus","closing","sectioned","empty","hasSubmenu","focusedIndex","navSeq","ringedIndex","skipAutoFocus","menuId","typeaheadBuffer","keyboardModality","openedViaKeyboard","listboxMode","listbox","density","trackKeyboardModality","trackPointerModality","lastSurfaceSize","handleOutsideClick","e","path","composedPath","includes","el","close","handleDocumentKeyDown","key","restoreFocusToAnchor","handleScroll","positionMenu","handleSlotChange","updateSections","propagateVariant","wireItemObserver","updateEmpty","querySelector","asListbox","setComboboxElement","comboboxEl","removeAttribute","undefined","connectedCallback","document","addEventListener","componentDidLoad","applyDepthZIndex","onEmptyTextChange","onVariantChange","setVirtualProvider","provider","getScrollViewport","shadowRoot","show","opts","clearTimeout","closeTimer","collapseSubmenus","reposition","setTimeout","onOpenChange","dismissPeerMenus","requestAnimationFrame","mdOpen","emit","updateAnchorAria","window","observeSurfaceResize","scheduleFocus","initRovingTabindex","focusFirstItem","mdClose","resetRovingTabindex","removeEventListener","unobserveSurfaceResize","ResizeObserver","surface","surfaceRO","entries","r","length","contentRect","size","Math","round","width","height","observe","disconnect","handleFocusIn","target","item","closest","attr","getAttribute","index","parseInt","isNaN","prev","domItemForIndex","setAttribute","ringed","items","getMenuItems","indexOf","handleKeyDown","handleKeyDownVirtual","preventDefault","focusItem","stopPropagation","closeEntireMenuTree","ctrlKey","metaKey","altKey","shiftKey","handleTypeahead","p","count","fromInput","tagName","focusVirtual","nextEnabled","click","handleTypeaheadVirtual","from","dir","idx","i","isDisabledAt","showRing","seq","ensureVisible","node","old","id","focus","preventScroll","char","typeaheadTimer","toLowerCase","findPrefix","all","Array","querySelectorAll","filter","getItemLabel","headline","textContent","trim","startIndex","label","startsWith","forEach","subItems","collapse","allItems","fn","retries","getAnchorEl","root","getRootNode","getElementById","anchorEl","anchorRole","supportsExpanded","has","hasAttribute","style","zIndex","anchorRect","getBoundingClientRect","gap","minWidth","top","left","right","bottom","menuW","offsetWidth","menuH","offsetHeight","vw","innerWidth","vh","innerHeight","m","h","transformOrigin","max","min","vertical","horizontal","endsWith","spaceBelow","spaceAbove","scrollCapped","avail","scrollEl","chrome","setProperty","removeProperty","vOrigin","hOrigin","clampedLeft","clampedTop","rootMenu","current","parentMenu","parentElement","anchorId","peer","contains","isHidden","display","hasVisibleItem","tag","children","some","child","slot","getContentSlot","assignedElements","itemObserver","MutationObserver","attributes","attributeFilter","subtree","slots","find","s","nested","foundGap","afterGap","disconnectedCallback","inlineFill","classList","maxHeightValue","maxHeight","raw","String","test","useScrollViewport","renderMenuBody","onSlotchange","class","part","role","render","Host","inert","name","tabindex","maxBlockSize","mdMenuItemCss","MdMenuItem","supportingText","trailingText","disabled","selected","indeterminate","keepOpen","divider","badge","type","checkPosition","presentation","roleOverride","hasLeadingIcon","hasTrailingIcon","handleClick","deselectSiblingRadios","mdClick","menu","parent","triggerRipple","componentWillLoad","group","siblings","sibling","onClick","onKeyDown"],"sources":["src/components/md-menu/md-menu.css?tag=md-menu&encapsulation=shadow","src/components/md-menu/md-menu.tsx","src/components/md-menu-item/md-menu-item.css?tag=md-menu-item&encapsulation=shadow","src/components/md-menu-item/md-menu-item.tsx"],"sourcesContent":["/* ═══════════════════════════════════════════════════════════\n md-menu\n Material Design 3 — Menus\n https://m3.material.io/components/menus/specs\n\n Variants:\n baseline — MD3 original (8px corners, surface container)\n standard — M3 Expressive vertical (16px corners, surface-based)\n vibrant — M3 Expressive vertical (16px corners, tertiary-based)\n\n CSS custom properties:\n --md-menu-min-width Min container width (default 112px)\n --md-menu-max-width Max container width (default 280px)\n --md-menu-inline-surface-color Background for md-menu--inline-fill only (default transparent)\n --md-menu-inline-fill-radius-end Bottom corner radius for inline-fill embed (default 0)\n --md-sys-z-index-popup Stack order (default 1000)\n\n Parts: (none — container is internal)\n Slots: (default) — accepts md-menu-item, md-sub-menu-item\n ═══════════════════════════════════════════════════════════ */\n\n/* ==========================================================\n 1. HOST\n ========================================================== */\n:host {\n display: block;\n position: fixed;\n z-index: auto;\n pointer-events: none;\n}\n\n:host(.md-menu--open) {\n pointer-events: auto;\n}\n\n/* ==========================================================\n 2. SURFACE — BASELINE\n ========================================================== */\n.md-menu__surface {\n background-color: var(--md-sys-color-surface-container, #F7F2FA);\n border-radius: var(--md-sys-shape-corner-small, 8px);\n box-shadow:\n 0 1px 2px rgba(0, 0, 0, 0.3),\n 0 2px 6px 2px rgba(0, 0, 0, 0.15);\n min-width: var(--md-menu-min-width, 112px);\n /* Grow to fit the widest item, bounded only by the viewport (minus an edge\n margin) — long labels no longer truncate at a fixed 280px. Consumers wanting\n the MD3 280dp cap (or any cap) set --md-menu-max-width; we still clamp that\n to the viewport so it can never run off-screen. */\n max-width: min(\n var(--md-menu-max-width, 100vw),\n calc(100vw - 2 * var(--md-menu-viewport-margin, 8px))\n );\n /* Inline padding is 0 by design: baseline menu rows are FULL-BLEED, so their\n hover / focus / selected state layer runs edge to edge (M3 gives the menu\n list vertical padding only). An inline inset here leaves the highlight\n floating in a gutter — visible on md-select, which uses this surface.\n The vertical `standard` / `vibrant` variants override this with a real\n inline inset further down, because THEIR rows are rounded plates and need\n the breathing room for the corner radius. */\n padding: var(--md-sys-spacing-inset-xs, 4px) 0;\n overflow: visible;\n opacity: 0;\n transform: scaleY(0.8);\n transform-origin: top left;\n transition:\n opacity var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n transform var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n:host(.md-menu--open) .md-menu__surface {\n opacity: 1;\n transform: none;\n}\n\n/* --- Close animation --- */\n:host(.md-menu--closing) .md-menu__surface {\n opacity: 0;\n transform: scaleY(0.8);\n transition:\n opacity var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)),\n transform var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15));\n}\n\n/* Keep pointer-events active during close so ripple finishes */\n:host(.md-menu--closing) {\n pointer-events: none;\n}\n\n:host(.md-menu--quick) .md-menu__surface {\n transition: none;\n}\n\n/* --- Inline fill: embedded in a flex parent (e.g. md-date-picker docked panel) --- */\n:host(.md-menu--inline-fill) {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-block-size: 0;\n block-size: 100%;\n inline-size: 100%;\n pointer-events: auto;\n}\n\n:host(.md-menu--inline-fill) .md-menu__surface {\n flex: 1 1 auto;\n block-size: 100%;\n min-block-size: 0;\n min-inline-size: 100%;\n max-inline-size: none;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: none;\n border: none;\n outline: none;\n /* Baseline menus use padding: 4px 0 — strip for flush embed (e.g. date-picker). */\n padding: 0;\n border-radius: 0;\n border-end-start-radius: var(--md-menu-inline-fill-radius-end, 0);\n border-end-end-radius: var(--md-menu-inline-fill-radius-end, 0);\n /* Consumer sets --md-menu-inline-surface-color (e.g. md-date-picker docked panel). */\n background-color: var(--md-menu-inline-surface-color, transparent);\n}\n\n/* Inline-fill scroll is owned by md-scroll-shadow (edge fades when overflow). */\n:host(.md-menu--inline-fill) .md-menu__scroll-shadow {\n flex: 1 1 auto;\n min-block-size: 0;\n block-size: 100%;\n}\n\n:host(.md-menu--inline-fill) .md-menu__surface ::slotted(md-menu-item:last-child) {\n border-end-start-radius: var(--md-menu-inline-fill-radius-end, 0);\n border-end-end-radius: var(--md-menu-inline-fill-radius-end, 0);\n}\n\n/* --- Capped height: long lists scroll inside md-scroll-shadow (edge fades) --- */\n/* The scroll-shadow (display:flex column, bounded by the inline max-block-size)\n owns the vertical scroll; the surface only clips so it never double-scrolls.\n The viewport-safe rule below opts capped menus out (:not(.md-menu--scroll))\n so its `overflow-y: auto` can't compete with this. */\n:host(.md-menu--scroll):not(.md-menu--has-submenu) .md-menu__surface {\n overflow: hidden;\n}\n\n:host(.md-menu--scroll) .md-menu__scroll-shadow {\n min-block-size: 0;\n}\n\n/* The menu's scroll viewport (long lists scroll inside its inline max-block-size\n cap). Virtualized menus reposition their windowed rows by rewriting a\n multi-million-px top spacer between renders. Browser scroll-anchoring would try\n to keep the pre-render content stable and silently shift scrollTop to\n compensate — which desyncs the keyboard-nav anchor from the offset it was laid\n out for and snaps the view away. Opt out so our programmatic offset wins. */\n.md-menu__scroll-shadow {\n overflow-y: auto;\n overflow-anchor: none;\n}\n\n/* --- Match anchor width: min-width set via JS; grow to content but stay on-screen --- */\n:host([match-anchor-width]) .md-menu__surface {\n max-width: calc(100vw - 2 * var(--md-menu-viewport-margin, 8px));\n box-sizing: border-box;\n}\n\n/* ==========================================================\n 2b. RESPONSIVE / VIEWPORT-SAFE SIZING\n ========================================================== */\n\n/* Tall menus scroll instead of running off the bottom of the screen. Skipped\n when the menu has submenus — their flyouts are positioned children that\n would be clipped by an overflow on the surface — and when capped, where\n md-scroll-shadow owns the scroll instead (see the capped-height block above). */\n:host(:not(.md-menu--has-submenu):not(.md-menu--inline-fill):not(.md-menu--scroll)) .md-menu__surface {\n max-height: calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px));\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n/* `responsive` on a compact viewport: near-full-width sheet below the trigger.\n Positioning (left edge + vertical flip/clamp) is handled in positionMenu(). */\n@media (max-width: 600px) {\n :host(.md-menu--responsive) .md-menu__surface {\n width: calc(100vw - 2 * var(--md-menu-viewport-margin, 8px));\n min-width: 0;\n max-width: none;\n box-sizing: border-box;\n }\n}\n\n/* ==========================================================\n 3. PLACEMENT — TRANSFORM ORIGIN\n ========================================================== */\n:host([placement=\"bottom-start\"]) .md-menu__surface { transform-origin: top left; }\n:host([placement=\"bottom-end\"]) .md-menu__surface { transform-origin: top right; }\n:host([placement=\"top-start\"]) .md-menu__surface { transform-origin: bottom left; }\n:host([placement=\"top-end\"]) .md-menu__surface { transform-origin: bottom right; }\n\n/* ==========================================================\n 4. VERTICAL MENU — STANDARD VARIANT\n ========================================================== */\n:host(.md-menu--standard) .md-menu__surface {\n background-color: var(--md-sys-color-surface-container-low, #F7F2FA);\n border-radius: var(--md-sys-shape-corner-large, 16px);\n box-shadow:\n 0 1px 3px rgba(0, 0, 0, 0.12),\n 0 4px 8px 3px rgba(0, 0, 0, 0.08);\n padding: var(--md-sys-spacing-inset-xs, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item) {\n border-radius: var(--md-sys-shape-corner-small, 8px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:first-child),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:first-child) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:last-child),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:last-child) {\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:hover) {\n border-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:active),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item.md-menu-item--selected),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:active) {\n border-radius: var(--md-sys-shape-corner-medium, 12px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:first-child:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:first-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:last-child:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:last-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-start-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n/* ==========================================================\n 5. VERTICAL MENU — VIBRANT VARIANT\n ========================================================== */\n:host(.md-menu--vibrant) .md-menu__surface {\n background-color: var(--md-sys-color-tertiary-container, #FFD8E4);\n border-radius: var(--md-sys-shape-corner-large, 16px);\n box-shadow:\n 0 1px 3px rgba(0, 0, 0, 0.12),\n 0 4px 8px 3px rgba(0, 0, 0, 0.08);\n padding: var(--md-sys-spacing-inset-xs, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item) {\n border-radius: var(--md-sys-shape-corner-small, 8px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:first-child),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:first-child) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:last-child),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:last-child) {\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:hover) {\n border-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:active),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item.md-menu-item--selected),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:active) {\n border-radius: var(--md-sys-shape-corner-medium, 12px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:first-child:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:first-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:last-child:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:last-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-start-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n/* ==========================================================\n 6. GAP LAYOUT — uniform gap between all items\n ========================================================== */\n:host(.md-menu--gap) .md-menu__surface {\n gap: var(--md-sys-spacing-gap-xs, 4px);\n display: flex;\n flex-direction: column;\n}\n\n/* ==========================================================\n 6b. GROUPED + GAP — each md-menu-item-group becomes a card\n container. The surface is transparent; groups get their\n own background, separated by a gap.\n ========================================================== */\n:host(.md-menu--grouped.md-menu--gap.md-menu--standard) .md-menu__surface,\n:host(.md-menu--grouped.md-menu--gap.md-menu--vibrant) .md-menu__surface {\n background-color: transparent;\n box-shadow: none;\n overflow: visible;\n display: flex;\n flex-direction: column;\n /* The gap between group cards is a FLEX GAP, not a margin on the cards. A\n margin would have to be declared on the group's `:host`, and document-tree\n rules beat host styles — so a consumer's `* { margin: 0 }` reset (Starlight,\n Tailwind preflight, any normalise) silently collapsed the cards flush\n together. A height-capped menu nests the groups inside\n `.md-menu__scroll-shadow`, so that container repeats the gap below. */\n gap: var(--md-menu-group-gap, 4px);\n padding: 0;\n filter:\n drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15))\n drop-shadow(0 2px 6px rgba(0, 0, 0, 0.1));\n}\n\n/* The gap needs a flex container, and flex items shrink by default — in a short\n viewport that squashed each group card instead of overflowing, and because the\n cards clip (`overflow: hidden`) their rows were cut off rather than scrolled\n to. Pin the cards to their natural height so the viewport scrolls instead. */\n:host(.md-menu--grouped.md-menu--gap) .md-menu__surface ::slotted(md-menu-item-group),\n:host(.md-menu--grouped.md-menu--gap) .md-menu__scroll-shadow ::slotted(md-menu-item-group) {\n flex-shrink: 0;\n}\n\n/* When a height cap nests the groups inside the scroll viewport, that viewport\n is their flex parent — repeat the gap there so it survives the wrapper. */\n:host(.md-menu--grouped.md-menu--gap) .md-menu__scroll-shadow {\n display: flex;\n flex-direction: column;\n row-gap: var(--md-menu-group-gap, 4px);\n}\n\n/* --- Baseline: gap as spacing only --- */\n:host(.md-menu--sectioned.md-menu--baseline) .md-menu__surface ::slotted([gap]) {\n margin-bottom: var(--md-menu-section-gap, 2px);\n}\n\n/* ==========================================================\n 7. EMPTY STATE\n ========================================================== */\n.md-menu__empty {\n display: none;\n padding: var(--md-sys-spacing-inset-md, 12px) var(--md-sys-spacing-inset-lg, 16px);\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: var(--md-sys-typescale-body-medium-size, 14px);\n line-height: var(--md-sys-typescale-body-medium-line-height, 20px);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n text-align: center;\n}\n\n:host(.md-menu--empty) .md-menu__empty {\n display: block;\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Method, Watch, Listen } from '@stencil/core';\nimport { MenuElement, VirtualMenuProvider } from '../../utils/types';\n\nconst CLOSE_ANIMATION_MS = 150;\nconst TYPEAHEAD_TIMEOUT_MS = 500;\n/** Gap kept between the menu surface and every viewport edge when clamping. */\nconst VIEWPORT_MARGIN = 8;\n/** MD3 \"compact\" window-class breakpoint — below this `responsive` goes full-width. */\nconst COMPACT_BREAKPOINT = 600;\n/** Anchor roles for which `aria-expanded` is a valid, announced state. A roleless\n * anchor (e.g. a md-text-field trigger host) can't carry it — see updateAnchorAria. */\nconst EXPANDABLE_ANCHOR_ROLES = new Set([\n 'button', 'combobox', 'link', 'menuitem', 'tab', 'treeitem', 'checkbox', 'gridcell', 'row', 'rowheader', 'columnheader',\n]);\n/** Native tags whose IMPLICIT role supports aria-expanded (used when the anchor\n * sets no explicit `role` — a custom element like md-text-field is roleless). */\nconst NATIVE_EXPANDABLE_TAGS = new Set(['BUTTON', 'SUMMARY']);\n\nlet menuIdCounter = 0;\n\n@Component({ tag: 'md-menu', styleUrl: 'md-menu.css', shadow: true })\nexport class MdMenu {\n @Element() el!: HTMLElement;\n\n /** Whether the menu is open. */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n /** ID of the anchor element to position relative to. */\n @Prop() anchor: string = '';\n /** Position of the menu relative to the anchor. */\n @Prop({ reflect: true }) placement: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end' = 'bottom-start';\n /** Skip open/close animation. */\n @Prop() quick: boolean = false;\n /**\n * Visual variant.\n * - 'baseline': MD3 baseline menu (square corners, surface container)\n * - 'standard': M3 Expressive vertical menu (rounded, surface-based colors)\n * - 'vibrant': M3 Expressive vertical menu (rounded, tertiary-based colors)\n */\n @Prop({ reflect: true }) variant: 'baseline' | 'standard' | 'vibrant' = 'baseline';\n /** Layout style for vertical menus. 'standard' is flat, 'grouped' uses visual section separators. */\n @Prop({ reflect: true }) layout: 'standard' | 'grouped' = 'standard';\n /** Use gap separators instead of dividers between groups (vertical menu only). */\n @Prop({ attribute: 'use-gap', reflect: true }) useGap: boolean = false;\n /** Message shown when all menu items are hidden (e.g. no filter results). Empty string disables. */\n @Prop({ attribute: 'empty-text' }) emptyText: string = '';\n /** When true, the menu surface min-width matches the anchor element's width. The menu still grows wider if items need more space. */\n @Prop({ attribute: 'match-anchor-width', reflect: true }) matchAnchorWidth: boolean = false;\n /**\n * Adapt to compact viewports. The menu is *always* clamped within the\n * viewport (it never overflows the screen and pins to the edges with a\n * margin). When `responsive` is set, on viewports at or below the compact\n * breakpoint (600px) the menu additionally expands to near-full-width\n * below the trigger for comfortable touch use.\n */\n @Prop({ reflect: true }) responsive: boolean = false;\n /**\n * When set, the menu does NOT auto-dismiss in response to interaction\n * elsewhere on the page. By default a menu closes when:\n * 1. The user clicks outside the menu and its anchor.\n * 2. Another non-persistent menu opens (single-open coordination —\n * opening menu B closes menu A so two top-level menus never\n * overlap each other on screen).\n *\n * `persistent` opts out of both auto-dismiss paths. The menu then only\n * closes via `close()`, the anchor's toggle, item activation, or\n * Escape. Useful for modal-style pickers, multi-step menus, and any\n * context where the consumer manages dismissal explicitly.\n *\n * Submenus (an `<md-menu>` rendered inside a parent menu's `submenu`\n * slot) are never affected by sibling-menu dismissal even without this\n * flag — ancestors and descendants are always preserved.\n */\n @Prop({ reflect: true }) persistent: boolean = false;\n /**\n * When false, opening the menu initializes roving tabindex without moving\n * focus to the first item. The consumer handles focus (e.g. docked pickers\n * that scroll to the selected option). `show({ autoFocus: false })` still\n * takes precedence for a single open.\n */\n @Prop({ attribute: 'auto-focus', reflect: true }) autoFocus: boolean = true;\n\n /**\n * Cap the menu surface block-size. When the items exceed it the list\n * scrolls vertically inside a plain scroll viewport. A number is treated\n * as pixels; any CSS length is passed through (e.g. `'50vh'`). Ignored\n * when the menu has submenus — their flyouts must not be clipped by an\n * overflow container.\n */\n @Prop({ attribute: 'max-height' }) maxHeight?: number | string;\n\n /**\n * Fires when the menu opens. Scoped to the menu element: `bubbles: false`\n * stops it climbing the light-DOM tree, and `composed: false` stops it\n * escaping the shadow root of a host that embeds this menu (md-select,\n * md-multi-select, md-date-picker …). Without `composed: false` a\n * `composed` event still surfaces at the embedding host as an\n * `AT_TARGET` event — so a consumer's `mdOpen` listener on the wrapper\n * would fire for both the wrapper's own event and this inner one\n * (duplicate open/close). Wrappers listen via `onMdOpen` on the menu\n * element itself, which still fires regardless.\n */\n @Event({ bubbles: false, composed: false }) mdOpen: EventEmitter<void>;\n /** Fires when the menu closes. Scoped like `mdOpen` — see its note. */\n @Event({ bubbles: false, composed: false }) mdClose: EventEmitter<void>;\n\n @State() private closing = false;\n @State() private sectioned = false;\n @State() private empty = false;\n /** True when the menu contains submenus — they fly out and must not be\n * clipped, so the surface keeps `overflow: visible` instead of scrolling. */\n @State() private hasSubmenu = false;\n\n private focusedIndex = -1;\n /**\n * Monotonic token for virtualized keyboard nav. `focusVirtual` is async (it\n * awaits `ensureVisible` to scroll the target row into the window). Under fast\n * ArrowUp/Down key-repeat the calls overlap; without this guard a superseded\n * call would resolve *after* a newer one and re-stamp `data-md-focused` on its\n * stale index — leaving a lingering focus state-layer on whatever row now sits\n * in that slot (the \"second item background flickers\" bug). Each call captures\n * the token and bails if a newer call has since incremented it.\n */\n private navSeq = 0;\n /**\n * Filtered index of the row that currently shows the visible focus ring\n * (`data-md-focused`) in provider/virtual mode, or -1 for none. The ring is\n * removed only by the *winning* `focusVirtual` call, just before it stamps the\n * new row — never synchronously up-front. That keeps the ring on a real row\n * across the whole ArrowUp/Down autorepeat burst instead of blinking off for\n * the frames between a press and its async `ensureVisible` settling.\n */\n private ringedIndex = -1;\n private closeTimer?: ReturnType<typeof setTimeout>;\n private skipAutoFocus = false;\n private menuId = `md-menu-${++menuIdCounter}`;\n private typeaheadBuffer = '';\n private typeaheadTimer?: ReturnType<typeof setTimeout>;\n private itemObserver?: MutationObserver;\n /**\n * Tracks whether the most recent interaction was via keyboard. Used to\n * decide if the initial focus ring should show when the menu opens: a\n * mouse-opened menu auto-focuses the first item (so arrow keys work)\n * but stays ring-less until the user actually uses the keyboard.\n */\n private keyboardModality = false;\n private openedViaKeyboard = false;\n\n /**\n * When set, the menu's keyboard navigation / typeahead / focus run against a\n * *virtualized* data model instead of `querySelectorAll('md-menu-item')` —\n * only the rows in the current scroll window exist in the DOM. Null = the\n * default DOM-driven behaviour (every other menu in the app). See\n * `setVirtualProvider`. In provider mode `focusedIndex` is a filtered row\n * index rather than an index into the live DOM items.\n */\n private provider?: VirtualMenuProvider;\n\n /**\n * In provider (virtualized `md-select`) mode the popup is a WAI-ARIA\n * combobox/listbox, not a menu. `listboxMode` flips the surface role to\n * `listbox` (reactive, so the role updates when a provider is registered) and\n * `comboboxEl` is the element that owns DOM focus (the select's search input):\n * keyboard nav moves `aria-activedescendant` on it instead of moving real\n * focus onto recycled virtual rows. `listboxLabel` names the listbox.\n */\n @State() private listboxMode = false;\n private comboboxEl?: HTMLElement;\n @Prop({ attribute: 'list-label' }) listLabel?: string;\n\n /**\n * Present the popup as a WAI-ARIA listbox (surface `role=\"presentation\"`,\n * anchor `aria-haspopup=\"listbox\"`) rather than a menu. `md-select` sets this\n * for both its virtual and non-virtual lists so the popup is a listbox of\n * options regardless of size. (The virtual path additionally registers a\n * provider, which adds the aria-activedescendant focus model.)\n */\n @Prop({ reflect: true }) listbox: boolean = false;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** True when the popup should expose listbox semantics (prop or provider). */\n private get asListbox(): boolean {\n return this.listbox || this.listboxMode;\n }\n\n /**\n * Register (or clear with `null`) the combobox element that holds focus while\n * a virtual provider drives the list. When set, keyboard navigation manages\n * `aria-activedescendant` on it rather than calling `.focus()` on options —\n * the canonical pattern for a listbox whose rows are virtualized/recycled.\n */\n @Method()\n async setComboboxElement(el: HTMLElement | null) {\n if (this.comboboxEl && this.comboboxEl !== el) {\n this.comboboxEl.removeAttribute('aria-activedescendant');\n }\n this.comboboxEl = el ?? undefined;\n }\n\n connectedCallback() {\n if (typeof document === 'undefined') return;\n document.addEventListener('keydown', this.trackKeyboardModality, true);\n document.addEventListener('pointerdown', this.trackPointerModality, true);\n }\n\n private trackKeyboardModality = () => { this.keyboardModality = true; };\n private trackPointerModality = () => { this.keyboardModality = false; };\n\n componentDidLoad() {\n if (this.open) {\n this.applyDepthZIndex();\n }\n // Run an initial scan so a menu that mounts already-empty\n // (e.g. SSR snapshot, or items hidden before first paint)\n // shows the empty-state on its first frame instead of after\n // the first slotchange.\n this.wireItemObserver();\n this.updateEmpty();\n // Propagate variant/use-gap to slotted groups on load. The initial\n // `slotchange` can fire before our handler is wired (so it's missed), which\n // left grouped+gap groups without their data-variant/data-use-gap\n // attributes — the group cards then have no background (transparent surface,\n // floating items). componentDidLoad runs once children are assigned, so this\n // is the reliable initial pass; handleSlotChange keeps it in sync after.\n this.propagateVariant();\n }\n\n @Watch('emptyText')\n onEmptyTextChange() {\n this.updateEmpty();\n }\n\n // Re-propagate to slotted groups/items when the visual variant or gap mode\n // changes at runtime (e.g. via Storybook controls) — reflect only updates the\n // host attribute, not the children the group-card CSS keys off.\n @Watch('variant')\n @Watch('useGap')\n onVariantChange() {\n this.propagateVariant();\n }\n\n /**\n * Register (or clear with `null`) a virtual provider. With a provider set,\n * keyboard nav, typeahead, and roving focus run against the data model so a\n * windowed list of millions of options behaves like a normal menu. Without\n * one the menu is unchanged.\n */\n @Method()\n async setVirtualProvider(provider: VirtualMenuProvider | null) {\n this.provider = provider ?? undefined;\n // Flip the surface to a listbox (reactive via @State) so the virtualized\n // select's popup is exposed as a WAI-ARIA listbox, not a menu.\n this.listboxMode = !!this.provider;\n }\n\n /**\n * The scrollable viewport element (the menu's `.md-menu__scroll-shadow`\n * scroll div), or null when the menu isn't capped/scrollable. A virtualized\n * host attaches its scroll listener and reads `scrollTop`/`clientHeight`\n * from this.\n */\n @Method()\n async getScrollViewport(): Promise<HTMLElement | null> {\n return (\n (this.el.shadowRoot?.querySelector('.md-menu__scroll-shadow') as HTMLElement | null) ??\n null\n );\n }\n\n /** Opens the menu programmatically. Pass `{ autoFocus: false }` to keep focus on the caller (e.g. a text field). */\n @Method()\n async show(opts?: { autoFocus?: boolean }) {\n clearTimeout(this.closeTimer);\n this.closing = false;\n // Top-level menus always (re)open from a clean state. This also covers\n // the case where a prior close was interrupted — e.g. clicking the\n // trigger fires the anchor's show() which cancels the close timer, so\n // `open` never flips to false and the close-path reset never runs.\n // Submenus (no anchor) are skipped so live drill-down isn't disturbed.\n if (this.anchor) this.collapseSubmenus();\n this.skipAutoFocus = opts?.autoFocus === false;\n this.open = true;\n this.applyDepthZIndex();\n }\n\n /**\n * Recompute the menu's position against its anchor. md-menu already reacts to\n * scroll/resize, but not to the anchor MOVING because sibling content reflowed\n * (e.g. a multi-select whose button trigger shifts as chips are added beside\n * it). Call this after such a reflow to keep the popup glued to the anchor.\n */\n @Method()\n async reposition() {\n if (this.open) this.positionMenu();\n }\n\n /** Closes the menu programmatically. */\n @Method()\n async close() {\n if (!this.open || this.closing) return;\n\n if (this.quick) {\n this.open = false;\n return;\n }\n\n this.closing = true;\n this.closeTimer = setTimeout(() => {\n this.closing = false;\n this.open = false;\n }, CLOSE_ANIMATION_MS);\n }\n\n @Watch('open')\n onOpenChange(open: boolean) {\n if (open) {\n // Snapshot the modality that triggered this open; the actual focus\n // is deferred (scheduleFocus), so capture it now before it drifts.\n this.openedViaKeyboard = this.keyboardModality;\n this.dismissPeerMenus();\n this.applyDepthZIndex();\n requestAnimationFrame(() => this.positionMenu());\n this.mdOpen.emit();\n this.updateAnchorAria(true);\n if (this.anchor) {\n requestAnimationFrame(() => {\n document.addEventListener('click', this.handleOutsideClick);\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n });\n window.addEventListener('scroll', this.handleScroll, true);\n window.addEventListener('resize', this.handleScroll);\n this.observeSurfaceResize();\n }\n if (this.skipAutoFocus || !this.autoFocus) {\n this.scheduleFocus(() => this.initRovingTabindex());\n } else {\n // Always move focus to the first item so it leaves the trigger\n // (a mouse-clicked trigger must not keep its keyboard ring). The\n // ring on the item itself is shown only for keyboard opens — see\n // focusFirstItem(): mouse opens focus the item ring-less, and the\n // ring appears once the user navigates with the keyboard.\n this.scheduleFocus(() => this.focusFirstItem());\n }\n this.skipAutoFocus = false;\n } else {\n this.mdClose.emit();\n this.focusedIndex = -1;\n this.updateAnchorAria(false);\n this.resetRovingTabindex();\n this.collapseSubmenus();\n if (this.anchor) {\n document.removeEventListener('click', this.handleOutsideClick);\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n window.removeEventListener('scroll', this.handleScroll, true);\n window.removeEventListener('resize', this.handleScroll);\n }\n this.unobserveSurfaceResize();\n }\n }\n\n /** Reposition when the open surface's own size changes — e.g. an\n * autocomplete's list shrinking as the user types. A top-flipped menu\n * positioned for the taller list would otherwise keep its stale `top`\n * and float detached above the anchor. */\n private surfaceRO?: ResizeObserver;\n private lastSurfaceSize = '';\n\n private observeSurfaceResize() {\n if (typeof ResizeObserver === 'undefined') return;\n const surface = this.el.shadowRoot?.querySelector('.md-menu__surface');\n if (!surface) return;\n this.lastSurfaceSize = '';\n this.surfaceRO = new ResizeObserver((entries) => {\n if (!this.open) return;\n const r = entries[entries.length - 1]?.contentRect;\n if (!r) return;\n // Guard against feedback loops: only reposition on a REAL size change\n // (positionMenu itself tweaks min-width, which would re-fire once).\n const size = `${Math.round(r.width)}x${Math.round(r.height)}`;\n if (size === this.lastSurfaceSize) return;\n this.lastSurfaceSize = size;\n this.positionMenu();\n });\n this.surfaceRO.observe(surface);\n }\n\n private unobserveSurfaceResize() {\n this.surfaceRO?.disconnect();\n this.surfaceRO = undefined;\n }\n\n @Listen('focusin')\n handleFocusIn(e: FocusEvent) {\n if (!this.open) return;\n const target = e.target as HTMLElement;\n\n if (this.provider) {\n // Map a pointer-focused windowed item back to its filtered index via the\n // `data-vindex` the host stamps on each rendered row.\n const item = target.closest('md-menu-item') as HTMLElement | null;\n const attr = item?.getAttribute('data-vindex');\n if (item && attr != null) {\n const index = parseInt(attr, 10);\n if (!isNaN(index) && index !== this.focusedIndex) {\n const prev =\n this.focusedIndex >= 0 ? this.provider.domItemForIndex(this.focusedIndex) : null;\n prev?.setAttribute('tabindex', '-1');\n this.focusedIndex = index;\n item.setAttribute('tabindex', '0');\n // Pointer focus is ring-less; drop any deferred keyboard ring still\n // seated on a different row so it can't linger after a hover/click.\n if (this.ringedIndex >= 0 && this.ringedIndex !== index) {\n const ringed = this.provider.domItemForIndex(this.ringedIndex);\n ringed?.removeAttribute('data-md-focused');\n }\n this.ringedIndex = -1;\n }\n }\n return;\n }\n\n const items = this.getMenuItems();\n const index = items.indexOf(target);\n if (index >= 0 && index !== this.focusedIndex) {\n if (this.focusedIndex >= 0 && this.focusedIndex < items.length) {\n items[this.focusedIndex].setAttribute('tabindex', '-1');\n }\n this.focusedIndex = index;\n target.setAttribute('tabindex', '0');\n }\n }\n\n @Listen('keydown')\n handleKeyDown(e: KeyboardEvent) {\n if (!this.open) return;\n\n const target = e.target as HTMLElement;\n if (target && target.closest('md-menu') !== this.el) return;\n\n if (this.provider) {\n this.handleKeyDownVirtual(e);\n return;\n }\n\n const items = this.getMenuItems();\n if (!items.length) return;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this.focusItem(items, this.focusedIndex + 1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.focusItem(items, this.focusedIndex - 1);\n break;\n case 'Home':\n e.preventDefault();\n this.focusItem(items, 0);\n break;\n case 'End':\n e.preventDefault();\n this.focusItem(items, items.length - 1);\n break;\n case 'Escape':\n e.preventDefault();\n this.close();\n this.restoreFocusToAnchor();\n break;\n case 'Tab':\n e.stopPropagation();\n this.closeEntireMenuTree();\n // Return focus to the trigger (like Escape) so it doesn't fall to <body>\n // when the focused option/search input unmounts; the user tabs onward from\n // there.\n this.restoreFocusToAnchor();\n break;\n default:\n if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey) {\n this.handleTypeahead(e.key, items);\n }\n break;\n }\n }\n\n // ── Virtualized (provider) navigation ────────────────────\n // Mirrors the DOM-driven path but operates on filtered row indices in the\n // provider's data model, scrolling the target row into the rendered window\n // (ensureVisible) before moving real focus to it. `focusedIndex` is a\n // filtered index here, not a DOM-items index.\n\n private handleKeyDownVirtual(e: KeyboardEvent) {\n const p = this.provider!;\n const count = p.count();\n // Keystrokes inside a header search field (the filterable select) type into\n // the input; only navigation keys are intercepted for the list.\n const fromInput = (e.target as HTMLElement)?.tagName === 'INPUT';\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(this.focusedIndex, 1, count));\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(this.focusedIndex, -1, count));\n break;\n case 'Home':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(-1, 1, count));\n break;\n case 'End':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(count, -1, count));\n break;\n case 'Enter':\n // In combobox mode the input keeps focus, so the active option never\n // receives the keystroke itself — activate it here. (In roving-focus\n // mode the focused option handles its own Enter, so don't double-fire.)\n if (this.comboboxEl && this.focusedIndex >= 0) {\n e.preventDefault();\n this.provider!.domItemForIndex(this.focusedIndex)?.click();\n }\n break;\n case 'Escape':\n e.preventDefault();\n this.close();\n this.restoreFocusToAnchor();\n break;\n case 'Tab':\n e.stopPropagation();\n this.closeEntireMenuTree();\n // Return focus to the trigger (like Escape) so it doesn't fall to <body>\n // when the focused option/search input unmounts; the user tabs onward from\n // there.\n this.restoreFocusToAnchor();\n break;\n default:\n if (\n !fromInput &&\n e.key.length === 1 &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.altKey &&\n !e.shiftKey\n ) {\n this.handleTypeaheadVirtual(e.key);\n }\n break;\n }\n }\n\n /**\n * Next non-disabled filtered index from `from` in `dir` (±1), wrapping like\n * the DOM path. Returns -1 only when every row is disabled / the list empty.\n */\n private nextEnabled(from: number, dir: number, count: number): number {\n if (count <= 0) return -1;\n let idx = from;\n for (let i = 0; i < count; i++) {\n idx += dir;\n if (idx < 0) idx = count - 1;\n else if (idx >= count) idx = 0;\n if (!this.provider!.isDisabledAt(idx)) return idx;\n }\n return from >= 0 && from < count ? from : -1;\n }\n\n private async focusVirtual(index: number, showRing = true) {\n if (index < 0) return;\n const p = this.provider!;\n const seq = ++this.navSeq;\n // Advance the logical active index immediately, but do NOT strip the visible\n // ring from the old row up-front: `ensureVisible` is async, and under\n // ArrowUp/Down autorepeat each press supersedes the last. Removing the ring\n // here left ~1-in-4 frames with no ring on any row (the held-key flicker).\n // The winning call below swaps the ring atomically once its row is windowed.\n this.focusedIndex = index;\n await p.ensureVisible(index);\n // A newer keystroke superseded this one while we awaited the scroll. Bail so\n // we don't re-stamp the focus ring / move focus to this now-stale row — the\n // latest call owns those. The current ring stays put (we never removed it).\n if (seq !== this.navSeq) return;\n const node = p.domItemForIndex(index);\n if (!node) return;\n // Atomic swap: clear the previously ringed row, then ring/seat the new one,\n // so the ring is never absent between the two.\n if (this.ringedIndex >= 0 && this.ringedIndex !== index) {\n const old = p.domItemForIndex(this.ringedIndex);\n old?.setAttribute('tabindex', '-1');\n old?.removeAttribute('data-md-focused');\n }\n if (showRing) {\n node.setAttribute('data-md-focused', '');\n this.ringedIndex = index;\n } else {\n node.removeAttribute('data-md-focused');\n this.ringedIndex = -1;\n }\n if (this.comboboxEl) {\n // WAI-ARIA combobox/listbox: focus stays on the combobox (the select's\n // search input); the active option is conveyed via aria-activedescendant.\n // This is the robust model for a virtualized listbox — no real focus is\n // moved onto rows that scroll out of the window and get recycled. The\n // option keeps tabindex -1 (only the combobox is in the tab order).\n node.id ||= `${this.menuId}-opt-${index}`;\n if (node.id) this.comboboxEl.setAttribute('aria-activedescendant', node.id);\n } else {\n // No combobox (e.g. a non-filterable virtual list): fall back to the\n // standalone-listbox roving-focus model.\n node.setAttribute('tabindex', '0');\n // ensureVisible already revealed the row; preventScroll stops the browser's\n // own scroll-into-view from fighting the (anchor-driven) virtual window.\n node.focus({ preventScroll: true });\n }\n }\n\n private handleTypeaheadVirtual(char: string) {\n clearTimeout(this.typeaheadTimer);\n this.typeaheadBuffer += char.toLowerCase();\n this.typeaheadTimer = setTimeout(() => {\n this.typeaheadBuffer = '';\n }, TYPEAHEAD_TIMEOUT_MS);\n\n const from =\n this.typeaheadBuffer.length === 1 ? this.focusedIndex + 1 : this.focusedIndex;\n const idx = this.provider!.findPrefix(this.typeaheadBuffer, from < 0 ? 0 : from);\n if (idx >= 0) this.focusVirtual(idx);\n }\n\n private getMenuItems(): HTMLElement[] {\n const all = Array.from(\n this.el.querySelectorAll('md-menu-item, md-sub-menu-item')\n ) as HTMLElement[];\n return all.filter(item => item.closest('md-menu') === this.el);\n }\n\n private getItemLabel(item: HTMLElement): string {\n return (item as MenuElement).headline || item.textContent?.trim() || '';\n }\n\n private handleTypeahead(char: string, items: HTMLElement[]) {\n clearTimeout(this.typeaheadTimer);\n this.typeaheadBuffer += char.toLowerCase();\n this.typeaheadTimer = setTimeout(() => { this.typeaheadBuffer = ''; }, TYPEAHEAD_TIMEOUT_MS);\n\n const startIndex = this.typeaheadBuffer.length === 1\n ? this.focusedIndex + 1\n : this.focusedIndex;\n\n for (let i = 0; i < items.length; i++) {\n const idx = (startIndex + i) % items.length;\n const label = this.getItemLabel(items[idx]).toLowerCase();\n if (label.startsWith(this.typeaheadBuffer)) {\n this.focusItem(items, idx);\n return;\n }\n }\n }\n\n private focusItem(items: HTMLElement[], index: number, showRing = true) {\n if (items.length === 0) return;\n if (index < 0) index = items.length - 1;\n if (index >= items.length) index = 0;\n\n if (this.focusedIndex >= 0 && this.focusedIndex < items.length) {\n items[this.focusedIndex].setAttribute('tabindex', '-1');\n items[this.focusedIndex].removeAttribute('data-md-focused');\n }\n\n this.focusedIndex = index;\n items[index].setAttribute('tabindex', '0');\n // `data-md-focused` is the visible focus ring. Keyboard navigation always\n // shows it; a mouse-opened menu focuses without it (see focusFirstItem)\n // so the ring only appears once the user reaches for the keyboard.\n if (showRing) {\n items[index].setAttribute('data-md-focused', '');\n } else {\n items[index].removeAttribute('data-md-focused');\n }\n items[index].focus();\n }\n\n private initRovingTabindex() {\n if (this.provider) {\n // No focus move (skipAutoFocus path, e.g. a combobox whose search input\n // keeps focus). Seat the active index *before* the first row (-1) so the\n // first ArrowDown lands on the first item — seating it on row 0 instead\n // made the first ArrowDown skip to the second item. Nothing is active /\n // ringed until the user actually arrows.\n this.focusedIndex = -1;\n return;\n }\n const items = this.getMenuItems();\n items.forEach((item, i) => {\n item.setAttribute('tabindex', i === 0 ? '0' : '-1');\n });\n this.focusedIndex = 0;\n }\n\n private resetRovingTabindex() {\n if (this.provider) {\n const node =\n this.focusedIndex >= 0 ? this.provider.domItemForIndex(this.focusedIndex) : null;\n node?.setAttribute('tabindex', '-1');\n node?.removeAttribute('data-md-focused');\n // Also clear any deferred ring still seated on a different row.\n if (this.ringedIndex >= 0 && this.ringedIndex !== this.focusedIndex) {\n const ringed = this.provider.domItemForIndex(this.ringedIndex);\n ringed?.setAttribute('tabindex', '-1');\n ringed?.removeAttribute('data-md-focused');\n }\n this.ringedIndex = -1;\n // Drop the active-option pointer on the combobox so a screen reader\n // doesn't announce a stale active row after the listbox closes.\n this.comboboxEl?.removeAttribute('aria-activedescendant');\n return;\n }\n const items = this.getMenuItems();\n items.forEach(item => {\n item.setAttribute('tabindex', '-1');\n item.removeAttribute('data-md-focused');\n });\n }\n\n /**\n * Reset the entire subtree when this menu closes: collapse every\n * descendant submenu and clear lingering focus markers / tabindex at\n * all depths. Without this, reopening the menu restores whichever\n * submenu was open and whichever item was focused last time.\n */\n private collapseSubmenus() {\n const subItems = Array.from(\n this.el.querySelectorAll('md-sub-menu-item')\n ) as Array<HTMLElement & { collapse?: () => Promise<void> }>;\n subItems.forEach(item => item.collapse?.());\n\n const allItems = Array.from(\n this.el.querySelectorAll('md-menu-item, md-sub-menu-item')\n ) as HTMLElement[];\n allItems.forEach(item => {\n item.removeAttribute('data-md-focused');\n item.setAttribute('tabindex', '-1');\n });\n }\n\n private scheduleFocus(fn: () => void) {\n setTimeout(() => requestAnimationFrame(() => fn()), 0);\n }\n\n private focusFirstItem(retries = 3) {\n if (this.provider) {\n const count = this.provider.count();\n if (count > 0) {\n // Ring only on keyboard opens, matching the DOM path.\n this.focusVirtual(this.nextEnabled(-1, 1, count), this.openedViaKeyboard);\n } else if (retries > 0) {\n this.scheduleFocus(() => this.focusFirstItem(retries - 1));\n }\n return;\n }\n const items = this.getMenuItems();\n if (items.length) {\n // Only show the ring on auto-focus when the menu was opened by keyboard.\n this.focusItem(items, 0, this.openedViaKeyboard);\n } else if (retries > 0) {\n this.scheduleFocus(() => this.focusFirstItem(retries - 1));\n }\n }\n\n /**\n * Resolve the anchor element by id. Looks within the menu's own root node\n * first — so a menu rendered inside another component's shadow root (e.g.\n * md-select) finds a sibling trigger that `document.getElementById` can't\n * see across the shadow boundary — then falls back to the document for\n * light-DOM anchors.\n */\n private getAnchorEl(id: string = this.anchor): HTMLElement | null {\n if (!id) return null;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n return (\n (root.getElementById?.(id) as HTMLElement | null) ??\n document.getElementById(id)\n );\n }\n\n private updateAnchorAria(open: boolean) {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n if (!anchorEl) return;\n\n // aria-expanded is only VALID on roles that support it. Some anchors can't\n // carry it — e.g. a md-text-field trigger whose HOST is roleless (its textbox\n // role sits on the inner input): a screen reader ignores it there and axe\n // flags aria-supported-attr. Gate it on the anchor's role; the popup stays\n // discoverable via aria-haspopup + focus moving into the menu, and role-bearing\n // triggers (a role=\"button\" opener) still get it.\n const anchorRole = anchorEl.getAttribute('role');\n const supportsExpanded =\n anchorRole !== null\n ? EXPANDABLE_ANCHOR_ROLES.has(anchorRole)\n : NATIVE_EXPANDABLE_TAGS.has(anchorEl.tagName) ||\n (anchorEl.tagName === 'A' && anchorEl.hasAttribute('href'));\n\n if (open) {\n anchorEl.setAttribute('aria-haspopup', this.asListbox ? 'listbox' : 'menu');\n // In listbox/provider mode the OWNER (md-select / md-multi-select) renders the\n // real role=\"listbox\" in ITS OWN shadow and points the trigger's aria-controls\n // at it (an in-scope IDREF). Don't clobber that with menuId, which identifies\n // this menu's role=\"presentation\" surface in a DIFFERENT shadow root (an\n // unresolvable cross-shadow reference).\n if (!this.asListbox) anchorEl.setAttribute('aria-controls', this.menuId);\n }\n if (supportsExpanded) anchorEl.setAttribute('aria-expanded', open ? 'true' : 'false');\n else anchorEl.removeAttribute('aria-expanded');\n }\n\n private applyDepthZIndex() {\n if (!this.anchor) return;\n this.el.style.zIndex = 'var(--md-sys-z-index-popup, 1000)';\n }\n\n private positionMenu() {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n if (!anchorEl) return;\n\n const anchorRect = anchorEl.getBoundingClientRect();\n const surface = this.el.shadowRoot?.querySelector('.md-menu__surface') as HTMLElement;\n if (!surface) return;\n\n const gap = 4;\n surface.style.minWidth = this.matchAnchorWidth ? `${anchorRect.width}px` : '';\n\n // Park at top-left with right/bottom cleared so stale inline styles\n // cannot shrink-to-fit the surface and corrupt the measurements.\n this.el.style.top = '0';\n this.el.style.left = '0';\n this.el.style.right = 'auto';\n this.el.style.bottom = 'auto';\n\n const menuW = surface.offsetWidth;\n let menuH = surface.offsetHeight;\n\n if (menuW === 0 || menuH === 0) {\n requestAnimationFrame(() => this.positionMenu());\n return;\n }\n\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const m = VIEWPORT_MARGIN;\n\n // Compact + responsive: drop the trigger-relative horizontal placement and\n // present a near-full-width sheet below (or above, if cramped) the anchor.\n // The CSS media query sizes the surface to `100vw - 2*margin`.\n if (this.responsive && vw <= COMPACT_BREAKPOINT) {\n const h = surface.offsetHeight;\n let top = anchorRect.bottom + gap;\n if (top + h + m > vh && anchorRect.top - gap - h >= m) {\n top = anchorRect.top - gap - h;\n surface.style.transformOrigin = 'bottom left';\n } else {\n surface.style.transformOrigin = 'top left';\n }\n top = Math.max(m, Math.min(top, vh - h - m));\n this.el.style.top = `${top}px`;\n this.el.style.left = `${m}px`;\n return;\n }\n\n let vertical: 'bottom' | 'top' = this.placement.startsWith('bottom') ? 'bottom' : 'top';\n let horizontal: 'start' | 'end' = this.placement.endsWith('start') ? 'start' : 'end';\n\n const spaceBelow = vh - anchorRect.bottom - gap - m;\n const spaceAbove = anchorRect.top - gap - m;\n\n // Keep the requested vertical side if the menu fits; otherwise flip to the side\n // that fits. A CAPPED (scrollable) menu that fits neither side picks the side\n // with MORE room and shrinks its scroll region to it (below), so it scrolls\n // instead of being clamped over the anchor.\n if (vertical === 'bottom' && menuH > spaceBelow) {\n if (menuH <= spaceAbove || (this.scrollCapped && spaceAbove > spaceBelow)) vertical = 'top';\n } else if (vertical === 'top' && menuH > spaceAbove) {\n if (menuH <= spaceBelow || (this.scrollCapped && spaceBelow > spaceAbove)) vertical = 'bottom';\n }\n\n if (horizontal === 'start' && anchorRect.left + menuW > vw) {\n if (anchorRect.right - menuW >= 0) horizontal = 'end';\n } else if (horizontal === 'end' && anchorRect.right - menuW < 0) {\n if (anchorRect.left + menuW <= vw) horizontal = 'start';\n }\n\n // Cap a scrollable menu's height to the chosen side's available space so it\n // scrolls instead of overflowing or being clamped across the anchor. Only\n // capped menus have the scroll viewport that makes this safe.\n if (this.scrollCapped) {\n const avail = vertical === 'bottom' ? spaceBelow : spaceAbove;\n const scrollEl = surface.querySelector('.md-menu__scroll-shadow') as HTMLElement | null;\n const chrome = surface.offsetHeight - (scrollEl?.offsetHeight ?? 0); // header + padding\n this.el.style.setProperty('--md-menu-avail-block', `${Math.max(48, avail - chrome)}px`);\n menuH = surface.offsetHeight; // re-measure after the cap reflows the surface\n } else {\n this.el.style.removeProperty('--md-menu-avail-block');\n }\n\n const vOrigin = vertical === 'bottom' ? 'top' : 'bottom';\n const hOrigin = horizontal === 'start' ? 'left' : 'right';\n surface.style.transformOrigin = `${vOrigin} ${hOrigin}`;\n\n const top = vertical === 'bottom'\n ? anchorRect.bottom + gap\n : anchorRect.top - gap - menuH;\n\n const left = horizontal === 'start'\n ? anchorRect.left\n : anchorRect.right - menuW;\n\n // Viewport clamp (always on): keep the surface fully on-screen with a\n // margin so it never bleeds off any edge. Width is capped in CSS, so a\n // clamp to `margin` here simply pins an oversized menu to the edge.\n const clampedLeft = Math.max(m, Math.min(left, vw - menuW - m));\n const clampedTop = Math.max(m, Math.min(top, vh - menuH - m));\n\n this.el.style.top = `${clampedTop}px`;\n this.el.style.left = `${clampedLeft}px`;\n }\n\n private restoreFocusToAnchor() {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n anchorEl?.focus();\n }\n\n private closeEntireMenuTree() {\n let rootMenu: MenuElement = this.el as unknown as MenuElement;\n let current: HTMLElement | null = this.el;\n while (current) {\n const parentMenu = current.parentElement?.closest('md-menu') as MenuElement | null;\n if (parentMenu) {\n rootMenu = parentMenu;\n current = parentMenu;\n } else {\n break;\n }\n }\n\n const allItems = rootMenu.querySelectorAll('md-menu-item, md-sub-menu-item');\n allItems.forEach(item => item.setAttribute('tabindex', '-1'));\n\n if (rootMenu.close) rootMenu.close();\n\n const anchorId = rootMenu.anchor;\n if (anchorId) {\n const root = (rootMenu as unknown as HTMLElement).getRootNode() as\n | Document\n | ShadowRoot;\n const anchorEl =\n (root.getElementById?.(anchorId) as HTMLElement | null) ??\n document.getElementById(anchorId);\n anchorEl?.focus();\n }\n }\n\n private handleOutsideClick = (e: MouseEvent) => {\n if (this.persistent) return;\n const path = e.composedPath();\n if (!path.includes(this.el)) {\n this.close();\n }\n };\n\n /**\n * Single-open coordination. When this menu opens, dismiss every other\n * non-persistent top-level menu currently open on the page so two\n * unrelated menus never overlap. Ancestors and descendants of `this`\n * are deliberately preserved — submenus must not close their parent\n * menu when they open, and parent menus must not nuke an in-flight\n * submenu the user is interacting with.\n */\n private dismissPeerMenus() {\n if (this.persistent) return;\n if (typeof document === 'undefined') return;\n const all = Array.from(document.querySelectorAll('md-menu')) as MenuElement[];\n for (const peer of all) {\n if (peer === this.el) continue;\n if (!peer.open) continue;\n if (peer.persistent) continue;\n if (peer.contains(this.el)) continue;\n if (this.el.contains(peer)) continue;\n peer.close();\n }\n }\n\n private handleDocumentKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && this.open) {\n this.close();\n this.restoreFocusToAnchor();\n }\n };\n\n private handleScroll = () => {\n if (this.open && !this.closing) {\n this.positionMenu();\n }\n };\n\n private handleSlotChange = () => {\n this.updateSections();\n this.propagateVariant();\n this.wireItemObserver();\n this.updateEmpty();\n this.hasSubmenu = !!this.el.querySelector('md-sub-menu-item');\n };\n\n /**\n * Returns true when the element is *explicitly* hidden — either the HTML\n * `hidden` attribute is set, or `style=\"display: none\"` is applied\n * inline. We deliberately avoid `getComputedStyle()` here because\n * `display: none` from a stylesheet rule on `<md-menu-item>` would\n * report the element as hidden during the brief window before the\n * loader finishes registering the custom element, which would flash\n * the empty-state on every menu open.\n */\n private isHidden(el: HTMLElement): boolean {\n if (el.hasAttribute('hidden')) return true;\n if (el.style.display === 'none') return true;\n return false;\n }\n\n private hasVisibleItem(el: HTMLElement): boolean {\n if (this.isHidden(el)) return false;\n const tag = el.tagName.toLowerCase();\n if (tag === 'md-menu-item' || tag === 'md-sub-menu-item') return true;\n if (tag === 'md-menu-item-group') {\n return Array.from(el.children).some((child) =>\n this.hasVisibleItem(child as HTMLElement),\n );\n }\n return false;\n }\n\n private updateEmpty() {\n if (!this.emptyText) {\n // No empty-text configured — the empty UI is opt-in; skip the\n // class entirely so the surface stays its natural collapsed\n // height when an unconfigured menu has no items.\n this.empty = false;\n return;\n }\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n this.empty = !children.some((child) => this.hasVisibleItem(child));\n }\n\n private wireItemObserver() {\n // The empty-state has to react to consumer code toggling\n // `style=\"display: none\"` / `hidden` on items (the canonical\n // type-to-filter pattern). `slotchange` fires when *children* of\n // the menu are added/removed, but NOT when their attributes\n // change in place — so a MutationObserver covers that gap.\n this.itemObserver?.disconnect();\n // Stencil's jsdom-lite test environment doesn't ship a\n // MutationObserver. Skip the observer there — the slotchange-\n // driven path still keeps the empty-state in sync, and the\n // dynamic-attribute path is exercised by browser-only e2e tests.\n if (typeof MutationObserver === 'undefined') return;\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n if (children.length === 0) return;\n this.itemObserver = new MutationObserver(() => this.updateEmpty());\n for (const child of children) {\n this.itemObserver.observe(child, {\n attributes: true,\n attributeFilter: ['style', 'hidden'],\n subtree: true,\n });\n }\n }\n\n /**\n * The default (content) slot — NOT the named `header` slot, which renders\n * FIRST inside the surface (a virtualized select's pinned search field). A\n * plain `querySelector('slot')` grabs that header slot (empty for normal\n * menus), so every slot-scanning method must filter by name — otherwise\n * grouped+gap groups never receive data-variant/data-use-gap and lose their\n * card background (transparent surface → floating items). Built from\n * querySelectorAll (a simple selector Stencil's jsdom-lite mock supports)\n * rather than `slot:not([name])`, which the mock can't parse.\n */\n private getContentSlot(): HTMLSlotElement | null {\n const root = this.el.shadowRoot;\n if (!root) return null;\n const slots = Array.from(root.querySelectorAll('slot')) as HTMLSlotElement[];\n // Match on the `name` ATTRIBUTE, not the `.name` property — Stencil's\n // jsdom-lite mock doesn't reflect the attribute onto the property, so `.name`\n // is undefined there and would wrongly match the header slot first.\n return slots.find((s) => !s.getAttribute('name')) ?? null;\n }\n\n private propagateVariant() {\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n for (const child of children) {\n child.setAttribute('data-variant', this.variant);\n if (child.tagName.toLowerCase() === 'md-menu-item-group') {\n if (this.useGap) {\n child.setAttribute('data-use-gap', '');\n } else {\n child.removeAttribute('data-use-gap');\n }\n const nested = child.querySelectorAll('md-menu-item, md-sub-menu-item');\n for (const item of Array.from(nested)) {\n item.setAttribute('data-variant', this.variant);\n }\n }\n }\n }\n\n private updateSections() {\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n\n let foundGap = false;\n let afterGap = false;\n\n for (const child of children) {\n if (afterGap) {\n child.setAttribute('data-after-gap', '');\n afterGap = false;\n } else {\n child.removeAttribute('data-after-gap');\n }\n\n if (child.hasAttribute('gap')) {\n foundGap = true;\n afterGap = true;\n }\n }\n\n this.sectioned = foundGap;\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this.handleOutsideClick);\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('keydown', this.trackKeyboardModality, true);\n document.removeEventListener('pointerdown', this.trackPointerModality, true);\n window.removeEventListener('scroll', this.handleScroll, true);\n window.removeEventListener('resize', this.handleScroll);\n clearTimeout(this.closeTimer);\n clearTimeout(this.typeaheadTimer);\n this.itemObserver?.disconnect();\n this.itemObserver = undefined;\n this.unobserveSurfaceResize();\n this.updateAnchorAria(false);\n }\n\n /** Embedded flex menus (e.g. md-date-picker docked month/year lists). */\n private get inlineFill(): boolean {\n return this.el.classList.contains('md-menu--inline-fill');\n }\n\n /** Resolved `max-height` as a CSS length, or null when unset. */\n private get maxHeightValue(): string | null {\n if (this.maxHeight === undefined || this.maxHeight === null || this.maxHeight === '') {\n return null;\n }\n // A bare number — or a numeric string (attributes and `md-select`\n // forwarding both arrive as strings) — is treated as pixels; any other\n // CSS length (`'50vh'`, `'20rem'`, …) is passed through verbatim.\n const raw = String(this.maxHeight);\n return /^\\d+(\\.\\d+)?$/.test(raw) ? `${raw}px` : raw;\n }\n\n /** Every regular menu (not a submenu whose flyouts must not clip, not an inline-\n * fill embed) is bounded by the viewport and scrolls inside its scroll viewport\n * when it would overflow — with OR without an explicit max-height. This keeps a\n * pinned header and plain scrolling for every overflowing menu, not just capped\n * ones. */\n private get scrollCapped(): boolean {\n return !this.hasSubmenu && !this.inlineFill;\n }\n\n /** Inline-fill and every capped menu wrap their body in a scroll viewport. */\n private get useScrollViewport(): boolean {\n return this.inlineFill || this.scrollCapped;\n }\n\n private renderMenuBody() {\n return [\n <slot onSlotchange={this.handleSlotChange} />,\n this.emptyText ? (\n <span class=\"md-menu__empty\" part=\"empty-text\" role=\"status\">\n {this.emptyText}\n </span>\n ) : null,\n ];\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-menu': true,\n 'md-menu--open': this.open,\n 'md-menu--closing': this.closing,\n 'md-menu--quick': this.quick,\n [`md-menu--${this.variant}`]: true,\n [`md-menu--${this.layout}`]: this.variant !== 'baseline',\n 'md-menu--gap': this.useGap,\n 'md-menu--sectioned': this.sectioned,\n 'md-menu--empty': this.empty,\n 'md-menu--responsive': this.responsive,\n 'md-menu--has-submenu': this.hasSubmenu,\n 'md-menu--scroll': this.scrollCapped,\n }}\n aria-hidden={(!this.open || this.closing) ? 'true' : 'false'}\n // A closed menu stays in the DOM (opacity 0, never display:none, so the\n // open/close motion can play), which leaves focusable content — items, a\n // filterable select's search input — inside an aria-hidden subtree. That\n // is tab-reachable-but-invisible for keyboard users and fails axe\n // aria-hidden-focus (caught as a transient on story navigation, but the\n // closed steady state is just as affected). `inert` while hidden removes\n // the whole subtree from focus order and the a11y tree; it flips off in\n // the same render that clears aria-hidden, before any post-open focus.\n inert={!this.open || this.closing}\n >\n <div\n class=\"md-menu__surface\"\n part=\"surface\"\n // In provider/listbox mode the surface is just a container: it holds\n // the combobox (header slot) AND the listbox, so it must not itself be\n // a menu or a listbox. The host (md-select) renders the actual\n // role=\"listbox\" wrapper around the options in its own shadow root, so\n // aria-controls / aria-activedescendant IDREFs resolve.\n role={this.asListbox ? 'presentation' : 'menu'}\n id={this.menuId}\n aria-orientation={this.asListbox ? undefined : 'vertical'}\n aria-labelledby={this.asListbox ? undefined : this.anchor || undefined}\n >\n {/* Pinned header above the scroll area (e.g. a virtualized select's\n search field). Empty — and zero-cost — for every other menu. */}\n <slot name=\"header\" />\n {this.useScrollViewport ? (\n <div\n class=\"md-menu__scroll-shadow\"\n part=\"menu-viewport\"\n // Keyboard access to the scrolling option list (WCAG 2.1.1): the\n // active option's roving tabindex can sit on a PINNED HEADER item\n // (e.g. a select's \"Select all\") that lives outside this viewport,\n // leaving the scroll area with no focusable child. Make it focusable\n // — but ONLY in listbox mode. There the surface is role=\"presentation\"\n // (the owner renders the real listbox), so a focusable tabindex=\"0\"\n // viewport is harmless. In a plain role=\"menu\" the viewport would be a\n // role-less `div[tabindex]` OWNED by the menu, which axe flags as a\n // disallowed menu child (aria-required-children) — and a menu's own\n // menuitems (roving tabindex) already satisfy WCAG 2.1.1 without it.\n tabindex={this.asListbox ? '0' : undefined}\n // inline-fill is bounded by its flex parent; a capped menu is\n // bounded by max-height so the viewport scrolls within it. Clamp\n // to the viewport so an oversized cap can't run off-screen.\n style={\n this.inlineFill\n ? undefined // flexes to fill its parent; no fixed cap\n : {\n // Bound the scroll region to the smaller of any explicit\n // max-height, the space on the chosen side (--md-menu-avail-block,\n // set by positionMenu), and the viewport — so it scrolls\n // instead of overflowing, with or without max-height.\n maxBlockSize: this.maxHeightValue\n ? `min(${this.maxHeightValue}, var(--md-menu-avail-block, 100dvh), calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px)))`\n : `min(var(--md-menu-avail-block, 100dvh), calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px)))`,\n }\n }\n >\n {this.renderMenuBody()}\n </div>\n ) : (\n this.renderMenuBody()\n )}\n </div>\n </Host>\n );\n }\n}\n","/* ═══════════════════════════════════════════════════════════\n md-menu-item\n Material Design 3 — Menus\n https://m3.material.io/components/menus/specs\n\n CSS custom properties:\n --md-menu-item-height Item height (default 48px)\n --md-menu-item-padding-inline Horizontal padding (default 12px)\n --md-menu-item-gap Gap between elements (default 12px)\n --md-menu-item-icon-size Leading/trailing icon (default 24px,\n 20px in the standard/vibrant variants)\n --md-menu-item-check-size Selection check/radio glyph (default 20px)\n\n Heights and all three icon sizes taper with the global `data-density`\n scale; the custom properties above opt out of that curve entirely.\n\n Parts:\n state-layer, leading-icon, content, headline,\n supporting-text, badge, trailing\n\n Slots:\n leading-icon, trailing-icon, (default)\n ═══════════════════════════════════════════════════════════ */\n\n/* ==========================================================\n 1. HOST\n ========================================================== */\n:host {\n display: flex;\n align-items: center;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n user-select: none;\n /* Global density: each `data-density` rung (0…-4) trims 4px off the row.\n density-scale is 0 by default, so the 48px default is unchanged.\n See packages/tokens/src/tokens.css §10-12. */\n min-height: var(--md-menu-item-height, calc(48px + var(--md-sys-density-scale, 0) * 4px));\n /* Leading/trailing icon size — one lever for the wrapper box AND the slotted\n glyph so they can never drift apart. Tapers 1px per rung (24 → 20px at -4)\n with an 18px floor, matching md-list-item's icon convention. */\n --_icon-size: var(--md-menu-item-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n /* Selection check/radio glyph — 20dp per M3, same 1px/rung taper, 16px floor. */\n --_check-size: var(--md-menu-item-check-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n padding: 0 var(--md-menu-item-padding-inline, var(--md-sys-spacing-inset-md, 12px));\n gap: var(--md-menu-item-gap, var(--md-sys-spacing-gap-md, 12px));\n color: var(--md-sys-color-on-surface, #1C1B1F);\n box-sizing: border-box;\n -webkit-tap-highlight-color: transparent;\n outline: none;\n /* M3 motion — quick tonal/selection fades plus an expressive shape morph\n so the corner radii ease (rather than snap) on hover / active / select. */\n transition:\n background-color var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n color var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-radius var(--md-sys-motion-duration-medium2, 300ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n}\n\n/* ==========================================================\n 2. STATES\n ========================================================== */\n.md-menu-item__state-layer {\n position: absolute;\n inset: 0;\n background-color: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n pointer-events: none;\n /* No transition by default: only pointer hover/active eases in (rule below).\n Keyboard focus (data-md-focused / focus-visible) is deliberately left\n transition-less so the tint snaps fully on and off. During fast ArrowUp/Down\n the focused row is a freshly-windowed node that starts at opacity 0, so a\n fade-in would restart every press and PULSE the focused element; and a\n fade-out would TRAIL lit rows behind the moving focus. Both are flicker. */\n}\n\n/* Inside a gapped group card the state layer sits `padding` in from a ROUNDED\n edge, so square corners left a wider band at the card's corners than along\n its sides. Concentric radius = card radius − that inset. */\n:host-context(md-menu-item-group[data-use-gap]) .md-menu-item__state-layer {\n border-radius: calc(var(--md-menu-group-shape, 12px) - var(--md-sys-spacing-inset-xs, 4px));\n}\n\n:host(:hover) .md-menu-item__state-layer { opacity: 0.08; }\n:host(:active) .md-menu-item__state-layer { opacity: 0.12; }\n:host(:focus-visible) .md-menu-item__state-layer,\n:host([data-md-focused]) .md-menu-item__state-layer { opacity: 0.12; }\n\n/* Soft ease-in for pointer hover/active only — keyboard focus stays instant. */\n:host(:hover) .md-menu-item__state-layer,\n:host(:active) .md-menu-item__state-layer {\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host(:focus-visible),\n:host([data-md-focused]) {\n outline: 3px solid var(--md-sys-color-secondary, #625B71);\n outline-offset: -3px;\n}\n\n/* ==========================================================\n 3. SELECTED STATE\n ========================================================== */\n\n/* Baseline */\n:host(.md-menu-item--selected) {\n background-color: var(--md-sys-color-secondary-container, #E8DEF8);\n}\n\n/* Vertical Standard */\n:host([data-variant=\"standard\"].md-menu-item--selected) {\n background-color: var(--md-sys-color-tertiary-container, #FFD8E4);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"]:active) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"]:first-child:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"]:last-child:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"][data-after-gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"][gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"][data-after-gap][gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n/* Vertical Vibrant */\n:host([data-variant=\"vibrant\"].md-menu-item--selected) {\n background-color: var(--md-sys-color-tertiary, #7D5260);\n color: var(--md-sys-color-on-tertiary, #FFFFFF);\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"]:active) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"]:first-child:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"]:last-child:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"][data-after-gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"][gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"][data-after-gap][gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n/* ==========================================================\n 4. DISABLED STATE\n ========================================================== */\n:host(.md-menu-item--disabled) {\n cursor: default;\n opacity: 0.38;\n pointer-events: none;\n}\n\n/* ==========================================================\n 5. LEADING ICON\n ========================================================== */\n.md-menu-item__leading {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--_icon-size);\n height: var(--_icon-size);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n.md-menu-item__leading ::slotted(*) {\n /* `!important` here is load-bearing, not a specificity hack. Icon glyphs are\n slotted light-DOM nodes carrying a DOCUMENT-tree class — Material Symbols\n ships `.material-symbols-outlined { font-size: 24px }`. Per CSS Scoping\n §3.3 the OUTER tree wins normal declarations against `::slotted()` no\n matter the specificity, and only `!important` flips that (important\n declarations resolve the other way, inner tree first). Without the flag the\n glyph stays welded at 24px while this wrapper tapers to 20px, so the icon\n overflows its box at every density rung. Width/height are uncontested by\n that stylesheet and stay normal, so authors can still override them. */\n font-size: var(--_icon-size) !important;\n width: var(--_icon-size);\n height: var(--_icon-size);\n color: inherit;\n}\n\n:host(.md-menu-item--selected) .md-menu-item__leading {\n color: inherit;\n}\n\n/* ==========================================================\n 6. CONTENT\n ========================================================== */\n.md-menu-item__content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n.md-menu-item__headline {\n font-family: var(--md-sys-typescale-body-large-font-family, Roboto, sans-serif);\n font-size: max(13px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-body-large-weight, 400);\n line-height: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.md-menu-item__supporting {\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: max(11px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n color: var(--md-sys-color-on-surface-variant, #49454F);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ==========================================================\n 7. BADGE\n ========================================================== */\n.md-menu-item__badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n height: 20px;\n margin-inline-start: 12px;\n padding: 0 8px;\n border-radius: var(--md-sys-shape-corner-full, 9999px);\n background-color: var(--md-sys-color-tertiary-container, #FFD8E4);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n font-family: var(--md-sys-typescale-label-small-font-family, Roboto, sans-serif);\n font-size: var(--md-sys-typescale-label-small-size, 11px);\n font-weight: var(--md-sys-typescale-label-small-weight, 500);\n line-height: var(--md-sys-typescale-label-small-line-height, 16px);\n letter-spacing: var(--md-sys-typescale-label-small-tracking, 0.5px);\n white-space: nowrap;\n}\n\n/* ==========================================================\n 8. TRAILING\n ========================================================== */\n.md-menu-item__trailing {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n margin-inline-start: 8px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n.md-menu-item__trailing /* NOT badges. A custom property inside ::slotted() resolves in the SLOTTED\n element's own scope, and md-badge defines its own `--_icon-size` (10px, for\n its glyph). So `height: var(--_icon-size) !important` here picked up the\n BADGE's 10px instead of this component's icon size and, being !important,\n beat the badge's own 16px — squashing every badge slotted onto an icon\n button / avatar / menu item into a 10px blob. A badge is not an icon; it\n sizes itself. */\n::slotted(*:not(md-badge)) {\n /* `!important` for the same document-tree reason as the leading glyph above. */\n font-size: var(--_icon-size) !important;\n width: var(--_icon-size);\n height: var(--_icon-size);\n color: inherit;\n}\n\n.md-menu-item__trailing-text {\n font-family: var(--md-sys-typescale-label-small-font-family, Roboto, sans-serif);\n font-size: var(--md-sys-typescale-label-small-size, 11px);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* Hide trailing when nothing is slotted and no trailing text */\n.md-menu-item__trailing:not(:has(::slotted(*), .md-menu-item__trailing-text)) {\n display: none;\n}\n\n:host(.md-menu-item--selected) .md-menu-item__trailing {\n color: inherit;\n}\n\n/* ==========================================================\n 9. CHECK INDICATOR (checkbox/radio)\n ========================================================== */\n.md-menu-item__check {\n display: flex;\n align-items: center;\n justify-content: center;\n /* Shadow-internal glyph, so no document-tree rule competes and no\n `!important` is needed — but it still has to taper with its row. */\n width: var(--_check-size);\n height: var(--_check-size);\n flex-shrink: 0;\n margin-inline-start: 8px;\n color: inherit;\n}\n\n.md-menu-item__check .material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-weight: normal;\n font-style: normal;\n font-size: var(--_check-size);\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* ==========================================================\n 10. DIVIDER\n ========================================================== */\n/* The line is flush: it separates two rows without displacing either.\n\n The previous `padding-bottom: 8px` came out of the item's OWN height —\n `min-block-size` is a border-box measurement, so a divider row rendered 40px\n of content where every other row got 48px, sitting 4px high against the\n list's rhythm with a correspondingly shorter hit area. The matching\n `margin-bottom: 8px` then left dead menu background under the line, which\n the row's hover surface could not reach.\n\n Rows that want breathing room use the separate `gap` prop, which the menu\n applies as a margin from the outside (md-menu.css, `::slotted([gap])`). */\n:host(.md-menu-item--divider) {\n padding-bottom: 0;\n margin-bottom: 0;\n}\n\n:host(.md-menu-item--divider)::after {\n content: '';\n position: absolute;\n bottom: 0;\n inset-inline: 0;\n height: 1px;\n background-color: var(--md-sys-color-outline-variant, #CAC4D0);\n}\n\n/* ==========================================================\n 11. VERTICAL MENU (STANDARD) VARIANT OVERRIDES\n ========================================================== */\n:host([data-variant=\"standard\"]) {\n /* Resting corners, named so the hover/press/selected rules below can blend\n BACK to them. Freezing is per-corner because an item's resting shape\n depends on its position: first/last child carry large outer corners while\n the rest are small, so a single blanket rest value would round the wrong\n corners when shape morph is switched off. See §13 in tokens.css. */\n --_rest-ss: var(--md-sys-shape-corner-small, 8px);\n --_rest-se: var(--md-sys-shape-corner-small, 8px);\n --_rest-es: var(--md-sys-shape-corner-small, 8px);\n --_rest-ee: var(--md-sys-shape-corner-small, 8px);\n color: var(--md-sys-color-on-surface, #1C1B1F);\n gap: 8px;\n border-radius: var(--md-sys-shape-corner-small, 8px);\n /* The vertical variants tighten icons to 20dp; retargeting the same lever\n keeps them on the density curve instead of freezing at 20px. */\n --_icon-size: var(--md-menu-item-icon-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n}\n\n:host([data-variant=\"standard\"]:first-child) {\n --_rest-ss: var(--md-sys-shape-corner-large, 16px);\n --_rest-se: var(--md-sys-shape-corner-large, 16px);\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host([data-variant=\"standard\"]:last-child) {\n --_rest-es: var(--md-sys-shape-corner-large, 16px);\n --_rest-ee: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host([data-variant=\"standard\"]) .md-menu-item__leading {\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n:host([data-variant=\"standard\"]) .md-menu-item__trailing,\n:host([data-variant=\"standard\"]) .md-menu-item__supporting,\n:host([data-variant=\"standard\"]) .md-menu-item__trailing-text {\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n:host([data-variant=\"standard\"].md-menu-item--selected) .md-menu-item__leading,\n:host([data-variant=\"standard\"].md-menu-item--selected) .md-menu-item__trailing {\n color: inherit;\n}\n\n/* ==========================================================\n 12. VERTICAL MENU (VIBRANT) VARIANT OVERRIDES\n ========================================================== */\n:host([data-variant=\"vibrant\"]) {\n /* Resting corners, named so the hover/press/selected rules below can blend\n BACK to them. Freezing is per-corner because an item's resting shape\n depends on its position: first/last child carry large outer corners while\n the rest are small, so a single blanket rest value would round the wrong\n corners when shape morph is switched off. See §13 in tokens.css. */\n --_rest-ss: var(--md-sys-shape-corner-small, 8px);\n --_rest-se: var(--md-sys-shape-corner-small, 8px);\n --_rest-es: var(--md-sys-shape-corner-small, 8px);\n --_rest-ee: var(--md-sys-shape-corner-small, 8px);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n gap: 8px;\n border-radius: var(--md-sys-shape-corner-small, 8px);\n --_icon-size: var(--md-menu-item-icon-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n}\n\n:host([data-variant=\"vibrant\"]:first-child) {\n --_rest-ss: var(--md-sys-shape-corner-large, 16px);\n --_rest-se: var(--md-sys-shape-corner-large, 16px);\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host([data-variant=\"vibrant\"]:last-child) {\n --_rest-es: var(--md-sys-shape-corner-large, 16px);\n --_rest-ee: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host([data-variant=\"vibrant\"]) .md-menu-item__leading {\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n}\n\n:host([data-variant=\"vibrant\"]) .md-menu-item__trailing,\n:host([data-variant=\"vibrant\"]) .md-menu-item__supporting,\n:host([data-variant=\"vibrant\"]) .md-menu-item__trailing-text {\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n}\n\n:host([data-variant=\"vibrant\"].md-menu-item--selected) .md-menu-item__leading,\n:host([data-variant=\"vibrant\"].md-menu-item--selected) .md-menu-item__trailing {\n color: inherit;\n}\n\n:host([data-variant=\"vibrant\"]) .md-menu-item__state-layer {\n background-color: var(--md-sys-color-on-tertiary-container, #31111D);\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, Event, EventEmitter, Element, State } from '@stencil/core';\nimport { MenuElement, SelectableElement } from '../../utils/types';\nimport { triggerRipple } from '../../utils/ripple';\n\n@Component({ tag: 'md-menu-item', styleUrl: 'md-menu-item.css', shadow: true })\nexport class MdMenuItem {\n @Element() el!: HTMLElement;\n\n /** Primary label text. */\n @Prop() headline: string = '';\n /** Secondary descriptive text below the headline. */\n @Prop({ attribute: 'supporting-text' }) supportingText: string = '';\n /** Trailing text (e.g. keyboard shortcut). */\n @Prop({ attribute: 'trailing-text' }) trailingText: string = '';\n /** Whether the item is disabled. */\n @Prop({ reflect: true }) disabled: boolean = false;\n /** Whether the item is currently selected. */\n @Prop({ mutable: true, reflect: true }) selected: boolean = false;\n /** Mixed/partial state for a `checkbox` item — renders a dash in the check\n * slot instead of a tick and exposes `aria-checked=\"mixed\"`. Used for a\n * \"select all\" affordance where only some children are selected. Ignored for\n * `button`/`radio` types and when `selected` is true. */\n @Prop({ mutable: true, reflect: true }) indeterminate: boolean = false;\n /** Prevent the parent menu from closing when this item is clicked. */\n @Prop({ attribute: 'keep-open' }) keepOpen: boolean = false;\n /** Render a divider line below this item. */\n @Prop({ reflect: true }) divider: boolean = false;\n /** Render a gap (extra space) below this item — an alternative separator to divider. */\n @Prop({ reflect: true }) gap: boolean = false;\n /** Small badge label (e.g. \"New\") displayed before the trailing area. */\n @Prop() badge: string = '';\n /** Type of item: 'button' (default action), 'checkbox' (toggle), or 'radio' (single-select within group). */\n @Prop() type: 'button' | 'checkbox' | 'radio' = 'button';\n /** Position of the selection checkmark indicator. */\n @Prop({ attribute: 'check-position', reflect: true }) checkPosition: 'start' | 'end' = 'end';\n /**\n * ARIA presentation. `'menuitem'` (default) exposes the item with the menu\n * role family (`menuitem` / `menuitemradio` / `menuitemcheckbox`, state via\n * `aria-checked`). `'option'` exposes it as a listbox option (`role=\"option\"`,\n * state via `aria-selected`) — used by `md-select` so the popup is a proper\n * WAI-ARIA combobox/listbox rather than a menu.\n */\n @Prop({ reflect: true }) presentation: 'menuitem' | 'option' = 'menuitem';\n\n /**\n * Override the computed ARIA role. Used when a checkbox/radio item is NOT inside\n * a menu — e.g. a \"select all\" toggle in a listbox popup, which is semantically a\n * `checkbox` (keeps `aria-checked`, drops the menu-only required-parent). Empty =\n * the default menuitem/option role family.\n */\n @Prop({ attribute: 'role-override' }) roleOverride: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fires when the item is activated. */\n @Event() mdClick: EventEmitter<void>;\n\n @State() private hasLeadingIcon = false;\n @State() private hasTrailingIcon = false;\n\n componentWillLoad() {\n this.hasLeadingIcon = !!this.el.querySelector('[slot=\"leading-icon\"]');\n this.hasTrailingIcon = !!this.el.querySelector('[slot=\"trailing-icon\"]');\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.disabled) { e.preventDefault(); e.stopPropagation(); return; }\n\n if (this.type === 'checkbox') {\n this.selected = !this.selected;\n } else if (this.type === 'radio') {\n this.selected = true;\n this.deselectSiblingRadios();\n }\n\n this.mdClick.emit();\n\n if (!this.keepOpen) {\n let menu = this.el.closest('md-menu') as HTMLElement | null;\n let root = menu;\n while (menu) {\n const parent = menu.parentElement?.closest('md-menu') as HTMLElement | null;\n if (parent) { root = parent; menu = parent; } else { break; }\n }\n if (root) {\n const rootMenu = root as MenuElement;\n if (rootMenu.anchor) {\n document.getElementById(rootMenu.anchor)?.focus();\n }\n setTimeout(() => rootMenu.close?.(), 150);\n }\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n if (!this.disabled) triggerRipple(this.el);\n this.el.click();\n } else if (e.key === ' ') {\n e.preventDefault();\n if (this.disabled) return;\n\n triggerRipple(this.el);\n\n if (this.type === 'checkbox') {\n this.selected = !this.selected;\n this.mdClick.emit();\n } else if (this.type === 'radio') {\n this.selected = true;\n this.deselectSiblingRadios();\n this.mdClick.emit();\n } else {\n this.el.click();\n }\n }\n };\n\n private deselectSiblingRadios() {\n if (this.type !== 'radio') return;\n const group = this.el.closest('md-menu-item-group') || this.el.closest('md-menu');\n if (!group) return;\n const siblings = Array.from(group.querySelectorAll('md-menu-item')) as unknown as SelectableElement[];\n for (const sibling of siblings) {\n if (sibling !== this.el && sibling.type === 'radio' && sibling.selected) {\n sibling.selected = false;\n }\n }\n }\n\n private get role(): string {\n if (this.roleOverride) return this.roleOverride;\n if (this.presentation === 'option') return 'option';\n if (this.type === 'checkbox') return 'menuitemcheckbox';\n if (this.type === 'radio') return 'menuitemradio';\n return 'menuitem';\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-menu-item': true,\n 'md-menu-item--selected': this.selected,\n 'md-menu-item--disabled': this.disabled,\n 'md-menu-item--divider': this.divider,\n 'md-menu-item--gap': this.gap,\n }}\n role={this.role}\n aria-disabled={this.disabled ? 'true' : 'false'}\n aria-selected={this.presentation === 'option' ? String(this.selected) : undefined}\n aria-checked={\n this.presentation !== 'option' && this.type !== 'button'\n ? this.indeterminate && !this.selected\n ? 'mixed'\n : String(this.selected)\n : undefined\n }\n tabindex=\"-1\"\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n >\n <md-ripple disabled={this.disabled}></md-ripple>\n <span class=\"md-menu-item__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n {this.type !== 'button' && this.checkPosition === 'start' && (\n <span class=\"md-menu-item__check\" aria-hidden=\"true\">\n <span class=\"material-symbols-outlined\">\n {this.selected ? 'check' : this.indeterminate ? 'remove' : ''}\n </span>\n </span>\n )}\n\n {this.hasLeadingIcon && (\n <span class=\"md-menu-item__leading\" part=\"leading-icon\" aria-hidden=\"true\">\n <slot name=\"leading-icon\"></slot>\n </span>\n )}\n\n <span class=\"md-menu-item__content\" part=\"content\">\n <span class=\"md-menu-item__headline\" part=\"headline\">{this.headline}</span>\n {this.supportingText && (\n <span class=\"md-menu-item__supporting\" part=\"supporting-text\">{this.supportingText}</span>\n )}\n </span>\n\n {this.badge && (\n <span class=\"md-menu-item__badge\" part=\"badge\">{this.badge}</span>\n )}\n\n {(this.hasTrailingIcon || this.trailingText) && (\n <span class=\"md-menu-item__trailing\" part=\"trailing\">\n <slot name=\"trailing-icon\">\n {this.trailingText && (\n <span class=\"md-menu-item__trailing-text\">{this.trailingText}</span>\n )}\n </slot>\n </span>\n )}\n\n {this.type !== 'button' && this.checkPosition === 'end' && (\n <span class=\"md-menu-item__check\" aria-hidden=\"true\">\n <span class=\"material-symbols-outlined\">\n {this.selected ? 'check' : this.indeterminate ? 'remove' : ''}\n </span>\n </span>\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["mdMenuCss","CLOSE_ANIMATION_MS","TYPEAHEAD_TIMEOUT_MS","VIEWPORT_MARGIN","COMPACT_BREAKPOINT","EXPANDABLE_ANCHOR_ROLES","Set","NATIVE_EXPANDABLE_TAGS","menuIdCounter","MdMenu","constructor","hostRef","this","open","anchor","placement","quick","variant","layout","useGap","emptyText","matchAnchorWidth","responsive","persistent","autoFocus","closing","sectioned","empty","hasSubmenu","focusedIndex","navSeq","ringedIndex","skipAutoFocus","menuId","typeaheadBuffer","keyboardModality","openedViaKeyboard","listboxMode","listbox","density","trackKeyboardModality","trackPointerModality","lastSurfaceSize","handleOutsideClick","e","path","composedPath","includes","el","close","handleDocumentKeyDown","key","restoreFocusToAnchor","handleScroll","positionMenu","handleSlotChange","updateSections","propagateVariant","wireItemObserver","updateEmpty","querySelector","asListbox","setComboboxElement","comboboxEl","removeAttribute","undefined","connectedCallback","document","addEventListener","componentDidLoad","applyDepthZIndex","onEmptyTextChange","onVariantChange","setVirtualProvider","provider","getScrollViewport","shadowRoot","show","opts","clearTimeout","closeTimer","collapseSubmenus","reposition","setTimeout","onOpenChange","dismissPeerMenus","requestAnimationFrame","mdOpen","emit","updateAnchorAria","window","observeSurfaceResize","scheduleFocus","initRovingTabindex","focusFirstItem","mdClose","resetRovingTabindex","removeEventListener","unobserveSurfaceResize","ResizeObserver","surface","surfaceRO","entries","r","length","contentRect","size","Math","round","width","height","observe","disconnect","handleFocusIn","target","item","closest","attr","getAttribute","index","parseInt","isNaN","prev","domItemForIndex","setAttribute","ringed","items","getMenuItems","indexOf","handleKeyDown","handleKeyDownVirtual","preventDefault","focusItem","stopPropagation","closeEntireMenuTree","ctrlKey","metaKey","altKey","shiftKey","handleTypeahead","p","count","fromInput","tagName","focusVirtual","nextEnabled","click","handleTypeaheadVirtual","from","dir","idx","i","isDisabledAt","showRing","seq","ensureVisible","node","old","id","focus","preventScroll","char","typeaheadTimer","toLowerCase","findPrefix","all","Array","querySelectorAll","filter","getItemLabel","headline","textContent","trim","startIndex","label","startsWith","forEach","subItems","collapse","allItems","fn","retries","getAnchorEl","root","getRootNode","getElementById","anchorEl","anchorRole","supportsExpanded","has","hasAttribute","style","zIndex","anchorRect","getBoundingClientRect","gap","minWidth","top","left","right","bottom","menuW","offsetWidth","menuH","offsetHeight","vw","innerWidth","vh","innerHeight","m","h","transformOrigin","max","min","vertical","horizontal","endsWith","spaceBelow","spaceAbove","scrollCapped","avail","scrollEl","chrome","setProperty","removeProperty","vOrigin","hOrigin","clampedLeft","clampedTop","rootMenu","current","parentMenu","parentElement","anchorId","peer","contains","isHidden","display","hasVisibleItem","tag","children","some","child","slot","getContentSlot","assignedElements","itemObserver","MutationObserver","attributes","attributeFilter","subtree","slots","find","s","nested","foundGap","afterGap","disconnectedCallback","inlineFill","classList","maxHeightValue","maxHeight","raw","String","test","useScrollViewport","renderMenuBody","onSlotchange","class","part","role","render","Host","inert","name","tabindex","maxBlockSize","mdMenuItemCss","MdMenuItem","supportingText","trailingText","disabled","selected","indeterminate","keepOpen","divider","badge","type","checkPosition","presentation","roleOverride","hasLeadingIcon","hasTrailingIcon","handleClick","deselectSiblingRadios","mdClick","menu","parent","triggerRipple","componentWillLoad","group","siblings","sibling","onClick","onKeyDown"],"sources":["src/components/md-menu/md-menu.css?tag=md-menu&encapsulation=shadow","src/components/md-menu/md-menu.tsx","src/components/md-menu-item/md-menu-item.css?tag=md-menu-item&encapsulation=shadow","src/components/md-menu-item/md-menu-item.tsx"],"sourcesContent":["/* ═══════════════════════════════════════════════════════════\n md-menu\n Material Design 3 — Menus\n https://m3.material.io/components/menus/specs\n\n Variants:\n baseline — MD3 original (8px corners, surface container)\n standard — M3 Expressive vertical (16px corners, surface-based)\n vibrant — M3 Expressive vertical (16px corners, tertiary-based)\n\n CSS custom properties:\n --md-menu-min-width Min container width (default 112px)\n --md-menu-max-width Max container width (default 280px)\n --md-menu-inline-surface-color Background for md-menu--inline-fill only (default transparent)\n --md-menu-inline-fill-radius-end Bottom corner radius for inline-fill embed (default 0)\n --md-sys-z-index-popup Stack order (default 1000)\n\n Parts: (none — container is internal)\n Slots: (default) — accepts md-menu-item, md-sub-menu-item\n ═══════════════════════════════════════════════════════════ */\n\n/* ==========================================================\n 1. HOST\n ========================================================== */\n:host {\n display: block;\n position: fixed;\n z-index: auto;\n pointer-events: none;\n}\n\n:host(.md-menu--open) {\n pointer-events: auto;\n}\n\n/* ==========================================================\n 2. SURFACE — BASELINE\n ========================================================== */\n.md-menu__surface {\n background-color: var(--md-sys-color-surface-container, #F7F2FA);\n border-radius: var(--md-sys-shape-corner-small, 8px);\n box-shadow:\n 0 1px 2px rgba(0, 0, 0, 0.3),\n 0 2px 6px 2px rgba(0, 0, 0, 0.15);\n min-width: var(--md-menu-min-width, 112px);\n /* Grow to fit the widest item, bounded only by the viewport (minus an edge\n margin) — long labels no longer truncate at a fixed 280px. Consumers wanting\n the MD3 280dp cap (or any cap) set --md-menu-max-width; we still clamp that\n to the viewport so it can never run off-screen. */\n max-width: min(\n var(--md-menu-max-width, 100vw),\n calc(100vw - 2 * var(--md-menu-viewport-margin, 8px))\n );\n /* Inline padding is 0 by design: baseline menu rows are FULL-BLEED, so their\n hover / focus / selected state layer runs edge to edge (M3 gives the menu\n list vertical padding only). An inline inset here leaves the highlight\n floating in a gutter — visible on md-select, which uses this surface.\n The vertical `standard` / `vibrant` variants override this with a real\n inline inset further down, because THEIR rows are rounded plates and need\n the breathing room for the corner radius. */\n padding: var(--md-sys-spacing-inset-xs, 4px) 0;\n overflow: visible;\n opacity: 0;\n transform: scaleY(0.8);\n transform-origin: top left;\n transition:\n opacity var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1)),\n transform var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n:host(.md-menu--open) .md-menu__surface {\n opacity: 1;\n transform: none;\n}\n\n/* --- Close animation --- */\n:host(.md-menu--closing) .md-menu__surface {\n opacity: 0;\n transform: scaleY(0.8);\n transition:\n opacity var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15)),\n transform var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-emphasized-accelerate, cubic-bezier(0.3, 0, 0.8, 0.15));\n}\n\n/* Keep pointer-events active during close so ripple finishes */\n:host(.md-menu--closing) {\n pointer-events: none;\n}\n\n:host(.md-menu--quick) .md-menu__surface {\n transition: none;\n}\n\n/* --- Inline fill: embedded in a flex parent (e.g. md-date-picker docked panel) --- */\n:host(.md-menu--inline-fill) {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-block-size: 0;\n block-size: 100%;\n inline-size: 100%;\n pointer-events: auto;\n}\n\n:host(.md-menu--inline-fill) .md-menu__surface {\n flex: 1 1 auto;\n block-size: 100%;\n min-block-size: 0;\n min-inline-size: 100%;\n max-inline-size: none;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n box-shadow: none;\n border: none;\n outline: none;\n /* Baseline menus use padding: 4px 0 — strip for flush embed (e.g. date-picker). */\n padding: 0;\n border-radius: 0;\n border-end-start-radius: var(--md-menu-inline-fill-radius-end, 0);\n border-end-end-radius: var(--md-menu-inline-fill-radius-end, 0);\n /* Consumer sets --md-menu-inline-surface-color (e.g. md-date-picker docked panel). */\n background-color: var(--md-menu-inline-surface-color, transparent);\n}\n\n/* Inline-fill scroll is owned by md-scroll-shadow (edge fades when overflow). */\n:host(.md-menu--inline-fill) .md-menu__scroll-shadow {\n flex: 1 1 auto;\n min-block-size: 0;\n block-size: 100%;\n}\n\n:host(.md-menu--inline-fill) .md-menu__surface ::slotted(md-menu-item:last-child) {\n border-end-start-radius: var(--md-menu-inline-fill-radius-end, 0);\n border-end-end-radius: var(--md-menu-inline-fill-radius-end, 0);\n}\n\n/* --- Capped height: long lists scroll inside md-scroll-shadow (edge fades) --- */\n/* The scroll-shadow (display:flex column, bounded by the inline max-block-size)\n owns the vertical scroll; the surface only clips so it never double-scrolls.\n The viewport-safe rule below opts capped menus out (:not(.md-menu--scroll))\n so its `overflow-y: auto` can't compete with this. */\n:host(.md-menu--scroll):not(.md-menu--has-submenu) .md-menu__surface {\n overflow: hidden;\n}\n\n:host(.md-menu--scroll) .md-menu__scroll-shadow {\n min-block-size: 0;\n}\n\n/* The menu's scroll viewport (long lists scroll inside its inline max-block-size\n cap). Virtualized menus reposition their windowed rows by rewriting a\n multi-million-px top spacer between renders. Browser scroll-anchoring would try\n to keep the pre-render content stable and silently shift scrollTop to\n compensate — which desyncs the keyboard-nav anchor from the offset it was laid\n out for and snaps the view away. Opt out so our programmatic offset wins. */\n.md-menu__scroll-shadow {\n overflow-y: auto;\n overflow-anchor: none;\n}\n\n/* --- Match anchor width: min-width set via JS; grow to content but stay on-screen --- */\n:host([match-anchor-width]) .md-menu__surface {\n max-width: calc(100vw - 2 * var(--md-menu-viewport-margin, 8px));\n box-sizing: border-box;\n}\n\n/* ==========================================================\n 2b. RESPONSIVE / VIEWPORT-SAFE SIZING\n ========================================================== */\n\n/* Tall menus scroll instead of running off the bottom of the screen. Skipped\n when the menu has submenus — their flyouts are positioned children that\n would be clipped by an overflow on the surface — and when capped, where\n md-scroll-shadow owns the scroll instead (see the capped-height block above). */\n:host(:not(.md-menu--has-submenu):not(.md-menu--inline-fill):not(.md-menu--scroll)) .md-menu__surface {\n max-height: calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px));\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n/* `responsive` on a compact viewport: near-full-width sheet below the trigger.\n Positioning (left edge + vertical flip/clamp) is handled in positionMenu(). */\n@media (max-width: 600px) {\n :host(.md-menu--responsive) .md-menu__surface {\n width: calc(100vw - 2 * var(--md-menu-viewport-margin, 8px));\n min-width: 0;\n max-width: none;\n box-sizing: border-box;\n }\n}\n\n/* ==========================================================\n 3. PLACEMENT — TRANSFORM ORIGIN\n ========================================================== */\n:host([placement=\"bottom-start\"]) .md-menu__surface { transform-origin: top left; }\n:host([placement=\"bottom-end\"]) .md-menu__surface { transform-origin: top right; }\n:host([placement=\"top-start\"]) .md-menu__surface { transform-origin: bottom left; }\n:host([placement=\"top-end\"]) .md-menu__surface { transform-origin: bottom right; }\n\n/* ==========================================================\n 4. VERTICAL MENU — STANDARD VARIANT\n ========================================================== */\n:host(.md-menu--standard) .md-menu__surface {\n background-color: var(--md-sys-color-surface-container-low, #F7F2FA);\n border-radius: var(--md-sys-shape-corner-large, 16px);\n box-shadow:\n 0 1px 3px rgba(0, 0, 0, 0.12),\n 0 4px 8px 3px rgba(0, 0, 0, 0.08);\n padding: var(--md-sys-spacing-inset-xs, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item) {\n border-radius: var(--md-sys-shape-corner-small, 8px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:first-child),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:first-child) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:last-child),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:last-child) {\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:hover) {\n border-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:active),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item.md-menu-item--selected),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:active) {\n border-radius: var(--md-sys-shape-corner-medium, 12px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:first-child:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:first-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-menu-item:last-child:hover),\n:host(.md-menu--standard) .md-menu__surface ::slotted(md-sub-menu-item:last-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-start-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n/* ==========================================================\n 5. VERTICAL MENU — VIBRANT VARIANT\n ========================================================== */\n:host(.md-menu--vibrant) .md-menu__surface {\n background-color: var(--md-sys-color-tertiary-container, #FFD8E4);\n border-radius: var(--md-sys-shape-corner-large, 16px);\n box-shadow:\n 0 1px 3px rgba(0, 0, 0, 0.12),\n 0 4px 8px 3px rgba(0, 0, 0, 0.08);\n padding: var(--md-sys-spacing-inset-xs, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item) {\n border-radius: var(--md-sys-shape-corner-small, 8px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:first-child),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:first-child) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:last-child),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:last-child) {\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:hover) {\n border-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:active),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item.md-menu-item--selected),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:active) {\n border-radius: var(--md-sys-shape-corner-medium, 12px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:first-child:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:first-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n}\n\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-menu-item:last-child:hover),\n:host(.md-menu--vibrant) .md-menu__surface ::slotted(md-sub-menu-item:last-child:hover) {\n border-start-start-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-start-end-radius: var(--md-sys-shape-corner-extra-small, 4px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n/* ==========================================================\n 6. GAP LAYOUT — uniform gap between all items\n ========================================================== */\n:host(.md-menu--gap) .md-menu__surface {\n gap: var(--md-sys-spacing-gap-xs, 4px);\n display: flex;\n flex-direction: column;\n}\n\n/* ==========================================================\n 6b. GROUPED + GAP — each md-menu-item-group becomes a card\n container. The surface is transparent; groups get their\n own background, separated by a gap.\n ========================================================== */\n:host(.md-menu--grouped.md-menu--gap.md-menu--standard) .md-menu__surface,\n:host(.md-menu--grouped.md-menu--gap.md-menu--vibrant) .md-menu__surface {\n background-color: transparent;\n box-shadow: none;\n overflow: visible;\n display: flex;\n flex-direction: column;\n /* The gap between group cards is a FLEX GAP, not a margin on the cards. A\n margin would have to be declared on the group's `:host`, and document-tree\n rules beat host styles — so a consumer's `* { margin: 0 }` reset (Starlight,\n Tailwind preflight, any normalise) silently collapsed the cards flush\n together. A height-capped menu nests the groups inside\n `.md-menu__scroll-shadow`, so that container repeats the gap below. */\n gap: var(--md-menu-group-gap, 4px);\n padding: 0;\n filter:\n drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15))\n drop-shadow(0 2px 6px rgba(0, 0, 0, 0.1));\n}\n\n/* The gap needs a flex container, and flex items shrink by default — in a short\n viewport that squashed each group card instead of overflowing, and because the\n cards clip (`overflow: hidden`) their rows were cut off rather than scrolled\n to. Pin the cards to their natural height so the viewport scrolls instead. */\n:host(.md-menu--grouped.md-menu--gap) .md-menu__surface ::slotted(md-menu-item-group),\n:host(.md-menu--grouped.md-menu--gap) .md-menu__scroll-shadow ::slotted(md-menu-item-group) {\n flex-shrink: 0;\n}\n\n/* When a height cap nests the groups inside the scroll viewport, that viewport\n is their flex parent — repeat the gap there so it survives the wrapper. */\n:host(.md-menu--grouped.md-menu--gap) .md-menu__scroll-shadow {\n display: flex;\n flex-direction: column;\n row-gap: var(--md-menu-group-gap, 4px);\n}\n\n/* --- Baseline: gap as spacing only --- */\n:host(.md-menu--sectioned.md-menu--baseline) .md-menu__surface ::slotted([gap]) {\n margin-bottom: var(--md-menu-section-gap, 2px);\n}\n\n/* ==========================================================\n 7. EMPTY STATE\n ========================================================== */\n.md-menu__empty {\n display: none;\n padding: var(--md-sys-spacing-inset-md, 12px) var(--md-sys-spacing-inset-lg, 16px);\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: var(--md-sys-typescale-body-medium-size, 14px);\n line-height: var(--md-sys-typescale-body-medium-line-height, 20px);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n text-align: center;\n}\n\n:host(.md-menu--empty) .md-menu__empty {\n display: block;\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Method, Watch, Listen } from '@stencil/core';\nimport { MenuElement, VirtualMenuProvider } from '../../utils/types';\n\nconst CLOSE_ANIMATION_MS = 150;\nconst TYPEAHEAD_TIMEOUT_MS = 500;\n/** Gap kept between the menu surface and every viewport edge when clamping. */\nconst VIEWPORT_MARGIN = 8;\n/** MD3 \"compact\" window-class breakpoint — below this `responsive` goes full-width. */\nconst COMPACT_BREAKPOINT = 600;\n/** Anchor roles for which `aria-expanded` is a valid, announced state. A roleless\n * anchor (e.g. a md-text-field trigger host) can't carry it — see updateAnchorAria. */\nconst EXPANDABLE_ANCHOR_ROLES = new Set([\n 'button', 'combobox', 'link', 'menuitem', 'tab', 'treeitem', 'checkbox', 'gridcell', 'row', 'rowheader', 'columnheader',\n]);\n/** Native tags whose IMPLICIT role supports aria-expanded (used when the anchor\n * sets no explicit `role` — a custom element like md-text-field is roleless). */\nconst NATIVE_EXPANDABLE_TAGS = new Set(['BUTTON', 'SUMMARY']);\n\nlet menuIdCounter = 0;\n\n@Component({ tag: 'md-menu', styleUrl: 'md-menu.css', shadow: true })\nexport class MdMenu {\n @Element() el!: HTMLElement;\n\n /** Whether the menu is open. */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n /** ID of the anchor element to position relative to. */\n @Prop() anchor: string = '';\n /** Position of the menu relative to the anchor. */\n @Prop({ reflect: true }) placement: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end' = 'bottom-start';\n /** Skip open/close animation. */\n @Prop() quick: boolean = false;\n /**\n * Visual variant.\n * - 'baseline': MD3 baseline menu (square corners, surface container)\n * - 'standard': M3 Expressive vertical menu (rounded, surface-based colors)\n * - 'vibrant': M3 Expressive vertical menu (rounded, tertiary-based colors)\n */\n @Prop({ reflect: true }) variant: 'baseline' | 'standard' | 'vibrant' = 'baseline';\n /** Layout style for vertical menus. 'standard' is flat, 'grouped' uses visual section separators. */\n @Prop({ reflect: true }) layout: 'standard' | 'grouped' = 'standard';\n /** Use gap separators instead of dividers between groups (vertical menu only). */\n @Prop({ attribute: 'use-gap', reflect: true }) useGap: boolean = false;\n /** Message shown when all menu items are hidden (e.g. no filter results). Empty string disables. */\n @Prop({ attribute: 'empty-text' }) emptyText: string = '';\n /** When true, the menu surface min-width matches the anchor element's width. The menu still grows wider if items need more space. */\n @Prop({ attribute: 'match-anchor-width', reflect: true }) matchAnchorWidth: boolean = false;\n /**\n * Adapt to compact viewports. The menu is *always* clamped within the\n * viewport (it never overflows the screen and pins to the edges with a\n * margin). When `responsive` is set, on viewports at or below the compact\n * breakpoint (600px) the menu additionally expands to near-full-width\n * below the trigger for comfortable touch use.\n */\n @Prop({ reflect: true }) responsive: boolean = false;\n /**\n * When set, the menu does NOT auto-dismiss in response to interaction\n * elsewhere on the page. By default a menu closes when:\n * 1. The user clicks outside the menu and its anchor.\n * 2. Another non-persistent menu opens (single-open coordination —\n * opening menu B closes menu A so two top-level menus never\n * overlap each other on screen).\n *\n * `persistent` opts out of both auto-dismiss paths. The menu then only\n * closes via `close()`, the anchor's toggle, item activation, or\n * Escape. Useful for modal-style pickers, multi-step menus, and any\n * context where the consumer manages dismissal explicitly.\n *\n * Submenus (an `<md-menu>` rendered inside a parent menu's `submenu`\n * slot) are never affected by sibling-menu dismissal even without this\n * flag — ancestors and descendants are always preserved.\n */\n @Prop({ reflect: true }) persistent: boolean = false;\n /**\n * When false, opening the menu initializes roving tabindex without moving\n * focus to the first item. The consumer handles focus (e.g. docked pickers\n * that scroll to the selected option). `show({ autoFocus: false })` still\n * takes precedence for a single open.\n */\n @Prop({ attribute: 'auto-focus', reflect: true }) autoFocus: boolean = true;\n\n /**\n * Cap the menu surface block-size. When the items exceed it the list\n * scrolls vertically inside a plain scroll viewport. A number is treated\n * as pixels; any CSS length is passed through (e.g. `'50vh'`). Ignored\n * when the menu has submenus — their flyouts must not be clipped by an\n * overflow container.\n */\n @Prop({ attribute: 'max-height' }) maxHeight?: number | string;\n\n /**\n * Fires when the menu opens. Scoped to the menu element: `bubbles: false`\n * stops it climbing the light-DOM tree, and `composed: false` stops it\n * escaping the shadow root of a host that embeds this menu (md-select,\n * md-multi-select, md-date-picker …). Without `composed: false` a\n * `composed` event still surfaces at the embedding host as an\n * `AT_TARGET` event — so a consumer's `mdOpen` listener on the wrapper\n * would fire for both the wrapper's own event and this inner one\n * (duplicate open/close). Wrappers listen via `onMdOpen` on the menu\n * element itself, which still fires regardless.\n */\n @Event({ bubbles: false, composed: false }) mdOpen: EventEmitter<void>;\n /** Fires when the menu closes. Scoped like `mdOpen` — see its note. */\n @Event({ bubbles: false, composed: false }) mdClose: EventEmitter<void>;\n\n @State() private closing = false;\n @State() private sectioned = false;\n @State() private empty = false;\n /** True when the menu contains submenus — they fly out and must not be\n * clipped, so the surface keeps `overflow: visible` instead of scrolling. */\n @State() private hasSubmenu = false;\n\n private focusedIndex = -1;\n /**\n * Monotonic token for virtualized keyboard nav. `focusVirtual` is async (it\n * awaits `ensureVisible` to scroll the target row into the window). Under fast\n * ArrowUp/Down key-repeat the calls overlap; without this guard a superseded\n * call would resolve *after* a newer one and re-stamp `data-md-focused` on its\n * stale index — leaving a lingering focus state-layer on whatever row now sits\n * in that slot (the \"second item background flickers\" bug). Each call captures\n * the token and bails if a newer call has since incremented it.\n */\n private navSeq = 0;\n /**\n * Filtered index of the row that currently shows the visible focus ring\n * (`data-md-focused`) in provider/virtual mode, or -1 for none. The ring is\n * removed only by the *winning* `focusVirtual` call, just before it stamps the\n * new row — never synchronously up-front. That keeps the ring on a real row\n * across the whole ArrowUp/Down autorepeat burst instead of blinking off for\n * the frames between a press and its async `ensureVisible` settling.\n */\n private ringedIndex = -1;\n private closeTimer?: ReturnType<typeof setTimeout>;\n private skipAutoFocus = false;\n private menuId = `md-menu-${++menuIdCounter}`;\n private typeaheadBuffer = '';\n private typeaheadTimer?: ReturnType<typeof setTimeout>;\n private itemObserver?: MutationObserver;\n /**\n * Tracks whether the most recent interaction was via keyboard. Used to\n * decide if the initial focus ring should show when the menu opens: a\n * mouse-opened menu auto-focuses the first item (so arrow keys work)\n * but stays ring-less until the user actually uses the keyboard.\n */\n private keyboardModality = false;\n private openedViaKeyboard = false;\n\n /**\n * When set, the menu's keyboard navigation / typeahead / focus run against a\n * *virtualized* data model instead of `querySelectorAll('md-menu-item')` —\n * only the rows in the current scroll window exist in the DOM. Null = the\n * default DOM-driven behaviour (every other menu in the app). See\n * `setVirtualProvider`. In provider mode `focusedIndex` is a filtered row\n * index rather than an index into the live DOM items.\n */\n private provider?: VirtualMenuProvider;\n\n /**\n * In provider (virtualized `md-select`) mode the popup is a WAI-ARIA\n * combobox/listbox, not a menu. `listboxMode` flips the surface role to\n * `listbox` (reactive, so the role updates when a provider is registered) and\n * `comboboxEl` is the element that owns DOM focus (the select's search input):\n * keyboard nav moves `aria-activedescendant` on it instead of moving real\n * focus onto recycled virtual rows. `listboxLabel` names the listbox.\n */\n @State() private listboxMode = false;\n private comboboxEl?: HTMLElement;\n @Prop({ attribute: 'list-label' }) listLabel?: string;\n\n /**\n * Present the popup as a WAI-ARIA listbox (surface `role=\"presentation\"`,\n * anchor `aria-haspopup=\"listbox\"`) rather than a menu. `md-select` sets this\n * for both its virtual and non-virtual lists so the popup is a listbox of\n * options regardless of size. (The virtual path additionally registers a\n * provider, which adds the aria-activedescendant focus model.)\n */\n @Prop({ reflect: true }) listbox: boolean = false;\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** True when the popup should expose listbox semantics (prop or provider). */\n private get asListbox(): boolean {\n return this.listbox || this.listboxMode;\n }\n\n /**\n * Register (or clear with `null`) the combobox element that holds focus while\n * a virtual provider drives the list. When set, keyboard navigation manages\n * `aria-activedescendant` on it rather than calling `.focus()` on options —\n * the canonical pattern for a listbox whose rows are virtualized/recycled.\n */\n @Method()\n async setComboboxElement(el: HTMLElement | null) {\n if (this.comboboxEl && this.comboboxEl !== el) {\n this.comboboxEl.removeAttribute('aria-activedescendant');\n }\n this.comboboxEl = el ?? undefined;\n }\n\n connectedCallback() {\n if (typeof document === 'undefined') return;\n document.addEventListener('keydown', this.trackKeyboardModality, true);\n document.addEventListener('pointerdown', this.trackPointerModality, true);\n }\n\n private trackKeyboardModality = () => { this.keyboardModality = true; };\n private trackPointerModality = () => { this.keyboardModality = false; };\n\n componentDidLoad() {\n if (this.open) {\n this.applyDepthZIndex();\n }\n // Run an initial scan so a menu that mounts already-empty\n // (e.g. SSR snapshot, or items hidden before first paint)\n // shows the empty-state on its first frame instead of after\n // the first slotchange.\n this.wireItemObserver();\n this.updateEmpty();\n // Propagate variant/use-gap to slotted groups on load. The initial\n // `slotchange` can fire before our handler is wired (so it's missed), which\n // left grouped+gap groups without their data-variant/data-use-gap\n // attributes — the group cards then have no background (transparent surface,\n // floating items). componentDidLoad runs once children are assigned, so this\n // is the reliable initial pass; handleSlotChange keeps it in sync after.\n this.propagateVariant();\n }\n\n @Watch('emptyText')\n onEmptyTextChange() {\n this.updateEmpty();\n }\n\n // Re-propagate to slotted groups/items when the visual variant or gap mode\n // changes at runtime (e.g. via Storybook controls) — reflect only updates the\n // host attribute, not the children the group-card CSS keys off.\n @Watch('variant')\n @Watch('useGap')\n onVariantChange() {\n this.propagateVariant();\n }\n\n /**\n * Register (or clear with `null`) a virtual provider. With a provider set,\n * keyboard nav, typeahead, and roving focus run against the data model so a\n * windowed list of millions of options behaves like a normal menu. Without\n * one the menu is unchanged.\n */\n @Method()\n async setVirtualProvider(provider: VirtualMenuProvider | null) {\n this.provider = provider ?? undefined;\n // Flip the surface to a listbox (reactive via @State) so the virtualized\n // select's popup is exposed as a WAI-ARIA listbox, not a menu.\n this.listboxMode = !!this.provider;\n }\n\n /**\n * The scrollable viewport element (the menu's `.md-menu__scroll-shadow`\n * scroll div), or null when the menu isn't capped/scrollable. A virtualized\n * host attaches its scroll listener and reads `scrollTop`/`clientHeight`\n * from this.\n */\n @Method()\n async getScrollViewport(): Promise<HTMLElement | null> {\n return (\n (this.el.shadowRoot?.querySelector('.md-menu__scroll-shadow') as HTMLElement | null) ??\n null\n );\n }\n\n /** Opens the menu programmatically. Pass `{ autoFocus: false }` to keep focus on the caller (e.g. a text field). */\n @Method()\n async show(opts?: { autoFocus?: boolean }) {\n clearTimeout(this.closeTimer);\n this.closing = false;\n // Top-level menus always (re)open from a clean state. This also covers\n // the case where a prior close was interrupted — e.g. clicking the\n // trigger fires the anchor's show() which cancels the close timer, so\n // `open` never flips to false and the close-path reset never runs.\n // Submenus (no anchor) are skipped so live drill-down isn't disturbed.\n if (this.anchor) this.collapseSubmenus();\n this.skipAutoFocus = opts?.autoFocus === false;\n this.open = true;\n this.applyDepthZIndex();\n }\n\n /**\n * Recompute the menu's position against its anchor. md-menu already reacts to\n * scroll/resize, but not to the anchor MOVING because sibling content reflowed\n * (e.g. a multi-select whose button trigger shifts as chips are added beside\n * it). Call this after such a reflow to keep the popup glued to the anchor.\n */\n @Method()\n async reposition() {\n if (this.open) this.positionMenu();\n }\n\n /** Closes the menu programmatically. */\n @Method()\n async close() {\n if (!this.open || this.closing) return;\n\n if (this.quick) {\n this.open = false;\n return;\n }\n\n this.closing = true;\n this.closeTimer = setTimeout(() => {\n this.closing = false;\n this.open = false;\n }, CLOSE_ANIMATION_MS);\n }\n\n @Watch('open')\n onOpenChange(open: boolean) {\n if (open) {\n // Snapshot the modality that triggered this open; the actual focus\n // is deferred (scheduleFocus), so capture it now before it drifts.\n this.openedViaKeyboard = this.keyboardModality;\n this.dismissPeerMenus();\n this.applyDepthZIndex();\n requestAnimationFrame(() => this.positionMenu());\n this.mdOpen.emit();\n this.updateAnchorAria(true);\n if (this.anchor) {\n requestAnimationFrame(() => {\n document.addEventListener('click', this.handleOutsideClick);\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n });\n window.addEventListener('scroll', this.handleScroll, true);\n window.addEventListener('resize', this.handleScroll);\n this.observeSurfaceResize();\n }\n if (this.skipAutoFocus || !this.autoFocus) {\n this.scheduleFocus(() => this.initRovingTabindex());\n } else {\n // Always move focus to the first item so it leaves the trigger\n // (a mouse-clicked trigger must not keep its keyboard ring). The\n // ring on the item itself is shown only for keyboard opens — see\n // focusFirstItem(): mouse opens focus the item ring-less, and the\n // ring appears once the user navigates with the keyboard.\n this.scheduleFocus(() => this.focusFirstItem());\n }\n this.skipAutoFocus = false;\n } else {\n this.mdClose.emit();\n this.focusedIndex = -1;\n this.updateAnchorAria(false);\n this.resetRovingTabindex();\n this.collapseSubmenus();\n if (this.anchor) {\n document.removeEventListener('click', this.handleOutsideClick);\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n window.removeEventListener('scroll', this.handleScroll, true);\n window.removeEventListener('resize', this.handleScroll);\n }\n this.unobserveSurfaceResize();\n }\n }\n\n /** Reposition when the open surface's own size changes — e.g. an\n * autocomplete's list shrinking as the user types. A top-flipped menu\n * positioned for the taller list would otherwise keep its stale `top`\n * and float detached above the anchor. */\n private surfaceRO?: ResizeObserver;\n private lastSurfaceSize = '';\n\n private observeSurfaceResize() {\n if (typeof ResizeObserver === 'undefined') return;\n const surface = this.el.shadowRoot?.querySelector('.md-menu__surface');\n if (!surface) return;\n this.lastSurfaceSize = '';\n this.surfaceRO = new ResizeObserver((entries) => {\n if (!this.open) return;\n const r = entries[entries.length - 1]?.contentRect;\n if (!r) return;\n // Guard against feedback loops: only reposition on a REAL size change\n // (positionMenu itself tweaks min-width, which would re-fire once).\n const size = `${Math.round(r.width)}x${Math.round(r.height)}`;\n if (size === this.lastSurfaceSize) return;\n this.lastSurfaceSize = size;\n this.positionMenu();\n });\n this.surfaceRO.observe(surface);\n }\n\n private unobserveSurfaceResize() {\n this.surfaceRO?.disconnect();\n this.surfaceRO = undefined;\n }\n\n @Listen('focusin')\n handleFocusIn(e: FocusEvent) {\n if (!this.open) return;\n const target = e.target as HTMLElement;\n\n if (this.provider) {\n // Map a pointer-focused windowed item back to its filtered index via the\n // `data-vindex` the host stamps on each rendered row.\n const item = target.closest('md-menu-item') as HTMLElement | null;\n const attr = item?.getAttribute('data-vindex');\n if (item && attr != null) {\n const index = parseInt(attr, 10);\n if (!isNaN(index) && index !== this.focusedIndex) {\n const prev =\n this.focusedIndex >= 0 ? this.provider.domItemForIndex(this.focusedIndex) : null;\n prev?.setAttribute('tabindex', '-1');\n this.focusedIndex = index;\n item.setAttribute('tabindex', '0');\n // Pointer focus is ring-less; drop any deferred keyboard ring still\n // seated on a different row so it can't linger after a hover/click.\n if (this.ringedIndex >= 0 && this.ringedIndex !== index) {\n const ringed = this.provider.domItemForIndex(this.ringedIndex);\n ringed?.removeAttribute('data-md-focused');\n }\n this.ringedIndex = -1;\n }\n }\n return;\n }\n\n const items = this.getMenuItems();\n const index = items.indexOf(target);\n if (index >= 0 && index !== this.focusedIndex) {\n if (this.focusedIndex >= 0 && this.focusedIndex < items.length) {\n items[this.focusedIndex].setAttribute('tabindex', '-1');\n }\n this.focusedIndex = index;\n target.setAttribute('tabindex', '0');\n }\n }\n\n @Listen('keydown')\n handleKeyDown(e: KeyboardEvent) {\n if (!this.open) return;\n\n const target = e.target as HTMLElement;\n if (target && target.closest('md-menu') !== this.el) return;\n\n if (this.provider) {\n this.handleKeyDownVirtual(e);\n return;\n }\n\n const items = this.getMenuItems();\n if (!items.length) return;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this.focusItem(items, this.focusedIndex + 1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.focusItem(items, this.focusedIndex - 1);\n break;\n case 'Home':\n e.preventDefault();\n this.focusItem(items, 0);\n break;\n case 'End':\n e.preventDefault();\n this.focusItem(items, items.length - 1);\n break;\n case 'Escape':\n e.preventDefault();\n this.close();\n this.restoreFocusToAnchor();\n break;\n case 'Tab':\n e.stopPropagation();\n this.closeEntireMenuTree();\n // Return focus to the trigger (like Escape) so it doesn't fall to <body>\n // when the focused option/search input unmounts; the user tabs onward from\n // there.\n this.restoreFocusToAnchor();\n break;\n default:\n if (e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey) {\n this.handleTypeahead(e.key, items);\n }\n break;\n }\n }\n\n // ── Virtualized (provider) navigation ────────────────────\n // Mirrors the DOM-driven path but operates on filtered row indices in the\n // provider's data model, scrolling the target row into the rendered window\n // (ensureVisible) before moving real focus to it. `focusedIndex` is a\n // filtered index here, not a DOM-items index.\n\n private handleKeyDownVirtual(e: KeyboardEvent) {\n const p = this.provider!;\n const count = p.count();\n // Keystrokes inside a header search field (the filterable select) type into\n // the input; only navigation keys are intercepted for the list.\n const fromInput = (e.target as HTMLElement)?.tagName === 'INPUT';\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(this.focusedIndex, 1, count));\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(this.focusedIndex, -1, count));\n break;\n case 'Home':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(-1, 1, count));\n break;\n case 'End':\n e.preventDefault();\n this.focusVirtual(this.nextEnabled(count, -1, count));\n break;\n case 'Enter':\n // In combobox mode the input keeps focus, so the active option never\n // receives the keystroke itself — activate it here. (In roving-focus\n // mode the focused option handles its own Enter, so don't double-fire.)\n if (this.comboboxEl && this.focusedIndex >= 0) {\n e.preventDefault();\n this.provider!.domItemForIndex(this.focusedIndex)?.click();\n }\n break;\n case 'Escape':\n e.preventDefault();\n this.close();\n this.restoreFocusToAnchor();\n break;\n case 'Tab':\n e.stopPropagation();\n this.closeEntireMenuTree();\n // Return focus to the trigger (like Escape) so it doesn't fall to <body>\n // when the focused option/search input unmounts; the user tabs onward from\n // there.\n this.restoreFocusToAnchor();\n break;\n default:\n if (\n !fromInput &&\n e.key.length === 1 &&\n !e.ctrlKey &&\n !e.metaKey &&\n !e.altKey &&\n !e.shiftKey\n ) {\n this.handleTypeaheadVirtual(e.key);\n }\n break;\n }\n }\n\n /**\n * Next non-disabled filtered index from `from` in `dir` (±1), wrapping like\n * the DOM path. Returns -1 only when every row is disabled / the list empty.\n */\n private nextEnabled(from: number, dir: number, count: number): number {\n if (count <= 0) return -1;\n let idx = from;\n for (let i = 0; i < count; i++) {\n idx += dir;\n if (idx < 0) idx = count - 1;\n else if (idx >= count) idx = 0;\n if (!this.provider!.isDisabledAt(idx)) return idx;\n }\n return from >= 0 && from < count ? from : -1;\n }\n\n private async focusVirtual(index: number, showRing = true) {\n if (index < 0) return;\n const p = this.provider!;\n const seq = ++this.navSeq;\n // Advance the logical active index immediately, but do NOT strip the visible\n // ring from the old row up-front: `ensureVisible` is async, and under\n // ArrowUp/Down autorepeat each press supersedes the last. Removing the ring\n // here left ~1-in-4 frames with no ring on any row (the held-key flicker).\n // The winning call below swaps the ring atomically once its row is windowed.\n this.focusedIndex = index;\n await p.ensureVisible(index);\n // A newer keystroke superseded this one while we awaited the scroll. Bail so\n // we don't re-stamp the focus ring / move focus to this now-stale row — the\n // latest call owns those. The current ring stays put (we never removed it).\n if (seq !== this.navSeq) return;\n const node = p.domItemForIndex(index);\n if (!node) return;\n // Atomic swap: clear the previously ringed row, then ring/seat the new one,\n // so the ring is never absent between the two.\n if (this.ringedIndex >= 0 && this.ringedIndex !== index) {\n const old = p.domItemForIndex(this.ringedIndex);\n old?.setAttribute('tabindex', '-1');\n old?.removeAttribute('data-md-focused');\n }\n if (showRing) {\n node.setAttribute('data-md-focused', '');\n this.ringedIndex = index;\n } else {\n node.removeAttribute('data-md-focused');\n this.ringedIndex = -1;\n }\n if (this.comboboxEl) {\n // WAI-ARIA combobox/listbox: focus stays on the combobox (the select's\n // search input); the active option is conveyed via aria-activedescendant.\n // This is the robust model for a virtualized listbox — no real focus is\n // moved onto rows that scroll out of the window and get recycled. The\n // option keeps tabindex -1 (only the combobox is in the tab order).\n node.id ||= `${this.menuId}-opt-${index}`;\n if (node.id) this.comboboxEl.setAttribute('aria-activedescendant', node.id);\n } else {\n // No combobox (e.g. a non-filterable virtual list): fall back to the\n // standalone-listbox roving-focus model.\n node.setAttribute('tabindex', '0');\n // ensureVisible already revealed the row; preventScroll stops the browser's\n // own scroll-into-view from fighting the (anchor-driven) virtual window.\n node.focus({ preventScroll: true });\n }\n }\n\n private handleTypeaheadVirtual(char: string) {\n clearTimeout(this.typeaheadTimer);\n this.typeaheadBuffer += char.toLowerCase();\n this.typeaheadTimer = setTimeout(() => {\n this.typeaheadBuffer = '';\n }, TYPEAHEAD_TIMEOUT_MS);\n\n const from =\n this.typeaheadBuffer.length === 1 ? this.focusedIndex + 1 : this.focusedIndex;\n const idx = this.provider!.findPrefix(this.typeaheadBuffer, from < 0 ? 0 : from);\n if (idx >= 0) this.focusVirtual(idx);\n }\n\n private getMenuItems(): HTMLElement[] {\n const all = Array.from(\n this.el.querySelectorAll('md-menu-item, md-sub-menu-item')\n ) as HTMLElement[];\n return all.filter(item => item.closest('md-menu') === this.el);\n }\n\n private getItemLabel(item: HTMLElement): string {\n return (item as MenuElement).headline || item.textContent?.trim() || '';\n }\n\n private handleTypeahead(char: string, items: HTMLElement[]) {\n clearTimeout(this.typeaheadTimer);\n this.typeaheadBuffer += char.toLowerCase();\n this.typeaheadTimer = setTimeout(() => { this.typeaheadBuffer = ''; }, TYPEAHEAD_TIMEOUT_MS);\n\n const startIndex = this.typeaheadBuffer.length === 1\n ? this.focusedIndex + 1\n : this.focusedIndex;\n\n for (let i = 0; i < items.length; i++) {\n const idx = (startIndex + i) % items.length;\n const label = this.getItemLabel(items[idx]).toLowerCase();\n if (label.startsWith(this.typeaheadBuffer)) {\n this.focusItem(items, idx);\n return;\n }\n }\n }\n\n private focusItem(items: HTMLElement[], index: number, showRing = true) {\n if (items.length === 0) return;\n if (index < 0) index = items.length - 1;\n if (index >= items.length) index = 0;\n\n if (this.focusedIndex >= 0 && this.focusedIndex < items.length) {\n items[this.focusedIndex].setAttribute('tabindex', '-1');\n items[this.focusedIndex].removeAttribute('data-md-focused');\n }\n\n this.focusedIndex = index;\n items[index].setAttribute('tabindex', '0');\n // `data-md-focused` is the visible focus ring. Keyboard navigation always\n // shows it; a mouse-opened menu focuses without it (see focusFirstItem)\n // so the ring only appears once the user reaches for the keyboard.\n if (showRing) {\n items[index].setAttribute('data-md-focused', '');\n } else {\n items[index].removeAttribute('data-md-focused');\n }\n items[index].focus();\n }\n\n private initRovingTabindex() {\n if (this.provider) {\n // No focus move (skipAutoFocus path, e.g. a combobox whose search input\n // keeps focus). Seat the active index *before* the first row (-1) so the\n // first ArrowDown lands on the first item — seating it on row 0 instead\n // made the first ArrowDown skip to the second item. Nothing is active /\n // ringed until the user actually arrows.\n this.focusedIndex = -1;\n return;\n }\n const items = this.getMenuItems();\n items.forEach((item, i) => {\n item.setAttribute('tabindex', i === 0 ? '0' : '-1');\n });\n this.focusedIndex = 0;\n }\n\n private resetRovingTabindex() {\n if (this.provider) {\n const node =\n this.focusedIndex >= 0 ? this.provider.domItemForIndex(this.focusedIndex) : null;\n node?.setAttribute('tabindex', '-1');\n node?.removeAttribute('data-md-focused');\n // Also clear any deferred ring still seated on a different row.\n if (this.ringedIndex >= 0 && this.ringedIndex !== this.focusedIndex) {\n const ringed = this.provider.domItemForIndex(this.ringedIndex);\n ringed?.setAttribute('tabindex', '-1');\n ringed?.removeAttribute('data-md-focused');\n }\n this.ringedIndex = -1;\n // Drop the active-option pointer on the combobox so a screen reader\n // doesn't announce a stale active row after the listbox closes.\n this.comboboxEl?.removeAttribute('aria-activedescendant');\n return;\n }\n const items = this.getMenuItems();\n items.forEach(item => {\n item.setAttribute('tabindex', '-1');\n item.removeAttribute('data-md-focused');\n });\n }\n\n /**\n * Reset the entire subtree when this menu closes: collapse every\n * descendant submenu and clear lingering focus markers / tabindex at\n * all depths. Without this, reopening the menu restores whichever\n * submenu was open and whichever item was focused last time.\n */\n private collapseSubmenus() {\n const subItems = Array.from(\n this.el.querySelectorAll('md-sub-menu-item')\n ) as Array<HTMLElement & { collapse?: () => Promise<void> }>;\n subItems.forEach(item => item.collapse?.());\n\n const allItems = Array.from(\n this.el.querySelectorAll('md-menu-item, md-sub-menu-item')\n ) as HTMLElement[];\n allItems.forEach(item => {\n item.removeAttribute('data-md-focused');\n item.setAttribute('tabindex', '-1');\n });\n }\n\n private scheduleFocus(fn: () => void) {\n setTimeout(() => requestAnimationFrame(() => fn()), 0);\n }\n\n private focusFirstItem(retries = 3) {\n if (this.provider) {\n const count = this.provider.count();\n if (count > 0) {\n // Ring only on keyboard opens, matching the DOM path.\n this.focusVirtual(this.nextEnabled(-1, 1, count), this.openedViaKeyboard);\n } else if (retries > 0) {\n this.scheduleFocus(() => this.focusFirstItem(retries - 1));\n }\n return;\n }\n const items = this.getMenuItems();\n if (items.length) {\n // Only show the ring on auto-focus when the menu was opened by keyboard.\n this.focusItem(items, 0, this.openedViaKeyboard);\n } else if (retries > 0) {\n this.scheduleFocus(() => this.focusFirstItem(retries - 1));\n }\n }\n\n /**\n * Resolve the anchor element by id. Looks within the menu's own root node\n * first — so a menu rendered inside another component's shadow root (e.g.\n * md-select) finds a sibling trigger that `document.getElementById` can't\n * see across the shadow boundary — then falls back to the document for\n * light-DOM anchors.\n */\n private getAnchorEl(id: string = this.anchor): HTMLElement | null {\n if (!id) return null;\n const root = this.el.getRootNode() as Document | ShadowRoot;\n return (\n (root.getElementById?.(id) as HTMLElement | null) ??\n document.getElementById(id)\n );\n }\n\n private updateAnchorAria(open: boolean) {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n if (!anchorEl) return;\n\n // aria-expanded is only VALID on roles that support it. Some anchors can't\n // carry it — e.g. a md-text-field trigger whose HOST is roleless (its textbox\n // role sits on the inner input): a screen reader ignores it there and axe\n // flags aria-supported-attr. Gate it on the anchor's role; the popup stays\n // discoverable via aria-haspopup + focus moving into the menu, and role-bearing\n // triggers (a role=\"button\" opener) still get it.\n const anchorRole = anchorEl.getAttribute('role');\n const supportsExpanded =\n anchorRole !== null\n ? EXPANDABLE_ANCHOR_ROLES.has(anchorRole)\n : NATIVE_EXPANDABLE_TAGS.has(anchorEl.tagName) ||\n (anchorEl.tagName === 'A' && anchorEl.hasAttribute('href'));\n\n if (open) {\n anchorEl.setAttribute('aria-haspopup', this.asListbox ? 'listbox' : 'menu');\n // In listbox/provider mode the OWNER (md-select / md-multi-select) renders the\n // real role=\"listbox\" in ITS OWN shadow and points the trigger's aria-controls\n // at it (an in-scope IDREF). Don't clobber that with menuId, which identifies\n // this menu's role=\"presentation\" surface in a DIFFERENT shadow root (an\n // unresolvable cross-shadow reference).\n if (!this.asListbox) anchorEl.setAttribute('aria-controls', this.menuId);\n }\n if (supportsExpanded) anchorEl.setAttribute('aria-expanded', open ? 'true' : 'false');\n else anchorEl.removeAttribute('aria-expanded');\n }\n\n private applyDepthZIndex() {\n if (!this.anchor) return;\n this.el.style.zIndex = 'var(--md-sys-z-index-popup, 1000)';\n }\n\n private positionMenu() {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n if (!anchorEl) return;\n\n const anchorRect = anchorEl.getBoundingClientRect();\n const surface = this.el.shadowRoot?.querySelector('.md-menu__surface') as HTMLElement;\n if (!surface) return;\n\n const gap = 4;\n surface.style.minWidth = this.matchAnchorWidth ? `${anchorRect.width}px` : '';\n\n // Park at top-left with right/bottom cleared so stale inline styles\n // cannot shrink-to-fit the surface and corrupt the measurements.\n this.el.style.top = '0';\n this.el.style.left = '0';\n this.el.style.right = 'auto';\n this.el.style.bottom = 'auto';\n\n const menuW = surface.offsetWidth;\n let menuH = surface.offsetHeight;\n\n if (menuW === 0 || menuH === 0) {\n requestAnimationFrame(() => this.positionMenu());\n return;\n }\n\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const m = VIEWPORT_MARGIN;\n\n // Compact + responsive: drop the trigger-relative horizontal placement and\n // present a near-full-width sheet below (or above, if cramped) the anchor.\n // The CSS media query sizes the surface to `100vw - 2*margin`.\n if (this.responsive && vw <= COMPACT_BREAKPOINT) {\n const h = surface.offsetHeight;\n let top = anchorRect.bottom + gap;\n if (top + h + m > vh && anchorRect.top - gap - h >= m) {\n top = anchorRect.top - gap - h;\n surface.style.transformOrigin = 'bottom left';\n } else {\n surface.style.transformOrigin = 'top left';\n }\n top = Math.max(m, Math.min(top, vh - h - m));\n this.el.style.top = `${top}px`;\n this.el.style.left = `${m}px`;\n return;\n }\n\n let vertical: 'bottom' | 'top' = this.placement.startsWith('bottom') ? 'bottom' : 'top';\n let horizontal: 'start' | 'end' = this.placement.endsWith('start') ? 'start' : 'end';\n\n const spaceBelow = vh - anchorRect.bottom - gap - m;\n const spaceAbove = anchorRect.top - gap - m;\n\n // Keep the requested vertical side if the menu fits; otherwise flip to the side\n // that fits. A CAPPED (scrollable) menu that fits neither side picks the side\n // with MORE room and shrinks its scroll region to it (below), so it scrolls\n // instead of being clamped over the anchor.\n if (vertical === 'bottom' && menuH > spaceBelow) {\n if (menuH <= spaceAbove || (this.scrollCapped && spaceAbove > spaceBelow)) vertical = 'top';\n } else if (vertical === 'top' && menuH > spaceAbove) {\n if (menuH <= spaceBelow || (this.scrollCapped && spaceBelow > spaceAbove)) vertical = 'bottom';\n }\n\n if (horizontal === 'start' && anchorRect.left + menuW > vw) {\n if (anchorRect.right - menuW >= 0) horizontal = 'end';\n } else if (horizontal === 'end' && anchorRect.right - menuW < 0) {\n if (anchorRect.left + menuW <= vw) horizontal = 'start';\n }\n\n // Cap a scrollable menu's height to the chosen side's available space so it\n // scrolls instead of overflowing or being clamped across the anchor. Only\n // capped menus have the scroll viewport that makes this safe.\n if (this.scrollCapped) {\n const avail = vertical === 'bottom' ? spaceBelow : spaceAbove;\n const scrollEl = surface.querySelector('.md-menu__scroll-shadow') as HTMLElement | null;\n const chrome = surface.offsetHeight - (scrollEl?.offsetHeight ?? 0); // header + padding\n this.el.style.setProperty('--md-menu-avail-block', `${Math.max(48, avail - chrome)}px`);\n menuH = surface.offsetHeight; // re-measure after the cap reflows the surface\n } else {\n this.el.style.removeProperty('--md-menu-avail-block');\n }\n\n const vOrigin = vertical === 'bottom' ? 'top' : 'bottom';\n const hOrigin = horizontal === 'start' ? 'left' : 'right';\n surface.style.transformOrigin = `${vOrigin} ${hOrigin}`;\n\n const top = vertical === 'bottom'\n ? anchorRect.bottom + gap\n : anchorRect.top - gap - menuH;\n\n const left = horizontal === 'start'\n ? anchorRect.left\n : anchorRect.right - menuW;\n\n // Viewport clamp (always on): keep the surface fully on-screen with a\n // margin so it never bleeds off any edge. Width is capped in CSS, so a\n // clamp to `margin` here simply pins an oversized menu to the edge.\n const clampedLeft = Math.max(m, Math.min(left, vw - menuW - m));\n const clampedTop = Math.max(m, Math.min(top, vh - menuH - m));\n\n this.el.style.top = `${clampedTop}px`;\n this.el.style.left = `${clampedLeft}px`;\n }\n\n private restoreFocusToAnchor() {\n if (!this.anchor) return;\n const anchorEl = this.getAnchorEl();\n anchorEl?.focus();\n }\n\n private closeEntireMenuTree() {\n let rootMenu: MenuElement = this.el as unknown as MenuElement;\n let current: HTMLElement | null = this.el;\n while (current) {\n const parentMenu = current.parentElement?.closest('md-menu') as MenuElement | null;\n if (parentMenu) {\n rootMenu = parentMenu;\n current = parentMenu;\n } else {\n break;\n }\n }\n\n const allItems = rootMenu.querySelectorAll('md-menu-item, md-sub-menu-item');\n allItems.forEach(item => item.setAttribute('tabindex', '-1'));\n\n if (rootMenu.close) rootMenu.close();\n\n const anchorId = rootMenu.anchor;\n if (anchorId) {\n const root = (rootMenu as unknown as HTMLElement).getRootNode() as\n | Document\n | ShadowRoot;\n const anchorEl =\n (root.getElementById?.(anchorId) as HTMLElement | null) ??\n document.getElementById(anchorId);\n anchorEl?.focus();\n }\n }\n\n private handleOutsideClick = (e: MouseEvent) => {\n if (this.persistent) return;\n const path = e.composedPath();\n if (!path.includes(this.el)) {\n this.close();\n }\n };\n\n /**\n * Single-open coordination. When this menu opens, dismiss every other\n * non-persistent top-level menu currently open on the page so two\n * unrelated menus never overlap. Ancestors and descendants of `this`\n * are deliberately preserved — submenus must not close their parent\n * menu when they open, and parent menus must not nuke an in-flight\n * submenu the user is interacting with.\n */\n private dismissPeerMenus() {\n if (this.persistent) return;\n if (typeof document === 'undefined') return;\n const all = Array.from(document.querySelectorAll('md-menu')) as MenuElement[];\n for (const peer of all) {\n if (peer === this.el) continue;\n if (!peer.open) continue;\n if (peer.persistent) continue;\n if (peer.contains(this.el)) continue;\n if (this.el.contains(peer)) continue;\n peer.close();\n }\n }\n\n private handleDocumentKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && this.open) {\n this.close();\n this.restoreFocusToAnchor();\n }\n };\n\n private handleScroll = () => {\n if (this.open && !this.closing) {\n this.positionMenu();\n }\n };\n\n private handleSlotChange = () => {\n this.updateSections();\n this.propagateVariant();\n this.wireItemObserver();\n this.updateEmpty();\n this.hasSubmenu = !!this.el.querySelector('md-sub-menu-item');\n };\n\n /**\n * Returns true when the element is *explicitly* hidden — either the HTML\n * `hidden` attribute is set, or `style=\"display: none\"` is applied\n * inline. We deliberately avoid `getComputedStyle()` here because\n * `display: none` from a stylesheet rule on `<md-menu-item>` would\n * report the element as hidden during the brief window before the\n * loader finishes registering the custom element, which would flash\n * the empty-state on every menu open.\n */\n private isHidden(el: HTMLElement): boolean {\n if (el.hasAttribute('hidden')) return true;\n if (el.style.display === 'none') return true;\n return false;\n }\n\n private hasVisibleItem(el: HTMLElement): boolean {\n if (this.isHidden(el)) return false;\n const tag = el.tagName.toLowerCase();\n if (tag === 'md-menu-item' || tag === 'md-sub-menu-item') return true;\n if (tag === 'md-menu-item-group') {\n return Array.from(el.children).some((child) =>\n this.hasVisibleItem(child as HTMLElement),\n );\n }\n return false;\n }\n\n private updateEmpty() {\n if (!this.emptyText) {\n // No empty-text configured — the empty UI is opt-in; skip the\n // class entirely so the surface stays its natural collapsed\n // height when an unconfigured menu has no items.\n this.empty = false;\n return;\n }\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n this.empty = !children.some((child) => this.hasVisibleItem(child));\n }\n\n private wireItemObserver() {\n // The empty-state has to react to consumer code toggling\n // `style=\"display: none\"` / `hidden` on items (the canonical\n // type-to-filter pattern). `slotchange` fires when *children* of\n // the menu are added/removed, but NOT when their attributes\n // change in place — so a MutationObserver covers that gap.\n this.itemObserver?.disconnect();\n // Stencil's jsdom-lite test environment doesn't ship a\n // MutationObserver. Skip the observer there — the slotchange-\n // driven path still keeps the empty-state in sync, and the\n // dynamic-attribute path is exercised by browser-only e2e tests.\n if (typeof MutationObserver === 'undefined') return;\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n if (children.length === 0) return;\n this.itemObserver = new MutationObserver(() => this.updateEmpty());\n for (const child of children) {\n this.itemObserver.observe(child, {\n attributes: true,\n attributeFilter: ['style', 'hidden'],\n subtree: true,\n });\n }\n }\n\n /**\n * The default (content) slot — NOT the named `header` slot, which renders\n * FIRST inside the surface (a virtualized select's pinned search field). A\n * plain `querySelector('slot')` grabs that header slot (empty for normal\n * menus), so every slot-scanning method must filter by name — otherwise\n * grouped+gap groups never receive data-variant/data-use-gap and lose their\n * card background (transparent surface → floating items). Built from\n * querySelectorAll (a simple selector Stencil's jsdom-lite mock supports)\n * rather than `slot:not([name])`, which the mock can't parse.\n */\n private getContentSlot(): HTMLSlotElement | null {\n const root = this.el.shadowRoot;\n if (!root) return null;\n const slots = Array.from(root.querySelectorAll('slot')) as HTMLSlotElement[];\n // Match on the `name` ATTRIBUTE, not the `.name` property — Stencil's\n // jsdom-lite mock doesn't reflect the attribute onto the property, so `.name`\n // is undefined there and would wrongly match the header slot first.\n return slots.find((s) => !s.getAttribute('name')) ?? null;\n }\n\n private propagateVariant() {\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n for (const child of children) {\n child.setAttribute('data-variant', this.variant);\n if (child.tagName.toLowerCase() === 'md-menu-item-group') {\n if (this.useGap) {\n child.setAttribute('data-use-gap', '');\n } else {\n child.removeAttribute('data-use-gap');\n }\n const nested = child.querySelectorAll('md-menu-item, md-sub-menu-item');\n for (const item of Array.from(nested)) {\n item.setAttribute('data-variant', this.variant);\n }\n }\n }\n }\n\n private updateSections() {\n const slot = this.getContentSlot();\n if (!slot) return;\n const children = slot.assignedElements() as HTMLElement[];\n\n let foundGap = false;\n let afterGap = false;\n\n for (const child of children) {\n if (afterGap) {\n child.setAttribute('data-after-gap', '');\n afterGap = false;\n } else {\n child.removeAttribute('data-after-gap');\n }\n\n if (child.hasAttribute('gap')) {\n foundGap = true;\n afterGap = true;\n }\n }\n\n this.sectioned = foundGap;\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this.handleOutsideClick);\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('keydown', this.trackKeyboardModality, true);\n document.removeEventListener('pointerdown', this.trackPointerModality, true);\n window.removeEventListener('scroll', this.handleScroll, true);\n window.removeEventListener('resize', this.handleScroll);\n clearTimeout(this.closeTimer);\n clearTimeout(this.typeaheadTimer);\n this.itemObserver?.disconnect();\n this.itemObserver = undefined;\n this.unobserveSurfaceResize();\n this.updateAnchorAria(false);\n }\n\n /** Embedded flex menus (e.g. md-date-picker docked month/year lists). */\n private get inlineFill(): boolean {\n return this.el.classList.contains('md-menu--inline-fill');\n }\n\n /** Resolved `max-height` as a CSS length, or null when unset. */\n private get maxHeightValue(): string | null {\n if (this.maxHeight === undefined || this.maxHeight === null || this.maxHeight === '') {\n return null;\n }\n // A bare number — or a numeric string (attributes and `md-select`\n // forwarding both arrive as strings) — is treated as pixels; any other\n // CSS length (`'50vh'`, `'20rem'`, …) is passed through verbatim.\n const raw = String(this.maxHeight);\n return /^\\d+(\\.\\d+)?$/.test(raw) ? `${raw}px` : raw;\n }\n\n /** Every regular menu (not a submenu whose flyouts must not clip, not an inline-\n * fill embed) is bounded by the viewport and scrolls inside its scroll viewport\n * when it would overflow — with OR without an explicit max-height. This keeps a\n * pinned header and plain scrolling for every overflowing menu, not just capped\n * ones. */\n private get scrollCapped(): boolean {\n return !this.hasSubmenu && !this.inlineFill;\n }\n\n /** Inline-fill and every capped menu wrap their body in a scroll viewport. */\n private get useScrollViewport(): boolean {\n return this.inlineFill || this.scrollCapped;\n }\n\n private renderMenuBody() {\n return [\n <slot onSlotchange={this.handleSlotChange} />,\n this.emptyText ? (\n <span class=\"md-menu__empty\" part=\"empty-text\" role=\"status\">\n {this.emptyText}\n </span>\n ) : null,\n ];\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-menu': true,\n 'md-menu--open': this.open,\n 'md-menu--closing': this.closing,\n 'md-menu--quick': this.quick,\n [`md-menu--${this.variant}`]: true,\n [`md-menu--${this.layout}`]: this.variant !== 'baseline',\n 'md-menu--gap': this.useGap,\n 'md-menu--sectioned': this.sectioned,\n 'md-menu--empty': this.empty,\n 'md-menu--responsive': this.responsive,\n 'md-menu--has-submenu': this.hasSubmenu,\n 'md-menu--scroll': this.scrollCapped,\n }}\n aria-hidden={(!this.open || this.closing) ? 'true' : 'false'}\n // A closed menu stays in the DOM (opacity 0, never display:none, so the\n // open/close motion can play), which leaves focusable content — items, a\n // filterable select's search input — inside an aria-hidden subtree. That\n // is tab-reachable-but-invisible for keyboard users and fails axe\n // aria-hidden-focus (caught as a transient on story navigation, but the\n // closed steady state is just as affected). `inert` while hidden removes\n // the whole subtree from focus order and the a11y tree; it flips off in\n // the same render that clears aria-hidden, before any post-open focus.\n inert={!this.open || this.closing}\n >\n <div\n class=\"md-menu__surface\"\n part=\"surface\"\n // In provider/listbox mode the surface is just a container: it holds\n // the combobox (header slot) AND the listbox, so it must not itself be\n // a menu or a listbox. The host (md-select) renders the actual\n // role=\"listbox\" wrapper around the options in its own shadow root, so\n // aria-controls / aria-activedescendant IDREFs resolve.\n role={this.asListbox ? 'presentation' : 'menu'}\n id={this.menuId}\n aria-orientation={this.asListbox ? undefined : 'vertical'}\n aria-labelledby={this.asListbox ? undefined : this.anchor || undefined}\n >\n {/* Pinned header above the scroll area (e.g. a virtualized select's\n search field). Empty — and zero-cost — for every other menu. */}\n <slot name=\"header\" />\n {this.useScrollViewport ? (\n <div\n class=\"md-menu__scroll-shadow\"\n part=\"menu-viewport\"\n // Keyboard access to the scrolling option list (WCAG 2.1.1): the\n // active option's roving tabindex can sit on a PINNED HEADER item\n // (e.g. a select's \"Select all\") that lives outside this viewport,\n // leaving the scroll area with no focusable child. Make it focusable\n // — but ONLY in listbox mode. There the surface is role=\"presentation\"\n // (the owner renders the real listbox), so a focusable tabindex=\"0\"\n // viewport is harmless. In a plain role=\"menu\" the viewport would be a\n // role-less `div[tabindex]` OWNED by the menu, which axe flags as a\n // disallowed menu child (aria-required-children) — and a menu's own\n // menuitems (roving tabindex) already satisfy WCAG 2.1.1 without it.\n tabindex={this.asListbox ? '0' : undefined}\n // inline-fill is bounded by its flex parent; a capped menu is\n // bounded by max-height so the viewport scrolls within it. Clamp\n // to the viewport so an oversized cap can't run off-screen.\n style={\n this.inlineFill\n ? undefined // flexes to fill its parent; no fixed cap\n : {\n // Bound the scroll region to the smaller of any explicit\n // max-height, the space on the chosen side (--md-menu-avail-block,\n // set by positionMenu), and the viewport — so it scrolls\n // instead of overflowing, with or without max-height.\n maxBlockSize: this.maxHeightValue\n ? `min(${this.maxHeightValue}, var(--md-menu-avail-block, 100dvh), calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px)))`\n : `min(var(--md-menu-avail-block, 100dvh), calc(100dvh - 2 * var(--md-menu-viewport-margin, 8px)))`,\n }\n }\n >\n {this.renderMenuBody()}\n </div>\n ) : (\n this.renderMenuBody()\n )}\n </div>\n </Host>\n );\n }\n}\n","/* ═══════════════════════════════════════════════════════════\n md-menu-item\n Material Design 3 — Menus\n https://m3.material.io/components/menus/specs\n\n CSS custom properties:\n --md-menu-item-height Item height (default 48px)\n --md-menu-item-padding-inline Horizontal padding (default 12px)\n --md-menu-item-gap Gap between elements (default 12px)\n --md-menu-item-icon-size Leading/trailing icon (default 24px,\n 20px in the standard/vibrant variants)\n --md-menu-item-check-size Selection check/radio glyph (default 20px)\n\n Heights and all three icon sizes taper with the global `data-density`\n scale; the custom properties above opt out of that curve entirely.\n\n Parts:\n state-layer, leading-icon, content, headline,\n supporting-text, badge, trailing\n\n Slots:\n leading-icon, trailing-icon, (default)\n ═══════════════════════════════════════════════════════════ */\n\n/* ==========================================================\n 1. HOST\n ========================================================== */\n:host {\n display: flex;\n align-items: center;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n user-select: none;\n /* Global density: each `data-density` rung (0…-4) trims 4px off the row.\n density-scale is 0 by default, so the 48px default is unchanged.\n See packages/tokens/src/tokens.css §10-12. */\n min-height: var(--md-menu-item-height, calc(48px + var(--md-sys-density-scale, 0) * 4px));\n /* Leading/trailing icon size — one lever for the wrapper box AND the slotted\n glyph so they can never drift apart. Tapers 1px per rung (24 → 20px at -4)\n with an 18px floor, matching md-list-item's icon convention. */\n --_icon-size: var(--md-menu-item-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n /* Selection check/radio glyph — 20dp per M3, same 1px/rung taper, 16px floor. */\n --_check-size: var(--md-menu-item-check-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n padding: 0 var(--md-menu-item-padding-inline, var(--md-sys-spacing-inset-md, 12px));\n gap: var(--md-menu-item-gap, var(--md-sys-spacing-gap-md, 12px));\n color: var(--md-sys-color-on-surface, #1C1B1F);\n box-sizing: border-box;\n -webkit-tap-highlight-color: transparent;\n outline: none;\n /* M3 motion — quick tonal/selection fades plus an expressive shape morph\n so the corner radii ease (rather than snap) on hover / active / select. */\n transition:\n background-color var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n color var(--md-sys-motion-duration-short3, 150ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)),\n border-radius var(--md-sys-motion-duration-medium2, 300ms) var(--md-sys-motion-easing-emphasized-decelerate, cubic-bezier(0.05, 0.7, 0.1, 1));\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n}\n\n/* ==========================================================\n 2. STATES\n ========================================================== */\n.md-menu-item__state-layer {\n position: absolute;\n inset: 0;\n background-color: var(--md-sys-color-on-surface, #1C1B1F);\n opacity: 0;\n pointer-events: none;\n /* No transition by default: only pointer hover/active eases in (rule below).\n Keyboard focus (data-md-focused / focus-visible) is deliberately left\n transition-less so the tint snaps fully on and off. During fast ArrowUp/Down\n the focused row is a freshly-windowed node that starts at opacity 0, so a\n fade-in would restart every press and PULSE the focused element; and a\n fade-out would TRAIL lit rows behind the moving focus. Both are flicker. */\n}\n\n/* Inside a gapped group card the state layer sits `padding` in from a ROUNDED\n edge, so square corners left a wider band at the card's corners than along\n its sides. Concentric radius = card radius − that inset. */\n:host-context(md-menu-item-group[data-use-gap]) .md-menu-item__state-layer {\n border-radius: calc(var(--md-menu-group-shape, 12px) - var(--md-sys-spacing-inset-xs, 4px));\n}\n\n:host(:hover) .md-menu-item__state-layer { opacity: 0.08; }\n:host(:active) .md-menu-item__state-layer { opacity: 0.12; }\n:host(:focus-visible) .md-menu-item__state-layer,\n:host([data-md-focused]) .md-menu-item__state-layer { opacity: 0.12; }\n\n/* Soft ease-in for pointer hover/active only — keyboard focus stays instant. */\n:host(:hover) .md-menu-item__state-layer,\n:host(:active) .md-menu-item__state-layer {\n transition: opacity var(--md-sys-motion-duration-short2, 100ms) var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host(:focus-visible),\n:host([data-md-focused]) {\n outline: 3px solid var(--md-sys-color-secondary, #625B71);\n outline-offset: -3px;\n}\n\n/* ==========================================================\n 3. SELECTED STATE\n ========================================================== */\n\n/* Baseline */\n:host(.md-menu-item--selected) {\n background-color: var(--md-sys-color-secondary-container, #E8DEF8);\n}\n\n/* Vertical Standard */\n:host([data-variant=\"standard\"].md-menu-item--selected) {\n background-color: var(--md-sys-color-tertiary-container, #FFD8E4);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"]:active) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"]:first-child:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"]:last-child:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"][data-after-gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"][gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"standard\"][data-after-gap][gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n/* Vertical Vibrant */\n:host([data-variant=\"vibrant\"].md-menu-item--selected) {\n background-color: var(--md-sys-color-tertiary, #7D5260);\n color: var(--md-sys-color-on-tertiary, #FFFFFF);\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"]:active) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-medium, 12px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"]:first-child:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"]:last-child:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"][data-after-gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"][gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-extra-small, 4px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n:host([data-variant=\"vibrant\"][data-after-gap][gap]:hover) {\n border-start-start-radius: calc(var(--_rest-ss) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ss)));\n border-start-end-radius: calc(var(--_rest-se) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-se)));\n border-end-start-radius: calc(var(--_rest-es) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-es)));\n border-end-end-radius: calc(var(--_rest-ee) + var(--md-sys-shape-morph-enabled, 1) * (var(--md-sys-shape-corner-large, 16px) - var(--_rest-ee)));\n}\n\n/* ==========================================================\n 4. DISABLED STATE\n ========================================================== */\n:host(.md-menu-item--disabled) {\n cursor: default;\n opacity: 0.38;\n pointer-events: none;\n}\n\n/* ==========================================================\n 5. LEADING ICON\n ========================================================== */\n.md-menu-item__leading {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n width: var(--_icon-size);\n height: var(--_icon-size);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n.md-menu-item__leading ::slotted(*) {\n /* `!important` here is load-bearing, not a specificity hack. Icon glyphs are\n slotted light-DOM nodes carrying a DOCUMENT-tree class — Material Symbols\n ships `.material-symbols-outlined { font-size: 24px }`. Per CSS Scoping\n §3.3 the OUTER tree wins normal declarations against `::slotted()` no\n matter the specificity, and only `!important` flips that (important\n declarations resolve the other way, inner tree first). Without the flag the\n glyph stays welded at 24px while this wrapper tapers to 20px, so the icon\n overflows its box at every density rung. Width/height are uncontested by\n that stylesheet and stay normal, so authors can still override them. */\n font-size: var(--_icon-size) !important;\n width: var(--_icon-size);\n height: var(--_icon-size);\n color: inherit;\n}\n\n:host(.md-menu-item--selected) .md-menu-item__leading {\n color: inherit;\n}\n\n/* ==========================================================\n 6. CONTENT\n ========================================================== */\n.md-menu-item__content {\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-width: 0;\n}\n\n.md-menu-item__headline {\n font-family: var(--md-sys-typescale-body-large-font-family, Roboto, sans-serif);\n font-size: max(13px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-body-large-weight, 400);\n line-height: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.md-menu-item__supporting {\n font-family: var(--md-sys-typescale-body-medium-font-family, Roboto, sans-serif);\n font-size: max(11px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n color: var(--md-sys-color-on-surface-variant, #49454F);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ==========================================================\n 7. BADGE\n ========================================================== */\n.md-menu-item__badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n height: 20px;\n margin-inline-start: 12px;\n padding: 0 8px;\n border-radius: var(--md-sys-shape-corner-full, 9999px);\n background-color: var(--md-sys-color-tertiary-container, #FFD8E4);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n font-family: var(--md-sys-typescale-label-small-font-family, Roboto, sans-serif);\n font-size: var(--md-sys-typescale-label-small-size, 11px);\n font-weight: var(--md-sys-typescale-label-small-weight, 500);\n line-height: var(--md-sys-typescale-label-small-line-height, 16px);\n letter-spacing: var(--md-sys-typescale-label-small-tracking, 0.5px);\n white-space: nowrap;\n}\n\n/* ==========================================================\n 8. TRAILING\n ========================================================== */\n.md-menu-item__trailing {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n margin-inline-start: 8px;\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n.md-menu-item__trailing /* NOT badges. A custom property inside ::slotted() resolves in the SLOTTED\n element's own scope, and md-badge defines its own `--_icon-size` (10px, for\n its glyph). So `height: var(--_icon-size) !important` here picked up the\n BADGE's 10px instead of this component's icon size and, being !important,\n beat the badge's own 16px — squashing every badge slotted onto an icon\n button / avatar / menu item into a 10px blob. A badge is not an icon; it\n sizes itself. */\n::slotted(*:not(md-badge)) {\n /* `!important` for the same document-tree reason as the leading glyph above. */\n font-size: var(--_icon-size) !important;\n width: var(--_icon-size);\n height: var(--_icon-size);\n color: inherit;\n}\n\n.md-menu-item__trailing-text {\n font-family: var(--md-sys-typescale-label-small-font-family, Roboto, sans-serif);\n font-size: var(--md-sys-typescale-label-small-size, 11px);\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n/* Hide trailing when nothing is slotted and no trailing text */\n.md-menu-item__trailing:not(:has(::slotted(*), .md-menu-item__trailing-text)) {\n display: none;\n}\n\n:host(.md-menu-item--selected) .md-menu-item__trailing {\n color: inherit;\n}\n\n/* ==========================================================\n 9. CHECK INDICATOR (checkbox/radio)\n ========================================================== */\n.md-menu-item__check {\n display: flex;\n align-items: center;\n justify-content: center;\n /* Shadow-internal glyph, so no document-tree rule competes and no\n `!important` is needed — but it still has to taper with its row. */\n width: var(--_check-size);\n height: var(--_check-size);\n flex-shrink: 0;\n margin-inline-start: 8px;\n color: inherit;\n}\n\n.md-menu-item__check .material-symbols-outlined {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-weight: normal;\n font-style: normal;\n font-size: var(--_check-size);\n line-height: 1;\n letter-spacing: normal;\n text-transform: none;\n display: inline-block;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n font-feature-settings: 'liga';\n -webkit-font-smoothing: antialiased;\n}\n\n/* ==========================================================\n 10. DIVIDER\n ========================================================== */\n/* The line is flush: it separates two rows without displacing either.\n\n The previous `padding-bottom: 8px` came out of the item's OWN height —\n `min-block-size` is a border-box measurement, so a divider row rendered 40px\n of content where every other row got 48px, sitting 4px high against the\n list's rhythm with a correspondingly shorter hit area. The matching\n `margin-bottom: 8px` then left dead menu background under the line, which\n the row's hover surface could not reach.\n\n Rows that want breathing room use the separate `gap` prop, which the menu\n applies as a margin from the outside (md-menu.css, `::slotted([gap])`). */\n:host(.md-menu-item--divider) {\n padding-bottom: 0;\n margin-bottom: 0;\n}\n\n:host(.md-menu-item--divider)::after {\n content: '';\n position: absolute;\n bottom: 0;\n inset-inline: 0;\n height: 1px;\n background-color: var(--md-sys-color-outline-variant, #CAC4D0);\n}\n\n/* ==========================================================\n 11. VERTICAL MENU (STANDARD) VARIANT OVERRIDES\n ========================================================== */\n:host([data-variant=\"standard\"]) {\n /* Resting corners, named so the hover/press/selected rules below can blend\n BACK to them. Freezing is per-corner because an item's resting shape\n depends on its position: first/last child carry large outer corners while\n the rest are small, so a single blanket rest value would round the wrong\n corners when shape morph is switched off. See §13 in tokens.css. */\n --_rest-ss: var(--md-sys-shape-corner-small, 8px);\n --_rest-se: var(--md-sys-shape-corner-small, 8px);\n --_rest-es: var(--md-sys-shape-corner-small, 8px);\n --_rest-ee: var(--md-sys-shape-corner-small, 8px);\n color: var(--md-sys-color-on-surface, #1C1B1F);\n gap: 8px;\n border-radius: var(--md-sys-shape-corner-small, 8px);\n /* The vertical variants tighten icons to 20dp; retargeting the same lever\n keeps them on the density curve instead of freezing at 20px. */\n --_icon-size: var(--md-menu-item-icon-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n}\n\n:host([data-variant=\"standard\"]:first-child) {\n --_rest-ss: var(--md-sys-shape-corner-large, 16px);\n --_rest-se: var(--md-sys-shape-corner-large, 16px);\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host([data-variant=\"standard\"]:last-child) {\n --_rest-es: var(--md-sys-shape-corner-large, 16px);\n --_rest-ee: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host([data-variant=\"standard\"]) .md-menu-item__leading {\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n:host([data-variant=\"standard\"]) .md-menu-item__trailing,\n:host([data-variant=\"standard\"]) .md-menu-item__supporting,\n:host([data-variant=\"standard\"]) .md-menu-item__trailing-text {\n color: var(--md-sys-color-on-surface-variant, #49454F);\n}\n\n:host([data-variant=\"standard\"].md-menu-item--selected) .md-menu-item__leading,\n:host([data-variant=\"standard\"].md-menu-item--selected) .md-menu-item__trailing {\n color: inherit;\n}\n\n/* ==========================================================\n 12. VERTICAL MENU (VIBRANT) VARIANT OVERRIDES\n ========================================================== */\n:host([data-variant=\"vibrant\"]) {\n /* Resting corners, named so the hover/press/selected rules below can blend\n BACK to them. Freezing is per-corner because an item's resting shape\n depends on its position: first/last child carry large outer corners while\n the rest are small, so a single blanket rest value would round the wrong\n corners when shape morph is switched off. See §13 in tokens.css. */\n --_rest-ss: var(--md-sys-shape-corner-small, 8px);\n --_rest-se: var(--md-sys-shape-corner-small, 8px);\n --_rest-es: var(--md-sys-shape-corner-small, 8px);\n --_rest-ee: var(--md-sys-shape-corner-small, 8px);\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n gap: 8px;\n border-radius: var(--md-sys-shape-corner-small, 8px);\n --_icon-size: var(--md-menu-item-icon-size, max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px)));\n}\n\n:host([data-variant=\"vibrant\"]:first-child) {\n --_rest-ss: var(--md-sys-shape-corner-large, 16px);\n --_rest-se: var(--md-sys-shape-corner-large, 16px);\n border-start-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-start-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host([data-variant=\"vibrant\"]:last-child) {\n --_rest-es: var(--md-sys-shape-corner-large, 16px);\n --_rest-ee: var(--md-sys-shape-corner-large, 16px);\n border-end-start-radius: var(--md-sys-shape-corner-large, 16px);\n border-end-end-radius: var(--md-sys-shape-corner-large, 16px);\n}\n\n:host([data-variant=\"vibrant\"]) .md-menu-item__leading {\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n}\n\n:host([data-variant=\"vibrant\"]) .md-menu-item__trailing,\n:host([data-variant=\"vibrant\"]) .md-menu-item__supporting,\n:host([data-variant=\"vibrant\"]) .md-menu-item__trailing-text {\n color: var(--md-sys-color-on-tertiary-container, #31111D);\n}\n\n:host([data-variant=\"vibrant\"].md-menu-item--selected) .md-menu-item__leading,\n:host([data-variant=\"vibrant\"].md-menu-item--selected) .md-menu-item__trailing {\n color: inherit;\n}\n\n:host([data-variant=\"vibrant\"]) .md-menu-item__state-layer {\n background-color: var(--md-sys-color-on-tertiary-container, #31111D);\n}\n\n/* ==========================================================\n DENSITY (local override)\n Maps the local `density` prop onto the same --md-sys-density-scale signal a\n global `data-density` ancestor sets. Declared on :host, so a local rung wins\n over the inherited global one. Every density-sensitive value in this file\n derives from that single signal by calc — never add a fixed per-rung ladder.\n ========================================================== */\n:host([density='-1']) { --md-sys-density-scale: -1; }\n:host([density='-2']) { --md-sys-density-scale: -2; }\n:host([density='-3']) { --md-sys-density-scale: -3; }\n:host([density='-4']) { --md-sys-density-scale: -4; }\n","import { Component, Host, h, Prop, Event, EventEmitter, Element, State } from '@stencil/core';\nimport { MenuElement, SelectableElement } from '../../utils/types';\nimport { triggerRipple } from '../../utils/ripple';\n\n@Component({ tag: 'md-menu-item', styleUrl: 'md-menu-item.css', shadow: true })\nexport class MdMenuItem {\n @Element() el!: HTMLElement;\n\n /** Primary label text. */\n @Prop() headline: string = '';\n /** Secondary descriptive text below the headline. */\n @Prop({ attribute: 'supporting-text' }) supportingText: string = '';\n /** Trailing text (e.g. keyboard shortcut). */\n @Prop({ attribute: 'trailing-text' }) trailingText: string = '';\n /** Whether the item is disabled. */\n @Prop({ reflect: true }) disabled: boolean = false;\n /** Whether the item is currently selected. */\n @Prop({ mutable: true, reflect: true }) selected: boolean = false;\n /** Mixed/partial state for a `checkbox` item — renders a dash in the check\n * slot instead of a tick and exposes `aria-checked=\"mixed\"`. Used for a\n * \"select all\" affordance where only some children are selected. Ignored for\n * `button`/`radio` types and when `selected` is true. */\n @Prop({ mutable: true, reflect: true }) indeterminate: boolean = false;\n /** Prevent the parent menu from closing when this item is clicked. */\n @Prop({ attribute: 'keep-open' }) keepOpen: boolean = false;\n /** Render a divider line below this item. */\n @Prop({ reflect: true }) divider: boolean = false;\n /** Render a gap (extra space) below this item — an alternative separator to divider. */\n @Prop({ reflect: true }) gap: boolean = false;\n /** Small badge label (e.g. \"New\") displayed before the trailing area. */\n @Prop() badge: string = '';\n /** Type of item: 'button' (default action), 'checkbox' (toggle), or 'radio' (single-select within group). */\n @Prop() type: 'button' | 'checkbox' | 'radio' = 'button';\n /** Position of the selection checkmark indicator. */\n @Prop({ attribute: 'check-position', reflect: true }) checkPosition: 'start' | 'end' = 'end';\n /**\n * ARIA presentation. `'menuitem'` (default) exposes the item with the menu\n * role family (`menuitem` / `menuitemradio` / `menuitemcheckbox`, state via\n * `aria-checked`). `'option'` exposes it as a listbox option (`role=\"option\"`,\n * state via `aria-selected`) — used by `md-select` so the popup is a proper\n * WAI-ARIA combobox/listbox rather than a menu.\n */\n @Prop({ reflect: true }) presentation: 'menuitem' | 'option' = 'menuitem';\n\n /**\n * Override the computed ARIA role. Used when a checkbox/radio item is NOT inside\n * a menu — e.g. a \"select all\" toggle in a listbox popup, which is semantically a\n * `checkbox` (keeps `aria-checked`, drops the menu-only required-parent). Empty =\n * the default menuitem/option role family.\n */\n @Prop({ attribute: 'role-override' }) roleOverride: string = '';\n\n /**\n * Local density rung. Drives the same `--md-sys-density-scale` signal that a\n * global `data-density` ancestor sets, so a local value simply overrides the\n * inherited one. 0 = default, -4 = ultra-compact.\n */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fires when the item is activated. */\n @Event() mdClick: EventEmitter<void>;\n\n @State() private hasLeadingIcon = false;\n @State() private hasTrailingIcon = false;\n\n componentWillLoad() {\n this.hasLeadingIcon = !!this.el.querySelector('[slot=\"leading-icon\"]');\n this.hasTrailingIcon = !!this.el.querySelector('[slot=\"trailing-icon\"]');\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.disabled) { e.preventDefault(); e.stopPropagation(); return; }\n\n if (this.type === 'checkbox') {\n this.selected = !this.selected;\n } else if (this.type === 'radio') {\n this.selected = true;\n this.deselectSiblingRadios();\n }\n\n this.mdClick.emit();\n\n if (!this.keepOpen) {\n let menu = this.el.closest('md-menu') as HTMLElement | null;\n let root = menu;\n while (menu) {\n const parent = menu.parentElement?.closest('md-menu') as HTMLElement | null;\n if (parent) { root = parent; menu = parent; } else { break; }\n }\n if (root) {\n const rootMenu = root as MenuElement;\n if (rootMenu.anchor) {\n document.getElementById(rootMenu.anchor)?.focus();\n }\n setTimeout(() => rootMenu.close?.(), 150);\n }\n }\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n if (!this.disabled) triggerRipple(this.el);\n this.el.click();\n } else if (e.key === ' ') {\n e.preventDefault();\n if (this.disabled) return;\n\n triggerRipple(this.el);\n\n if (this.type === 'checkbox') {\n this.selected = !this.selected;\n this.mdClick.emit();\n } else if (this.type === 'radio') {\n this.selected = true;\n this.deselectSiblingRadios();\n this.mdClick.emit();\n } else {\n this.el.click();\n }\n }\n };\n\n private deselectSiblingRadios() {\n if (this.type !== 'radio') return;\n const group = this.el.closest('md-menu-item-group') || this.el.closest('md-menu');\n if (!group) return;\n const siblings = Array.from(group.querySelectorAll('md-menu-item')) as unknown as SelectableElement[];\n for (const sibling of siblings) {\n if (sibling !== this.el && sibling.type === 'radio' && sibling.selected) {\n sibling.selected = false;\n }\n }\n }\n\n private get role(): string {\n if (this.roleOverride) return this.roleOverride;\n if (this.presentation === 'option') return 'option';\n if (this.type === 'checkbox') return 'menuitemcheckbox';\n if (this.type === 'radio') return 'menuitemradio';\n return 'menuitem';\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-menu-item': true,\n 'md-menu-item--selected': this.selected,\n 'md-menu-item--disabled': this.disabled,\n 'md-menu-item--divider': this.divider,\n 'md-menu-item--gap': this.gap,\n }}\n role={this.role}\n aria-disabled={this.disabled ? 'true' : 'false'}\n aria-selected={this.presentation === 'option' ? String(this.selected) : undefined}\n aria-checked={\n this.presentation !== 'option' && this.type !== 'button'\n ? this.indeterminate && !this.selected\n ? 'mixed'\n : String(this.selected)\n : undefined\n }\n tabindex=\"-1\"\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n >\n <md-ripple disabled={this.disabled}></md-ripple>\n <span class=\"md-menu-item__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n {this.type !== 'button' && this.checkPosition === 'start' && (\n <span class=\"md-menu-item__check\" aria-hidden=\"true\">\n <span class=\"material-symbols-outlined\">\n {this.selected ? 'check' : this.indeterminate ? 'remove' : ''}\n </span>\n </span>\n )}\n\n {this.hasLeadingIcon && (\n <span class=\"md-menu-item__leading\" part=\"leading-icon\" aria-hidden=\"true\">\n <slot name=\"leading-icon\"></slot>\n </span>\n )}\n\n <span class=\"md-menu-item__content\" part=\"content\">\n <span class=\"md-menu-item__headline\" part=\"headline\">{this.headline}</span>\n {this.supportingText && (\n <span class=\"md-menu-item__supporting\" part=\"supporting-text\">{this.supportingText}</span>\n )}\n </span>\n\n {this.badge && (\n <span class=\"md-menu-item__badge\" part=\"badge\">{this.badge}</span>\n )}\n\n {(this.hasTrailingIcon || this.trailingText) && (\n <span class=\"md-menu-item__trailing\" part=\"trailing\">\n <slot name=\"trailing-icon\">\n {this.trailingText && (\n <span class=\"md-menu-item__trailing-text\">{this.trailingText}</span>\n )}\n </slot>\n </span>\n )}\n\n {this.type !== 'button' && this.checkPosition === 'end' && (\n <span class=\"md-menu-item__check\" aria-hidden=\"true\">\n <span class=\"material-symbols-outlined\">\n {this.selected ? 'check' : this.indeterminate ? 'remove' : ''}\n </span>\n </span>\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|