@slotted/angular 0.0.0-stage → 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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
package/docs/drawer.json
ADDED
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
{
|
|
2
|
+
"family": "drawer",
|
|
3
|
+
"ui": "drawer",
|
|
4
|
+
"binding": "angular",
|
|
5
|
+
"catalog": {
|
|
6
|
+
"group": "Overlays",
|
|
7
|
+
"summary": "Panel that slides in from an edge."
|
|
8
|
+
},
|
|
9
|
+
"axes": {
|
|
10
|
+
"mode": [
|
|
11
|
+
"overlay",
|
|
12
|
+
"inline"
|
|
13
|
+
],
|
|
14
|
+
"side": [
|
|
15
|
+
"start",
|
|
16
|
+
"end",
|
|
17
|
+
"top",
|
|
18
|
+
"bottom"
|
|
19
|
+
],
|
|
20
|
+
"size": [
|
|
21
|
+
"sm",
|
|
22
|
+
"md",
|
|
23
|
+
"lg",
|
|
24
|
+
"xl",
|
|
25
|
+
"full",
|
|
26
|
+
"content"
|
|
27
|
+
],
|
|
28
|
+
"mount": [
|
|
29
|
+
"active",
|
|
30
|
+
"lazy",
|
|
31
|
+
"eager"
|
|
32
|
+
],
|
|
33
|
+
"modal": [
|
|
34
|
+
true,
|
|
35
|
+
false
|
|
36
|
+
],
|
|
37
|
+
"escape": [
|
|
38
|
+
"close",
|
|
39
|
+
"none"
|
|
40
|
+
],
|
|
41
|
+
"outsidePress": [
|
|
42
|
+
"close",
|
|
43
|
+
"none"
|
|
44
|
+
],
|
|
45
|
+
"back": [
|
|
46
|
+
"close",
|
|
47
|
+
"none"
|
|
48
|
+
],
|
|
49
|
+
"drag": [
|
|
50
|
+
"panel",
|
|
51
|
+
"resizer"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
"members": {
|
|
55
|
+
"drawer": {
|
|
56
|
+
"nativeElement": "div",
|
|
57
|
+
"role": "dialog",
|
|
58
|
+
"defaults": {
|
|
59
|
+
"mode": "overlay",
|
|
60
|
+
"side": "end",
|
|
61
|
+
"size": "md",
|
|
62
|
+
"mount": "active",
|
|
63
|
+
"modal": true,
|
|
64
|
+
"escape": "close",
|
|
65
|
+
"outsidePress": "close",
|
|
66
|
+
"back": "close",
|
|
67
|
+
"drag": "panel",
|
|
68
|
+
"minExtent": 0.2,
|
|
69
|
+
"maxExtent": 1,
|
|
70
|
+
"loading": false,
|
|
71
|
+
"scrimFrom": 0
|
|
72
|
+
},
|
|
73
|
+
"fixed": {
|
|
74
|
+
"modalUnderInline": false
|
|
75
|
+
},
|
|
76
|
+
"capabilities": [
|
|
77
|
+
"open",
|
|
78
|
+
"extent",
|
|
79
|
+
"size",
|
|
80
|
+
"placement",
|
|
81
|
+
"appearance",
|
|
82
|
+
"loading",
|
|
83
|
+
"wiring"
|
|
84
|
+
],
|
|
85
|
+
"states": [
|
|
86
|
+
"default",
|
|
87
|
+
"hover",
|
|
88
|
+
"active",
|
|
89
|
+
"focus-visible",
|
|
90
|
+
"open",
|
|
91
|
+
"loading",
|
|
92
|
+
"dragging"
|
|
93
|
+
],
|
|
94
|
+
"parts": [
|
|
95
|
+
"root",
|
|
96
|
+
"trigger",
|
|
97
|
+
"backdrop",
|
|
98
|
+
"panel",
|
|
99
|
+
"resizer",
|
|
100
|
+
"line",
|
|
101
|
+
"grip",
|
|
102
|
+
"header",
|
|
103
|
+
"title",
|
|
104
|
+
"description",
|
|
105
|
+
"body",
|
|
106
|
+
"footer",
|
|
107
|
+
"close"
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
"docs": {
|
|
112
|
+
"drawer": {
|
|
113
|
+
"imports": {
|
|
114
|
+
"source": "import { SlDrawer, SlDrawerBody, SlDrawerClose, SlDrawerDescription, SlDrawerFooter, SlDrawerHeader, SlDrawerResizer, SlDrawerTitle, SlDrawerTrigger, provideDrawerDefaults } from '@slotted/angular/drawer';",
|
|
115
|
+
"selector": "<sl-drawer>, exportAs slDrawer"
|
|
116
|
+
},
|
|
117
|
+
"anatomy": [
|
|
118
|
+
{
|
|
119
|
+
"part": "root",
|
|
120
|
+
"element": "div inside <sl-drawer>, moved into a portal under mode=\"overlay\"",
|
|
121
|
+
"required": true,
|
|
122
|
+
"purpose": "The layer. Under mode=\"overlay\" it is fixed to the viewport and stacked above the page; under mode=\"inline\" it is a box in your own layout, and its own width or height is what opens and closes. It carries data-ui=\"drawer\", every axis as a data attribute, and data-open, data-loading and data-dragging. The <sl-drawer> host renders display: contents where you wrote it, and the layer keeps the theme, density and direction of that place."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"part": "trigger",
|
|
126
|
+
"element": "your own element, with slDrawerTrigger on it",
|
|
127
|
+
"required": false,
|
|
128
|
+
"purpose": "The control that opens and closes the drawer, rendered where it is written. It carries aria-expanded and aria-controls in both modes, and aria-haspopup=\"dialog\" only under mode=\"overlay\", because an inline drawer is a disclosure. A press on it is never read as a press outside the drawer."
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"part": "backdrop",
|
|
132
|
+
"element": "div",
|
|
133
|
+
"required": false,
|
|
134
|
+
"purpose": "The scrim behind the panel, painted from --slotted-drawer-scrim under mode=\"overlay\" whether the drawer is modal or not, and not painted while the measure is below scrimFrom. It takes a press like the page would, so a press on it is a press outside the drawer. Set --slotted-drawer-scrim: transparent to paint none."
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"part": "panel",
|
|
138
|
+
"element": "div, holding the projected content",
|
|
139
|
+
"required": true,
|
|
140
|
+
"purpose": "The surface, aligned to side. Under mode=\"overlay\" it carries role=\"dialog\", and aria-modal=\"true\" while modal; under mode=\"inline\" it has no role, so put a landmark such as <nav slDrawerBody> inside it. Its rows are the header, the body and the footer, and only the body scrolls. An aria-label written on <sl-drawer> is moved to it."
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"part": "resizer",
|
|
144
|
+
"element": "your own element, with slDrawerResizer on it",
|
|
145
|
+
"required": false,
|
|
146
|
+
"purpose": "The separator the reader drags, or focuses and moves with the keyboard, to resize the panel. Rendering it is what makes the drawer resizable. It carries role=\"separator\", tabindex=\"0\", aria-orientation, aria-valuenow, aria-valuemin and aria-valuemax as percentages, aria-controls naming the panel and aria-labelledby naming the title. On start and end it sits on the panel’s inner edge; on top and bottom it is the grip above the header."
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"part": "line",
|
|
150
|
+
"element": "span",
|
|
151
|
+
"required": true,
|
|
152
|
+
"purpose": "A hairline on each side of the grip on start and end, which runs the whole edge under the pointer, under focus and during a drag. It is not drawn on top and bottom."
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"part": "grip",
|
|
156
|
+
"element": "span[aria-hidden]",
|
|
157
|
+
"required": true,
|
|
158
|
+
"purpose": "The mark the pointer aims at: a dot grid on start and end, and a pill above the header on top and bottom. It is hidden from assistive technology, because the separator around it is already named and valued."
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"part": "header",
|
|
162
|
+
"element": "your own element, with slDrawerHeader on it",
|
|
163
|
+
"required": false,
|
|
164
|
+
"purpose": "Lays out the title and the description in one column and the close button in another, so a title that wraps grows the row instead of moving the button."
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"part": "title",
|
|
168
|
+
"element": "your own heading, with slDrawerTitle on it",
|
|
169
|
+
"required": false,
|
|
170
|
+
"purpose": "The visible name of the drawer. The panel and the separator point at it with aria-labelledby, and only while it is rendered."
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"part": "description",
|
|
174
|
+
"element": "your own element, with slDrawerDescription on it",
|
|
175
|
+
"required": false,
|
|
176
|
+
"purpose": "The sentence under the title. The panel points at it with aria-describedby while it is rendered."
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"part": "body",
|
|
180
|
+
"element": "your own element, with slDrawerBody on it",
|
|
181
|
+
"required": false,
|
|
182
|
+
"purpose": "The row that scrolls, and the row that carries aria-busy while loading is set. A wheel that reaches its end does not scroll the page behind. inset=\"none\" removes its padding, for content that brings its own, such as a list that runs to the panel’s edges."
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"part": "footer",
|
|
186
|
+
"element": "your own element, with slDrawerFooter on it",
|
|
187
|
+
"required": false,
|
|
188
|
+
"purpose": "The actions, in a wrapping row aligned to the end, on a sunken surface with a rule above it."
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"part": "close",
|
|
192
|
+
"element": "your own button, with slDrawerClose on it",
|
|
193
|
+
"required": false,
|
|
194
|
+
"purpose": "The ✕ button. Its target is at least --slotted-target-min in both directions. It closes the drawer with the reason dismiss, and its value is the result of that close."
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
"api": [
|
|
198
|
+
{
|
|
199
|
+
"name": "open",
|
|
200
|
+
"type": "model<boolean>",
|
|
201
|
+
"defaultValue": "false",
|
|
202
|
+
"appliesTo": "<sl-drawer>",
|
|
203
|
+
"description": "Whether the drawer is open. A model, so [(open)] binds both halves and there is no defaultOpen."
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"name": "extent",
|
|
207
|
+
"type": "model<number | undefined>",
|
|
208
|
+
"defaultValue": "—",
|
|
209
|
+
"appliesTo": "<sl-drawer>",
|
|
210
|
+
"description": "The panel’s measure: a fraction from 0 to 1 of the screen, or of your layout under mode=\"inline\". undefined means the size step decides. A model, so [(extent)] binds both halves."
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"name": "minExtent",
|
|
214
|
+
"type": "number",
|
|
215
|
+
"defaultValue": "0.2",
|
|
216
|
+
"appliesTo": "<sl-drawer>",
|
|
217
|
+
"description": "The smallest measure the reader can set, and the separator’s aria-valuemin. A drag released below it asks to close the drawer, with the reason pointer."
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"name": "maxExtent",
|
|
221
|
+
"type": "number",
|
|
222
|
+
"defaultValue": "1",
|
|
223
|
+
"appliesTo": "<sl-drawer>",
|
|
224
|
+
"description": "The largest measure the reader can set, and the separator’s aria-valuemax. With snap points, both limits default to the first and the last stop."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"name": "snapPoints",
|
|
228
|
+
"type": "readonly number[]",
|
|
229
|
+
"defaultValue": "—",
|
|
230
|
+
"appliesTo": "<sl-drawer>",
|
|
231
|
+
"description": "The stops the measure moves between, as fractions. With them an arrow key moves to the next stop, Home and End go to the first and the last, and a drag is released onto the nearest."
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"name": "mode",
|
|
235
|
+
"type": "'overlay' | 'inline'",
|
|
236
|
+
"defaultValue": "overlay",
|
|
237
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
238
|
+
"description": "overlay puts the drawer over the page, in a portal; inline puts it in your own layout. The value can change while the drawer is open, and the panel’s content and the state of its fields are kept across the change."
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"name": "side",
|
|
242
|
+
"type": "'start' | 'end' | 'top' | 'bottom'",
|
|
243
|
+
"defaultValue": "end",
|
|
244
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
245
|
+
"description": "The edge the panel comes from. start and end follow the writing direction, so the drawer changes sides in a right-to-left document."
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"name": "size",
|
|
249
|
+
"type": "'sm' | 'md' | 'lg' | 'xl' | 'full' | 'content'",
|
|
250
|
+
"defaultValue": "md",
|
|
251
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
252
|
+
"description": "The panel’s measure at rest: one of the steps sm (18rem), md (24rem), lg (30rem), xl (40rem) and full, or content, which fits what the panel holds, up to 4rem short of the screen. When unset, content on top and bottom and md on start and end. A step wider than the screen is held to it."
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"name": "mount",
|
|
256
|
+
"type": "'active' | 'lazy' | 'eager'",
|
|
257
|
+
"defaultValue": "active",
|
|
258
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
259
|
+
"description": "When an overlay layer is in the document: active only while it is open or closing, lazy from the first open on, and eager from the start, inert while closed. An inline drawer is always in the document."
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"name": "modal",
|
|
263
|
+
"type": "boolean",
|
|
264
|
+
"defaultValue": "true",
|
|
265
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
266
|
+
"description": "Whether the page behind is inert, its scroll is locked and focus is contained in the panel, and whether the panel carries aria-modal. The scrim is painted either way. Always false under mode=\"inline\"."
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"name": "escape",
|
|
270
|
+
"type": "'close' | 'none'",
|
|
271
|
+
"defaultValue": "close",
|
|
272
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
273
|
+
"description": "Whether Escape asks to close the drawer. Escape reaches only the topmost layer, and a layer that refuses it does not pass it to the one below."
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"name": "outsidePress",
|
|
277
|
+
"type": "'close' | 'none'",
|
|
278
|
+
"defaultValue": "close",
|
|
279
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
280
|
+
"description": "Whether a press outside the layer, the scrim included, asks to close the drawer. It has no effect under mode=\"inline\"."
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"name": "back",
|
|
284
|
+
"type": "'close' | 'none'",
|
|
285
|
+
"defaultValue": "close",
|
|
286
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
287
|
+
"description": "Whether the browser’s back button or a phone’s back gesture closes a modal drawer instead of leaving the page. The drawer holds one history entry while it is open. It has no effect under mode=\"inline\"."
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
"name": "drag",
|
|
291
|
+
"type": "'panel' | 'resizer'",
|
|
292
|
+
"defaultValue": "panel",
|
|
293
|
+
"appliesTo": "<sl-drawer>, provideDrawerDefaults",
|
|
294
|
+
"description": "What a touch moves a bottom sheet by: panel, anywhere on the panel, or resizer, the separator only. With panel, a drag that starts in a list scrolled away from its top scrolls the list. A mouse or a pen always drags the separator."
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"name": "scrimFrom",
|
|
298
|
+
"type": "number",
|
|
299
|
+
"defaultValue": "0",
|
|
300
|
+
"appliesTo": "<sl-drawer>",
|
|
301
|
+
"description": "While the measure is below this fraction, the scrim is not painted, a press reaches the page, and the root carries data-undimmed. Use it with [modal]=\"false\" and outsidePress=\"none\"."
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
"name": "loading",
|
|
305
|
+
"type": "boolean",
|
|
306
|
+
"defaultValue": "false",
|
|
307
|
+
"appliesTo": "<sl-drawer>",
|
|
308
|
+
"description": "Marks the body as busy with aria-busy and gives it a minimum height, so the panel does not jump when the content arrives. The header, the ✕, Escape and the separator stay available."
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"name": "messages",
|
|
312
|
+
"type": "Partial<DrawerMessages>",
|
|
313
|
+
"defaultValue": "—",
|
|
314
|
+
"appliesTo": "<sl-drawer>",
|
|
315
|
+
"description": "Words laid over the current language, key by key: close, the name of the ✕. An aria-label on slDrawerClose takes precedence."
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"name": "initialFocus",
|
|
319
|
+
"type": "'first' | 'container' | HTMLElement | false",
|
|
320
|
+
"defaultValue": "first",
|
|
321
|
+
"appliesTo": "<sl-drawer>",
|
|
322
|
+
"description": "Where focus goes when an overlay drawer opens: first, the first focusable element; container, the panel itself, for content that is read before it is used; an element; or false, nowhere. An inline drawer moves no focus."
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"name": "finalFocus",
|
|
326
|
+
"type": "HTMLElement | false",
|
|
327
|
+
"defaultValue": "—",
|
|
328
|
+
"appliesTo": "<sl-drawer>",
|
|
329
|
+
"description": "Where focus goes when the drawer closes, as an element, or false for nowhere. When unset, it returns to the element that had focus when the drawer opened, usually the trigger."
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
"name": "inset",
|
|
333
|
+
"type": "'none'",
|
|
334
|
+
"defaultValue": "—",
|
|
335
|
+
"appliesTo": "slDrawerBody",
|
|
336
|
+
"description": "none removes the body’s padding, for content that brings its own inset, such as a page or a list that runs to the panel’s edges."
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"name": "step",
|
|
340
|
+
"type": "number",
|
|
341
|
+
"defaultValue": "16",
|
|
342
|
+
"appliesTo": "slDrawerResizer",
|
|
343
|
+
"description": "How far one arrow key moves the separator, in pixels, when there are no snap points."
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
"name": "largeStep",
|
|
347
|
+
"type": "number",
|
|
348
|
+
"defaultValue": "64",
|
|
349
|
+
"appliesTo": "slDrawerResizer",
|
|
350
|
+
"description": "How far Shift and an arrow key move the separator, in pixels, when there are no snap points."
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"name": "value",
|
|
354
|
+
"type": "string",
|
|
355
|
+
"defaultValue": "—",
|
|
356
|
+
"appliesTo": "slDrawerClose",
|
|
357
|
+
"description": "The result of a close from this button, carried on the close request as result."
|
|
358
|
+
}
|
|
359
|
+
],
|
|
360
|
+
"composition": [
|
|
361
|
+
{
|
|
362
|
+
"name": "exportAs",
|
|
363
|
+
"type": "'slDrawer'",
|
|
364
|
+
"defaultValue": "—",
|
|
365
|
+
"appliesTo": "<sl-drawer>",
|
|
366
|
+
"description": "A template reference variable, #drawer=\"slDrawer\", reaches the drawer, which is how a trigger anywhere in the same template opens it."
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"name": "ng-content",
|
|
370
|
+
"type": "—",
|
|
371
|
+
"defaultValue": "—",
|
|
372
|
+
"appliesTo": "<sl-drawer>",
|
|
373
|
+
"description": "The drawer’s content is your own elements with the part directives on them, projected into the panel. Under mount=\"active\" the layer is built only while the drawer is open."
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
"name": "openDrawer(), close(result), focus()",
|
|
377
|
+
"type": "() => void",
|
|
378
|
+
"defaultValue": "—",
|
|
379
|
+
"appliesTo": "<sl-drawer>",
|
|
380
|
+
"description": "Open the drawer, close it with a result, and move focus into the panel, from code. Each opens or closes with the reason programmatic."
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"name": "container",
|
|
384
|
+
"type": "Element | null",
|
|
385
|
+
"defaultValue": "—",
|
|
386
|
+
"appliesTo": "<sl-drawer>",
|
|
387
|
+
"description": "An element to portal this layer into instead of the shared portal root, for an application shell with its own stacking context. setPortalContainer from @slotted/core/portal sets one for the whole document."
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
"name": "provideDrawerDefaults()",
|
|
391
|
+
"type": "{ mode, side, size, mount, modal, escape, outsidePress, back, drag }",
|
|
392
|
+
"defaultValue": "—",
|
|
393
|
+
"appliesTo": "an injector",
|
|
394
|
+
"description": "Sets these nine axes for every drawer in the injector, through DRAWER_DEFAULTS. A value set on one drawer still wins."
|
|
395
|
+
}
|
|
396
|
+
],
|
|
397
|
+
"events": [
|
|
398
|
+
{
|
|
399
|
+
"name": "openChange",
|
|
400
|
+
"payload": "boolean",
|
|
401
|
+
"when": "The two-way half of open, which [(open)] binds. It fires once the drawer has opened or closed."
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"name": "openChangeRequest",
|
|
405
|
+
"payload": "DrawerChangeRequest",
|
|
406
|
+
"when": "Before the drawer opens or closes, for every way it can: the trigger, the ✕, Escape, a press outside, the back gesture and a call from code. The request carries value, previous, reason (pointer, keyboard, dismiss, escape, outsidePress, back or programmatic), result, the source event and cancel(), which keeps the drawer as it is."
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"name": "extentChange",
|
|
410
|
+
"payload": "number | undefined",
|
|
411
|
+
"when": "The two-way half of extent, which [(extent)] binds. It fires once the measure has changed."
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
"name": "extentChangeRequest",
|
|
415
|
+
"payload": "DrawerExtentRequest",
|
|
416
|
+
"when": "Before the panel’s measure changes, with the reason pointer for a drag or a tap on the grip, keyboard for an arrow key, Home, End or Enter, and programmatic for a change from code. A drag of the separator fires on every pointer move and can report a value below minExtent; a drag of a sheet’s body fires once, on release, with the stop it landed on. undefined means the panel is back on its size step, or on the height of its content under size=\"content\"."
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
"name": "closed",
|
|
420
|
+
"payload": "string | undefined",
|
|
421
|
+
"when": "Once the drawer has closed, with the result of the close, or undefined for a close that carried none."
|
|
422
|
+
}
|
|
423
|
+
],
|
|
424
|
+
"accessibility": [
|
|
425
|
+
"Under mode=\"overlay\" the drawer follows the WAI-ARIA dialog (modal) pattern. While it is modal, Tab and Shift+Tab move through the panel and wrap at its ends. Escape closes it, and reaches only the topmost layer, so one press never closes two drawers.",
|
|
426
|
+
"Under mode=\"inline\" the panel has no role, because a navigation drawer is a navigation landmark and a filter panel is complementary; write the landmark yourself, such as <nav slDrawerBody>. The trigger has no aria-haspopup there, because an inline drawer is a disclosure, not a popup.",
|
|
427
|
+
"aria-modal=\"true\" is written only while the drawer is modal, which is the only state in which the page behind is inert. modal is always false under mode=\"inline\". An aria-label written on <sl-drawer> is moved to the panel, which is the element the role is on.",
|
|
428
|
+
"The separator follows the WAI-ARIA window splitter pattern. The arrow keys move it in the direction they point, Home and End go to the limits, and Enter collapses the panel to its minimum and then restores it. Enter never closes the drawer; Escape does. The values are percentages, and there is no aria-valuetext, so a screen reader announces 40 rather than 40 per cent.",
|
|
429
|
+
"A bottom sheet moves under a touch on its body as well as on its separator, and every stop a finger reaches, the height of the content among them, is also reachable with the arrow keys on the separator. A touch drag never starts on a field, on selected text, or on an element whose touch-action already takes vertical movement.",
|
|
430
|
+
"A closed panel is inert in both modes, so its controls are in neither the tab order nor the accessibility tree.",
|
|
431
|
+
"Focus moves into an overlay panel when it opens, to the first focusable element unless initialFocus names another, and returns on close to the element that had it before; if that element has left the document, focus goes to its nearest ancestor still in it. An inline drawer moves no focus when it opens, and on close restores focus only when focus is inside the panel or on the page body.",
|
|
432
|
+
"The ✕ button and the separator are each at least --slotted-target-min across, so both meet the WCAG 2.2 minimum target size of 24 by 24 pixels."
|
|
433
|
+
]
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
"tokens": [
|
|
437
|
+
"--slotted-border-strong",
|
|
438
|
+
"--slotted-border-subtle",
|
|
439
|
+
"--slotted-border-width-thick",
|
|
440
|
+
"--slotted-border-width-thin",
|
|
441
|
+
"--slotted-control-font-family",
|
|
442
|
+
"--slotted-control-icon-size-md",
|
|
443
|
+
"--slotted-control-inner-size-md",
|
|
444
|
+
"--slotted-control-radius",
|
|
445
|
+
"--slotted-control-transition-duration",
|
|
446
|
+
"--slotted-control-transition-easing",
|
|
447
|
+
"--slotted-drawer-body-color",
|
|
448
|
+
"--slotted-drawer-border-color",
|
|
449
|
+
"--slotted-drawer-close-active-background",
|
|
450
|
+
"--slotted-drawer-close-color",
|
|
451
|
+
"--slotted-drawer-close-hover-background",
|
|
452
|
+
"--slotted-drawer-color",
|
|
453
|
+
"--slotted-drawer-description-color",
|
|
454
|
+
"--slotted-drawer-extent",
|
|
455
|
+
"--slotted-drawer-extent-lg",
|
|
456
|
+
"--slotted-drawer-extent-md",
|
|
457
|
+
"--slotted-drawer-extent-sm",
|
|
458
|
+
"--slotted-drawer-extent-xl",
|
|
459
|
+
"--slotted-drawer-footer-surface",
|
|
460
|
+
"--slotted-drawer-radius",
|
|
461
|
+
"--slotted-drawer-resizer-line-active-color",
|
|
462
|
+
"--slotted-drawer-resizer-line-color",
|
|
463
|
+
"--slotted-drawer-rule-color",
|
|
464
|
+
"--slotted-drawer-scrim",
|
|
465
|
+
"--slotted-drawer-sheet-inline-size",
|
|
466
|
+
"--slotted-drawer-surface",
|
|
467
|
+
"--slotted-drawer-title-color",
|
|
468
|
+
"--slotted-drawer-title-font-family",
|
|
469
|
+
"--slotted-duration-instant",
|
|
470
|
+
"--slotted-duration-long",
|
|
471
|
+
"--slotted-duration-medium",
|
|
472
|
+
"--slotted-duration-short",
|
|
473
|
+
"--slotted-easing-enter",
|
|
474
|
+
"--slotted-easing-exit",
|
|
475
|
+
"--slotted-easing-standard",
|
|
476
|
+
"--slotted-focus-ring-color",
|
|
477
|
+
"--slotted-focus-ring-offset",
|
|
478
|
+
"--slotted-focus-ring-width",
|
|
479
|
+
"--slotted-font-family-heading",
|
|
480
|
+
"--slotted-font-family-sans",
|
|
481
|
+
"--slotted-font-size-lg",
|
|
482
|
+
"--slotted-font-size-md",
|
|
483
|
+
"--slotted-font-size-xl",
|
|
484
|
+
"--slotted-font-weight-semibold",
|
|
485
|
+
"--slotted-line-height-lg",
|
|
486
|
+
"--slotted-line-height-md",
|
|
487
|
+
"--slotted-radius-full",
|
|
488
|
+
"--slotted-radius-lg",
|
|
489
|
+
"--slotted-radius-sm",
|
|
490
|
+
"--slotted-scrim",
|
|
491
|
+
"--slotted-shadow-lg",
|
|
492
|
+
"--slotted-space-11",
|
|
493
|
+
"--slotted-space-12",
|
|
494
|
+
"--slotted-space-2",
|
|
495
|
+
"--slotted-space-4",
|
|
496
|
+
"--slotted-space-5",
|
|
497
|
+
"--slotted-space-6",
|
|
498
|
+
"--slotted-space-7",
|
|
499
|
+
"--slotted-space-8",
|
|
500
|
+
"--slotted-space-9",
|
|
501
|
+
"--slotted-surface-raised",
|
|
502
|
+
"--slotted-surface-sunken",
|
|
503
|
+
"--slotted-target-comfortable",
|
|
504
|
+
"--slotted-target-min",
|
|
505
|
+
"--slotted-text",
|
|
506
|
+
"--slotted-text-muted",
|
|
507
|
+
"--slotted-tone-secondary-subtle-active",
|
|
508
|
+
"--slotted-tone-secondary-subtle-hover",
|
|
509
|
+
"--slotted-z-index-overlay"
|
|
510
|
+
],
|
|
511
|
+
"examples": [
|
|
512
|
+
{
|
|
513
|
+
"id": "playground",
|
|
514
|
+
"title": "Playground",
|
|
515
|
+
"note": "A drawer opened inside the scene rather than over the page. Press the trigger, then Tab: focus is contained, Escape closes, and focus returns to the button it came from.",
|
|
516
|
+
"language": "html",
|
|
517
|
+
"source": "<button slButton [slDrawerTrigger]=\"d\">Abrir detalhes</button>\n<sl-drawer #d=\"slDrawer\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Fatura 4471</h2>\n <p slDrawerDescription>Emitida em 12 de agosto.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <input slTextField aria-label=\"Observação\" />\n </div>\n <footer slDrawerFooter>\n <button slButton size=\"sm\" variant=\"ghost\" tone=\"secondary\">Cancelar</button>\n <button slButton size=\"sm\">Salvar</button>\n </footer>\n</sl-drawer>\n",
|
|
518
|
+
"verdict": "excerpt"
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
"id": "mode",
|
|
522
|
+
"title": "A layer over the page, or a panel beside it",
|
|
523
|
+
"note": "One axis rather than two components, because an application binds it to its own breakpoint: swapping one element for another there would take the panel’s scroll position, its focus and every uncontrolled control with it.",
|
|
524
|
+
"language": "html",
|
|
525
|
+
"source": "<div style=\"display: grid; grid-template-columns: auto minmax(0, 1fr)\">\n <sl-drawer [mode]=\"wide() ? 'inline' : 'overlay'\" [(open)]=\"open\" side=\"start\">\n <nav slDrawerBody aria-label=\"Seções\">…</nav>\n </sl-drawer>\n <main>…</main>\n</div>\n",
|
|
526
|
+
"verdict": "excerpt"
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
"id": "side",
|
|
530
|
+
"title": "Which edge it comes from",
|
|
531
|
+
"note": "start and end rather than left and right, so the whole layout mirrors in a right-to-left document with no second stylesheet. Only the exit slide is physical, and it takes one rule per inline side.",
|
|
532
|
+
"language": "html",
|
|
533
|
+
"source": "<sl-drawer side=\"bottom\" [(open)]=\"open\">\n <div slDrawerBody>…</div>\n</sl-drawer>\n",
|
|
534
|
+
"verdict": "excerpt"
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"id": "size",
|
|
538
|
+
"title": "How much room the panel takes",
|
|
539
|
+
"note": "Five named steps rather than a pixel string, because a theme can retune a step and cannot retune width: 400px. A drawer wider than the layer is clamped to it, which is what makes a side drawer full-bleed on a phone.",
|
|
540
|
+
"language": "html",
|
|
541
|
+
"source": "<sl-drawer size=\"lg\">…</sl-drawer>\n\n<!-- An exact measure is the token the steps resolve into. -->\n<sl-drawer style=\"--slotted-drawer-extent: 27rem\">…</sl-drawer>\n",
|
|
542
|
+
"verdict": "excerpt"
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
"id": "resize",
|
|
546
|
+
"title": "An edge the reader can move — with a keyboard",
|
|
547
|
+
"note": "Putting slDrawerResizer on an element is the capability; there is no resizable input. Arrow keys move it sixteen pixels at a time and sixty-four with Shift, Home and End reach the limits, Enter collapses and restores, and a double click puts the panel back on the measure its size step gives it — which is the Window Splitter pattern, and which no surveyed drawer answers.",
|
|
548
|
+
"language": "ts",
|
|
549
|
+
"source": "import { Component, computed, signal } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n} from '@slotted/angular/description-list';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerResizer,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\n\nconst LINES = [\n { term: 'Arabica beans, 5 kg', value: '6 cases, $420.00' },\n { term: 'Oat milk, 12 × 1 L', value: '4 cases, $192.00' },\n { term: 'Paper cups, 16 oz, 1,000 per case', value: '4 cases, $628.00' },\n];\n\n@Component({\n selector: 'app-drawer-resize',\n imports: [\n SlButton,\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerResizer,\n SlDrawerTitle,\n SlDrawerTrigger,\n ],\n template: `\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n View order lines\n </button>\n <sl-drawer #drawer=\"slDrawer\" [maxExtent]=\"0.8\" [minExtent]=\"0.25\" [(extent)]=\"extent\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Order SO-1182 lines</h2>\n <p slDrawerDescription>Width: {{ width() }}.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slDescriptionList>\n @for (line of lines; track line.term) {\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>{{ line.term }}</dt>\n <dd slDescriptionListDescription>{{ line.value }}</dd>\n </div>\n }\n </div>\n </div>\n <div slDrawerResizer></div>\n </sl-drawer>\n `,\n})\nexport class DrawerResize {\n readonly lines = LINES;\n readonly extent = signal<number | undefined>(undefined);\n readonly width = computed(() => {\n const extent = this.extent();\n return extent === undefined ? 'the md step' : `${Math.round(extent * 100)}% of the window`;\n });\n}\n",
|
|
550
|
+
"verdict": "example"
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
"id": "snapPoints",
|
|
554
|
+
"title": "Stops the sheet lands on",
|
|
555
|
+
"note": "A snap point is a stop of the same separator, so the arrows that move it move between them — which is the condition the guide puts on shipping snap points at all. A drag released below the first stop asks to close.",
|
|
556
|
+
"language": "html",
|
|
557
|
+
"source": "<sl-drawer side=\"bottom\" [snapPoints]=\"[0.3, 0.6, 0.95]\" [(extent)]=\"extent\">\n <div slDrawerResizer></div>\n <div slDrawerBody>…</div>\n</sl-drawer>\n",
|
|
558
|
+
"verdict": "excerpt"
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
"id": "sheet",
|
|
562
|
+
"title": "A bottom sheet as a phone draws one",
|
|
563
|
+
"note": "The sheet measures what it holds — the default size on top and bottom — stops at forty rems on a wide layer, and moves under a touch anywhere on its body. A downward drag with the list at its top moves the sheet; an upward one grows it to the next stop — the height of its content among them — before the list scrolls; a fling faster than 500 px/s goes to the next stop or closes. A tap on the grabber walks the stops.",
|
|
564
|
+
"language": "ts",
|
|
565
|
+
"source": "import { Component, computed, signal } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerResizer,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlFieldGroup, SlFieldGroupLegend } from '@slotted/angular/field-group';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlRadio, SlRadioGroup } from '@slotted/angular/radio-group';\nimport { SlText } from '@slotted/angular/typography';\n\nconst WINDOWS = [\n { value: 'morning', label: 'Thursday 8 October, 8 AM to noon' },\n { value: 'afternoon', label: 'Thursday 8 October, 1 to 5 PM' },\n { value: 'friday', label: 'Friday 9 October, 8 AM to noon' },\n];\n\n@Component({\n selector: 'app-drawer-sheet',\n imports: [\n SlButton,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerResizer,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlFieldGroup,\n SlFieldGroupLegend,\n SlInline,\n SlRadio,\n SlRadioGroup,\n SlText,\n ],\n template: `\n <div slInline align=\"center\" [gap]=\"3\">\n <span slText size=\"sm\">Pickup: {{ pickupLabel() }}</span>\n <button slButton size=\"sm\" tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Reschedule\n </button>\n <sl-drawer #drawer=\"slDrawer\" side=\"bottom\" [open]=\"open()\" (openChange)=\"toggle($event)\">\n <div slDrawerResizer></div>\n <header slDrawerHeader>\n <h2 slDrawerTitle>Reschedule pickup</h2>\n <p slDrawerDescription>Shipment SH-4471, UPS Ground from Reno, NV.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <fieldset slFieldGroup>\n <legend slFieldGroupLegend>Pickup window</legend>\n <div slRadioGroup [value]=\"draft()\" (valueChange)=\"draft.set($event.value ?? draft())\">\n @for (window of windows; track window.value) {\n <div slRadio [value]=\"window.value\">{{ window.label }}</div>\n }\n </div>\n </fieldset>\n </div>\n <footer slDrawerFooter>\n <button slButton variant=\"ghost\" tone=\"secondary\" (click)=\"open.set(false)\">\n Cancel\n </button>\n <button slButton (click)=\"reschedule()\">Reschedule</button>\n </footer>\n </sl-drawer>\n </div>\n `,\n})\nexport class DrawerSheet {\n readonly windows = WINDOWS;\n readonly open = signal(false);\n readonly pickup = signal('morning');\n readonly draft = signal(this.pickup());\n readonly pickupLabel = computed(\n () => WINDOWS.find((window) => window.value === this.pickup())?.label,\n );\n\n toggle(next: boolean): void {\n if (next) this.draft.set(this.pickup());\n this.open.set(next);\n }\n\n reschedule(): void {\n this.pickup.set(this.draft());\n this.open.set(false);\n }\n}\n",
|
|
566
|
+
"verdict": "example"
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
"id": "scrimFrom",
|
|
570
|
+
"title": "A sheet over a page that stays in use",
|
|
571
|
+
"note": "Below scrimFrom the scrim is not painted and a press reaches the page — the sheet over a map. It is written beside [modal]=\"false\" and outsidePress=\"none\", because an undimmed page that stayed inert would promise something it does not do. Move the sheet past sixty per cent and the scrim fades in.",
|
|
572
|
+
"language": "html",
|
|
573
|
+
"source": "<sl-drawer\n side=\"bottom\"\n [snapPoints]=\"[0.25, 0.6, 0.95]\"\n [(extent)]=\"extent\"\n [scrimFrom]=\"0.6\"\n [modal]=\"false\"\n outsidePress=\"none\"\n>\n …\n</sl-drawer>\n",
|
|
574
|
+
"verdict": "excerpt"
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
"id": "keyboard",
|
|
578
|
+
"title": "A sheet above the virtual keyboard",
|
|
579
|
+
"note": "On a phone the keyboard shrinks the visual viewport and leaves fixed layers under the keys. The open layer reads what the keyboard covers and recedes by it, so the sheet — and its footer — land above the keys. The button beside the scene writes the same property the binding writes, 260 pixels, to show it on a screen without one.",
|
|
580
|
+
"language": "html",
|
|
581
|
+
"source": "<sl-drawer side=\"bottom\" [(open)]=\"reminding\">\n <header slDrawerHeader><h2 slDrawerTitle>Enviar lembrete</h2></header>\n <div slDrawerBody>\n <input slTextField aria-label=\"Nota para o cliente\" />\n </div>\n <footer slDrawerFooter>…</footer>\n</sl-drawer>\n",
|
|
582
|
+
"verdict": "excerpt"
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
"id": "modal",
|
|
586
|
+
"title": "A drawer the page behind can still be used",
|
|
587
|
+
"note": "modal=\"false\" writes no aria-modal, makes nothing inert, locks no scroll and contains no focus. The APG warns that marking a container modal without doing all four is worse for a screen-reader reader than not marking it at all.",
|
|
588
|
+
"language": "html",
|
|
589
|
+
"source": "<sl-drawer [modal]=\"false\" [(open)]=\"open\">\n <div slDrawerBody>…</div>\n</sl-drawer>\n",
|
|
590
|
+
"verdict": "excerpt"
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
"id": "policy",
|
|
594
|
+
"title": "Refusing a close, and refusing it once",
|
|
595
|
+
"note": "Five ways to close and one output. A guard on openChangeRequest covers Escape, an outside press, the close button, the trigger and the imperative call together; Angular Material’s disableClose refuses two of them.",
|
|
596
|
+
"language": "html",
|
|
597
|
+
"source": "<sl-drawer [(open)]=\"open\" (openChangeRequest)=\"guard($event)\">…</sl-drawer>\n",
|
|
598
|
+
"verdict": "excerpt"
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
"id": "focus",
|
|
602
|
+
"title": "Where focus goes, and where it comes back to",
|
|
603
|
+
"note": "An overlay drawer takes focus on open and gives it back on close. An inline one takes nothing — a sidebar that stole focus every time a breakpoint crossed would be unusable — and still gives it back when it closes under the reader’s hands.",
|
|
604
|
+
"language": "html",
|
|
605
|
+
"source": "<sl-drawer [initialFocus]=\"search\">\n <div slDrawerBody>\n <input #search slTextField aria-label=\"Buscar\" />\n </div>\n</sl-drawer>\n",
|
|
606
|
+
"verdict": "excerpt"
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
"id": "loading",
|
|
610
|
+
"title": "Open before the content arrived",
|
|
611
|
+
"note": "The body carries aria-busy and keeps a floor so the panel does not jump to size when the data lands. The header, the close button, Escape and the separator all stay operable: a drawer a reader cannot leave is the worse failure of the two.",
|
|
612
|
+
"language": "ts",
|
|
613
|
+
"source": "import { Component, effect, signal } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n} from '@slotted/angular/description-list';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlSkeleton, SlSkeletonRegion } from '@slotted/angular/skeleton';\n\ninterface Shipment {\n carrier: string;\n tracking: string;\n packages: string;\n delivery: string;\n}\n\nconst FIELDS: { key: keyof Shipment; term: string; width: string }[] = [\n { key: 'carrier', term: 'Carrier', width: '6rem' },\n { key: 'tracking', term: 'Tracking number', width: '11rem' },\n { key: 'packages', term: 'Packages', width: '8rem' },\n { key: 'delivery', term: 'Estimated delivery', width: '9rem' },\n];\n\n@Component({\n selector: 'app-drawer-loading',\n imports: [\n SlButton,\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlSkeleton,\n SlSkeletonRegion,\n ],\n template: `\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Track shipment SH-4471\n </button>\n <sl-drawer #drawer=\"slDrawer\" [loading]=\"shipment() === null\" [(open)]=\"open\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Shipment SH-4471</h2>\n <p slDrawerDescription>Order SO-1182 for Contoso Foods, Seattle.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div\n slSkeletonRegion\n [delay]=\"200\"\n [loading]=\"shipment() === null\"\n [messages]=\"{ label: 'Loading shipment' }\"\n [minDuration]=\"400\"\n >\n <div slDescriptionList>\n @for (field of fields; track field.key) {\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>{{ field.term }}</dt>\n <dd slDescriptionListDescription>\n @if (shipment(); as loaded) {\n {{ loaded[field.key] }}\n } @else {\n <span slSkeleton [inlineSize]=\"field.width\"></span>\n }\n </dd>\n </div>\n }\n </div>\n </div>\n </div>\n </sl-drawer>\n `,\n})\nexport class DrawerLoading {\n readonly fields = FIELDS;\n readonly open = signal(false);\n readonly shipment = signal<Shipment | null>(null);\n\n constructor() {\n effect((onCleanup) => {\n if (!this.open()) return;\n this.shipment.set(null);\n const timer = setTimeout(\n () =>\n this.shipment.set({\n carrier: 'UPS Ground',\n tracking: '1Z 999 AA1 01 2345 6784',\n packages: '3, 18.4 kg in total',\n delivery: 'Thursday, 8 October',\n }),\n 1200,\n );\n onCleanup(() => clearTimeout(timer));\n });\n }\n}\n",
|
|
614
|
+
"verdict": "example"
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
"id": "nested",
|
|
618
|
+
"title": "A drawer opened from a drawer",
|
|
619
|
+
"note": "Escape reaches the topmost layer only, and a layer that refuses it stops the request reaching the one beneath. The depth comes from the single stack dismissable-layer keeps, so nothing here states a z-index.",
|
|
620
|
+
"language": "ts",
|
|
621
|
+
"source": "import { Component } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n} from '@slotted/angular/description-list';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlStack } from '@slotted/angular/stack';\n\nconst ORDER = [\n { term: 'Customer', value: 'Contoso Foods' },\n { term: 'Items', value: '14 cases, 3 products' },\n { term: 'Total', value: '$1,240.00' },\n];\n\nconst CUSTOMER = [\n { term: 'Account', value: 'C-0042' },\n { term: 'Contact', value: 'Ana Ruiz, ap@contoso.com' },\n { term: 'Open orders', value: '3, $4,815.50 in total' },\n { term: 'Payment terms', value: 'Net 30' },\n];\n\n@Component({\n selector: 'app-drawer-nested',\n imports: [\n SlButton,\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlInline,\n SlStack,\n ],\n template: `\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"order\">\n View order SO-1182\n </button>\n <sl-drawer #order=\"slDrawer\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Order SO-1182</h2>\n <p slDrawerDescription>Placed on 2 October 2026.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slStack [gap]=\"5\">\n <div slDescriptionList>\n @for (detail of orderDetails; track detail.term) {\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>{{ detail.term }}</dt>\n <dd slDescriptionListDescription>{{ detail.value }}</dd>\n </div>\n }\n </div>\n <div slInline>\n <button\n slButton\n size=\"sm\"\n tone=\"secondary\"\n variant=\"outline\"\n [slDrawerTrigger]=\"customer\"\n >\n View customer\n </button>\n </div>\n <sl-drawer #customer=\"slDrawer\" size=\"sm\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Contoso Foods</h2>\n <p slDrawerDescription>Customer since March 2021.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slDescriptionList>\n @for (detail of customerDetails; track detail.term) {\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>{{ detail.term }}</dt>\n <dd slDescriptionListDescription>{{ detail.value }}</dd>\n </div>\n }\n </div>\n </div>\n </sl-drawer>\n </div>\n </div>\n </sl-drawer>\n `,\n})\nexport class DrawerNested {\n readonly orderDetails = ORDER;\n readonly customerDetails = CUSTOMER;\n}\n",
|
|
622
|
+
"verdict": "example"
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
"id": "content",
|
|
626
|
+
"title": "Content the family did not choose",
|
|
627
|
+
"note": "A ninety-character token in a title breaks rather than widening the panel, and a body longer than the layer scrolls while the actions hold still. MUI and Angular Material ship no layout, so a footer past the fold is the default of following either.",
|
|
628
|
+
"language": "html",
|
|
629
|
+
"source": "<sl-drawer>\n <header slDrawerHeader>\n <h2 slDrawerTitle>{{ fileName }}</h2>\n </header>\n <div slDrawerBody>{{ longText }}</div>\n <footer slDrawerFooter><button slButton>Salvar</button></footer>\n</sl-drawer>\n",
|
|
630
|
+
"verdict": "excerpt"
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
"id": "composition",
|
|
634
|
+
"title": "The parts are the consumer’s own elements",
|
|
635
|
+
"note": "Every part is a directive on an element the consumer wrote, so the trigger is the library’s button and an inline panel’s content is a nav — nothing is reimplemented and nothing is wrapped. An empty list inside the body is result-state, which owns that question.",
|
|
636
|
+
"language": "html",
|
|
637
|
+
"source": "<button slButton variant=\"outline\" [slDrawerTrigger]=\"d\">Abrir</button>\n<sl-drawer #d=\"slDrawer\" mode=\"inline\" side=\"start\">\n <nav slDrawerBody aria-label=\"Seções\">…</nav>\n</sl-drawer>\n",
|
|
638
|
+
"verdict": "excerpt"
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"id": "defaults",
|
|
642
|
+
"title": "What an application decides once",
|
|
643
|
+
"note": "Seven axes set for a whole injector rather than repeated on every drawer in a product. A drawer that states any of them itself still wins, because an explicit consumer value always does.",
|
|
644
|
+
"language": "ts",
|
|
645
|
+
"source": "import { Component } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n provideDrawerDefaults,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlText } from '@slotted/angular/typography';\n\n@Component({\n selector: 'app-drawer-defaults',\n imports: [\n SlButton,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlInline,\n SlText,\n ],\n providers: [provideDrawerDefaults({ side: 'start', size: 'sm' })],\n template: `\n <div slInline [gap]=\"2\">\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"warehouses\">\n Warehouses\n </button>\n <sl-drawer #warehouses=\"slDrawer\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Warehouses</h2>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <span slText size=\"sm\">From the start edge and small, both from the provider.</span>\n </div>\n </sl-drawer>\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"carriers\">\n Carriers\n </button>\n <sl-drawer #carriers=\"slDrawer\" size=\"lg\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Carriers</h2>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <span slText size=\"sm\">\n From the start edge, from the provider, and large because this drawer says so.\n </span>\n </div>\n </sl-drawer>\n </div>\n `,\n})\nexport class DrawerDefaults {}\n",
|
|
646
|
+
"verdict": "example"
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
"id": "accessibility",
|
|
650
|
+
"title": "What a reader hears, and what they can reach",
|
|
651
|
+
"note": "The title names the panel and the separator; the trigger says expanded in both modes and haspopup in one. Tab wraps inside a modal panel, and the closed panel of an inline drawer is inert so the collapse the eye reads and the tab order agree.",
|
|
652
|
+
"language": "html",
|
|
653
|
+
"source": "<sl-drawer mode=\"inline\" side=\"start\">\n <header slDrawerHeader><h2 slDrawerTitle>Coleções</h2></header>\n <div slDrawerResizer></div>\n</sl-drawer>\n",
|
|
654
|
+
"verdict": "excerpt"
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
"id": "basic",
|
|
658
|
+
"title": "basic.ts",
|
|
659
|
+
"note": null,
|
|
660
|
+
"language": "ts",
|
|
661
|
+
"source": "import { Component, signal } from '@angular/core';\nimport { SlBadge } from '@slotted/angular/badge';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n} from '@slotted/angular/description-list';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlStack } from '@slotted/angular/stack';\n\nconst DETAILS = [\n { term: 'Ship to', value: '1200 Harbor Ave, Seattle, WA' },\n { term: 'Payment', value: 'Captured, card ending 4242' },\n { term: 'Items', value: '14 cases, 3 products' },\n { term: 'Warehouse', value: 'Reno, NV' },\n { term: 'Total', value: '$1,240.00' },\n];\n\n@Component({\n selector: 'app-drawer-basic',\n imports: [\n SlBadge,\n SlButton,\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlInline,\n SlStack,\n ],\n template: `\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n View order SO-1182\n </button>\n <sl-drawer #drawer=\"slDrawer\" [(open)]=\"open\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Order SO-1182</h2>\n <p slDrawerDescription>Contoso Foods, placed on 2 October 2026.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slStack [gap]=\"4\">\n <div slInline>\n <span slBadge tone=\"accent\">Ready to ship</span>\n </div>\n <div slDescriptionList>\n @for (detail of details; track detail.term) {\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>{{ detail.term }}</dt>\n <dd slDescriptionListDescription>{{ detail.value }}</dd>\n </div>\n }\n </div>\n </div>\n </div>\n <footer slDrawerFooter>\n <button slButton variant=\"ghost\" tone=\"secondary\" (click)=\"open.set(false)\">Close</button>\n <button slButton (click)=\"open.set(false)\">Create shipment</button>\n </footer>\n </sl-drawer>\n `,\n})\nexport class DrawerBasic {\n readonly open = signal(false);\n readonly details = DETAILS;\n}\n",
|
|
662
|
+
"verdict": "example"
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
"id": "detail-panel",
|
|
666
|
+
"title": "detail-panel.ts",
|
|
667
|
+
"note": null,
|
|
668
|
+
"language": "ts",
|
|
669
|
+
"source": "import { Component, signal } from '@angular/core';\nimport { SlBadge } from '@slotted/angular/badge';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n} from '@slotted/angular/description-list';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerTitle,\n} from '@slotted/angular/drawer';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlStack } from '@slotted/angular/stack';\nimport {\n SlTable,\n SlTableBody,\n SlTableCell,\n SlTableColumnHeader,\n SlTableContent,\n SlTableHead,\n SlTableRow,\n SlTableRowHeader,\n} from '@slotted/angular/table';\nimport { SlVisuallyHidden } from '@slotted/angular/visually-hidden';\n\nconst ORDERS = [\n {\n id: 'SO-1182',\n customer: 'Contoso Foods',\n city: 'Seattle, WA',\n status: 'Ready to ship',\n tone: 'accent',\n items: '14 cases, 3 products',\n total: '$1,240.00',\n },\n {\n id: 'SO-1183',\n customer: 'Fabrikam Grocers',\n city: 'Portland, OR',\n status: 'Shipped',\n tone: 'success',\n items: '6 cases, 2 products',\n total: '$386.50',\n },\n {\n id: 'SO-1184',\n customer: 'Tailspin Market',\n city: 'Boise, ID',\n status: 'On hold',\n tone: 'warning',\n items: '22 cases, 5 products',\n total: '$2,075.25',\n },\n {\n id: 'SO-1185',\n customer: 'Adventure Works',\n city: 'Denver, CO',\n status: 'Ready to ship',\n tone: 'accent',\n items: '9 cases, 4 products',\n total: '$918.00',\n },\n] as const;\n\ntype Order = (typeof ORDERS)[number];\n\n@Component({\n selector: 'app-drawer-detail-panel',\n imports: [\n SlBadge,\n SlButton,\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerTitle,\n SlInline,\n SlStack,\n SlTable,\n SlTableBody,\n SlTableCell,\n SlTableColumnHeader,\n SlTableContent,\n SlTableHead,\n SlTableRow,\n SlTableRowHeader,\n SlVisuallyHidden,\n ],\n template: `\n <div slTable [columns]=\"4\">\n <div slTableContent>\n <thead slTableHead>\n <tr slTableRow>\n <th slTableColumnHeader>Order</th>\n <th slTableColumnHeader>Customer</th>\n <th slTableColumnHeader numeric>Total</th>\n <th slTableColumnHeader><span slVisuallyHidden>Actions</span></th>\n </tr>\n </thead>\n <tbody slTableBody>\n @for (row of orders; track row.id) {\n <tr slTableRow [value]=\"row.id\">\n <th slTableRowHeader>{{ row.id }}</th>\n <td slTableCell>{{ row.customer }}</td>\n <td slTableCell numeric>{{ row.total }}</td>\n <td slTableCell>\n <button\n slButton\n size=\"sm\"\n tone=\"secondary\"\n variant=\"ghost\"\n [attr.aria-label]=\"'View ' + row.id\"\n (click)=\"view(row)\"\n >\n View\n </button>\n </td>\n </tr>\n }\n </tbody>\n </div>\n </div>\n <sl-drawer [modal]=\"false\" outsidePress=\"none\" [scrimFrom]=\"1\" size=\"sm\" [(open)]=\"open\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Order {{ order().id }}</h2>\n <p slDrawerDescription>{{ order().customer }}, {{ order().city }}</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slStack [gap]=\"4\">\n <div slInline>\n <span slBadge [tone]=\"order().tone\">{{ order().status }}</span>\n </div>\n <div slDescriptionList>\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>Items</dt>\n <dd slDescriptionListDescription>{{ order().items }}</dd>\n </div>\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>Total</dt>\n <dd slDescriptionListDescription>{{ order().total }}</dd>\n </div>\n </div>\n </div>\n </div>\n </sl-drawer>\n `,\n})\nexport class DrawerDetailPanel {\n readonly orders = ORDERS;\n readonly open = signal(false);\n readonly order = signal<Order>(ORDERS[0]);\n\n view(row: Order): void {\n this.order.set(row);\n this.open.set(true);\n }\n}\n",
|
|
670
|
+
"verdict": "example"
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
"id": "filters",
|
|
674
|
+
"title": "filters.ts",
|
|
675
|
+
"note": null,
|
|
676
|
+
"language": "ts",
|
|
677
|
+
"source": "import { Component, computed, signal } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport { SlCheckbox } from '@slotted/angular/checkbox';\nimport { SlCheckboxGroup } from '@slotted/angular/checkbox-group';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlFieldGroup, SlFieldGroupLegend } from '@slotted/angular/field-group';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlRadio, SlRadioGroup } from '@slotted/angular/radio-group';\nimport { SlStack } from '@slotted/angular/stack';\nimport { SlText } from '@slotted/angular/typography';\n\nconst ORDERS = [\n { id: 'SO-1182', status: 'processing', warehouse: 'RNO' },\n { id: 'SO-1183', status: 'shipped', warehouse: 'CMH' },\n { id: 'SO-1184', status: 'on-hold', warehouse: 'RNO' },\n { id: 'SO-1185', status: 'processing', warehouse: 'SAV' },\n { id: 'SO-1186', status: 'shipped', warehouse: 'RNO' },\n { id: 'SO-1187', status: 'processing', warehouse: 'CMH' },\n { id: 'SO-1188', status: 'on-hold', warehouse: 'SAV' },\n { id: 'SO-1189', status: 'processing', warehouse: 'RNO' },\n];\n\ninterface Filters {\n statuses: readonly string[];\n warehouse: string;\n}\n\nconst ALL: Filters = { statuses: ['processing', 'shipped', 'on-hold'], warehouse: 'any' };\n\nconst matching = (filters: Filters) =>\n ORDERS.filter(\n (order) =>\n filters.statuses.includes(order.status) &&\n (filters.warehouse === 'any' || order.warehouse === filters.warehouse),\n ).length;\n\n@Component({\n selector: 'app-drawer-filters',\n imports: [\n SlButton,\n SlCheckbox,\n SlCheckboxGroup,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlFieldGroup,\n SlFieldGroupLegend,\n SlInline,\n SlRadio,\n SlRadioGroup,\n SlStack,\n SlText,\n ],\n template: `\n <div slInline align=\"center\" [gap]=\"3\">\n <span slText size=\"sm\">{{ shown() }} of {{ total }} orders</span>\n <button slButton size=\"sm\" tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Filters\n </button>\n <sl-drawer #drawer=\"slDrawer\" size=\"sm\" [open]=\"open()\" (openChange)=\"toggle($event)\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Filter orders</h2>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slStack [gap]=\"6\">\n <fieldset slFieldGroup>\n <legend slFieldGroupLegend>Status</legend>\n <div\n slCheckboxGroup\n [value]=\"draft().statuses\"\n (valueChange)=\"draft.set({ statuses: $event.value, warehouse: draft().warehouse })\"\n >\n <div slCheckbox value=\"processing\">Processing</div>\n <div slCheckbox value=\"shipped\">Shipped</div>\n <div slCheckbox value=\"on-hold\">On hold</div>\n </div>\n </fieldset>\n <fieldset slFieldGroup>\n <legend slFieldGroupLegend>Warehouse</legend>\n <div\n slRadioGroup\n [value]=\"draft().warehouse\"\n (valueChange)=\"\n draft.set({ statuses: draft().statuses, warehouse: $event.value ?? 'any' })\n \"\n >\n <div slRadio value=\"any\">Any warehouse</div>\n <div slRadio value=\"RNO\">Reno, NV</div>\n <div slRadio value=\"CMH\">Columbus, OH</div>\n <div slRadio value=\"SAV\">Savannah, GA</div>\n </div>\n </fieldset>\n </div>\n </div>\n <footer slDrawerFooter>\n <button slButton variant=\"ghost\" tone=\"secondary\" (click)=\"draft.set(all)\">Reset</button>\n <button slButton (click)=\"apply()\">Show {{ count() }} orders</button>\n </footer>\n </sl-drawer>\n </div>\n `,\n})\nexport class DrawerFilters {\n readonly all = ALL;\n readonly total = ORDERS.length;\n readonly open = signal(false);\n readonly applied = signal<Filters>(ALL);\n readonly draft = signal<Filters>(ALL);\n readonly shown = computed(() => matching(this.applied()));\n readonly count = computed(() => matching(this.draft()));\n\n toggle(next: boolean): void {\n if (next) this.draft.set(this.applied());\n this.open.set(next);\n }\n\n apply(): void {\n this.applied.set(this.draft());\n this.open.set(false);\n }\n}\n",
|
|
678
|
+
"verdict": "example"
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
"id": "form",
|
|
682
|
+
"title": "form.ts",
|
|
683
|
+
"note": null,
|
|
684
|
+
"language": "ts",
|
|
685
|
+
"source": "import { Component, computed, signal } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlField, SlFieldError, SlFieldLabel } from '@slotted/angular/field';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlSelect, SlSelectItem } from '@slotted/angular/select';\nimport { SlStack } from '@slotted/angular/stack';\nimport { SlTextField, SlTextFieldInput } from '@slotted/angular/text-field';\nimport { SlText } from '@slotted/angular/typography';\n\nconst TERMS = [\n { value: 'due', label: 'Due on receipt' },\n { value: 'net-15', label: 'Net 15' },\n { value: 'net-30', label: 'Net 30' },\n { value: 'net-60', label: 'Net 60' },\n];\n\nconst CUSTOMER = { name: 'Contoso Foods', email: 'ap@contoso.com', terms: 'net-30' };\n\nconst termsLabel = (value: string) => TERMS.find((option) => option.value === value)?.label;\n\nfunction nameError(value: string): string {\n return value.trim() === '' ? 'Enter the name printed on invoices.' : '';\n}\n\nfunction emailError(value: string): string {\n if (value.trim() === '') return 'Enter the address invoices are sent to.';\n if (!/^\\S+@\\S+\\.\\S+$/.test(value)) return 'Enter an address like ap@contoso.com.';\n return '';\n}\n\n@Component({\n selector: 'app-drawer-form',\n imports: [\n SlButton,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlField,\n SlFieldError,\n SlFieldLabel,\n SlInline,\n SlSelect,\n SlSelectItem,\n SlStack,\n SlText,\n SlTextField,\n SlTextFieldInput,\n ],\n template: `\n <div slInline align=\"center\" [gap]=\"3\">\n <span slText role=\"status\" size=\"sm\" tone=\"muted\">\n {{ customer().name }}, {{ customer().email }}, {{ termsLabel(customer().terms) }}\n </span>\n <button slButton [slDrawerTrigger]=\"drawer\">Edit customer</button>\n <sl-drawer #drawer=\"slDrawer\" [open]=\"open()\" (openChange)=\"toggle($event)\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Edit customer</h2>\n <p slDrawerDescription>Account C-0042, customer since March 2021.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <form id=\"edit-customer\" novalidate (submit)=\"submit($event)\">\n <div slStack [gap]=\"4\">\n <div slField required [invalid]=\"errors()?.name ? true : undefined\">\n <label slFieldLabel>Company name</label>\n <div slTextField>\n <input\n slTextFieldInput\n autocomplete=\"organization\"\n [value]=\"name()\"\n (valueChange)=\"name.set($event.value)\"\n />\n </div>\n <span slFieldError live=\"polite\" reserve>{{ errors()?.name }}</span>\n </div>\n <div slField required [invalid]=\"errors()?.email ? true : undefined\">\n <label slFieldLabel>Billing email</label>\n <div slTextField>\n <input\n slTextFieldInput\n type=\"email\"\n [value]=\"email()\"\n (valueChange)=\"email.set($event.value)\"\n />\n </div>\n <span slFieldError live=\"polite\" reserve>{{ errors()?.email }}</span>\n </div>\n <div slField>\n <label slFieldLabel>Payment terms</label>\n <sl-select [items]=\"terms\" [(value)]=\"term\">\n @for (option of terms; track option.value) {\n <sl-select-item [value]=\"option.value\">{{ option.label }}</sl-select-item>\n }\n </sl-select>\n </div>\n </div>\n </form>\n </div>\n <footer slDrawerFooter>\n <button slButton variant=\"ghost\" tone=\"secondary\" (click)=\"open.set(false)\">\n Cancel\n </button>\n <button slButton type=\"submit\" form=\"edit-customer\">Save customer</button>\n </footer>\n </sl-drawer>\n </div>\n `,\n})\nexport class DrawerForm {\n readonly terms = TERMS;\n readonly termsLabel = termsLabel;\n readonly open = signal(false);\n readonly customer = signal(CUSTOMER);\n readonly name = signal(CUSTOMER.name);\n readonly email = signal(CUSTOMER.email);\n readonly term = signal<string | null>(CUSTOMER.terms);\n readonly submitted = signal(false);\n readonly errors = computed(() =>\n this.submitted() ? { name: nameError(this.name()), email: emailError(this.email()) } : null,\n );\n\n toggle(next: boolean): void {\n if (next) {\n this.name.set(this.customer().name);\n this.email.set(this.customer().email);\n this.term.set(this.customer().terms);\n this.submitted.set(false);\n }\n this.open.set(next);\n }\n\n submit(event: Event): void {\n event.preventDefault();\n this.submitted.set(true);\n if (nameError(this.name()) !== '' || emailError(this.email()) !== '') return;\n this.customer.set({\n name: this.name().trim(),\n email: this.email().trim(),\n terms: this.term() ?? this.customer().terms,\n });\n this.open.set(false);\n }\n}\n",
|
|
686
|
+
"verdict": "example"
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
"id": "inline",
|
|
690
|
+
"title": "inline.ts",
|
|
691
|
+
"note": null,
|
|
692
|
+
"language": "ts",
|
|
693
|
+
"source": "import { Component, computed, signal } from '@angular/core';\nimport { SlBadge } from '@slotted/angular/badge';\nimport { SlButton } from '@slotted/angular/button';\nimport { SlCheckbox } from '@slotted/angular/checkbox';\nimport { SlCheckboxGroup } from '@slotted/angular/checkbox-group';\nimport { SlDrawer, SlDrawerBody, SlDrawerTrigger } from '@slotted/angular/drawer';\nimport { SlFieldGroup, SlFieldGroupLegend } from '@slotted/angular/field-group';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlStack } from '@slotted/angular/stack';\nimport { SlText } from '@slotted/angular/typography';\n\nconst STATUSES = [\n { value: 'processing', label: 'Processing', tone: 'accent' },\n { value: 'shipped', label: 'Shipped', tone: 'success' },\n { value: 'on-hold', label: 'On hold', tone: 'warning' },\n] as const;\n\nconst ORDERS = [\n { id: 'SO-1182', customer: 'Contoso Foods', status: 'processing' },\n { id: 'SO-1183', customer: 'Fabrikam Grocers', status: 'shipped' },\n { id: 'SO-1184', customer: 'Tailspin Market', status: 'on-hold' },\n { id: 'SO-1185', customer: 'Adventure Works', status: 'processing' },\n { id: 'SO-1186', customer: 'Litware Deli', status: 'shipped' },\n] as const;\n\n@Component({\n selector: 'app-drawer-inline',\n imports: [\n SlBadge,\n SlButton,\n SlCheckbox,\n SlCheckboxGroup,\n SlDrawer,\n SlDrawerBody,\n SlDrawerTrigger,\n SlFieldGroup,\n SlFieldGroupLegend,\n SlInline,\n SlStack,\n SlText,\n ],\n template: `\n <div slStack [gap]=\"3\">\n <div slInline>\n <button slButton size=\"sm\" tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Filters\n </button>\n </div>\n <div\n style=\"\n display: flex;\n flex-wrap: wrap;\n min-block-size: 16rem;\n border: 1px solid var(--slotted-border-subtle);\n border-radius: var(--slotted-radius-lg);\n overflow: hidden;\n \"\n >\n <sl-drawer #drawer=\"slDrawer\" mode=\"inline\" side=\"start\" size=\"sm\" [(open)]=\"open\">\n <div slDrawerBody>\n <fieldset slFieldGroup>\n <legend slFieldGroupLegend>Status</legend>\n <div slCheckboxGroup [value]=\"statuses()\" (valueChange)=\"statuses.set($event.value)\">\n @for (status of options; track status.value) {\n <div slCheckbox [value]=\"status.value\">{{ status.label }}</div>\n }\n </div>\n </fieldset>\n </div>\n </sl-drawer>\n <div slStack [gap]=\"3\" style=\"flex: 1 1 12rem; padding: var(--slotted-space-6)\">\n <span slText size=\"sm\" tone=\"muted\">{{ shown().length }} of {{ total }} orders</span>\n @for (order of shown(); track order.id) {\n <div slInline align=\"center\" [gap]=\"3\" justify=\"between\">\n <div slStack [gap]=\"0\">\n <span slText size=\"sm\" weight=\"semibold\">{{ order.id }}</span>\n <span slText size=\"sm\" tone=\"muted\">{{ order.customer }}</span>\n </div>\n <span slBadge [tone]=\"statusOf(order.status).tone\">\n {{ statusOf(order.status).label }}\n </span>\n </div>\n }\n </div>\n </div>\n </div>\n `,\n})\nexport class DrawerInline {\n readonly options = STATUSES;\n readonly total = ORDERS.length;\n readonly open = signal(true);\n readonly statuses = signal<readonly string[]>(['processing', 'on-hold']);\n readonly shown = computed(() => ORDERS.filter((order) => this.statuses().includes(order.status)));\n\n statusOf(value: string) {\n return STATUSES.find((item) => item.value === value)!;\n }\n}\n",
|
|
694
|
+
"verdict": "example"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"id": "long-content",
|
|
698
|
+
"title": "long-content.ts",
|
|
699
|
+
"note": null,
|
|
700
|
+
"language": "ts",
|
|
701
|
+
"source": "import { Component, signal } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlStack } from '@slotted/angular/stack';\nimport { SlText } from '@slotted/angular/typography';\n\nconst EVENTS = [\n { at: 'Oct 6, 7:42 AM', what: 'Out for delivery, Seattle, WA' },\n { at: 'Oct 6, 5:10 AM', what: 'Arrived at the delivery facility, Seattle, WA' },\n { at: 'Oct 5, 11:58 PM', what: 'Departed facility, Portland, OR' },\n { at: 'Oct 5, 9:20 PM', what: 'Arrived at facility, Portland, OR' },\n { at: 'Oct 5, 2:04 PM', what: 'Departed facility, Medford, OR' },\n { at: 'Oct 5, 10:37 AM', what: 'Arrived at facility, Medford, OR' },\n { at: 'Oct 4, 11:15 PM', what: 'Departed facility, Sacramento, CA' },\n { at: 'Oct 4, 6:48 PM', what: 'Arrived at facility, Sacramento, CA' },\n { at: 'Oct 4, 1:30 PM', what: 'Departed facility, Reno, NV' },\n { at: 'Oct 4, 9:02 AM', what: 'Processed at the origin facility, Reno, NV' },\n { at: 'Oct 3, 6:15 PM', what: 'Picked up from the Northwind warehouse, Reno, NV' },\n { at: 'Oct 3, 4:40 PM', what: 'Weighed and labelled: 3 packages, 18.4 kg' },\n { at: 'Oct 3, 2:12 PM', what: 'Packed at station 4, Reno, NV' },\n { at: 'Oct 3, 11:05 AM', what: 'Picked from aisles 12, 14 and 21' },\n { at: 'Oct 2, 4:55 PM', what: 'Released to the warehouse' },\n { at: 'Oct 2, 4:31 PM', what: 'Payment captured, card ending 4242' },\n];\n\n@Component({\n selector: 'app-drawer-long-content',\n imports: [\n SlButton,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlStack,\n SlText,\n ],\n template: `\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Tracking history\n </button>\n <sl-drawer #drawer=\"slDrawer\" [(open)]=\"open\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Tracking 1Z999AA10123456784</h2>\n <p slDrawerDescription>Shipment SH-4471, 16 events since 2 October.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slStack [gap]=\"4\">\n @for (event of events; track event.at) {\n <div slStack [gap]=\"0\">\n <span slText size=\"sm\" tone=\"muted\">{{ event.at }}</span>\n <span slText size=\"sm\">{{ event.what }}</span>\n </div>\n }\n </div>\n </div>\n <footer slDrawerFooter>\n <button slButton variant=\"ghost\" tone=\"secondary\" (click)=\"open.set(false)\">Close</button>\n <button slButton>Email to customer</button>\n </footer>\n </sl-drawer>\n `,\n})\nexport class DrawerLongContent {\n readonly events = EVENTS;\n readonly open = signal(false);\n}\n",
|
|
702
|
+
"verdict": "example"
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
"id": "non-modal",
|
|
706
|
+
"title": "non-modal.ts",
|
|
707
|
+
"note": null,
|
|
708
|
+
"language": "ts",
|
|
709
|
+
"source": "import { Component } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n} from '@slotted/angular/description-list';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlField, SlFieldDescription, SlFieldLabel } from '@slotted/angular/field';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlStack } from '@slotted/angular/stack';\nimport { SlTextField, SlTextFieldInput } from '@slotted/angular/text-field';\n\nconst RATES = [\n { term: 'UPS Ground', value: '$38.40, 3 business days' },\n { term: 'FedEx Home Delivery', value: '$41.15, 3 business days' },\n { term: 'UPS 2nd Day Air', value: '$96.80, 2 business days' },\n { term: 'FedEx Priority Overnight', value: '$184.25, next business day' },\n];\n\n@Component({\n selector: 'app-drawer-non-modal',\n imports: [\n SlButton,\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlField,\n SlFieldDescription,\n SlFieldLabel,\n SlInline,\n SlStack,\n SlTextField,\n SlTextFieldInput,\n ],\n template: `\n <div slStack [gap]=\"4\">\n <div slField>\n <label slFieldLabel>Shipping charge</label>\n <div slTextField>\n <input slTextFieldInput inputmode=\"decimal\" placeholder=\"0.00\" />\n </div>\n <span slFieldDescription>Charged to Contoso Foods on invoice INV-2041.</span>\n </div>\n <div slInline>\n <button slButton size=\"sm\" tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Show carrier rates\n </button>\n </div>\n <sl-drawer #drawer=\"slDrawer\" [modal]=\"false\" outsidePress=\"none\" [scrimFrom]=\"1\" size=\"sm\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Carrier rates</h2>\n <p slDrawerDescription>3 packages, 18.4 kg, Reno to Seattle.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slDescriptionList>\n @for (rate of rates; track rate.term) {\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>{{ rate.term }}</dt>\n <dd slDescriptionListDescription>{{ rate.value }}</dd>\n </div>\n }\n </div>\n </div>\n </sl-drawer>\n </div>\n `,\n})\nexport class DrawerNonModal {\n readonly rates = RATES;\n}\n",
|
|
710
|
+
"verdict": "example"
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
"id": "pin",
|
|
714
|
+
"title": "pin.ts",
|
|
715
|
+
"note": null,
|
|
716
|
+
"language": "ts",
|
|
717
|
+
"source": "import { Component, signal } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n} from '@slotted/angular/description-list';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlField, SlFieldLabel } from '@slotted/angular/field';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlStack } from '@slotted/angular/stack';\nimport { SlTextarea } from '@slotted/angular/textarea';\n\nconst DETAILS = [\n { term: 'Customer', value: 'Contoso Foods, Seattle' },\n { term: 'Items', value: '14 cases, 3 products' },\n { term: 'Warehouse', value: 'Reno, NV' },\n];\n\n@Component({\n selector: 'app-drawer-pin',\n imports: [\n SlButton,\n SlDescriptionList,\n SlDescriptionListDescription,\n SlDescriptionListItem,\n SlDescriptionListTerm,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlField,\n SlFieldLabel,\n SlInline,\n SlStack,\n SlTextarea,\n ],\n template: `\n <div slStack [gap]=\"3\">\n <div slInline>\n <button slButton size=\"sm\" tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Notes\n </button>\n </div>\n <div\n style=\"\n display: flex;\n flex-wrap: wrap;\n min-block-size: 18rem;\n border: 1px solid var(--slotted-border-subtle);\n border-radius: var(--slotted-radius-lg);\n overflow: hidden;\n \"\n >\n <div style=\"flex: 1 1 12rem; padding: var(--slotted-space-6)\">\n <div slDescriptionList>\n @for (detail of details; track detail.term) {\n <div slDescriptionListItem>\n <dt slDescriptionListTerm>{{ detail.term }}</dt>\n <dd slDescriptionListDescription>{{ detail.value }}</dd>\n </div>\n }\n </div>\n </div>\n <sl-drawer\n #drawer=\"slDrawer\"\n size=\"sm\"\n [mode]=\"pinned() ? 'inline' : 'overlay'\"\n [(open)]=\"open\"\n >\n <header slDrawerHeader>\n <h2 slDrawerTitle>Notes on SO-1182</h2>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slField>\n <label slFieldLabel>Note for the warehouse</label>\n <textarea\n slTextarea\n placeholder=\"Pallet height, dock number, contact on site\"\n ></textarea>\n </div>\n </div>\n <footer slDrawerFooter>\n <button\n slButton\n size=\"sm\"\n tone=\"secondary\"\n variant=\"outline\"\n (click)=\"pinned.set(!pinned())\"\n >\n {{ pinned() ? 'Unpin' : 'Pin beside the order' }}\n </button>\n </footer>\n </sl-drawer>\n </div>\n </div>\n `,\n})\nexport class DrawerPin {\n readonly details = DETAILS;\n readonly open = signal(false);\n readonly pinned = signal(false);\n}\n",
|
|
718
|
+
"verdict": "example"
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
"id": "sides",
|
|
722
|
+
"title": "sides.ts",
|
|
723
|
+
"note": null,
|
|
724
|
+
"language": "ts",
|
|
725
|
+
"source": "import { Component } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlText } from '@slotted/angular/typography';\n\nconst SIDES = [\n {\n side: 'start',\n label: 'Start',\n title: 'Warehouses',\n body: 'Reno, Columbus and Savannah. A panel from the start edge suits navigation between sites.',\n },\n {\n side: 'end',\n label: 'End',\n title: 'Order SO-1182',\n body: 'Contoso Foods, 14 cases. The end edge is the default and suits the details of a row.',\n },\n {\n side: 'top',\n label: 'Top',\n title: 'Carrier notice',\n body: 'UPS pickups from Reno run two hours late today. A panel from the top suits a notice that belongs to the whole screen.',\n },\n {\n side: 'bottom',\n label: 'Bottom',\n title: '3 orders selected',\n body: 'SO-1182, SO-1183 and SO-1184. A sheet from the bottom suits actions on a phone, within reach of the thumb.',\n },\n] as const;\n\n@Component({\n selector: 'app-drawer-sides',\n imports: [\n SlButton,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlInline,\n SlText,\n ],\n template: `\n <div slInline [gap]=\"2\">\n @for (item of sides; track item.side) {\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n {{ item.label }}\n </button>\n <sl-drawer #drawer=\"slDrawer\" [side]=\"item.side\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>{{ item.title }}</h2>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <span slText size=\"sm\">{{ item.body }}</span>\n </div>\n </sl-drawer>\n }\n </div>\n `,\n})\nexport class DrawerSides {\n readonly sides = SIDES;\n}\n",
|
|
726
|
+
"verdict": "example"
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
"id": "sizes",
|
|
730
|
+
"title": "sizes.ts",
|
|
731
|
+
"note": null,
|
|
732
|
+
"language": "ts",
|
|
733
|
+
"source": "import { Component } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlText } from '@slotted/angular/typography';\n\nconst SIZES = [\n { size: 'sm', body: '18rem. One field or a short list, such as the carrier for a shipment.' },\n { size: 'md', body: '24rem, the default. The details of an order or a short form.' },\n { size: 'lg', body: '30rem. A record with a table of lines, such as the items of an order.' },\n { size: 'xl', body: '40rem. Two columns, such as a customer and their open orders.' },\n { size: 'full', body: 'The whole screen. A task that needs every column, such as a pick list.' },\n] as const;\n\n@Component({\n selector: 'app-drawer-sizes',\n imports: [\n SlButton,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlInline,\n SlText,\n ],\n template: `\n <div slInline [gap]=\"2\">\n @for (item of sizes; track item.size) {\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n {{ item.size }}\n </button>\n <sl-drawer #drawer=\"slDrawer\" [size]=\"item.size\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Shipment SH-4471</h2>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <span slText size=\"sm\">{{ item.body }}</span>\n </div>\n </sl-drawer>\n }\n </div>\n `,\n})\nexport class DrawerSizes {\n readonly sizes = SIZES;\n}\n",
|
|
734
|
+
"verdict": "example"
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
"id": "snap-points",
|
|
738
|
+
"title": "snap-points.ts",
|
|
739
|
+
"note": null,
|
|
740
|
+
"language": "ts",
|
|
741
|
+
"source": "import { Component, signal } from '@angular/core';\nimport { SlBadge } from '@slotted/angular/badge';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerResizer,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport { SlInline } from '@slotted/angular/inline';\nimport { SlStack } from '@slotted/angular/stack';\nimport { SlText } from '@slotted/angular/typography';\n\nconst SHIPMENTS = [\n { id: 'SH-4471', to: 'Contoso Foods, Seattle', status: 'In transit', tone: 'accent' },\n { id: 'SH-4472', to: 'Fabrikam Grocers, Portland', status: 'In transit', tone: 'accent' },\n { id: 'SH-4473', to: 'Tailspin Market, Boise', status: 'Delayed', tone: 'warning' },\n { id: 'SH-4474', to: 'Adventure Works, Denver', status: 'In transit', tone: 'accent' },\n {\n id: 'SH-4475',\n to: 'Litware Deli, Salt Lake City',\n status: 'Out for delivery',\n tone: 'success',\n },\n { id: 'SH-4476', to: 'Proseware Cafe, Spokane', status: 'In transit', tone: 'accent' },\n { id: 'SH-4477', to: 'Wingtip Bakery, Eugene', status: 'Delayed', tone: 'warning' },\n { id: 'SH-4478', to: 'Coho Winery, Walla Walla', status: 'Out for delivery', tone: 'success' },\n { id: 'SH-4479', to: 'Northwind Outlet, Reno', status: 'In transit', tone: 'accent' },\n { id: 'SH-4480', to: 'Fourth Coffee, Tacoma', status: 'In transit', tone: 'accent' },\n] as const;\n\n@Component({\n selector: 'app-drawer-snap-points',\n imports: [\n SlBadge,\n SlButton,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerHeader,\n SlDrawerResizer,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlInline,\n SlStack,\n SlText,\n ],\n template: `\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Shipments in transit\n </button>\n <sl-drawer #drawer=\"slDrawer\" side=\"bottom\" [snapPoints]=\"[0.4, 0.9]\" [(extent)]=\"extent\">\n <div slDrawerResizer></div>\n <header slDrawerHeader>\n <h2 slDrawerTitle>Shipments in transit</h2>\n <p slDrawerDescription>10 shipments left the Reno warehouse this week.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slStack [gap]=\"3\">\n @for (shipment of shipments; track shipment.id) {\n <div slInline align=\"center\" [gap]=\"3\" justify=\"between\">\n <div slStack [gap]=\"0\">\n <span slText size=\"sm\" weight=\"semibold\">{{ shipment.id }}</span>\n <span slText size=\"sm\" tone=\"muted\">{{ shipment.to }}</span>\n </div>\n <span slBadge [tone]=\"shipment.tone\">{{ shipment.status }}</span>\n </div>\n }\n </div>\n </div>\n </sl-drawer>\n `,\n})\nexport class DrawerSnapPoints {\n readonly shipments = SHIPMENTS;\n readonly extent = signal<number | undefined>(0.4);\n}\n",
|
|
742
|
+
"verdict": "example"
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
"id": "unsaved-changes",
|
|
746
|
+
"title": "unsaved-changes.ts",
|
|
747
|
+
"note": null,
|
|
748
|
+
"language": "ts",
|
|
749
|
+
"source": "import { Component, signal } from '@angular/core';\nimport { SlButton } from '@slotted/angular/button';\nimport {\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n} from '@slotted/angular/drawer';\nimport type { DrawerChangeRequest } from '@slotted/angular/drawer';\nimport { SlField, SlFieldLabel } from '@slotted/angular/field';\nimport { SlInlineMessage } from '@slotted/angular/inline-message';\nimport { SlTextarea } from '@slotted/angular/textarea';\n\n@Component({\n selector: 'app-drawer-unsaved-changes',\n imports: [\n SlButton,\n SlDrawer,\n SlDrawerBody,\n SlDrawerClose,\n SlDrawerDescription,\n SlDrawerFooter,\n SlDrawerHeader,\n SlDrawerTitle,\n SlDrawerTrigger,\n SlField,\n SlFieldLabel,\n SlInlineMessage,\n SlTextarea,\n ],\n template: `\n <button slButton tone=\"secondary\" variant=\"outline\" [slDrawerTrigger]=\"drawer\">\n Delivery instructions\n </button>\n <sl-drawer #drawer=\"slDrawer\" [(open)]=\"open\" (openChangeRequest)=\"guard($event)\">\n <header slDrawerHeader>\n <h2 slDrawerTitle>Delivery instructions</h2>\n <p slDrawerDescription>Order SO-1182, printed on the packing slip.</p>\n <button slDrawerClose></button>\n </header>\n <div slDrawerBody>\n <div slField>\n <label slFieldLabel>Instructions for the carrier</label>\n <textarea slTextarea [value]=\"draft()\" (valueChange)=\"edit($event.value)\"></textarea>\n </div>\n </div>\n <footer slDrawerFooter>\n @if (confirming()) {\n <p slInlineMessage live=\"polite\" tone=\"warning\">\n Discard your changes to the instructions?\n </p>\n <button slButton variant=\"ghost\" tone=\"secondary\" (click)=\"confirming.set(false)\">\n Keep editing\n </button>\n <button slButton tone=\"danger\" (click)=\"close()\">Discard</button>\n } @else {\n <button slButton variant=\"ghost\" tone=\"secondary\" (click)=\"cancel()\">Cancel</button>\n <button slButton (click)=\"save()\">Save</button>\n }\n </footer>\n </sl-drawer>\n `,\n})\nexport class DrawerUnsavedChanges {\n readonly open = signal(false);\n readonly saved = signal('Leave at the loading dock, door 3.');\n readonly draft = signal(this.saved());\n readonly confirming = signal(false);\n\n guard(request: DrawerChangeRequest): void {\n if (request.value) {\n this.draft.set(this.saved());\n this.confirming.set(false);\n } else if (this.draft() !== this.saved()) {\n request.cancel();\n this.confirming.set(true);\n }\n }\n\n edit(value: string): void {\n this.draft.set(value);\n this.confirming.set(false);\n }\n\n cancel(): void {\n if (this.draft() === this.saved()) this.close();\n else this.confirming.set(true);\n }\n\n save(): void {\n this.saved.set(this.draft());\n this.close();\n }\n\n close(): void {\n this.confirming.set(false);\n this.open.set(false);\n }\n}\n",
|
|
750
|
+
"verdict": "example"
|
|
751
|
+
}
|
|
752
|
+
]
|
|
753
|
+
}
|