@slotted/angular 0.0.0-stage → 0.1.0-beta.1
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/LICENSE +21 -0
- package/README.md +51 -2
- package/docs/AGENTS.snippet.md +10 -0
- package/docs/accordion.json +345 -0
- package/docs/accordion.md +207 -0
- package/docs/action-bar.json +421 -0
- package/docs/action-bar.md +364 -0
- package/docs/action-sheet.json +210 -0
- package/docs/action-sheet.md +19 -0
- package/docs/alert.json +407 -0
- package/docs/alert.md +239 -0
- package/docs/app-shell.examples.md +349 -0
- package/docs/app-shell.json +835 -0
- package/docs/app-shell.md +214 -0
- package/docs/aspect-ratio.json +159 -0
- package/docs/aspect-ratio.md +134 -0
- package/docs/attachment.json +486 -0
- package/docs/attachment.md +253 -0
- package/docs/avatar-group.json +208 -0
- package/docs/avatar-group.md +130 -0
- package/docs/avatar.json +342 -0
- package/docs/avatar.md +142 -0
- package/docs/badge.json +334 -0
- package/docs/badge.md +138 -0
- package/docs/breadcrumb.json +368 -0
- package/docs/breadcrumb.md +237 -0
- package/docs/button-group.json +158 -0
- package/docs/button-group.md +72 -0
- package/docs/button.examples.md +621 -0
- package/docs/button.json +977 -0
- package/docs/button.md +200 -0
- package/docs/calendar.json +592 -0
- package/docs/calendar.md +242 -0
- package/docs/card.json +283 -0
- package/docs/card.md +130 -0
- package/docs/carousel.json +560 -0
- package/docs/carousel.md +357 -0
- package/docs/cascader.json +933 -0
- package/docs/cascader.md +379 -0
- package/docs/chart.examples.md +582 -0
- package/docs/chart.json +1359 -0
- package/docs/chart.md +187 -0
- package/docs/checkbox-group.examples.md +612 -0
- package/docs/checkbox-group.json +395 -0
- package/docs/checkbox-group.md +106 -0
- package/docs/checkbox.examples.md +546 -0
- package/docs/checkbox.json +506 -0
- package/docs/checkbox.md +104 -0
- package/docs/code-block.json +616 -0
- package/docs/code-block.md +303 -0
- package/docs/collapsible.json +456 -0
- package/docs/collapsible.md +261 -0
- package/docs/color-picker.json +523 -0
- package/docs/color-picker.md +201 -0
- package/docs/column-manager.json +486 -0
- package/docs/column-manager.md +277 -0
- package/docs/combobox.examples.md +1732 -0
- package/docs/combobox.json +1250 -0
- package/docs/combobox.md +209 -0
- package/docs/command-palette.json +800 -0
- package/docs/command-palette.md +419 -0
- package/docs/container.json +156 -0
- package/docs/container.md +92 -0
- package/docs/context-menu.json +231 -0
- package/docs/context-menu.md +176 -0
- package/docs/currency-field.examples.md +321 -0
- package/docs/currency-field.json +649 -0
- package/docs/currency-field.md +128 -0
- package/docs/dashboard-grid.json +680 -0
- package/docs/dashboard-grid.md +265 -0
- package/docs/data-grid.examples.md +3064 -0
- package/docs/data-grid.json +1577 -0
- package/docs/data-grid.md +237 -0
- package/docs/data-grid.props.md +81 -0
- package/docs/data-list.json +685 -0
- package/docs/data-list.md +327 -0
- package/docs/date-field.json +490 -0
- package/docs/date-field.md +235 -0
- package/docs/date-picker.examples.md +1226 -0
- package/docs/date-picker.json +696 -0
- package/docs/date-picker.md +121 -0
- package/docs/date-range-picker.examples.md +1300 -0
- package/docs/date-range-picker.json +903 -0
- package/docs/date-range-picker.md +142 -0
- package/docs/datetime-field.json +665 -0
- package/docs/datetime-field.md +337 -0
- package/docs/datetime-picker.examples.md +1269 -0
- package/docs/datetime-picker.json +928 -0
- package/docs/datetime-picker.md +150 -0
- package/docs/datetime-range-picker.examples.md +225 -0
- package/docs/datetime-range-picker.json +1015 -0
- package/docs/datetime-range-picker.md +162 -0
- package/docs/description-list.json +471 -0
- package/docs/description-list.md +268 -0
- package/docs/detail-panel.json +530 -0
- package/docs/detail-panel.md +361 -0
- package/docs/dialog.examples.md +2467 -0
- package/docs/dialog.json +1141 -0
- package/docs/dialog.md +217 -0
- package/docs/dialog.props.md +63 -0
- package/docs/divider.json +148 -0
- package/docs/divider.md +83 -0
- package/docs/drawer.examples.md +1929 -0
- package/docs/drawer.json +753 -0
- package/docs/drawer.md +199 -0
- package/docs/entity-picker.json +946 -0
- package/docs/entity-picker.md +365 -0
- package/docs/event-calendar.examples.md +308 -0
- package/docs/event-calendar.json +1202 -0
- package/docs/event-calendar.md +201 -0
- package/docs/field-group.json +333 -0
- package/docs/field-group.md +181 -0
- package/docs/field.examples.md +676 -0
- package/docs/field.json +528 -0
- package/docs/field.md +127 -0
- package/docs/filter-bar.json +817 -0
- package/docs/filter-bar.md +380 -0
- package/docs/form.json +378 -0
- package/docs/form.md +235 -0
- package/docs/fullscreen.json +395 -0
- package/docs/fullscreen.md +225 -0
- package/docs/grid.json +176 -0
- package/docs/grid.md +74 -0
- package/docs/highlight.json +279 -0
- package/docs/highlight.md +210 -0
- package/docs/hover-card.json +254 -0
- package/docs/hover-card.md +213 -0
- package/docs/icon.json +173 -0
- package/docs/icon.md +101 -0
- package/docs/image.json +476 -0
- package/docs/image.md +254 -0
- package/docs/import-export-center.json +836 -0
- package/docs/import-export-center.md +345 -0
- package/docs/index.md +141 -0
- package/docs/inline-message.json +312 -0
- package/docs/inline-message.md +191 -0
- package/docs/inline.json +149 -0
- package/docs/inline.md +72 -0
- package/docs/kbd.json +350 -0
- package/docs/kbd.md +210 -0
- package/docs/link.json +264 -0
- package/docs/link.md +167 -0
- package/docs/list-item.json +463 -0
- package/docs/list-item.md +236 -0
- package/docs/list.json +321 -0
- package/docs/list.md +185 -0
- package/docs/listbox.json +807 -0
- package/docs/listbox.md +413 -0
- package/docs/loading-overlay.json +440 -0
- package/docs/loading-overlay.md +248 -0
- package/docs/markdown.json +461 -0
- package/docs/markdown.md +266 -0
- package/docs/menu.examples.md +1651 -0
- package/docs/menu.json +922 -0
- package/docs/menu.md +155 -0
- package/docs/menubar.json +292 -0
- package/docs/menubar.md +173 -0
- package/docs/message-scroller.json +401 -0
- package/docs/message-scroller.md +212 -0
- package/docs/message.json +862 -0
- package/docs/message.md +473 -0
- package/docs/multi-select.examples.md +1922 -0
- package/docs/multi-select.json +1314 -0
- package/docs/multi-select.md +213 -0
- package/docs/navigation-menu.json +529 -0
- package/docs/navigation-menu.md +329 -0
- package/docs/notification-center.json +664 -0
- package/docs/notification-center.md +372 -0
- package/docs/number-field.examples.md +1078 -0
- package/docs/number-field.json +668 -0
- package/docs/number-field.md +137 -0
- package/docs/otp-input.json +479 -0
- package/docs/otp-input.md +291 -0
- package/docs/page-header.json +574 -0
- package/docs/page-header.md +338 -0
- package/docs/page.json +332 -0
- package/docs/page.md +184 -0
- package/docs/pagination.json +434 -0
- package/docs/pagination.md +238 -0
- package/docs/popover.examples.md +1235 -0
- package/docs/popover.json +656 -0
- package/docs/popover.md +199 -0
- package/docs/progress-indicator.json +501 -0
- package/docs/progress-indicator.md +329 -0
- package/docs/prompt-composer.json +498 -0
- package/docs/prompt-composer.md +278 -0
- package/docs/prose.json +357 -0
- package/docs/prose.md +226 -0
- package/docs/radio-group.examples.md +626 -0
- package/docs/radio-group.json +541 -0
- package/docs/radio-group.md +112 -0
- package/docs/rating.json +1053 -0
- package/docs/rating.md +435 -0
- package/docs/result-state.json +376 -0
- package/docs/result-state.md +286 -0
- package/docs/saved-views.json +384 -0
- package/docs/saved-views.md +242 -0
- package/docs/scroll-area.json +120 -0
- package/docs/scroll-area.md +8 -0
- package/docs/section.json +344 -0
- package/docs/section.md +208 -0
- package/docs/segmented-control.json +429 -0
- package/docs/segmented-control.md +240 -0
- package/docs/select.examples.md +1214 -0
- package/docs/select.json +1147 -0
- package/docs/select.md +199 -0
- package/docs/side-navigation.json +632 -0
- package/docs/side-navigation.md +430 -0
- package/docs/skeleton.json +358 -0
- package/docs/skeleton.md +223 -0
- package/docs/slider.json +522 -0
- package/docs/slider.md +261 -0
- package/docs/sparkline.json +426 -0
- package/docs/sparkline.md +206 -0
- package/docs/split-button.json +361 -0
- package/docs/split-button.md +275 -0
- package/docs/splitter.json +142 -0
- package/docs/splitter.md +14 -0
- package/docs/stack.json +135 -0
- package/docs/stack.md +74 -0
- package/docs/stat-card.json +529 -0
- package/docs/stat-card.md +270 -0
- package/docs/status-indicator.json +314 -0
- package/docs/status-indicator.md +197 -0
- package/docs/stepper.json +451 -0
- package/docs/stepper.md +250 -0
- package/docs/switch.json +451 -0
- package/docs/switch.md +508 -0
- package/docs/table-of-contents.json +553 -0
- package/docs/table-of-contents.md +289 -0
- package/docs/table.examples.md +1981 -0
- package/docs/table.json +1059 -0
- package/docs/table.md +290 -0
- package/docs/tabs.examples.md +1370 -0
- package/docs/tabs.json +661 -0
- package/docs/tabs.md +211 -0
- package/docs/tag.json +813 -0
- package/docs/tag.md +241 -0
- package/docs/tags-input.json +771 -0
- package/docs/tags-input.md +361 -0
- package/docs/text-field.examples.md +821 -0
- package/docs/text-field.json +604 -0
- package/docs/text-field.md +125 -0
- package/docs/textarea.examples.md +612 -0
- package/docs/textarea.json +440 -0
- package/docs/textarea.md +98 -0
- package/docs/time-field.json +584 -0
- package/docs/time-field.md +291 -0
- package/docs/time-picker.json +679 -0
- package/docs/time-picker.md +315 -0
- package/docs/time-range-picker.examples.md +191 -0
- package/docs/time-range-picker.json +924 -0
- package/docs/time-range-picker.md +152 -0
- package/docs/timeline.json +839 -0
- package/docs/timeline.md +401 -0
- package/docs/toast.json +642 -0
- package/docs/toast.md +311 -0
- package/docs/toggle-group.json +417 -0
- package/docs/toggle-group.md +255 -0
- package/docs/toggle.json +326 -0
- package/docs/toggle.md +222 -0
- package/docs/toolbar.json +380 -0
- package/docs/toolbar.md +240 -0
- package/docs/tooltip.examples.md +664 -0
- package/docs/tooltip.json +604 -0
- package/docs/tooltip.md +146 -0
- package/docs/top-navigation.examples.md +287 -0
- package/docs/top-navigation.json +648 -0
- package/docs/top-navigation.md +138 -0
- package/docs/tour.json +759 -0
- package/docs/tour.md +337 -0
- package/docs/transfer.json +746 -0
- package/docs/transfer.md +273 -0
- package/docs/tree.json +918 -0
- package/docs/tree.md +397 -0
- package/docs/typography.json +317 -0
- package/docs/typography.md +107 -0
- package/docs/upload.examples.md +358 -0
- package/docs/upload.json +1103 -0
- package/docs/upload.md +166 -0
- package/docs/visually-hidden.json +71 -0
- package/docs/visually-hidden.md +42 -0
- package/docs/wizard.json +724 -0
- package/docs/wizard.md +295 -0
- package/fesm2022/slotted-angular-accordion.mjs +247 -0
- package/fesm2022/slotted-angular-accordion.mjs.map +1 -0
- package/fesm2022/slotted-angular-action-bar.mjs +639 -0
- package/fesm2022/slotted-angular-action-bar.mjs.map +1 -0
- package/fesm2022/slotted-angular-action-sheet.mjs +749 -0
- package/fesm2022/slotted-angular-action-sheet.mjs.map +1 -0
- package/fesm2022/slotted-angular-alert.mjs +427 -0
- package/fesm2022/slotted-angular-alert.mjs.map +1 -0
- package/fesm2022/slotted-angular-app-shell.mjs +1334 -0
- package/fesm2022/slotted-angular-app-shell.mjs.map +1 -0
- package/fesm2022/slotted-angular-aspect-ratio.mjs +63 -0
- package/fesm2022/slotted-angular-aspect-ratio.mjs.map +1 -0
- package/fesm2022/slotted-angular-attachment.mjs +595 -0
- package/fesm2022/slotted-angular-attachment.mjs.map +1 -0
- package/fesm2022/slotted-angular-avatar-group.mjs +230 -0
- package/fesm2022/slotted-angular-avatar-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-avatar.mjs +330 -0
- package/fesm2022/slotted-angular-avatar.mjs.map +1 -0
- package/fesm2022/slotted-angular-badge.mjs +255 -0
- package/fesm2022/slotted-angular-badge.mjs.map +1 -0
- package/fesm2022/slotted-angular-breadcrumb.mjs +544 -0
- package/fesm2022/slotted-angular-breadcrumb.mjs.map +1 -0
- package/fesm2022/slotted-angular-button-group.mjs +146 -0
- package/fesm2022/slotted-angular-button-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-button.mjs +692 -0
- package/fesm2022/slotted-angular-button.mjs.map +1 -0
- package/fesm2022/slotted-angular-calendar.mjs +916 -0
- package/fesm2022/slotted-angular-calendar.mjs.map +1 -0
- package/fesm2022/slotted-angular-card.mjs +225 -0
- package/fesm2022/slotted-angular-card.mjs.map +1 -0
- package/fesm2022/slotted-angular-carousel.mjs +840 -0
- package/fesm2022/slotted-angular-carousel.mjs.map +1 -0
- package/fesm2022/slotted-angular-cascader.mjs +1839 -0
- package/fesm2022/slotted-angular-cascader.mjs.map +1 -0
- package/fesm2022/slotted-angular-chart.mjs +974 -0
- package/fesm2022/slotted-angular-chart.mjs.map +1 -0
- package/fesm2022/slotted-angular-checkbox-group.mjs +283 -0
- package/fesm2022/slotted-angular-checkbox-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-checkbox.mjs +468 -0
- package/fesm2022/slotted-angular-checkbox.mjs.map +1 -0
- package/fesm2022/slotted-angular-code-block.mjs +476 -0
- package/fesm2022/slotted-angular-code-block.mjs.map +1 -0
- package/fesm2022/slotted-angular-collapsible.mjs +479 -0
- package/fesm2022/slotted-angular-collapsible.mjs.map +1 -0
- package/fesm2022/slotted-angular-color-picker.mjs +910 -0
- package/fesm2022/slotted-angular-color-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-column-manager.mjs +1037 -0
- package/fesm2022/slotted-angular-column-manager.mjs.map +1 -0
- package/fesm2022/slotted-angular-combobox.mjs +1480 -0
- package/fesm2022/slotted-angular-combobox.mjs.map +1 -0
- package/fesm2022/slotted-angular-command-palette.mjs +1283 -0
- package/fesm2022/slotted-angular-command-palette.mjs.map +1 -0
- package/fesm2022/slotted-angular-container.mjs +105 -0
- package/fesm2022/slotted-angular-container.mjs.map +1 -0
- package/fesm2022/slotted-angular-context-menu.mjs +221 -0
- package/fesm2022/slotted-angular-context-menu.mjs.map +1 -0
- package/fesm2022/slotted-angular-currency-field.mjs +1131 -0
- package/fesm2022/slotted-angular-currency-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-dashboard-grid.mjs +1928 -0
- package/fesm2022/slotted-angular-dashboard-grid.mjs.map +1 -0
- package/fesm2022/slotted-angular-data-grid.mjs +6697 -0
- package/fesm2022/slotted-angular-data-grid.mjs.map +1 -0
- package/fesm2022/slotted-angular-data-list.mjs +1418 -0
- package/fesm2022/slotted-angular-data-list.mjs.map +1 -0
- package/fesm2022/slotted-angular-date-field.mjs +772 -0
- package/fesm2022/slotted-angular-date-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-date-picker.mjs +690 -0
- package/fesm2022/slotted-angular-date-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-date-range-picker.mjs +1150 -0
- package/fesm2022/slotted-angular-date-range-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-datetime-field.mjs +1058 -0
- package/fesm2022/slotted-angular-datetime-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-datetime-picker.mjs +1362 -0
- package/fesm2022/slotted-angular-datetime-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-datetime-range-picker.mjs +1872 -0
- package/fesm2022/slotted-angular-datetime-range-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-description-list.mjs +545 -0
- package/fesm2022/slotted-angular-description-list.mjs.map +1 -0
- package/fesm2022/slotted-angular-detail-panel.mjs +754 -0
- package/fesm2022/slotted-angular-detail-panel.mjs.map +1 -0
- package/fesm2022/slotted-angular-dialog.mjs +980 -0
- package/fesm2022/slotted-angular-dialog.mjs.map +1 -0
- package/fesm2022/slotted-angular-divider.mjs +76 -0
- package/fesm2022/slotted-angular-divider.mjs.map +1 -0
- package/fesm2022/slotted-angular-drawer.mjs +1397 -0
- package/fesm2022/slotted-angular-drawer.mjs.map +1 -0
- package/fesm2022/slotted-angular-entity-picker.mjs +1987 -0
- package/fesm2022/slotted-angular-entity-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-event-calendar.mjs +2934 -0
- package/fesm2022/slotted-angular-event-calendar.mjs.map +1 -0
- package/fesm2022/slotted-angular-field-group.mjs +301 -0
- package/fesm2022/slotted-angular-field-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-field.mjs +928 -0
- package/fesm2022/slotted-angular-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-filter-bar.mjs +3107 -0
- package/fesm2022/slotted-angular-filter-bar.mjs.map +1 -0
- package/fesm2022/slotted-angular-form.mjs +592 -0
- package/fesm2022/slotted-angular-form.mjs.map +1 -0
- package/fesm2022/slotted-angular-fullscreen.mjs +314 -0
- package/fesm2022/slotted-angular-fullscreen.mjs.map +1 -0
- package/fesm2022/slotted-angular-grid.mjs +58 -0
- package/fesm2022/slotted-angular-grid.mjs.map +1 -0
- package/fesm2022/slotted-angular-highlight.mjs +123 -0
- package/fesm2022/slotted-angular-highlight.mjs.map +1 -0
- package/fesm2022/slotted-angular-hover-card.mjs +326 -0
- package/fesm2022/slotted-angular-hover-card.mjs.map +1 -0
- package/fesm2022/slotted-angular-i18n.mjs +75 -0
- package/fesm2022/slotted-angular-i18n.mjs.map +1 -0
- package/fesm2022/slotted-angular-icon.mjs +232 -0
- package/fesm2022/slotted-angular-icon.mjs.map +1 -0
- package/fesm2022/slotted-angular-image.mjs +442 -0
- package/fesm2022/slotted-angular-image.mjs.map +1 -0
- package/fesm2022/slotted-angular-import-export-center.mjs +1792 -0
- package/fesm2022/slotted-angular-import-export-center.mjs.map +1 -0
- package/fesm2022/slotted-angular-inline-message.mjs +280 -0
- package/fesm2022/slotted-angular-inline-message.mjs.map +1 -0
- package/fesm2022/slotted-angular-inline.mjs +52 -0
- package/fesm2022/slotted-angular-inline.mjs.map +1 -0
- package/fesm2022/slotted-angular-kbd.mjs +284 -0
- package/fesm2022/slotted-angular-kbd.mjs.map +1 -0
- package/fesm2022/slotted-angular-link.mjs +182 -0
- package/fesm2022/slotted-angular-link.mjs.map +1 -0
- package/fesm2022/slotted-angular-list-item.mjs +367 -0
- package/fesm2022/slotted-angular-list-item.mjs.map +1 -0
- package/fesm2022/slotted-angular-list.mjs +256 -0
- package/fesm2022/slotted-angular-list.mjs.map +1 -0
- package/fesm2022/slotted-angular-listbox.mjs +1274 -0
- package/fesm2022/slotted-angular-listbox.mjs.map +1 -0
- package/fesm2022/slotted-angular-loading-overlay.mjs +451 -0
- package/fesm2022/slotted-angular-loading-overlay.mjs.map +1 -0
- package/fesm2022/slotted-angular-markdown.mjs +914 -0
- package/fesm2022/slotted-angular-markdown.mjs.map +1 -0
- package/fesm2022/slotted-angular-menu.mjs +1211 -0
- package/fesm2022/slotted-angular-menu.mjs.map +1 -0
- package/fesm2022/slotted-angular-menubar.mjs +230 -0
- package/fesm2022/slotted-angular-menubar.mjs.map +1 -0
- package/fesm2022/slotted-angular-message-scroller.mjs +378 -0
- package/fesm2022/slotted-angular-message-scroller.mjs.map +1 -0
- package/fesm2022/slotted-angular-message.mjs +866 -0
- package/fesm2022/slotted-angular-message.mjs.map +1 -0
- package/fesm2022/slotted-angular-multi-select.mjs +1939 -0
- package/fesm2022/slotted-angular-multi-select.mjs.map +1 -0
- package/fesm2022/slotted-angular-navigation-menu.mjs +770 -0
- package/fesm2022/slotted-angular-navigation-menu.mjs.map +1 -0
- package/fesm2022/slotted-angular-notification-center.mjs +1172 -0
- package/fesm2022/slotted-angular-notification-center.mjs.map +1 -0
- package/fesm2022/slotted-angular-number-field.mjs +966 -0
- package/fesm2022/slotted-angular-number-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-otp-input.mjs +629 -0
- package/fesm2022/slotted-angular-otp-input.mjs.map +1 -0
- package/fesm2022/slotted-angular-page-header.mjs +788 -0
- package/fesm2022/slotted-angular-page-header.mjs.map +1 -0
- package/fesm2022/slotted-angular-page.mjs +255 -0
- package/fesm2022/slotted-angular-page.mjs.map +1 -0
- package/fesm2022/slotted-angular-pagination.mjs +562 -0
- package/fesm2022/slotted-angular-pagination.mjs.map +1 -0
- package/fesm2022/slotted-angular-popover.mjs +799 -0
- package/fesm2022/slotted-angular-popover.mjs.map +1 -0
- package/fesm2022/slotted-angular-progress-indicator.mjs +572 -0
- package/fesm2022/slotted-angular-progress-indicator.mjs.map +1 -0
- package/fesm2022/slotted-angular-prompt-composer.mjs +596 -0
- package/fesm2022/slotted-angular-prompt-composer.mjs.map +1 -0
- package/fesm2022/slotted-angular-prose.mjs +314 -0
- package/fesm2022/slotted-angular-prose.mjs.map +1 -0
- package/fesm2022/slotted-angular-radio-group.mjs +469 -0
- package/fesm2022/slotted-angular-radio-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-rating.mjs +1174 -0
- package/fesm2022/slotted-angular-rating.mjs.map +1 -0
- package/fesm2022/slotted-angular-result-state.mjs +330 -0
- package/fesm2022/slotted-angular-result-state.mjs.map +1 -0
- package/fesm2022/slotted-angular-saved-views.mjs +877 -0
- package/fesm2022/slotted-angular-saved-views.mjs.map +1 -0
- package/fesm2022/slotted-angular-scroll-area.mjs +294 -0
- package/fesm2022/slotted-angular-scroll-area.mjs.map +1 -0
- package/fesm2022/slotted-angular-section.mjs +266 -0
- package/fesm2022/slotted-angular-section.mjs.map +1 -0
- package/fesm2022/slotted-angular-segmented-control.mjs +454 -0
- package/fesm2022/slotted-angular-segmented-control.mjs.map +1 -0
- package/fesm2022/slotted-angular-select.mjs +1899 -0
- package/fesm2022/slotted-angular-select.mjs.map +1 -0
- package/fesm2022/slotted-angular-side-navigation.mjs +1042 -0
- package/fesm2022/slotted-angular-side-navigation.mjs.map +1 -0
- package/fesm2022/slotted-angular-skeleton.mjs +316 -0
- package/fesm2022/slotted-angular-skeleton.mjs.map +1 -0
- package/fesm2022/slotted-angular-slider.mjs +586 -0
- package/fesm2022/slotted-angular-slider.mjs.map +1 -0
- package/fesm2022/slotted-angular-sparkline.mjs +235 -0
- package/fesm2022/slotted-angular-sparkline.mjs.map +1 -0
- package/fesm2022/slotted-angular-split-button.mjs +331 -0
- package/fesm2022/slotted-angular-split-button.mjs.map +1 -0
- package/fesm2022/slotted-angular-splitter.mjs +516 -0
- package/fesm2022/slotted-angular-splitter.mjs.map +1 -0
- package/fesm2022/slotted-angular-stack.mjs +48 -0
- package/fesm2022/slotted-angular-stack.mjs.map +1 -0
- package/fesm2022/slotted-angular-stat-card.mjs +478 -0
- package/fesm2022/slotted-angular-stat-card.mjs.map +1 -0
- package/fesm2022/slotted-angular-status-indicator.mjs +155 -0
- package/fesm2022/slotted-angular-status-indicator.mjs.map +1 -0
- package/fesm2022/slotted-angular-stepper.mjs +536 -0
- package/fesm2022/slotted-angular-stepper.mjs.map +1 -0
- package/fesm2022/slotted-angular-switch.mjs +447 -0
- package/fesm2022/slotted-angular-switch.mjs.map +1 -0
- package/fesm2022/slotted-angular-table-of-contents.mjs +750 -0
- package/fesm2022/slotted-angular-table-of-contents.mjs.map +1 -0
- package/fesm2022/slotted-angular-table.mjs +2518 -0
- package/fesm2022/slotted-angular-table.mjs.map +1 -0
- package/fesm2022/slotted-angular-tabs.mjs +829 -0
- package/fesm2022/slotted-angular-tabs.mjs.map +1 -0
- package/fesm2022/slotted-angular-tag.mjs +595 -0
- package/fesm2022/slotted-angular-tag.mjs.map +1 -0
- package/fesm2022/slotted-angular-tags-input.mjs +1211 -0
- package/fesm2022/slotted-angular-tags-input.mjs.map +1 -0
- package/fesm2022/slotted-angular-text-field.mjs +674 -0
- package/fesm2022/slotted-angular-text-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-textarea.mjs +275 -0
- package/fesm2022/slotted-angular-textarea.mjs.map +1 -0
- package/fesm2022/slotted-angular-theme.mjs +45 -0
- package/fesm2022/slotted-angular-theme.mjs.map +1 -0
- package/fesm2022/slotted-angular-time-field.mjs +895 -0
- package/fesm2022/slotted-angular-time-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-time-picker.mjs +856 -0
- package/fesm2022/slotted-angular-time-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-time-range-picker.mjs +1534 -0
- package/fesm2022/slotted-angular-time-range-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-timeline.mjs +928 -0
- package/fesm2022/slotted-angular-timeline.mjs.map +1 -0
- package/fesm2022/slotted-angular-toast.mjs +917 -0
- package/fesm2022/slotted-angular-toast.mjs.map +1 -0
- package/fesm2022/slotted-angular-toggle-group.mjs +311 -0
- package/fesm2022/slotted-angular-toggle-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-toggle.mjs +162 -0
- package/fesm2022/slotted-angular-toggle.mjs.map +1 -0
- package/fesm2022/slotted-angular-toolbar.mjs +536 -0
- package/fesm2022/slotted-angular-toolbar.mjs.map +1 -0
- package/fesm2022/slotted-angular-tooltip.mjs +798 -0
- package/fesm2022/slotted-angular-tooltip.mjs.map +1 -0
- package/fesm2022/slotted-angular-top-navigation.mjs +1308 -0
- package/fesm2022/slotted-angular-top-navigation.mjs.map +1 -0
- package/fesm2022/slotted-angular-tour.mjs +1330 -0
- package/fesm2022/slotted-angular-tour.mjs.map +1 -0
- package/fesm2022/slotted-angular-transfer.mjs +1406 -0
- package/fesm2022/slotted-angular-transfer.mjs.map +1 -0
- package/fesm2022/slotted-angular-tree.mjs +1448 -0
- package/fesm2022/slotted-angular-tree.mjs.map +1 -0
- package/fesm2022/slotted-angular-typography.mjs +184 -0
- package/fesm2022/slotted-angular-typography.mjs.map +1 -0
- package/fesm2022/slotted-angular-upload.mjs +1523 -0
- package/fesm2022/slotted-angular-upload.mjs.map +1 -0
- package/fesm2022/slotted-angular-visually-hidden.mjs +32 -0
- package/fesm2022/slotted-angular-visually-hidden.mjs.map +1 -0
- package/fesm2022/slotted-angular-wizard.mjs +1715 -0
- package/fesm2022/slotted-angular-wizard.mjs.map +1 -0
- package/fesm2022/slotted-angular.mjs +4 -0
- package/fesm2022/slotted-angular.mjs.map +1 -0
- package/package.json +537 -3
- package/types/slotted-angular-accordion.d.ts +156 -0
- package/types/slotted-angular-accordion.d.ts.map +1 -0
- package/types/slotted-angular-action-bar.d.ts +291 -0
- package/types/slotted-angular-action-bar.d.ts.map +1 -0
- package/types/slotted-angular-action-sheet.d.ts +294 -0
- package/types/slotted-angular-action-sheet.d.ts.map +1 -0
- package/types/slotted-angular-alert.d.ts +214 -0
- package/types/slotted-angular-alert.d.ts.map +1 -0
- package/types/slotted-angular-app-shell.d.ts +549 -0
- package/types/slotted-angular-app-shell.d.ts.map +1 -0
- package/types/slotted-angular-aspect-ratio.d.ts +57 -0
- package/types/slotted-angular-aspect-ratio.d.ts.map +1 -0
- package/types/slotted-angular-attachment.d.ts +294 -0
- package/types/slotted-angular-attachment.d.ts.map +1 -0
- package/types/slotted-angular-avatar-group.d.ts +119 -0
- package/types/slotted-angular-avatar-group.d.ts.map +1 -0
- package/types/slotted-angular-avatar.d.ts +202 -0
- package/types/slotted-angular-avatar.d.ts.map +1 -0
- package/types/slotted-angular-badge.d.ts +166 -0
- package/types/slotted-angular-badge.d.ts.map +1 -0
- package/types/slotted-angular-breadcrumb.d.ts +251 -0
- package/types/slotted-angular-breadcrumb.d.ts.map +1 -0
- package/types/slotted-angular-button-group.d.ts +89 -0
- package/types/slotted-angular-button-group.d.ts.map +1 -0
- package/types/slotted-angular-button.d.ts +390 -0
- package/types/slotted-angular-button.d.ts.map +1 -0
- package/types/slotted-angular-calendar.d.ts +280 -0
- package/types/slotted-angular-calendar.d.ts.map +1 -0
- package/types/slotted-angular-card.d.ts +140 -0
- package/types/slotted-angular-card.d.ts.map +1 -0
- package/types/slotted-angular-carousel.d.ts +288 -0
- package/types/slotted-angular-carousel.d.ts.map +1 -0
- package/types/slotted-angular-cascader.d.ts +351 -0
- package/types/slotted-angular-cascader.d.ts.map +1 -0
- package/types/slotted-angular-chart.d.ts +319 -0
- package/types/slotted-angular-chart.d.ts.map +1 -0
- package/types/slotted-angular-checkbox-group.d.ts +156 -0
- package/types/slotted-angular-checkbox-group.d.ts.map +1 -0
- package/types/slotted-angular-checkbox.d.ts +197 -0
- package/types/slotted-angular-checkbox.d.ts.map +1 -0
- package/types/slotted-angular-code-block.d.ts +158 -0
- package/types/slotted-angular-code-block.d.ts.map +1 -0
- package/types/slotted-angular-collapsible.d.ts +272 -0
- package/types/slotted-angular-collapsible.d.ts.map +1 -0
- package/types/slotted-angular-color-picker.d.ts +181 -0
- package/types/slotted-angular-color-picker.d.ts.map +1 -0
- package/types/slotted-angular-column-manager.d.ts +200 -0
- package/types/slotted-angular-column-manager.d.ts.map +1 -0
- package/types/slotted-angular-combobox.d.ts +449 -0
- package/types/slotted-angular-combobox.d.ts.map +1 -0
- package/types/slotted-angular-command-palette.d.ts +256 -0
- package/types/slotted-angular-command-palette.d.ts.map +1 -0
- package/types/slotted-angular-container.d.ts +84 -0
- package/types/slotted-angular-container.d.ts.map +1 -0
- package/types/slotted-angular-context-menu.d.ts +84 -0
- package/types/slotted-angular-context-menu.d.ts.map +1 -0
- package/types/slotted-angular-currency-field.d.ts +480 -0
- package/types/slotted-angular-currency-field.d.ts.map +1 -0
- package/types/slotted-angular-dashboard-grid.d.ts +341 -0
- package/types/slotted-angular-dashboard-grid.d.ts.map +1 -0
- package/types/slotted-angular-data-grid.d.ts +1077 -0
- package/types/slotted-angular-data-grid.d.ts.map +1 -0
- package/types/slotted-angular-data-list.d.ts +272 -0
- package/types/slotted-angular-data-list.d.ts.map +1 -0
- package/types/slotted-angular-date-field.d.ts +320 -0
- package/types/slotted-angular-date-field.d.ts.map +1 -0
- package/types/slotted-angular-date-picker.d.ts +224 -0
- package/types/slotted-angular-date-picker.d.ts.map +1 -0
- package/types/slotted-angular-date-range-picker.d.ts +310 -0
- package/types/slotted-angular-date-range-picker.d.ts.map +1 -0
- package/types/slotted-angular-datetime-field.d.ts +362 -0
- package/types/slotted-angular-datetime-field.d.ts.map +1 -0
- package/types/slotted-angular-datetime-picker.d.ts +370 -0
- package/types/slotted-angular-datetime-picker.d.ts.map +1 -0
- package/types/slotted-angular-datetime-range-picker.d.ts +459 -0
- package/types/slotted-angular-datetime-range-picker.d.ts.map +1 -0
- package/types/slotted-angular-description-list.d.ts +281 -0
- package/types/slotted-angular-description-list.d.ts.map +1 -0
- package/types/slotted-angular-detail-panel.d.ts +240 -0
- package/types/slotted-angular-detail-panel.d.ts.map +1 -0
- package/types/slotted-angular-dialog.d.ts +497 -0
- package/types/slotted-angular-dialog.d.ts.map +1 -0
- package/types/slotted-angular-divider.d.ts +40 -0
- package/types/slotted-angular-divider.d.ts.map +1 -0
- package/types/slotted-angular-drawer.d.ts +532 -0
- package/types/slotted-angular-drawer.d.ts.map +1 -0
- package/types/slotted-angular-entity-picker.d.ts +338 -0
- package/types/slotted-angular-entity-picker.d.ts.map +1 -0
- package/types/slotted-angular-event-calendar.d.ts +574 -0
- package/types/slotted-angular-event-calendar.d.ts.map +1 -0
- package/types/slotted-angular-field-group.d.ts +152 -0
- package/types/slotted-angular-field-group.d.ts.map +1 -0
- package/types/slotted-angular-field.d.ts +535 -0
- package/types/slotted-angular-field.d.ts.map +1 -0
- package/types/slotted-angular-filter-bar.d.ts +573 -0
- package/types/slotted-angular-filter-bar.d.ts.map +1 -0
- package/types/slotted-angular-form.d.ts +298 -0
- package/types/slotted-angular-form.d.ts.map +1 -0
- package/types/slotted-angular-fullscreen.d.ts +145 -0
- package/types/slotted-angular-fullscreen.d.ts.map +1 -0
- package/types/slotted-angular-grid.d.ts +50 -0
- package/types/slotted-angular-grid.d.ts.map +1 -0
- package/types/slotted-angular-highlight.d.ts +93 -0
- package/types/slotted-angular-highlight.d.ts.map +1 -0
- package/types/slotted-angular-hover-card.d.ts +140 -0
- package/types/slotted-angular-hover-card.d.ts.map +1 -0
- package/types/slotted-angular-i18n.d.ts +46 -0
- package/types/slotted-angular-i18n.d.ts.map +1 -0
- package/types/slotted-angular-icon.d.ts +94 -0
- package/types/slotted-angular-icon.d.ts.map +1 -0
- package/types/slotted-angular-image.d.ts +251 -0
- package/types/slotted-angular-image.d.ts.map +1 -0
- package/types/slotted-angular-import-export-center.d.ts +351 -0
- package/types/slotted-angular-import-export-center.d.ts.map +1 -0
- package/types/slotted-angular-inline-message.d.ts +195 -0
- package/types/slotted-angular-inline-message.d.ts.map +1 -0
- package/types/slotted-angular-inline.d.ts +41 -0
- package/types/slotted-angular-inline.d.ts.map +1 -0
- package/types/slotted-angular-kbd.d.ts +174 -0
- package/types/slotted-angular-kbd.d.ts.map +1 -0
- package/types/slotted-angular-link.d.ts +94 -0
- package/types/slotted-angular-link.d.ts.map +1 -0
- package/types/slotted-angular-list-item.d.ts +210 -0
- package/types/slotted-angular-list-item.d.ts.map +1 -0
- package/types/slotted-angular-list.d.ts +176 -0
- package/types/slotted-angular-list.d.ts.map +1 -0
- package/types/slotted-angular-listbox.d.ts +470 -0
- package/types/slotted-angular-listbox.d.ts.map +1 -0
- package/types/slotted-angular-loading-overlay.d.ts +219 -0
- package/types/slotted-angular-loading-overlay.d.ts.map +1 -0
- package/types/slotted-angular-markdown.d.ts +172 -0
- package/types/slotted-angular-markdown.d.ts.map +1 -0
- package/types/slotted-angular-menu.d.ts +448 -0
- package/types/slotted-angular-menu.d.ts.map +1 -0
- package/types/slotted-angular-menubar.d.ts +90 -0
- package/types/slotted-angular-menubar.d.ts.map +1 -0
- package/types/slotted-angular-message-scroller.d.ts +151 -0
- package/types/slotted-angular-message-scroller.d.ts.map +1 -0
- package/types/slotted-angular-message.d.ts +348 -0
- package/types/slotted-angular-message.d.ts.map +1 -0
- package/types/slotted-angular-multi-select.d.ts +462 -0
- package/types/slotted-angular-multi-select.d.ts.map +1 -0
- package/types/slotted-angular-navigation-menu.d.ts +309 -0
- package/types/slotted-angular-navigation-menu.d.ts.map +1 -0
- package/types/slotted-angular-notification-center.d.ts +318 -0
- package/types/slotted-angular-notification-center.d.ts.map +1 -0
- package/types/slotted-angular-number-field.d.ts +402 -0
- package/types/slotted-angular-number-field.d.ts.map +1 -0
- package/types/slotted-angular-otp-input.d.ts +286 -0
- package/types/slotted-angular-otp-input.d.ts.map +1 -0
- package/types/slotted-angular-page-header.d.ts +334 -0
- package/types/slotted-angular-page-header.d.ts.map +1 -0
- package/types/slotted-angular-page.d.ts +141 -0
- package/types/slotted-angular-page.d.ts.map +1 -0
- package/types/slotted-angular-pagination.d.ts +213 -0
- package/types/slotted-angular-pagination.d.ts.map +1 -0
- package/types/slotted-angular-popover.d.ts +366 -0
- package/types/slotted-angular-popover.d.ts.map +1 -0
- package/types/slotted-angular-progress-indicator.d.ts +312 -0
- package/types/slotted-angular-progress-indicator.d.ts.map +1 -0
- package/types/slotted-angular-prompt-composer.d.ts +242 -0
- package/types/slotted-angular-prompt-composer.d.ts.map +1 -0
- package/types/slotted-angular-prose.d.ts +171 -0
- package/types/slotted-angular-prose.d.ts.map +1 -0
- package/types/slotted-angular-radio-group.d.ts +268 -0
- package/types/slotted-angular-radio-group.d.ts.map +1 -0
- package/types/slotted-angular-rating.d.ts +374 -0
- package/types/slotted-angular-rating.d.ts.map +1 -0
- package/types/slotted-angular-result-state.d.ts +217 -0
- package/types/slotted-angular-result-state.d.ts.map +1 -0
- package/types/slotted-angular-saved-views.d.ts +198 -0
- package/types/slotted-angular-saved-views.d.ts.map +1 -0
- package/types/slotted-angular-scroll-area.d.ts +186 -0
- package/types/slotted-angular-scroll-area.d.ts.map +1 -0
- package/types/slotted-angular-section.d.ts +143 -0
- package/types/slotted-angular-section.d.ts.map +1 -0
- package/types/slotted-angular-segmented-control.d.ts +251 -0
- package/types/slotted-angular-segmented-control.d.ts.map +1 -0
- package/types/slotted-angular-select.d.ts +507 -0
- package/types/slotted-angular-select.d.ts.map +1 -0
- package/types/slotted-angular-side-navigation.d.ts +373 -0
- package/types/slotted-angular-side-navigation.d.ts.map +1 -0
- package/types/slotted-angular-skeleton.d.ts +198 -0
- package/types/slotted-angular-skeleton.d.ts.map +1 -0
- package/types/slotted-angular-slider.d.ts +216 -0
- package/types/slotted-angular-slider.d.ts.map +1 -0
- package/types/slotted-angular-sparkline.d.ts +106 -0
- package/types/slotted-angular-sparkline.d.ts.map +1 -0
- package/types/slotted-angular-split-button.d.ts +180 -0
- package/types/slotted-angular-split-button.d.ts.map +1 -0
- package/types/slotted-angular-splitter.d.ts +206 -0
- package/types/slotted-angular-splitter.d.ts.map +1 -0
- package/types/slotted-angular-stack.d.ts +38 -0
- package/types/slotted-angular-stack.d.ts.map +1 -0
- package/types/slotted-angular-stat-card.d.ts +232 -0
- package/types/slotted-angular-stat-card.d.ts.map +1 -0
- package/types/slotted-angular-status-indicator.d.ts +106 -0
- package/types/slotted-angular-status-indicator.d.ts.map +1 -0
- package/types/slotted-angular-stepper.d.ts +198 -0
- package/types/slotted-angular-stepper.d.ts.map +1 -0
- package/types/slotted-angular-switch.d.ts +243 -0
- package/types/slotted-angular-switch.d.ts.map +1 -0
- package/types/slotted-angular-table-of-contents.d.ts +210 -0
- package/types/slotted-angular-table-of-contents.d.ts.map +1 -0
- package/types/slotted-angular-table.d.ts +888 -0
- package/types/slotted-angular-table.d.ts.map +1 -0
- package/types/slotted-angular-tabs.d.ts +340 -0
- package/types/slotted-angular-tabs.d.ts.map +1 -0
- package/types/slotted-angular-tag.d.ts +279 -0
- package/types/slotted-angular-tag.d.ts.map +1 -0
- package/types/slotted-angular-tags-input.d.ts +302 -0
- package/types/slotted-angular-tags-input.d.ts.map +1 -0
- package/types/slotted-angular-text-field.d.ts +334 -0
- package/types/slotted-angular-text-field.d.ts.map +1 -0
- package/types/slotted-angular-textarea.d.ts +150 -0
- package/types/slotted-angular-textarea.d.ts.map +1 -0
- package/types/slotted-angular-theme.d.ts +26 -0
- package/types/slotted-angular-theme.d.ts.map +1 -0
- package/types/slotted-angular-time-field.d.ts +300 -0
- package/types/slotted-angular-time-field.d.ts.map +1 -0
- package/types/slotted-angular-time-picker.d.ts +260 -0
- package/types/slotted-angular-time-picker.d.ts.map +1 -0
- package/types/slotted-angular-time-range-picker.d.ts +401 -0
- package/types/slotted-angular-time-range-picker.d.ts.map +1 -0
- package/types/slotted-angular-timeline.d.ts +329 -0
- package/types/slotted-angular-timeline.d.ts.map +1 -0
- package/types/slotted-angular-toast.d.ts +340 -0
- package/types/slotted-angular-toast.d.ts.map +1 -0
- package/types/slotted-angular-toggle-group.d.ts +167 -0
- package/types/slotted-angular-toggle-group.d.ts.map +1 -0
- package/types/slotted-angular-toggle.d.ts +106 -0
- package/types/slotted-angular-toggle.d.ts.map +1 -0
- package/types/slotted-angular-toolbar.d.ts +252 -0
- package/types/slotted-angular-toolbar.d.ts.map +1 -0
- package/types/slotted-angular-tooltip.d.ts +388 -0
- package/types/slotted-angular-tooltip.d.ts.map +1 -0
- package/types/slotted-angular-top-navigation.d.ts +442 -0
- package/types/slotted-angular-top-navigation.d.ts.map +1 -0
- package/types/slotted-angular-tour.d.ts +440 -0
- package/types/slotted-angular-tour.d.ts.map +1 -0
- package/types/slotted-angular-transfer.d.ts +296 -0
- package/types/slotted-angular-transfer.d.ts.map +1 -0
- package/types/slotted-angular-tree.d.ts +499 -0
- package/types/slotted-angular-tree.d.ts.map +1 -0
- package/types/slotted-angular-typography.d.ts +89 -0
- package/types/slotted-angular-typography.d.ts.map +1 -0
- package/types/slotted-angular-upload.d.ts +365 -0
- package/types/slotted-angular-upload.d.ts.map +1 -0
- package/types/slotted-angular-visually-hidden.d.ts +19 -0
- package/types/slotted-angular-visually-hidden.d.ts.map +1 -0
- package/types/slotted-angular-wizard.d.ts +441 -0
- package/types/slotted-angular-wizard.d.ts.map +1 -0
- package/types/slotted-angular.d.ts +3 -0
- package/types/slotted-angular.d.ts.map +1 -0
|
@@ -0,0 +1,1899 @@
|
|
|
1
|
+
import { createFilter, moveIndex } from '@slotted/core/collection';
|
|
2
|
+
import { tabbables } from '@slotted/core/focus';
|
|
3
|
+
import { createWidthGate } from '@slotted/core/measure';
|
|
4
|
+
import { createCollapse } from '@slotted/core/overflow';
|
|
5
|
+
import { createDismissableLayer } from '@slotted/core/dismissable-layer';
|
|
6
|
+
import { selectMessages } from '@slotted/core/i18n';
|
|
7
|
+
import { createPortalRoot } from '@slotted/core/portal';
|
|
8
|
+
import { createPositioner } from '@slotted/core/positioner';
|
|
9
|
+
import { createPresence } from '@slotted/core/presence';
|
|
10
|
+
import { createControllable } from '@slotted/core/state';
|
|
11
|
+
import { isPrintable, createTypeahead } from '@slotted/core/typeahead';
|
|
12
|
+
import * as i0 from '@angular/core';
|
|
13
|
+
import { InjectionToken, inject, Directive, booleanAttribute, numberAttribute, model, output, input, computed, ViewContainerRef, viewChild, contentChild, TemplateRef, signal, HostAttributeToken, DestroyRef, ElementRef, effect, untracked, afterRenderEffect, afterNextRender, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
14
|
+
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
15
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
16
|
+
import { injectMessages, injectLocale } from '@slotted/angular/i18n';
|
|
17
|
+
import { SlGlyph, SlIcon } from '@slotted/angular/icon';
|
|
18
|
+
import { SlField } from '@slotted/angular/field';
|
|
19
|
+
import { matchRanges } from '@slotted/core/highlight';
|
|
20
|
+
import { SlHighlight } from '@slotted/angular/highlight';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The numbers, and why they are these numbers. The reasoning is the React
|
|
24
|
+
* binding's, written out in `packages/react/src/select/select-defaults.tsx`;
|
|
25
|
+
* the two tables are checked against each other by the contract, which holds
|
|
26
|
+
* every one of them as a declared default.
|
|
27
|
+
*/
|
|
28
|
+
const SELECT_FALLBACK = {
|
|
29
|
+
align: 'start',
|
|
30
|
+
alignOffset: 0,
|
|
31
|
+
clearable: false,
|
|
32
|
+
highlightMatch: true,
|
|
33
|
+
search: false,
|
|
34
|
+
closeOnEscape: true,
|
|
35
|
+
closeOnOutsidePress: true,
|
|
36
|
+
closeOnSelect: true,
|
|
37
|
+
collisionPadding: 8,
|
|
38
|
+
disabled: false,
|
|
39
|
+
flip: true,
|
|
40
|
+
fullWidth: true,
|
|
41
|
+
hideWhenDetached: true,
|
|
42
|
+
invalid: false,
|
|
43
|
+
loading: false,
|
|
44
|
+
loop: false,
|
|
45
|
+
mount: 'active',
|
|
46
|
+
multiple: false,
|
|
47
|
+
portal: true,
|
|
48
|
+
readOnly: false,
|
|
49
|
+
required: false,
|
|
50
|
+
shift: true,
|
|
51
|
+
side: 'bottom',
|
|
52
|
+
sideOffset: 4,
|
|
53
|
+
size: 'md',
|
|
54
|
+
strategy: 'absolute',
|
|
55
|
+
typeahead: true,
|
|
56
|
+
typeaheadTimeout: 500,
|
|
57
|
+
variant: 'outline',
|
|
58
|
+
width: 'content',
|
|
59
|
+
};
|
|
60
|
+
const SELECT_DEFAULTS = new InjectionToken('SELECT_DEFAULTS', {
|
|
61
|
+
providedIn: 'root',
|
|
62
|
+
factory: () => SELECT_FALLBACK,
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* The decisions an application takes once, in its bootstrap, rather than on
|
|
66
|
+
* every select it renders. A select that states one of them itself still wins.
|
|
67
|
+
* Its words come from the language in force (`provideSlotted`).
|
|
68
|
+
*/
|
|
69
|
+
function provideSelectDefaults(defaults) {
|
|
70
|
+
return { provide: SELECT_DEFAULTS, useValue: { ...SELECT_FALLBACK, ...defaults } };
|
|
71
|
+
}
|
|
72
|
+
function injectSelectDefaults() {
|
|
73
|
+
return inject(SELECT_DEFAULTS);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The summary a consumer writes instead of the family's own.
|
|
78
|
+
*
|
|
79
|
+
* A `TemplateRef` rather than a render function, because that is what Angular
|
|
80
|
+
* has where React has a function — and it is the asymmetry
|
|
81
|
+
* `docs/history/designs/2026-09-04-select-and-combobox-design.md` §11 records
|
|
82
|
+
* rather than levels away. The context carries the values and the labels the
|
|
83
|
+
* family could resolve, so a consumer who already holds the records does not
|
|
84
|
+
* resolve them twice:
|
|
85
|
+
*
|
|
86
|
+
* ```html
|
|
87
|
+
* <ng-template slSelectValue let-values let-labels="labels">
|
|
88
|
+
* {{ values.length }} of 40 chosen
|
|
89
|
+
* </ng-template>
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
class SlSelectValue {
|
|
93
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelectValue, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
94
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: SlSelectValue, isStandalone: true, selector: "[slSelectValue]", ngImport: i0 });
|
|
95
|
+
}
|
|
96
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelectValue, decorators: [{
|
|
97
|
+
type: Directive,
|
|
98
|
+
args: [{ selector: '[slSelectValue]', standalone: true }]
|
|
99
|
+
}] });
|
|
100
|
+
|
|
101
|
+
/** The width, in CSS pixels, under which a chip has no room for a word (SL4). */
|
|
102
|
+
const NARROW_WIDTH = 120;
|
|
103
|
+
/* A filtered-out option stays in the DOM and hides: Angular cannot decline to
|
|
104
|
+
render a host component from inside it. Every reader of the collection —
|
|
105
|
+
the movement keys, the count, the entry highlight — takes the visible ones,
|
|
106
|
+
which is the selector `combobox` already writes for the same reason. */
|
|
107
|
+
const OPTION_SELECTOR = "[data-part='item']:not([hidden])";
|
|
108
|
+
/**
|
|
109
|
+
* Brings an option into view without moving the page: the nearest scrolling
|
|
110
|
+
* box between the option and the popup surface is scrolled, by the least
|
|
111
|
+
* distance that shows the whole row, and nothing past it. `scrollIntoView`
|
|
112
|
+
* would scroll every ancestor too, and on the first open it runs before the
|
|
113
|
+
* popup is positioned — a select far down a page sent the page to its top.
|
|
114
|
+
*/
|
|
115
|
+
function revealWithin(option, surface) {
|
|
116
|
+
let box = surface;
|
|
117
|
+
for (let node = option.parentElement; node !== null && node !== surface; node = node.parentElement) {
|
|
118
|
+
const overflow = getComputedStyle(node).overflowY;
|
|
119
|
+
if (overflow === 'auto' || overflow === 'scroll') {
|
|
120
|
+
box = node;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const row = option.getBoundingClientRect();
|
|
125
|
+
const top = box.getBoundingClientRect().top + box.clientTop;
|
|
126
|
+
const bottom = top + box.clientHeight;
|
|
127
|
+
if (row.top < top)
|
|
128
|
+
box.scrollTop -= top - row.top;
|
|
129
|
+
else if (row.bottom > bottom)
|
|
130
|
+
box.scrollTop += Math.min(row.bottom - bottom, row.top - top);
|
|
131
|
+
}
|
|
132
|
+
const isGroup = (entry) => 'options' in entry;
|
|
133
|
+
const flatten = (items) => items === undefined ? [] : items.flatMap((entry) => (isGroup(entry) ? entry.options : [entry]));
|
|
134
|
+
/**
|
|
135
|
+
* A control that shows the current choice and opens a listbox of the rest.
|
|
136
|
+
*
|
|
137
|
+
* **The host element is the control.** `sl-select` carries `data-ui` and the
|
|
138
|
+
* frame's own `data-part`, and the button, the chevron, the clear button and
|
|
139
|
+
* the hidden native `select` are its template — the same shape `text-field`
|
|
140
|
+
* has, where the frame draws the border and the ring because a ring can only be
|
|
141
|
+
* drawn by an ancestor of whatever took focus.
|
|
142
|
+
*
|
|
143
|
+
* **The popup is an `ng-template` built into the portal when it opens**, which
|
|
144
|
+
* is how `sl-menu` is built and for the same reason: a surface that has to
|
|
145
|
+
* escape its parent's clipping cannot be rendered where it was declared. It
|
|
146
|
+
* also makes `mount` a real axis here — a hundred options are not constructed
|
|
147
|
+
* until the popup is.
|
|
148
|
+
*
|
|
149
|
+
* **Focus never leaves the button.** The highlighted option is named by
|
|
150
|
+
* `aria-activedescendant`, which is what the APG's own select-only combobox
|
|
151
|
+
* example does and what this family's pair, `combobox`, has no choice about.
|
|
152
|
+
*/
|
|
153
|
+
class SlSelect {
|
|
154
|
+
static flag = (given) => given === undefined ? undefined : booleanAttribute(given);
|
|
155
|
+
static count = (given) => given === undefined ? undefined : numberAttribute(given);
|
|
156
|
+
/** The chosen value, or the chosen values when `multiple` is set. */
|
|
157
|
+
value = model(null, /* @ts-ignore */
|
|
158
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
159
|
+
valueChangeRequest = output();
|
|
160
|
+
open = model(false, /* @ts-ignore */
|
|
161
|
+
...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
162
|
+
openChangeRequest = output();
|
|
163
|
+
/** The option the highlight is on, which is not the option that is chosen. */
|
|
164
|
+
highlightedValue = model(null, /* @ts-ignore */
|
|
165
|
+
...(ngDevMode ? [{ debugName: "highlightedValue" }] : /* istanbul ignore next */ []));
|
|
166
|
+
highlightedValueChangeRequest = output();
|
|
167
|
+
/**
|
|
168
|
+
* What the reader has typed into the search field. It is a value the consumer
|
|
169
|
+
* can own and it is **not** the selection: no request ever carries both.
|
|
170
|
+
*/
|
|
171
|
+
searchValue = model('', /* @ts-ignore */
|
|
172
|
+
...(ngDevMode ? [{ debugName: "searchValue" }] : /* istanbul ignore next */ []));
|
|
173
|
+
searchValueChangeRequest = output();
|
|
174
|
+
ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
175
|
+
placeholder = input('', /* @ts-ignore */
|
|
176
|
+
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
177
|
+
name = input(undefined, /* @ts-ignore */
|
|
178
|
+
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
179
|
+
form = input(undefined, /* @ts-ignore */
|
|
180
|
+
...(ngDevMode ? [{ debugName: "form" }] : /* istanbul ignore next */ []));
|
|
181
|
+
/** Labels for values, so a closed control can name one it never rendered. */
|
|
182
|
+
items = input(undefined, /* @ts-ignore */
|
|
183
|
+
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
184
|
+
total = input(undefined, { ...(ngDevMode ? { debugName: "total" } : /* istanbul ignore next */ {}), transform: SlSelect.count });
|
|
185
|
+
size = input(undefined, /* @ts-ignore */
|
|
186
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
187
|
+
variant = input(undefined, /* @ts-ignore */
|
|
188
|
+
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
189
|
+
side = input(undefined, /* @ts-ignore */
|
|
190
|
+
...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
|
|
191
|
+
align = input(undefined, /* @ts-ignore */
|
|
192
|
+
...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
193
|
+
width = input(undefined, /* @ts-ignore */
|
|
194
|
+
...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
195
|
+
mount = input(undefined, /* @ts-ignore */
|
|
196
|
+
...(ngDevMode ? [{ debugName: "mount" }] : /* istanbul ignore next */ []));
|
|
197
|
+
strategy = input(undefined, /* @ts-ignore */
|
|
198
|
+
...(ngDevMode ? [{ debugName: "strategy" }] : /* istanbul ignore next */ []));
|
|
199
|
+
/**
|
|
200
|
+
* Words laid over the catalog of the language in force, key by key: the clear
|
|
201
|
+
* button, the chips, the summary, the search field, and the sentences.
|
|
202
|
+
*/
|
|
203
|
+
messages = input(undefined, /* @ts-ignore */
|
|
204
|
+
...(ngDevMode ? [{ debugName: "messages" }] : /* istanbul ignore next */ []));
|
|
205
|
+
/** Whether an option answers the query. `null` turns filtering off. */
|
|
206
|
+
filter = input(undefined, /* @ts-ignore */
|
|
207
|
+
...(ngDevMode ? [{ debugName: "filter" }] : /* istanbul ignore next */ []));
|
|
208
|
+
/** BCP 47, for the comparison the default filter makes. */
|
|
209
|
+
/** BCP 47, for the comparison the default filter makes. The language in force when absent. */
|
|
210
|
+
locale = input(undefined, /* @ts-ignore */
|
|
211
|
+
...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
212
|
+
sideOffset = input(undefined, { ...(ngDevMode ? { debugName: "sideOffset" } : /* istanbul ignore next */ {}), transform: SlSelect.count });
|
|
213
|
+
alignOffset = input(undefined, { ...(ngDevMode ? { debugName: "alignOffset" } : /* istanbul ignore next */ {}), transform: SlSelect.count });
|
|
214
|
+
collisionPadding = input(undefined, { ...(ngDevMode ? { debugName: "collisionPadding" } : /* istanbul ignore next */ {}), transform: SlSelect.count });
|
|
215
|
+
typeaheadTimeout = input(undefined, { ...(ngDevMode ? { debugName: "typeaheadTimeout" } : /* istanbul ignore next */ {}), transform: SlSelect.count });
|
|
216
|
+
multiple = input(undefined, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
217
|
+
clearable = input(undefined, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
218
|
+
loop = input(undefined, { ...(ngDevMode ? { debugName: "loop" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
219
|
+
search = input(undefined, { ...(ngDevMode ? { debugName: "search" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
220
|
+
highlightMatch = input(undefined, { ...(ngDevMode ? { debugName: "highlightMatch" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
221
|
+
typeahead = input(undefined, { ...(ngDevMode ? { debugName: "typeahead" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
222
|
+
closeOnSelect = input(undefined, { ...(ngDevMode ? { debugName: "closeOnSelect" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
223
|
+
closeOnEscape = input(undefined, { ...(ngDevMode ? { debugName: "closeOnEscape" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
224
|
+
closeOnOutsidePress = input(undefined, { ...(ngDevMode ? { debugName: "closeOnOutsidePress" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
225
|
+
flip = input(undefined, { ...(ngDevMode ? { debugName: "flip" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
226
|
+
shift = input(undefined, { ...(ngDevMode ? { debugName: "shift" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
227
|
+
hideWhenDetached = input(undefined, { ...(ngDevMode ? { debugName: "hideWhenDetached" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
228
|
+
portal = input(undefined, { ...(ngDevMode ? { debugName: "portal" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
229
|
+
fullWidth = input(undefined, { ...(ngDevMode ? { debugName: "fullWidth" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
230
|
+
disabled = input(undefined, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
231
|
+
readOnly = input(undefined, { ...(ngDevMode ? { debugName: "readOnly" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
232
|
+
required = input(undefined, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
233
|
+
invalid = input(undefined, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: SlSelect.flag });
|
|
234
|
+
loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
235
|
+
defaults = injectSelectDefaults();
|
|
236
|
+
/** The family's words in the language in force, with this select's `messages` laid over them. */
|
|
237
|
+
t = injectMessages(selectMessages, this.messages);
|
|
238
|
+
inForceLocale = injectLocale();
|
|
239
|
+
/** The locale the default filter compares in: the `locale` input, or the language in force. */
|
|
240
|
+
resolvedLocale = computed(() => this.locale() ?? this.inForceLocale(), /* @ts-ignore */
|
|
241
|
+
...(ngDevMode ? [{ debugName: "resolvedLocale" }] : /* istanbul ignore next */ []));
|
|
242
|
+
viewContainer = inject(ViewContainerRef);
|
|
243
|
+
template = viewChild.required('layer', /* @ts-ignore */
|
|
244
|
+
...(ngDevMode ? [{ debugName: "template" }] : /* istanbul ignore next */ []));
|
|
245
|
+
triggerRef = viewChild.required('trigger', /* @ts-ignore */
|
|
246
|
+
...(ngDevMode ? [{ debugName: "triggerRef" }] : /* istanbul ignore next */ []));
|
|
247
|
+
/** The summary a consumer writes instead of the family's own. */
|
|
248
|
+
summaryTemplate = contentChild(SlSelectValue, { ...(ngDevMode ? { debugName: "summaryTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
|
|
249
|
+
/** The field around the control, whose state a bare input defers to. */
|
|
250
|
+
field = inject(SlField, { optional: true });
|
|
251
|
+
identifier = Math.random().toString(36).slice(2, 8);
|
|
252
|
+
contentId = `sl-select-${this.identifier}`;
|
|
253
|
+
/**
|
|
254
|
+
* The listbox's own identifier. Without a search field the surface is the
|
|
255
|
+
* listbox and `contentId` names it; with one the surface is a dialog and the
|
|
256
|
+
* listbox is one element in, so the two need separate names.
|
|
257
|
+
*/
|
|
258
|
+
listId = `sl-select-list-${this.identifier}`;
|
|
259
|
+
searchId = `sl-select-search-${this.identifier}`;
|
|
260
|
+
/** The field's control identifier inside a field, so its label's `for` reaches the trigger. */
|
|
261
|
+
triggerId = this.field?.ids().control ?? `sl-select-trigger-${this.identifier}`;
|
|
262
|
+
registry = signal(new Map(), /* @ts-ignore */
|
|
263
|
+
...(ngDevMode ? [{ debugName: "registry" }] : /* istanbul ignore next */ []));
|
|
264
|
+
optionCount = signal(0, /* @ts-ignore */
|
|
265
|
+
...(ngDevMode ? [{ debugName: "optionCount" }] : /* istanbul ignore next */ []));
|
|
266
|
+
entry = 'selected';
|
|
267
|
+
pending = null;
|
|
268
|
+
lastQuery = '';
|
|
269
|
+
disabledByForm = signal(undefined, /* @ts-ignore */
|
|
270
|
+
...(ngDevMode ? [{ debugName: "disabledByForm" }] : /* istanbul ignore next */ []));
|
|
271
|
+
view = null;
|
|
272
|
+
layerNode = null;
|
|
273
|
+
surfaceNode = null;
|
|
274
|
+
portalRoot = null;
|
|
275
|
+
positioner = null;
|
|
276
|
+
layer = null;
|
|
277
|
+
presence = null;
|
|
278
|
+
typeaheadHandle = null;
|
|
279
|
+
hostLabelledBy = inject(new HostAttributeToken('aria-labelledby'), {
|
|
280
|
+
optional: true,
|
|
281
|
+
});
|
|
282
|
+
onChange = () => undefined;
|
|
283
|
+
onTouched = () => undefined;
|
|
284
|
+
resolvedSize = computed(() => this.size() ?? this.field?.size() ?? this.defaults.size, /* @ts-ignore */
|
|
285
|
+
...(ngDevMode ? [{ debugName: "resolvedSize" }] : /* istanbul ignore next */ []));
|
|
286
|
+
resolvedVariant = computed(() => this.variant() ?? this.defaults.variant, /* @ts-ignore */
|
|
287
|
+
...(ngDevMode ? [{ debugName: "resolvedVariant" }] : /* istanbul ignore next */ []));
|
|
288
|
+
resolvedAlign = computed(() => this.align() ?? this.defaults.align, /* @ts-ignore */
|
|
289
|
+
...(ngDevMode ? [{ debugName: "resolvedAlign" }] : /* istanbul ignore next */ []));
|
|
290
|
+
resolvedSide = computed(() => this.side() ?? this.defaults.side, /* @ts-ignore */
|
|
291
|
+
...(ngDevMode ? [{ debugName: "resolvedSide" }] : /* istanbul ignore next */ []));
|
|
292
|
+
resolvedWidth = computed(() => this.width() ?? this.defaults.width, /* @ts-ignore */
|
|
293
|
+
...(ngDevMode ? [{ debugName: "resolvedWidth" }] : /* istanbul ignore next */ []));
|
|
294
|
+
resolvedMount = computed(() => this.mount() ?? this.defaults.mount, /* @ts-ignore */
|
|
295
|
+
...(ngDevMode ? [{ debugName: "resolvedMount" }] : /* istanbul ignore next */ []));
|
|
296
|
+
resolvedMultiple = computed(() => this.multiple() ?? this.defaults.multiple, /* @ts-ignore */
|
|
297
|
+
...(ngDevMode ? [{ debugName: "resolvedMultiple" }] : /* istanbul ignore next */ []));
|
|
298
|
+
resolvedClearable = computed(() => this.clearable() ?? this.defaults.clearable, /* @ts-ignore */
|
|
299
|
+
...(ngDevMode ? [{ debugName: "resolvedClearable" }] : /* istanbul ignore next */ []));
|
|
300
|
+
resolvedLoop = computed(() => this.loop() ?? this.defaults.loop, /* @ts-ignore */
|
|
301
|
+
...(ngDevMode ? [{ debugName: "resolvedLoop" }] : /* istanbul ignore next */ []));
|
|
302
|
+
resolvedSearch = computed(() => this.search() ?? this.defaults.search, /* @ts-ignore */
|
|
303
|
+
...(ngDevMode ? [{ debugName: "resolvedSearch" }] : /* istanbul ignore next */ []));
|
|
304
|
+
resolvedHighlightMatch = computed(() => this.highlightMatch() ?? this.defaults.highlightMatch, /* @ts-ignore */
|
|
305
|
+
...(ngDevMode ? [{ debugName: "resolvedHighlightMatch" }] : /* istanbul ignore next */ []));
|
|
306
|
+
/* A reader typing into a field cannot also be driving a typeahead on the
|
|
307
|
+
same keys: two searches on one keystroke move the highlight twice. */
|
|
308
|
+
resolvedTypeahead = computed(() => this.resolvedSearch() ? false : (this.typeahead() ?? this.defaults.typeahead), /* @ts-ignore */
|
|
309
|
+
...(ngDevMode ? [{ debugName: "resolvedTypeahead" }] : /* istanbul ignore next */ []));
|
|
310
|
+
resolvedCloseOnSelect = computed(() => this.closeOnSelect() ?? this.defaults.closeOnSelect, /* @ts-ignore */
|
|
311
|
+
...(ngDevMode ? [{ debugName: "resolvedCloseOnSelect" }] : /* istanbul ignore next */ []));
|
|
312
|
+
resolvedFullWidth = computed(() => this.fullWidth() ?? this.defaults.fullWidth, /* @ts-ignore */
|
|
313
|
+
...(ngDevMode ? [{ debugName: "resolvedFullWidth" }] : /* istanbul ignore next */ []));
|
|
314
|
+
/** The query, which only exists while there is a field holding it. */
|
|
315
|
+
query = computed(() => (this.resolvedSearch() ? this.searchValue() : ''), /* @ts-ignore */
|
|
316
|
+
...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
|
|
317
|
+
fallbackFilter = computed(() => createFilter({ locale: this.resolvedLocale() }), /* @ts-ignore */
|
|
318
|
+
...(ngDevMode ? [{ debugName: "fallbackFilter" }] : /* istanbul ignore next */ []));
|
|
319
|
+
/**
|
|
320
|
+
* Three answers, and `undefined` is not one of them. Not giving `filter` asks
|
|
321
|
+
* for the library's own locale-sensitive `contains`; giving `null` turns
|
|
322
|
+
* filtering off, which is what a list a server has already filtered needs;
|
|
323
|
+
* giving a function replaces the comparison.
|
|
324
|
+
*/
|
|
325
|
+
matches(label) {
|
|
326
|
+
const query = this.query();
|
|
327
|
+
const given = this.filter();
|
|
328
|
+
if (query === '' || given === null)
|
|
329
|
+
return true;
|
|
330
|
+
if (given !== undefined)
|
|
331
|
+
return given(label, query);
|
|
332
|
+
return this.fallbackFilter().contains(label, query);
|
|
333
|
+
}
|
|
334
|
+
/** What the live region carries: the wait, or how many options survived. */
|
|
335
|
+
statusMessage = computed(() => {
|
|
336
|
+
if (this.loading())
|
|
337
|
+
return this.t('loading');
|
|
338
|
+
if (!this.resolvedSearch() || this.optionCount() === 0)
|
|
339
|
+
return '';
|
|
340
|
+
return this.t('count', { count: this.optionCount() });
|
|
341
|
+
}, /* @ts-ignore */
|
|
342
|
+
...(ngDevMode ? [{ debugName: "statusMessage" }] : /* istanbul ignore next */ []));
|
|
343
|
+
/** Unset asks the field; a field that says nothing leaves the default. */
|
|
344
|
+
resolvedDisabled = computed(() => this.disabled() ?? this.disabledByForm() ?? this.field?.disabled() ?? this.defaults.disabled, /* @ts-ignore */
|
|
345
|
+
...(ngDevMode ? [{ debugName: "resolvedDisabled" }] : /* istanbul ignore next */ []));
|
|
346
|
+
resolvedReadOnly = computed(() => this.readOnly() ?? this.field?.readOnly() ?? this.defaults.readOnly, /* @ts-ignore */
|
|
347
|
+
...(ngDevMode ? [{ debugName: "resolvedReadOnly" }] : /* istanbul ignore next */ []));
|
|
348
|
+
resolvedRequired = computed(() => this.required() ?? this.field?.required() ?? this.defaults.required, /* @ts-ignore */
|
|
349
|
+
...(ngDevMode ? [{ debugName: "resolvedRequired" }] : /* istanbul ignore next */ []));
|
|
350
|
+
resolvedInvalid = computed(() => this.invalid() ?? this.field?.invalid() ?? this.defaults.invalid, /* @ts-ignore */
|
|
351
|
+
...(ngDevMode ? [{ debugName: "resolvedInvalid" }] : /* istanbul ignore next */ []));
|
|
352
|
+
isOpen = computed(() => this.open() && !this.resolvedDisabled(), /* @ts-ignore */
|
|
353
|
+
...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
354
|
+
/** One value, several, or none — always read as a list, whatever was given. */
|
|
355
|
+
selection = computed(() => {
|
|
356
|
+
const held = this.value();
|
|
357
|
+
if (held === null || held === undefined)
|
|
358
|
+
return [];
|
|
359
|
+
return typeof held === 'string' ? [held] : held;
|
|
360
|
+
}, /* @ts-ignore */
|
|
361
|
+
...(ngDevMode ? [{ debugName: "selection" }] : /* istanbul ignore next */ []));
|
|
362
|
+
declared = computed(() => {
|
|
363
|
+
const table = new Map();
|
|
364
|
+
for (const option of flatten(this.items()))
|
|
365
|
+
table.set(option.value, option.label);
|
|
366
|
+
return table;
|
|
367
|
+
}, /* @ts-ignore */
|
|
368
|
+
...(ngDevMode ? [{ debugName: "declared" }] : /* istanbul ignore next */ []));
|
|
369
|
+
labels = computed(() => this.selection().map((held) => this.labelFor(held) ?? held), /* @ts-ignore */
|
|
370
|
+
...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
|
|
371
|
+
unmatched = computed(() => this.selection().some((held) => this.labelFor(held) === undefined), /* @ts-ignore */
|
|
372
|
+
...(ngDevMode ? [{ debugName: "unmatched" }] : /* istanbul ignore next */ []));
|
|
373
|
+
/** The first label, then how many more. A count alone names none of them. */
|
|
374
|
+
summary = computed(() => {
|
|
375
|
+
const held = this.selection();
|
|
376
|
+
if (held.length === 0)
|
|
377
|
+
return this.placeholder();
|
|
378
|
+
const first = this.labelFor(held[0]) ?? held[0];
|
|
379
|
+
if (!this.resolvedMultiple() || held.length === 1)
|
|
380
|
+
return first;
|
|
381
|
+
/* Several values are the chips beside this element, not a sentence here
|
|
382
|
+
(SL4). The sentence stays: it names the trigger, and it is what a control
|
|
383
|
+
too narrow for a chip shows instead. */
|
|
384
|
+
return this.t('summary', { count: held.length });
|
|
385
|
+
}, /* @ts-ignore */
|
|
386
|
+
...(ngDevMode ? [{ debugName: "summary" }] : /* istanbul ignore next */ []));
|
|
387
|
+
showClear = computed(() => this.resolvedClearable() &&
|
|
388
|
+
this.selection().length > 0 &&
|
|
389
|
+
!this.resolvedDisabled() &&
|
|
390
|
+
!this.resolvedReadOnly(), /* @ts-ignore */
|
|
391
|
+
...(ngDevMode ? [{ debugName: "showClear" }] : /* istanbul ignore next */ []));
|
|
392
|
+
empty = computed(() => this.optionCount() === 0, /* @ts-ignore */
|
|
393
|
+
...(ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []));
|
|
394
|
+
activeDescendant = computed(() => {
|
|
395
|
+
const held = this.highlightedValue();
|
|
396
|
+
return this.isOpen() && held !== null ? this.optionId(held) : null;
|
|
397
|
+
}, /* @ts-ignore */
|
|
398
|
+
...(ngDevMode ? [{ debugName: "activeDescendant" }] : /* istanbul ignore next */ []));
|
|
399
|
+
/**
|
|
400
|
+
* The trigger names the highlighted option only while it is the focused
|
|
401
|
+
* element. With a search field the field holds focus and names it instead;
|
|
402
|
+
* two elements naming one option would put the announcement on the element
|
|
403
|
+
* nobody is operating.
|
|
404
|
+
*/
|
|
405
|
+
triggerActiveDescendant = computed(() => this.resolvedSearch() ? null : this.activeDescendant(), /* @ts-ignore */
|
|
406
|
+
...(ngDevMode ? [{ debugName: "triggerActiveDescendant" }] : /* istanbul ignore next */ []));
|
|
407
|
+
labelledBy = computed(() => {
|
|
408
|
+
if (this.ariaLabel() !== undefined)
|
|
409
|
+
return null;
|
|
410
|
+
return this.hostLabelledBy ?? this.field?.ids().label ?? null;
|
|
411
|
+
}, /* @ts-ignore */
|
|
412
|
+
...(ngDevMode ? [{ debugName: "labelledBy" }] : /* istanbul ignore next */ []));
|
|
413
|
+
describedBy = computed(() => this.field?.describedBy() ?? null, /* @ts-ignore */
|
|
414
|
+
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
415
|
+
/**
|
|
416
|
+
* The chip row, and the two measurements it needs (SL4).
|
|
417
|
+
*
|
|
418
|
+
* `createCollapse` is the same ResizeObserver arithmetic `toolbar` collapses
|
|
419
|
+
* a bar with: it hides the chips that overrun and reveals the `+N` chip from
|
|
420
|
+
* the first one that does, so the count is what the collapse reports and
|
|
421
|
+
* cannot disagree with what is on screen. `createWidthGate` answers the other
|
|
422
|
+
* question — whether the frame has room for a chip at all — because under a
|
|
423
|
+
* hundred and twenty pixels a chip is a shape with no word in it.
|
|
424
|
+
*/
|
|
425
|
+
tags = viewChild('tags', /* @ts-ignore */
|
|
426
|
+
...(ngDevMode ? [{ debugName: "tags" }] : /* istanbul ignore next */ []));
|
|
427
|
+
chipOverflow = viewChild('chipOverflow', /* @ts-ignore */
|
|
428
|
+
...(ngDevMode ? [{ debugName: "chipOverflow" }] : /* istanbul ignore next */ []));
|
|
429
|
+
collapsedCount = signal(0, /* @ts-ignore */
|
|
430
|
+
...(ngDevMode ? [{ debugName: "collapsedCount" }] : /* istanbul ignore next */ []));
|
|
431
|
+
narrow = signal(false, /* @ts-ignore */
|
|
432
|
+
...(ngDevMode ? [{ debugName: "narrow" }] : /* istanbul ignore next */ []));
|
|
433
|
+
collapse = null;
|
|
434
|
+
widthGate = null;
|
|
435
|
+
removeLabelFor(value) {
|
|
436
|
+
return this.t('remove', { label: String(this.labelFor(value) ?? value) });
|
|
437
|
+
}
|
|
438
|
+
onRemoveChip(value, event) {
|
|
439
|
+
event.preventDefault();
|
|
440
|
+
event.stopPropagation();
|
|
441
|
+
this.toggle(value, 'select', event);
|
|
442
|
+
/* A control that removes itself as it is pressed would leave focus on the
|
|
443
|
+
document; the reader lands back on the control they were on. */
|
|
444
|
+
this.triggerRef().nativeElement.focus({ preventScroll: true });
|
|
445
|
+
}
|
|
446
|
+
constructor() {
|
|
447
|
+
const destroyRef = inject(DestroyRef);
|
|
448
|
+
const host = inject((ElementRef));
|
|
449
|
+
effect(() => {
|
|
450
|
+
const row = this.tags()?.nativeElement ?? null;
|
|
451
|
+
const trigger = this.chipOverflow()?.nativeElement ?? null;
|
|
452
|
+
untracked(() => {
|
|
453
|
+
this.collapse?.destroy();
|
|
454
|
+
this.collapse = null;
|
|
455
|
+
this.widthGate?.destroy();
|
|
456
|
+
this.widthGate = null;
|
|
457
|
+
this.narrow.set(false);
|
|
458
|
+
if (row === null) {
|
|
459
|
+
this.collapsedCount.set(0);
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
/* The swap is the chips' alone (contract `chips.narrowWidth`): a
|
|
463
|
+
control drawing none has nothing to give way. */
|
|
464
|
+
this.widthGate = createWidthGate(host.nativeElement, {
|
|
465
|
+
at: NARROW_WIDTH,
|
|
466
|
+
onChange: (narrow) => this.narrow.set(narrow),
|
|
467
|
+
});
|
|
468
|
+
this.collapse = createCollapse(row, {
|
|
469
|
+
collapsible: () => true,
|
|
470
|
+
onChange: (units) => this.collapsedCount.set(units.length),
|
|
471
|
+
trigger: () => trigger,
|
|
472
|
+
units: () => [...row.querySelectorAll(':scope > *:not([data-overflow])')],
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
/* A value arriving or leaving changes what there is to fit. */
|
|
477
|
+
effect(() => {
|
|
478
|
+
this.selection();
|
|
479
|
+
untracked(() => this.collapse?.refresh());
|
|
480
|
+
});
|
|
481
|
+
effect(() => {
|
|
482
|
+
const open = this.isOpen();
|
|
483
|
+
untracked(() => (open ? this.show() : this.hide()));
|
|
484
|
+
});
|
|
485
|
+
/**
|
|
486
|
+
* The highlight follows the query. A reader who types four characters and
|
|
487
|
+
* presses `Enter` means the first row they can see, and a highlight left on
|
|
488
|
+
* a row the filter has just removed answers with nothing at all. It is read
|
|
489
|
+
* after render because the options decide their own visibility, so the
|
|
490
|
+
* surviving set does not exist until the view has answered.
|
|
491
|
+
*/
|
|
492
|
+
afterRenderEffect(() => {
|
|
493
|
+
const query = this.query();
|
|
494
|
+
untracked(() => {
|
|
495
|
+
if (!this.isOpen() || !this.resolvedSearch())
|
|
496
|
+
return;
|
|
497
|
+
if (this.lastQuery === query)
|
|
498
|
+
return;
|
|
499
|
+
this.lastQuery = query;
|
|
500
|
+
this.recount();
|
|
501
|
+
this.move('first', new Event('input'));
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
afterNextRender(() => {
|
|
505
|
+
if (this.resolvedMount() === 'eager' && !this.isOpen())
|
|
506
|
+
this.build();
|
|
507
|
+
});
|
|
508
|
+
destroyRef.onDestroy(() => {
|
|
509
|
+
this.collapse?.destroy();
|
|
510
|
+
this.widthGate?.destroy();
|
|
511
|
+
this.teardown();
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
/** The element `aria-activedescendant` names, and the option carries. */
|
|
515
|
+
optionId(value) {
|
|
516
|
+
return `${this.contentId}-option-${encodeURIComponent(value)}`;
|
|
517
|
+
}
|
|
518
|
+
labelFor(value) {
|
|
519
|
+
return this.declared().get(value) ?? this.registry().get(value);
|
|
520
|
+
}
|
|
521
|
+
/** An option hands over what it reads as, so the closed control can print it. */
|
|
522
|
+
registerLabel(value, label) {
|
|
523
|
+
if (this.registry().get(value) === label)
|
|
524
|
+
return;
|
|
525
|
+
const next = new Map(this.registry());
|
|
526
|
+
next.set(value, label);
|
|
527
|
+
this.registry.set(next);
|
|
528
|
+
}
|
|
529
|
+
/** Options count themselves, so the popup knows whether it holds any. */
|
|
530
|
+
recount() {
|
|
531
|
+
this.optionCount.set(this.options().length);
|
|
532
|
+
}
|
|
533
|
+
options() {
|
|
534
|
+
return [...(this.surfaceNode?.querySelectorAll(OPTION_SELECTOR) ?? [])];
|
|
535
|
+
}
|
|
536
|
+
focus() {
|
|
537
|
+
this.triggerRef().nativeElement.focus({ preventScroll: true });
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Whether a click landed on the control's frame. A click a `label` elsewhere
|
|
541
|
+
* forwards to the button carries the label's coordinates, which lie outside it.
|
|
542
|
+
*/
|
|
543
|
+
pressedOnFrame(x, y) {
|
|
544
|
+
const button = this.triggerRef().nativeElement;
|
|
545
|
+
const box = (button.parentElement ?? button).getBoundingClientRect();
|
|
546
|
+
return x >= box.left && x <= box.right && y >= box.top && y <= box.bottom;
|
|
547
|
+
}
|
|
548
|
+
scrollToKey(value) {
|
|
549
|
+
const option = this.options().find((candidate) => candidate.dataset['value'] === value);
|
|
550
|
+
if (option !== undefined && this.surfaceNode !== null)
|
|
551
|
+
revealWithin(option, this.surfaceNode);
|
|
552
|
+
}
|
|
553
|
+
/** Asks to open or close, and reports the reason before anything moves. */
|
|
554
|
+
setOpen(next, reason, source) {
|
|
555
|
+
if (next === this.isOpen())
|
|
556
|
+
return;
|
|
557
|
+
const state = createControllable({
|
|
558
|
+
initial: this.isOpen(),
|
|
559
|
+
onRequest: (request) => this.openChangeRequest.emit(request),
|
|
560
|
+
});
|
|
561
|
+
if (!state.request(next, reason, source))
|
|
562
|
+
return;
|
|
563
|
+
this.open.set(next);
|
|
564
|
+
if (!next) {
|
|
565
|
+
this.highlightedValue.set(null);
|
|
566
|
+
this.entry = 'selected';
|
|
567
|
+
/* A popup that closes takes the query with it: the field is built with
|
|
568
|
+
the popup, and a select that reopened onto four characters nobody had
|
|
569
|
+
typed this time would filter a list the reader thought was whole. */
|
|
570
|
+
this.setQuery('', 'clear', source);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* The query. The reset the popup performs as it opens and as it closes
|
|
575
|
+
* carries `clear`, which is what happened to the field.
|
|
576
|
+
*/
|
|
577
|
+
setQuery(next, reason, source) {
|
|
578
|
+
if (next === this.query())
|
|
579
|
+
return;
|
|
580
|
+
const state = createControllable({
|
|
581
|
+
initial: this.query(),
|
|
582
|
+
onRequest: (request) => this.searchValueChangeRequest.emit(request),
|
|
583
|
+
});
|
|
584
|
+
if (state.request(next, reason, source))
|
|
585
|
+
this.searchValue.set(next);
|
|
586
|
+
}
|
|
587
|
+
/** The field inside the popup, which lives in an embedded view. */
|
|
588
|
+
searchNode() {
|
|
589
|
+
return this.layerNode?.querySelector("[data-part='search-input']") ?? null;
|
|
590
|
+
}
|
|
591
|
+
/** Focuses the field when there is one, and the control otherwise. */
|
|
592
|
+
focusSearch() {
|
|
593
|
+
(this.searchNode() ?? this.triggerRef().nativeElement).focus({ preventScroll: true });
|
|
594
|
+
}
|
|
595
|
+
setHighlighted(next, reason, source) {
|
|
596
|
+
if (next === this.highlightedValue())
|
|
597
|
+
return;
|
|
598
|
+
const state = createControllable({
|
|
599
|
+
initial: this.highlightedValue(),
|
|
600
|
+
onRequest: (request) => this.highlightedValueChangeRequest.emit(request),
|
|
601
|
+
});
|
|
602
|
+
if (state.request(next, reason, source)) {
|
|
603
|
+
this.highlightedValue.set(next);
|
|
604
|
+
this.reveal(next);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
/** Takes an option, or takes it back when the select holds several. */
|
|
608
|
+
toggle(value, reason, source) {
|
|
609
|
+
if (!this.resolvedMultiple()) {
|
|
610
|
+
this.commit([value], reason, source);
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
const held = this.selection();
|
|
614
|
+
this.commit(held.includes(value) ? held.filter((candidate) => candidate !== value) : [...held, value], reason, source);
|
|
615
|
+
}
|
|
616
|
+
clear(reason, source) {
|
|
617
|
+
this.commit([], reason, source);
|
|
618
|
+
}
|
|
619
|
+
commit(next, reason, source) {
|
|
620
|
+
const held = this.selection();
|
|
621
|
+
const same = next.length === held.length && next.every((value, index) => value === held[index]);
|
|
622
|
+
if (same)
|
|
623
|
+
return;
|
|
624
|
+
const shaped = this.resolvedMultiple() ? next : (next[0] ?? null);
|
|
625
|
+
const state = createControllable({
|
|
626
|
+
initial: this.resolvedMultiple() ? held : (held[0] ?? null),
|
|
627
|
+
/* Membership was compared above; comparing the shaped values here would
|
|
628
|
+
compare two fresh arrays by identity and call every request a change. */
|
|
629
|
+
equals: () => false,
|
|
630
|
+
onRequest: (request) => this.valueChangeRequest.emit(request),
|
|
631
|
+
});
|
|
632
|
+
if (!state.request(shaped, reason, source))
|
|
633
|
+
return;
|
|
634
|
+
this.value.set(shaped);
|
|
635
|
+
this.onChange(shaped);
|
|
636
|
+
this.onTouched();
|
|
637
|
+
}
|
|
638
|
+
onTriggerClick(event) {
|
|
639
|
+
/* A press on the field's label arrives here as the click the label
|
|
640
|
+
forwards: a pointer click at the label's coordinates, outside the frame.
|
|
641
|
+
It focuses the control and does not open the list — the select-only
|
|
642
|
+
example's label only focuses, and so does a native select's. A keyboard
|
|
643
|
+
or assistive-technology click carries detail 0 and opens. */
|
|
644
|
+
if (event.detail > 0 && !this.pressedOnFrame(event.clientX, event.clientY)) {
|
|
645
|
+
this.focus();
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
if (this.resolvedDisabled() || this.resolvedReadOnly())
|
|
649
|
+
return;
|
|
650
|
+
this.entry = 'selected';
|
|
651
|
+
this.setOpen(!this.isOpen(), 'pointer', event);
|
|
652
|
+
}
|
|
653
|
+
onClear(event) {
|
|
654
|
+
this.clear('clear', event);
|
|
655
|
+
this.focus();
|
|
656
|
+
}
|
|
657
|
+
onBlur() {
|
|
658
|
+
this.onTouched();
|
|
659
|
+
}
|
|
660
|
+
onKeyDown(event) {
|
|
661
|
+
if (this.resolvedDisabled() || this.resolvedReadOnly())
|
|
662
|
+
return;
|
|
663
|
+
const alt = event.altKey;
|
|
664
|
+
if (!this.isOpen()) {
|
|
665
|
+
switch (event.key) {
|
|
666
|
+
case 'ArrowDown':
|
|
667
|
+
event.preventDefault();
|
|
668
|
+
return this.openWith(alt ? 'none' : 'selected', event);
|
|
669
|
+
case 'ArrowUp':
|
|
670
|
+
/* The example opens onto the first option; the last is the mirror of
|
|
671
|
+
ArrowDown, and the contract records the departure. */
|
|
672
|
+
event.preventDefault();
|
|
673
|
+
return this.openWith('last', event);
|
|
674
|
+
case 'Enter':
|
|
675
|
+
case ' ':
|
|
676
|
+
event.preventDefault();
|
|
677
|
+
return this.openWith('selected', event);
|
|
678
|
+
case 'Home':
|
|
679
|
+
event.preventDefault();
|
|
680
|
+
return this.openWith('first', event);
|
|
681
|
+
case 'End':
|
|
682
|
+
event.preventDefault();
|
|
683
|
+
return this.openWith('last', event);
|
|
684
|
+
default:
|
|
685
|
+
break;
|
|
686
|
+
}
|
|
687
|
+
if (!event.ctrlKey && !event.metaKey && !alt && isPrintable(event.key)) {
|
|
688
|
+
/* With a field the character opens the popup and becomes the first
|
|
689
|
+
character of the query; without one it seeds the typeahead. The
|
|
690
|
+
pattern asks the same of both, and only the search it feeds differs. */
|
|
691
|
+
if (this.resolvedSearch()) {
|
|
692
|
+
event.preventDefault();
|
|
693
|
+
this.setQuery(event.key, 'keyboard', event);
|
|
694
|
+
return this.openWith('first', event);
|
|
695
|
+
}
|
|
696
|
+
if (this.resolvedTypeahead()) {
|
|
697
|
+
event.preventDefault();
|
|
698
|
+
this.pending = event.key;
|
|
699
|
+
this.openWith('none', event);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
switch (event.key) {
|
|
705
|
+
case 'ArrowDown':
|
|
706
|
+
event.preventDefault();
|
|
707
|
+
return this.move('next', event);
|
|
708
|
+
case 'ArrowUp':
|
|
709
|
+
event.preventDefault();
|
|
710
|
+
return alt ? this.commitHighlighted(event, true) : this.move('previous', event);
|
|
711
|
+
case 'Home':
|
|
712
|
+
event.preventDefault();
|
|
713
|
+
return this.move('first', event);
|
|
714
|
+
case 'End':
|
|
715
|
+
event.preventDefault();
|
|
716
|
+
return this.move('last', event);
|
|
717
|
+
case 'PageDown':
|
|
718
|
+
event.preventDefault();
|
|
719
|
+
return this.move('pageDown', event);
|
|
720
|
+
case 'PageUp':
|
|
721
|
+
event.preventDefault();
|
|
722
|
+
return this.move('pageUp', event);
|
|
723
|
+
case 'Enter':
|
|
724
|
+
event.preventDefault();
|
|
725
|
+
return this.commitHighlighted(event, this.resolvedCloseOnSelect());
|
|
726
|
+
case ' ':
|
|
727
|
+
event.preventDefault();
|
|
728
|
+
/* Multiple selection keeps the popup open on Space, which is the
|
|
729
|
+
listbox pattern's recommended model. */
|
|
730
|
+
return this.commitHighlighted(event, this.resolvedMultiple() ? false : this.resolvedCloseOnSelect());
|
|
731
|
+
case 'Escape':
|
|
732
|
+
event.preventDefault();
|
|
733
|
+
return this.setOpen(false, 'escape', event);
|
|
734
|
+
case 'Tab':
|
|
735
|
+
/* Not prevented: the key commits and then does what Tab does, which the
|
|
736
|
+
example states and notes differs from a native select. */
|
|
737
|
+
return this.commitHighlighted(event, true);
|
|
738
|
+
default:
|
|
739
|
+
break;
|
|
740
|
+
}
|
|
741
|
+
const handle = this.typeaheadHandle;
|
|
742
|
+
if (handle === null)
|
|
743
|
+
return;
|
|
744
|
+
if (event.ctrlKey || event.metaKey || alt)
|
|
745
|
+
return;
|
|
746
|
+
if (!isPrintable(event.key, handle.query.length > 0))
|
|
747
|
+
return;
|
|
748
|
+
event.preventDefault();
|
|
749
|
+
this.typeaheadMatch(event.key, handle);
|
|
750
|
+
}
|
|
751
|
+
onSearchInput(event) {
|
|
752
|
+
const field = event.target;
|
|
753
|
+
this.setQuery(field.value, 'keyboard', event);
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* The keys the field takes, and the three the closed control spends that this
|
|
757
|
+
* one cannot: `Home`, `End` and the space bar all belong to the caret while
|
|
758
|
+
* the reader is typing, and the pattern's editable branch returns them there.
|
|
759
|
+
*/
|
|
760
|
+
onSearchKeyDown(event) {
|
|
761
|
+
const alt = event.altKey;
|
|
762
|
+
switch (event.key) {
|
|
763
|
+
case 'ArrowDown':
|
|
764
|
+
event.preventDefault();
|
|
765
|
+
return this.move('next', event);
|
|
766
|
+
case 'ArrowUp':
|
|
767
|
+
event.preventDefault();
|
|
768
|
+
return alt ? this.commitHighlighted(event, true) : this.move('previous', event);
|
|
769
|
+
case 'PageDown':
|
|
770
|
+
event.preventDefault();
|
|
771
|
+
return this.move('pageDown', event);
|
|
772
|
+
case 'PageUp':
|
|
773
|
+
event.preventDefault();
|
|
774
|
+
return this.move('pageUp', event);
|
|
775
|
+
case 'Enter':
|
|
776
|
+
event.preventDefault();
|
|
777
|
+
return this.commitHighlighted(event, this.resolvedMultiple() ? false : this.resolvedCloseOnSelect());
|
|
778
|
+
case 'Escape':
|
|
779
|
+
event.preventDefault();
|
|
780
|
+
/* The layer saw this key first, in the capture phase, and its dismiss
|
|
781
|
+
handler holds the two steps. This branch is what answers when the
|
|
782
|
+
layer was told to ignore Escape entirely: the query still empties,
|
|
783
|
+
and the popup a consumer said to keep open stays open. */
|
|
784
|
+
if (this.query() !== '')
|
|
785
|
+
this.setQuery('', 'clear', event);
|
|
786
|
+
return;
|
|
787
|
+
case 'Tab': {
|
|
788
|
+
event.preventDefault();
|
|
789
|
+
const layer = this.layerNode;
|
|
790
|
+
this.commitHighlighted(event, true);
|
|
791
|
+
return this.moveTabFrom(layer, event.shiftKey);
|
|
792
|
+
}
|
|
793
|
+
default:
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Where `Tab` goes from inside the popup. The layer is portalled to the end
|
|
799
|
+
* of the document, so the browser's own next element is the end of the page
|
|
800
|
+
* rather than the element after the control: the document's tab order is read
|
|
801
|
+
* with the layer taken out of it, the trigger is found in what remains, and
|
|
802
|
+
* focus goes to the entry beside it.
|
|
803
|
+
*/
|
|
804
|
+
moveTabFrom(layer, backwards) {
|
|
805
|
+
const trigger = this.triggerRef().nativeElement;
|
|
806
|
+
const order = tabbables(document.body).filter((node) => layer === null || !layer.contains(node));
|
|
807
|
+
const index = order.indexOf(trigger);
|
|
808
|
+
const next = index === -1 ? undefined : order[index + (backwards ? -1 : 1)];
|
|
809
|
+
(next ?? trigger).focus({ preventScroll: true });
|
|
810
|
+
}
|
|
811
|
+
openWith(entry, event) {
|
|
812
|
+
this.entry = entry;
|
|
813
|
+
this.setOpen(true, 'keyboard', event);
|
|
814
|
+
}
|
|
815
|
+
move(intent, event) {
|
|
816
|
+
const list = this.options();
|
|
817
|
+
if (list.length === 0)
|
|
818
|
+
return;
|
|
819
|
+
const held = this.highlightedValue();
|
|
820
|
+
const index = moveIndex({
|
|
821
|
+
enabled: list.map((option) => option.dataset['disabled'] === undefined),
|
|
822
|
+
from: held === null ? -1 : list.findIndex((option) => option.dataset['value'] === held),
|
|
823
|
+
intent,
|
|
824
|
+
loop: this.resolvedLoop(),
|
|
825
|
+
});
|
|
826
|
+
if (index !== -1)
|
|
827
|
+
this.setHighlighted(list[index]?.dataset['value'] ?? null, 'keyboard', event);
|
|
828
|
+
}
|
|
829
|
+
commitHighlighted(event, close) {
|
|
830
|
+
const held = this.highlightedValue();
|
|
831
|
+
if (held !== null)
|
|
832
|
+
this.toggle(held, 'keyboard', event);
|
|
833
|
+
if (close) {
|
|
834
|
+
this.setOpen(false, 'select', event);
|
|
835
|
+
/* The trigger takes focus back wherever the popup is closed by a key.
|
|
836
|
+
It does not on an outside press: the reader has just put focus
|
|
837
|
+
somewhere themselves. Without a field focus never left, and the call
|
|
838
|
+
costs nothing. */
|
|
839
|
+
const leaving = event instanceof KeyboardEvent && event.key === 'Tab';
|
|
840
|
+
if (!leaving)
|
|
841
|
+
this.focus();
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
/* The popup stayed open, so the query is emptied here rather than by the
|
|
845
|
+
close: a list still filtered to the row the reader has just taken is a
|
|
846
|
+
list that looks broken. */
|
|
847
|
+
if (held !== null)
|
|
848
|
+
this.setQuery('', 'select', event);
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Typeahead searches the **enabled** options and only those. The arrows step
|
|
852
|
+
* over a disabled option, so a typeahead that landed on one would let a
|
|
853
|
+
* reader reach by typing a row the family then refuses to commit.
|
|
854
|
+
*/
|
|
855
|
+
typeaheadMatch(character, handle) {
|
|
856
|
+
const list = this.options().filter((option) => option.dataset['disabled'] === undefined);
|
|
857
|
+
const labels = list.map((option) => option.dataset['textValue'] ??
|
|
858
|
+
option.querySelector("[data-part='label']")?.textContent?.trim() ??
|
|
859
|
+
'');
|
|
860
|
+
const held = this.highlightedValue();
|
|
861
|
+
const from = held === null ? -1 : list.findIndex((option) => option.dataset['value'] === held);
|
|
862
|
+
const index = handle.match(character, labels, from);
|
|
863
|
+
if (index !== -1)
|
|
864
|
+
this.setHighlighted(list[index]?.dataset['value'] ?? null, 'keyboard');
|
|
865
|
+
}
|
|
866
|
+
reveal(value) {
|
|
867
|
+
if (value === null)
|
|
868
|
+
return;
|
|
869
|
+
this.scrollToKey(value);
|
|
870
|
+
}
|
|
871
|
+
show() {
|
|
872
|
+
this.build();
|
|
873
|
+
this.position();
|
|
874
|
+
this.bind();
|
|
875
|
+
this.enter();
|
|
876
|
+
}
|
|
877
|
+
build() {
|
|
878
|
+
if (this.view !== null) {
|
|
879
|
+
this.presence?.sync(this.isOpen());
|
|
880
|
+
this.view.detectChanges();
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
this.portalRoot = createPortalRoot({
|
|
884
|
+
origin: this.triggerRef().nativeElement,
|
|
885
|
+
disabled: this.portal() === false,
|
|
886
|
+
});
|
|
887
|
+
this.view = this.viewContainer.createEmbeddedView(this.template());
|
|
888
|
+
this.view.detectChanges();
|
|
889
|
+
this.layerNode = this.view.rootNodes.find((node) => node instanceof HTMLElement);
|
|
890
|
+
this.surfaceNode = this.layerNode?.querySelector("[data-part='content']") ?? null;
|
|
891
|
+
if (this.layerNode === null)
|
|
892
|
+
return;
|
|
893
|
+
this.portalRoot.container?.append(this.layerNode);
|
|
894
|
+
this.presence = createPresence({ present: this.isOpen() });
|
|
895
|
+
this.presence.setNode(this.layerNode);
|
|
896
|
+
this.recount();
|
|
897
|
+
}
|
|
898
|
+
position() {
|
|
899
|
+
if (this.layerNode === null)
|
|
900
|
+
return;
|
|
901
|
+
this.positioner?.destroy();
|
|
902
|
+
/* The anchor is the frame rather than the button inside it, so the popup is
|
|
903
|
+
as wide as the control the reader sees: the trigger is the frame less its
|
|
904
|
+
two borders, and `matchWidth` writes whatever it is given (SL10). */
|
|
905
|
+
const trigger = this.triggerRef().nativeElement;
|
|
906
|
+
this.positioner = createPositioner(trigger.closest("[data-part='root']") ?? trigger, this.layerNode, {
|
|
907
|
+
align: this.resolvedAlign(),
|
|
908
|
+
alignOffset: this.alignOffset() ?? this.defaults.alignOffset,
|
|
909
|
+
boundaryPadding: this.collisionPadding() ?? this.defaults.collisionPadding,
|
|
910
|
+
flip: this.flip() ?? this.defaults.flip,
|
|
911
|
+
hideWhenDetached: this.hideWhenDetached() ?? this.defaults.hideWhenDetached,
|
|
912
|
+
matchWidth: this.resolvedWidth() === 'anchor',
|
|
913
|
+
shift: this.shift() ?? this.defaults.shift,
|
|
914
|
+
side: this.resolvedSide(),
|
|
915
|
+
sideOffset: this.sideOffset() ?? this.defaults.sideOffset,
|
|
916
|
+
strategy: this.strategy() ?? this.defaults.strategy,
|
|
917
|
+
});
|
|
918
|
+
/* The height that bounds the list arrives with the position, after the
|
|
919
|
+
highlight has landed, so the highlighted row is revealed again. */
|
|
920
|
+
void this.positioner.update().then(() => this.reveal(this.highlightedValue()));
|
|
921
|
+
}
|
|
922
|
+
bind() {
|
|
923
|
+
if (this.layerNode === null)
|
|
924
|
+
return;
|
|
925
|
+
/* The control is a branch, so pressing the trigger again toggles the popup
|
|
926
|
+
instead of dismissing it and reopening it in one gesture. */
|
|
927
|
+
this.layer = createDismissableLayer(this.layerNode, {
|
|
928
|
+
branches: [this.triggerRef().nativeElement.parentElement].filter((branch) => branch !== null),
|
|
929
|
+
escape: this.closeOnEscape() ?? this.defaults.closeOnEscape,
|
|
930
|
+
focusOutside: false,
|
|
931
|
+
modal: false,
|
|
932
|
+
outsidePress: this.closeOnOutsidePress() ?? this.defaults.closeOnOutsidePress,
|
|
933
|
+
scrollLock: false,
|
|
934
|
+
onDismiss: (request) => {
|
|
935
|
+
const source = request.source;
|
|
936
|
+
/**
|
|
937
|
+
* The query first, the popup second — and the decision lives here
|
|
938
|
+
* rather than in the field's own handler because the layer listens in
|
|
939
|
+
* the **capture** phase: it sees Escape before anything inside it does,
|
|
940
|
+
* so a field that tried to spend the key first would already have lost
|
|
941
|
+
* the surface. A reader four characters into a search wants the whole
|
|
942
|
+
* list back more often than they want the popup gone, and the pattern
|
|
943
|
+
* names this branch and makes it optional.
|
|
944
|
+
*/
|
|
945
|
+
if (request.reason === 'escape' && this.resolvedSearch() && this.query() !== '') {
|
|
946
|
+
this.setQuery('', 'clear', source);
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
this.setOpen(false, request.reason === 'escape' ? 'escape' : 'outsidePress', source);
|
|
950
|
+
/* Focus goes back to the control on a key and stays where the reader
|
|
951
|
+
put it on a press outside. */
|
|
952
|
+
if (request.reason === 'escape')
|
|
953
|
+
this.focus();
|
|
954
|
+
},
|
|
955
|
+
});
|
|
956
|
+
if (this.resolvedTypeahead()) {
|
|
957
|
+
this.typeaheadHandle = createTypeahead({
|
|
958
|
+
timeout: this.typeaheadTimeout() ?? this.defaults.typeaheadTimeout,
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Where the highlight lands as the popup opens, and where focus goes.
|
|
964
|
+
*
|
|
965
|
+
* Without a search field nothing moves: the trigger keeps focus for the whole
|
|
966
|
+
* interaction. With one, focus enters the layer — the combobox pattern's own
|
|
967
|
+
* note says a dialog popup does not support `aria-activedescendant`, so DOM
|
|
968
|
+
* focus moves into the dialog — and the field takes it however the popup was
|
|
969
|
+
* opened, a press on the trigger included.
|
|
970
|
+
*/
|
|
971
|
+
enter() {
|
|
972
|
+
this.recount();
|
|
973
|
+
if (this.resolvedSearch())
|
|
974
|
+
this.searchNode()?.focus({ preventScroll: true });
|
|
975
|
+
const list = this.options();
|
|
976
|
+
if (list.length === 0)
|
|
977
|
+
return;
|
|
978
|
+
const character = this.pending;
|
|
979
|
+
this.pending = null;
|
|
980
|
+
if (character !== null && this.typeaheadHandle !== null) {
|
|
981
|
+
this.typeaheadMatch(character, this.typeaheadHandle);
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
if (this.entry === 'none')
|
|
985
|
+
return;
|
|
986
|
+
if (this.entry === 'selected') {
|
|
987
|
+
const held = this.selection();
|
|
988
|
+
const chosen = list.find((option) => held.includes(option.dataset['value'] ?? '') && option.dataset['disabled'] === undefined);
|
|
989
|
+
if (chosen !== undefined) {
|
|
990
|
+
this.setHighlighted(chosen.dataset['value'] ?? null, 'keyboard');
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
this.move('first', new Event('keydown'));
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
this.move(this.entry, new Event('keydown'));
|
|
997
|
+
}
|
|
998
|
+
hide() {
|
|
999
|
+
this.unbind();
|
|
1000
|
+
if (this.resolvedMount() === 'active')
|
|
1001
|
+
this.teardown();
|
|
1002
|
+
}
|
|
1003
|
+
unbind() {
|
|
1004
|
+
this.layer?.destroy();
|
|
1005
|
+
this.positioner?.destroy();
|
|
1006
|
+
this.typeaheadHandle?.destroy();
|
|
1007
|
+
this.layer = null;
|
|
1008
|
+
this.positioner = null;
|
|
1009
|
+
this.typeaheadHandle = null;
|
|
1010
|
+
}
|
|
1011
|
+
teardown() {
|
|
1012
|
+
this.unbind();
|
|
1013
|
+
this.presence?.destroy();
|
|
1014
|
+
this.portalRoot?.release();
|
|
1015
|
+
this.layerNode?.remove();
|
|
1016
|
+
this.view?.destroy();
|
|
1017
|
+
this.presence = null;
|
|
1018
|
+
this.portalRoot = null;
|
|
1019
|
+
this.layerNode = null;
|
|
1020
|
+
this.surfaceNode = null;
|
|
1021
|
+
this.view = null;
|
|
1022
|
+
}
|
|
1023
|
+
writeValue(value) {
|
|
1024
|
+
this.value.set(value ?? null);
|
|
1025
|
+
}
|
|
1026
|
+
registerOnChange(fn) {
|
|
1027
|
+
this.onChange = fn;
|
|
1028
|
+
}
|
|
1029
|
+
registerOnTouched(fn) {
|
|
1030
|
+
this.onTouched = fn;
|
|
1031
|
+
}
|
|
1032
|
+
setDisabledState(isDisabled) {
|
|
1033
|
+
this.disabledByForm.set(isDisabled);
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* The one validity the family owns. `required` on a native `select` is
|
|
1037
|
+
* satisfied by any non-empty option, and the hidden element this control
|
|
1038
|
+
* carries always holds one — so the browser cannot answer the question and
|
|
1039
|
+
* the family answers it here.
|
|
1040
|
+
*/
|
|
1041
|
+
validate() {
|
|
1042
|
+
if (!this.resolvedRequired())
|
|
1043
|
+
return null;
|
|
1044
|
+
return this.selection().length === 0 ? { required: true } : null;
|
|
1045
|
+
}
|
|
1046
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1047
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: SlSelect, isStandalone: true, selector: "sl-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, highlightedValue: { classPropertyName: "highlightedValue", publicName: "highlightedValue", isSignal: true, isRequired: false, transformFunction: null }, searchValue: { classPropertyName: "searchValue", publicName: "searchValue", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, mount: { classPropertyName: "mount", publicName: "mount", isSignal: true, isRequired: false, transformFunction: null }, strategy: { classPropertyName: "strategy", publicName: "strategy", isSignal: true, isRequired: false, transformFunction: null }, messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, sideOffset: { classPropertyName: "sideOffset", publicName: "sideOffset", isSignal: true, isRequired: false, transformFunction: null }, alignOffset: { classPropertyName: "alignOffset", publicName: "alignOffset", isSignal: true, isRequired: false, transformFunction: null }, collisionPadding: { classPropertyName: "collisionPadding", publicName: "collisionPadding", isSignal: true, isRequired: false, transformFunction: null }, typeaheadTimeout: { classPropertyName: "typeaheadTimeout", publicName: "typeaheadTimeout", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, loop: { classPropertyName: "loop", publicName: "loop", isSignal: true, isRequired: false, transformFunction: null }, search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, highlightMatch: { classPropertyName: "highlightMatch", publicName: "highlightMatch", isSignal: true, isRequired: false, transformFunction: null }, typeahead: { classPropertyName: "typeahead", publicName: "typeahead", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutsidePress: { classPropertyName: "closeOnOutsidePress", publicName: "closeOnOutsidePress", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "flip", isSignal: true, isRequired: false, transformFunction: null }, shift: { classPropertyName: "shift", publicName: "shift", isSignal: true, isRequired: false, transformFunction: null }, hideWhenDetached: { classPropertyName: "hideWhenDetached", publicName: "hideWhenDetached", isSignal: true, isRequired: false, transformFunction: null }, portal: { classPropertyName: "portal", publicName: "portal", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", valueChangeRequest: "valueChangeRequest", open: "openChange", openChangeRequest: "openChangeRequest", highlightedValue: "highlightedValueChange", highlightedValueChangeRequest: "highlightedValueChangeRequest", searchValue: "searchValueChange", searchValueChangeRequest: "searchValueChangeRequest" }, host: { attributes: { "data-ui": "select", "data-part": "root" }, properties: { "attr.aria-label": "null", "attr.aria-labelledby": "null", "attr.data-size": "resolvedSize()", "attr.data-variant": "resolvedVariant()", "attr.data-full-width": "resolvedFullWidth() ? '' : null", "attr.data-multiple": "resolvedMultiple() ? '' : null", "attr.data-open": "isOpen() ? '' : null", "attr.data-disabled": "resolvedDisabled() ? '' : null", "attr.data-readonly": "resolvedReadOnly() ? '' : null", "attr.data-invalid": "resolvedInvalid() ? '' : null", "attr.data-required": "resolvedRequired() ? '' : null", "attr.data-loading": "loading() ? '' : null", "attr.data-narrow": "narrow() ? '' : null" } }, providers: [
|
|
1048
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SlSelect), multi: true },
|
|
1049
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => SlSelect), multi: true },
|
|
1050
|
+
], queries: [{ propertyName: "summaryTemplate", first: true, predicate: SlSelectValue, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "template", first: true, predicate: ["layer"], descendants: true, isSignal: true }, { propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "tags", first: true, predicate: ["tags"], descendants: true, isSignal: true }, { propertyName: "chipOverflow", first: true, predicate: ["chipOverflow"], descendants: true, isSignal: true }], exportAs: ["slSelect"], ngImport: i0, template: `
|
|
1051
|
+
<button
|
|
1052
|
+
#trigger
|
|
1053
|
+
type="button"
|
|
1054
|
+
role="combobox"
|
|
1055
|
+
data-part="trigger"
|
|
1056
|
+
[id]="triggerId"
|
|
1057
|
+
[attr.aria-haspopup]="resolvedSearch() ? 'dialog' : 'listbox'"
|
|
1058
|
+
[disabled]="resolvedDisabled()"
|
|
1059
|
+
[attr.aria-expanded]="isOpen()"
|
|
1060
|
+
[attr.aria-controls]="isOpen() ? contentId : null"
|
|
1061
|
+
[attr.aria-activedescendant]="triggerActiveDescendant()"
|
|
1062
|
+
[attr.aria-label]="ariaLabel() ?? null"
|
|
1063
|
+
[attr.aria-labelledby]="labelledBy()"
|
|
1064
|
+
[attr.aria-describedby]="describedBy()"
|
|
1065
|
+
[attr.aria-readonly]="resolvedReadOnly() ? true : null"
|
|
1066
|
+
[attr.aria-required]="resolvedRequired() ? true : null"
|
|
1067
|
+
[attr.aria-invalid]="resolvedInvalid() ? true : null"
|
|
1068
|
+
(click)="onTriggerClick($event)"
|
|
1069
|
+
(keydown)="onKeyDown($event)"
|
|
1070
|
+
(blur)="onBlur()"
|
|
1071
|
+
>
|
|
1072
|
+
<span
|
|
1073
|
+
data-part="value"
|
|
1074
|
+
[attr.data-placeholder]="selection().length === 0 ? '' : null"
|
|
1075
|
+
[attr.data-unmatched]="unmatched() ? '' : null"
|
|
1076
|
+
>
|
|
1077
|
+
@if (summaryTemplate(); as template) {
|
|
1078
|
+
<ng-container
|
|
1079
|
+
[ngTemplateOutlet]="template"
|
|
1080
|
+
[ngTemplateOutletContext]="{ $implicit: selection(), labels: labels() }"
|
|
1081
|
+
/>
|
|
1082
|
+
} @else if (resolvedMultiple() && selection().length > 1) {
|
|
1083
|
+
<span data-part="summary">{{ summary() }}</span>
|
|
1084
|
+
} @else {
|
|
1085
|
+
{{ summary() }}
|
|
1086
|
+
}
|
|
1087
|
+
</span>
|
|
1088
|
+
</button>
|
|
1089
|
+
|
|
1090
|
+
<!--
|
|
1091
|
+
The chips, over the trigger rather than inside it: the trigger is a
|
|
1092
|
+
button, and a remove control inside one is a control inside a control
|
|
1093
|
+
(SL4). The stylesheet places the row over the trigger's own content box
|
|
1094
|
+
and lets every press it does not want through to the button underneath.
|
|
1095
|
+
-->
|
|
1096
|
+
@if (resolvedMultiple() && selection().length > 0) {
|
|
1097
|
+
<span #tags data-part="tags">
|
|
1098
|
+
@for (value of selection(); track value) {
|
|
1099
|
+
<span data-ui="tag" data-part="root" data-size="sm" data-variant="soft">
|
|
1100
|
+
<span data-part="body">
|
|
1101
|
+
<span data-part="label">{{ labelFor(value) ?? value }}</span>
|
|
1102
|
+
</span>
|
|
1103
|
+
<button
|
|
1104
|
+
type="button"
|
|
1105
|
+
data-part="remove"
|
|
1106
|
+
[disabled]="resolvedDisabled() || resolvedReadOnly()"
|
|
1107
|
+
[attr.aria-label]="removeLabelFor(value)"
|
|
1108
|
+
(click)="onRemoveChip(value, $event)"
|
|
1109
|
+
>
|
|
1110
|
+
<span slIcon><svg slGlyph name="x"></svg></span>
|
|
1111
|
+
</button>
|
|
1112
|
+
</span>
|
|
1113
|
+
}
|
|
1114
|
+
<span
|
|
1115
|
+
#chipOverflow
|
|
1116
|
+
data-ui="tag"
|
|
1117
|
+
data-part="root"
|
|
1118
|
+
data-size="sm"
|
|
1119
|
+
data-variant="soft"
|
|
1120
|
+
data-overflow
|
|
1121
|
+
hidden
|
|
1122
|
+
>
|
|
1123
|
+
<span data-part="body"
|
|
1124
|
+
><span data-part="label">+{{ collapsedCount() || 1 }}</span></span
|
|
1125
|
+
>
|
|
1126
|
+
</span>
|
|
1127
|
+
</span>
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
@if (showClear()) {
|
|
1131
|
+
<button
|
|
1132
|
+
type="button"
|
|
1133
|
+
data-part="clear"
|
|
1134
|
+
[attr.aria-label]="t('clear')"
|
|
1135
|
+
(click)="onClear($event)"
|
|
1136
|
+
>
|
|
1137
|
+
<span slIcon><svg slGlyph name="x"></svg></span>
|
|
1138
|
+
</button>
|
|
1139
|
+
}
|
|
1140
|
+
@if (loading()) {
|
|
1141
|
+
<span data-part="busy" data-ui="spinner" aria-hidden="true"></span>
|
|
1142
|
+
} @else {
|
|
1143
|
+
<span data-part="arrow"
|
|
1144
|
+
><span slIcon><svg slGlyph name="chevron-down"></svg></span
|
|
1145
|
+
></span>
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
@if (name(); as submissionName) {
|
|
1149
|
+
<select
|
|
1150
|
+
aria-hidden="true"
|
|
1151
|
+
tabindex="-1"
|
|
1152
|
+
[name]="submissionName"
|
|
1153
|
+
[attr.form]="form() ?? null"
|
|
1154
|
+
[multiple]="resolvedMultiple()"
|
|
1155
|
+
[disabled]="resolvedDisabled()"
|
|
1156
|
+
[required]="resolvedRequired()"
|
|
1157
|
+
style="
|
|
1158
|
+
position: absolute;
|
|
1159
|
+
inline-size: 1px;
|
|
1160
|
+
block-size: 1px;
|
|
1161
|
+
padding: 0;
|
|
1162
|
+
border: 0;
|
|
1163
|
+
overflow: hidden;
|
|
1164
|
+
clip-path: inset(50%);
|
|
1165
|
+
white-space: nowrap;
|
|
1166
|
+
"
|
|
1167
|
+
>
|
|
1168
|
+
<option value=""></option>
|
|
1169
|
+
@for (held of selection(); track $index) {
|
|
1170
|
+
<option [value]="held" selected>{{ labelFor(held) ?? held }}</option>
|
|
1171
|
+
}
|
|
1172
|
+
</select>
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
<!--
|
|
1176
|
+
The rows the popup holds, stamped into the listbox wherever the listbox
|
|
1177
|
+
is: the surface itself without a search field, and the list part one
|
|
1178
|
+
element in with one. They are a template rather than markup written twice
|
|
1179
|
+
because ng-content may be projected into exactly one place, and the
|
|
1180
|
+
options are that one place.
|
|
1181
|
+
-->
|
|
1182
|
+
<ng-template #rows>
|
|
1183
|
+
<!--
|
|
1184
|
+
Everything that is chosen, at the top of the popup (SL10). The
|
|
1185
|
+
control holds one line, so twelve values are three chips and a
|
|
1186
|
+
count; here they are all of them, and the band scrolls at about two
|
|
1187
|
+
rows of its own rather than growing the surface.
|
|
1188
|
+
|
|
1189
|
+
It is aria-hidden, and carries no remove control. The reason is
|
|
1190
|
+
keyboard reach: without a search field focus never enters this
|
|
1191
|
+
layer at all, and with one the layer spends its single Tab on
|
|
1192
|
+
commiting and leaving the control — so a widget in the band would
|
|
1193
|
+
answer the pointer and nothing else. What it says is already said,
|
|
1194
|
+
by the trigger's own name and by each option's aria-selected.
|
|
1195
|
+
-->
|
|
1196
|
+
@if (resolvedMultiple() && selection().length > 0) {
|
|
1197
|
+
<div data-part="chosen" aria-hidden="true">
|
|
1198
|
+
@for (value of selection(); track value) {
|
|
1199
|
+
<span data-ui="tag" data-part="root" data-size="sm" data-variant="soft">
|
|
1200
|
+
<span data-part="body">
|
|
1201
|
+
<span data-part="label">{{ labelFor(value) ?? value }}</span>
|
|
1202
|
+
</span>
|
|
1203
|
+
</span>
|
|
1204
|
+
}
|
|
1205
|
+
</div>
|
|
1206
|
+
}
|
|
1207
|
+
<ng-content />
|
|
1208
|
+
@if (loading()) {
|
|
1209
|
+
<!--
|
|
1210
|
+
The wait, as the shape of the list that is coming: three rows the
|
|
1211
|
+
height of an option, drawn by the skeleton sheet (SL6/CB5). Hidden
|
|
1212
|
+
assistive technology — the status row is the live region.
|
|
1213
|
+
-->
|
|
1214
|
+
<div data-part="placeholder" aria-hidden="true">
|
|
1215
|
+
@for (row of [0, 1, 2]; track row) {
|
|
1216
|
+
<div>
|
|
1217
|
+
<span data-ui="skeleton" data-part="root" data-shape="text" data-loading></span>
|
|
1218
|
+
</div>
|
|
1219
|
+
}
|
|
1220
|
+
</div>
|
|
1221
|
+
}
|
|
1222
|
+
@if (!loading() && empty()) {
|
|
1223
|
+
<div data-part="empty">{{ t('empty') }}</div>
|
|
1224
|
+
}
|
|
1225
|
+
@if (loading() || resolvedSearch()) {
|
|
1226
|
+
<!--
|
|
1227
|
+
The live region. While an answer is travelling it says so; while
|
|
1228
|
+
the reader is searching it says how many options survived the
|
|
1229
|
+
query, which is what docs/component-features.md §6 asks of a
|
|
1230
|
+
filtered collection. An empty row draws nothing.
|
|
1231
|
+
-->
|
|
1232
|
+
<div
|
|
1233
|
+
data-part="status"
|
|
1234
|
+
role="status"
|
|
1235
|
+
aria-live="polite"
|
|
1236
|
+
[attr.data-loading]="loading() ? '' : null"
|
|
1237
|
+
>
|
|
1238
|
+
{{ statusMessage() }}
|
|
1239
|
+
</div>
|
|
1240
|
+
}
|
|
1241
|
+
</ng-template>
|
|
1242
|
+
|
|
1243
|
+
<ng-template #layer>
|
|
1244
|
+
<div
|
|
1245
|
+
data-ui="select"
|
|
1246
|
+
data-part="positioner"
|
|
1247
|
+
[attr.data-align]="resolvedAlign()"
|
|
1248
|
+
[attr.data-size]="resolvedSize()"
|
|
1249
|
+
[attr.data-width]="resolvedWidth()"
|
|
1250
|
+
[attr.data-open]="isOpen() ? '' : null"
|
|
1251
|
+
[attr.inert]="isOpen() ? null : ''"
|
|
1252
|
+
>
|
|
1253
|
+
<div
|
|
1254
|
+
#surface
|
|
1255
|
+
data-part="content"
|
|
1256
|
+
[attr.role]="resolvedSearch() ? 'dialog' : 'listbox'"
|
|
1257
|
+
[attr.data-search]="resolvedSearch() ? '' : null"
|
|
1258
|
+
[id]="contentId"
|
|
1259
|
+
[attr.aria-labelledby]="ariaLabel() === undefined ? triggerId : null"
|
|
1260
|
+
[attr.aria-label]="ariaLabel() ?? null"
|
|
1261
|
+
[attr.aria-multiselectable]="resolvedSearch() || !resolvedMultiple() ? null : true"
|
|
1262
|
+
[attr.aria-busy]="resolvedSearch() || !loading() ? null : true"
|
|
1263
|
+
[attr.data-loading]="loading() ? '' : null"
|
|
1264
|
+
>
|
|
1265
|
+
<!--
|
|
1266
|
+
The field the reader filters with, and the listbox one element in.
|
|
1267
|
+
The combobox pattern lists the four roles a popup may carry and a
|
|
1268
|
+
popup holding a text field is a dialog, so the listbox moves inside
|
|
1269
|
+
it: a listbox holds options and groups, and a text field is neither.
|
|
1270
|
+
-->
|
|
1271
|
+
@if (resolvedSearch()) {
|
|
1272
|
+
<div data-part="search">
|
|
1273
|
+
<span data-part="search-icon" aria-hidden="true"
|
|
1274
|
+
><span slIcon><svg slGlyph name="search"></svg></span
|
|
1275
|
+
></span>
|
|
1276
|
+
<input
|
|
1277
|
+
#search
|
|
1278
|
+
type="text"
|
|
1279
|
+
role="combobox"
|
|
1280
|
+
data-part="search-input"
|
|
1281
|
+
autocomplete="off"
|
|
1282
|
+
spellcheck="false"
|
|
1283
|
+
aria-expanded="true"
|
|
1284
|
+
aria-autocomplete="list"
|
|
1285
|
+
[id]="searchId"
|
|
1286
|
+
[attr.aria-controls]="listId"
|
|
1287
|
+
[attr.aria-activedescendant]="activeDescendant()"
|
|
1288
|
+
[attr.aria-label]="t('search')"
|
|
1289
|
+
[placeholder]="t('searchPlaceholder')"
|
|
1290
|
+
[value]="query()"
|
|
1291
|
+
(input)="onSearchInput($event)"
|
|
1292
|
+
(keydown)="onSearchKeyDown($event)"
|
|
1293
|
+
/>
|
|
1294
|
+
</div>
|
|
1295
|
+
}
|
|
1296
|
+
@if (resolvedSearch()) {
|
|
1297
|
+
<div
|
|
1298
|
+
data-part="list"
|
|
1299
|
+
role="listbox"
|
|
1300
|
+
[id]="listId"
|
|
1301
|
+
[attr.aria-labelledby]="triggerId"
|
|
1302
|
+
[attr.aria-multiselectable]="resolvedMultiple() ? true : null"
|
|
1303
|
+
[attr.aria-busy]="loading() ? true : null"
|
|
1304
|
+
>
|
|
1305
|
+
<ng-container [ngTemplateOutlet]="rows" />
|
|
1306
|
+
</div>
|
|
1307
|
+
} @else {
|
|
1308
|
+
<ng-container [ngTemplateOutlet]="rows" />
|
|
1309
|
+
}
|
|
1310
|
+
</div>
|
|
1311
|
+
</div>
|
|
1312
|
+
</ng-template>
|
|
1313
|
+
`, isInline: true, styles: ["@layer slotted.components{[data-ui=select][data-part=root]{--_font-size: var(--slotted-control-font-size-md, 13px);--_height: var(--slotted-control-height-md, 34px);--_padding-inline: var(--slotted-control-padding-inline-md, 13px);--_gap: var(--slotted-control-gap-md, 8px);--_icon-floor: var(--slotted-select-icon-size-min, 14px);--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-md, 16px));--_inner-size: var(--slotted-control-inner-size-md, 24px);--_action-size: var( --slotted-select-action-size, min(calc(var(--_icon-size) + 2 * var(--slotted-space-2, .25rem)), var(--_inner-size)) );align-items:center;background-color:var(--slotted-select-background, var(--slotted-control-surface, Field));border:var(--slotted-control-border-width, 1px) solid var(--slotted-select-border-color, var(--slotted-control-border-color, ButtonBorder));border-radius:var(--slotted-select-radius, var(--slotted-control-radius, 4px));box-shadow:var(--slotted-select-shadow, var(--slotted-control-shadow, none));box-sizing:border-box;color:var(--slotted-select-color, var(--slotted-text, CanvasText));column-gap:var(--_gap);display:grid;font-family:var(--slotted-control-font-family, system-ui, sans-serif);font-size:var(--_font-size);grid-template-columns:minmax(0,1fr) auto;inline-size:100%;min-inline-size:0;min-block-size:var(--_height);position:relative;transition:background-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),border-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),box-shadow var(--slotted-control-transition-duration) var(--slotted-control-transition-easing)}[data-ui=select][data-part=root]:has(>[data-part=clear]){grid-template-columns:minmax(0,1fr) auto auto}[data-ui=select][data-part=root]:not([data-full-width]){inline-size:auto}[data-ui=select]>[data-part=trigger]{align-items:center;appearance:none;background-color:transparent;border:0;box-sizing:border-box;color:inherit;cursor:pointer;display:flex;font:inherit;gap:var(--_gap);grid-area:1 / 1 / 2 / -1;margin-block:calc(var(--slotted-control-border-width, 1px) * -1);min-block-size:var(--_height);min-inline-size:0;outline:none;padding-block:0;padding-inline-start:var(--_padding-inline);padding-inline-end:calc(var(--_padding-inline) + var(--_icon-size) + var(--_gap));text-align:start;touch-action:manipulation;-webkit-tap-highlight-color:transparent}[data-ui=select][data-part=root]:has(>[data-part=clear])>[data-part=trigger]{padding-inline-end:calc(var(--_padding-inline) + var(--_icon-size) + var(--_gap) + var(--_action-size) + var(--_gap))}[data-ui=select] [data-part=value]{flex:1 1 auto;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}[data-ui=select] [data-part=value][data-placeholder]{color:var(--slotted-select-placeholder-color, var(--slotted-text-muted, GrayText))}[data-ui=select] [data-part=value][data-unmatched]{font-variant-numeric:tabular-nums}[data-ui=select][data-part=root]>[data-part=tags]{align-items:center;display:flex;gap:var(--slotted-space-2, .25rem);grid-area:1 / 1 / 2 / 2;margin-inline-start:var(--_padding-inline);min-block-size:var(--slotted-target-min, 24px);min-inline-size:0;overflow:hidden;pointer-events:none}[data-ui=select]>[data-part=tags]>*{pointer-events:auto;position:relative}[data-ui=select]>[data-part=tags]>[data-overflow]{flex:none}[data-ui=select] [data-part=summary]{display:block;overflow:hidden;text-overflow:ellipsis;unicode-bidi:plaintext;white-space:nowrap}[data-ui=select][data-part=root]:not([data-narrow]) [data-part=summary]{block-size:1px;clip-path:inset(50%);inline-size:1px;overflow:hidden;white-space:nowrap}[data-ui=select][data-part=root][data-narrow]>[data-part=tags]{display:none}[data-ui=select]>[data-part=arrow]{--slotted-icon-size: var(--_icon-size);align-items:center;block-size:var(--_icon-size);color:var(--slotted-select-arrow-color, var(--slotted-text-muted, GrayText));display:flex;grid-area:1 / -2 / 2 / -1;inline-size:var(--_icon-size);justify-content:center;margin-inline-end:var(--_padding-inline);pointer-events:none}[data-ui=select]>[data-part=arrow]>[data-ui=icon]{transition:rotate var(--slotted-control-transition-duration) var(--slotted-control-transition-easing)}[data-ui=select][data-open]>[data-part=arrow]>[data-ui=icon]{rotate:180deg}[data-ui=select]>[data-part=busy]{--slotted-spinner-size: var(--_icon-size);color:var(--slotted-select-arrow-color, var(--slotted-text-muted, GrayText));grid-area:1 / -2 / 2 / -1;margin-inline-end:var(--_padding-inline);pointer-events:none}[data-ui=select]>[data-part=clear]{align-items:center;appearance:none;background-color:transparent;block-size:var(--_action-size);border:0;border-radius:var(--slotted-select-radius, var(--slotted-control-radius, 4px));color:var(--slotted-select-action-color, var(--slotted-text-muted, GrayText));cursor:pointer;display:inline-flex;grid-area:1 / 2 / 2 / 3;inline-size:var(--_action-size);justify-content:center;margin-inline:calc((var(--_icon-size) - var(--_action-size)) / 2);padding:0;position:relative;touch-action:manipulation;transition:background-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);-webkit-tap-highlight-color:transparent}[data-ui=select]>[data-part=clear]:after{content:\"\";inset:min(0px,calc((100% - var(--slotted-target-min, 24px)) / 2));position:absolute}@media(pointer:coarse){[data-ui=select]>[data-part=clear]:after{inset:min(0px,calc((100% - var(--slotted-target-comfortable, 44px)) / 2));inset-inline-end:0}}[data-ui=select]>[data-part=clear]{--slotted-icon-size: var(--_icon-size)}[data-ui=select][data-part=root][data-size=sm]{--_font-size: var(--slotted-control-font-size-sm, 12px);--_height: var(--slotted-control-height-sm, 30px);--_padding-inline: var(--slotted-control-padding-inline-sm, 10px);--_gap: var(--slotted-control-gap-sm, 6px);--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-sm, 14px));--_inner-size: var(--slotted-control-inner-size-sm, 22px)}[data-ui=select][data-part=root][data-size=md]{--_font-size: var(--slotted-control-font-size-md, 13px);--_height: var(--slotted-control-height-md, 34px);--_padding-inline: var(--slotted-control-padding-inline-md, 13px);--_gap: var(--slotted-control-gap-md, 8px);--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-md, 16px));--_inner-size: var(--slotted-control-inner-size-md, 24px)}[data-ui=select][data-part=root][data-size=lg]{--_font-size: var(--slotted-control-font-size-lg, 14px);--_height: var(--slotted-control-height-lg, 38px);--_padding-inline: var(--slotted-control-padding-inline-lg, 16px);--_gap: var(--slotted-control-gap-lg, 8px);--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-lg, 18px));--_inner-size: var(--slotted-control-inner-size-lg, 28px)}[data-ui=select][data-part=root][data-variant=subtle]{background-color:var( --slotted-select-subtle-background, var(--slotted-surface-sunken, Canvas) );border-color:var( --slotted-select-subtle-border-color, var(--slotted-border-subtle, ButtonBorder) )}[data-ui=select][data-part=root][data-variant=plain]{background-color:transparent;border-color:transparent;border-radius:var(--slotted-radius-none, 0px);box-shadow:none}@media(forced-colors:active){[data-ui=select][data-part=root][data-variant=plain]{border-color:ButtonBorder}}[data-ui=select][data-part=root]:hover:not([data-disabled]):not([data-readonly]):not([data-invalid]){border-color:var(--slotted-select-hover-border-color, var(--slotted-tone-accent-border))}[data-ui=select][data-part=root][data-variant=subtle]:hover:not([data-disabled]):not([data-readonly]):not([data-invalid]){background-color:var( --slotted-select-subtle-hover-background, var(--slotted-tone-secondary-subtle-hover) )}[data-ui=select][data-part=root][data-variant=plain]:hover:not([data-disabled]):not([data-readonly]):not([data-invalid]){background-color:var( --slotted-select-plain-hover-background, var(--slotted-tone-secondary-subtle-hover) );border-color:transparent}[data-ui=select][data-part=root]:has(>[data-part=trigger]:focus-visible){box-shadow:var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px) var(--slotted-focus-ring-color, Highlight);outline:var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);outline-offset:var(--slotted-focus-ring-offset, 2px)}[data-ui=select][data-part=root][data-variant=plain]:has(>[data-part=trigger]:focus-visible){box-shadow:none;outline-offset:calc(var(--slotted-focus-ring-offset, 2px) * -1)}[data-ui=select][data-part=root][data-open]:not([data-disabled]){border-color:var(--slotted-select-open-border-color, var(--slotted-tone-accent-border))}[data-ui=select][data-part=root][data-invalid]{--slotted-focus-ring-color: var( --slotted-select-invalid-focus-ring-color, var(--slotted-focus-ring-color-invalid, Highlight) );--_invalid-edge-width: var( --slotted-select-invalid-edge-width, var(--slotted-control-invalid-edge-width, 1px) );--_invalid-edge-color: var( --slotted-select-invalid-border-color, var(--slotted-tone-danger-border) );--_invalid-edge: inset 0 0 0 var(--_invalid-edge-width) var(--_invalid-edge-color);border-color:var(--slotted-select-invalid-border-color, var(--slotted-tone-danger-border));box-shadow:var(--_invalid-edge)}[data-ui=select][data-part=root][data-invalid]:has(>[data-part=trigger]:focus-visible){box-shadow:var(--_invalid-edge),var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px) var(--slotted-focus-ring-color, Highlight)}[data-ui=select][data-part=root][data-variant=plain][data-invalid]:has(>[data-part=trigger]:focus-visible){box-shadow:inset 0 0 0 calc(var(--slotted-focus-ring-offset, 2px) - var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width)) var(--_invalid-edge-color)}@media(forced-colors:active){[data-ui=select][data-part=root][data-invalid]{outline:var(--_invalid-edge-width) solid CanvasText;outline-offset:calc(-1 * (var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width)))}[data-ui=select][data-part=root][data-invalid]:has(>[data-part=trigger]:focus-visible){outline:calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double var(--slotted-focus-ring-color, Highlight);outline-offset:var(--slotted-focus-ring-offset, 2px)}[data-ui=select][data-part=root][data-variant=plain][data-invalid]:has(>[data-part=trigger]:focus-visible){outline:calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double var(--slotted-focus-ring-color, Highlight);outline-offset:calc(-1 * (var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)))}}[data-ui=select][data-part=root][data-readonly]{background-color:var( --slotted-select-readonly-background, var(--slotted-tone-secondary-subtle-hover) )}[data-ui=select][data-part=root][data-readonly] [data-part=arrow]{opacity:.5}[data-ui=select][data-part=root][data-disabled],[data-ui=select][data-part=root]:has(>[data-part=trigger]:disabled){background-color:var(--slotted-select-disabled-background, var(--slotted-disabled-background));border-color:var(--slotted-select-disabled-border-color, var(--slotted-disabled-border));box-shadow:none;color:var(--slotted-select-disabled-color, var(--slotted-disabled-foreground))}[data-ui=select][data-part=root][data-disabled]>[data-part=trigger],[data-ui=select][data-part=root]>[data-part=trigger]:disabled{cursor:not-allowed}[data-ui=select]>[data-part=clear]:hover:not(:disabled):not([data-disabled]){background-color:var( --slotted-select-action-hover-background, var(--slotted-tone-secondary-subtle-hover) )}[data-ui=select]>[data-part=clear]:active:not(:disabled):not([data-disabled]){background-color:var( --slotted-select-action-active-background, var(--slotted-tone-secondary-subtle-active) )}[data-ui=select]>[data-part=clear]:focus-visible{outline:var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);outline-offset:calc(var(--slotted-focus-ring-offset, 2px) * -1)}[data-ui=select][data-part=positioner]{--_surface: var(--slotted-select-surface, var(--slotted-surface-raised, #ffffff));--_text: var(--slotted-select-content-text, var(--slotted-text, #0f172a));--_muted: var(--slotted-select-content-text-muted, var(--slotted-text-muted, #5b6b7f));--_border-color: var( --slotted-select-content-border-color, var(--slotted-border-subtle, #e2e8f0) );--_border-width: var(--slotted-border-width-thin, 1px);--_radius: var(--slotted-select-content-radius, var(--slotted-radius-lg, 8px));--_shadow: var(--slotted-select-content-shadow, var(--slotted-shadow-md));--_highlight: var(--slotted-select-highlight, var(--slotted-tone-secondary-subtle-active));--_highlight-active: var(--slotted-select-highlight-active, var(--slotted-tone-accent-surface));--_selected-color: var(--slotted-select-selected-color, var(--slotted-tone-accent-text));--_inset-block: var(--slotted-select-content-padding-block, var(--slotted-space-2, .25rem));--_inset-inline: var(--slotted-select-content-padding-inline, var(--slotted-space-2, .25rem));--_item-inset: var(--slotted-control-padding-inline-md, .8125rem);--_item-height: var(--slotted-control-height-md, 34px);--_item-radius: var(--slotted-select-item-radius, var(--slotted-control-radius));--_content-font-size: var(--slotted-control-font-size-md, 13px);--_secondary-font-size: var(--slotted-control-font-size-sm, 12px);--_content-icon-size: var(--slotted-control-icon-size-md, 16px);--_column-gap: var(--slotted-control-gap-md, .5rem);--_measure: var(--slotted-select-measure, 24rem);position:absolute;inset-block-start:0;z-index:calc(var(--slotted-z-index-popover, 1100) + var(--slotted-layer-depth, 0));isolation:isolate;box-sizing:border-box;pointer-events:none;opacity:0;--_enter-distance: var(--slotted-space-2, .25rem);translate:0 calc(-1 * var(--_enter-distance));transition:opacity var(--slotted-duration-short) var(--slotted-easing-exit),translate var(--slotted-duration-short) var(--slotted-easing-exit)}[data-ui=select][data-part=positioner][data-side=top]{translate:0 var(--_enter-distance)}[data-ui=select][data-part=positioner]:is([data-side=left],[data-side=right]){translate:0 0}[data-ui=select][data-part=positioner][data-open]{opacity:1;translate:0 0;transition:none}[data-ui=select][data-part=positioner][data-open][data-positioned]{animation:slotted-select-enter-down var(--slotted-duration-medium) var(--slotted-easing-enter)}[data-ui=select][data-part=positioner][data-open][data-positioned][data-side=top]{animation-name:slotted-select-enter-up}[data-ui=select][data-part=positioner][data-open][data-positioned]:is([data-side=left],[data-side=right]){animation-name:slotted-select-fade}@keyframes slotted-select-enter-down{0%{opacity:0;translate:0 calc(-1 * var(--_enter-distance))}}@keyframes slotted-select-enter-up{0%{opacity:0;translate:0 var(--_enter-distance)}}@keyframes slotted-select-fade{0%{opacity:0}}@media(prefers-reduced-motion:reduce){[data-ui=select][data-part=positioner],[data-ui=select][data-part=positioner][data-side=top],[data-ui=select][data-part=positioner][data-side=left],[data-ui=select][data-part=positioner][data-side=right]{translate:0 0;transition:opacity var(--slotted-duration-short) var(--slotted-easing-exit)}[data-ui=select][data-part=positioner][data-open][data-positioned],[data-ui=select][data-part=positioner][data-open][data-positioned][data-side=top],[data-ui=select][data-part=positioner][data-open][data-positioned][data-side=left],[data-ui=select][data-part=positioner][data-open][data-positioned][data-side=right]{animation-name:slotted-select-fade}}[data-ui=select][data-part=positioner][data-detached]{visibility:hidden}[data-ui=select][data-part=positioner][data-width=anchor]{inline-size:var(--slotted-positioner-anchor-width, auto)}[data-ui=select][data-part=positioner][data-width=content]{inline-size:max-content;max-inline-size:min(var(--_measure),var(--slotted-positioner-available-width, 100vw));min-inline-size:var(--slotted-positioner-anchor-width, auto)}[data-ui=select][data-part=positioner][data-size=sm]{--_item-inset: var(--slotted-control-padding-inline-sm, .625rem);--_item-height: var(--slotted-control-height-sm, 30px);--_content-font-size: var(--slotted-control-font-size-sm, 12px);--_secondary-font-size: var(--slotted-font-size-xs, .75rem);--_content-icon-size: var(--slotted-control-icon-size-sm, 14px);--_column-gap: var(--slotted-control-gap-sm, .375rem)}[data-ui=select][data-part=positioner][data-size=lg]{--_item-inset: var(--slotted-control-padding-inline-lg, 1rem);--_item-height: var(--slotted-control-height-lg, 38px);--_content-font-size: var(--slotted-control-font-size-lg, 14px);--_secondary-font-size: var(--slotted-control-font-size-sm, 12px);--_content-icon-size: var(--slotted-control-icon-size-lg, 18px);--_column-gap: var(--slotted-control-gap-lg, .5rem)}[data-ui=select]>[data-part=content]{background:var(--_surface);border:var(--_border-width) solid var(--_border-color);border-radius:var(--_radius);box-shadow:var(--_shadow);box-sizing:border-box;color:var(--_text);font-family:var(--slotted-font-family-sans);font-size:var(--_content-font-size);max-block-size:calc(var(--slotted-positioner-available-height, 100vh) - var(--slotted-space-5, .75rem));outline:none;pointer-events:auto}[data-ui=select]>[data-part=content]:not([data-search]),[data-ui=select] [data-part=list]{display:grid;grid-template-columns:auto minmax(0,1fr) auto;overflow-y:auto;overscroll-behavior:contain;padding-block:var(--_inset-block);padding-inline:var(--_inset-inline)}[data-ui=select]>[data-part=content][data-search]{display:flex;flex-direction:column;padding:0}[data-ui=select] [data-part=list]{flex:1 1 auto;min-block-size:0}[data-ui=select] [data-part=search]{align-items:center;border-block-end:var(--_border-width) solid var(--_border-color);box-sizing:border-box;display:flex;flex:0 0 auto;gap:var(--_column-gap);min-block-size:var(--_item-height);padding-block:var(--slotted-space-2, .25rem);padding-inline:calc(var(--_inset-inline) + var(--_item-inset))}[data-ui=select] [data-part=search-icon]{--slotted-icon-size: var(--_content-icon-size);align-items:center;block-size:var(--_content-icon-size);color:var(--slotted-select-search-icon-color, var(--_muted));display:flex;flex:0 0 auto;inline-size:var(--_content-icon-size);justify-content:center;pointer-events:none}[data-ui=select] [data-part=search-input]{background-color:transparent;border:0;color:inherit;flex:1 1 auto;font:inherit;min-inline-size:0;outline:none;padding:0;text-overflow:ellipsis}[data-ui=select] [data-part=search-input]::placeholder{color:var(--slotted-select-placeholder-color, var(--_muted));text-overflow:ellipsis}[data-ui=select] [data-part=chosen]{background:var(--_surface);border-block-end:var(--_border-width) solid var(--_border-color);box-sizing:border-box;display:flex;flex-wrap:wrap;gap:var(--slotted-space-2, .25rem);grid-column:1 / -1;inset-block-start:calc(-1 * var(--_inset-block));margin-block:calc(-1 * var(--_inset-block)) var(--_inset-block);margin-inline:calc(-1 * var(--_inset-inline));max-block-size:calc(2 * var(--slotted-target-min, 24px) + var(--slotted-space-2, .25rem) + var(--_inset-block));min-inline-size:0;overflow-y:auto;overscroll-behavior:contain;padding-block:var(--_inset-block);padding-inline:var(--_inset-inline);position:sticky;z-index:1}[data-ui=select]>[data-part=content]:focus-visible{outline:none}[data-ui=select] [data-part=group]{display:grid;grid-column:1 / -1;grid-template-columns:subgrid}[data-ui=select] [data-part=item][hidden],[data-ui=select] [data-part=group][hidden]{display:none}[data-ui=select] [data-part=group-label]{color:var(--_muted);font-size:var(--_secondary-font-size);font-weight:var(--slotted-font-weight-semibold, 600);grid-column:1 / -1;line-height:var(--slotted-line-height-sm, 1.45);padding-block:var(--slotted-space-2, .25rem);padding-inline:var(--_item-inset)}[data-ui=select] [data-part=item]{align-content:center;border-radius:var(--_item-radius);box-sizing:border-box;cursor:pointer;display:grid;grid-column:1 / -1;grid-template-columns:subgrid;line-height:var(--slotted-line-height-md, 1.5);min-block-size:var(--_item-height);padding-block:var(--slotted-space-2, .25rem);padding-inline:var(--_item-inset);row-gap:var(--slotted-space-1, .125rem);-webkit-user-select:none;user-select:none;transition:background-color var(--slotted-control-transition-duration, var(--slotted-duration-short)) var(--slotted-control-transition-easing, var(--slotted-easing-standard)),color var(--slotted-control-transition-duration, var(--slotted-duration-short)) var(--slotted-control-transition-easing, var(--slotted-easing-standard))}[data-ui=select] [data-part=item][data-current]{background-color:var(--_highlight);box-shadow:inset 0 0 0 var(--slotted-border-width-thin, 1px) var(--slotted-select-highlight-ring, var(--slotted-tone-accent-border))}[data-ui=select] [data-part=item]:not([data-disabled]):active{background-color:var(--_highlight-active)}[data-ui=select] [data-part=item][data-selected]{color:var(--_selected-color)}[data-ui=select] [data-part=item][data-selected]+[data-part=item][data-selected]{border-start-end-radius:0;border-start-start-radius:0}[data-ui=select] [data-part=item][data-selected]:has(+[data-part=item][data-selected]){border-end-end-radius:0;border-end-start-radius:0}[data-ui=select] [data-part=item][data-selected]>[data-part=label]{font-weight:var(--slotted-font-weight-medium, 500)}[data-ui=select] [data-part=item][data-disabled]{color:var(--slotted-disabled-foreground, #64748b);cursor:not-allowed}[data-ui=select] [data-part=item][data-disabled][data-current]{box-shadow:inset 0 0 0 var(--slotted-border-width-thin, 1px) var(--slotted-disabled-border, #cbd5e1);color:var(--slotted-disabled-foreground, #64748b)}[data-ui=select] :is([data-part=indicator],[data-part=icon]){block-size:1lh}[data-ui=select] [data-part=icon]{--slotted-icon-size: var(--_content-icon-size);align-items:center;display:flex;grid-column:1;grid-row:1;inline-size:var(--_content-icon-size);justify-content:center;justify-self:center;margin-inline-end:var(--_column-gap)}[data-ui=select] [data-part=item]>[data-part=label]{grid-column:2;grid-row:1;min-inline-size:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;overflow-wrap:anywhere}[data-ui=select] [data-part=description]{color:var(--_muted);font-size:var(--_secondary-font-size);grid-column:2;grid-row:2;line-height:var(--slotted-line-height-sm, 1.45);min-inline-size:0;overflow-wrap:anywhere}[data-ui=select] [data-part=item][data-disabled]>[data-part=description]{color:inherit}[data-ui=select] [data-part=indicator]{--slotted-icon-size: var(--_content-icon-size);align-items:center;display:flex;grid-column:3;grid-row:1;inline-size:var(--_content-icon-size);justify-content:center;justify-self:end;margin-inline-start:var(--_column-gap);opacity:0;transition:opacity var(--slotted-duration-short) var(--slotted-easing-standard)}[data-ui=select] [data-part=item][data-selected]>[data-part=indicator]{opacity:1}[data-ui=select] [data-part=separator]{background-color:var(--slotted-select-separator-color, var(--_border-color));block-size:var(--_border-width);border:0;grid-column:1 / -1;margin-block:var(--slotted-space-2, .25rem);margin-inline:0}[data-ui=select] :is([data-part=empty],[data-part=status]){color:var(--_muted);unicode-bidi:plaintext;grid-column:1 / -1;min-inline-size:min(12rem,100%);padding-block:var(--slotted-space-5, .75rem);padding-inline:var(--_item-inset);text-align:center}[data-ui=select] [data-part=status]:empty{display:none}[data-ui=select] [data-part=placeholder]{display:grid;grid-column:1 / -1;padding-block:var(--slotted-space-2, .25rem);padding-inline:var(--_item-inset)}[data-ui=select] [data-part=placeholder]>[data-ui=skeleton]{align-self:center}[data-ui=select] [data-part=placeholder]>*{align-items:center;display:flex;min-block-size:var(--_item-height)}[data-ui=select] [data-part=placeholder]>:nth-child(2) [data-ui=skeleton]{inline-size:78%}[data-ui=select] [data-part=placeholder]>:nth-child(3) [data-ui=skeleton]{inline-size:56%}[data-ui=select]>[data-part=content][data-loading]{cursor:progress}@media(forced-colors:active){[data-ui=select] [data-part=item][data-current]{background-color:Highlight;color:HighlightText;forced-color-adjust:none}[data-ui=select] [data-part=item][data-disabled][data-current]{background-color:Highlight;color:GrayText}}}\n", "@layer slotted.components{[data-ui=tag][data-part=root]{--_solid: var(--slotted-tone-secondary-solid-hover);--_solid-hover: var(--slotted-tone-secondary-solid-active);--_solid-active: var(--slotted-tone-secondary-solid-active);--_on-solid: var(--slotted-tone-secondary-on-solid);--_surface: var(--slotted-tone-secondary-surface);--_subtle-hover: var(--slotted-tone-secondary-subtle-hover);--_subtle-active: var(--slotted-tone-secondary-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-secondary-border));--_text: var(--slotted-tone-secondary-text);--_edge: var(--_solid);--_font-size: var(--slotted-control-font-size-md, 13px);--_icon-size: var(--slotted-control-icon-size-sm, 14px);--_inner-size: var(--slotted-control-inner-size-sm, 22px);--_inset-block: var(--slotted-tag-inset-block, var(--slotted-space-2, .25rem));--_inset-inline: var(--slotted-space-4, .5rem);--_gap: var(--slotted-space-2, .25rem);--_line-height: var(--slotted-line-height-xs, 1.4);--_edge-width: var(--slotted-tag-border-width, var(--slotted-border-width-thin, 1px));--_radius: var(--slotted-radius-full, 9999px);--_inner-radius: max(0px, calc(var(--_radius) - var(--_edge-width)));--_own-size: calc( var(--_font-size) * var(--_line-height) + 2 * var(--_inset-block) + 2 * var(--_edge-width) );--_block-size: var(--slotted-control-inner-size, var(--_own-size));--_line: min( calc(var(--_font-size) * var(--_line-height)), calc(var(--_block-size) - 2 * var(--_edge-width)) );--_inset: max(0px, calc((var(--_block-size) - var(--_line) - 2 * var(--_edge-width)) / 2));align-items:stretch;border:var(--_edge-width) solid transparent;border-radius:var(--_radius);box-sizing:border-box;display:inline-flex;font-family:var(--slotted-tag-font-family, var(--slotted-control-font-family, sans-serif));font-size:var(--_font-size);font-weight:var(--slotted-tag-font-weight, var(--slotted-font-weight-medium, 500));line-height:var(--_line);max-inline-size:100%;min-block-size:var(--_block-size);vertical-align:middle;white-space:nowrap}[data-ui=tag][data-part=root][hidden]{display:none}[data-ui=tag][data-part=root][data-tone=secondary]{--_edge: var(--_border)}[data-ui=tag][data-part=root][data-tone=accent]{--_solid: var(--slotted-tone-accent-solid);--_solid-hover: var(--slotted-tone-accent-solid-hover);--_solid-active: var(--slotted-tone-accent-solid-active);--_on-solid: var(--slotted-tone-accent-on-solid);--_surface: var(--slotted-tone-accent-surface);--_subtle-hover: var(--slotted-tone-accent-subtle-hover);--_subtle-active: var(--slotted-tone-accent-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-accent-border));--_text: var(--slotted-tone-accent-text)}[data-ui=tag][data-part=root][data-tone=success]{--_solid: var(--slotted-tone-success-solid);--_solid-hover: var(--slotted-tone-success-solid-hover);--_solid-active: var(--slotted-tone-success-solid-active);--_on-solid: var(--slotted-tone-success-on-solid);--_surface: var(--slotted-tone-success-surface);--_subtle-hover: var(--slotted-tone-success-subtle-hover);--_subtle-active: var(--slotted-tone-success-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-success-border));--_text: var(--slotted-tone-success-text)}[data-ui=tag][data-part=root][data-tone=warning]{--_solid: var(--slotted-tone-warning-solid);--_solid-hover: var(--slotted-tone-warning-solid-hover);--_solid-active: var(--slotted-tone-warning-solid-active);--_on-solid: var(--slotted-tone-warning-on-solid);--_surface: var(--slotted-tone-warning-surface);--_subtle-hover: var(--slotted-tone-warning-subtle-hover);--_subtle-active: var(--slotted-tone-warning-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-warning-border));--_text: var(--slotted-tone-warning-text)}[data-ui=tag][data-part=root][data-tone=danger]{--_solid: var(--slotted-tone-danger-solid);--_solid-hover: var(--slotted-tone-danger-solid-hover);--_solid-active: var(--slotted-tone-danger-solid-active);--_on-solid: var(--slotted-tone-danger-on-solid);--_surface: var(--slotted-tone-danger-surface);--_subtle-hover: var(--slotted-tone-danger-subtle-hover);--_subtle-active: var(--slotted-tone-danger-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-danger-border));--_text: var(--slotted-tone-danger-text)}[data-ui=tag][data-part=root][data-variant=solid]{background-color:var(--_solid, ButtonFace);border-color:var(--_edge, ButtonFace);color:var(--_on-solid, ButtonText)}[data-ui=tag][data-part=root][data-variant=soft]{background-color:var(--_surface, ButtonFace);border-color:var(--_border, ButtonBorder);color:var(--_text, ButtonText)}[data-ui=tag][data-part=root][data-variant=outline]{background-color:transparent;border-color:var(--_border, ButtonBorder);color:var(--_text, ButtonText)}[data-ui=tag][data-part=root][data-size=sm]{--_font-size: var(--slotted-control-font-size-sm, 12px);--_inset-block: var(--slotted-tag-inset-block, var(--slotted-space-1, .125rem));--_inset-inline: var(--slotted-space-3, .375rem)}[data-ui=tag][data-part=root][data-size=lg]{--_font-size: var(--slotted-control-font-size-lg, 14px);--_icon-size: var(--slotted-control-icon-size-md, 16px);--_inner-size: var(--slotted-control-inner-size-md, 24px);--_inset-block: var(--slotted-tag-inset-block, var(--slotted-space-3, .375rem));--_inset-inline: var(--slotted-space-5, .75rem);--_gap: var(--slotted-space-3, .375rem)}[data-ui=tag][data-part=root][data-shape=square]{--_radius: var(--slotted-radius-sm, 4px)}[data-ui=tag] [data-part=body]{align-items:center;background-color:transparent;border:0;border-end-start-radius:var(--_inner-radius);border-start-start-radius:var(--_inner-radius);box-sizing:border-box;color:inherit;display:inline-flex;font:inherit;gap:var(--_gap);letter-spacing:inherit;min-inline-size:0;padding-block:var(--_inset);padding-inline:var(--_inset-inline);text-align:start;text-decoration:none;transition:background-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing)}[data-ui=tag] [data-part=body]:last-child{border-end-end-radius:var(--_inner-radius);border-start-end-radius:var(--_inner-radius)}[data-ui=tag] [data-part=body]:has(+[data-part=remove]){padding-inline-end:var(--_gap)}[data-ui=tag] [data-part=body]:is(a,button){cursor:pointer}[data-ui=tag] [data-part=label]{min-inline-size:0;overflow:hidden;text-overflow:ellipsis;unicode-bidi:plaintext}@supports (text-box: trim-both cap alphabetic){[data-ui=tag] [data-part=label]{margin-block:-.3em;padding-block:.3em;text-box:trim-both cap alphabetic}}[data-ui=tag] [data-part=start],[data-ui=tag] [data-part=end]{--slotted-icon-size: var(--_icon-size);align-items:center;block-size:var(--_icon-size);box-sizing:border-box;display:inline-flex;flex:none;font-size:var(--_icon-size);inline-size:var(--_icon-size);justify-content:center;line-height:1}[data-ui=tag] [data-part=start]>*,[data-ui=tag] [data-part=end]>*{block-size:100%;display:block;inline-size:100%}[data-ui=tag] [data-part=indicator]{--slotted-icon-size: var(--_icon-size);align-items:center;block-size:var(--_icon-size);display:inline-flex;flex:none;inline-size:0;justify-content:center;margin-inline-end:calc(-1 * var(--_gap));opacity:0;overflow:hidden;transition:inline-size var(--slotted-duration-short) var(--slotted-easing-standard),margin-inline-end var(--slotted-duration-short) var(--slotted-easing-standard),opacity var(--slotted-duration-short) var(--slotted-easing-standard)}[data-ui=tag][data-part=root][data-selected] [data-part=indicator]{inline-size:var(--_icon-size);margin-inline-end:0;opacity:1}[data-ui=tag] [data-part=remove]{--slotted-icon-size: var(--_icon-size);align-items:center;appearance:none;background-color:transparent;border:0;border-end-end-radius:var(--_inner-radius);border-start-end-radius:var(--_inner-radius);box-sizing:border-box;color:inherit;cursor:pointer;display:inline-flex;flex:none;inline-size:max(var(--slotted-target-min, 24px),min(calc(var(--_icon-size) + 2 * var(--slotted-space-2, .25rem)),var(--_inner-size)));justify-content:center;padding:0;position:relative;transition:background-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing)}[data-ui=tag] [data-part=remove]:after{content:\"\";inset:min(0px,calc((100% - var(--slotted-target-min, 24px)) / 2));position:absolute}@media(pointer:coarse){[data-ui=tag] [data-part=remove]{inline-size:max(var(--slotted-target-min, 24px),min(calc(var(--_icon-size) + 2 * var(--slotted-space-2, .25rem)),var(--_inner-size)),calc(var(--_block-size) - 2 * var(--_edge-width)))}[data-ui=tag] [data-part=remove]:after{inset:min(0px,calc((100% - var(--slotted-target-comfortable, 44px)) / 2))}}[data-ui=tag] [data-part=remove]:first-child{border-end-start-radius:var(--_inner-radius);border-start-start-radius:var(--_inner-radius)}[data-ui=tag][data-part=root][data-selected]:not([data-disabled]){background-color:var(--_solid, ButtonFace);border-color:var(--_edge, ButtonBorder);color:var(--_on-solid, ButtonText)}[data-ui=tag][data-part=root]{--_state-hover: color-mix( in oklab, currentColor var(--slotted-tag-state-layer-hover, 8%), transparent );--_state-active: color-mix( in oklab, currentColor var(--slotted-tag-state-layer-active, 14%), transparent )}[data-ui=tag][data-part=root][data-variant=soft]:not([data-disabled]):not([data-selected]) :is([data-part=body]:is(a,button),[data-part=remove]):hover:not(:disabled){background-color:var(--_state-hover)}[data-ui=tag][data-part=root][data-variant=soft]:not([data-disabled]):not([data-selected]) :is([data-part=body]:is(a,button),[data-part=remove]):active:not(:disabled){background-color:var(--_state-active)}[data-ui=tag][data-part=root][data-variant=outline]:not([data-disabled]):not([data-selected]) :is([data-part=body]:is(a,button),[data-part=remove]):hover:not(:disabled){background-color:var(--_subtle-hover, ButtonFace)}[data-ui=tag][data-part=root][data-variant=outline]:not([data-disabled]):not([data-selected]) :is([data-part=body]:is(a,button),[data-part=remove]):active:not(:disabled){background-color:var(--_subtle-active, ButtonFace)}[data-ui=tag][data-part=root][data-variant=solid]:not([data-disabled]) :is([data-part=body]:is(a,button),[data-part=remove]):hover:not(:disabled),[data-ui=tag][data-part=root][data-selected]:not([data-disabled]) :is([data-part=body]:is(a,button),[data-part=remove]):hover:not(:disabled){background-color:var(--_solid-hover, Highlight)}[data-ui=tag][data-part=root][data-variant=solid]:not([data-disabled]) :is([data-part=body]:is(a,button),[data-part=remove]):active:not(:disabled),[data-ui=tag][data-part=root][data-selected]:not([data-disabled]) :is([data-part=body]:is(a,button),[data-part=remove]):active:not(:disabled){background-color:var(--_solid-active, Highlight)}[data-ui=tag] [data-part=body]:focus-visible,[data-ui=tag] [data-part=remove]:focus-visible{outline:var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);outline-offset:calc(-2 * var(--slotted-focus-ring-width, 2px))}[data-ui=tag][data-part=group]:focus-visible{outline:var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);outline-offset:var(--slotted-focus-ring-offset, 2px)}[data-ui=tag][data-part=root][data-disabled]{color:var(--slotted-disabled-foreground, GrayText)}[data-ui=tag][data-part=root][data-variant=solid][data-disabled],[data-ui=tag][data-part=root][data-variant=soft][data-disabled],[data-ui=tag][data-part=root][data-selected][data-disabled]{background-color:var(--slotted-disabled-background, Canvas);border-color:var(--slotted-disabled-border, GrayText)}[data-ui=tag][data-part=root][data-variant=outline][data-disabled]{background-color:transparent;border-color:var(--slotted-disabled-border, GrayText)}[data-ui=tag][data-part=root][data-disabled] :is([data-part=body],[data-part=remove]),[data-ui=tag] [data-part=body]:disabled,[data-ui=tag] [data-part=remove]:disabled{background-color:transparent;cursor:not-allowed}[data-ui=tag] [data-part=remove]:disabled{color:var(--slotted-disabled-foreground, GrayText)}[data-ui=tag][data-part=group]{align-items:center;display:flex;flex-wrap:wrap;gap:var(--slotted-tag-group-gap, var(--slotted-space-2, .25rem))}[data-ui=tag][data-part=group][data-orientation=vertical]{align-items:start;flex-direction:column;flex-wrap:nowrap;inline-size:fit-content}[data-ui=tag][data-part=group]:empty{display:none}@media(forced-colors:active){[data-ui=tag][data-part=root]{border-color:currentColor}[data-ui=tag][data-part=root][data-selected]:not([data-disabled]){background-color:Highlight;color:HighlightText;forced-color-adjust:none}[data-ui=tag][data-part=root][data-disabled]{border-color:GrayText;color:GrayText}}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: SlGlyph, selector: "svg[slGlyph]", inputs: ["name", "solid"] }, { kind: "component", type: SlIcon, selector: "[slIcon]", inputs: ["directional", "label", "size", "tone"], exportAs: ["slIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1314
|
+
}
|
|
1315
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelect, decorators: [{
|
|
1316
|
+
type: Component,
|
|
1317
|
+
args: [{ selector: 'sl-select', standalone: true, exportAs: 'slSelect', imports: [NgTemplateOutlet, SlGlyph, SlIcon], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [
|
|
1318
|
+
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SlSelect), multi: true },
|
|
1319
|
+
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => SlSelect), multi: true },
|
|
1320
|
+
], host: {
|
|
1321
|
+
'data-ui': 'select',
|
|
1322
|
+
'data-part': 'root',
|
|
1323
|
+
/* The name a page writes on the element is forwarded to the control, and
|
|
1324
|
+
the root keeps none: ARIA 1.2 does not name a generic element. */
|
|
1325
|
+
'[attr.aria-label]': 'null',
|
|
1326
|
+
'[attr.aria-labelledby]': 'null',
|
|
1327
|
+
'[attr.data-size]': 'resolvedSize()',
|
|
1328
|
+
'[attr.data-variant]': 'resolvedVariant()',
|
|
1329
|
+
'[attr.data-full-width]': "resolvedFullWidth() ? '' : null",
|
|
1330
|
+
'[attr.data-multiple]': "resolvedMultiple() ? '' : null",
|
|
1331
|
+
'[attr.data-open]': "isOpen() ? '' : null",
|
|
1332
|
+
'[attr.data-disabled]': "resolvedDisabled() ? '' : null",
|
|
1333
|
+
'[attr.data-readonly]': "resolvedReadOnly() ? '' : null",
|
|
1334
|
+
'[attr.data-invalid]': "resolvedInvalid() ? '' : null",
|
|
1335
|
+
'[attr.data-required]': "resolvedRequired() ? '' : null",
|
|
1336
|
+
'[attr.data-loading]': "loading() ? '' : null",
|
|
1337
|
+
'[attr.data-narrow]': "narrow() ? '' : null",
|
|
1338
|
+
}, template: `
|
|
1339
|
+
<button
|
|
1340
|
+
#trigger
|
|
1341
|
+
type="button"
|
|
1342
|
+
role="combobox"
|
|
1343
|
+
data-part="trigger"
|
|
1344
|
+
[id]="triggerId"
|
|
1345
|
+
[attr.aria-haspopup]="resolvedSearch() ? 'dialog' : 'listbox'"
|
|
1346
|
+
[disabled]="resolvedDisabled()"
|
|
1347
|
+
[attr.aria-expanded]="isOpen()"
|
|
1348
|
+
[attr.aria-controls]="isOpen() ? contentId : null"
|
|
1349
|
+
[attr.aria-activedescendant]="triggerActiveDescendant()"
|
|
1350
|
+
[attr.aria-label]="ariaLabel() ?? null"
|
|
1351
|
+
[attr.aria-labelledby]="labelledBy()"
|
|
1352
|
+
[attr.aria-describedby]="describedBy()"
|
|
1353
|
+
[attr.aria-readonly]="resolvedReadOnly() ? true : null"
|
|
1354
|
+
[attr.aria-required]="resolvedRequired() ? true : null"
|
|
1355
|
+
[attr.aria-invalid]="resolvedInvalid() ? true : null"
|
|
1356
|
+
(click)="onTriggerClick($event)"
|
|
1357
|
+
(keydown)="onKeyDown($event)"
|
|
1358
|
+
(blur)="onBlur()"
|
|
1359
|
+
>
|
|
1360
|
+
<span
|
|
1361
|
+
data-part="value"
|
|
1362
|
+
[attr.data-placeholder]="selection().length === 0 ? '' : null"
|
|
1363
|
+
[attr.data-unmatched]="unmatched() ? '' : null"
|
|
1364
|
+
>
|
|
1365
|
+
@if (summaryTemplate(); as template) {
|
|
1366
|
+
<ng-container
|
|
1367
|
+
[ngTemplateOutlet]="template"
|
|
1368
|
+
[ngTemplateOutletContext]="{ $implicit: selection(), labels: labels() }"
|
|
1369
|
+
/>
|
|
1370
|
+
} @else if (resolvedMultiple() && selection().length > 1) {
|
|
1371
|
+
<span data-part="summary">{{ summary() }}</span>
|
|
1372
|
+
} @else {
|
|
1373
|
+
{{ summary() }}
|
|
1374
|
+
}
|
|
1375
|
+
</span>
|
|
1376
|
+
</button>
|
|
1377
|
+
|
|
1378
|
+
<!--
|
|
1379
|
+
The chips, over the trigger rather than inside it: the trigger is a
|
|
1380
|
+
button, and a remove control inside one is a control inside a control
|
|
1381
|
+
(SL4). The stylesheet places the row over the trigger's own content box
|
|
1382
|
+
and lets every press it does not want through to the button underneath.
|
|
1383
|
+
-->
|
|
1384
|
+
@if (resolvedMultiple() && selection().length > 0) {
|
|
1385
|
+
<span #tags data-part="tags">
|
|
1386
|
+
@for (value of selection(); track value) {
|
|
1387
|
+
<span data-ui="tag" data-part="root" data-size="sm" data-variant="soft">
|
|
1388
|
+
<span data-part="body">
|
|
1389
|
+
<span data-part="label">{{ labelFor(value) ?? value }}</span>
|
|
1390
|
+
</span>
|
|
1391
|
+
<button
|
|
1392
|
+
type="button"
|
|
1393
|
+
data-part="remove"
|
|
1394
|
+
[disabled]="resolvedDisabled() || resolvedReadOnly()"
|
|
1395
|
+
[attr.aria-label]="removeLabelFor(value)"
|
|
1396
|
+
(click)="onRemoveChip(value, $event)"
|
|
1397
|
+
>
|
|
1398
|
+
<span slIcon><svg slGlyph name="x"></svg></span>
|
|
1399
|
+
</button>
|
|
1400
|
+
</span>
|
|
1401
|
+
}
|
|
1402
|
+
<span
|
|
1403
|
+
#chipOverflow
|
|
1404
|
+
data-ui="tag"
|
|
1405
|
+
data-part="root"
|
|
1406
|
+
data-size="sm"
|
|
1407
|
+
data-variant="soft"
|
|
1408
|
+
data-overflow
|
|
1409
|
+
hidden
|
|
1410
|
+
>
|
|
1411
|
+
<span data-part="body"
|
|
1412
|
+
><span data-part="label">+{{ collapsedCount() || 1 }}</span></span
|
|
1413
|
+
>
|
|
1414
|
+
</span>
|
|
1415
|
+
</span>
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
@if (showClear()) {
|
|
1419
|
+
<button
|
|
1420
|
+
type="button"
|
|
1421
|
+
data-part="clear"
|
|
1422
|
+
[attr.aria-label]="t('clear')"
|
|
1423
|
+
(click)="onClear($event)"
|
|
1424
|
+
>
|
|
1425
|
+
<span slIcon><svg slGlyph name="x"></svg></span>
|
|
1426
|
+
</button>
|
|
1427
|
+
}
|
|
1428
|
+
@if (loading()) {
|
|
1429
|
+
<span data-part="busy" data-ui="spinner" aria-hidden="true"></span>
|
|
1430
|
+
} @else {
|
|
1431
|
+
<span data-part="arrow"
|
|
1432
|
+
><span slIcon><svg slGlyph name="chevron-down"></svg></span
|
|
1433
|
+
></span>
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
@if (name(); as submissionName) {
|
|
1437
|
+
<select
|
|
1438
|
+
aria-hidden="true"
|
|
1439
|
+
tabindex="-1"
|
|
1440
|
+
[name]="submissionName"
|
|
1441
|
+
[attr.form]="form() ?? null"
|
|
1442
|
+
[multiple]="resolvedMultiple()"
|
|
1443
|
+
[disabled]="resolvedDisabled()"
|
|
1444
|
+
[required]="resolvedRequired()"
|
|
1445
|
+
style="
|
|
1446
|
+
position: absolute;
|
|
1447
|
+
inline-size: 1px;
|
|
1448
|
+
block-size: 1px;
|
|
1449
|
+
padding: 0;
|
|
1450
|
+
border: 0;
|
|
1451
|
+
overflow: hidden;
|
|
1452
|
+
clip-path: inset(50%);
|
|
1453
|
+
white-space: nowrap;
|
|
1454
|
+
"
|
|
1455
|
+
>
|
|
1456
|
+
<option value=""></option>
|
|
1457
|
+
@for (held of selection(); track $index) {
|
|
1458
|
+
<option [value]="held" selected>{{ labelFor(held) ?? held }}</option>
|
|
1459
|
+
}
|
|
1460
|
+
</select>
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
<!--
|
|
1464
|
+
The rows the popup holds, stamped into the listbox wherever the listbox
|
|
1465
|
+
is: the surface itself without a search field, and the list part one
|
|
1466
|
+
element in with one. They are a template rather than markup written twice
|
|
1467
|
+
because ng-content may be projected into exactly one place, and the
|
|
1468
|
+
options are that one place.
|
|
1469
|
+
-->
|
|
1470
|
+
<ng-template #rows>
|
|
1471
|
+
<!--
|
|
1472
|
+
Everything that is chosen, at the top of the popup (SL10). The
|
|
1473
|
+
control holds one line, so twelve values are three chips and a
|
|
1474
|
+
count; here they are all of them, and the band scrolls at about two
|
|
1475
|
+
rows of its own rather than growing the surface.
|
|
1476
|
+
|
|
1477
|
+
It is aria-hidden, and carries no remove control. The reason is
|
|
1478
|
+
keyboard reach: without a search field focus never enters this
|
|
1479
|
+
layer at all, and with one the layer spends its single Tab on
|
|
1480
|
+
commiting and leaving the control — so a widget in the band would
|
|
1481
|
+
answer the pointer and nothing else. What it says is already said,
|
|
1482
|
+
by the trigger's own name and by each option's aria-selected.
|
|
1483
|
+
-->
|
|
1484
|
+
@if (resolvedMultiple() && selection().length > 0) {
|
|
1485
|
+
<div data-part="chosen" aria-hidden="true">
|
|
1486
|
+
@for (value of selection(); track value) {
|
|
1487
|
+
<span data-ui="tag" data-part="root" data-size="sm" data-variant="soft">
|
|
1488
|
+
<span data-part="body">
|
|
1489
|
+
<span data-part="label">{{ labelFor(value) ?? value }}</span>
|
|
1490
|
+
</span>
|
|
1491
|
+
</span>
|
|
1492
|
+
}
|
|
1493
|
+
</div>
|
|
1494
|
+
}
|
|
1495
|
+
<ng-content />
|
|
1496
|
+
@if (loading()) {
|
|
1497
|
+
<!--
|
|
1498
|
+
The wait, as the shape of the list that is coming: three rows the
|
|
1499
|
+
height of an option, drawn by the skeleton sheet (SL6/CB5). Hidden
|
|
1500
|
+
assistive technology — the status row is the live region.
|
|
1501
|
+
-->
|
|
1502
|
+
<div data-part="placeholder" aria-hidden="true">
|
|
1503
|
+
@for (row of [0, 1, 2]; track row) {
|
|
1504
|
+
<div>
|
|
1505
|
+
<span data-ui="skeleton" data-part="root" data-shape="text" data-loading></span>
|
|
1506
|
+
</div>
|
|
1507
|
+
}
|
|
1508
|
+
</div>
|
|
1509
|
+
}
|
|
1510
|
+
@if (!loading() && empty()) {
|
|
1511
|
+
<div data-part="empty">{{ t('empty') }}</div>
|
|
1512
|
+
}
|
|
1513
|
+
@if (loading() || resolvedSearch()) {
|
|
1514
|
+
<!--
|
|
1515
|
+
The live region. While an answer is travelling it says so; while
|
|
1516
|
+
the reader is searching it says how many options survived the
|
|
1517
|
+
query, which is what docs/component-features.md §6 asks of a
|
|
1518
|
+
filtered collection. An empty row draws nothing.
|
|
1519
|
+
-->
|
|
1520
|
+
<div
|
|
1521
|
+
data-part="status"
|
|
1522
|
+
role="status"
|
|
1523
|
+
aria-live="polite"
|
|
1524
|
+
[attr.data-loading]="loading() ? '' : null"
|
|
1525
|
+
>
|
|
1526
|
+
{{ statusMessage() }}
|
|
1527
|
+
</div>
|
|
1528
|
+
}
|
|
1529
|
+
</ng-template>
|
|
1530
|
+
|
|
1531
|
+
<ng-template #layer>
|
|
1532
|
+
<div
|
|
1533
|
+
data-ui="select"
|
|
1534
|
+
data-part="positioner"
|
|
1535
|
+
[attr.data-align]="resolvedAlign()"
|
|
1536
|
+
[attr.data-size]="resolvedSize()"
|
|
1537
|
+
[attr.data-width]="resolvedWidth()"
|
|
1538
|
+
[attr.data-open]="isOpen() ? '' : null"
|
|
1539
|
+
[attr.inert]="isOpen() ? null : ''"
|
|
1540
|
+
>
|
|
1541
|
+
<div
|
|
1542
|
+
#surface
|
|
1543
|
+
data-part="content"
|
|
1544
|
+
[attr.role]="resolvedSearch() ? 'dialog' : 'listbox'"
|
|
1545
|
+
[attr.data-search]="resolvedSearch() ? '' : null"
|
|
1546
|
+
[id]="contentId"
|
|
1547
|
+
[attr.aria-labelledby]="ariaLabel() === undefined ? triggerId : null"
|
|
1548
|
+
[attr.aria-label]="ariaLabel() ?? null"
|
|
1549
|
+
[attr.aria-multiselectable]="resolvedSearch() || !resolvedMultiple() ? null : true"
|
|
1550
|
+
[attr.aria-busy]="resolvedSearch() || !loading() ? null : true"
|
|
1551
|
+
[attr.data-loading]="loading() ? '' : null"
|
|
1552
|
+
>
|
|
1553
|
+
<!--
|
|
1554
|
+
The field the reader filters with, and the listbox one element in.
|
|
1555
|
+
The combobox pattern lists the four roles a popup may carry and a
|
|
1556
|
+
popup holding a text field is a dialog, so the listbox moves inside
|
|
1557
|
+
it: a listbox holds options and groups, and a text field is neither.
|
|
1558
|
+
-->
|
|
1559
|
+
@if (resolvedSearch()) {
|
|
1560
|
+
<div data-part="search">
|
|
1561
|
+
<span data-part="search-icon" aria-hidden="true"
|
|
1562
|
+
><span slIcon><svg slGlyph name="search"></svg></span
|
|
1563
|
+
></span>
|
|
1564
|
+
<input
|
|
1565
|
+
#search
|
|
1566
|
+
type="text"
|
|
1567
|
+
role="combobox"
|
|
1568
|
+
data-part="search-input"
|
|
1569
|
+
autocomplete="off"
|
|
1570
|
+
spellcheck="false"
|
|
1571
|
+
aria-expanded="true"
|
|
1572
|
+
aria-autocomplete="list"
|
|
1573
|
+
[id]="searchId"
|
|
1574
|
+
[attr.aria-controls]="listId"
|
|
1575
|
+
[attr.aria-activedescendant]="activeDescendant()"
|
|
1576
|
+
[attr.aria-label]="t('search')"
|
|
1577
|
+
[placeholder]="t('searchPlaceholder')"
|
|
1578
|
+
[value]="query()"
|
|
1579
|
+
(input)="onSearchInput($event)"
|
|
1580
|
+
(keydown)="onSearchKeyDown($event)"
|
|
1581
|
+
/>
|
|
1582
|
+
</div>
|
|
1583
|
+
}
|
|
1584
|
+
@if (resolvedSearch()) {
|
|
1585
|
+
<div
|
|
1586
|
+
data-part="list"
|
|
1587
|
+
role="listbox"
|
|
1588
|
+
[id]="listId"
|
|
1589
|
+
[attr.aria-labelledby]="triggerId"
|
|
1590
|
+
[attr.aria-multiselectable]="resolvedMultiple() ? true : null"
|
|
1591
|
+
[attr.aria-busy]="loading() ? true : null"
|
|
1592
|
+
>
|
|
1593
|
+
<ng-container [ngTemplateOutlet]="rows" />
|
|
1594
|
+
</div>
|
|
1595
|
+
} @else {
|
|
1596
|
+
<ng-container [ngTemplateOutlet]="rows" />
|
|
1597
|
+
}
|
|
1598
|
+
</div>
|
|
1599
|
+
</div>
|
|
1600
|
+
</ng-template>
|
|
1601
|
+
`, styles: ["@layer slotted.components{[data-ui=select][data-part=root]{--_font-size: var(--slotted-control-font-size-md, 13px);--_height: var(--slotted-control-height-md, 34px);--_padding-inline: var(--slotted-control-padding-inline-md, 13px);--_gap: var(--slotted-control-gap-md, 8px);--_icon-floor: var(--slotted-select-icon-size-min, 14px);--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-md, 16px));--_inner-size: var(--slotted-control-inner-size-md, 24px);--_action-size: var( --slotted-select-action-size, min(calc(var(--_icon-size) + 2 * var(--slotted-space-2, .25rem)), var(--_inner-size)) );align-items:center;background-color:var(--slotted-select-background, var(--slotted-control-surface, Field));border:var(--slotted-control-border-width, 1px) solid var(--slotted-select-border-color, var(--slotted-control-border-color, ButtonBorder));border-radius:var(--slotted-select-radius, var(--slotted-control-radius, 4px));box-shadow:var(--slotted-select-shadow, var(--slotted-control-shadow, none));box-sizing:border-box;color:var(--slotted-select-color, var(--slotted-text, CanvasText));column-gap:var(--_gap);display:grid;font-family:var(--slotted-control-font-family, system-ui, sans-serif);font-size:var(--_font-size);grid-template-columns:minmax(0,1fr) auto;inline-size:100%;min-inline-size:0;min-block-size:var(--_height);position:relative;transition:background-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),border-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),box-shadow var(--slotted-control-transition-duration) var(--slotted-control-transition-easing)}[data-ui=select][data-part=root]:has(>[data-part=clear]){grid-template-columns:minmax(0,1fr) auto auto}[data-ui=select][data-part=root]:not([data-full-width]){inline-size:auto}[data-ui=select]>[data-part=trigger]{align-items:center;appearance:none;background-color:transparent;border:0;box-sizing:border-box;color:inherit;cursor:pointer;display:flex;font:inherit;gap:var(--_gap);grid-area:1 / 1 / 2 / -1;margin-block:calc(var(--slotted-control-border-width, 1px) * -1);min-block-size:var(--_height);min-inline-size:0;outline:none;padding-block:0;padding-inline-start:var(--_padding-inline);padding-inline-end:calc(var(--_padding-inline) + var(--_icon-size) + var(--_gap));text-align:start;touch-action:manipulation;-webkit-tap-highlight-color:transparent}[data-ui=select][data-part=root]:has(>[data-part=clear])>[data-part=trigger]{padding-inline-end:calc(var(--_padding-inline) + var(--_icon-size) + var(--_gap) + var(--_action-size) + var(--_gap))}[data-ui=select] [data-part=value]{flex:1 1 auto;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}[data-ui=select] [data-part=value][data-placeholder]{color:var(--slotted-select-placeholder-color, var(--slotted-text-muted, GrayText))}[data-ui=select] [data-part=value][data-unmatched]{font-variant-numeric:tabular-nums}[data-ui=select][data-part=root]>[data-part=tags]{align-items:center;display:flex;gap:var(--slotted-space-2, .25rem);grid-area:1 / 1 / 2 / 2;margin-inline-start:var(--_padding-inline);min-block-size:var(--slotted-target-min, 24px);min-inline-size:0;overflow:hidden;pointer-events:none}[data-ui=select]>[data-part=tags]>*{pointer-events:auto;position:relative}[data-ui=select]>[data-part=tags]>[data-overflow]{flex:none}[data-ui=select] [data-part=summary]{display:block;overflow:hidden;text-overflow:ellipsis;unicode-bidi:plaintext;white-space:nowrap}[data-ui=select][data-part=root]:not([data-narrow]) [data-part=summary]{block-size:1px;clip-path:inset(50%);inline-size:1px;overflow:hidden;white-space:nowrap}[data-ui=select][data-part=root][data-narrow]>[data-part=tags]{display:none}[data-ui=select]>[data-part=arrow]{--slotted-icon-size: var(--_icon-size);align-items:center;block-size:var(--_icon-size);color:var(--slotted-select-arrow-color, var(--slotted-text-muted, GrayText));display:flex;grid-area:1 / -2 / 2 / -1;inline-size:var(--_icon-size);justify-content:center;margin-inline-end:var(--_padding-inline);pointer-events:none}[data-ui=select]>[data-part=arrow]>[data-ui=icon]{transition:rotate var(--slotted-control-transition-duration) var(--slotted-control-transition-easing)}[data-ui=select][data-open]>[data-part=arrow]>[data-ui=icon]{rotate:180deg}[data-ui=select]>[data-part=busy]{--slotted-spinner-size: var(--_icon-size);color:var(--slotted-select-arrow-color, var(--slotted-text-muted, GrayText));grid-area:1 / -2 / 2 / -1;margin-inline-end:var(--_padding-inline);pointer-events:none}[data-ui=select]>[data-part=clear]{align-items:center;appearance:none;background-color:transparent;block-size:var(--_action-size);border:0;border-radius:var(--slotted-select-radius, var(--slotted-control-radius, 4px));color:var(--slotted-select-action-color, var(--slotted-text-muted, GrayText));cursor:pointer;display:inline-flex;grid-area:1 / 2 / 2 / 3;inline-size:var(--_action-size);justify-content:center;margin-inline:calc((var(--_icon-size) - var(--_action-size)) / 2);padding:0;position:relative;touch-action:manipulation;transition:background-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing);-webkit-tap-highlight-color:transparent}[data-ui=select]>[data-part=clear]:after{content:\"\";inset:min(0px,calc((100% - var(--slotted-target-min, 24px)) / 2));position:absolute}@media(pointer:coarse){[data-ui=select]>[data-part=clear]:after{inset:min(0px,calc((100% - var(--slotted-target-comfortable, 44px)) / 2));inset-inline-end:0}}[data-ui=select]>[data-part=clear]{--slotted-icon-size: var(--_icon-size)}[data-ui=select][data-part=root][data-size=sm]{--_font-size: var(--slotted-control-font-size-sm, 12px);--_height: var(--slotted-control-height-sm, 30px);--_padding-inline: var(--slotted-control-padding-inline-sm, 10px);--_gap: var(--slotted-control-gap-sm, 6px);--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-sm, 14px));--_inner-size: var(--slotted-control-inner-size-sm, 22px)}[data-ui=select][data-part=root][data-size=md]{--_font-size: var(--slotted-control-font-size-md, 13px);--_height: var(--slotted-control-height-md, 34px);--_padding-inline: var(--slotted-control-padding-inline-md, 13px);--_gap: var(--slotted-control-gap-md, 8px);--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-md, 16px));--_inner-size: var(--slotted-control-inner-size-md, 24px)}[data-ui=select][data-part=root][data-size=lg]{--_font-size: var(--slotted-control-font-size-lg, 14px);--_height: var(--slotted-control-height-lg, 38px);--_padding-inline: var(--slotted-control-padding-inline-lg, 16px);--_gap: var(--slotted-control-gap-lg, 8px);--_icon-size: max(var(--_icon-floor), var(--slotted-control-icon-size-lg, 18px));--_inner-size: var(--slotted-control-inner-size-lg, 28px)}[data-ui=select][data-part=root][data-variant=subtle]{background-color:var( --slotted-select-subtle-background, var(--slotted-surface-sunken, Canvas) );border-color:var( --slotted-select-subtle-border-color, var(--slotted-border-subtle, ButtonBorder) )}[data-ui=select][data-part=root][data-variant=plain]{background-color:transparent;border-color:transparent;border-radius:var(--slotted-radius-none, 0px);box-shadow:none}@media(forced-colors:active){[data-ui=select][data-part=root][data-variant=plain]{border-color:ButtonBorder}}[data-ui=select][data-part=root]:hover:not([data-disabled]):not([data-readonly]):not([data-invalid]){border-color:var(--slotted-select-hover-border-color, var(--slotted-tone-accent-border))}[data-ui=select][data-part=root][data-variant=subtle]:hover:not([data-disabled]):not([data-readonly]):not([data-invalid]){background-color:var( --slotted-select-subtle-hover-background, var(--slotted-tone-secondary-subtle-hover) )}[data-ui=select][data-part=root][data-variant=plain]:hover:not([data-disabled]):not([data-readonly]):not([data-invalid]){background-color:var( --slotted-select-plain-hover-background, var(--slotted-tone-secondary-subtle-hover) );border-color:transparent}[data-ui=select][data-part=root]:has(>[data-part=trigger]:focus-visible){box-shadow:var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px) var(--slotted-focus-ring-color, Highlight);outline:var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);outline-offset:var(--slotted-focus-ring-offset, 2px)}[data-ui=select][data-part=root][data-variant=plain]:has(>[data-part=trigger]:focus-visible){box-shadow:none;outline-offset:calc(var(--slotted-focus-ring-offset, 2px) * -1)}[data-ui=select][data-part=root][data-open]:not([data-disabled]){border-color:var(--slotted-select-open-border-color, var(--slotted-tone-accent-border))}[data-ui=select][data-part=root][data-invalid]{--slotted-focus-ring-color: var( --slotted-select-invalid-focus-ring-color, var(--slotted-focus-ring-color-invalid, Highlight) );--_invalid-edge-width: var( --slotted-select-invalid-edge-width, var(--slotted-control-invalid-edge-width, 1px) );--_invalid-edge-color: var( --slotted-select-invalid-border-color, var(--slotted-tone-danger-border) );--_invalid-edge: inset 0 0 0 var(--_invalid-edge-width) var(--_invalid-edge-color);border-color:var(--slotted-select-invalid-border-color, var(--slotted-tone-danger-border));box-shadow:var(--_invalid-edge)}[data-ui=select][data-part=root][data-invalid]:has(>[data-part=trigger]:focus-visible){box-shadow:var(--_invalid-edge),var(--slotted-control-shadow-focus-geometry, 0 1px 4px -1px) var(--slotted-focus-ring-color, Highlight)}[data-ui=select][data-part=root][data-variant=plain][data-invalid]:has(>[data-part=trigger]:focus-visible){box-shadow:inset 0 0 0 calc(var(--slotted-focus-ring-offset, 2px) - var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width)) var(--_invalid-edge-color)}@media(forced-colors:active){[data-ui=select][data-part=root][data-invalid]{outline:var(--_invalid-edge-width) solid CanvasText;outline-offset:calc(-1 * (var(--slotted-control-border-width, 1px) + var(--_invalid-edge-width)))}[data-ui=select][data-part=root][data-invalid]:has(>[data-part=trigger]:focus-visible){outline:calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double var(--slotted-focus-ring-color, Highlight);outline-offset:var(--slotted-focus-ring-offset, 2px)}[data-ui=select][data-part=root][data-variant=plain][data-invalid]:has(>[data-part=trigger]:focus-visible){outline:calc(var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)) double var(--slotted-focus-ring-color, Highlight);outline-offset:calc(-1 * (var(--slotted-focus-ring-width, 2px) + var(--_invalid-edge-width)))}}[data-ui=select][data-part=root][data-readonly]{background-color:var( --slotted-select-readonly-background, var(--slotted-tone-secondary-subtle-hover) )}[data-ui=select][data-part=root][data-readonly] [data-part=arrow]{opacity:.5}[data-ui=select][data-part=root][data-disabled],[data-ui=select][data-part=root]:has(>[data-part=trigger]:disabled){background-color:var(--slotted-select-disabled-background, var(--slotted-disabled-background));border-color:var(--slotted-select-disabled-border-color, var(--slotted-disabled-border));box-shadow:none;color:var(--slotted-select-disabled-color, var(--slotted-disabled-foreground))}[data-ui=select][data-part=root][data-disabled]>[data-part=trigger],[data-ui=select][data-part=root]>[data-part=trigger]:disabled{cursor:not-allowed}[data-ui=select]>[data-part=clear]:hover:not(:disabled):not([data-disabled]){background-color:var( --slotted-select-action-hover-background, var(--slotted-tone-secondary-subtle-hover) )}[data-ui=select]>[data-part=clear]:active:not(:disabled):not([data-disabled]){background-color:var( --slotted-select-action-active-background, var(--slotted-tone-secondary-subtle-active) )}[data-ui=select]>[data-part=clear]:focus-visible{outline:var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);outline-offset:calc(var(--slotted-focus-ring-offset, 2px) * -1)}[data-ui=select][data-part=positioner]{--_surface: var(--slotted-select-surface, var(--slotted-surface-raised, #ffffff));--_text: var(--slotted-select-content-text, var(--slotted-text, #0f172a));--_muted: var(--slotted-select-content-text-muted, var(--slotted-text-muted, #5b6b7f));--_border-color: var( --slotted-select-content-border-color, var(--slotted-border-subtle, #e2e8f0) );--_border-width: var(--slotted-border-width-thin, 1px);--_radius: var(--slotted-select-content-radius, var(--slotted-radius-lg, 8px));--_shadow: var(--slotted-select-content-shadow, var(--slotted-shadow-md));--_highlight: var(--slotted-select-highlight, var(--slotted-tone-secondary-subtle-active));--_highlight-active: var(--slotted-select-highlight-active, var(--slotted-tone-accent-surface));--_selected-color: var(--slotted-select-selected-color, var(--slotted-tone-accent-text));--_inset-block: var(--slotted-select-content-padding-block, var(--slotted-space-2, .25rem));--_inset-inline: var(--slotted-select-content-padding-inline, var(--slotted-space-2, .25rem));--_item-inset: var(--slotted-control-padding-inline-md, .8125rem);--_item-height: var(--slotted-control-height-md, 34px);--_item-radius: var(--slotted-select-item-radius, var(--slotted-control-radius));--_content-font-size: var(--slotted-control-font-size-md, 13px);--_secondary-font-size: var(--slotted-control-font-size-sm, 12px);--_content-icon-size: var(--slotted-control-icon-size-md, 16px);--_column-gap: var(--slotted-control-gap-md, .5rem);--_measure: var(--slotted-select-measure, 24rem);position:absolute;inset-block-start:0;z-index:calc(var(--slotted-z-index-popover, 1100) + var(--slotted-layer-depth, 0));isolation:isolate;box-sizing:border-box;pointer-events:none;opacity:0;--_enter-distance: var(--slotted-space-2, .25rem);translate:0 calc(-1 * var(--_enter-distance));transition:opacity var(--slotted-duration-short) var(--slotted-easing-exit),translate var(--slotted-duration-short) var(--slotted-easing-exit)}[data-ui=select][data-part=positioner][data-side=top]{translate:0 var(--_enter-distance)}[data-ui=select][data-part=positioner]:is([data-side=left],[data-side=right]){translate:0 0}[data-ui=select][data-part=positioner][data-open]{opacity:1;translate:0 0;transition:none}[data-ui=select][data-part=positioner][data-open][data-positioned]{animation:slotted-select-enter-down var(--slotted-duration-medium) var(--slotted-easing-enter)}[data-ui=select][data-part=positioner][data-open][data-positioned][data-side=top]{animation-name:slotted-select-enter-up}[data-ui=select][data-part=positioner][data-open][data-positioned]:is([data-side=left],[data-side=right]){animation-name:slotted-select-fade}@keyframes slotted-select-enter-down{0%{opacity:0;translate:0 calc(-1 * var(--_enter-distance))}}@keyframes slotted-select-enter-up{0%{opacity:0;translate:0 var(--_enter-distance)}}@keyframes slotted-select-fade{0%{opacity:0}}@media(prefers-reduced-motion:reduce){[data-ui=select][data-part=positioner],[data-ui=select][data-part=positioner][data-side=top],[data-ui=select][data-part=positioner][data-side=left],[data-ui=select][data-part=positioner][data-side=right]{translate:0 0;transition:opacity var(--slotted-duration-short) var(--slotted-easing-exit)}[data-ui=select][data-part=positioner][data-open][data-positioned],[data-ui=select][data-part=positioner][data-open][data-positioned][data-side=top],[data-ui=select][data-part=positioner][data-open][data-positioned][data-side=left],[data-ui=select][data-part=positioner][data-open][data-positioned][data-side=right]{animation-name:slotted-select-fade}}[data-ui=select][data-part=positioner][data-detached]{visibility:hidden}[data-ui=select][data-part=positioner][data-width=anchor]{inline-size:var(--slotted-positioner-anchor-width, auto)}[data-ui=select][data-part=positioner][data-width=content]{inline-size:max-content;max-inline-size:min(var(--_measure),var(--slotted-positioner-available-width, 100vw));min-inline-size:var(--slotted-positioner-anchor-width, auto)}[data-ui=select][data-part=positioner][data-size=sm]{--_item-inset: var(--slotted-control-padding-inline-sm, .625rem);--_item-height: var(--slotted-control-height-sm, 30px);--_content-font-size: var(--slotted-control-font-size-sm, 12px);--_secondary-font-size: var(--slotted-font-size-xs, .75rem);--_content-icon-size: var(--slotted-control-icon-size-sm, 14px);--_column-gap: var(--slotted-control-gap-sm, .375rem)}[data-ui=select][data-part=positioner][data-size=lg]{--_item-inset: var(--slotted-control-padding-inline-lg, 1rem);--_item-height: var(--slotted-control-height-lg, 38px);--_content-font-size: var(--slotted-control-font-size-lg, 14px);--_secondary-font-size: var(--slotted-control-font-size-sm, 12px);--_content-icon-size: var(--slotted-control-icon-size-lg, 18px);--_column-gap: var(--slotted-control-gap-lg, .5rem)}[data-ui=select]>[data-part=content]{background:var(--_surface);border:var(--_border-width) solid var(--_border-color);border-radius:var(--_radius);box-shadow:var(--_shadow);box-sizing:border-box;color:var(--_text);font-family:var(--slotted-font-family-sans);font-size:var(--_content-font-size);max-block-size:calc(var(--slotted-positioner-available-height, 100vh) - var(--slotted-space-5, .75rem));outline:none;pointer-events:auto}[data-ui=select]>[data-part=content]:not([data-search]),[data-ui=select] [data-part=list]{display:grid;grid-template-columns:auto minmax(0,1fr) auto;overflow-y:auto;overscroll-behavior:contain;padding-block:var(--_inset-block);padding-inline:var(--_inset-inline)}[data-ui=select]>[data-part=content][data-search]{display:flex;flex-direction:column;padding:0}[data-ui=select] [data-part=list]{flex:1 1 auto;min-block-size:0}[data-ui=select] [data-part=search]{align-items:center;border-block-end:var(--_border-width) solid var(--_border-color);box-sizing:border-box;display:flex;flex:0 0 auto;gap:var(--_column-gap);min-block-size:var(--_item-height);padding-block:var(--slotted-space-2, .25rem);padding-inline:calc(var(--_inset-inline) + var(--_item-inset))}[data-ui=select] [data-part=search-icon]{--slotted-icon-size: var(--_content-icon-size);align-items:center;block-size:var(--_content-icon-size);color:var(--slotted-select-search-icon-color, var(--_muted));display:flex;flex:0 0 auto;inline-size:var(--_content-icon-size);justify-content:center;pointer-events:none}[data-ui=select] [data-part=search-input]{background-color:transparent;border:0;color:inherit;flex:1 1 auto;font:inherit;min-inline-size:0;outline:none;padding:0;text-overflow:ellipsis}[data-ui=select] [data-part=search-input]::placeholder{color:var(--slotted-select-placeholder-color, var(--_muted));text-overflow:ellipsis}[data-ui=select] [data-part=chosen]{background:var(--_surface);border-block-end:var(--_border-width) solid var(--_border-color);box-sizing:border-box;display:flex;flex-wrap:wrap;gap:var(--slotted-space-2, .25rem);grid-column:1 / -1;inset-block-start:calc(-1 * var(--_inset-block));margin-block:calc(-1 * var(--_inset-block)) var(--_inset-block);margin-inline:calc(-1 * var(--_inset-inline));max-block-size:calc(2 * var(--slotted-target-min, 24px) + var(--slotted-space-2, .25rem) + var(--_inset-block));min-inline-size:0;overflow-y:auto;overscroll-behavior:contain;padding-block:var(--_inset-block);padding-inline:var(--_inset-inline);position:sticky;z-index:1}[data-ui=select]>[data-part=content]:focus-visible{outline:none}[data-ui=select] [data-part=group]{display:grid;grid-column:1 / -1;grid-template-columns:subgrid}[data-ui=select] [data-part=item][hidden],[data-ui=select] [data-part=group][hidden]{display:none}[data-ui=select] [data-part=group-label]{color:var(--_muted);font-size:var(--_secondary-font-size);font-weight:var(--slotted-font-weight-semibold, 600);grid-column:1 / -1;line-height:var(--slotted-line-height-sm, 1.45);padding-block:var(--slotted-space-2, .25rem);padding-inline:var(--_item-inset)}[data-ui=select] [data-part=item]{align-content:center;border-radius:var(--_item-radius);box-sizing:border-box;cursor:pointer;display:grid;grid-column:1 / -1;grid-template-columns:subgrid;line-height:var(--slotted-line-height-md, 1.5);min-block-size:var(--_item-height);padding-block:var(--slotted-space-2, .25rem);padding-inline:var(--_item-inset);row-gap:var(--slotted-space-1, .125rem);-webkit-user-select:none;user-select:none;transition:background-color var(--slotted-control-transition-duration, var(--slotted-duration-short)) var(--slotted-control-transition-easing, var(--slotted-easing-standard)),color var(--slotted-control-transition-duration, var(--slotted-duration-short)) var(--slotted-control-transition-easing, var(--slotted-easing-standard))}[data-ui=select] [data-part=item][data-current]{background-color:var(--_highlight);box-shadow:inset 0 0 0 var(--slotted-border-width-thin, 1px) var(--slotted-select-highlight-ring, var(--slotted-tone-accent-border))}[data-ui=select] [data-part=item]:not([data-disabled]):active{background-color:var(--_highlight-active)}[data-ui=select] [data-part=item][data-selected]{color:var(--_selected-color)}[data-ui=select] [data-part=item][data-selected]+[data-part=item][data-selected]{border-start-end-radius:0;border-start-start-radius:0}[data-ui=select] [data-part=item][data-selected]:has(+[data-part=item][data-selected]){border-end-end-radius:0;border-end-start-radius:0}[data-ui=select] [data-part=item][data-selected]>[data-part=label]{font-weight:var(--slotted-font-weight-medium, 500)}[data-ui=select] [data-part=item][data-disabled]{color:var(--slotted-disabled-foreground, #64748b);cursor:not-allowed}[data-ui=select] [data-part=item][data-disabled][data-current]{box-shadow:inset 0 0 0 var(--slotted-border-width-thin, 1px) var(--slotted-disabled-border, #cbd5e1);color:var(--slotted-disabled-foreground, #64748b)}[data-ui=select] :is([data-part=indicator],[data-part=icon]){block-size:1lh}[data-ui=select] [data-part=icon]{--slotted-icon-size: var(--_content-icon-size);align-items:center;display:flex;grid-column:1;grid-row:1;inline-size:var(--_content-icon-size);justify-content:center;justify-self:center;margin-inline-end:var(--_column-gap)}[data-ui=select] [data-part=item]>[data-part=label]{grid-column:2;grid-row:1;min-inline-size:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;overflow-wrap:anywhere}[data-ui=select] [data-part=description]{color:var(--_muted);font-size:var(--_secondary-font-size);grid-column:2;grid-row:2;line-height:var(--slotted-line-height-sm, 1.45);min-inline-size:0;overflow-wrap:anywhere}[data-ui=select] [data-part=item][data-disabled]>[data-part=description]{color:inherit}[data-ui=select] [data-part=indicator]{--slotted-icon-size: var(--_content-icon-size);align-items:center;display:flex;grid-column:3;grid-row:1;inline-size:var(--_content-icon-size);justify-content:center;justify-self:end;margin-inline-start:var(--_column-gap);opacity:0;transition:opacity var(--slotted-duration-short) var(--slotted-easing-standard)}[data-ui=select] [data-part=item][data-selected]>[data-part=indicator]{opacity:1}[data-ui=select] [data-part=separator]{background-color:var(--slotted-select-separator-color, var(--_border-color));block-size:var(--_border-width);border:0;grid-column:1 / -1;margin-block:var(--slotted-space-2, .25rem);margin-inline:0}[data-ui=select] :is([data-part=empty],[data-part=status]){color:var(--_muted);unicode-bidi:plaintext;grid-column:1 / -1;min-inline-size:min(12rem,100%);padding-block:var(--slotted-space-5, .75rem);padding-inline:var(--_item-inset);text-align:center}[data-ui=select] [data-part=status]:empty{display:none}[data-ui=select] [data-part=placeholder]{display:grid;grid-column:1 / -1;padding-block:var(--slotted-space-2, .25rem);padding-inline:var(--_item-inset)}[data-ui=select] [data-part=placeholder]>[data-ui=skeleton]{align-self:center}[data-ui=select] [data-part=placeholder]>*{align-items:center;display:flex;min-block-size:var(--_item-height)}[data-ui=select] [data-part=placeholder]>:nth-child(2) [data-ui=skeleton]{inline-size:78%}[data-ui=select] [data-part=placeholder]>:nth-child(3) [data-ui=skeleton]{inline-size:56%}[data-ui=select]>[data-part=content][data-loading]{cursor:progress}@media(forced-colors:active){[data-ui=select] [data-part=item][data-current]{background-color:Highlight;color:HighlightText;forced-color-adjust:none}[data-ui=select] [data-part=item][data-disabled][data-current]{background-color:Highlight;color:GrayText}}}\n", "@layer slotted.components{[data-ui=tag][data-part=root]{--_solid: var(--slotted-tone-secondary-solid-hover);--_solid-hover: var(--slotted-tone-secondary-solid-active);--_solid-active: var(--slotted-tone-secondary-solid-active);--_on-solid: var(--slotted-tone-secondary-on-solid);--_surface: var(--slotted-tone-secondary-surface);--_subtle-hover: var(--slotted-tone-secondary-subtle-hover);--_subtle-active: var(--slotted-tone-secondary-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-secondary-border));--_text: var(--slotted-tone-secondary-text);--_edge: var(--_solid);--_font-size: var(--slotted-control-font-size-md, 13px);--_icon-size: var(--slotted-control-icon-size-sm, 14px);--_inner-size: var(--slotted-control-inner-size-sm, 22px);--_inset-block: var(--slotted-tag-inset-block, var(--slotted-space-2, .25rem));--_inset-inline: var(--slotted-space-4, .5rem);--_gap: var(--slotted-space-2, .25rem);--_line-height: var(--slotted-line-height-xs, 1.4);--_edge-width: var(--slotted-tag-border-width, var(--slotted-border-width-thin, 1px));--_radius: var(--slotted-radius-full, 9999px);--_inner-radius: max(0px, calc(var(--_radius) - var(--_edge-width)));--_own-size: calc( var(--_font-size) * var(--_line-height) + 2 * var(--_inset-block) + 2 * var(--_edge-width) );--_block-size: var(--slotted-control-inner-size, var(--_own-size));--_line: min( calc(var(--_font-size) * var(--_line-height)), calc(var(--_block-size) - 2 * var(--_edge-width)) );--_inset: max(0px, calc((var(--_block-size) - var(--_line) - 2 * var(--_edge-width)) / 2));align-items:stretch;border:var(--_edge-width) solid transparent;border-radius:var(--_radius);box-sizing:border-box;display:inline-flex;font-family:var(--slotted-tag-font-family, var(--slotted-control-font-family, sans-serif));font-size:var(--_font-size);font-weight:var(--slotted-tag-font-weight, var(--slotted-font-weight-medium, 500));line-height:var(--_line);max-inline-size:100%;min-block-size:var(--_block-size);vertical-align:middle;white-space:nowrap}[data-ui=tag][data-part=root][hidden]{display:none}[data-ui=tag][data-part=root][data-tone=secondary]{--_edge: var(--_border)}[data-ui=tag][data-part=root][data-tone=accent]{--_solid: var(--slotted-tone-accent-solid);--_solid-hover: var(--slotted-tone-accent-solid-hover);--_solid-active: var(--slotted-tone-accent-solid-active);--_on-solid: var(--slotted-tone-accent-on-solid);--_surface: var(--slotted-tone-accent-surface);--_subtle-hover: var(--slotted-tone-accent-subtle-hover);--_subtle-active: var(--slotted-tone-accent-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-accent-border));--_text: var(--slotted-tone-accent-text)}[data-ui=tag][data-part=root][data-tone=success]{--_solid: var(--slotted-tone-success-solid);--_solid-hover: var(--slotted-tone-success-solid-hover);--_solid-active: var(--slotted-tone-success-solid-active);--_on-solid: var(--slotted-tone-success-on-solid);--_surface: var(--slotted-tone-success-surface);--_subtle-hover: var(--slotted-tone-success-subtle-hover);--_subtle-active: var(--slotted-tone-success-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-success-border));--_text: var(--slotted-tone-success-text)}[data-ui=tag][data-part=root][data-tone=warning]{--_solid: var(--slotted-tone-warning-solid);--_solid-hover: var(--slotted-tone-warning-solid-hover);--_solid-active: var(--slotted-tone-warning-solid-active);--_on-solid: var(--slotted-tone-warning-on-solid);--_surface: var(--slotted-tone-warning-surface);--_subtle-hover: var(--slotted-tone-warning-subtle-hover);--_subtle-active: var(--slotted-tone-warning-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-warning-border));--_text: var(--slotted-tone-warning-text)}[data-ui=tag][data-part=root][data-tone=danger]{--_solid: var(--slotted-tone-danger-solid);--_solid-hover: var(--slotted-tone-danger-solid-hover);--_solid-active: var(--slotted-tone-danger-solid-active);--_on-solid: var(--slotted-tone-danger-on-solid);--_surface: var(--slotted-tone-danger-surface);--_subtle-hover: var(--slotted-tone-danger-subtle-hover);--_subtle-active: var(--slotted-tone-danger-subtle-active);--_border: var(--slotted-tag-border-color, var(--slotted-tone-danger-border));--_text: var(--slotted-tone-danger-text)}[data-ui=tag][data-part=root][data-variant=solid]{background-color:var(--_solid, ButtonFace);border-color:var(--_edge, ButtonFace);color:var(--_on-solid, ButtonText)}[data-ui=tag][data-part=root][data-variant=soft]{background-color:var(--_surface, ButtonFace);border-color:var(--_border, ButtonBorder);color:var(--_text, ButtonText)}[data-ui=tag][data-part=root][data-variant=outline]{background-color:transparent;border-color:var(--_border, ButtonBorder);color:var(--_text, ButtonText)}[data-ui=tag][data-part=root][data-size=sm]{--_font-size: var(--slotted-control-font-size-sm, 12px);--_inset-block: var(--slotted-tag-inset-block, var(--slotted-space-1, .125rem));--_inset-inline: var(--slotted-space-3, .375rem)}[data-ui=tag][data-part=root][data-size=lg]{--_font-size: var(--slotted-control-font-size-lg, 14px);--_icon-size: var(--slotted-control-icon-size-md, 16px);--_inner-size: var(--slotted-control-inner-size-md, 24px);--_inset-block: var(--slotted-tag-inset-block, var(--slotted-space-3, .375rem));--_inset-inline: var(--slotted-space-5, .75rem);--_gap: var(--slotted-space-3, .375rem)}[data-ui=tag][data-part=root][data-shape=square]{--_radius: var(--slotted-radius-sm, 4px)}[data-ui=tag] [data-part=body]{align-items:center;background-color:transparent;border:0;border-end-start-radius:var(--_inner-radius);border-start-start-radius:var(--_inner-radius);box-sizing:border-box;color:inherit;display:inline-flex;font:inherit;gap:var(--_gap);letter-spacing:inherit;min-inline-size:0;padding-block:var(--_inset);padding-inline:var(--_inset-inline);text-align:start;text-decoration:none;transition:background-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing),color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing)}[data-ui=tag] [data-part=body]:last-child{border-end-end-radius:var(--_inner-radius);border-start-end-radius:var(--_inner-radius)}[data-ui=tag] [data-part=body]:has(+[data-part=remove]){padding-inline-end:var(--_gap)}[data-ui=tag] [data-part=body]:is(a,button){cursor:pointer}[data-ui=tag] [data-part=label]{min-inline-size:0;overflow:hidden;text-overflow:ellipsis;unicode-bidi:plaintext}@supports (text-box: trim-both cap alphabetic){[data-ui=tag] [data-part=label]{margin-block:-.3em;padding-block:.3em;text-box:trim-both cap alphabetic}}[data-ui=tag] [data-part=start],[data-ui=tag] [data-part=end]{--slotted-icon-size: var(--_icon-size);align-items:center;block-size:var(--_icon-size);box-sizing:border-box;display:inline-flex;flex:none;font-size:var(--_icon-size);inline-size:var(--_icon-size);justify-content:center;line-height:1}[data-ui=tag] [data-part=start]>*,[data-ui=tag] [data-part=end]>*{block-size:100%;display:block;inline-size:100%}[data-ui=tag] [data-part=indicator]{--slotted-icon-size: var(--_icon-size);align-items:center;block-size:var(--_icon-size);display:inline-flex;flex:none;inline-size:0;justify-content:center;margin-inline-end:calc(-1 * var(--_gap));opacity:0;overflow:hidden;transition:inline-size var(--slotted-duration-short) var(--slotted-easing-standard),margin-inline-end var(--slotted-duration-short) var(--slotted-easing-standard),opacity var(--slotted-duration-short) var(--slotted-easing-standard)}[data-ui=tag][data-part=root][data-selected] [data-part=indicator]{inline-size:var(--_icon-size);margin-inline-end:0;opacity:1}[data-ui=tag] [data-part=remove]{--slotted-icon-size: var(--_icon-size);align-items:center;appearance:none;background-color:transparent;border:0;border-end-end-radius:var(--_inner-radius);border-start-end-radius:var(--_inner-radius);box-sizing:border-box;color:inherit;cursor:pointer;display:inline-flex;flex:none;inline-size:max(var(--slotted-target-min, 24px),min(calc(var(--_icon-size) + 2 * var(--slotted-space-2, .25rem)),var(--_inner-size)));justify-content:center;padding:0;position:relative;transition:background-color var(--slotted-control-transition-duration) var(--slotted-control-transition-easing)}[data-ui=tag] [data-part=remove]:after{content:\"\";inset:min(0px,calc((100% - var(--slotted-target-min, 24px)) / 2));position:absolute}@media(pointer:coarse){[data-ui=tag] [data-part=remove]{inline-size:max(var(--slotted-target-min, 24px),min(calc(var(--_icon-size) + 2 * var(--slotted-space-2, .25rem)),var(--_inner-size)),calc(var(--_block-size) - 2 * var(--_edge-width)))}[data-ui=tag] [data-part=remove]:after{inset:min(0px,calc((100% - var(--slotted-target-comfortable, 44px)) / 2))}}[data-ui=tag] [data-part=remove]:first-child{border-end-start-radius:var(--_inner-radius);border-start-start-radius:var(--_inner-radius)}[data-ui=tag][data-part=root][data-selected]:not([data-disabled]){background-color:var(--_solid, ButtonFace);border-color:var(--_edge, ButtonBorder);color:var(--_on-solid, ButtonText)}[data-ui=tag][data-part=root]{--_state-hover: color-mix( in oklab, currentColor var(--slotted-tag-state-layer-hover, 8%), transparent );--_state-active: color-mix( in oklab, currentColor var(--slotted-tag-state-layer-active, 14%), transparent )}[data-ui=tag][data-part=root][data-variant=soft]:not([data-disabled]):not([data-selected]) :is([data-part=body]:is(a,button),[data-part=remove]):hover:not(:disabled){background-color:var(--_state-hover)}[data-ui=tag][data-part=root][data-variant=soft]:not([data-disabled]):not([data-selected]) :is([data-part=body]:is(a,button),[data-part=remove]):active:not(:disabled){background-color:var(--_state-active)}[data-ui=tag][data-part=root][data-variant=outline]:not([data-disabled]):not([data-selected]) :is([data-part=body]:is(a,button),[data-part=remove]):hover:not(:disabled){background-color:var(--_subtle-hover, ButtonFace)}[data-ui=tag][data-part=root][data-variant=outline]:not([data-disabled]):not([data-selected]) :is([data-part=body]:is(a,button),[data-part=remove]):active:not(:disabled){background-color:var(--_subtle-active, ButtonFace)}[data-ui=tag][data-part=root][data-variant=solid]:not([data-disabled]) :is([data-part=body]:is(a,button),[data-part=remove]):hover:not(:disabled),[data-ui=tag][data-part=root][data-selected]:not([data-disabled]) :is([data-part=body]:is(a,button),[data-part=remove]):hover:not(:disabled){background-color:var(--_solid-hover, Highlight)}[data-ui=tag][data-part=root][data-variant=solid]:not([data-disabled]) :is([data-part=body]:is(a,button),[data-part=remove]):active:not(:disabled),[data-ui=tag][data-part=root][data-selected]:not([data-disabled]) :is([data-part=body]:is(a,button),[data-part=remove]):active:not(:disabled){background-color:var(--_solid-active, Highlight)}[data-ui=tag] [data-part=body]:focus-visible,[data-ui=tag] [data-part=remove]:focus-visible{outline:var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);outline-offset:calc(-2 * var(--slotted-focus-ring-width, 2px))}[data-ui=tag][data-part=group]:focus-visible{outline:var(--slotted-focus-ring-width, 2px) solid var(--slotted-focus-ring-color, Highlight);outline-offset:var(--slotted-focus-ring-offset, 2px)}[data-ui=tag][data-part=root][data-disabled]{color:var(--slotted-disabled-foreground, GrayText)}[data-ui=tag][data-part=root][data-variant=solid][data-disabled],[data-ui=tag][data-part=root][data-variant=soft][data-disabled],[data-ui=tag][data-part=root][data-selected][data-disabled]{background-color:var(--slotted-disabled-background, Canvas);border-color:var(--slotted-disabled-border, GrayText)}[data-ui=tag][data-part=root][data-variant=outline][data-disabled]{background-color:transparent;border-color:var(--slotted-disabled-border, GrayText)}[data-ui=tag][data-part=root][data-disabled] :is([data-part=body],[data-part=remove]),[data-ui=tag] [data-part=body]:disabled,[data-ui=tag] [data-part=remove]:disabled{background-color:transparent;cursor:not-allowed}[data-ui=tag] [data-part=remove]:disabled{color:var(--slotted-disabled-foreground, GrayText)}[data-ui=tag][data-part=group]{align-items:center;display:flex;flex-wrap:wrap;gap:var(--slotted-tag-group-gap, var(--slotted-space-2, .25rem))}[data-ui=tag][data-part=group][data-orientation=vertical]{align-items:start;flex-direction:column;flex-wrap:nowrap;inline-size:fit-content}[data-ui=tag][data-part=group]:empty{display:none}@media(forced-colors:active){[data-ui=tag][data-part=root]{border-color:currentColor}[data-ui=tag][data-part=root][data-selected]:not([data-disabled]){background-color:Highlight;color:HighlightText;forced-color-adjust:none}[data-ui=tag][data-part=root][data-disabled]{border-color:GrayText;color:GrayText}}}\n"] }]
|
|
1602
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], valueChangeRequest: [{ type: i0.Output, args: ["valueChangeRequest"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], openChangeRequest: [{ type: i0.Output, args: ["openChangeRequest"] }], highlightedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightedValue", required: false }] }, { type: i0.Output, args: ["highlightedValueChange"] }], highlightedValueChangeRequest: [{ type: i0.Output, args: ["highlightedValueChangeRequest"] }], searchValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchValue", required: false }] }, { type: i0.Output, args: ["searchValueChange"] }], searchValueChangeRequest: [{ type: i0.Output, args: ["searchValueChangeRequest"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], total: [{ type: i0.Input, args: [{ isSignal: true, alias: "total", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], mount: [{ type: i0.Input, args: [{ isSignal: true, alias: "mount", required: false }] }], strategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "strategy", required: false }] }], messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], sideOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "sideOffset", required: false }] }], alignOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "alignOffset", required: false }] }], collisionPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "collisionPadding", required: false }] }], typeaheadTimeout: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeaheadTimeout", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], loop: [{ type: i0.Input, args: [{ isSignal: true, alias: "loop", required: false }] }], search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: false }] }], highlightMatch: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightMatch", required: false }] }], typeahead: [{ type: i0.Input, args: [{ isSignal: true, alias: "typeahead", required: false }] }], closeOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnSelect", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeOnOutsidePress: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutsidePress", required: false }] }], flip: [{ type: i0.Input, args: [{ isSignal: true, alias: "flip", required: false }] }], shift: [{ type: i0.Input, args: [{ isSignal: true, alias: "shift", required: false }] }], hideWhenDetached: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideWhenDetached", required: false }] }], portal: [{ type: i0.Input, args: [{ isSignal: true, alias: "portal", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], template: [{ type: i0.ViewChild, args: ['layer', { isSignal: true }] }], triggerRef: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], summaryTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SlSelectValue), { ...{ read: TemplateRef }, isSignal: true }] }], tags: [{ type: i0.ViewChild, args: ['tags', { isSignal: true }] }], chipOverflow: [{ type: i0.ViewChild, args: ['chipOverflow', { isSignal: true }] }] } });
|
|
1603
|
+
|
|
1604
|
+
/**
|
|
1605
|
+
* One option.
|
|
1606
|
+
*
|
|
1607
|
+
* `role="option"` on the host, and not a button: the listbox pattern's option
|
|
1608
|
+
* is not separately focusable — DOM focus stays on the trigger for the whole
|
|
1609
|
+
* interaction — and a button here would put a widget inside a widget and add a
|
|
1610
|
+
* tab stop the pattern excludes by name.
|
|
1611
|
+
*
|
|
1612
|
+
* The highlight is set by the pointer as well as by the keyboard, so exactly
|
|
1613
|
+
* one option is highlighted whichever device is driving and the state a screen
|
|
1614
|
+
* reader announces is the state the eye sees.
|
|
1615
|
+
*/
|
|
1616
|
+
class SlSelectItem {
|
|
1617
|
+
value = input.required(/* @ts-ignore */
|
|
1618
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1619
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1620
|
+
description = input(undefined, /* @ts-ignore */
|
|
1621
|
+
...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
1622
|
+
/** The glyph drawn in the first column, as a `Glyph` inside an `Icon` box. */
|
|
1623
|
+
icon = input(undefined, /* @ts-ignore */
|
|
1624
|
+
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
1625
|
+
/**
|
|
1626
|
+
* What typeahead matches on, what the search filters on, and what the mark
|
|
1627
|
+
* splits, when the label is not plain text.
|
|
1628
|
+
*/
|
|
1629
|
+
textValue = input(undefined, /* @ts-ignore */
|
|
1630
|
+
...(ngDevMode ? [{ debugName: "textValue" }] : /* istanbul ignore next */ []));
|
|
1631
|
+
/**
|
|
1632
|
+
* The label as text, given rather than projected.
|
|
1633
|
+
*
|
|
1634
|
+
* It is the one place this binding differs from its React counterpart, and it
|
|
1635
|
+
* is the difference `combobox` already records: a split needs the text before
|
|
1636
|
+
* the view exists, and Angular cannot read projected content that has not
|
|
1637
|
+
* been created. An option that projects its content instead is filtered on
|
|
1638
|
+
* `textValue` or on what it rendered, and its matched span is not marked —
|
|
1639
|
+
* there is nothing to split.
|
|
1640
|
+
*/
|
|
1641
|
+
label = input(undefined, /* @ts-ignore */
|
|
1642
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1643
|
+
position = input(undefined, { ...(ngDevMode ? { debugName: "position" } : /* istanbul ignore next */ {}), transform: (given) => given === undefined ? undefined : numberAttribute(given) });
|
|
1644
|
+
select = inject(SlSelect);
|
|
1645
|
+
host = inject((ElementRef));
|
|
1646
|
+
optionId = computed(() => this.select.optionId(this.value()), /* @ts-ignore */
|
|
1647
|
+
...(ngDevMode ? [{ debugName: "optionId" }] : /* istanbul ignore next */ []));
|
|
1648
|
+
selected = computed(() => this.select.selection().includes(this.value()), /* @ts-ignore */
|
|
1649
|
+
...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
|
|
1650
|
+
current = computed(() => this.select.highlightedValue() === this.value(), /* @ts-ignore */
|
|
1651
|
+
...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
|
|
1652
|
+
/** What was rendered, for an option that projected its content. */
|
|
1653
|
+
rendered = signal('', /* @ts-ignore */
|
|
1654
|
+
...(ngDevMode ? [{ debugName: "rendered" }] : /* istanbul ignore next */ []));
|
|
1655
|
+
/**
|
|
1656
|
+
* The text the filter judges: what the consumer said this option reads as,
|
|
1657
|
+
* then what it actually rendered. An option the filter cannot judge — one
|
|
1658
|
+
* whose content has not been created yet — is shown, which is what keeps a
|
|
1659
|
+
* list whole on its first render.
|
|
1660
|
+
*/
|
|
1661
|
+
searchText = computed(() => this.label() ?? this.textValue() ?? this.rendered(), /* @ts-ignore */
|
|
1662
|
+
...(ngDevMode ? [{ debugName: "searchText" }] : /* istanbul ignore next */ []));
|
|
1663
|
+
/**
|
|
1664
|
+
* Each option decides whether it belongs in the results: the family holds the
|
|
1665
|
+
* query and the comparison, and the option holds its own text. It hides
|
|
1666
|
+
* rather than leaving, because Angular cannot decline to render a host
|
|
1667
|
+
* component from inside it — and every reader of the collection takes the
|
|
1668
|
+
* visible ones.
|
|
1669
|
+
*/
|
|
1670
|
+
visible = computed(() => {
|
|
1671
|
+
const text = this.searchText();
|
|
1672
|
+
return text === '' || this.select.matches(text);
|
|
1673
|
+
}, /* @ts-ignore */
|
|
1674
|
+
...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
1675
|
+
/**
|
|
1676
|
+
* The spans the query matched, from the same collator the filter used, drawn
|
|
1677
|
+
* by the `highlight` family inside this family's label. An `indexOf` beside
|
|
1678
|
+
* a locale-sensitive filter marks nothing on the row it has just matched.
|
|
1679
|
+
*/
|
|
1680
|
+
ranges(text) {
|
|
1681
|
+
const query = this.select.query();
|
|
1682
|
+
if (!this.select.resolvedHighlightMatch() || query === '')
|
|
1683
|
+
return [];
|
|
1684
|
+
return matchRanges(text, query, { locale: this.select.resolvedLocale() });
|
|
1685
|
+
}
|
|
1686
|
+
constructor() {
|
|
1687
|
+
/**
|
|
1688
|
+
* The label reaches the closed control from here, and the count from the
|
|
1689
|
+
* same place. Both are read after render rather than from the input,
|
|
1690
|
+
* because the children may be elements and what a reader sees is the honest
|
|
1691
|
+
* answer either way.
|
|
1692
|
+
*/
|
|
1693
|
+
afterRenderEffect(() => {
|
|
1694
|
+
/* Read so that hiding or showing this option re-runs the count: the
|
|
1695
|
+
popup's own answer to "how many are there" is what draws the empty row
|
|
1696
|
+
and what the live region announces. */
|
|
1697
|
+
this.visible();
|
|
1698
|
+
const element = this.host.nativeElement;
|
|
1699
|
+
const text = element.querySelector("[data-part='label']")?.textContent?.trim() ?? '';
|
|
1700
|
+
if (text !== '')
|
|
1701
|
+
this.rendered.set(text);
|
|
1702
|
+
const label = this.label() ?? this.textValue() ?? text;
|
|
1703
|
+
if (label !== '')
|
|
1704
|
+
this.select.registerLabel(this.value(), label);
|
|
1705
|
+
this.select.recount();
|
|
1706
|
+
});
|
|
1707
|
+
inject(DestroyRef).onDestroy(() => this.select.recount());
|
|
1708
|
+
}
|
|
1709
|
+
onPointerEnter(event) {
|
|
1710
|
+
if (this.disabled())
|
|
1711
|
+
return;
|
|
1712
|
+
this.select.setHighlighted(this.value(), 'pointer', event);
|
|
1713
|
+
}
|
|
1714
|
+
/**
|
|
1715
|
+
* Only to stop the browser moving focus off the trigger. Under
|
|
1716
|
+
* `aria-activedescendant` the trigger is the focused element, and a press that
|
|
1717
|
+
* took focus to the body would leave the property pointing at something that
|
|
1718
|
+
* is no longer the active element (CB11).
|
|
1719
|
+
*/
|
|
1720
|
+
onPointerDown(event) {
|
|
1721
|
+
if (event.defaultPrevented)
|
|
1722
|
+
return;
|
|
1723
|
+
event.preventDefault();
|
|
1724
|
+
}
|
|
1725
|
+
onClick(event) {
|
|
1726
|
+
if (this.disabled())
|
|
1727
|
+
return;
|
|
1728
|
+
this.select.toggle(this.value(), 'pointer', event);
|
|
1729
|
+
/* Multiple selection keeps the popup open, so a reader can take three
|
|
1730
|
+
options without reopening it twice. */
|
|
1731
|
+
if (this.select.resolvedCloseOnSelect() && !this.select.resolvedMultiple()) {
|
|
1732
|
+
this.select.setOpen(false, 'select', event);
|
|
1733
|
+
this.select.focus();
|
|
1734
|
+
return;
|
|
1735
|
+
}
|
|
1736
|
+
/* The popup stayed open, so the query is emptied here rather than by the
|
|
1737
|
+
close: a list still filtered to the row the reader has just taken is a
|
|
1738
|
+
list that looks broken. */
|
|
1739
|
+
this.select.setQuery('', 'select', event);
|
|
1740
|
+
this.select.focusSearch();
|
|
1741
|
+
}
|
|
1742
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelectItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1743
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: SlSelectItem, isStandalone: true, selector: "sl-select-item", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, textValue: { classPropertyName: "textValue", publicName: "textValue", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-part": "item", "role": "option" }, listeners: { "click": "onClick($event)", "pointerdown": "onPointerDown($event)", "pointerenter": "onPointerEnter($event)" }, properties: { "id": "optionId()", "hidden": "!visible()", "attr.data-value": "value()", "attr.data-text-value": "searchText() || null", "attr.aria-selected": "selected()", "attr.aria-disabled": "disabled() ? true : null", "attr.aria-posinset": "position() ?? null", "attr.aria-setsize": "position() === undefined ? null : (select.total() ?? null)", "attr.data-disabled": "disabled() ? '' : null", "attr.data-selected": "selected() ? '' : null", "attr.data-current": "current() ? '' : null" } }, exportAs: ["slSelectItem"], ngImport: i0, template: `
|
|
1744
|
+
@if (icon(); as glyph) {
|
|
1745
|
+
<span data-part="icon"
|
|
1746
|
+
><span slIcon><svg slGlyph [name]="glyph"></svg></span
|
|
1747
|
+
></span>
|
|
1748
|
+
}
|
|
1749
|
+
<span data-part="label">
|
|
1750
|
+
@if (label(); as text) {
|
|
1751
|
+
@if (ranges(text).length > 0) {
|
|
1752
|
+
<span slHighlight [text]="text" [ranges]="ranges(text)"></span>
|
|
1753
|
+
} @else {
|
|
1754
|
+
{{ text }}
|
|
1755
|
+
}
|
|
1756
|
+
} @else {
|
|
1757
|
+
<ng-content />
|
|
1758
|
+
}
|
|
1759
|
+
</span>
|
|
1760
|
+
@if (description()) {
|
|
1761
|
+
<span data-part="description">{{ description() }}</span>
|
|
1762
|
+
}
|
|
1763
|
+
<span data-part="indicator"
|
|
1764
|
+
><span slIcon><svg slGlyph name="check"></svg></span
|
|
1765
|
+
></span>
|
|
1766
|
+
`, isInline: true, dependencies: [{ kind: "component", type: SlGlyph, selector: "svg[slGlyph]", inputs: ["name", "solid"] }, { kind: "component", type: SlHighlight, selector: "[slHighlight]", inputs: ["text", "query", "ranges", "matcher", "current", "locale", "sensitivity", "occurrences", "disabled"], exportAs: ["slHighlight"] }, { kind: "component", type: SlIcon, selector: "[slIcon]", inputs: ["directional", "label", "size", "tone"], exportAs: ["slIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1767
|
+
}
|
|
1768
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelectItem, decorators: [{
|
|
1769
|
+
type: Component,
|
|
1770
|
+
args: [{
|
|
1771
|
+
selector: 'sl-select-item',
|
|
1772
|
+
standalone: true,
|
|
1773
|
+
exportAs: 'slSelectItem',
|
|
1774
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1775
|
+
encapsulation: ViewEncapsulation.None,
|
|
1776
|
+
imports: [SlGlyph, SlHighlight, SlIcon],
|
|
1777
|
+
host: {
|
|
1778
|
+
'data-part': 'item',
|
|
1779
|
+
role: 'option',
|
|
1780
|
+
'[id]': 'optionId()',
|
|
1781
|
+
'[hidden]': '!visible()',
|
|
1782
|
+
'[attr.data-value]': 'value()',
|
|
1783
|
+
'[attr.data-text-value]': 'searchText() || null',
|
|
1784
|
+
'[attr.aria-selected]': 'selected()',
|
|
1785
|
+
'[attr.aria-disabled]': 'disabled() ? true : null',
|
|
1786
|
+
'[attr.aria-posinset]': 'position() ?? null',
|
|
1787
|
+
'[attr.aria-setsize]': 'position() === undefined ? null : (select.total() ?? null)',
|
|
1788
|
+
'[attr.data-disabled]': "disabled() ? '' : null",
|
|
1789
|
+
'[attr.data-selected]': "selected() ? '' : null",
|
|
1790
|
+
'[attr.data-current]': "current() ? '' : null",
|
|
1791
|
+
'(click)': 'onClick($event)',
|
|
1792
|
+
'(pointerdown)': 'onPointerDown($event)',
|
|
1793
|
+
'(pointerenter)': 'onPointerEnter($event)',
|
|
1794
|
+
},
|
|
1795
|
+
template: `
|
|
1796
|
+
@if (icon(); as glyph) {
|
|
1797
|
+
<span data-part="icon"
|
|
1798
|
+
><span slIcon><svg slGlyph [name]="glyph"></svg></span
|
|
1799
|
+
></span>
|
|
1800
|
+
}
|
|
1801
|
+
<span data-part="label">
|
|
1802
|
+
@if (label(); as text) {
|
|
1803
|
+
@if (ranges(text).length > 0) {
|
|
1804
|
+
<span slHighlight [text]="text" [ranges]="ranges(text)"></span>
|
|
1805
|
+
} @else {
|
|
1806
|
+
{{ text }}
|
|
1807
|
+
}
|
|
1808
|
+
} @else {
|
|
1809
|
+
<ng-content />
|
|
1810
|
+
}
|
|
1811
|
+
</span>
|
|
1812
|
+
@if (description()) {
|
|
1813
|
+
<span data-part="description">{{ description() }}</span>
|
|
1814
|
+
}
|
|
1815
|
+
<span data-part="indicator"
|
|
1816
|
+
><span slIcon><svg slGlyph name="check"></svg></span
|
|
1817
|
+
></span>
|
|
1818
|
+
`,
|
|
1819
|
+
}]
|
|
1820
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], textValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "textValue", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }] } });
|
|
1821
|
+
/**
|
|
1822
|
+
* A set of options under a heading, named by `aria-labelledby` pointing at its
|
|
1823
|
+
* own label — which the listbox pattern requires of every option group. The
|
|
1824
|
+
* label is an input rather than a projected part, because a group with no
|
|
1825
|
+
* accessible name is a pattern violation the type system can refuse.
|
|
1826
|
+
*/
|
|
1827
|
+
class SlSelectGroup {
|
|
1828
|
+
label = input.required(/* @ts-ignore */
|
|
1829
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1830
|
+
labelId = `sl-select-group-${Math.random().toString(36).slice(2, 8)}`;
|
|
1831
|
+
select = inject(SlSelect);
|
|
1832
|
+
host = inject((ElementRef));
|
|
1833
|
+
empty = signal(false, /* @ts-ignore */
|
|
1834
|
+
...(ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []));
|
|
1835
|
+
constructor() {
|
|
1836
|
+
/* A group whose every option was filtered away renders nothing at all: a
|
|
1837
|
+
heading with no options under it says a category matched when none did.
|
|
1838
|
+
The query is read so that a moving query re-measures the group. */
|
|
1839
|
+
afterRenderEffect(() => {
|
|
1840
|
+
this.select.query();
|
|
1841
|
+
const element = this.host.nativeElement;
|
|
1842
|
+
this.empty.set(element.querySelector("[data-part='item']:not([hidden])") === null);
|
|
1843
|
+
});
|
|
1844
|
+
}
|
|
1845
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelectGroup, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1846
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: SlSelectGroup, isStandalone: true, selector: "sl-select-group", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "data-part": "group", "role": "group" }, properties: { "hidden": "empty()", "attr.aria-labelledby": "labelId" } }, exportAs: ["slSelectGroup"], ngImport: i0, template: `
|
|
1847
|
+
<div data-part="group-label" [id]="labelId">{{ label() }}</div>
|
|
1848
|
+
<ng-content />
|
|
1849
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1850
|
+
}
|
|
1851
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelectGroup, decorators: [{
|
|
1852
|
+
type: Component,
|
|
1853
|
+
args: [{
|
|
1854
|
+
selector: 'sl-select-group',
|
|
1855
|
+
standalone: true,
|
|
1856
|
+
exportAs: 'slSelectGroup',
|
|
1857
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1858
|
+
encapsulation: ViewEncapsulation.None,
|
|
1859
|
+
host: {
|
|
1860
|
+
'data-part': 'group',
|
|
1861
|
+
role: 'group',
|
|
1862
|
+
'[hidden]': 'empty()',
|
|
1863
|
+
'[attr.aria-labelledby]': 'labelId',
|
|
1864
|
+
},
|
|
1865
|
+
template: `
|
|
1866
|
+
<div data-part="group-label" [id]="labelId">{{ label() }}</div>
|
|
1867
|
+
<ng-content />
|
|
1868
|
+
`,
|
|
1869
|
+
}]
|
|
1870
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }] } });
|
|
1871
|
+
/**
|
|
1872
|
+
* A line between two sets of options. `role="separator"` inside a listbox is a
|
|
1873
|
+
* structural element and takes no orientation: the line is horizontal because
|
|
1874
|
+
* the list is vertical, and saying so twice is how two families came to
|
|
1875
|
+
* disagree about which axis the word names.
|
|
1876
|
+
*/
|
|
1877
|
+
class SlSelectSeparator {
|
|
1878
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelectSeparator, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1879
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: SlSelectSeparator, isStandalone: true, selector: "sl-select-separator", host: { attributes: { "data-part": "separator", "role": "separator" } }, exportAs: ["slSelectSeparator"], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1880
|
+
}
|
|
1881
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: SlSelectSeparator, decorators: [{
|
|
1882
|
+
type: Component,
|
|
1883
|
+
args: [{
|
|
1884
|
+
selector: 'sl-select-separator',
|
|
1885
|
+
standalone: true,
|
|
1886
|
+
exportAs: 'slSelectSeparator',
|
|
1887
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1888
|
+
encapsulation: ViewEncapsulation.None,
|
|
1889
|
+
host: { 'data-part': 'separator', role: 'separator' },
|
|
1890
|
+
template: '',
|
|
1891
|
+
}]
|
|
1892
|
+
}] });
|
|
1893
|
+
|
|
1894
|
+
/**
|
|
1895
|
+
* Generated bundle index. Do not edit.
|
|
1896
|
+
*/
|
|
1897
|
+
|
|
1898
|
+
export { SELECT_DEFAULTS, SELECT_FALLBACK, SlSelect, SlSelectGroup, SlSelectItem, SlSelectSeparator, SlSelectValue, injectSelectDefaults, provideSelectDefaults };
|
|
1899
|
+
//# sourceMappingURL=slotted-angular-select.mjs.map
|