@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["mdSearchCss","MdSearch","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","variant","layout","triggerIcon","triggerFor","fullWidth","value","placeholder","open","disabled","elevation","leadingIcon","showClearButton","voiceSearch","escapeCloses","dismissOnOutsideClick","scrollShadow","maxBlockSize","inputAriaLabel","initialFocus","announceResults","resultsLabel","noResultsLabel","loading","debounce","throttle","loadingLabel","density","focused","hasSlottedLeading","hasSlottedTrailing","hasSlottedTrigger","resultsStatus","barExpanded","panelVisible","showFocusRing","listening","loadingMorphMounted","loadingMorphIn","keyboardModality","previousFocus","valueOnFocus","pendingFullScreenReveal","pendingSearchValue","lastEmittedSearch","wiredTrigger","handleExternalTriggerClick","e","stopPropagation","handleTriggerActivate","handleTriggerClick","handleTriggerKeyDown","key","preventDefault","handleBarClick","target","closest","input","focus","handleLeadingClick","slotted","interactiveDefault","mdLeadingIconClick","emit","handleTrailingClick","path","composedPath","nodes","length","isOwnAffordance","some","n","cl","classList","contains","assigned","trailingSlotEl","assignedElements","hitSlotted","el","mdTrailingIconClick","handleClearClick","mdInput","flushSearch","mdClear","handleVoiceClick","stopVoice","startVoice","handleVoiceResult","event","transcript","isFinal","results","i","replace","scheduleSearch","mdVoice","final","handleVoiceEnd","recognition","undefined","handleInput","next","trackKeyboardModality","trackPointerModality","handleInputFocus","handleInputBlur","mdChange","handleInputKeyDown","mdSubmit","show","close","toggle","focusInput","connectedCallback","document","addEventListener","componentWillLoad","trim","updateResultsStatus","componentDidLoad","wireExternalTrigger","shadow","shadowRoot","leadingSlot","querySelector","trailingSlot","resultsSlot","triggerSlot","measureRippleExtend","observeHostResize","applyOpenSideEffects","onExternalTriggerChange","disconnectedCallback","unwireExternalTrigger","clearCloseTimer","cancelReveal","clearSearchTimers","clearLoadingMorphTimers","removeOutsideClickHandler","resizeObserver","disconnect","removeEventListener","body","style","removeProperty","effectiveTrigger","hasExternalTrigger","trigger","Boolean","triggerElement","usesIconTrigger","resolveExternalTrigger","sel","console","warn","syncExternalTriggerAria","removeAttribute","t","setAttribute","String","showBar","ripple","rippleEl","window","bar","barWidth","getBoundingClientRect","width","delta","innerWidth","setProperty","probe","insetProbeEl","inset","Number","isFinite","ResizeObserver","observe","onOpenChange","newVal","oldVal","mdOpen","mdClose","closeTimer","setTimeout","finishCloseSideEffects","active","activeElement","inSearch","PANEL_CLOSE_MS","onLoadingChange","updateLoadingMorph","requestAnimationFrame","loadingMorphInRaf","loadingMorphTimer","MORPH_MS","clearTimeout","cancelAnimationFrame","componentDidRender","revealRaf","scrollbarWidth","documentElement","clientWidth","paddingInlineEnd","overflow","attachOutsideClickHandler","focusInitialTarget","resolveInitialFocusTarget","preventScroll","leadingFocusTarget","focusableSel","getAttribute","matches","inner","builtin","outsideClickHandler","includes","getSpeechRecognitionCtor","w","SpeechRecognition","webkitSpeechRecognition","isVoiceSupported","resolveVoiceLang","lang","startVoiceInternal","stop","Ctor","abort","interimResults","continuous","maxAlternatives","onresult","onerror","onend","start","debounceMs","Math","max","throttleMs","searchDebounceTimer","searchMaxWaitTimer","normalized","mdSearch","handleWindowKeyDown","moveResultFocus","focusables","collectFocusables","first","last","shiftKey","root","inShadow","Array","from","querySelectorAll","inLight","filter","node","hasAttribute","tabindex","countResults","containers","itemSelector","items","Set","add","forEach","size","resultItems","current","findIndex","it","min","focusResultItem","item","count","shouldShowVisibleEmptyState","shouldShowResultsChrome","isPanelRevealed","effectiveLabel","resolveOpenLeadingIcon","openLeadingIcon","renderTrigger","h","class","part","name","icon","onClick","onKeyDown","renderLeading","showCloseButton","ariaLabel","openGlyph","type","tabIndex","renderClearButton","renderVoiceButton","renderTrailing","showClear","showMorph","showVoice","LazyLoadingIndicator","exportparts","label","render","isFullScreen","hostStyle","Host","Object","keys","ref","role","autocomplete","spellcheck","onInput","onFocus","onBlur","id","hidden"],"sources":["src/components/md-search/md-search.css?tag=md-search&encapsulation=shadow","src/components/md-search/md-search.tsx"],"sourcesContent":["/* ==========================================================\n md-search — Material Design 3 Search\n Spec: https://m3.material.io/components/search/specs\n\n Implements both M3 axes:\n - variant: contained (Expressive default) | divided (baseline)\n - layout : full-screen (modal) | docked (anchored popup)\n\n PUBLIC CSS CUSTOM PROPERTIES (override per-instance):\n --md-search-container-color Bar background (#ECE6F0 / surface-container-high)\n --md-search-contained-background-color\n Contained full-screen surface (#F7F2FA)\n --md-search-container-elevation Custom bar shadow — overrides the\n `elevation` prop level (default none)\n --md-search-leading-icon-color Leading / open-back icon (#1D1B20 / on-surface)\n --md-search-trailing-icon-color Trailing + clear icons (#49454F / on-surface-variant)\n --md-search-icon-color Alias for trailing icon colour (legacy)\n --md-search-loading-color In-bar loading indicator shape colour\n (#6750A4 / primary)\n --md-search-container-shape Bar border-radius\n --md-search-container-height Bar block-size — docked / contained (56dp)\n --md-search-divided-fullscreen-bar-height\n Divided × full-screen header height (72dp)\n --md-search-icon-button-size Leading / trailing icon tap target (48dp)\n --md-search-contained-docked-panel-offset\n Contained docked bar ↔ results gap (4dp)\n --md-search-leading-icon-label-gap Tap target → label gap (4dp)\n --md-search-trailing-icon-label-gap Label → tap target gap (4dp)\n --md-search-container-min-inline-size Bar minimum width (360dp)\n --md-search-container-max-inline-size Bar maximum width (720dp)\n --md-search-container-padding-inline Extra inline padding on the bar (0dp)\n --md-search-container-padding-inline-focused Inline padding on the bar when focused / open\n --md-search-leading-padding-inline Space from the bar's leading edge\n to the leading icon tap target (4dp)\n --md-search-trailing-padding-inline Space from the bar's trailing edge\n to the trailing icon tap target (4dp)\n --md-search-input-color Input text colour\n --md-search-input-font-family Input typescale font (body-large)\n --md-search-input-font-size Input typescale size (16dp)\n --md-search-input-line-height Input typescale line height (24dp)\n --md-search-input-font-weight Input typescale weight (400)\n --md-search-input-letter-spacing Input typescale tracking (0.5dp)\n --md-search-placeholder-color Placeholder / supporting text colour\n --md-search-state-layer-color Hover/press wash (#1D1B20 / on-surface)\n --md-search-hover-state-layer-opacity Hover state layer opacity (0.08)\n --md-search-pressed-state-layer-opacity Pressed state layer opacity (0.1)\n --md-search-focus-indicator-color Focus ring colour (#625B71 / secondary)\n --md-search-focus-indicator-thickness Focus ring thickness (3dp)\n --md-search-focus-indicator-offset Focus ring offset (2dp)\n --md-search-avatar-size Avatar diameter when slotted (40dp)\n --md-search-panel-min-block-size Docked panel floor — 0 = shrink to\n content; raise for a taller empty drawer\n --md-search-panel-max-block-size Docked panel maximum height —\n compact drawer default min(400px, 60vh)\n --md-search-max-block-size Open surface max height — full-screen\n overlay cap or docked panel cap\n (unset = layout default)\n --md-search-docked-panel-shape Contained docked results card radius\n (16dp / shape-corner-large)\n --md-search-panel-offset Docked panel gap fallback (divided / generic 4dp)\n --md-search-bar-fullscreen-color Bar background in full-screen open\n --md-search-fullscreen-results-color Opaque results surface in full-screen\n open (default: surface-container-low)\n --md-search-divider-color Hairline colour (divided variant)\n --md-search-divider-thickness Hairline thickness (1px)\n --md-search-fullscreen-bar-offset-block-start\n Contained full-screen: bar inset\n from viewport block-start (16dp)\n --md-search-fullscreen-bar-offset-inline\n Contained full-screen: bar inset from\n viewport inline edges (8dp)\n --md-search-fullscreen-bar-panel-gap Contained full-screen: gap between\n the pill bar and the results panel\n --md-search-panel-padding-block-start Full-screen panel padding above\n slotted results (0dp)\n --md-search-empty-color No-results message colour\n --md-search-empty-padding-block No-results vertical padding\n --md-search-empty-padding-inline No-results horizontal padding\n --md-search-expand-inset Docked/inline bar RESTING side\n margin (24dp). The bar springs to\n the focused margin on focus/open,\n evenly left + right. Full-screen\n ignores this (pure fade)\n --md-search-expand-focused-inset Docked/inline bar FOCUSED side\n margin (12dp). Set equal to the\n resting inset to disable the motion.\n Set BOTH insets to 0 (or use the\n `full-width` prop) for an edge-to-edge\n bar + drawer with no side gutters\n --md-search-expand-duration Springy expand duration (medium4 / 400ms)\n --md-search-expand-easing Springy expand easing — back-out\n with overshoot + snap-back\n (cubic-bezier(0.34, 1.56, 0.64, 1))\n --md-search-panel-motion-duration Docked panel + bar transition\n duration (medium2). The bar\n contraction delay on close is a JS\n constant (MdSearch.PANEL_CLOSE_MS),\n not this property\n --md-search-fullscreen-expand-duration Full-screen modal enter duration\n (medium2 / 300ms — matches md-dialog)\n --md-search-fullscreen-expand-easing Full-screen enter easing\n (standard — matches md-dialog)\n --md-search-fullscreen-collapse-duration Full-screen exit duration\n (medium2 / 300ms; synced to JS)\n --md-search-fullscreen-collapse-easing Full-screen exit easing\n (standard — matches md-dialog)\n\n ICON MORPH:\n The leading icon morphs from `search` (resting) to a directional\n close glyph (open) whenever the bar is selected, in BOTH layouts.\n The open glyph is variant-aware: `contained` (Expressive) uses\n `chevron_left` so the caret echoes the pill silhouette, while\n `divided` (baseline) uses the spec-canonical `arrow_back`. The two\n glyphs are stacked at the same centred slot inside a single button\n and cross-fade with a rotation + scale spring so the change reads\n as a single icon moving rather than two icons swapping. Override\n either glyph via the `leading-icon` and `open-leading-icon` props.\n\n The trailing loading indicator and clear-× share a single fixed-size\n box and cross-fade (opacity + scale + rotate) in BOTH directions as\n `loading` toggles, so the swap morphs expressively without shifting\n the trailing cluster's width.\n\n NOTE: Slotted results default to transparent list / list-item\n backgrounds so rows sit flush on the search surface (panel or bar\n chrome) instead of painting a nested M3 `surface` bay. Re-tint via\n `--md-list-container-color` / `--md-list-item-container-color` on the\n slotted `<md-list>` when you need a distinct results chassis.\n\n CSS PARTS:\n bar Search bar container\n status Visually-hidden polite live region (result announcements)\n state-layer Hover / focus / press overlay on the bar\n leading Leading icon container\n input Native <input>\n trailing Trailing slot container (icon buttons / avatar)\n clear-button Built-in clear (×) button\n voice-button Built-in voice-search mic button (when `voice-search`\n is on and the Web Speech API is available)\n loading In-bar loading indicator (shown while `loading`)\n loading-shape Morphing shape inside the loading indicator\n panel Results panel — full-viewport surface (full-screen) /\n anchored popup (docked)\n panel-body Flex region that sizes the scroll viewport\n empty Visible no-results message (open + query + zero rows)\n divider Hairline between bar and panel (visible in `divided`)\n results-viewport Inner scroll viewport (md-scroll-shadow)\n results-shadow-block-start Top scroll-shadow gradient\n results-shadow-block-end Bottom scroll-shadow gradient\n trigger Icon-button entry point (full-screen closed state)\n trigger-button Built-in search icon button (when trigger slot empty)\n\n SLOTS:\n leading Replace the leading icon\n trailing Trailing icon buttons + avatar (any combination)\n results Suggestions / results list\n trigger Replace the built-in search icon trigger (full-screen)\n loader Replace the in-bar loading indicator shown while `loading`\n ========================================================== */\n\n:host {\n /* ── Public API ─────────────────────────────────────────── */\n --_container-color: var(\n --md-search-container-color,\n var(--md-sys-color-surface-container-high, #ECE6F0)\n );\n --_container-shape: var(\n --md-search-container-shape,\n var(--md-sys-shape-corner-full, 9999px)\n );\n /* Bar height follows global density (0…-4, 4px/rung, floor 40px); 56px at\n density 0. The pill radius + panel offsets are all derived from this, so\n the whole bar tightens coherently. */\n --_container-height: var(--md-search-container-height, max(40px, calc(56px + var(--md-sys-density-scale, 0) * 4px)));\n /* The resting bar's VISIBLE corner radius: `--_container-shape` is a full\n pill (9999px) by default, which the browser clamps to half the bar height.\n Reproduce that clamp here so the divided × docked open card can round its\n outer corners by the same amount instead of clamping against the much\n larger bar+panel box (which would look far rounder). */\n --_resting-corner-shape: min(\n var(--_container-shape),\n calc(var(--_container-height) / 2)\n );\n /* Docked results panel corner radius. Contained × docked is a standalone\n rounded card below the bar; this radius is clipped (panel overflow:hidden)\n so the scrolling viewport, scrollbar and slotted surface stay inside the\n rounded corners on ALL sides. Divided × docked keeps its own unified-card\n radius (`--_resting-corner-shape`) — see the divided-docked-open rules. */\n --_docked-panel-shape: var(--md-search-docked-panel-shape, var(--md-sys-shape-corner-large, 16px));\n /* Full-screen header follows global density (72px at 0, floor 48px) like the\n resting bar; contained full-screen already uses the density-responsive\n --_container-height. */\n --_divided-fullscreen-bar-height: var(--md-search-divided-fullscreen-bar-height, max(48px, calc(72px + var(--md-sys-density-scale, 0) * 4px)));\n /* M3 search-bar layout: icons live inside 48dp tap targets; the gap from a\n tap target to the label is 4dp (the 48dp target absorbs the rest, landing\n the visible glyph ~16dp from the bar edge and the label ~56dp in). */\n --_leading-icon-label-gap: var(--md-search-leading-icon-label-gap, 4px);\n --_trailing-icon-label-gap: var(--md-search-trailing-icon-label-gap, 4px);\n /* Leading (back) + trailing tap targets shrink with global density (48px at\n 0, floor 32px to keep room around the 24px glyph) so they don't floor the\n tightened bar. */\n --_icon-button-size: var(--md-search-icon-button-size, max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px)));\n --_container-min-inline-size: var(--md-search-container-min-inline-size, 360px);\n --_container-max-inline-size: var(--md-search-container-max-inline-size, 720px);\n /* Padding lives on the leading / trailing wrappers so the icons stay at a\n stable 16dp from the bar's edges regardless of focus state. The bar\n itself has no inline padding by default; consumers can still inject\n extra inline padding on the bar via these props. */\n --_container-padding-inline: var(--md-search-container-padding-inline, 0px);\n --_container-padding-inline-focused: var(\n --md-search-container-padding-inline-focused,\n var(--_container-padding-inline)\n );\n\n /* Stable inline padding inside the leading / trailing clusters: the space\n from the bar edge to the icon's 48dp tap target (4dp per M3). The tap\n target centres a 24dp glyph, so the visible icon lands ~16dp from the\n bar edge and the trailing cluster mirrors it. As the bar's outer edge\n expands during the expressive focus motion, the icon rides along. */\n --_leading-padding-inline: var(--md-search-leading-padding-inline, 4px);\n --_trailing-padding-inline: var(--md-search-trailing-padding-inline, 8px);\n\n /* Unified M3 Expressive expansion (docked / inline bars ONLY).\n\n The single, consistent expansion mechanism across ALL docked/inline bars\n — contained AND divided alike: the bar rests at a 24dp side margin and\n springs to a 12dp side margin on focus / open, symmetrically (even\n left + right). Both edges move inward-to-outward by exactly the\n 24 → 12 = 12dp delta, so the container grows evenly on both sides. The\n default easing is a back-out curve that briefly overshoots the target\n width and snaps back, giving the motion a slick, springy feel.\n\n Full-screen layout does NOT use this margin expansion — its open/close\n is a pure opacity fade (both insets are zeroed for full-screen below),\n so only docked/inline bars expand.\n\n Duration drives BOTH the bar's springy expand AND the ripple wave's\n grow (the wave is synced to this token via `--md-ripple-grow-duration`\n further down in this file). The two HAVE to share a duration: if the\n wave is shorter, it finishes before the bar settles and looks too\n snappy; if the wave is longer, it lags during the bar's overshoot\n and exposes a coverage gap on whichever side the bar grew. medium4\n (400ms) gives the gesture a deliberate, expressive feel without\n drifting into the ceremonial long-tier durations.\n\n `--md-search-expand-inset` sets the RESTING margin (24dp default) and\n `--md-search-expand-focused-inset` the FOCUSED margin (12dp default).\n The per-side travel is `resting - focused` (12dp by default); its\n concrete length is resolved in JS (host-anchored probe) before being\n forwarded to the ripple — see `measureRippleExtend()` and the ripple\n note below. Set both equal (e.g. `--md-search-expand-inset: 0` and\n `--md-search-expand-focused-inset: 0`) to disable the motion. */\n --_expand-inset: var(--md-search-expand-inset, 24px);\n --_expand-inset-focused: var(--md-search-expand-focused-inset, 12px);\n --_expand-duration: var(\n --md-search-expand-duration,\n var(--md-sys-motion-duration-medium4, 400ms)\n );\n /* Back-out spring curve: overshoots ~17 % then settles. Pure CSS, no\n web-animations API needed. */\n --_expand-easing: var(\n --md-search-expand-easing,\n cubic-bezier(0.34, 1.56, 0.64, 1)\n );\n\n --_input-color: var(\n --md-search-input-color,\n var(--md-sys-color-on-surface, #1D1B20)\n );\n /* M3 \"Search view header input / supporting text\" — body-large. */\n --_input-font-family: var(\n --md-search-input-font-family,\n var(--md-sys-typescale-body-large-font-family, Roboto, sans-serif)\n );\n --_input-font-size: var(\n --md-search-input-font-size,\n max(13px, calc(16px + var(--md-sys-density-scale, 0) * 0.5px))\n );\n --_input-line-height: var(\n --md-search-input-line-height,\n var(--md-sys-typescale-body-large-line-height, 24px)\n );\n --_input-font-weight: var(\n --md-search-input-font-weight,\n var(--md-sys-typescale-body-large-font-weight, 400)\n );\n --_input-letter-spacing: var(\n --md-search-input-letter-spacing,\n var(--md-sys-typescale-body-large-letter-spacing, 0.5px)\n );\n --_placeholder-color: var(\n --md-search-placeholder-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n );\n --_leading-icon-color: var(\n --md-search-leading-icon-color,\n var(--md-sys-color-on-surface, #1D1B20)\n );\n --_trailing-icon-color: var(\n --md-search-trailing-icon-color,\n var(\n --md-search-icon-color,\n var(--md-sys-color-on-surface-variant, #49454F)\n )\n );\n --_icon-size: var(--md-search-icon-size, max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px)));\n --_loading-color: var(\n --md-search-loading-color,\n var(--md-sys-color-primary, #6750A4)\n );\n /* Inline mirror for the directional open glyph (chevron_left / arrow_back).\n 1 in LTR, -1 in RTL so the \"back\" glyph points the correct way. Baked into\n the glyph's transform in BOTH resting and open states via the var, so the\n mirror never depends on a separate (fragile) RTL open-state selector. */\n --_open-glyph-mirror: 1;\n --_contained-background-color: var(\n --md-search-contained-background-color,\n var(--md-sys-color-surface-container-low, #F7F2FA)\n );\n /* Resting bar shadow. Default is no elevation (M3 default). Use the\n `elevation` prop (0–5) to apply an `--md-sys-elevation-{n}` tier, or set\n `--md-search-container-elevation` directly for a fully custom shadow —\n the custom property wins over the prop-driven level below.\n\n Level 0 resolves to a transparent zero-shadow (NOT the `none` keyword) so\n it can be safely composed into the focus-ring box-shadow list — a bare\n `none` in a comma-separated shadow list invalidates the whole rule and\n would drop the focus indicator. */\n --_container-elevation-level: 0px 0px 0px 0px transparent;\n --_container-elevation: var(\n --md-search-container-elevation,\n var(--_container-elevation-level)\n );\n\n --_state-layer-color: var(\n --md-search-state-layer-color,\n var(--md-sys-color-on-surface, #1D1B20)\n );\n --_hover-state-layer-opacity: var(\n --md-search-hover-state-layer-opacity,\n var(--md-sys-state-hover-state-layer-opacity, 0.08)\n );\n --_pressed-state-layer-opacity: var(\n --md-search-pressed-state-layer-opacity,\n 0.1\n );\n --_focus-indicator-color: var(\n --md-search-focus-indicator-color,\n var(--md-sys-color-secondary, #625B71)\n );\n --_focus-indicator-thickness: var(--md-search-focus-indicator-thickness, 3px);\n --_focus-indicator-offset: var(--md-search-focus-indicator-offset, 2px);\n\n --_avatar-size: var(--md-search-avatar-size, 40px);\n\n /* Docked results drawer block budget. Default min is 0 so the open panel\n shrinks to fit few rows; authors can raise `--md-search-panel-min-block-size`\n for a taller empty bay. Max defaults to a compact drawer (~5–6 rows);\n results beyond it scroll inside the rounded panel (via md-scroll-shadow).\n Raise `--md-search-panel-max-block-size` or `--md-search-max-block-size`\n for a taller drawer. */\n --_panel-min-block-size: var(--md-search-panel-min-block-size, 0px);\n --_panel-max-block-size: var(--md-search-panel-max-block-size, min(400px, 60vh));\n /* Optional cap on the open surface — full-screen host or docked panel.\n Deliberately NO fallback value: when `--md-search-max-block-size` is unset\n this resolves to the guaranteed-invalid value, so consumers fall through to\n their own default (docked panel → `--_panel-max-block-size` 66vh; full-screen\n host → the property's initial `none`). A literal `none` here would be a SET\n value and would swallow the docked panel's `var(..., --_panel-max-block-size)`\n fallback, leaving the docked panel uncapped and unable to scroll. */\n --_max-block-size: var(--md-search-max-block-size);\n /* Clear the bar's keyboard focus ring (offset + thickness = 5px by default)\n plus a small gap, so the docked results panel doesn't cover the ring's\n rounded bottom edge. */\n --_panel-offset: var(\n --md-search-panel-offset,\n calc(var(--_focus-indicator-offset) + var(--_focus-indicator-thickness) + 3px)\n );\n\n --_bar-fullscreen-color: var(\n --md-search-bar-fullscreen-color,\n var(--md-sys-color-surface-container-low, #F7F2FA)\n );\n\n /* Opaque results surface for the full-screen panel. The panel fills the\n whole viewport (inset:0) as this surface and fades in — there is no scrim.\n It must stay opaque so the page never shows through behind the results.\n Both contained and divided full-screen use surface-container-low here. */\n --_fullscreen-results-color: var(\n --md-search-fullscreen-results-color,\n var(--md-sys-color-surface-container-low, #F7F2FA)\n );\n\n --_divider-color: var(\n --md-search-divider-color,\n var(--md-sys-color-outline, #79747E)\n );\n --_divider-thickness: var(--md-search-divider-thickness, 1px);\n\n /* Contained × full-screen: floating pill bar insets + panel anchor. */\n --_fullscreen-bar-offset-block-start: var(\n --md-search-fullscreen-bar-offset-block-start,\n max(16px, env(safe-area-inset-block-start, 0px))\n );\n --_fullscreen-bar-offset-inline: var(\n --md-search-fullscreen-bar-offset-inline,\n max(0px, env(safe-area-inset-inline-start, 0px))\n );\n --_fullscreen-bar-panel-gap: var(--md-search-fullscreen-bar-panel-gap, 0px);\n --_panel-padding-block-start: var(--md-search-panel-padding-block-start, 0px);\n\n /* The public `--md-search-panel-motion-duration` was advertised in the doc\n block above but read by nothing, so setting it did nothing. Honour it here\n — the fallback chain is unchanged, so no instance moves by default. */\n --_motion-duration: var(\n --md-search-panel-motion-duration,\n var(--md-sys-motion-duration-medium2, 250ms)\n );\n --_motion-easing: var(--md-sys-motion-easing-emphasized, cubic-bezier(0.2, 0, 0, 1));\n\n /* Full-screen modal enter / exit — matches md-dialog fullscreen:\n translateY(30px) + opacity fade over medium2 / standard easing.\n Collapse duration is kept in sync with PANEL_CLOSE_MS in md-search.tsx\n so the bar un-pins right as the surface finishes exiting. */\n --_fs-expand-duration: var(\n --md-search-fullscreen-expand-duration,\n var(--md-sys-motion-duration-medium2, 300ms)\n );\n --_fs-expand-easing: var(\n --md-search-fullscreen-expand-easing,\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1))\n );\n --_fs-collapse-duration: var(\n --md-search-fullscreen-collapse-duration,\n var(--md-sys-motion-duration-medium2, 300ms)\n );\n --_fs-collapse-easing: var(\n --md-search-fullscreen-collapse-easing,\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1))\n );\n\n /* ── Host layout ────────────────────────────────────────── */\n display: block;\n position: relative;\n inline-size: 100%;\n min-inline-size: var(--_container-min-inline-size);\n max-inline-size: var(--_container-max-inline-size);\n margin-inline: auto;\n /* Reserve the bar's height even when it pins to the viewport in\n full-screen open, so surrounding layout doesn't shift. */\n min-block-size: var(--_container-height);\n\n font-family: var(--_input-font-family);\n color: var(--_input-color);\n box-sizing: border-box;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n/* Full-screen icon trigger (default): compact closed chrome — only the\n search icon button, not the 360–720dp resting bar. Shrink-wrap the host\n (no 100% inline stretch) and drop the inert panel from layout — the panel\n still sizes to slotted results while visibility:hidden, which otherwise\n inflates the host to the full results height and pins the icon to the\n corner of Storybook / app-bar shells. */\n:host(.md-search--trigger-icon.md-search--closed) {\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n inline-size: fit-content;\n block-size: fit-content;\n min-inline-size: 0;\n max-inline-size: none;\n min-block-size: 0;\n margin-inline: 0;\n overflow: visible;\n}\n\n:host(.md-search--trigger-icon.md-search--closed) .md-search__panel,\n:host(.md-search--trigger-icon.md-search--closed) .md-search__inset-probe {\n display: none;\n}\n\n/* Icon trigger is removed from layout once the bar expands (open). */\n:host(.md-search--trigger-icon.md-search--open) .md-search__trigger {\n display: none;\n}\n\n/* Pass-through wrapper — no extra box, background, or clipping around the\n icon button (Storybook previously clipped a 56dp button inside 48dp). */\n.md-search__trigger {\n display: contents;\n}\n\n:host(.md-search--trigger-icon) .md-search__trigger-button {\n /* Shrink with density (floor 32px) so the tap target doesn't floor the bar. */\n --md-icon-button-container-width: max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px));\n --md-icon-button-container-height: max(32px, calc(48px + var(--md-sys-density-scale, 0) * 4px));\n --md-icon-button-icon-size: max(18px, calc(24px + var(--md-sys-density-scale, 0) * 1px));\n --md-icon-button-icon-color: var(\n --md-search-leading-icon-color,\n var(--md-sys-color-on-surface, #1d1b20)\n );\n}\n\n/* Contained & Divided share the unified M3 search-bar layout: a 4dp space\n from each bar edge to a 48dp icon tap target, then a 4dp gap to the label.\n This lands the leading/trailing glyphs 16dp from the bar edges and the\n label 56dp in — matching the contained (4 + 48 + 4) and divided (16dp to\n glyph, 16dp glyph → label) measurement sheets simultaneously. Spacing is\n therefore inherited from the :host defaults; no per-variant override. */\n\n:host(.md-search--contained.md-search--docked) {\n --_panel-offset: var(\n --md-search-contained-docked-panel-offset,\n calc(var(--_focus-indicator-offset) + var(--_focus-indicator-thickness) + 3px)\n );\n}\n\n/* Full-screen never uses the docked/inline margin expansion — its open/close\n is a translateY(30px) slide + opacity fade (see the panel rules), matching\n md-dialog fullscreen. Zero both insets so the bar fills its host width at\n rest and open alike; only docked/inline bars spring 24 → 12. */\n:host(.md-search--full-screen) {\n --_expand-inset: 0px;\n --_expand-inset-focused: 0px;\n}\n\n/* Opt-in full-width (docked / inline): zero BOTH expand insets so the bar\n fills its container edge-to-edge with no side gutters and no 24 → 12dp\n margin animation. The aligned results drawer (inset by --_expand-inset-focused)\n then fills the same full width. This is exactly the `full-width` prop's\n effect; consumers can achieve the identical result purely via the CSS vars\n (`--md-search-expand-inset: 0; --md-search-expand-focused-inset: 0`). */\n:host(.md-search--full-width) {\n --_expand-inset: 0px;\n --_expand-inset-focused: 0px;\n}\n\n/* Contained × full-screen: the bar floats as a rounded pill, inset from the\n viewport edges. Those gutters sit OVER the full-viewport results surface\n (the panel fills inset:0 behind the bar), so they read as the opaque\n surface — never as a dimmer or page band. */\n:host(.md-search--contained.md-search--full-screen) {\n --_fullscreen-bar-offset-inline: var(\n --md-search-fullscreen-bar-offset-inline,\n max(8px, env(safe-area-inset-inline-start, 0px))\n );\n /* Clear the floating pill before the results begin. The global default is 0px\n because `divided` WANTS a flush seam — its 1px divider IS the separation.\n Contained has no divider and its bar is a detached rounded pill, so a flush\n list tucks the first row's state layer under the pill's bottom corners.\n Same clearance as the docked panel (`--_panel-offset`), so a contained\n search reads identically whether it docks or goes full-screen — and, like\n docked, it stays constant across density: this gap clears the focus ring,\n whose thickness doesn't scale, so tapering it would re-introduce the\n overlap at exactly the rungs where the layout is already tightest. */\n --_fullscreen-bar-panel-gap: var(\n --md-search-fullscreen-bar-panel-gap,\n calc(var(--_focus-indicator-offset) + var(--_focus-indicator-thickness) + 3px)\n );\n}\n\n/* Resting divided × full-screen reads as the same compact, rounded pill as the\n contained variant (56dp, `--_container-shape`). The 72dp flat app-bar header\n chrome only applies once the view is open/expanded — see the open rules. */\n:host(.md-search--divided.md-search--full-screen.md-search--open) {\n /* M3 divided baseline: full-screen header is 72dp; docked stays 56dp. */\n --_container-height: var(--_divided-fullscreen-bar-height);\n /* Flat app-bar flush to the viewport edges (safe-area only). */\n --_fullscreen-bar-offset-block-start: max(0px, env(safe-area-inset-block-start, 0px));\n --_fullscreen-bar-offset-inline: max(0px, env(safe-area-inset-inline-start, 0px));\n}\n\n/* Full-screen open: the host becomes the fixed viewport overlay. The results\n panel fills the ENTIRE viewport (inset:0) as the opaque surface that fades\n in — there is no scrim/dimmer. The bar floats on top of that surface\n (contained pill or divided app-bar header), so the bar's gutters show the\n opaque results surface rather than the dimmed page (no gray bands). */\n:host(.md-search--full-screen.md-search--open) {\n position: fixed;\n inset: 0;\n display: block;\n inline-size: 100%;\n block-size: 100dvh;\n max-inline-size: none;\n min-inline-size: 0;\n margin: 0;\n min-block-size: 0;\n z-index: var(--md-sys-z-index-modal, 1300);\n box-sizing: border-box;\n}\n\n/* Cancel compact icon-host shrink-wrap once the full-screen overlay opens. */\n:host(.md-search--trigger-icon.md-search--full-screen.md-search--open) {\n display: block;\n inline-size: 100%;\n block-size: 100dvh;\n max-inline-size: none;\n min-inline-size: 0;\n min-block-size: 0;\n align-items: stretch;\n justify-content: flex-start;\n}\n\n/* Bar floats on top of the full-viewport panel. `inset-inline` insets it by\n the per-variant gutter (contained pill = 8dp, divided header = flush). */\n:host(.md-search--full-screen.md-search--open) .md-search__bar {\n position: fixed;\n inset-block-start: var(--_fullscreen-bar-offset-block-start);\n inset-inline: var(--_fullscreen-bar-offset-inline);\n inline-size: auto;\n margin-inline: 0;\n z-index: 2;\n}\n\n/* Keep the focus ring above the panel's divider at the bar/results seam so it\n reads as one continuous outline (bar already sits above the panel). */\n:host(.md-search--full-screen.md-search--open) .md-search__bar--focus-ring {\n z-index: 2;\n}\n\n/* The opaque results surface fills the whole viewport (inset:0) and fades in.\n Its content is offset below the floating bar via padding-block-start so the\n first result clears the bar; the surface itself still paints edge-to-edge\n behind the bar (no gaps / bands). */\n:host(.md-search--full-screen.md-search--open) .md-search__panel--full-screen {\n position: fixed;\n inset: 0;\n margin: 0;\n padding-block-start: calc(\n var(--_fullscreen-bar-offset-block-start) + var(--_container-height) +\n var(--_fullscreen-bar-panel-gap) + var(--_panel-padding-block-start)\n );\n padding-inline: 0;\n max-block-size: var(--_max-block-size, 100dvh);\n z-index: 1;\n background-color: var(--_fullscreen-results-color);\n}\n\n/* Contained open: cancel the open-state leading-button pull. The leading\n space is now the spec's 4dp \"with actions\" value, so the 40dp back button\n sits flush against that 4dp gutter (glyph lands ~12dp from the bar edge)\n without the legacy -8px overshoot. */\n:host(.md-search--contained.md-search--open) .md-search__leading-button {\n margin-inline-start: 0;\n}\n\n/* ──────────────────────────────────────────────────────────\n Search bar\n ────────────────────────────────────────────────────────── */\n\n.md-search__bar {\n position: relative;\n display: flex;\n align-items: center;\n /* border-box so `inline-size: 100%` (and the resting inset calc) include the\n bar's inline padding. With the default content-box, the focused padding is\n ADDED outside the 100%, pushing the border-box past the host's inline-end\n edge — the bar then overflows to the right instead of expanding evenly. */\n box-sizing: border-box;\n /* No flex gap — spacing is provided by the leading/trailing wrappers'\n own padding-inline, so the icon-to-text distance equals exactly\n `--_leading-padding-inline` (16dp) with no double-spacing. */\n gap: 0;\n /* Resting width is inset symmetrically; margin-inline: auto keeps the bar\n centred so the focused expansion grows into both edges at once\n (the M3 \"expressive\" expand-left-and-right motion). */\n inline-size: calc(100% - calc(var(--_expand-inset) * 2));\n /* Never exceed the host, and allow the flex bar to shrink below its\n content's min-content width (default `min-inline-size: auto`). Without\n this, when the container is narrower than the bar's intrinsic content the\n bar can't shrink, so `inline-size: 100%` is ignored, the bar overflows past\n the host's inline-end edge and `margin-inline: auto` collapses to 0 — the\n bar then appears to expand only to the right. Capping at 100% + allowing\n shrink (the input has `min-inline-size: 0`) keeps the centred bar growing\n symmetrically into both edges at every responsive width. */\n min-inline-size: 0;\n max-inline-size: 100%;\n margin-inline: auto;\n block-size: var(--_container-height);\n padding-inline: var(--_container-padding-inline);\n background-color: var(--_container-color);\n border-radius: var(--_container-shape);\n box-shadow: var(--_container-elevation);\n cursor: text;\n overflow: hidden;\n /* Inline padding is no longer animated — leading/trailing wrappers\n carry stable padding so the icons don't shift on focus. */\n transition:\n inline-size var(--_expand-duration) var(--_expand-easing),\n background-color var(--_motion-duration) var(--_motion-easing),\n box-shadow var(--_motion-duration) var(--_motion-easing),\n border-radius var(--_motion-duration) var(--_motion-easing);\n}\n\n/* Elevation levels — `elevation` prop maps to an MD3 elevation tier.\n `--md-search-container-elevation` (set on :host) still overrides these. */\n:host(.md-search--elevation-0) { --_container-elevation-level: 0px 0px 0px 0px transparent; }\n:host(.md-search--elevation-1) { --_container-elevation-level: var(--md-sys-elevation-1); }\n:host(.md-search--elevation-2) { --_container-elevation-level: var(--md-sys-elevation-2); }\n:host(.md-search--elevation-3) { --_container-elevation-level: var(--md-sys-elevation-3); }\n:host(.md-search--elevation-4) { --_container-elevation-level: var(--md-sys-elevation-4); }\n:host(.md-search--elevation-5) { --_container-elevation-level: var(--md-sys-elevation-5); }\n\n/* Focused or open: the docked/inline bar springs from its 24dp resting\n margin out to the 12dp focused margin, evenly left + right (M3 Expressive\n \"container width\" focus motion). Full-screen zeroes both insets, so this\n resolves to the full overlay width there. */\n.md-search__bar--focused,\n:host(.md-search--open) .md-search__bar {\n inline-size: calc(100% - calc(var(--_expand-inset-focused) * 2));\n padding-inline: var(--_container-padding-inline-focused);\n}\n\n:host(.md-search--disabled) .md-search__bar {\n cursor: not-allowed;\n opacity: 0.38;\n}\n\n/* Full-screen: the host flips position:relative → fixed on open and its\n containing block changes from the 720dp max to the viewport. Animating\n the bar's percentage `inline-size` with the springy overshoot across\n that switch resolves the percentage against a moving target and reads\n as jitter. In full-screen the bar simply fills the overlay, so we drop\n the width spring here and let the modal-like slide + fade carry the\n open/close motion. The expressive width-spring stays for docked. */\n:host(.md-search--full-screen) .md-search__bar {\n transition:\n opacity var(--_fs-collapse-duration) var(--_fs-collapse-easing),\n transform var(--_fs-collapse-duration) var(--_fs-collapse-easing),\n background-color var(--_motion-duration) var(--_motion-easing),\n border-radius var(--_motion-duration) var(--_motion-easing);\n}\n\n/* Full-screen open: bar slides up with the panel (md-dialog fullscreen\n pattern — translateY(30px) → 0 + opacity). Hidden until the deferred\n panel reveal commits so the animation starts from a settled layout. */\n:host(.md-search--full-screen.md-search--open) .md-search__bar {\n opacity: 0;\n transform: translateY(30px);\n pointer-events: none;\n}\n\n:host(.md-search--full-screen.md-search--open.md-search--panel-content) .md-search__bar {\n opacity: 1;\n transform: translateY(0);\n pointer-events: auto;\n transition:\n opacity var(--_fs-expand-duration) var(--_fs-expand-easing),\n transform var(--_fs-expand-duration) var(--_fs-expand-easing),\n background-color var(--_motion-duration) var(--_motion-easing),\n border-radius var(--_motion-duration) var(--_motion-easing);\n}\n\n/* Divided × full-screen open: flat app-bar chrome (host overlay above). */\n:host(.md-search--divided.md-search--full-screen.md-search--open) .md-search__bar {\n border-radius: 0;\n background-color: var(--_bar-fullscreen-color);\n padding-inline: var(--_container-padding-inline-focused);\n}\n\n/* Contained × full-screen open: expanded expressive pill at full host width. */\n:host(.md-search--contained.md-search--full-screen.md-search--open) .md-search__bar {\n border-radius: var(--_container-shape);\n background-color: var(--_container-color);\n padding-inline: var(--_container-padding-inline-focused);\n}\n\n/* Ripple pinning. The actual `--md-ripple-extend-inline` value is set\n imperatively from md-search.tsx — see `measureRippleExtend()`.\n\n Why JS instead of CSS: the obvious declaration here would be\n `--md-ripple-extend-inline: calc(var(--_expand-inset) - var(--_expand-inset-focused))`\n — each bar edge moves out by exactly that delta as the bar springs from\n `100% - 2*resting` to `100% - 2*focused`, so the per-side extend the ripple\n needs IS that delta. But the insets may be overridden with percentages\n (`--md-search-expand-inset` / `--md-search-expand-focused-inset`). A\n percentage resolves against whatever element\n the `inline-size` ultimately lands on: the bar resolves it against the\n SEARCH HOST (its containing block), but the same expression read back\n through md-ripple's shadow tree walks up to the BAR, so it would\n resolve against the bar's narrower width and the extent would fall\n short of the actual travel. Resolving the inset in JS — through an\n inset-probe whose containing block IS the host — sidesteps that\n asymmetry for any value (fixed or percentage) and gives md-ripple the\n exact pixel value it needs. */\n.md-search__bar > md-ripple {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n pointer-events: none;\n /* Sync the wave's grow with the bar's springy expand. Both have to\n resolve at the same instant — if the wave is shorter, it lands\n before the bar settles and the press feels rushed; if the wave is\n longer, it lags during the bar's overshoot peak (~58 % of duration\n in) and exposes a coverage gap on whichever side the bar grew,\n because by then the bar has already swept past the wave's\n still-ramping radius. Driving the wave's grow off\n `--_expand-duration` / `--_expand-easing` ties the two together —\n same back-out spring, same 400ms travel — so the bar and the wave\n share both timing and character. We can use a `var(...)` reference\n here because durations and timing-function tokens are resolved as\n part of getComputedStyle's substitution (unlike the\n length-percentage extend value, which can carry an unresolved\n percentage component). */\n --md-ripple-grow-duration: var(--_expand-duration);\n --md-ripple-grow-easing: var(--_expand-easing);\n}\n\n/* Hidden probe used by md-search.tsx to resolve `--_expand-inset` to a\n pixel value. It's a child of `:host` rather than of the bar so its\n absolute-positioning containing block (the `position: relative` host)\n matches the bar's containing block — so any percentage override of\n `--md-search-expand-inset` resolves against the SAME inline-size for\n both the probe and the bar. Reading `probe.getBoundingClientRect().width`\n forces the browser to resolve the value (fixed length or percentage)\n to concrete pixels, which we then forward to md-ripple as a fixed\n length via inline style. */\n.md-search__inset-probe {\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 0;\n /* The ripple's per-side reach equals the bar's per-side travel on focus:\n the resting margin minus the focused margin (24 → 12 = 12dp default). */\n inline-size: max(0px, calc(var(--_expand-inset) - var(--_expand-inset-focused)));\n block-size: 0;\n visibility: hidden;\n pointer-events: none;\n opacity: 0;\n}\n\n/* Visually-hidden polite live region for autosuggest announcements. Kept in\n the accessibility tree (not display:none / visibility:hidden) so screen\n readers still pick up content changes. */\n.md-search__a11y-status {\n position: absolute;\n inline-size: 1px;\n block-size: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n/* State layer */\n.md-search__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms)\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n.md-search__bar:hover .md-search__state-layer {\n opacity: var(--_hover-state-layer-opacity);\n}\n\n/* M3 Search bar / Focused: focus indicator ring (3dp / 2dp offset) — not a\n state-layer wash. Box-shadow avoids clipping from overflow:hidden.\n\n The ring is keyboard-only: a text input always matches :focus-visible (even\n on click), so the component drives the ring from the `--focus-ring` class,\n which is set only when focus did NOT follow a pointer interaction. */\n.md-search__bar--focus-ring .md-search__state-layer {\n opacity: 0;\n}\n\n.md-search__bar--focus-ring {\n box-shadow:\n var(--_container-elevation),\n 0 0 0 var(--_focus-indicator-offset) var(--_container-color),\n 0 0 0\n calc(var(--_focus-indicator-offset) + var(--_focus-indicator-thickness))\n var(--_focus-indicator-color);\n}\n\n.md-search__bar:active .md-search__state-layer {\n opacity: var(--_pressed-state-layer-opacity);\n}\n\n/* Hover / pressed: supporting text stays on-surface-variant (#49454F). */\n.md-search__bar:hover .md-search__input::placeholder,\n.md-search__bar:active .md-search__input::placeholder {\n color: var(--_placeholder-color);\n}\n\n:host(.md-search--disabled) .md-search__state-layer {\n display: none;\n}\n\n/* ──────────────────────────────────────────────────────────\n Leading / trailing clusters\n ────────────────────────────────────────────────────────── */\n\n.md-search__leading,\n.md-search__trailing {\n display: inline-flex;\n align-items: center;\n gap: var(--md-sys-spacing-gap-xs, 4px);\n flex: 0 0 auto;\n position: relative;\n z-index: 1;\n /* Box-sizing keeps the wrapper's outer footprint consistent so the\n leading icon sits at exactly --_leading-padding-inline from the bar's\n leading edge (and the trailing cluster mirrors it on the other side). */\n box-sizing: border-box;\n}\n\n.md-search__leading {\n /* Leading space (bar edge → icon) + icon → label gap per M3 layout tokens. */\n padding-inline-start: var(--_leading-padding-inline);\n padding-inline-end: var(--_leading-icon-label-gap);\n}\n\n.md-search__trailing {\n margin-inline-start: auto;\n /* Label → trailing cluster gap + trailing space (cluster → bar edge). */\n padding-inline-start: var(--_trailing-icon-label-gap);\n padding-inline-end: var(--_trailing-padding-inline);\n}\n\n.md-search__leading .md-search__icon,\n.md-search__leading-button {\n color: var(--_leading-icon-color);\n}\n\n.md-search__trailing .md-search__icon {\n color: var(--_trailing-icon-color);\n}\n\n.md-search__icon {\n font-family: var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');\n font-size: var(--_icon-size);\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n line-height: 1;\n font-weight: normal;\n font-style: normal;\n letter-spacing: normal;\n text-transform: none;\n white-space: nowrap;\n overflow-wrap: normal;\n direction: ltr;\n -webkit-font-smoothing: antialiased;\n pointer-events: none;\n user-select: none;\n}\n\n/* Built-in icon button (used for the leading close button + clear button) */\n.md-search__icon-button {\n appearance: none;\n background: transparent;\n border: 0;\n margin: 0;\n padding: 0;\n cursor: pointer;\n inline-size: var(--_icon-button-size);\n block-size: var(--_icon-button-size);\n border-radius: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n color: var(--_trailing-icon-color);\n position: relative;\n transition: background-color var(--md-sys-motion-duration-short2, 100ms)\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n.md-search__icon-button:hover {\n background-color: color-mix(\n in srgb,\n var(--_trailing-icon-color) 8%,\n transparent\n );\n}\n\n/* Inline loading indicator (shape-morph) shown while results are fetched.\n Occupies the same 48dp trailing slot as an icon button so the cluster\n width doesn't jump when it replaces the clear button; its morphing shape\n matches the 24dp trailing icon size. */\n.md-search__loading {\n --md-loading-indicator-size: var(--_icon-button-size);\n --md-loading-indicator-shape-size: var(--_icon-size);\n --md-loading-indicator-color: var(--_loading-color);\n flex: 0 0 auto;\n pointer-events: none;\n}\n\n/* ──────────────────────────────────────────────────────────\n Trailing loading ↔ clear-× morph\n One fixed-size box holds both the loading indicator and the clear button,\n stacked. Toggling `loading` cross-fades them (opacity + scale + rotate) in\n BOTH directions over the same box, so the trailing cluster never jumps and\n the swap reads as one expressive shape-morph rather than a hard switch.\n ────────────────────────────────────────────────────────── */\n.md-search__trailing-morph {\n position: relative;\n flex: 0 0 auto;\n inline-size: var(--_icon-button-size);\n block-size: var(--_icon-button-size);\n}\n\n.md-search__trailing-morph > .md-search__loading,\n.md-search__trailing-morph > .md-search__clear {\n position: absolute;\n inset: 0;\n margin: auto;\n transition:\n opacity var(--md-sys-motion-duration-medium1, 250ms)\n var(--md-sys-motion-easing-emphasized, cubic-bezier(0.2, 0, 0, 1)),\n transform var(--md-sys-motion-duration-medium1, 250ms)\n var(--md-sys-motion-easing-emphasized, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* Resting (not loading): clear-× present, loading morphed away. */\n.md-search__trailing-morph > .md-search__clear {\n opacity: 1;\n transform: scale(1) rotate(0deg);\n}\n.md-search__trailing-morph > .md-search__loading {\n opacity: 0;\n transform: scale(0.6) rotate(-90deg);\n}\n\n/* Loading: indicator present, clear-× morphed away (and non-interactive). */\n.md-search__trailing-morph--loading > .md-search__clear {\n opacity: 0;\n transform: scale(0.6) rotate(90deg);\n pointer-events: none;\n}\n.md-search__trailing-morph--loading > .md-search__loading {\n opacity: 1;\n transform: scale(1) rotate(0deg);\n}\n\n/* ──────────────────────────────────────────────────────────\n Voice search mic button\n ────────────────────────────────────────────────────────── */\n.md-search__voice {\n flex: 0 0 auto;\n color: var(--_trailing-icon-color);\n}\n\n/* Keep the glyph above the listening halo. */\n.md-search__voice .md-search__icon {\n position: relative;\n z-index: 1;\n}\n\n/* Listening: tint the mic with the primary colour and pulse a soft halo so\n the active state reads at a glance. */\n.md-search__voice--listening {\n color: var(--md-sys-color-primary, #6750A4);\n}\n\n.md-search__voice--listening::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: 50%;\n background-color: color-mix(\n in srgb,\n var(--md-sys-color-primary, #6750A4) 16%,\n transparent\n );\n animation: md-search-voice-pulse 1.4s\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1)) infinite;\n}\n\n@keyframes md-search-voice-pulse {\n 0%,\n 100% {\n transform: scale(0.82);\n opacity: 0.55;\n }\n 50% {\n transform: scale(1.12);\n opacity: 0.2;\n }\n}\n\n/* Inside the bar there's only ~4dp of room around a 48dp icon button, so an\n outset ring (offset + thickness) would spill over the bar edge / rounded\n corners. Draw the ring INSET instead — it hugs the inner perimeter of the\n tap target and stays fully contained within the bar. */\n.md-search__icon-button:focus-visible {\n outline: var(--_focus-indicator-thickness) solid var(--_focus-indicator-color);\n outline-offset: calc(-1 * var(--_focus-indicator-thickness));\n}\n\n/* ──────────────────────────────────────────────────────────\n Leading button — search ↔ back-arrow morph\n\n Both glyphs are always rendered, stacked at the same centred slot so\n the change between the resting and open states reads as a single icon\n smoothly morphing (cross-fade + rotation + scale) rather than two\n sibling glyphs swapping.\n\n The wrapper is always a 48dp circular tap target (the M3 search-bar icon\n target). With the 4dp leading space, the 24dp glyph centred inside lands\n ~16dp from the bar's leading edge in both states — so there's no size or\n position jump on open.\n\n In the resting state pointer-events are turned off so a click on the\n search glyph falls through to the bar — preserving the behaviour where\n tapping anywhere on the bar focuses the input. When the bar is open the\n wrapper becomes interactive and gains its own hover / press / focus chrome.\n ────────────────────────────────────────────────────────── */\n\n.md-search__leading-button {\n appearance: none;\n background: transparent;\n border: 0;\n margin: 0;\n padding: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n inline-size: var(--_icon-button-size);\n block-size: var(--_icon-button-size);\n border-radius: 50%;\n cursor: text;\n /* Closed state: clicks fall through to .md-search__bar so the input\n gets focused exactly like clicking anywhere else on the bar. */\n pointer-events: none;\n transition: background-color var(--md-sys-motion-duration-short2, 100ms)\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host(.md-search--open) .md-search__leading-button {\n cursor: pointer;\n pointer-events: auto;\n}\n\n/* Dedicated state layer for the leading button. An opacity-driven overlay\n (rather than a `background-color` wash on the button itself) guarantees a\n fully transparent idle — there is no painted circle behind the icon until\n the button is genuinely hovered / pressed — while still rendering a clean\n circular layer sized exactly to the 48dp tap target on interaction. It\n sits behind the morphing glyphs and is inert. */\n.md-search__leading-state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_leading-icon-color);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--md-sys-motion-duration-short2, 100ms)\n var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n:host(.md-search--open) .md-search__leading-button:hover .md-search__leading-state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(.md-search--open) .md-search__leading-button:active .md-search__leading-state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.12);\n}\n\n.md-search__leading-button:focus-visible {\n outline: var(--_focus-indicator-thickness) solid var(--_focus-indicator-color);\n outline-offset: calc(-1 * var(--_focus-indicator-thickness));\n border-radius: 50%;\n}\n\n.md-search__leading-button:disabled {\n cursor: not-allowed;\n}\n\n/* Stacked icons. Each occupies the same centred slot inside the leading\n button so the morph reads as a single glyph rotating / fading. */\n.md-search__leading-button .md-search__icon {\n position: absolute;\n inset: 0;\n margin: auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n inline-size: var(--_icon-size);\n block-size: var(--_icon-size);\n transition:\n opacity var(--_motion-duration) var(--_motion-easing),\n transform var(--_motion-duration) var(--_motion-easing);\n}\n\n/* Resting → search. Visible at rest, rotates out + scales down on open. */\n.md-search__icon--resting {\n opacity: 1;\n transform: rotate(0deg) scale(1);\n}\n\n:host(.md-search--open) .md-search__icon--resting {\n opacity: 0;\n transform: rotate(-90deg) scale(0.6);\n}\n\n/* Open → directional close glyph (chevron_left or arrow_back, picked by\n variant in TSX). Pre-positioned rotated + scaled so it\n springs in from the opposite side of the morph.\n\n Both `chevron_left` and `arrow_back` are literal pictograms pointing\n physically left — in an RTL context \"back\" means physically right, so the\n glyph is mirrored along the inline axis via `--_open-glyph-mirror` (-1 in\n RTL). Because the mirror lives in the transform of BOTH the resting and\n open states, it stays applied through the whole morph and never relies on\n a separate RTL open-state selector (chaining a class onto `:host-context()`\n did not reliably match, leaving the glyph stuck mid-rotation in RTL). The\n resting search glyph is directionally neutral and stays unmirrored. */\n.md-search__icon--open {\n opacity: 0;\n transform: rotate(90deg) scale(0.6) scaleX(var(--_open-glyph-mirror));\n}\n\n:host(.md-search--open) .md-search__icon--open {\n opacity: 1;\n transform: rotate(0deg) scale(1) scaleX(var(--_open-glyph-mirror));\n}\n\n/* RTL flips the open glyph's inline axis. Set only on the host (no chaining\n onto `:host-context()`), so it inherits cleanly into the glyph regardless\n of open state. */\n:host([dir=\"rtl\"]),\n:host-context([dir=\"rtl\"]) {\n --_open-glyph-mirror: -1;\n}\n\n/* Slotted icon buttons / avatars */\n::slotted([slot='leading']),\n::slotted([slot='trailing']) {\n display: inline-flex;\n align-items: center;\n}\n\n::slotted(md-avatar[slot='trailing']),\n::slotted([slot='trailing'][role='img']),\n::slotted(img[slot='trailing']) {\n inline-size: var(--_avatar-size);\n block-size: var(--_avatar-size);\n}\n\n/* ──────────────────────────────────────────────────────────\n Input\n ────────────────────────────────────────────────────────── */\n\n.md-search__input {\n flex: 1 1 auto;\n min-inline-size: 0;\n border: 0;\n outline: 0;\n background: transparent;\n color: var(--_input-color);\n font-family: var(--_input-font-family);\n font-size: var(--_input-font-size);\n font-weight: var(--_input-font-weight);\n line-height: var(--_input-line-height);\n letter-spacing: var(--_input-letter-spacing);\n /* No internal padding — the leading/trailing wrappers control the entire\n icon-to-text distance (16dp by default) with no double-spacing. */\n padding-inline: 0;\n position: relative;\n z-index: 1;\n}\n\n/* Supporting text (placeholder) uses the same body-large typescale as input. */\n.md-search__input::placeholder {\n color: var(--_placeholder-color);\n opacity: 1;\n font-family: var(--_input-font-family);\n font-size: var(--_input-font-size);\n font-weight: var(--_input-font-weight);\n line-height: var(--_input-line-height);\n letter-spacing: var(--_input-letter-spacing);\n}\n\n.md-search__input:disabled {\n cursor: not-allowed;\n}\n\n/* Hide the native `type=search` clear cross — we render our own. */\n.md-search__input::-webkit-search-cancel-button,\n.md-search__input::-webkit-search-decoration {\n display: none;\n}\n\n/* ──────────────────────────────────────────────────────────\n Panel\n ────────────────────────────────────────────────────────── */\n\n/* The panel is a pure positioning + dialog wrapper. Scrolling happens in\n the inner viewport (`md-scroll-shadow` by default) so edge shadows and\n the native scrollbar align with the slotted surface chrome. */\n.md-search__panel {\n visibility: hidden;\n opacity: 0;\n pointer-events: none;\n box-sizing: border-box;\n background-color: transparent;\n color: var(--_input-color);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n min-block-size: 0;\n transition:\n opacity var(--_motion-duration) var(--_motion-easing),\n transform var(--_motion-duration) var(--_motion-easing),\n visibility 0s linear var(--_motion-duration);\n}\n\n/* Flex region below the divider — sizes the scroll viewport from the\n panel's (or open host's) max-block-size budget. */\n.md-search__panel-body {\n flex: 1 1 auto;\n min-block-size: 0;\n display: flex;\n flex-direction: column;\n}\n\n/* Flex column wrapper so the scroll viewport gets a definite block-size\n from the panel chain (same pattern as md-bottom-sheet__content). Without\n this, the host is a block box sized to full slotted content and the docked\n panel's max-block-size only clips — no inner scroll. */\n.md-search__results-host {\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-block-size: 0;\n overflow: hidden;\n}\n\n.md-search__results-host .md-search__results-scroll {\n flex: 1 1 auto;\n min-block-size: 0;\n}\n\n/* The results list is the scroll surface. */\n.md-search__results-scroll {\n flex: 1 1 auto;\n min-block-size: 0;\n overflow-block: auto;\n overflow-inline: hidden;\n overscroll-behavior: contain;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: thin;\n scrollbar-color: var(--md-sys-color-outline-variant, #cac4d0) transparent;\n}\n\n.md-search__results-scroll::-webkit-scrollbar {\n inline-size: 8px;\n}\n\n.md-search__results-scroll::-webkit-scrollbar-thumb {\n background-color: var(--md-sys-color-outline-variant, #cac4d0);\n border-radius: 4px;\n}\n\n/* Visible empty state — shown when the panel is open, the user has typed a\n query, and there are zero slotted result rows (not while `loading`). */\n.md-search__empty {\n flex: 0 0 auto;\n margin: 0;\n padding-block: var(--md-search-empty-padding-block, var(--md-sys-spacing-inset-xl, 24px));\n padding-inline: var(--md-search-empty-padding-inline, var(--md-sys-spacing-inset-lg, 16px));\n text-align: center;\n color: var(\n --md-search-empty-color,\n var(--md-sys-color-on-surface-variant, #49454f)\n );\n font-family: var(\n --md-sys-typescale-body-medium-font,\n Roboto,\n system-ui,\n sans-serif\n );\n font-size: var(--md-sys-typescale-body-medium-size, 14px);\n font-weight: var(--md-sys-typescale-body-medium-weight, 400);\n line-height: var(--md-sys-typescale-body-medium-line-height, 20px);\n letter-spacing: var(--md-sys-typescale-body-medium-tracking, 0.25px);\n}\n\n/* Results slot stays mounted (for slotchange + consumer DOM) but is hidden\n while the visible empty state is shown. */\n.md-search__panel-body--empty .md-search__results-host {\n display: none;\n}\n\n/* Docked: anchored popup beneath the bar. The drawer aligns EXACTLY to the\n open bar's edges — it is inset by the same focused expand margin\n (`--_expand-inset-focused`, 12dp) on both sides, so the bar and the results\n drawer share identical inline-start / inline-end edges at every responsive\n width. The host already clamps the overall inline-size (min 360 / max 720),\n so the drawer inherits that clamp through `inset-inline` rather than carrying\n its own (which would otherwise force the drawer wider than the inset bar at\n the lower clamp). Block clamps: min shrinks to content (0 default); max\n scrolls inside when the list is long. The slotted list owns the surface. */\n.md-search__panel--docked {\n position: absolute;\n inset-inline: var(--_expand-inset-focused);\n inset-block-start: calc(var(--_container-height) + var(--_panel-offset));\n /* Intrinsic height from slotted rows, capped by max — no fixed 240dp bay. */\n block-size: fit-content;\n min-block-size: var(--_panel-min-block-size);\n max-block-size: var(--_max-block-size, var(--_panel-max-block-size));\n transform: translateY(-4px);\n z-index: var(--md-sys-z-index-popup, 1100);\n}\n\n.md-search__panel--docked.md-search__panel--open {\n visibility: visible;\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0);\n transition:\n opacity var(--_motion-duration) var(--_motion-easing),\n transform var(--_motion-duration) var(--_motion-easing),\n visibility 0s;\n}\n\n/* Full-screen (closed): panel is inert; when open it becomes the fixed\n full-viewport surface — see :host(.md-search--full-screen.md-search--open).\n Open/close matches md-dialog fullscreen: translateY(30px) + opacity fade\n over medium2 / standard easing (no scrim). The deferred-reveal rAF in\n md-search.tsx commits the position:fixed overlay layout before this\n animation starts so there's no relayout on the animating frames. */\n.md-search__panel--full-screen {\n opacity: 0;\n transform: translateY(30px);\n will-change: opacity, transform;\n transition:\n opacity var(--_fs-collapse-duration) var(--_fs-collapse-easing),\n transform var(--_fs-collapse-duration) var(--_fs-collapse-easing),\n visibility 0s linear var(--_fs-collapse-duration);\n}\n\n.md-search__panel--full-screen.md-search__panel--open {\n visibility: visible;\n opacity: 1;\n pointer-events: auto;\n transform: translateY(0);\n transition:\n opacity var(--_fs-expand-duration) var(--_fs-expand-easing),\n transform var(--_fs-expand-duration) var(--_fs-expand-easing),\n visibility 0s;\n}\n\n/* ──────────────────────────────────────────────────────────\n Divider (`divided` variant)\n ────────────────────────────────────────────────────────── */\n\n.md-search__divider {\n display: none;\n block-size: var(--_divider-thickness);\n background-color: var(--_divider-color);\n flex: 0 0 auto;\n}\n\n:host(.md-search--divided.md-search--panel-content) .md-search__divider {\n display: block;\n}\n\n/* In the divided baseline FULL-SCREEN the OPEN bar is a flat app-bar header, so\n it drops the rounded shape and the divider becomes the only separator between\n bar and results. The resting bar keeps the rounded `--_container-shape` (pill)\n so it reads exactly like the contained variant before expansion. Docked keeps\n the rounded pill in both states — see the docked-open card rule below. */\n:host(.md-search--divided.md-search--full-screen.md-search--open.md-search--panel-content) .md-search__bar {\n border-radius: 0;\n}\n\n:host(.md-search--divided) .md-search__panel--docked {\n inset-block-start: var(--_container-height);\n}\n\n/* Divided × docked: snap the bar's corner morph instead of transitioning it.\n Animating border-radius eased the bottom corners from the resting pill down\n to square WHILE the results panel revealed flush beneath — for a few frames\n the bar's still-rounded bottom corners exposed notches against the square-\n topped panel, reading as a flicker at the seam. The corner change is\n imperceptible when snapped (the top corners don't change and the bottom is\n immediately covered by the flush panel), so we drop border-radius from the\n transition for this combination only. */\n:host(.md-search--divided.md-search--docked) .md-search__bar {\n transition:\n inline-size var(--_expand-duration) var(--_expand-easing),\n background-color var(--_motion-duration) var(--_motion-easing),\n box-shadow var(--_motion-duration) var(--_motion-easing);\n}\n\n/* Divided × docked open: one unified floating card — the bar + panel read as a\n single surface whose OUTER corners keep the resting bar's VISIBLE radius\n (`--_resting-corner-shape`: the clamped half-height of the default pill),\n while the seam between bar and panel stays flat. The bar rounds only its top\n corners and the panel only its bottom corners, so the combined silhouette\n matches the resting pill exactly rather than clamping against the taller\n open card. */\n:host(.md-search--divided.md-search--docked.md-search--open.md-search--panel-content) .md-search__bar {\n border-radius: var(--_resting-corner-shape) var(--_resting-corner-shape) 0 0;\n background-color: var(--_container-color);\n overflow: hidden;\n}\n\n:host(.md-search--divided.md-search--docked.md-search--open.md-search--panel-content) .md-search__panel--docked {\n background-color: var(--_container-color);\n border-radius: 0 0 var(--_resting-corner-shape) var(--_resting-corner-shape);\n overflow: hidden;\n}\n\n/* Contained × docked open: the results panel is a standalone rounded card\n below the bar (4dp gap). Keep ALL four corners rounded; the panel's\n `overflow: hidden` then clips the scrolling viewport, its scrollbar, and the\n slotted list surface inside that radius, so enabling scroll never squares off\n the top corners (under the bar seam) or the bottom corners (below the last\n result). overflow:clip would also work; hidden is inherited from\n .md-search__panel and is sufficient since the inner viewport owns scrolling.\n Only apply when there is panel content (rows or empty-state message). */\n:host(.md-search--contained.md-search--docked.md-search--open.md-search--panel-content) .md-search__panel--docked {\n border-radius: var(--_docked-panel-shape);\n background-color: var(--_container-color);\n}\n\n/* ──────────────────────────────────────────────────────────\n Slotted results — transparent on the search surface\n ────────────────────────────────────────────────────────── */\n\n/* Slotted `<md-list>` (or any results wrapper) inherits the panel / bar\n chrome. Suppress the default M3 `surface` list-item fill so rows don't\n read as a nested dark card against surface-container-* panels — especially\n in dark theme. Authors can re-tint per-list when they want a distinct bay.\n Zero out the list's default 8dp block padding so the first and last rows\n sit flush against the drawer edges with no gap. */\n::slotted([slot='results']) {\n display: block;\n --md-list-container-color: transparent;\n --md-list-item-container-color: transparent;\n --md-list-padding-block: 0px;\n}\n\n/* ──────────────────────────────────────────────────────────\n Disabled\n ────────────────────────────────────────────────────────── */\n\n:host(.md-search--disabled) .md-search__input,\n:host(.md-search--disabled) .md-search__icon,\n:host(.md-search--disabled) .md-search__icon-button,\n:host(.md-search--disabled) .md-search__leading-button {\n pointer-events: none;\n color: color-mix(\n in srgb,\n var(--md-sys-color-on-surface, #1D1B20) 38%,\n transparent\n );\n}\n\n/* ──────────────────────────────────────────────────────────\n Reduced motion\n ────────────────────────────────────────────────────────── */\n\n@media (prefers-reduced-motion: reduce) {\n .md-search__bar,\n .md-search__panel,\n .md-search__state-layer,\n .md-search__icon-button,\n .md-search__leading-button,\n .md-search__leading-state-layer,\n .md-search__leading-button .md-search__icon,\n .md-search__trailing-morph > .md-search__loading,\n .md-search__trailing-morph > .md-search__clear {\n transition-duration: 0.01ms !important;\n }\n\n /* The listening halo is decorative — drop the pulse but keep the tint. */\n .md-search__voice--listening::before {\n animation: none;\n }\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 {\n Component,\n Host,\n h,\n Prop,\n State,\n Event,\n EventEmitter,\n Element,\n Method,\n Watch,\n Listen,\n} from '@stencil/core';\nimport { LazyLoadingIndicator } from '../../utils/lazy-loading-indicator';\n\n/**\n * Minimal structural type for the Web Speech API `SpeechRecognition`\n * instance — the DOM lib doesn't ship these types in every TS target, and we\n * only touch a small surface. Indexing the global ctor avoids a hard\n * dependency on the (prefixed / non-standard) API.\n */\ninterface SpeechRecognitionLike {\n lang: string;\n interimResults: boolean;\n continuous: boolean;\n maxAlternatives: number;\n onresult: ((event: SpeechRecognitionEventLike) => void) | null;\n onerror: (() => void) | null;\n onend: (() => void) | null;\n start(): void;\n stop(): void;\n abort(): void;\n}\n\ninterface SpeechRecognitionEventLike {\n resultIndex: number;\n results: ArrayLike<\n ArrayLike<{ transcript: string }> & { isFinal: boolean }\n >;\n}\n\ntype SpeechRecognitionCtor = new () => SpeechRecognitionLike;\n\n/**\n * Payload for the `mdLeadingIconClick` event. Emitted when the interactive\n * leading affordance (the morphing back/dismiss button, or a custom slotted\n * `leading` icon) is clicked.\n */\nexport interface MdSearchLeadingIconClickDetail {\n /** The bar's current input value at click time. */\n value: string;\n /** Whether the bar / panel is open at click time. */\n open: boolean;\n}\n\n/**\n * Payload for the `mdTrailingIconClick` event. Emitted when a slotted\n * `trailing` affordance is clicked (the built-in clear / voice buttons emit\n * their own `mdClear` / `mdVoice` events instead).\n */\nexport interface MdSearchTrailingIconClickDetail {\n /** The bar's current input value at click time. */\n value: string;\n /** Whether the bar / panel is open at click time. */\n open: boolean;\n}\n\n/**\n * Material Design 3 Search.\n *\n * Implements the M3 Search specification\n * (https://m3.material.io/components/search/specs).\n *\n * Two orthogonal axes describe every spec configuration:\n * - `variant`: `contained` (M3 Expressive default) | `divided` (baseline)\n * - `layout` : `full-screen` (modal overlay) | `docked` (anchored panel)\n *\n * The component renders a single resting bar plus a results panel. When the\n * `full-screen` layout is `open` the bar pins itself to the top of the\n * viewport via `position: fixed` so consumers don't need a portal — CSS does\n * the work, and the input keeps a stable identity throughout the open/close\n * lifecycle.\n */\n@Component({\n tag: 'md-search',\n styleUrl: 'md-search.css',\n shadow: true,\n})\nexport class MdSearch {\n @Element() el!: HTMLElement;\n\n // ────────────────────────────────────────────────────────────────────────\n // Spec axes\n // ────────────────────────────────────────────────────────────────────────\n\n /**\n * Visual style. `contained` is the M3 Expressive default with a filled\n * surface and rounded shape; `divided` is the baseline pre-Expressive look\n * that uses a hairline divider between bar and results.\n */\n @Prop({ reflect: true }) variant: 'contained' | 'divided' = 'contained';\n\n /**\n * How the focused panel appears. `full-screen` fills the viewport\n * edge-to-edge with an opaque results surface and a focus trap (no scrim —\n * open/close uses the same translateY + opacity motion as md-dialog\n * fullscreen); `docked` anchors a popup beneath the bar\n * (min 360dp / max 720dp wide; results drawer shrinks to content up to max ⅔ vh).\n */\n @Prop({ reflect: true }) layout: 'full-screen' | 'docked' = 'full-screen';\n\n /**\n * What the user sees while the search view is closed. `bar` renders the\n * resting search field (docked default). `icon` renders a compact search\n * icon button that opens the view — the default for `full-screen` layout\n * (contained and divided spec sheets). Docked layouts should keep `bar`.\n */\n @Prop({ reflect: true }) trigger?: 'bar' | 'icon';\n\n /**\n * Material Symbols glyph for the built-in icon trigger (`trigger=\"icon\"`).\n * Ignored when a custom element is slotted in `trigger`.\n */\n @Prop({ attribute: 'trigger-icon' }) triggerIcon: string = 'search';\n\n /**\n * Open the search from an element that lives ELSEWHERE on the page — a\n * button in the app bar, a menu item, a keyboard-shortcut hint — rather than\n * from the built-in trigger or the `trigger` slot, both of which have to sit\n * inside this element.\n *\n * Takes a CSS selector resolved against the document\n * (`trigger-for=\"#app-bar-search\"`), or an element assigned to the\n * `triggerElement` property when you already hold a reference. The component\n * wires it rather than rendering it: activating it opens the view,\n * `aria-haspopup=\"dialog\"` and `aria-expanded` are kept in step, and closing\n * returns focus to it.\n *\n * With one set, the built-in trigger is not rendered — otherwise the page\n * would show two ways in.\n */\n @Prop({ attribute: 'trigger-for' }) triggerFor: string = '';\n\n /** The external trigger as an element, for consumers that hold a reference. */\n @Prop() triggerElement?: HTMLElement;\n\n /**\n * Make the docked / inline bar span its container's full inline width with\n * NO side gutters. This zeroes both expand insets for the instance\n * (resting + focused = 0), so there is no 24 → 12dp margin animation and the\n * aligned results drawer fills the same full width. Purely an ergonomic\n * switch over the CSS vars — the identical effect is available by setting\n * `--md-search-expand-inset: 0` and `--md-search-expand-focused-inset: 0`.\n * Has no effect on `full-screen` layout (already edge-to-edge).\n */\n @Prop({ reflect: true, attribute: 'full-width' }) fullWidth: boolean = false;\n\n // ────────────────────────────────────────────────────────────────────────\n // Bar state\n // ────────────────────────────────────────────────────────────────────────\n\n /** Current input text, two-way bindable. */\n @Prop({ mutable: true, reflect: true }) value: string = '';\n\n /**\n * Placeholder text — the spec calls this \"supporting text\" within the bar\n * anatomy.\n */\n @Prop() placeholder: string = 'Search';\n\n /** Whether the focused panel is open. */\n @Prop({ mutable: true, reflect: true }) open: boolean = false;\n\n /** Whether interaction is blocked. */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /**\n * Resting bar elevation level, mapped to `--md-sys-elevation-{n}`. `0`\n * (the M3 default) renders no shadow; `1`–`5` apply the matching MD3\n * elevation tier. For a fully custom shadow, set the CSS custom property\n * `--md-search-container-elevation` instead (it overrides this prop).\n */\n @Prop({ reflect: true }) elevation: 0 | 1 | 2 | 3 | 4 | 5 = 0;\n\n // ────────────────────────────────────────────────────────────────────────\n // Icon configuration\n // ────────────────────────────────────────────────────────────────────────\n\n /** Material Symbols glyph for the resting leading icon. */\n @Prop({ attribute: 'leading-icon' }) leadingIcon: string = 'search';\n\n /**\n * Material Symbols glyph used for the leading button when the bar is\n * open. Defaults are variant-aware: the `contained` (Expressive) bar\n * uses `chevron_left` so the caret matches the bar's softer, pill-\n * shaped silhouette, while the `divided` (baseline) bar uses the\n * classic `arrow_back` to match its squared, app-bar-like chrome.\n * Pass an explicit value to override either default.\n */\n @Prop({ attribute: 'open-leading-icon' }) openLeadingIcon?: string;\n\n // ────────────────────────────────────────────────────────────────────────\n // Behaviour\n // ────────────────────────────────────────────────────────────────────────\n\n /** Show the trailing clear (×) button when the input has a value. */\n @Prop({ attribute: 'show-clear-button' }) showClearButton: boolean = true;\n\n /**\n * Opt-in voice search. When `true` AND the browser exposes the Web Speech\n * API (`SpeechRecognition` / `webkitSpeechRecognition`), a microphone\n * icon-button is rendered in the trailing cluster. Clicking it starts\n * recognition and streams the interim + final transcript into the input,\n * firing the normal `mdInput` / `mdSearch` flow as if typed. When the API is\n * unavailable the mic is not rendered (graceful no-op). Default `false`.\n */\n @Prop({ attribute: 'voice-search' }) voiceSearch: boolean = false;\n\n /** Close on Escape key. */\n @Prop({ attribute: 'escape-closes' }) escapeCloses: boolean = true;\n\n /** Close on outside click (docked layout). */\n @Prop({ attribute: 'dismiss-on-outside-click' }) dismissOnOutsideClick: boolean = true;\n\n /**\n * Retained for API compatibility, but now a no-op: when the results list\n * overflows it always plain-scrolls inside the results viewport (no scroll\n * shadow / edge fades). Setting this has no visual effect.\n */\n @Prop({ reflect: true, attribute: 'scroll-shadow' })\n scrollShadow: boolean = true;\n\n /**\n * Maximum block-size of the open search surface (`\"480px\"`, `\"66vh\"`, etc.).\n * Full-screen: caps the fixed overlay height. Docked: caps the results panel\n * (bar height is unchanged). Prefer the CSS custom property\n * `--md-search-max-block-size` for stylesheet-based theming.\n */\n @Prop({ attribute: 'max-block-size' }) maxBlockSize: string = '';\n\n /**\n * Accessible label for the search bar / input. Per the M3 labeling guidance\n * the hinted search text (`placeholder`) describes the bar, so when this is\n * left empty the label falls back to `placeholder`. Set it explicitly only\n * when the visible hint and the accessible name should differ.\n */\n @Prop({ attribute: 'input-aria-label' }) inputAriaLabel: string = '';\n\n /**\n * Where focus lands when the panel opens. `auto` (default) and `input` focus\n * the text field so the user can type immediately. `leading` focuses the\n * leading button instead (falling back to the input if it isn't focusable).\n *\n * Note: the M3 \"initial focus lands on a leading icon, else the text field\"\n * rule applies to the RESTING bar's first tab stop and is handled by DOM\n * order — a slotted interactive leading icon button is the first tabbable\n * element, otherwise the text field. This prop only controls the open view.\n */\n @Prop({ attribute: 'initial-focus' }) initialFocus: 'auto' | 'input' | 'leading' =\n 'auto';\n\n /**\n * Announce the number of available suggestions / results to assistive\n * technology via a polite live region whenever the slotted results change\n * while the panel is open (M3 \"autosuggest\" requirement). Set to `false`\n * if you manage your own live region in the results slot.\n */\n @Prop({ attribute: 'announce-results' }) announceResults: boolean = true;\n\n /**\n * Template for the results announcement. `{count}` is replaced with the\n * number of detected result items (counts `md-list-item`, `[role=\"option\"]`,\n * or `<li>` descendants of the results slot, falling back to the number of\n * slotted elements).\n */\n @Prop({ attribute: 'results-label' }) resultsLabel: string =\n '{count} results available';\n\n /**\n * Message shown when the panel is open, the user has entered a query, and\n * there are no slotted results — both the on-screen empty state and the\n * polite live-region announcement (unless the visible empty state is shown,\n * in which case the live region defers to it to avoid duplicate speech).\n */\n @Prop({ attribute: 'no-results-label' }) noResultsLabel: string =\n 'No results available';\n\n // ────────────────────────────────────────────────────────────────────────\n // Async / loading\n // ────────────────────────────────────────────────────────────────────────\n\n /**\n * Whether an async results fetch is in flight. When `true` the M3 loading\n * indicator (the looping shape-morph) shows in the bar's trailing cluster.\n * Controlled by the consumer: set it `true` before awaiting your fetch and\n * back to `false` once results are slotted in. The component never flips\n * this itself — it only reflects the state visually + to assistive tech.\n */\n @Prop({ mutable: true, reflect: true }) loading: boolean = false;\n\n /**\n * Trailing debounce (ms) applied to the `mdSearch` event so a fetch only\n * fires after the user pauses typing. `0` (default) emits on every change.\n * `mdInput` always fires immediately on every keystroke regardless.\n */\n @Prop() debounce: number = 0;\n\n /**\n * Maximum wait (ms) before `mdSearch` is forced to fire during sustained\n * typing — a throttle/`maxWait` safety net so the user still sees interim\n * results when they never pause long enough for the debounce to settle.\n * `0` (default) disables it. Only meaningful alongside a non-zero\n * `debounce`.\n */\n @Prop() throttle: number = 0;\n\n /** Accessible label for the in-bar loading indicator. */\n @Prop({ attribute: 'loading-label' }) loadingLabel: string = 'Searching';\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 // ────────────────────────────────────────────────────────────────────────\n // Events\n // ────────────────────────────────────────────────────────────────────────\n\n /** Fires on every input change (immediate, every keystroke). */\n @Event() mdInput: EventEmitter<{ value: string }>;\n\n /**\n * Debounced, de-duplicated query event — the one to wire an async results\n * fetch to. Honours `debounce` / `throttle` and applies a\n * distinct-until-changed guard on the trimmed query (so re-typing the same\n * term, or only adding surrounding whitespace, won't re-trigger a fetch).\n * Pressing Enter or clearing the field flushes it immediately.\n */\n @Event() mdSearch: EventEmitter<{ value: string }>;\n\n /** Fires when the user presses Enter to submit a query. */\n @Event() mdSubmit: EventEmitter<{ value: string }>;\n\n /** Fires when the input loses focus with a different value than on focus. */\n @Event() mdChange: EventEmitter<{ value: string }>;\n\n /** Fires when the panel opens. */\n @Event() mdOpen: EventEmitter<void>;\n\n /** Fires when the panel closes. */\n @Event() mdClose: EventEmitter<void>;\n\n /** Fires when the user clicks the clear (×) button. */\n @Event() mdClear: EventEmitter<void>;\n\n /**\n * Fires while voice search is active as the transcript streams in. `value`\n * is the current (interim or final) transcript; `final` is `true` on the\n * recognised final result. The component already mirrors the transcript into\n * the input and fires `mdInput` / `mdSearch`, so listen to this only if you\n * need voice-specific UI (e.g. a transcript preview).\n */\n @Event() mdVoice: EventEmitter<{ value: string; final: boolean }>;\n\n /**\n * Fires when the interactive leading affordance is clicked — the morphing\n * back / dismiss button while the bar is open, or a custom slotted `leading`\n * icon. The default back button still dismisses the panel as before; this\n * event is additive. The closed resting search glyph is intentionally NOT a\n * click target (a click there focuses the input), so it does not emit.\n */\n @Event() mdLeadingIconClick: EventEmitter<MdSearchLeadingIconClickDetail>;\n\n /**\n * Fires when a slotted `trailing` affordance is clicked. The built-in clear\n * (×) and voice (mic) buttons own their dedicated `mdClear` / `mdVoice`\n * events and do NOT trigger this. Only emitted when slotted trailing content\n * is actually present and was the click target.\n */\n @Event() mdTrailingIconClick: EventEmitter<MdSearchTrailingIconClickDetail>;\n\n // ────────────────────────────────────────────────────────────────────────\n // Methods\n // ────────────────────────────────────────────────────────────────────────\n\n /** Open the focused panel. */\n @Method() async show(): Promise<void> {\n this.open = true;\n }\n\n /** Close the focused panel. */\n @Method() async close(): Promise<void> {\n this.open = false;\n }\n\n /** Toggle the focused panel. */\n @Method() async toggle(): Promise<void> {\n this.open = !this.open;\n }\n\n /** Programmatically focus the input. */\n @Method() async focusInput(): Promise<void> {\n this.input?.focus();\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // Internals\n // ────────────────────────────────────────────────────────────────────────\n\n @State() private focused = false;\n @State() private hasSlottedLeading = false;\n @State() private hasSlottedTrailing = false;\n @State() private hasSlottedTrigger = false;\n /** Live-region message announcing the count of available results. */\n @State() private resultsStatus = '';\n /** Bar expansion / icon morph — lags `open` on close so the panel can fade first. */\n @State() private barExpanded = false;\n /** Results panel visibility / fade state — tracks `open` immediately on close. */\n @State() private panelVisible = false;\n /**\n * Whether to render the focus ring. Only true when focus arrives via the\n * keyboard — a text input always matches `:focus-visible` (even on click),\n * so we track focus modality ourselves to keep the ring keyboard-only.\n */\n @State() private showFocusRing = false;\n /** Whether voice recognition is currently active (drives the mic pulse). */\n @State() private listening = false;\n /**\n * Trailing loading↔clear morph state. `loadingMorphMounted` keeps the\n * loading indicator in the DOM through its fade-out so the swap cross-fades\n * in BOTH directions; `loadingMorphIn` is the visible (committed) state that\n * the entry/exit transitions animate between.\n */\n @State() private loadingMorphMounted = false;\n @State() private loadingMorphIn = false;\n\n /**\n * Whether the most recent user interaction came from the keyboard. Mirrors\n * the browser's `:focus-visible` heuristic so the bar's focus ring only shows\n * for keyboard focus — never on click — even when focus is moved\n * programmatically (e.g. when a click opens the view and we focus the input\n * in a later frame).\n */\n private keyboardModality = false;\n\n private input?: HTMLInputElement;\n private rippleEl?: HTMLElement;\n private insetProbeEl?: HTMLElement;\n private trailingSlotEl?: HTMLSlotElement;\n private resizeObserver?: ResizeObserver;\n private previousFocus: HTMLElement | null = null;\n private valueOnFocus: string = '';\n private outsideClickHandler?: (e: MouseEvent) => void;\n private closeTimer?: ReturnType<typeof setTimeout>;\n /**\n * Set when a full-screen open is waiting for the `position: fixed` overlay\n * layout to commit before the panel surface reveal. `componentDidRender`\n * picks it up so the fade animates over an already-settled layout\n * (see `onOpenChange`).\n */\n private pendingFullScreenReveal = false;\n private revealRaf?: number;\n /** Debounce / throttle timers + dedupe state for the `mdSearch` event. */\n private searchDebounceTimer?: ReturnType<typeof setTimeout>;\n private searchMaxWaitTimer?: ReturnType<typeof setTimeout>;\n private pendingSearchValue: string | null = null;\n private lastEmittedSearch: string | null = null;\n\n /** Full-screen close duration — keep in sync with `--_fs-collapse-duration` in md-search.css. */\n private static readonly PANEL_CLOSE_MS = 300;\n /** Loading↔clear morph duration — keep in sync with the CSS morph transition. */\n private static readonly MORPH_MS = 300;\n\n /** Active SpeechRecognition instance while listening (Web Speech API). */\n private recognition?: SpeechRecognitionLike;\n private loadingMorphTimer?: ReturnType<typeof setTimeout>;\n private loadingMorphInRaf?: number;\n\n // ────────────────────────────────────────────────────────────────────────\n // Lifecycle\n // ────────────────────────────────────────────────────────────────────────\n\n connectedCallback() {\n if (typeof document !== 'undefined') {\n // Capture phase so we record the modality before the resulting focus\n // event fires (and before any programmatic focus we trigger on open).\n document.addEventListener('keydown', this.trackKeyboardModality, true);\n document.addEventListener('pointerdown', this.trackPointerModality, true);\n }\n }\n\n componentWillLoad() {\n this.barExpanded = this.open;\n this.panelVisible = this.open;\n // Seed the loading morph so an initial `loading` renders without a flash.\n this.loadingMorphMounted = this.loading;\n this.loadingMorphIn = this.loading;\n // Seed the distinct-until-changed baseline with any initial value so the\n // first user-driven change emits correctly (and a programmatic initial\n // value is treated as already-searched, not re-fetched on mount).\n this.lastEmittedSearch = this.value.trim();\n // Compute the initial announcement here (light-DOM result children already\n // exist) so we don't mutate @State inside componentDidLoad.\n this.updateResultsStatus();\n }\n\n componentDidLoad() {\n this.wireExternalTrigger();\n const shadow = this.el.shadowRoot;\n if (!shadow) return;\n\n const leadingSlot = shadow.querySelector('slot[name=\"leading\"]') as HTMLSlotElement | null;\n const trailingSlot = shadow.querySelector('slot[name=\"trailing\"]') as HTMLSlotElement | null;\n // Kept for mdTrailingIconClick hit-testing against assigned (slotted) nodes.\n this.trailingSlotEl = trailingSlot ?? undefined;\n\n leadingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedLeading = leadingSlot.assignedElements().length > 0;\n });\n trailingSlot?.addEventListener('slotchange', () => {\n this.hasSlottedTrailing = trailingSlot.assignedElements().length > 0;\n });\n\n // Recompute the announcement when the slotted results change in a real\n // browser. The count itself is read from the host's light DOM (see\n // countResults) so it also works in environments without slotchange.\n const resultsSlot = shadow.querySelector(\n 'slot[name=\"results\"]',\n ) as HTMLSlotElement | null;\n resultsSlot?.addEventListener('slotchange', () => this.updateResultsStatus());\n\n const triggerSlot = shadow.querySelector(\n 'slot[name=\"trigger\"]',\n ) as HTMLSlotElement | null;\n triggerSlot?.addEventListener('slotchange', () => {\n this.hasSlottedTrigger = triggerSlot.assignedElements().length > 0;\n });\n this.hasSlottedTrigger = (triggerSlot?.assignedElements().length ?? 0) > 0;\n\n this.measureRippleExtend();\n this.observeHostResize();\n\n if (this.open) this.applyOpenSideEffects();\n }\n\n @Watch('triggerFor')\n @Watch('triggerElement')\n onExternalTriggerChange() {\n this.wireExternalTrigger();\n }\n\n disconnectedCallback() {\n this.unwireExternalTrigger();\n this.clearCloseTimer();\n this.cancelReveal();\n this.clearSearchTimers();\n this.stopVoice();\n this.clearLoadingMorphTimers();\n this.removeOutsideClickHandler();\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n if (typeof document !== 'undefined') {\n document.removeEventListener('keydown', this.trackKeyboardModality, true);\n document.removeEventListener('pointerdown', this.trackPointerModality, true);\n }\n if (this.layout === 'full-screen' && typeof document !== 'undefined') {\n document.body.style.removeProperty('overflow');\n }\n }\n\n /**\n * Resolve the bar's per-side focus travel to a concrete pixel length and\n * forward it to the ripple as `--md-ripple-extend-inline`. The docked/inline\n * bar springs from `100% - 2 * resting` to `100% - 2 * focused` on focus,\n * which moves each edge out by exactly `resting - focused` (24 → 12 = 12dp\n * default) — the probe resolves that delta. md-ripple\n * applies the extend PER SIDE — `left = rect.left - extend`,\n * `right = rect.right + extend` — so the per-side value it needs is one\n * inset, not two. (Forwarding `2 * inset` over-inflated the wave to ~2×\n * the actual growth, reading as an oversized wash near the press point.)\n * The default inset is the responsive `clamp(0px, 8%, 64px)`, so its\n * concrete length must be measured rather than parsed: a percentage would\n * resolve against the bar instead of the host once the token reaches\n * md-ripple's shadow tree, so we resolve it in JS via the host-anchored\n * probe (see md-search.css for the full rationale).\n */\n /**\n * Resolved trigger mode. Explicit `trigger` wins; otherwise full-screen\n * uses the icon button entry point and docked keeps the resting bar.\n */\n private get effectiveTrigger(): 'bar' | 'icon' {\n // An external opener owns the resting affordance, so the component keeps\n // nothing on screen until it opens — the same \"hidden until invoked\"\n // shape as the icon trigger, minus the icon.\n if (this.hasExternalTrigger) return 'icon';\n if (this.trigger != null) return this.trigger;\n return this.layout === 'full-screen' ? 'icon' : 'bar';\n }\n\n /** Whether the consumer has pointed at an opener outside this element. */\n private get hasExternalTrigger(): boolean {\n return Boolean(this.triggerFor || this.triggerElement);\n }\n\n private get usesIconTrigger(): boolean {\n return this.effectiveTrigger === 'icon';\n }\n\n // ── External trigger ──────────────────────────────────────────────────\n\n /** The element currently wired as the external opener, if any. */\n private wiredTrigger: HTMLElement | null = null;\n\n private resolveExternalTrigger(): HTMLElement | null {\n if (this.triggerElement) return this.triggerElement;\n if (!this.triggerFor || typeof document === 'undefined') return null;\n const sel = this.triggerFor.trim();\n if (!sel) return null;\n try {\n return document.querySelector(sel) as HTMLElement | null;\n } catch {\n // A malformed selector is an authoring mistake, not a reason to break the\n // search — warn once and carry on with the built-in trigger.\n if (typeof console !== 'undefined') {\n console.warn('[md-search] `trigger-for` is not a valid selector:', this.triggerFor);\n }\n return null;\n }\n }\n\n private wireExternalTrigger() {\n const next = this.resolveExternalTrigger();\n if (next === this.wiredTrigger) {\n this.syncExternalTriggerAria();\n return;\n }\n this.unwireExternalTrigger();\n if (!next) return;\n next.addEventListener('click', this.handleExternalTriggerClick);\n this.wiredTrigger = next;\n this.syncExternalTriggerAria();\n }\n\n private unwireExternalTrigger() {\n this.wiredTrigger?.removeEventListener('click', this.handleExternalTriggerClick);\n this.wiredTrigger?.removeAttribute('aria-expanded');\n this.wiredTrigger = null;\n }\n\n /** The element is the consumer's, so it is wired rather than re-rendered. */\n private handleExternalTriggerClick = (e: Event) => {\n if (this.disabled) return;\n // The document-level outside-click handler runs in the CAPTURE phase, and\n // the trigger is outside this element — without this the same click would\n // close an open panel and then reopen it, or open and immediately close.\n e.stopPropagation();\n this.open = !this.open;\n };\n\n private syncExternalTriggerAria() {\n const t = this.wiredTrigger;\n if (!t) return;\n t.setAttribute('aria-haspopup', 'dialog');\n t.setAttribute('aria-expanded', String(this.open));\n }\n\n /** Whether the search bar chrome is in the DOM (icon trigger hides it until open). */\n private get showBar(): boolean {\n return !this.usesIconTrigger || this.barExpanded;\n }\n\n private measureRippleExtend() {\n if (!this.showBar) return;\n const ripple = this.rippleEl;\n if (!ripple) return;\n\n // Full-screen: the bar snaps from its resting (inset / max-720dp) width\n // to the full viewport width on open. md-ripple sizes the wave from the\n // bar's rect AT PRESS TIME — the resting width — so without an extend the\n // wave only covers the initial bar and stops half-way across the\n // expanded full-screen bar. Inflate the farthest-corner reach by exactly\n // the growth delta (viewport − resting bar width). That sizes the wave\n // to finish filling right as it reaches the expanded bar's far edge —\n // not so much that it fills instantly (which reads as a flat wash) — and\n // keeps the wave's origin near the press point. When the bar is already\n // open its width ≈ the viewport, so the delta collapses to ~0 and the\n // normal press-sized ripple is used.\n if (this.layout === 'full-screen' && typeof window !== 'undefined') {\n const bar = this.el.shadowRoot?.querySelector('.md-search__bar') as HTMLElement | null;\n const barWidth = bar?.getBoundingClientRect().width ?? 0;\n const delta = window.innerWidth - barWidth;\n if (delta > 1) {\n ripple.style.setProperty('--md-ripple-extend-inline', `${delta}px`);\n return;\n }\n }\n\n const probe = this.insetProbeEl;\n if (!probe) return;\n const inset = probe.getBoundingClientRect().width;\n if (!Number.isFinite(inset) || inset <= 0) {\n ripple.style.removeProperty('--md-ripple-extend-inline');\n return;\n }\n ripple.style.setProperty('--md-ripple-extend-inline', `${inset}px`);\n }\n\n private observeHostResize() {\n if (typeof ResizeObserver === 'undefined') return;\n this.resizeObserver = new ResizeObserver(() => {\n // The ripple extent only matters for the resting → press expansion, which\n // is measured before the view opens. Re-measuring while the bar is\n // expanded (or mid open/close transition) would call getBoundingClientRect\n // — a forced synchronous reflow — on the very frames the full-screen\n // reveal animates, stuttering it. Skip until the bar is back at rest.\n if (this.barExpanded) return;\n this.measureRippleExtend();\n });\n this.resizeObserver.observe(this.el);\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // Open / close side effects\n // ────────────────────────────────────────────────────────────────────────\n\n @Watch('open')\n onOpenChange(newVal: boolean, oldVal: boolean) {\n if (newVal === oldVal) return;\n this.clearCloseTimer();\n this.cancelReveal();\n if (newVal) {\n // Expand the bar first — in full-screen this flips the host to the\n // position:fixed overlay (a one-off layout + paint). The panel surface\n // reveal is deferred to AFTER that layout has committed and painted\n // (see componentDidRender) so the fade is a pure compositor\n // transition over a settled layout. Doing both in the same frame made\n // the reveal compete with the overlay relayout and stuttered it.\n this.barExpanded = true;\n if (this.layout === 'full-screen') {\n this.pendingFullScreenReveal = true;\n } else {\n // Docked keeps the host in-flow, so there's no overlay relayout to\n // wait on — reveal synchronously.\n this.panelVisible = true;\n }\n this.applyOpenSideEffects();\n this.updateResultsStatus();\n this.syncExternalTriggerAria();\n this.mdOpen.emit();\n } else {\n // Panel surface fades out first; bar contraction follows after the fade.\n this.pendingFullScreenReveal = false;\n this.panelVisible = false;\n // Closing the view (Escape, back button, outside/dismiss) ends any\n // active voice session — the input has lost its search context.\n this.stopVoice();\n this.removeOutsideClickHandler();\n this.updateResultsStatus();\n this.mdClose.emit();\n this.syncExternalTriggerAria();\n this.closeTimer = setTimeout(() => {\n this.barExpanded = false;\n this.finishCloseSideEffects();\n // An external opener is the thing the user left to get here, so it is\n // where focus belongs on the way back — the built-in trigger gets this\n // for free by being inside the component.\n if (this.wiredTrigger && typeof document !== 'undefined') {\n const active = document.activeElement;\n const inSearch = active === this.el || this.el.contains(active as Node);\n if (active === document.body || inSearch) this.wiredTrigger.focus?.();\n }\n this.closeTimer = undefined;\n }, MdSearch.PANEL_CLOSE_MS);\n }\n }\n\n @Watch('loading')\n onLoadingChange(newVal: boolean) {\n // Re-announce so screen readers hear \"Searching…\" while the fetch is in\n // flight and the result count once it resolves.\n this.updateResultsStatus();\n this.updateLoadingMorph(newVal);\n }\n\n /**\n * Drive the trailing loading↔clear cross-fade. Mounting the loading\n * indicator immediately (and committing the visible state on the next frame)\n * animates the entry; keeping it mounted for one morph duration after\n * `loading` clears animates the exit before it unmounts.\n */\n private updateLoadingMorph(loading: boolean) {\n this.clearLoadingMorphTimers();\n if (loading) {\n this.loadingMorphMounted = true;\n if (typeof requestAnimationFrame === 'undefined') {\n this.loadingMorphIn = true;\n return;\n }\n this.loadingMorphInRaf = requestAnimationFrame(() => {\n this.loadingMorphInRaf = undefined;\n if (this.loading) this.loadingMorphIn = true;\n });\n } else {\n this.loadingMorphIn = false;\n this.loadingMorphTimer = setTimeout(() => {\n this.loadingMorphTimer = undefined;\n if (!this.loading) this.loadingMorphMounted = false;\n }, MdSearch.MORPH_MS);\n }\n }\n\n private clearLoadingMorphTimers() {\n if (this.loadingMorphTimer) {\n clearTimeout(this.loadingMorphTimer);\n this.loadingMorphTimer = undefined;\n }\n if (this.loadingMorphInRaf !== undefined && typeof cancelAnimationFrame !== 'undefined') {\n cancelAnimationFrame(this.loadingMorphInRaf);\n this.loadingMorphInRaf = undefined;\n }\n }\n\n componentDidRender() {\n if (!this.pendingFullScreenReveal) return;\n // The host's position:fixed overlay layout (floating bar + the\n // full-viewport panel surface) is now committed to the DOM and will\n // paint at the end of this frame while the panel is still transparent.\n // Flip the reveal on the NEXT frame so the opacity fade starts\n // from that painted, settled layout — no relayout on the animating\n // frames, which is what made the open read as stepped / slow.\n this.pendingFullScreenReveal = false;\n if (typeof requestAnimationFrame === 'undefined') {\n this.panelVisible = true;\n return;\n }\n this.revealRaf = requestAnimationFrame(() => {\n this.revealRaf = undefined;\n // Guard against a close that landed between the layout commit and here.\n if (this.open) this.panelVisible = true;\n });\n }\n\n private cancelReveal() {\n if (this.revealRaf !== undefined && typeof cancelAnimationFrame !== 'undefined') {\n cancelAnimationFrame(this.revealRaf);\n }\n this.revealRaf = undefined;\n }\n\n private clearCloseTimer() {\n if (this.closeTimer === undefined) return;\n clearTimeout(this.closeTimer);\n this.closeTimer = undefined;\n }\n\n private applyOpenSideEffects() {\n if (typeof document === 'undefined') return;\n this.previousFocus = (document.activeElement as HTMLElement) ?? null;\n if (this.layout === 'full-screen') {\n // Lock document scroll. Compensate for the removed scrollbar with an\n // equal-width padding so the page (and the fixed overlay) doesn't\n // shift sideways when the scrollbar disappears — that lateral jump\n // was the main source of the open/close jitter.\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n if (scrollbarWidth > 0) {\n document.body.style.paddingInlineEnd = `${scrollbarWidth}px`;\n }\n document.body.style.overflow = 'hidden';\n }\n this.attachOutsideClickHandler();\n if (typeof requestAnimationFrame !== 'undefined') {\n requestAnimationFrame(() => this.focusInitialTarget());\n } else {\n this.focusInitialTarget();\n }\n }\n\n /**\n * Focus the open view's initial target. Defaults to the text field so the\n * user can type immediately; `initialFocus=\"leading\"` focuses the leading\n * button instead. (The resting bar's leading-icon-first tab order is handled\n * by DOM order, not here.)\n */\n private focusInitialTarget() {\n const target = this.resolveInitialFocusTarget();\n // preventScroll: focusing the input must not trigger a scroll-into-view,\n // which forces a synchronous layout on the same frame the open transition\n // starts and stutters the reveal.\n target?.focus?.({ preventScroll: true });\n }\n\n private resolveInitialFocusTarget(): HTMLElement | undefined {\n // Opening the search view is about typing, so by default focus the text\n // field. The M3 \"initial focus lands on a leading icon, else the text\n // field\" rule is satisfied by the RESTING tab order: a slotted interactive\n // leading icon button is the first tabbable element, otherwise the input.\n // `initialFocus=\"leading\"` opts the open view into focusing the leading\n // button instead.\n if (this.initialFocus === 'leading') {\n return this.leadingFocusTarget() ?? this.input;\n }\n return this.input;\n }\n\n /**\n * The focusable element representing the leading action: a focusable slotted\n * leading element (or its first inner focusable), falling back to the\n * built-in leading button when it's interactive (i.e. the bar is open).\n */\n private leadingFocusTarget(): HTMLElement | undefined {\n const focusableSel =\n 'button, a[href], input, select, textarea, md-icon-button, md-button, [tabindex]:not([tabindex=\"-1\"])';\n const slotted = this.el.querySelector('[slot=\"leading\"]') as HTMLElement | null;\n if (slotted) {\n if (typeof slotted.focus === 'function' && slotted.getAttribute('tabindex') !== '-1') {\n if (slotted.matches(focusableSel)) return slotted;\n }\n const inner = slotted.querySelector(focusableSel) as HTMLElement | null;\n if (inner) return inner;\n return slotted;\n }\n const builtin = this.el.shadowRoot?.querySelector(\n '.md-search__leading-button',\n ) as HTMLElement | null;\n if (builtin && builtin.getAttribute('tabindex') !== '-1') return builtin;\n return undefined;\n }\n\n private finishCloseSideEffects() {\n if (typeof document !== 'undefined' && this.layout === 'full-screen') {\n document.body.style.removeProperty('overflow');\n document.body.style.removeProperty('padding-inline-end');\n }\n this.previousFocus?.focus?.();\n this.previousFocus = null;\n }\n\n private attachOutsideClickHandler() {\n if (!this.dismissOnOutsideClick || typeof document === 'undefined') return;\n this.outsideClickHandler = (e: MouseEvent) => {\n const target = e.target as Node | null;\n if (!target) return;\n const path = e.composedPath ? e.composedPath() : [];\n if (path.includes(this.el)) return;\n if (this.el.contains(target)) return;\n // An external trigger is by definition outside this element. Closing on\n // its mousedown would fight its own click handler — the view would shut\n // and reopen in the same gesture — so let the trigger own the toggle.\n const trigger = this.wiredTrigger;\n if (trigger && (path.includes(trigger) || trigger.contains(target))) return;\n this.open = false;\n };\n document.addEventListener('mousedown', this.outsideClickHandler, true);\n }\n\n private removeOutsideClickHandler() {\n if (this.outsideClickHandler && typeof document !== 'undefined') {\n document.removeEventListener('mousedown', this.outsideClickHandler, true);\n }\n this.outsideClickHandler = undefined;\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // Bar handlers\n // ────────────────────────────────────────────────────────────────────────\n\n private handleTriggerActivate = () => {\n if (this.disabled) return;\n if (!this.open) this.open = true;\n };\n\n private handleTriggerClick = (e: MouseEvent) => {\n e.stopPropagation();\n this.handleTriggerActivate();\n };\n\n private handleTriggerKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Enter' && e.key !== ' ') return;\n e.preventDefault();\n this.handleTriggerActivate();\n };\n\n private handleBarClick = (e: MouseEvent) => {\n if (this.disabled) return;\n // Ignore clicks that originated inside the trailing cluster (those\n // belong to icon buttons / avatars) so they don't toggle the panel.\n const target = e.target as HTMLElement;\n if (target.closest('[part=\"trailing\"]')) return;\n if (!this.open) this.open = true;\n this.input?.focus();\n };\n\n private handleLeadingClick = (e: MouseEvent) => {\n if (this.disabled) return;\n // The default leading button is interactive only while the bar is open —\n // clicking the morphed back-arrow dismisses the search. When closed, it is\n // non-interactive (pointer-events: none in CSS) so clicks fall through to\n // the bar's own handler which focuses the input. A custom slotted `leading`\n // icon, by contrast, is interactive in any state.\n const slotted = this.hasSlottedLeading;\n const interactiveDefault = !slotted && this.open;\n // Closed resting search glyph (no slot, not open): not a click target —\n // let it bubble to the bar to focus the input. No event.\n if (!slotted && !interactiveDefault) return;\n\n this.mdLeadingIconClick.emit({ value: this.value, open: this.open });\n\n // Preserve the default back-button dismiss behaviour; the slotted variant\n // leaves bar semantics to the consumer.\n if (interactiveDefault) {\n e.stopPropagation();\n this.open = false;\n }\n };\n\n private handleTrailingClick = (e: MouseEvent) => {\n if (this.disabled) return;\n const path = (typeof e.composedPath === 'function'\n ? e.composedPath()\n : []) as Array<EventTarget>;\n const nodes = path.length ? path : [e.target as EventTarget];\n // The clear (×) and voice (mic) affordances emit their own dedicated\n // events (mdClear / mdVoice) — don't double-fire a generic trailing event.\n const isOwnAffordance = nodes.some((n) => {\n const cl = (n as Partial<HTMLElement>)?.classList;\n return (\n !!cl?.contains?.('md-search__clear') ||\n !!cl?.contains?.('md-search__voice')\n );\n });\n if (isOwnAffordance) return;\n // Only emit when a slotted trailing affordance is actually present and was\n // the click target (ignore empty wrapper padding / the morph box). Read the\n // slot's assigned nodes directly rather than the slotchange-driven state,\n // which isn't seeded for content present at first render.\n const assigned = this.trailingSlotEl?.assignedElements?.() ?? [];\n if (assigned.length === 0) return;\n const target = nodes[0] as Node | undefined;\n const hitSlotted = assigned.some(\n (el) => el === target || (target ? el.contains(target) : false),\n );\n if (!hitSlotted) return;\n\n // Treat the slotted affordance like the built-in icon buttons: don't let\n // the click bubble to the bar and toggle the panel.\n e.stopPropagation();\n this.mdTrailingIconClick.emit({ value: this.value, open: this.open });\n };\n\n private handleClearClick = (e: MouseEvent) => {\n e.stopPropagation();\n if (this.disabled) return;\n this.value = '';\n this.input?.focus();\n this.mdInput.emit({ value: '' });\n // Clearing should drop results immediately — flush past any pending\n // debounce so the empty query reaches the consumer without delay.\n this.pendingSearchValue = '';\n this.flushSearch();\n this.mdClear.emit();\n };\n\n // ────────────────────────────────────────────────────────────────────────\n // Voice search (Web Speech API)\n // ────────────────────────────────────────────────────────────────────────\n\n /** Resolve the (possibly prefixed) SpeechRecognition constructor, if any. */\n private getSpeechRecognitionCtor(): SpeechRecognitionCtor | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as unknown as {\n SpeechRecognition?: SpeechRecognitionCtor;\n webkitSpeechRecognition?: SpeechRecognitionCtor;\n };\n return w.SpeechRecognition || w.webkitSpeechRecognition;\n }\n\n /** Whether the Web Speech API is available in this environment. */\n private isVoiceSupported(): boolean {\n return !!this.getSpeechRecognitionCtor();\n }\n\n private resolveVoiceLang(): string {\n if (typeof document !== 'undefined') {\n const lang = this.el.getAttribute('lang') || document.documentElement.lang;\n if (lang) return lang;\n }\n return 'en-US';\n }\n\n private handleVoiceClick = (e: MouseEvent) => {\n // Keep the bar's click handler from re-toggling the panel.\n e.stopPropagation();\n if (this.disabled) return;\n if (this.listening) {\n this.stopVoice();\n } else {\n this.startVoice();\n }\n };\n\n /** Start streaming voice transcription into the input. No-op if unsupported. */\n @Method() async startVoice(): Promise<void> {\n this.startVoiceInternal();\n }\n\n /** Stop any active voice transcription. */\n @Method() async stopVoice(): Promise<void> {\n this.listening = false;\n if (this.recognition) {\n try {\n this.recognition.stop();\n } catch {\n /* stop() throws if not started — safe to ignore. */\n }\n }\n }\n\n private startVoiceInternal() {\n const Ctor = this.getSpeechRecognitionCtor();\n if (!Ctor || this.disabled || this.listening) return;\n if (this.recognition) {\n try {\n this.recognition.abort();\n } catch {\n /* no-op */\n }\n this.recognition = undefined;\n }\n const recognition = new Ctor();\n recognition.lang = this.resolveVoiceLang();\n recognition.interimResults = true;\n recognition.continuous = false;\n recognition.maxAlternatives = 1;\n recognition.onresult = this.handleVoiceResult;\n recognition.onerror = this.handleVoiceEnd;\n recognition.onend = this.handleVoiceEnd;\n this.recognition = recognition;\n // Opening the view surfaces streamed results just like typing would.\n if (!this.open) this.open = true;\n this.input?.focus();\n this.listening = true;\n try {\n recognition.start();\n } catch {\n // start() throws if invoked while already running — reset our state.\n this.listening = false;\n this.recognition = undefined;\n }\n }\n\n private handleVoiceResult = (event: SpeechRecognitionEventLike) => {\n let transcript = '';\n let isFinal = false;\n const results = event.results;\n for (let i = 0; i < results.length; i++) {\n transcript += results[i][0].transcript;\n if (results[i].isFinal) isFinal = true;\n }\n transcript = transcript.replace(/^\\s+/, '');\n // Mirror the transcript into the input and drive the normal typed flow.\n this.value = transcript;\n if (!this.open) this.open = true;\n this.mdInput.emit({ value: transcript });\n this.scheduleSearch(transcript);\n this.mdVoice.emit({ value: transcript, final: isFinal });\n if (isFinal) {\n // Flush the final query immediately, then end the session.\n this.pendingSearchValue = transcript;\n this.flushSearch();\n this.stopVoice();\n }\n };\n\n private handleVoiceEnd = () => {\n this.listening = false;\n this.recognition = undefined;\n };\n\n private handleInput = (e: Event) => {\n const next = (e.target as HTMLInputElement).value;\n this.value = next;\n // Typing activates the search view (it isn't opened by focus alone).\n if (!this.open && !this.disabled) this.open = true;\n // mdInput is immediate (every keystroke); mdSearch is debounced/throttled.\n this.mdInput.emit({ value: next });\n this.scheduleSearch(next);\n };\n\n // ────────────────────────────────────────────────────────────────────────\n // Debounced search emission (debounce + throttle + distinctUntilChanged)\n // ────────────────────────────────────────────────────────────────────────\n\n /**\n * Queue an `mdSearch` emission for `value`, honouring `debounce` (trailing\n * wait for a typing pause) and `throttle` (maxWait — guarantees an emit at\n * least every `throttle` ms during sustained typing). With both at `0` the\n * emit is synchronous. Either way the actual emit is de-duplicated in\n * `flushSearch` (distinct-until-changed on the trimmed query).\n */\n private scheduleSearch(value: string) {\n this.pendingSearchValue = value;\n const debounceMs = Math.max(0, Number(this.debounce) || 0);\n const throttleMs = Math.max(0, Number(this.throttle) || 0);\n\n if (debounceMs === 0 && throttleMs === 0) {\n this.flushSearch();\n return;\n }\n\n // (Re)start the trailing debounce timer on every keystroke.\n if (this.searchDebounceTimer) clearTimeout(this.searchDebounceTimer);\n this.searchDebounceTimer = setTimeout(() => this.flushSearch(), debounceMs);\n\n // Throttle / maxWait: if the user keeps typing past `throttle` ms without\n // the debounce ever settling, force an emit so interim results still show.\n if (throttleMs > 0 && this.searchMaxWaitTimer === undefined) {\n this.searchMaxWaitTimer = setTimeout(() => this.flushSearch(), throttleMs);\n }\n }\n\n /** Emit the pending query now (clearing timers), if it differs from the last. */\n private flushSearch() {\n this.clearSearchTimers();\n if (this.pendingSearchValue === null) return;\n const value = this.pendingSearchValue;\n this.pendingSearchValue = null;\n const normalized = value.trim();\n if (normalized === this.lastEmittedSearch) return; // distinctUntilChanged\n this.lastEmittedSearch = normalized;\n this.mdSearch.emit({ value: normalized });\n }\n\n private clearSearchTimers() {\n if (this.searchDebounceTimer) {\n clearTimeout(this.searchDebounceTimer);\n this.searchDebounceTimer = undefined;\n }\n if (this.searchMaxWaitTimer) {\n clearTimeout(this.searchMaxWaitTimer);\n this.searchMaxWaitTimer = undefined;\n }\n }\n\n /** Global modality trackers (capture phase) — see `keyboardModality`. */\n private trackKeyboardModality = () => {\n this.keyboardModality = true;\n };\n private trackPointerModality = () => {\n this.keyboardModality = false;\n };\n\n private handleInputFocus = () => {\n // Focus (e.g. via Tab) must NOT open the search view — it only moves focus.\n // The view opens on explicit activation: typing, Enter / Space, or click\n // (M3 keyboard spec: \"Space or Enter activates the search text field\").\n this.focused = true;\n // The focus ring is keyboard-only: show it only when the latest interaction\n // was via the keyboard (Tab, Enter / Space activation, arrows).\n this.showFocusRing = this.keyboardModality;\n this.valueOnFocus = this.value;\n };\n\n private handleInputBlur = () => {\n this.focused = false;\n this.showFocusRing = false;\n if (this.value !== this.valueOnFocus) {\n this.mdChange.emit({ value: this.value });\n }\n };\n\n private handleInputKeyDown = (e: KeyboardEvent) => {\n if (this.disabled) return;\n // When closed, Enter / Space activate the field for input (open the view)\n // rather than submitting / inserting a space.\n if (!this.open) {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.open = true;\n }\n return;\n }\n if (e.key === 'Enter') {\n // Submitting should fetch the current query at once — flush past any\n // pending debounce before notifying submit listeners.\n this.pendingSearchValue = this.value;\n this.flushSearch();\n this.mdSubmit.emit({ value: this.value });\n }\n };\n\n @Listen('keydown', { target: 'window' })\n handleWindowKeyDown(e: KeyboardEvent) {\n if (!this.open) return;\n if (e.key === 'Escape' && this.escapeCloses) {\n e.preventDefault();\n this.open = false;\n return;\n }\n // Arrow keys move focus between the slotted search result items (M3\n // keyboard spec). Down from the input lands on the first item; Up from the\n // first item returns to the input.\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n if (this.moveResultFocus(e.key === 'ArrowDown' ? 1 : -1)) {\n e.preventDefault();\n }\n return;\n }\n // Focus trap (full-screen only — docked is non-modal so Tab should\n // continue to the document like any other popup).\n if (this.layout !== 'full-screen' || e.key !== 'Tab') return;\n const focusables = this.collectFocusables();\n if (focusables.length === 0) return;\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n const active = (this.el.shadowRoot?.activeElement ?? document.activeElement) as HTMLElement | null;\n if (e.shiftKey && active === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && active === last) {\n e.preventDefault();\n first.focus();\n }\n }\n\n private collectFocusables(): HTMLElement[] {\n const root = this.el.shadowRoot;\n if (!root) return [];\n const sel =\n 'a[href], button, input, select, textarea, [tabindex]:not([tabindex=\"-1\"]), md-icon-button, md-button';\n const inShadow = Array.from(root.querySelectorAll(sel)) as HTMLElement[];\n const inLight = Array.from(this.el.querySelectorAll(sel)) as HTMLElement[];\n return [...inShadow, ...inLight].filter((node) => {\n if (node.hasAttribute('disabled')) return false;\n const tabindex = node.getAttribute('tabindex');\n return tabindex !== '-1';\n });\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // Autosuggest announcements (live region)\n // ────────────────────────────────────────────────────────────────────────\n\n /**\n * Count the result items the consumer placed in `slot=\"results\"`. Reads the\n * host's light DOM (the slotted elements are children of `<md-search>`) so it\n * works regardless of slot/flatten support. Prefers semantic item selectors\n * (`md-list-item`, `[role=\"option\"]`, `<li>`) so a single wrapping list\n * doesn't read as one result; falls back to the number of slotted containers\n * when no items are found.\n */\n private countResults(): number {\n const containers = Array.from(\n this.el.querySelectorAll('[slot=\"results\"]'),\n ) as HTMLElement[];\n const itemSelector =\n 'md-list-item, [role=\"option\"], li, [data-search-result]';\n const items = new Set<Element>();\n for (const el of containers) {\n if (el.matches(itemSelector)) items.add(el);\n el.querySelectorAll(itemSelector).forEach((node) => items.add(node));\n }\n return items.size > 0 ? items.size : containers.length;\n }\n\n /**\n * The slotted result items, in DOM order. Uses the same semantic item\n * selectors as the announcement counter so arrow navigation steps through\n * the real list rows rather than a wrapping container.\n */\n private resultItems(): HTMLElement[] {\n const itemSelector =\n 'md-list-item, [role=\"option\"], [role=\"menuitem\"], [data-search-result], li';\n const containers = Array.from(\n this.el.querySelectorAll('[slot=\"results\"]'),\n ) as HTMLElement[];\n const items = new Set<HTMLElement>();\n for (const el of containers) {\n if (el.matches(itemSelector)) items.add(el);\n el.querySelectorAll(itemSelector).forEach((node) =>\n items.add(node as HTMLElement),\n );\n }\n return Array.from(items);\n }\n\n /**\n * Move focus across result items by `delta` (+1 / -1). Returns `true` if it\n * handled the key (so the caller can `preventDefault`). Stepping up past the\n * first item returns focus to the text field.\n */\n private moveResultFocus(delta: number): boolean {\n const items = this.resultItems();\n if (items.length === 0) return false;\n const active = (this.el.shadowRoot?.activeElement ??\n (typeof document !== 'undefined' ? document.activeElement : null)) as\n | HTMLElement\n | null;\n const current = active\n ? items.findIndex((it) => it === active || it.contains(active))\n : -1;\n\n if (delta > 0) {\n const next = current < 0 ? 0 : Math.min(current + 1, items.length - 1);\n this.focusResultItem(items[next]);\n return true;\n }\n // delta < 0\n if (current <= 0) {\n this.input?.focus();\n return true;\n }\n this.focusResultItem(items[current - 1]);\n return true;\n }\n\n private focusResultItem(item: HTMLElement) {\n // Make the row programmatically focusable if the consumer hasn't (roving\n // tabindex) so .focus() lands and screen readers announce the row.\n if (item.getAttribute('tabindex') === null) {\n item.setAttribute('tabindex', '-1');\n }\n item.focus?.();\n }\n\n /**\n * Recompute the polite live-region message. Only speaks while the panel is\n * open so suggestions are announced as they appear / change; clears when\n * closed so re-opening re-announces.\n */\n private updateResultsStatus() {\n if (!this.announceResults || !this.open) {\n this.resultsStatus = '';\n return;\n }\n // While a fetch is in flight, announce the loading state rather than a\n // (stale) count so screen-reader users know results are on the way.\n if (this.loading) {\n this.resultsStatus = this.loadingLabel;\n return;\n }\n const count = this.countResults();\n if (count > 0) {\n this.resultsStatus = this.resultsLabel.replace('{count}', String(count));\n } else if (this.shouldShowVisibleEmptyState()) {\n // The visible empty state (role=\"status\", aria-live) owns this copy.\n this.resultsStatus = '';\n } else {\n this.resultsStatus = this.value.trim() ? this.noResultsLabel : '';\n }\n }\n\n /**\n * Whether to render the on-screen empty state in the results panel.\n * Requires an open panel, a non-empty query, zero detected result rows,\n * and no in-flight loading fetch.\n */\n private shouldShowVisibleEmptyState(): boolean {\n return (\n this.panelVisible &&\n !this.loading &&\n this.countResults() === 0 &&\n this.value.trim().length > 0\n );\n }\n\n /**\n * Whether the results panel should render visible chrome (divider, drawer,\n * empty state, slotted list). When the bar is open but there is nothing to\n * show yet — no query, no rows, not loading — keep the bar alone so a stray\n * divider or empty panel shell does not appear under it.\n */\n private shouldShowResultsChrome(): boolean {\n if (!this.panelVisible || this.loading) return false;\n if (this.countResults() > 0) return true;\n return this.shouldShowVisibleEmptyState();\n }\n\n /**\n * Whether the results panel surface is visible (opacity / pointer-events).\n * Full-screen open is always an edge-to-edge overlay once the panel commits,\n * even before slotted rows are detected. Docked / inline only open the drawer\n * when there is meaningful content to show.\n */\n private isPanelRevealed(): boolean {\n if (this.layout === 'full-screen') {\n return this.panelVisible && this.barExpanded;\n }\n return this.shouldShowResultsChrome();\n }\n\n /**\n * The accessible name for the bar / input. Falls back to the hinted search\n * text (`placeholder`) per the M3 labeling guidance when `inputAriaLabel`\n * isn't set.\n */\n private effectiveLabel(): string {\n return this.inputAriaLabel || this.placeholder || 'Search';\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // Render helpers\n // ────────────────────────────────────────────────────────────────────────\n\n /**\n * Resolve the open-state glyph. When a consumer hasn't passed\n * `open-leading-icon` we fall back to a variant-aware default —\n * `chevron_left` for the Expressive `contained` bar (whose pill shape\n * pairs better with a caret) and the spec-canonical `arrow_back` for\n * the baseline `divided` bar.\n */\n private resolveOpenLeadingIcon(): string {\n if (this.openLeadingIcon) return this.openLeadingIcon;\n return this.variant === 'contained' ? 'chevron_left' : 'arrow_back';\n }\n\n private renderTrigger() {\n if (!this.usesIconTrigger || this.barExpanded) return null;\n // An external opener replaces the built-in one — two ways in would be a\n // confusing surface, and only one of them can own the focus round trip.\n if (this.hasExternalTrigger) return null;\n\n return (\n <div class=\"md-search__trigger\" part=\"trigger\">\n <slot name=\"trigger\">\n <md-icon-button\n class=\"md-search__trigger-button\"\n part=\"trigger-button\"\n icon={this.triggerIcon}\n variant=\"standard\"\n size=\"md\"\n disabled={this.disabled}\n aria-label={this.effectiveLabel()}\n onClick={this.handleTriggerClick}\n onKeyDown={this.handleTriggerKeyDown}\n ></md-icon-button>\n </slot>\n </div>\n );\n }\n\n private renderLeading() {\n // The leading button is always rendered with BOTH glyphs stacked so the\n // search ↔ back-arrow change reads as a single icon morphing rather than\n // two icons swapping. The `--button` modifier flips on as soon as the\n // bar is open in either layout (M3 docked panels traditionally keep the\n // search glyph, but the morph affordance reads better and ties the\n // dismiss action to a single, predictable spot).\n const showCloseButton = this.barExpanded;\n const ariaLabel = showCloseButton ? 'Close search' : 'Search';\n const openGlyph = this.resolveOpenLeadingIcon();\n\n return (\n <span\n class={{\n 'md-search__leading': true,\n 'md-search__leading--button': showCloseButton,\n }}\n part=\"leading\"\n onClick={this.handleLeadingClick}\n >\n <slot name=\"leading\">\n <button\n type=\"button\"\n class=\"md-search__leading-button\"\n aria-label={ariaLabel}\n tabIndex={showCloseButton ? 0 : -1}\n disabled={this.disabled}\n >\n <span\n class=\"md-search__leading-state-layer\"\n part=\"leading-state-layer\"\n aria-hidden=\"true\"\n ></span>\n <span\n class=\"md-search__icon md-search__icon--resting material-symbols-outlined\"\n aria-hidden=\"true\"\n >\n {this.leadingIcon}\n </span>\n <span\n class=\"md-search__icon md-search__icon--open material-symbols-outlined\"\n aria-hidden=\"true\"\n >\n {openGlyph}\n </span>\n </button>\n </slot>\n </span>\n );\n }\n\n private renderClearButton() {\n if (!this.showClearButton || !this.value) return null;\n return (\n <button\n type=\"button\"\n class=\"md-search__icon-button md-search__clear\"\n part=\"clear-button\"\n aria-label=\"Clear search\"\n onClick={this.handleClearClick}\n >\n <span class=\"md-search__icon material-symbols-outlined\" aria-hidden=\"true\">\n close\n </span>\n </button>\n );\n }\n\n private renderVoiceButton() {\n return (\n <button\n type=\"button\"\n class={{\n 'md-search__icon-button': true,\n 'md-search__voice': true,\n 'md-search__voice--listening': this.listening,\n }}\n part=\"voice-button\"\n aria-label={this.listening ? 'Stop voice search' : 'Search by voice'}\n aria-pressed={this.listening ? 'true' : 'false'}\n disabled={this.disabled}\n onClick={this.handleVoiceClick}\n >\n <span class=\"md-search__icon material-symbols-outlined\" aria-hidden=\"true\">\n mic\n </span>\n </button>\n );\n }\n\n private renderTrailing() {\n const showClear = this.showClearButton && this.value.length > 0;\n // The loading indicator stays mounted through its fade-out (morph), so the\n // box is shown whenever there's a clear button OR the morph is in-flight.\n const showMorph = showClear || this.loadingMorphMounted;\n const showVoice = this.voiceSearch && this.isVoiceSupported();\n\n // Don't render an empty trailing wrapper: only mount it when it has a morph\n // box, a mic, or (potential) slotted content. The named slot itself is the\n // projection point and must stay so slotchange detection keeps working.\n return (\n <span\n class=\"md-search__trailing\"\n part=\"trailing\"\n onClick={this.handleTrailingClick}\n >\n {/* Loading indicator and clear-× share one fixed-size box and cross-fade\n (scale + rotate) in BOTH directions as `loading` toggles, so the\n cluster width never jumps. */}\n {showMorph && (\n <span\n class={{\n 'md-search__trailing-morph': true,\n 'md-search__trailing-morph--loading': this.loadingMorphIn,\n }}\n >\n {this.loadingMorphMounted && (\n // `loader` swaps the spinner (e.g. for a circular\n // md-progress-indicator); the default keeps the morph classes and\n // the exported shape part.\n <slot name=\"loader\">\n <LazyLoadingIndicator\n class=\"md-search__loading\"\n part=\"loading\"\n exportparts=\"shape:loading-shape\"\n label={this.loadingLabel}\n ></LazyLoadingIndicator>\n </slot>\n )}\n {showClear && this.renderClearButton()}\n </span>\n )}\n {showVoice && this.renderVoiceButton()}\n <slot name=\"trailing\"></slot>\n </span>\n );\n }\n\n // ────────────────────────────────────────────────────────────────────────\n // Render\n // ────────────────────────────────────────────────────────────────────────\n\n render() {\n const isFullScreen = this.layout === 'full-screen';\n const hostStyle: Record<string, string> = {};\n if (this.maxBlockSize) {\n hostStyle['--_max-block-size'] = this.maxBlockSize;\n }\n\n return (\n <Host\n class={{\n 'md-search': true,\n [`md-search--${this.variant}`]: true,\n [`md-search--${this.layout}`]: true,\n [`md-search--trigger-${this.effectiveTrigger}`]: true,\n 'md-search--open': this.barExpanded,\n 'md-search--panel-content':\n this.layout === 'full-screen'\n ? this.isPanelRevealed()\n : this.shouldShowResultsChrome(),\n 'md-search--closed': !this.barExpanded,\n 'md-search--has-slotted-trigger': this.hasSlottedTrigger,\n 'md-search--disabled': this.disabled,\n 'md-search--focused': this.focused,\n 'md-search--has-value': this.value.length > 0,\n 'md-search--has-slotted-leading': this.hasSlottedLeading,\n 'md-search--has-slotted-trailing': this.hasSlottedTrailing,\n 'md-search--full-width': this.fullWidth,\n [`md-search--elevation-${this.elevation}`]: true,\n }}\n style={Object.keys(hostStyle).length > 0 ? hostStyle : undefined}\n >\n {/* Hidden probe — resolves the bar's per-side focus travel\n (resting − focused inset) to a pixel length so\n measureRippleExtend() can forward the value to <md-ripple>.\n Lives directly under :host (NOT inside the bar) so its\n absolute-positioning containing block matches the bar's,\n which is what makes any percentage in the insets resolve\n against the same inline-size for both. */}\n <span\n class=\"md-search__inset-probe\"\n ref={(el) => (this.insetProbeEl = el as HTMLElement)}\n aria-hidden=\"true\"\n ></span>\n\n {/* Polite live region — announces suggestion / result availability to\n assistive tech as the slotted results change (M3 autosuggest). */}\n <div\n class=\"md-search__a11y-status\"\n part=\"status\"\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {this.resultsStatus}\n </div>\n\n {this.renderTrigger()}\n\n {/* Search bar — hidden for full-screen icon trigger until open */}\n {this.showBar && (\n <div\n class={{\n 'md-search__bar': true,\n 'md-search__bar--focused': this.focused,\n 'md-search__bar--focus-ring': this.showFocusRing,\n }}\n part=\"bar\"\n onClick={this.handleBarClick}\n >\n {!this.disabled && (\n <md-ripple ref={(el) => (this.rippleEl = el as HTMLElement)}></md-ripple>\n )}\n <span class=\"md-search__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n\n {this.renderLeading()}\n\n <input\n ref={(el) => (this.input = el)}\n class=\"md-search__input\"\n part=\"input\"\n type=\"search\"\n role=\"combobox\"\n value={this.value}\n placeholder={this.placeholder}\n disabled={this.disabled}\n aria-label={this.effectiveLabel()}\n aria-expanded={this.open ? 'true' : 'false'}\n aria-controls=\"md-search-panel\"\n aria-autocomplete=\"list\"\n autocomplete=\"off\"\n spellcheck={false}\n onInput={this.handleInput}\n onFocus={this.handleInputFocus}\n onBlur={this.handleInputBlur}\n onKeyDown={this.handleInputKeyDown}\n />\n\n {this.renderTrailing()}\n </div>\n )}\n\n {/* Results panel — positioning + dialog chrome. Long lists plain-scroll\n in the results viewport (`.md-search__results-scroll`) with a native\n scrollbar aligned to the slotted surface. */}\n <div\n id=\"md-search-panel\"\n class={{\n 'md-search__panel': true,\n [`md-search__panel--${this.layout}`]: true,\n 'md-search__panel--open': this.isPanelRevealed(),\n }}\n part=\"panel\"\n role=\"dialog\"\n aria-modal={isFullScreen && this.isPanelRevealed() ? 'true' : 'false'}\n aria-hidden={this.isPanelRevealed() ? 'false' : 'true'}\n aria-label={this.effectiveLabel()}\n >\n {/* Hairline divider is a `divided`-variant affordance only — don't\n emit the empty element for the contained variant. */}\n {this.variant === 'divided' && this.isPanelRevealed() && (\n <div class=\"md-search__divider\" part=\"divider\" aria-hidden=\"true\"></div>\n )}\n\n <div\n class={{\n 'md-search__panel-body': true,\n 'md-search__panel-body--empty': this.shouldShowVisibleEmptyState(),\n }}\n part=\"panel-body\"\n >\n {this.shouldShowVisibleEmptyState() && (\n <p\n class=\"md-search__empty\"\n part=\"empty\"\n role=\"status\"\n aria-live=\"polite\"\n >\n {this.noResultsLabel}\n </p>\n )}\n <div\n class=\"md-search__results-host\"\n part=\"results-host\"\n hidden={this.shouldShowVisibleEmptyState() ? true : undefined}\n aria-hidden={this.shouldShowVisibleEmptyState() ? 'true' : undefined}\n >\n <div class=\"md-search__results-scroll\" part=\"results-viewport\">\n <slot name=\"results\"></slot>\n </div>\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as e,H as t,c as s,h as n,d as o,t as i}from"./p-bSpXNc5J.js";const r=()=>`:host{display:inline-grid;grid-auto-flow:column;grid-auto-columns:1fr;box-sizing:border-box;vertical-align:middle}@media (prefers-reduced-motion: reduce){:host{transition:none}}@media (forced-colors: active){:host{forced-color-adjust:none}}`;const c=e(class e extends t{constructor(e){super();if(e!==false){this.__registerHost()}this.__attachShadow();this.mdChange=s(this,"mdChange",7);this.multiselect=false;this.density=0}onPropsChange(){this.syncSegments()}componentDidLoad(){this.syncSegments()}handleSegmentClick(e){e.stopPropagation();const t=this.getSegments();const s=e.target;if(!s)return;const{selected:n}=e.detail;if(this.multiselect){s.selected=n}else{for(const e of t){e.selected=e===s}}this.mdChange.emit(t.filter((e=>e.selected)).map((e=>e.value)))}getSegments(){return Array.from(this.el.querySelectorAll("md-segmented-button"))}syncSegments(){const e=this.getSegments();const t=e.length;for(let s=0;s<t;s++){const n=e[s];n.segmentIndex=s;n.segmentTotal=t;n.segmentDensity=this.density;n.segmentMultiselect=this.multiselect}}render(){return n(o,{key:"08a80aae8cd51957bd23eb11aa6ea04ebb13758a",class:{"md-segmented-button-set":true,[`md-segmented-button-set--density-${Math.abs(this.density)}`]:this.density!==0},role:this.multiselect?"group":"radiogroup"},n("slot",{key:"cbb502e3dea710e29deb484794ebdf23cb26c596"}))}get el(){return this}static get watchers(){return{multiselect:[{onPropsChange:0}],density:[{onPropsChange:0}]}}static get style(){return r()}},[257,"md-segmented-button-set",{multiselect:[4],density:[514]},[[0,"mdSegmentClick","handleSegmentClick"]],{multiselect:[{onPropsChange:0}],density:[{onPropsChange:0}]}]);function d(){if(typeof customElements==="undefined"){return}const e=["md-segmented-button-set"];e.forEach((e=>{switch(e){case"md-segmented-button-set":if(!customElements.get(i(e))){customElements.define(i(e),c)}break}}))}d();const a=c;const m=d;export{a as MdSegmentedButtonSet,m as defineCustomElement};
|
|
2
|
+
//# sourceMappingURL=md-segmented-button-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["mdSegmentedButtonSetCss","MdSegmentedButtonSet","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","multiselect","density","onPropsChange","syncSegments","componentDidLoad","handleSegmentClick","event","stopPropagation","segments","getSegments","clicked","target","selected","detail","seg","mdChange","emit","filter","s","map","value","Array","from","el","querySelectorAll","total","length","i","segmentIndex","segmentTotal","segmentDensity","segmentMultiselect","render","h","Host","key","class","Math","abs","role"],"sources":["src/components/md-segmented-button-set/md-segmented-button-set.css?tag=md-segmented-button-set&encapsulation=shadow","src/components/md-segmented-button-set/md-segmented-button-set.tsx"],"sourcesContent":["/* ==========================================================\n md-segmented-button-set — Container for segmented buttons\n Spec: https://m3.material.io/components/segmented-buttons/specs\n ========================================================== */\n\n:host {\n display: inline-grid;\n grid-auto-flow: column;\n grid-auto-columns: 1fr;\n box-sizing: border-box;\n vertical-align: middle;\n}\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n}\n\n@media (forced-colors: active) {\n :host {\n forced-color-adjust: none;\n }\n}\n","import { Component, Host, h, Prop, Element, Event, EventEmitter, Listen, Watch } from '@stencil/core';\nimport { SegmentElement } from '../../utils/types';\n\n@Component({\n tag: 'md-segmented-button-set',\n styleUrl: 'md-segmented-button-set.css',\n shadow: true,\n})\nexport class MdSegmentedButtonSet {\n @Element() el!: HTMLElement;\n\n /** Single-select or multi-select mode */\n @Prop() multiselect: boolean = false;\n\n /** Density: 0 = 40px, -1 = 36px, -2 = 32px, -3 = 28px, -4 = 24px */\n @Prop({ reflect: true }) density: 0 | -1 | -2 | -3 | -4 = 0;\n\n /** Fires when the set of selected segment values changes */\n @Event() mdChange: EventEmitter<string[]>;\n\n @Watch('multiselect')\n @Watch('density')\n onPropsChange() {\n this.syncSegments();\n }\n\n componentDidLoad() {\n this.syncSegments();\n }\n\n @Listen('mdSegmentClick')\n handleSegmentClick(event: CustomEvent<{ value: string; selected: boolean }>) {\n event.stopPropagation();\n const segments = this.getSegments();\n // Match by element identity, not by `.value`. The child segment\n // emits `mdSegmentClick` from its own host, and the event re-targets\n // to that <md-segmented-button> as it crosses the shadow boundary\n // into this set. Matching by value would break whenever segments\n // share the default value of '' (which is the common case when\n // consumers omit the `value` prop — every segment would toggle\n // together because every `'' === ''` is true).\n const clicked = event.target as SegmentElement | null;\n if (!clicked) return;\n\n const { selected } = event.detail;\n\n if (this.multiselect) {\n clicked.selected = selected;\n } else {\n for (const seg of segments) {\n seg.selected = seg === clicked;\n }\n }\n\n this.mdChange.emit(\n segments.filter(s => s.selected).map(s => s.value),\n );\n }\n\n private getSegments(): SegmentElement[] {\n return Array.from(this.el.querySelectorAll('md-segmented-button')) as unknown as SegmentElement[];\n }\n\n private syncSegments() {\n const segments = this.getSegments();\n const total = segments.length;\n\n for (let i = 0; i < total; i++) {\n const seg = segments[i];\n seg.segmentIndex = i;\n seg.segmentTotal = total;\n seg.segmentDensity = this.density;\n seg.segmentMultiselect = this.multiselect;\n }\n }\n\n render() {\n return (\n <Host\n class={{\n 'md-segmented-button-set': true,\n [`md-segmented-button-set--density-${Math.abs(this.density)}`]: this.density !== 0,\n }}\n role={this.multiselect ? 'group' : 'radiogroup'}\n >\n <slot></slot>\n </Host>\n );\n }\n}\n"],"mappings":"uEAAA,MAAMA,EAA0B,IAAM,mP,MCQzBC,EAAoBC,EAAA,MAAAD,UAAAE,EALjC,WAAAC,CAAAC,G,qGASUC,KAAAC,YAAuB,MAGND,KAAAE,QAAiC,CA0E3D,CAnEC,aAAAC,GACEH,KAAKI,c,CAGP,gBAAAC,GACEL,KAAKI,c,CAIP,kBAAAE,CAAmBC,GACjBA,EAAMC,kBACN,MAAMC,EAAWT,KAAKU,cAQtB,MAAMC,EAAUJ,EAAMK,OACtB,IAAKD,EAAS,OAEd,MAAME,SAAEA,GAAaN,EAAMO,OAE3B,GAAId,KAAKC,YAAa,CACpBU,EAAQE,SAAWA,C,KACd,CACL,IAAK,MAAME,KAAON,EAAU,CAC1BM,EAAIF,SAAWE,IAAQJ,C,EAI3BX,KAAKgB,SAASC,KACZR,EAASS,QAAOC,GAAKA,EAAEN,WAAUO,KAAID,GAAKA,EAAEE,Q,CAIxC,WAAAX,GACN,OAAOY,MAAMC,KAAKvB,KAAKwB,GAAGC,iBAAiB,uB,CAGrC,YAAArB,GACN,MAAMK,EAAWT,KAAKU,cACtB,MAAMgB,EAAQjB,EAASkB,OAEvB,IAAK,IAAIC,EAAI,EAAGA,EAAIF,EAAOE,IAAK,CAC9B,MAAMb,EAAMN,EAASmB,GACrBb,EAAIc,aAAeD,EACnBb,EAAIe,aAAeJ,EACnBX,EAAIgB,eAAiB/B,KAAKE,QAC1Ba,EAAIiB,mBAAqBhC,KAAKC,W,EAIlC,MAAAgC,GACE,OACEC,EAACC,EAAI,CAAAC,IAAA,2CACHC,MAAO,CACL,0BAA2B,KAC3B,CAAC,oCAAoCC,KAAKC,IAAIvC,KAAKE,YAAaF,KAAKE,UAAY,GAEnFsC,KAAMxC,KAAKC,YAAc,QAAU,cAEnCiC,EAAA,QAAAE,IAAA,6C","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as e,H as t,c as s,h as n,d as o,t as a}from"./p-bSpXNc5J.js";import{t as i}from"./p-DYBUr7K_.js";import{d as r}from"./p-C3vB0Hd9.js";const d=()=>`:host{--_container-color:var(--md-segmented-button-container-color, transparent);--_selected-container-color:var(--md-segmented-button-selected-container-color, var(--md-sys-color-secondary-container));--_label-color:var(--md-segmented-button-label-color, var(--md-sys-color-on-surface));--_selected-label-color:var(--md-segmented-button-selected-label-color, var(--md-sys-color-on-secondary-container));--_outline-color:var(--md-segmented-button-outline-color, var(--md-sys-color-outline));--_container-shape:var(--md-segmented-button-container-shape, var(--md-sys-shape-corner-full, 9999px));--_icon-size:var(--md-segmented-button-icon-size, max(14px, calc(18px + var(--md-sys-density-scale, 0) * 1px)));--_state-layer-color:var(--md-sys-color-on-surface);--_height:calc(40px + var(--md-sys-density-scale, 0) * 4px);display:inline-flex;align-items:center;justify-content:center;position:relative;overflow:hidden;cursor:pointer;user-select:none;border:none;outline:none;box-sizing:border-box;min-height:var(--_height);padding:0 var(--md-sys-spacing-inset-md, 12px);gap:max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));background-color:var(--_container-color);color:var(--_label-color);-webkit-tap-highlight-color:transparent;vertical-align:middle;font-family:var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);font-size:max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));font-weight:var(--md-sys-typescale-label-large-font-weight, 500);letter-spacing:var(--md-sys-typescale-label-large-letter-spacing, 0.1px);line-height:max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));transition:background-color 100ms var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1))}.md-segmented-button__outline{position:absolute;inset:0;pointer-events:none;border:1px solid var(--_outline-color)}:host(.md-segmented-button--first) .md-segmented-button__outline{border-start-start-radius:var(--_container-shape);border-end-start-radius:var(--_container-shape)}:host(.md-segmented-button--last) .md-segmented-button__outline{border-start-end-radius:var(--_container-shape);border-end-end-radius:var(--_container-shape)}:host(.md-segmented-button--first.md-segmented-button--last) .md-segmented-button__outline{border-radius:var(--_container-shape)}:host(:not(.md-segmented-button--first)) .md-segmented-button__outline{border-inline-start:none}:host(.md-segmented-button--last:not(.md-segmented-button--first)){margin-inline-start:-1px}:host(.md-segmented-button--last:not(.md-segmented-button--first)) .md-segmented-button__outline{border-inline-start:1px solid var(--_outline-color)}:host(.md-segmented-button--first){border-start-start-radius:var(--_container-shape);border-end-start-radius:var(--_container-shape)}:host(.md-segmented-button--last){border-start-end-radius:var(--_container-shape);border-end-end-radius:var(--_container-shape)}:host(.md-segmented-button--first.md-segmented-button--last){border-radius:var(--_container-shape)}:host(:not(.md-segmented-button--first):not(.md-segmented-button--last)){border-radius:0}:host(.md-segmented-button--selected){--_container-color:var(--md-segmented-button-selected-container-color, var(--md-sys-color-secondary-container));background-color:var(--_container-color);color:var(--_selected-label-color);--_state-layer-color:var(--md-sys-color-on-secondary-container)}.md-segmented-button__state-layer{position:absolute;inset:0;border-radius:inherit;background-color:var(--_state-layer-color);opacity:0;transition:opacity 100ms var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));pointer-events:none}:host(:hover) .md-segmented-button__state-layer{opacity:var(--md-sys-state-hover-state-layer-opacity, 0.08)}:host(:focus-visible) .md-segmented-button__state-layer{opacity:var(--md-sys-state-focus-state-layer-opacity, 0.10)}:host(:active) .md-segmented-button__state-layer{opacity:var(--md-sys-state-pressed-state-layer-opacity, 0.10)}:host(:focus-visible){outline:3px solid var(--md-sys-color-secondary);outline-offset:-3px;z-index:1}:host(.md-segmented-button--disabled){cursor:default;pointer-events:none;--_label-color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);--_outline-color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent)}:host(.md-segmented-button--disabled.md-segmented-button--selected){--_container-color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);color:color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent)}:host(.md-segmented-button--disabled:hover) .md-segmented-button__state-layer,:host(.md-segmented-button--disabled:active) .md-segmented-button__state-layer,:host(.md-segmented-button--disabled:focus-visible) .md-segmented-button__state-layer{opacity:0}:host([soft-disabled]){cursor:default;pointer-events:auto}:host([soft-disabled]) .md-segmented-button__state-layer{display:none}.md-segmented-button__content{display:flex;align-items:center;justify-content:center;gap:max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));z-index:0;position:relative}.md-segmented-button__graphic{font-size:var(--_icon-size);width:var(--_icon-size);height:var(--_icon-size);display:flex;align-items:center;justify-content:center;flex-shrink:0}.md-segmented-button__graphic--hidden{visibility:hidden}.md-segmented-button__spacer{width:var(--_icon-size);flex-shrink:0;visibility:hidden}slot[name="icon"]{display:contents}::slotted([slot="icon"]){width:var(--_icon-size);height:var(--_icon-size);flex-shrink:0}.md-segmented-button__label{display:flex;align-items:center;white-space:nowrap}:host(.md-segmented-button--density-1){--md-sys-density-scale:-1}:host(.md-segmented-button--density-2){--md-sys-density-scale:-2}:host(.md-segmented-button--density-3){--md-sys-density-scale:-3}:host(.md-segmented-button--density-4){--md-sys-density-scale:-4}.material-symbols-outlined{font-family:var(--md-sys-icon-font-family, 'Material Symbols Outlined', 'Material Icons');font-weight:normal;font-style:normal;font-size:var(--_icon-size, 18px);line-height:1;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;overflow-wrap:normal;direction:ltr;font-feature-settings:'liga';-webkit-font-smoothing:antialiased}@media (prefers-reduced-motion: reduce){:host{transition:none}.md-segmented-button__state-layer{transition:none}}@media (forced-colors: active){:host{forced-color-adjust:none;background-color:ButtonFace;color:ButtonText}.md-segmented-button__outline{border-color:ButtonText}:host(:focus-visible){outline-color:Highlight}:host(.md-segmented-button--selected){background-color:Highlight;color:HighlightText}:host(.md-segmented-button--disabled){color:GrayText;opacity:1}:host(.md-segmented-button--disabled) .md-segmented-button__outline{border-color:GrayText}.md-segmented-button__state-layer{display:none}}:host([density='-1']){--md-sys-density-scale:-1}:host([density='-2']){--md-sys-density-scale:-2}:host([density='-3']){--md-sys-density-scale:-3}:host([density='-4']){--md-sys-density-scale:-4}`;const l=e(class e extends t{constructor(e){super();if(e!==false){this.__registerHost()}this.__attachShadow();this.mdSegmentClick=s(this,"mdSegmentClick",7);this.value="";this.selected=false;this.disabled=false;this.softDisabled=false;this.icon="";this.label="";this.noCheckmark=false;this.ripple=true;this.segmentIndex=0;this.segmentTotal=1;this.segmentDensity=0;this.segmentMultiselect=false;this.density=0;this.handleClick=e=>{if(this.isDisabled){e.preventDefault();return}const t=this.segmentMultiselect?!this.selected:true;this.mdSegmentClick.emit({value:this.value,selected:t})};this.handleKeyDown=e=>{if(e.key==="Enter"||e.key===" "){e.preventDefault();if(!this.isDisabled){i(this.el);const e=this.segmentMultiselect?!this.selected:true;this.mdSegmentClick.emit({value:this.value,selected:e})}return}const t=e.key==="ArrowRight"||e.key==="ArrowLeft"||e.key==="ArrowDown"||e.key==="ArrowUp";if(!t)return;e.preventDefault();const s=this.el.closest("md-segmented-button-set");if(!s)return;const n=Array.from(s.querySelectorAll("md-segmented-button")).filter((e=>!e.hasAttribute("disabled")));if(n.length===0)return;const o=n.indexOf(this.el);if(o===-1)return;const a=e.key==="ArrowRight"||e.key==="ArrowDown";const r=n[(o+(a?1:-1)+n.length)%n.length];r.focus();if(!this.segmentMultiselect)r.click()};this.hasSlottedLabel=false}get isDisabled(){return this.disabled||this.softDisabled}componentDidLoad(){if(typeof window!=="undefined"&&window.__STENCIL_DEV_MODE__!==false){const e=!!this.el.textContent?.trim();if(!this.label&&!e&&!this.el.hasAttribute("aria-label")){console.warn(`[md-segmented-button] WCAG 1.1.1: Segment is missing an accessible name. `+`Provide a label prop, slotted text content, or aria-label attribute.`,this.el)}}}componentWillLoad(){this.hasSlottedLabel=(this.el.textContent||"").trim().length>0}render(){const e=this.segmentIndex;const t=this.segmentTotal;const s=this.segmentDensity;const a=!!this.icon;const i=!!this.label||this.hasSlottedLabel;const r=this.selected&&!this.noCheckmark;const d=e===0;const l=e===t-1;return n(o,{key:"040400dd6bb0b0ab5e3bdccf5fff7a8c43b04100",class:{"md-segmented-button":true,"md-segmented-button--selected":this.selected,"md-segmented-button--disabled":this.isDisabled,"md-segmented-button--with-icon":a||r,"md-segmented-button--first":d,"md-segmented-button--last":l,[`md-segmented-button--density-${Math.abs(s)}`]:s!==0},role:this.segmentMultiselect?"checkbox":"radio","aria-checked":String(this.selected),"aria-disabled":this.isDisabled?"true":"false",tabindex:this.disabled?"-1":"0",onClick:this.handleClick,onKeyDown:this.handleKeyDown},this.ripple&&n("md-ripple",{key:"9112444bea9c19672cece7041bef8a5b9b682f6c",disabled:this.isDisabled}),n("span",{key:"76a9ade37c4a4c07791d054648e6193b7a7ac92f",class:"md-segmented-button__state-layer",part:"state-layer","aria-hidden":"true"}),n("span",{key:"c07f1614f340deb86069aabf1dffacc8a4545e4d",class:"md-segmented-button__outline","aria-hidden":"true"}),n("span",{key:"f6015879af1865ef764aa858bd095a6d364a3006",class:"md-segmented-button__content"},a?n("span",{class:"md-segmented-button__graphic material-symbols-outlined",part:r?"checkmark":"icon","aria-hidden":"true"},r?"check":this.icon):!this.noCheckmark?n("span",{class:{"md-segmented-button__graphic":true,"material-symbols-outlined":true,"md-segmented-button__graphic--hidden":!this.selected},part:this.selected?"checkmark":undefined,"aria-hidden":"true"},this.selected?"check":""):null,n("slot",{key:"e7cb38222b3baeefdac203ba6b6bafb678e0e516",name:"icon"}),i?n("span",{class:"md-segmented-button__label",part:"label"},this.label?this.label:n("slot",null)):n("slot",null),!a&&!this.noCheckmark&&n("span",{key:"6e78f887f80833c8afa7e7df7798d7bd792ef8c9",class:"md-segmented-button__spacer","aria-hidden":"true"})))}get el(){return this}static get style(){return d()}},[257,"md-segmented-button",{value:[1],selected:[1540],disabled:[516],softDisabled:[516,"soft-disabled"],icon:[1],label:[1],noCheckmark:[4,"no-checkmark"],ripple:[4],segmentIndex:[2,"segment-index"],segmentTotal:[2,"segment-total"],segmentDensity:[2,"segment-density"],segmentMultiselect:[4,"segment-multiselect"],density:[514],hasSlottedLabel:[32]}]);function c(){if(typeof customElements==="undefined"){return}const e=["md-segmented-button","md-ripple"];e.forEach((e=>{switch(e){case"md-segmented-button":if(!customElements.get(a(e))){customElements.define(a(e),l)}break;case"md-ripple":if(!customElements.get(a(e))){r()}break}}))}c();const m=l;const b=c;export{m as MdSegmentedButton,b as defineCustomElement};
|
|
2
|
+
//# sourceMappingURL=md-segmented-button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["mdSegmentedButtonCss","MdSegmentedButton","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","value","selected","disabled","softDisabled","icon","label","noCheckmark","ripple","segmentIndex","segmentTotal","segmentDensity","segmentMultiselect","density","handleClick","e","isDisabled","preventDefault","newSelected","mdSegmentClick","emit","handleKeyDown","key","triggerRipple","el","isArrow","set","closest","siblings","Array","from","querySelectorAll","filter","s","hasAttribute","length","idx","indexOf","isForward","next","focus","click","hasSlottedLabel","componentDidLoad","window","__STENCIL_DEV_MODE__","hasSlottedText","textContent","trim","console","warn","componentWillLoad","render","index","total","hasIcon","hasLabel","showCheckmark","isFirst","isLast","h","Host","class","Math","abs","role","String","tabindex","onClick","onKeyDown","part","undefined","name"],"sources":["src/components/md-segmented-button/md-segmented-button.css?tag=md-segmented-button&encapsulation=shadow","src/components/md-segmented-button/md-segmented-button.tsx"],"sourcesContent":["/* ==========================================================\n md-segmented-button — Material Design 3 Segmented Button\n Spec: https://m3.material.io/components/segmented-buttons/specs\n\n PUBLIC CSS CUSTOM PROPERTIES:\n --md-segmented-button-container-color Unselected bg\n --md-segmented-button-selected-container-color Selected bg\n --md-segmented-button-label-color Unselected text\n --md-segmented-button-selected-label-color Selected text\n --md-segmented-button-outline-color Outline color\n --md-segmented-button-container-shape Border-radius\n --md-segmented-button-icon-size Icon dimensions\n\n CSS PARTS:\n state-layer Hover/press overlay\n checkmark Checkmark icon (selected)\n icon Icon element\n label Label text\n\n SLOTS:\n icon Custom icon (replaces icon prop)\n ========================================================== */\n\n:host {\n --_container-color: var(--md-segmented-button-container-color, transparent);\n --_selected-container-color: var(--md-segmented-button-selected-container-color, var(--md-sys-color-secondary-container));\n --_label-color: var(--md-segmented-button-label-color, var(--md-sys-color-on-surface));\n --_selected-label-color: var(--md-segmented-button-selected-label-color, var(--md-sys-color-on-secondary-container));\n --_outline-color: var(--md-segmented-button-outline-color, var(--md-sys-color-outline));\n --_container-shape: var(--md-segmented-button-container-shape, var(--md-sys-shape-corner-full, 9999px));\n --_icon-size: var(--md-segmented-button-icon-size, max(14px, calc(18px + var(--md-sys-density-scale, 0) * 1px)));\n --_state-layer-color: var(--md-sys-color-on-surface);\n /* Follows a global `data-density` ancestor (0…-4, 4px/rung); density-scale is\n 0 by default so 40px is unchanged. The local `segmentDensity` (0..-3) still\n overrides via the .--density-N blocks below. */\n --_height: calc(40px + var(--md-sys-density-scale, 0) * 4px);\n\n display: inline-flex;\n align-items: center;\n justify-content: center;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n user-select: none;\n border: none;\n outline: none;\n box-sizing: border-box;\n min-height: var(--_height);\n padding: 0 var(--md-sys-spacing-inset-md, 12px);\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n background-color: var(--_container-color);\n color: var(--_label-color);\n -webkit-tap-highlight-color: transparent;\n vertical-align: middle;\n\n font-family: var(--md-sys-typescale-label-large-font-family, Roboto, sans-serif);\n font-size: max(12px, calc(14px + var(--md-sys-density-scale, 0) * 0.5px));\n font-weight: var(--md-sys-typescale-label-large-font-weight, 500);\n letter-spacing: var(--md-sys-typescale-label-large-letter-spacing, 0.1px);\n line-height: max(16px, calc(20px + var(--md-sys-density-scale, 0) * 1px));\n\n transition: background-color 100ms var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n}\n\n/* ==========================================================\n 1. OUTLINE — drawn as a pseudo-element of an inner span\n Each segment has its own 1px border. Adjacent borders\n collapse via negative margin on the set's slotted children.\n ========================================================== */\n\n.md-segmented-button__outline {\n position: absolute;\n inset: 0;\n pointer-events: none;\n border: 1px solid var(--_outline-color);\n}\n\n/* Logical corner properties auto-flip in RTL (border-start-start-radius\n = top-left in LTR but top-right in RTL, etc.) so the rounded ends\n always face the outer edges of the group, never the inner seams. */\n:host(.md-segmented-button--first) .md-segmented-button__outline {\n border-start-start-radius: var(--_container-shape);\n border-end-start-radius: var(--_container-shape);\n}\n\n:host(.md-segmented-button--last) .md-segmented-button__outline {\n border-start-end-radius: var(--_container-shape);\n border-end-end-radius: var(--_container-shape);\n}\n\n:host(.md-segmented-button--first.md-segmented-button--last) .md-segmented-button__outline {\n border-radius: var(--_container-shape);\n}\n\n:host(:not(.md-segmented-button--first)) .md-segmented-button__outline {\n border-inline-start: none;\n}\n\n/* The last segment normally borrows the previous segment's right border as its\n leading divider. A DISABLED previous segment fades that border to ~12%, leaving\n the last segment open on its inline-start (see the \"disabled Gamma → Delta\"\n case). Give the last segment its own leading border, pulled 1px to overlap the\n shared edge so it stays a single 1px divider when the previous segment is\n enabled (no doubling). */\n:host(.md-segmented-button--last:not(.md-segmented-button--first)) {\n margin-inline-start: -1px;\n}\n:host(.md-segmented-button--last:not(.md-segmented-button--first)) .md-segmented-button__outline {\n border-inline-start: 1px solid var(--_outline-color);\n}\n\n/* ==========================================================\n 2. BORDER RADIUS ON HOST (matches outline)\n ========================================================== */\n\n:host(.md-segmented-button--first) {\n border-start-start-radius: var(--_container-shape);\n border-end-start-radius: var(--_container-shape);\n}\n\n:host(.md-segmented-button--last) {\n border-start-end-radius: var(--_container-shape);\n border-end-end-radius: var(--_container-shape);\n}\n\n:host(.md-segmented-button--first.md-segmented-button--last) {\n border-radius: var(--_container-shape);\n}\n\n:host(:not(.md-segmented-button--first):not(.md-segmented-button--last)) {\n border-radius: 0;\n}\n\n/* ==========================================================\n 3. SELECTED STATE\n ========================================================== */\n\n:host(.md-segmented-button--selected) {\n --_container-color: var(--md-segmented-button-selected-container-color, var(--md-sys-color-secondary-container));\n background-color: var(--_container-color);\n color: var(--_selected-label-color);\n --_state-layer-color: var(--md-sys-color-on-secondary-container);\n}\n\n/* ==========================================================\n 4. STATE LAYER\n ========================================================== */\n\n.md-segmented-button__state-layer {\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: var(--_state-layer-color);\n opacity: 0;\n transition: opacity 100ms var(--md-sys-motion-easing-standard, cubic-bezier(0.2, 0, 0, 1));\n pointer-events: none;\n}\n\n:host(:hover) .md-segmented-button__state-layer {\n opacity: var(--md-sys-state-hover-state-layer-opacity, 0.08);\n}\n\n:host(:focus-visible) .md-segmented-button__state-layer {\n opacity: var(--md-sys-state-focus-state-layer-opacity, 0.10);\n}\n\n:host(:active) .md-segmented-button__state-layer {\n opacity: var(--md-sys-state-pressed-state-layer-opacity, 0.10);\n}\n\n/* ==========================================================\n 5. FOCUS RING\n ========================================================== */\n\n:host(:focus-visible) {\n outline: 3px solid var(--md-sys-color-secondary);\n outline-offset: -3px;\n z-index: 1;\n}\n\n/* ==========================================================\n 6. DISABLED\n ========================================================== */\n\n:host(.md-segmented-button--disabled) {\n cursor: default;\n pointer-events: none;\n --_label-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n --_outline-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n}\n\n:host(.md-segmented-button--disabled.md-segmented-button--selected) {\n --_container-color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-container-opacity, 0.12) * 100%), transparent);\n color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity, 0.38) * 100%), transparent);\n}\n\n:host(.md-segmented-button--disabled:hover) .md-segmented-button__state-layer,\n:host(.md-segmented-button--disabled:active) .md-segmented-button__state-layer,\n:host(.md-segmented-button--disabled:focus-visible) .md-segmented-button__state-layer {\n opacity: 0;\n}\n\n/* Soft-disabled: looks disabled but stays focusable for AT */\n:host([soft-disabled]) {\n cursor: default;\n pointer-events: auto;\n}\n\n:host([soft-disabled]) .md-segmented-button__state-layer { display: none; }\n\n/* ==========================================================\n 7. CONTENT — icon + label layout\n ========================================================== */\n\n.md-segmented-button__content {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: max(4px, calc(8px + var(--md-sys-density-scale, 0) * 1px));\n z-index: 0;\n position: relative;\n}\n\n/* ==========================================================\n 8. ICON & CHECKMARK\n ========================================================== */\n\n/* Icon / checkmark graphic.\n Icon segments: always present, swaps icon ↔ checkmark in-place.\n Text-only segments: always present for width reservation;\n hidden when unselected, visible checkmark when selected. */\n.md-segmented-button__graphic {\n font-size: var(--_icon-size);\n width: var(--_icon-size);\n height: var(--_icon-size);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.md-segmented-button__graphic--hidden {\n visibility: hidden;\n}\n\n/* Trailing spacer mirrors the hidden leading graphic so that the label\n sits perfectly centered between two equal-width invisible elements. */\n.md-segmented-button__spacer {\n width: var(--_icon-size);\n flex-shrink: 0;\n visibility: hidden;\n}\n\nslot[name=\"icon\"] {\n display: contents;\n}\n\n::slotted([slot=\"icon\"]) {\n width: var(--_icon-size);\n height: var(--_icon-size);\n flex-shrink: 0;\n}\n\n/* ==========================================================\n 9. LABEL\n ========================================================== */\n\n.md-segmented-button__label {\n display: flex;\n align-items: center;\n white-space: nowrap;\n}\n\n/* ==========================================================\n 10. DENSITY\n Each step removes 4px from the 40px default height.\n\n The parent set pushes its density down as a class (this element is driven by\n `segmentDensity`, a property, so CSS cannot key on it directly). That class\n maps onto the SAME `--md-sys-density-scale` signal a global `data-density`\n ancestor sets, rather than hard-coding a height.\n\n This matters beyond tidiness: --_height was the ONLY value the old fixed\n ladder touched, so under the local prop the icon size, gap and label\n type (§0/§1, all scale-driven calcs) stayed at their density-0 values while a\n global data-density condensed them. Mapping the signal instead means every\n density-sensitive value in this file responds on both paths. The heights are\n unchanged — calc(40px + scale*4px) reproduces 36/32/28 exactly — and -4 (24px)\n now exists to match the library's 5-rung scale.\n ========================================================== */\n\n:host(.md-segmented-button--density-1) { --md-sys-density-scale: -1; }\n:host(.md-segmented-button--density-2) { --md-sys-density-scale: -2; }\n:host(.md-segmented-button--density-3) { --md-sys-density-scale: -3; }\n:host(.md-segmented-button--density-4) { --md-sys-density-scale: -4; }\n\n/* ==========================================================\n 11. MATERIAL SYMBOLS (default icon font)\n ========================================================== */\n\n.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(--_icon-size, 18px);\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 12. REDUCED MOTION\n ========================================================== */\n\n@media (prefers-reduced-motion: reduce) {\n :host {\n transition: none;\n }\n\n .md-segmented-button__state-layer {\n transition: none;\n }\n}\n\n/* ==========================================================\n 13. FORCED COLORS — Windows High Contrast\n ========================================================== */\n\n@media (forced-colors: active) {\n :host {\n forced-color-adjust: none;\n background-color: ButtonFace;\n color: ButtonText;\n }\n\n .md-segmented-button__outline {\n border-color: ButtonText;\n }\n\n :host(:focus-visible) {\n outline-color: Highlight;\n }\n\n :host(.md-segmented-button--selected) {\n background-color: Highlight;\n color: HighlightText;\n }\n\n :host(.md-segmented-button--disabled) {\n color: GrayText;\n opacity: 1;\n }\n\n :host(.md-segmented-button--disabled) .md-segmented-button__outline {\n border-color: GrayText;\n }\n\n .md-segmented-button__state-layer {\n display: none;\n }\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 { triggerRipple } from '../../utils/ripple';\n\n@Component({\n tag: 'md-segmented-button',\n styleUrl: 'md-segmented-button.css',\n shadow: true,\n})\nexport class MdSegmentedButton {\n @Element() el!: HTMLElement;\n\n /** Unique value identifying this segment */\n @Prop() value: string = '';\n\n /** Whether this segment is selected */\n @Prop({ mutable: true, reflect: true }) selected: boolean = false;\n\n /** Disable this segment */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Visually disabled but remains focusable for screen readers */\n @Prop({ reflect: true, attribute: 'soft-disabled' }) softDisabled: boolean = false;\n\n /** Material Symbols icon name (optional) */\n @Prop() icon: string = '';\n\n /** Label text */\n @Prop() label: string = '';\n\n /** Show checkmark icon when selected */\n @Prop({ attribute: 'no-checkmark' }) noCheckmark: boolean = false;\n\n /** Enable/disable ripple */\n @Prop() ripple: boolean = true;\n\n /** Position index within the set (managed by md-segmented-button-set) */\n @Prop() segmentIndex: number = 0;\n\n /** Total number of segments in the set (managed by md-segmented-button-set) */\n @Prop() segmentTotal: number = 1;\n\n /** Density value from parent set (managed by md-segmented-button-set) */\n @Prop() segmentDensity: number = 0;\n\n /** Whether the parent set is in multiselect mode (managed by md-segmented-button-set) */\n @Prop() segmentMultiselect: 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 /** Internal event — caught by the set */\n @Event() mdSegmentClick: EventEmitter<{ value: string; selected: boolean }>;\n\n private get isDisabled() {\n return this.disabled || this.softDisabled;\n }\n\n componentDidLoad() {\n if (\n typeof window !== 'undefined' &&\n window.__STENCIL_DEV_MODE__ !== false\n ) {\n // Slotted text (e.g. `<md-segmented-button>Day</md-segmented-button>`)\n // is a valid accessible name once we render `<slot/>` inside the label\n // wrapper below. Read textContent on the host to detect it — slot\n // assignment is already resolved by the time componentDidLoad runs.\n const hasSlottedText = !!this.el.textContent?.trim();\n if (!this.label && !hasSlottedText && !this.el.hasAttribute('aria-label')) {\n console.warn(\n `[md-segmented-button] WCAG 1.1.1: Segment is missing an accessible name. ` +\n `Provide a label prop, slotted text content, or aria-label attribute.`,\n this.el,\n );\n }\n }\n }\n\n private handleClick = (e: MouseEvent) => {\n if (this.isDisabled) {\n e.preventDefault();\n return;\n }\n\n const newSelected = this.segmentMultiselect ? !this.selected : true;\n this.mdSegmentClick.emit({ value: this.value, selected: newSelected });\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n if (!this.isDisabled) {\n triggerRipple(this.el);\n const newSelected = this.segmentMultiselect ? !this.selected : true;\n this.mdSegmentClick.emit({ value: this.value, selected: newSelected });\n }\n return;\n }\n\n const isArrow = e.key === 'ArrowRight' || e.key === 'ArrowLeft' ||\n e.key === 'ArrowDown' || e.key === 'ArrowUp';\n if (!isArrow) return;\n e.preventDefault();\n\n const set = this.el.closest('md-segmented-button-set');\n if (!set) return;\n const siblings = Array.from(\n set.querySelectorAll<HTMLElement>('md-segmented-button'),\n ).filter(s => !s.hasAttribute('disabled'));\n if (siblings.length === 0) return;\n\n const idx = siblings.indexOf(this.el);\n if (idx === -1) return;\n\n const isForward = e.key === 'ArrowRight' || e.key === 'ArrowDown';\n const next = siblings[(idx + (isForward ? 1 : -1) + siblings.length) % siblings.length];\n next.focus();\n\n // Single-select: arrow also selects (WAI-ARIA radiogroup pattern).\n if (!this.segmentMultiselect) next.click();\n };\n\n /** Whether the consumer put anything in the default slot, captured before the\n * first render so an unlabelled segment never renders an empty label box. */\n @State() private hasSlottedLabel = false;\n\n componentWillLoad() {\n this.hasSlottedLabel = (this.el.textContent || '').trim().length > 0;\n }\n\n render() {\n const index = this.segmentIndex;\n const total = this.segmentTotal;\n const density = this.segmentDensity;\n const hasIcon = !!this.icon;\n const hasLabel = !!this.label || this.hasSlottedLabel;\n const showCheckmark = this.selected && !this.noCheckmark;\n const _showIcon = hasIcon && !showCheckmark;\n const isFirst = index === 0;\n const isLast = index === total - 1;\n\n return (\n <Host\n class={{\n 'md-segmented-button': true,\n 'md-segmented-button--selected': this.selected,\n 'md-segmented-button--disabled': this.isDisabled,\n 'md-segmented-button--with-icon': hasIcon || showCheckmark,\n 'md-segmented-button--first': isFirst,\n 'md-segmented-button--last': isLast,\n [`md-segmented-button--density-${Math.abs(density)}`]: density !== 0,\n }}\n role={this.segmentMultiselect ? 'checkbox' : 'radio'}\n aria-checked={String(this.selected)}\n aria-disabled={this.isDisabled ? 'true' : 'false'}\n tabindex={this.disabled ? '-1' : '0'}\n onClick={this.handleClick}\n onKeyDown={this.handleKeyDown}\n >\n {this.ripple && <md-ripple disabled={this.isDisabled}></md-ripple>}\n <span class=\"md-segmented-button__state-layer\" part=\"state-layer\" aria-hidden=\"true\"></span>\n <span class=\"md-segmented-button__outline\" aria-hidden=\"true\"></span>\n\n <span class=\"md-segmented-button__content\">\n {hasIcon ? (\n // Icon segments: single element swaps icon ↔ checkmark in-place\n <span class=\"md-segmented-button__graphic material-symbols-outlined\"\n part={showCheckmark ? 'checkmark' : 'icon'}\n aria-hidden=\"true\"\n >{showCheckmark ? 'check' : this.icon}</span>\n ) : !this.noCheckmark ? (\n // Text-only: always reserve leading graphic space so segments\n // pre-account for the checkmark width and never cramp.\n <span class={{\n 'md-segmented-button__graphic': true,\n 'material-symbols-outlined': true,\n 'md-segmented-button__graphic--hidden': !this.selected,\n }}\n part={this.selected ? 'checkmark' : undefined}\n aria-hidden=\"true\"\n >{this.selected ? 'check' : ''}</span>\n ) : null}\n <slot name=\"icon\"></slot>\n {/* Label resolves from the `label` prop first, then falls back\n to whatever the consumer passed in the default slot, matching\n the pattern used across md-button, md-fab-menu-item, etc.\n The wrapper is always rendered so the slot's content lands\n inside the labelled part — empty wrapper is harmless. */}\n {/* Rendered only when there IS a label. An empty wrapper is not\n harmless after all: it is a second flex item, so the content row's\n gap sits between the glyph and a zero-width span and shifts an\n icon-only segment's glyph off-centre by half the gap (measured\n -4px). The default slot still needs a home when unlabelled, so it\n sits outside the wrapper below. */}\n {hasLabel ? (\n <span class=\"md-segmented-button__label\" part=\"label\">\n {this.label ? this.label : <slot />}\n </span>\n ) : (\n <slot />\n )}\n {/* Trailing spacer keeps total content width stable across selection states */}\n {!hasIcon && !this.noCheckmark && (\n <span class=\"md-segmented-button__spacer\" aria-hidden=\"true\"></span>\n )}\n </span>\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{p as e,H as t,c as a,h as n,d as s,t as o}from"./p-bSpXNc5J.js";const i=()=>`:host{display:none}`;const c=e(class e extends t{constructor(e){super();if(e!==false){this.__registerHost()}this.__attachShadow();this.mdSelectOptionChange=a(this,"mdSelectOptionChange",7);this.value="";this.label="";this.disabled=false;this.selected=false;this.icon="";this.iconColor="";this.supportingText=""}onDataChange(){this.mdSelectOptionChange.emit()}connectedCallback(){this.mdSelectOptionChange?.emit()}disconnectedCallback(){this.mdSelectOptionChange?.emit()}render(){return n(s,{key:"0b425bb49e3918cd1be482c1ddcc76739bf58163",role:"option","aria-hidden":"true","aria-selected":String(this.selected),"aria-disabled":this.disabled?"true":"false"},n("slot",{key:"12e2c4ca36f605dbdf20c8324e197872f8009e25"}))}get el(){return this}static get watchers(){return{value:[{onDataChange:0}],label:[{onDataChange:0}],disabled:[{onDataChange:0}],selected:[{onDataChange:0}],icon:[{onDataChange:0}],iconColor:[{onDataChange:0}],supportingText:[{onDataChange:0}]}}static get style(){return i()}},[257,"md-select-option",{value:[1],label:[1],disabled:[516],selected:[516],icon:[1],iconColor:[1,"icon-color"],supportingText:[1,"supporting-text"]},undefined,{value:[{onDataChange:0}],label:[{onDataChange:0}],disabled:[{onDataChange:0}],selected:[{onDataChange:0}],icon:[{onDataChange:0}],iconColor:[{onDataChange:0}],supportingText:[{onDataChange:0}]}]);function l(){if(typeof customElements==="undefined"){return}const e=["md-select-option"];e.forEach((e=>{switch(e){case"md-select-option":if(!customElements.get(o(e))){customElements.define(o(e),c)}break}}))}l();const h=c;const r=l;export{h as MdSelectOption,r as defineCustomElement};
|
|
2
|
+
//# sourceMappingURL=md-select-option.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["mdSelectOptionCss","MdSelectOption","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","value","label","disabled","selected","icon","iconColor","supportingText","onDataChange","mdSelectOptionChange","emit","connectedCallback","disconnectedCallback","render","h","Host","key","role","String"],"sources":["src/components/md-select-option/md-select-option.css?tag=md-select-option&encapsulation=shadow","src/components/md-select-option/md-select-option.tsx"],"sourcesContent":["/* ==========================================================\n md-select-option — declarative data carrier\n\n Renders nothing visible. The parent md-select / md-multi-select\n reads this element's value / label / icon / disabled and projects\n it into the md-menu dropdown as a real md-menu-item row. Keeping it\n display:none avoids any flash of unstyled options before hydration.\n ========================================================== */\n\n:host {\n display: none;\n}\n","import {\n Component,\n Host,\n h,\n Prop,\n Element,\n Event,\n EventEmitter,\n Watch,\n} from '@stencil/core';\n\n/**\n * `md-select-option` — declarative option for `md-select` / `md-multi-select`.\n *\n * This element is a **data carrier**: it renders nothing visible (the host\n * is `display: none`). The parent picker reads its `value`, label (the\n * `label` prop or slotted text), `disabled`, `icon`, and `supporting-text`\n * and projects them into the `md-menu` dropdown as `md-menu-item`s.\n *\n * Authoring:\n * ```html\n * <md-select label=\"Colour\">\n * <md-select-option value=\"red\" icon=\"circle\">Red</md-select-option>\n * <md-select-option value=\"green\" disabled>Green</md-select-option>\n * </md-select>\n * ```\n *\n * Whenever an option is added, removed, or has its data changed, it emits a\n * bubbling `mdSelectOptionChange` event so the parent re-reads its option set.\n */\n@Component({\n tag: 'md-select-option',\n styleUrl: 'md-select-option.css',\n shadow: true,\n})\nexport class MdSelectOption {\n @Element() el!: HTMLElement;\n\n /** Stable identifier emitted by the picker and used for matching. */\n @Prop() value: string = '';\n\n /** Visible label. Falls back to the slotted text content when empty. */\n @Prop() label: string = '';\n\n /** Disabled options stay visible in the menu but cannot be selected. */\n @Prop({ reflect: true }) disabled: boolean = false;\n\n /** Initial-selected hint (used by the picker only when its value is unset). */\n @Prop({ reflect: true }) selected: boolean = false;\n\n /** Material Symbols leading-icon glyph rendered in the menu row. */\n @Prop() icon: string = '';\n\n /** CSS colour for the leading icon (any CSS `<color>` — hex, `rgb()`, or a\n * theme token such as `var(--md-sys-color-primary)`). Ignored without `icon`. */\n @Prop({ attribute: 'icon-color' }) iconColor: string = '';\n\n /** Secondary text rendered under the label in the menu row. */\n @Prop({ attribute: 'supporting-text' }) supportingText: string = '';\n\n /** Fired when the option mounts, unmounts, or its data changes so the\n * parent picker can re-read its option set. */\n @Event({ bubbles: true, composed: true })\n mdSelectOptionChange!: EventEmitter<void>;\n\n @Watch('value')\n @Watch('label')\n @Watch('disabled')\n @Watch('selected')\n @Watch('icon')\n @Watch('iconColor')\n @Watch('supportingText')\n onDataChange() {\n this.mdSelectOptionChange.emit();\n }\n\n connectedCallback() {\n this.mdSelectOptionChange?.emit();\n }\n\n disconnectedCallback() {\n this.mdSelectOptionChange?.emit();\n }\n\n render() {\n // role=\"option\" is kept for AT semantics when authors inspect the DOM,\n // but the element is visually hidden — the picker renders the real,\n // interactive row inside its md-menu. aria-hidden avoids double\n // announcement of the (hidden) carrier alongside the live menu item.\n return (\n <Host\n role=\"option\"\n aria-hidden=\"true\"\n aria-selected={String(this.selected)}\n aria-disabled={this.disabled ? 'true' : 'false'}\n >\n <slot />\n </Host>\n );\n }\n}\n"],"mappings":"uEAAA,MAAMA,EAAoB,IAAM,sB,MCmCnBC,EAAcC,EAAA,MAAAD,UAAAE,EAL3B,WAAAC,CAAAC,G,6HASUC,KAAAC,MAAgB,GAGhBD,KAAAE,MAAgB,GAGCF,KAAAG,SAAoB,MAGpBH,KAAAI,SAAoB,MAGrCJ,KAAAK,KAAe,GAIYL,KAAAM,UAAoB,GAGfN,KAAAO,eAAyB,EA0ClE,CA5BC,YAAAC,GACER,KAAKS,qBAAqBC,M,CAG5B,iBAAAC,GACEX,KAAKS,sBAAsBC,M,CAG7B,oBAAAE,GACEZ,KAAKS,sBAAsBC,M,CAG7B,MAAAG,GAKE,OACEC,EAACC,EAAI,CAAAC,IAAA,2CACHC,KAAK,SAAQ,cACD,OAAM,gBACHC,OAAOlB,KAAKI,UAAS,gBACrBJ,KAAKG,SAAW,OAAS,SAExCW,EAAA,QAAAE,IAAA,6C","ignoreList":[]}
|