@slotted/angular 0.0.0-stage → 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +51 -2
- package/docs/AGENTS.snippet.md +10 -0
- package/docs/accordion.json +345 -0
- package/docs/accordion.md +207 -0
- package/docs/action-bar.json +421 -0
- package/docs/action-bar.md +364 -0
- package/docs/action-sheet.json +210 -0
- package/docs/action-sheet.md +19 -0
- package/docs/alert.json +407 -0
- package/docs/alert.md +239 -0
- package/docs/app-shell.examples.md +349 -0
- package/docs/app-shell.json +835 -0
- package/docs/app-shell.md +214 -0
- package/docs/aspect-ratio.json +159 -0
- package/docs/aspect-ratio.md +134 -0
- package/docs/attachment.json +486 -0
- package/docs/attachment.md +253 -0
- package/docs/avatar-group.json +208 -0
- package/docs/avatar-group.md +130 -0
- package/docs/avatar.json +342 -0
- package/docs/avatar.md +142 -0
- package/docs/badge.json +334 -0
- package/docs/badge.md +138 -0
- package/docs/breadcrumb.json +368 -0
- package/docs/breadcrumb.md +237 -0
- package/docs/button-group.json +158 -0
- package/docs/button-group.md +72 -0
- package/docs/button.examples.md +621 -0
- package/docs/button.json +977 -0
- package/docs/button.md +200 -0
- package/docs/calendar.json +592 -0
- package/docs/calendar.md +242 -0
- package/docs/card.json +283 -0
- package/docs/card.md +130 -0
- package/docs/carousel.json +560 -0
- package/docs/carousel.md +357 -0
- package/docs/cascader.json +933 -0
- package/docs/cascader.md +379 -0
- package/docs/chart.examples.md +582 -0
- package/docs/chart.json +1359 -0
- package/docs/chart.md +187 -0
- package/docs/checkbox-group.examples.md +612 -0
- package/docs/checkbox-group.json +395 -0
- package/docs/checkbox-group.md +106 -0
- package/docs/checkbox.examples.md +546 -0
- package/docs/checkbox.json +506 -0
- package/docs/checkbox.md +104 -0
- package/docs/code-block.json +616 -0
- package/docs/code-block.md +303 -0
- package/docs/collapsible.json +456 -0
- package/docs/collapsible.md +261 -0
- package/docs/color-picker.json +523 -0
- package/docs/color-picker.md +201 -0
- package/docs/column-manager.json +486 -0
- package/docs/column-manager.md +277 -0
- package/docs/combobox.examples.md +1732 -0
- package/docs/combobox.json +1250 -0
- package/docs/combobox.md +209 -0
- package/docs/command-palette.json +800 -0
- package/docs/command-palette.md +419 -0
- package/docs/container.json +156 -0
- package/docs/container.md +92 -0
- package/docs/context-menu.json +231 -0
- package/docs/context-menu.md +176 -0
- package/docs/currency-field.examples.md +321 -0
- package/docs/currency-field.json +649 -0
- package/docs/currency-field.md +128 -0
- package/docs/dashboard-grid.json +680 -0
- package/docs/dashboard-grid.md +265 -0
- package/docs/data-grid.examples.md +3064 -0
- package/docs/data-grid.json +1577 -0
- package/docs/data-grid.md +237 -0
- package/docs/data-grid.props.md +81 -0
- package/docs/data-list.json +685 -0
- package/docs/data-list.md +327 -0
- package/docs/date-field.json +490 -0
- package/docs/date-field.md +235 -0
- package/docs/date-picker.examples.md +1226 -0
- package/docs/date-picker.json +696 -0
- package/docs/date-picker.md +121 -0
- package/docs/date-range-picker.examples.md +1300 -0
- package/docs/date-range-picker.json +903 -0
- package/docs/date-range-picker.md +142 -0
- package/docs/datetime-field.json +665 -0
- package/docs/datetime-field.md +337 -0
- package/docs/datetime-picker.examples.md +1269 -0
- package/docs/datetime-picker.json +928 -0
- package/docs/datetime-picker.md +150 -0
- package/docs/datetime-range-picker.examples.md +225 -0
- package/docs/datetime-range-picker.json +1015 -0
- package/docs/datetime-range-picker.md +162 -0
- package/docs/description-list.json +471 -0
- package/docs/description-list.md +268 -0
- package/docs/detail-panel.json +530 -0
- package/docs/detail-panel.md +361 -0
- package/docs/dialog.examples.md +2467 -0
- package/docs/dialog.json +1141 -0
- package/docs/dialog.md +217 -0
- package/docs/dialog.props.md +63 -0
- package/docs/divider.json +148 -0
- package/docs/divider.md +83 -0
- package/docs/drawer.examples.md +1929 -0
- package/docs/drawer.json +753 -0
- package/docs/drawer.md +199 -0
- package/docs/entity-picker.json +946 -0
- package/docs/entity-picker.md +365 -0
- package/docs/event-calendar.examples.md +308 -0
- package/docs/event-calendar.json +1202 -0
- package/docs/event-calendar.md +201 -0
- package/docs/field-group.json +333 -0
- package/docs/field-group.md +181 -0
- package/docs/field.examples.md +676 -0
- package/docs/field.json +528 -0
- package/docs/field.md +127 -0
- package/docs/filter-bar.json +817 -0
- package/docs/filter-bar.md +380 -0
- package/docs/form.json +378 -0
- package/docs/form.md +235 -0
- package/docs/fullscreen.json +395 -0
- package/docs/fullscreen.md +225 -0
- package/docs/grid.json +176 -0
- package/docs/grid.md +74 -0
- package/docs/highlight.json +279 -0
- package/docs/highlight.md +210 -0
- package/docs/hover-card.json +254 -0
- package/docs/hover-card.md +213 -0
- package/docs/icon.json +173 -0
- package/docs/icon.md +101 -0
- package/docs/image.json +476 -0
- package/docs/image.md +254 -0
- package/docs/import-export-center.json +836 -0
- package/docs/import-export-center.md +345 -0
- package/docs/index.md +141 -0
- package/docs/inline-message.json +312 -0
- package/docs/inline-message.md +191 -0
- package/docs/inline.json +149 -0
- package/docs/inline.md +72 -0
- package/docs/kbd.json +350 -0
- package/docs/kbd.md +210 -0
- package/docs/link.json +264 -0
- package/docs/link.md +167 -0
- package/docs/list-item.json +463 -0
- package/docs/list-item.md +236 -0
- package/docs/list.json +321 -0
- package/docs/list.md +185 -0
- package/docs/listbox.json +807 -0
- package/docs/listbox.md +413 -0
- package/docs/loading-overlay.json +440 -0
- package/docs/loading-overlay.md +248 -0
- package/docs/markdown.json +461 -0
- package/docs/markdown.md +266 -0
- package/docs/menu.examples.md +1651 -0
- package/docs/menu.json +922 -0
- package/docs/menu.md +155 -0
- package/docs/menubar.json +292 -0
- package/docs/menubar.md +173 -0
- package/docs/message-scroller.json +401 -0
- package/docs/message-scroller.md +212 -0
- package/docs/message.json +862 -0
- package/docs/message.md +473 -0
- package/docs/multi-select.examples.md +1922 -0
- package/docs/multi-select.json +1314 -0
- package/docs/multi-select.md +213 -0
- package/docs/navigation-menu.json +529 -0
- package/docs/navigation-menu.md +329 -0
- package/docs/notification-center.json +664 -0
- package/docs/notification-center.md +372 -0
- package/docs/number-field.examples.md +1078 -0
- package/docs/number-field.json +668 -0
- package/docs/number-field.md +137 -0
- package/docs/otp-input.json +479 -0
- package/docs/otp-input.md +291 -0
- package/docs/page-header.json +574 -0
- package/docs/page-header.md +338 -0
- package/docs/page.json +332 -0
- package/docs/page.md +184 -0
- package/docs/pagination.json +434 -0
- package/docs/pagination.md +238 -0
- package/docs/popover.examples.md +1235 -0
- package/docs/popover.json +656 -0
- package/docs/popover.md +199 -0
- package/docs/progress-indicator.json +501 -0
- package/docs/progress-indicator.md +329 -0
- package/docs/prompt-composer.json +498 -0
- package/docs/prompt-composer.md +278 -0
- package/docs/prose.json +357 -0
- package/docs/prose.md +226 -0
- package/docs/radio-group.examples.md +626 -0
- package/docs/radio-group.json +541 -0
- package/docs/radio-group.md +112 -0
- package/docs/rating.json +1053 -0
- package/docs/rating.md +435 -0
- package/docs/result-state.json +376 -0
- package/docs/result-state.md +286 -0
- package/docs/saved-views.json +384 -0
- package/docs/saved-views.md +242 -0
- package/docs/scroll-area.json +120 -0
- package/docs/scroll-area.md +8 -0
- package/docs/section.json +344 -0
- package/docs/section.md +208 -0
- package/docs/segmented-control.json +429 -0
- package/docs/segmented-control.md +240 -0
- package/docs/select.examples.md +1214 -0
- package/docs/select.json +1147 -0
- package/docs/select.md +199 -0
- package/docs/side-navigation.json +632 -0
- package/docs/side-navigation.md +430 -0
- package/docs/skeleton.json +358 -0
- package/docs/skeleton.md +223 -0
- package/docs/slider.json +522 -0
- package/docs/slider.md +261 -0
- package/docs/sparkline.json +426 -0
- package/docs/sparkline.md +206 -0
- package/docs/split-button.json +361 -0
- package/docs/split-button.md +275 -0
- package/docs/splitter.json +142 -0
- package/docs/splitter.md +14 -0
- package/docs/stack.json +135 -0
- package/docs/stack.md +74 -0
- package/docs/stat-card.json +529 -0
- package/docs/stat-card.md +270 -0
- package/docs/status-indicator.json +314 -0
- package/docs/status-indicator.md +197 -0
- package/docs/stepper.json +451 -0
- package/docs/stepper.md +250 -0
- package/docs/switch.json +451 -0
- package/docs/switch.md +508 -0
- package/docs/table-of-contents.json +553 -0
- package/docs/table-of-contents.md +289 -0
- package/docs/table.examples.md +1981 -0
- package/docs/table.json +1059 -0
- package/docs/table.md +290 -0
- package/docs/tabs.examples.md +1370 -0
- package/docs/tabs.json +661 -0
- package/docs/tabs.md +211 -0
- package/docs/tag.json +813 -0
- package/docs/tag.md +241 -0
- package/docs/tags-input.json +771 -0
- package/docs/tags-input.md +361 -0
- package/docs/text-field.examples.md +821 -0
- package/docs/text-field.json +604 -0
- package/docs/text-field.md +125 -0
- package/docs/textarea.examples.md +612 -0
- package/docs/textarea.json +440 -0
- package/docs/textarea.md +98 -0
- package/docs/time-field.json +584 -0
- package/docs/time-field.md +291 -0
- package/docs/time-picker.json +679 -0
- package/docs/time-picker.md +315 -0
- package/docs/time-range-picker.examples.md +191 -0
- package/docs/time-range-picker.json +924 -0
- package/docs/time-range-picker.md +152 -0
- package/docs/timeline.json +839 -0
- package/docs/timeline.md +401 -0
- package/docs/toast.json +642 -0
- package/docs/toast.md +311 -0
- package/docs/toggle-group.json +417 -0
- package/docs/toggle-group.md +255 -0
- package/docs/toggle.json +326 -0
- package/docs/toggle.md +222 -0
- package/docs/toolbar.json +380 -0
- package/docs/toolbar.md +240 -0
- package/docs/tooltip.examples.md +664 -0
- package/docs/tooltip.json +604 -0
- package/docs/tooltip.md +146 -0
- package/docs/top-navigation.examples.md +287 -0
- package/docs/top-navigation.json +648 -0
- package/docs/top-navigation.md +138 -0
- package/docs/tour.json +759 -0
- package/docs/tour.md +337 -0
- package/docs/transfer.json +746 -0
- package/docs/transfer.md +273 -0
- package/docs/tree.json +918 -0
- package/docs/tree.md +397 -0
- package/docs/typography.json +317 -0
- package/docs/typography.md +107 -0
- package/docs/upload.examples.md +358 -0
- package/docs/upload.json +1103 -0
- package/docs/upload.md +166 -0
- package/docs/visually-hidden.json +71 -0
- package/docs/visually-hidden.md +42 -0
- package/docs/wizard.json +724 -0
- package/docs/wizard.md +295 -0
- package/fesm2022/slotted-angular-accordion.mjs +247 -0
- package/fesm2022/slotted-angular-accordion.mjs.map +1 -0
- package/fesm2022/slotted-angular-action-bar.mjs +639 -0
- package/fesm2022/slotted-angular-action-bar.mjs.map +1 -0
- package/fesm2022/slotted-angular-action-sheet.mjs +749 -0
- package/fesm2022/slotted-angular-action-sheet.mjs.map +1 -0
- package/fesm2022/slotted-angular-alert.mjs +427 -0
- package/fesm2022/slotted-angular-alert.mjs.map +1 -0
- package/fesm2022/slotted-angular-app-shell.mjs +1334 -0
- package/fesm2022/slotted-angular-app-shell.mjs.map +1 -0
- package/fesm2022/slotted-angular-aspect-ratio.mjs +63 -0
- package/fesm2022/slotted-angular-aspect-ratio.mjs.map +1 -0
- package/fesm2022/slotted-angular-attachment.mjs +595 -0
- package/fesm2022/slotted-angular-attachment.mjs.map +1 -0
- package/fesm2022/slotted-angular-avatar-group.mjs +230 -0
- package/fesm2022/slotted-angular-avatar-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-avatar.mjs +330 -0
- package/fesm2022/slotted-angular-avatar.mjs.map +1 -0
- package/fesm2022/slotted-angular-badge.mjs +255 -0
- package/fesm2022/slotted-angular-badge.mjs.map +1 -0
- package/fesm2022/slotted-angular-breadcrumb.mjs +544 -0
- package/fesm2022/slotted-angular-breadcrumb.mjs.map +1 -0
- package/fesm2022/slotted-angular-button-group.mjs +146 -0
- package/fesm2022/slotted-angular-button-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-button.mjs +692 -0
- package/fesm2022/slotted-angular-button.mjs.map +1 -0
- package/fesm2022/slotted-angular-calendar.mjs +916 -0
- package/fesm2022/slotted-angular-calendar.mjs.map +1 -0
- package/fesm2022/slotted-angular-card.mjs +225 -0
- package/fesm2022/slotted-angular-card.mjs.map +1 -0
- package/fesm2022/slotted-angular-carousel.mjs +840 -0
- package/fesm2022/slotted-angular-carousel.mjs.map +1 -0
- package/fesm2022/slotted-angular-cascader.mjs +1839 -0
- package/fesm2022/slotted-angular-cascader.mjs.map +1 -0
- package/fesm2022/slotted-angular-chart.mjs +974 -0
- package/fesm2022/slotted-angular-chart.mjs.map +1 -0
- package/fesm2022/slotted-angular-checkbox-group.mjs +283 -0
- package/fesm2022/slotted-angular-checkbox-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-checkbox.mjs +468 -0
- package/fesm2022/slotted-angular-checkbox.mjs.map +1 -0
- package/fesm2022/slotted-angular-code-block.mjs +476 -0
- package/fesm2022/slotted-angular-code-block.mjs.map +1 -0
- package/fesm2022/slotted-angular-collapsible.mjs +479 -0
- package/fesm2022/slotted-angular-collapsible.mjs.map +1 -0
- package/fesm2022/slotted-angular-color-picker.mjs +910 -0
- package/fesm2022/slotted-angular-color-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-column-manager.mjs +1037 -0
- package/fesm2022/slotted-angular-column-manager.mjs.map +1 -0
- package/fesm2022/slotted-angular-combobox.mjs +1480 -0
- package/fesm2022/slotted-angular-combobox.mjs.map +1 -0
- package/fesm2022/slotted-angular-command-palette.mjs +1283 -0
- package/fesm2022/slotted-angular-command-palette.mjs.map +1 -0
- package/fesm2022/slotted-angular-container.mjs +105 -0
- package/fesm2022/slotted-angular-container.mjs.map +1 -0
- package/fesm2022/slotted-angular-context-menu.mjs +221 -0
- package/fesm2022/slotted-angular-context-menu.mjs.map +1 -0
- package/fesm2022/slotted-angular-currency-field.mjs +1131 -0
- package/fesm2022/slotted-angular-currency-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-dashboard-grid.mjs +1928 -0
- package/fesm2022/slotted-angular-dashboard-grid.mjs.map +1 -0
- package/fesm2022/slotted-angular-data-grid.mjs +6697 -0
- package/fesm2022/slotted-angular-data-grid.mjs.map +1 -0
- package/fesm2022/slotted-angular-data-list.mjs +1418 -0
- package/fesm2022/slotted-angular-data-list.mjs.map +1 -0
- package/fesm2022/slotted-angular-date-field.mjs +772 -0
- package/fesm2022/slotted-angular-date-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-date-picker.mjs +690 -0
- package/fesm2022/slotted-angular-date-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-date-range-picker.mjs +1150 -0
- package/fesm2022/slotted-angular-date-range-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-datetime-field.mjs +1058 -0
- package/fesm2022/slotted-angular-datetime-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-datetime-picker.mjs +1362 -0
- package/fesm2022/slotted-angular-datetime-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-datetime-range-picker.mjs +1872 -0
- package/fesm2022/slotted-angular-datetime-range-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-description-list.mjs +545 -0
- package/fesm2022/slotted-angular-description-list.mjs.map +1 -0
- package/fesm2022/slotted-angular-detail-panel.mjs +754 -0
- package/fesm2022/slotted-angular-detail-panel.mjs.map +1 -0
- package/fesm2022/slotted-angular-dialog.mjs +980 -0
- package/fesm2022/slotted-angular-dialog.mjs.map +1 -0
- package/fesm2022/slotted-angular-divider.mjs +76 -0
- package/fesm2022/slotted-angular-divider.mjs.map +1 -0
- package/fesm2022/slotted-angular-drawer.mjs +1397 -0
- package/fesm2022/slotted-angular-drawer.mjs.map +1 -0
- package/fesm2022/slotted-angular-entity-picker.mjs +1987 -0
- package/fesm2022/slotted-angular-entity-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-event-calendar.mjs +2934 -0
- package/fesm2022/slotted-angular-event-calendar.mjs.map +1 -0
- package/fesm2022/slotted-angular-field-group.mjs +301 -0
- package/fesm2022/slotted-angular-field-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-field.mjs +928 -0
- package/fesm2022/slotted-angular-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-filter-bar.mjs +3107 -0
- package/fesm2022/slotted-angular-filter-bar.mjs.map +1 -0
- package/fesm2022/slotted-angular-form.mjs +592 -0
- package/fesm2022/slotted-angular-form.mjs.map +1 -0
- package/fesm2022/slotted-angular-fullscreen.mjs +314 -0
- package/fesm2022/slotted-angular-fullscreen.mjs.map +1 -0
- package/fesm2022/slotted-angular-grid.mjs +58 -0
- package/fesm2022/slotted-angular-grid.mjs.map +1 -0
- package/fesm2022/slotted-angular-highlight.mjs +123 -0
- package/fesm2022/slotted-angular-highlight.mjs.map +1 -0
- package/fesm2022/slotted-angular-hover-card.mjs +326 -0
- package/fesm2022/slotted-angular-hover-card.mjs.map +1 -0
- package/fesm2022/slotted-angular-i18n.mjs +75 -0
- package/fesm2022/slotted-angular-i18n.mjs.map +1 -0
- package/fesm2022/slotted-angular-icon.mjs +232 -0
- package/fesm2022/slotted-angular-icon.mjs.map +1 -0
- package/fesm2022/slotted-angular-image.mjs +442 -0
- package/fesm2022/slotted-angular-image.mjs.map +1 -0
- package/fesm2022/slotted-angular-import-export-center.mjs +1792 -0
- package/fesm2022/slotted-angular-import-export-center.mjs.map +1 -0
- package/fesm2022/slotted-angular-inline-message.mjs +280 -0
- package/fesm2022/slotted-angular-inline-message.mjs.map +1 -0
- package/fesm2022/slotted-angular-inline.mjs +52 -0
- package/fesm2022/slotted-angular-inline.mjs.map +1 -0
- package/fesm2022/slotted-angular-kbd.mjs +284 -0
- package/fesm2022/slotted-angular-kbd.mjs.map +1 -0
- package/fesm2022/slotted-angular-link.mjs +182 -0
- package/fesm2022/slotted-angular-link.mjs.map +1 -0
- package/fesm2022/slotted-angular-list-item.mjs +367 -0
- package/fesm2022/slotted-angular-list-item.mjs.map +1 -0
- package/fesm2022/slotted-angular-list.mjs +256 -0
- package/fesm2022/slotted-angular-list.mjs.map +1 -0
- package/fesm2022/slotted-angular-listbox.mjs +1274 -0
- package/fesm2022/slotted-angular-listbox.mjs.map +1 -0
- package/fesm2022/slotted-angular-loading-overlay.mjs +451 -0
- package/fesm2022/slotted-angular-loading-overlay.mjs.map +1 -0
- package/fesm2022/slotted-angular-markdown.mjs +914 -0
- package/fesm2022/slotted-angular-markdown.mjs.map +1 -0
- package/fesm2022/slotted-angular-menu.mjs +1211 -0
- package/fesm2022/slotted-angular-menu.mjs.map +1 -0
- package/fesm2022/slotted-angular-menubar.mjs +230 -0
- package/fesm2022/slotted-angular-menubar.mjs.map +1 -0
- package/fesm2022/slotted-angular-message-scroller.mjs +378 -0
- package/fesm2022/slotted-angular-message-scroller.mjs.map +1 -0
- package/fesm2022/slotted-angular-message.mjs +866 -0
- package/fesm2022/slotted-angular-message.mjs.map +1 -0
- package/fesm2022/slotted-angular-multi-select.mjs +1939 -0
- package/fesm2022/slotted-angular-multi-select.mjs.map +1 -0
- package/fesm2022/slotted-angular-navigation-menu.mjs +770 -0
- package/fesm2022/slotted-angular-navigation-menu.mjs.map +1 -0
- package/fesm2022/slotted-angular-notification-center.mjs +1172 -0
- package/fesm2022/slotted-angular-notification-center.mjs.map +1 -0
- package/fesm2022/slotted-angular-number-field.mjs +966 -0
- package/fesm2022/slotted-angular-number-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-otp-input.mjs +629 -0
- package/fesm2022/slotted-angular-otp-input.mjs.map +1 -0
- package/fesm2022/slotted-angular-page-header.mjs +788 -0
- package/fesm2022/slotted-angular-page-header.mjs.map +1 -0
- package/fesm2022/slotted-angular-page.mjs +255 -0
- package/fesm2022/slotted-angular-page.mjs.map +1 -0
- package/fesm2022/slotted-angular-pagination.mjs +562 -0
- package/fesm2022/slotted-angular-pagination.mjs.map +1 -0
- package/fesm2022/slotted-angular-popover.mjs +799 -0
- package/fesm2022/slotted-angular-popover.mjs.map +1 -0
- package/fesm2022/slotted-angular-progress-indicator.mjs +572 -0
- package/fesm2022/slotted-angular-progress-indicator.mjs.map +1 -0
- package/fesm2022/slotted-angular-prompt-composer.mjs +596 -0
- package/fesm2022/slotted-angular-prompt-composer.mjs.map +1 -0
- package/fesm2022/slotted-angular-prose.mjs +314 -0
- package/fesm2022/slotted-angular-prose.mjs.map +1 -0
- package/fesm2022/slotted-angular-radio-group.mjs +469 -0
- package/fesm2022/slotted-angular-radio-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-rating.mjs +1174 -0
- package/fesm2022/slotted-angular-rating.mjs.map +1 -0
- package/fesm2022/slotted-angular-result-state.mjs +330 -0
- package/fesm2022/slotted-angular-result-state.mjs.map +1 -0
- package/fesm2022/slotted-angular-saved-views.mjs +877 -0
- package/fesm2022/slotted-angular-saved-views.mjs.map +1 -0
- package/fesm2022/slotted-angular-scroll-area.mjs +294 -0
- package/fesm2022/slotted-angular-scroll-area.mjs.map +1 -0
- package/fesm2022/slotted-angular-section.mjs +266 -0
- package/fesm2022/slotted-angular-section.mjs.map +1 -0
- package/fesm2022/slotted-angular-segmented-control.mjs +454 -0
- package/fesm2022/slotted-angular-segmented-control.mjs.map +1 -0
- package/fesm2022/slotted-angular-select.mjs +1899 -0
- package/fesm2022/slotted-angular-select.mjs.map +1 -0
- package/fesm2022/slotted-angular-side-navigation.mjs +1042 -0
- package/fesm2022/slotted-angular-side-navigation.mjs.map +1 -0
- package/fesm2022/slotted-angular-skeleton.mjs +316 -0
- package/fesm2022/slotted-angular-skeleton.mjs.map +1 -0
- package/fesm2022/slotted-angular-slider.mjs +586 -0
- package/fesm2022/slotted-angular-slider.mjs.map +1 -0
- package/fesm2022/slotted-angular-sparkline.mjs +235 -0
- package/fesm2022/slotted-angular-sparkline.mjs.map +1 -0
- package/fesm2022/slotted-angular-split-button.mjs +331 -0
- package/fesm2022/slotted-angular-split-button.mjs.map +1 -0
- package/fesm2022/slotted-angular-splitter.mjs +516 -0
- package/fesm2022/slotted-angular-splitter.mjs.map +1 -0
- package/fesm2022/slotted-angular-stack.mjs +48 -0
- package/fesm2022/slotted-angular-stack.mjs.map +1 -0
- package/fesm2022/slotted-angular-stat-card.mjs +478 -0
- package/fesm2022/slotted-angular-stat-card.mjs.map +1 -0
- package/fesm2022/slotted-angular-status-indicator.mjs +155 -0
- package/fesm2022/slotted-angular-status-indicator.mjs.map +1 -0
- package/fesm2022/slotted-angular-stepper.mjs +536 -0
- package/fesm2022/slotted-angular-stepper.mjs.map +1 -0
- package/fesm2022/slotted-angular-switch.mjs +447 -0
- package/fesm2022/slotted-angular-switch.mjs.map +1 -0
- package/fesm2022/slotted-angular-table-of-contents.mjs +750 -0
- package/fesm2022/slotted-angular-table-of-contents.mjs.map +1 -0
- package/fesm2022/slotted-angular-table.mjs +2518 -0
- package/fesm2022/slotted-angular-table.mjs.map +1 -0
- package/fesm2022/slotted-angular-tabs.mjs +829 -0
- package/fesm2022/slotted-angular-tabs.mjs.map +1 -0
- package/fesm2022/slotted-angular-tag.mjs +595 -0
- package/fesm2022/slotted-angular-tag.mjs.map +1 -0
- package/fesm2022/slotted-angular-tags-input.mjs +1211 -0
- package/fesm2022/slotted-angular-tags-input.mjs.map +1 -0
- package/fesm2022/slotted-angular-text-field.mjs +674 -0
- package/fesm2022/slotted-angular-text-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-textarea.mjs +275 -0
- package/fesm2022/slotted-angular-textarea.mjs.map +1 -0
- package/fesm2022/slotted-angular-theme.mjs +45 -0
- package/fesm2022/slotted-angular-theme.mjs.map +1 -0
- package/fesm2022/slotted-angular-time-field.mjs +895 -0
- package/fesm2022/slotted-angular-time-field.mjs.map +1 -0
- package/fesm2022/slotted-angular-time-picker.mjs +856 -0
- package/fesm2022/slotted-angular-time-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-time-range-picker.mjs +1534 -0
- package/fesm2022/slotted-angular-time-range-picker.mjs.map +1 -0
- package/fesm2022/slotted-angular-timeline.mjs +928 -0
- package/fesm2022/slotted-angular-timeline.mjs.map +1 -0
- package/fesm2022/slotted-angular-toast.mjs +917 -0
- package/fesm2022/slotted-angular-toast.mjs.map +1 -0
- package/fesm2022/slotted-angular-toggle-group.mjs +311 -0
- package/fesm2022/slotted-angular-toggle-group.mjs.map +1 -0
- package/fesm2022/slotted-angular-toggle.mjs +162 -0
- package/fesm2022/slotted-angular-toggle.mjs.map +1 -0
- package/fesm2022/slotted-angular-toolbar.mjs +536 -0
- package/fesm2022/slotted-angular-toolbar.mjs.map +1 -0
- package/fesm2022/slotted-angular-tooltip.mjs +798 -0
- package/fesm2022/slotted-angular-tooltip.mjs.map +1 -0
- package/fesm2022/slotted-angular-top-navigation.mjs +1308 -0
- package/fesm2022/slotted-angular-top-navigation.mjs.map +1 -0
- package/fesm2022/slotted-angular-tour.mjs +1330 -0
- package/fesm2022/slotted-angular-tour.mjs.map +1 -0
- package/fesm2022/slotted-angular-transfer.mjs +1406 -0
- package/fesm2022/slotted-angular-transfer.mjs.map +1 -0
- package/fesm2022/slotted-angular-tree.mjs +1448 -0
- package/fesm2022/slotted-angular-tree.mjs.map +1 -0
- package/fesm2022/slotted-angular-typography.mjs +184 -0
- package/fesm2022/slotted-angular-typography.mjs.map +1 -0
- package/fesm2022/slotted-angular-upload.mjs +1523 -0
- package/fesm2022/slotted-angular-upload.mjs.map +1 -0
- package/fesm2022/slotted-angular-visually-hidden.mjs +32 -0
- package/fesm2022/slotted-angular-visually-hidden.mjs.map +1 -0
- package/fesm2022/slotted-angular-wizard.mjs +1715 -0
- package/fesm2022/slotted-angular-wizard.mjs.map +1 -0
- package/fesm2022/slotted-angular.mjs +4 -0
- package/fesm2022/slotted-angular.mjs.map +1 -0
- package/package.json +537 -3
- package/types/slotted-angular-accordion.d.ts +156 -0
- package/types/slotted-angular-accordion.d.ts.map +1 -0
- package/types/slotted-angular-action-bar.d.ts +291 -0
- package/types/slotted-angular-action-bar.d.ts.map +1 -0
- package/types/slotted-angular-action-sheet.d.ts +294 -0
- package/types/slotted-angular-action-sheet.d.ts.map +1 -0
- package/types/slotted-angular-alert.d.ts +214 -0
- package/types/slotted-angular-alert.d.ts.map +1 -0
- package/types/slotted-angular-app-shell.d.ts +549 -0
- package/types/slotted-angular-app-shell.d.ts.map +1 -0
- package/types/slotted-angular-aspect-ratio.d.ts +57 -0
- package/types/slotted-angular-aspect-ratio.d.ts.map +1 -0
- package/types/slotted-angular-attachment.d.ts +294 -0
- package/types/slotted-angular-attachment.d.ts.map +1 -0
- package/types/slotted-angular-avatar-group.d.ts +119 -0
- package/types/slotted-angular-avatar-group.d.ts.map +1 -0
- package/types/slotted-angular-avatar.d.ts +202 -0
- package/types/slotted-angular-avatar.d.ts.map +1 -0
- package/types/slotted-angular-badge.d.ts +166 -0
- package/types/slotted-angular-badge.d.ts.map +1 -0
- package/types/slotted-angular-breadcrumb.d.ts +251 -0
- package/types/slotted-angular-breadcrumb.d.ts.map +1 -0
- package/types/slotted-angular-button-group.d.ts +89 -0
- package/types/slotted-angular-button-group.d.ts.map +1 -0
- package/types/slotted-angular-button.d.ts +390 -0
- package/types/slotted-angular-button.d.ts.map +1 -0
- package/types/slotted-angular-calendar.d.ts +280 -0
- package/types/slotted-angular-calendar.d.ts.map +1 -0
- package/types/slotted-angular-card.d.ts +140 -0
- package/types/slotted-angular-card.d.ts.map +1 -0
- package/types/slotted-angular-carousel.d.ts +288 -0
- package/types/slotted-angular-carousel.d.ts.map +1 -0
- package/types/slotted-angular-cascader.d.ts +351 -0
- package/types/slotted-angular-cascader.d.ts.map +1 -0
- package/types/slotted-angular-chart.d.ts +319 -0
- package/types/slotted-angular-chart.d.ts.map +1 -0
- package/types/slotted-angular-checkbox-group.d.ts +156 -0
- package/types/slotted-angular-checkbox-group.d.ts.map +1 -0
- package/types/slotted-angular-checkbox.d.ts +197 -0
- package/types/slotted-angular-checkbox.d.ts.map +1 -0
- package/types/slotted-angular-code-block.d.ts +158 -0
- package/types/slotted-angular-code-block.d.ts.map +1 -0
- package/types/slotted-angular-collapsible.d.ts +272 -0
- package/types/slotted-angular-collapsible.d.ts.map +1 -0
- package/types/slotted-angular-color-picker.d.ts +181 -0
- package/types/slotted-angular-color-picker.d.ts.map +1 -0
- package/types/slotted-angular-column-manager.d.ts +200 -0
- package/types/slotted-angular-column-manager.d.ts.map +1 -0
- package/types/slotted-angular-combobox.d.ts +449 -0
- package/types/slotted-angular-combobox.d.ts.map +1 -0
- package/types/slotted-angular-command-palette.d.ts +256 -0
- package/types/slotted-angular-command-palette.d.ts.map +1 -0
- package/types/slotted-angular-container.d.ts +84 -0
- package/types/slotted-angular-container.d.ts.map +1 -0
- package/types/slotted-angular-context-menu.d.ts +84 -0
- package/types/slotted-angular-context-menu.d.ts.map +1 -0
- package/types/slotted-angular-currency-field.d.ts +480 -0
- package/types/slotted-angular-currency-field.d.ts.map +1 -0
- package/types/slotted-angular-dashboard-grid.d.ts +341 -0
- package/types/slotted-angular-dashboard-grid.d.ts.map +1 -0
- package/types/slotted-angular-data-grid.d.ts +1077 -0
- package/types/slotted-angular-data-grid.d.ts.map +1 -0
- package/types/slotted-angular-data-list.d.ts +272 -0
- package/types/slotted-angular-data-list.d.ts.map +1 -0
- package/types/slotted-angular-date-field.d.ts +320 -0
- package/types/slotted-angular-date-field.d.ts.map +1 -0
- package/types/slotted-angular-date-picker.d.ts +224 -0
- package/types/slotted-angular-date-picker.d.ts.map +1 -0
- package/types/slotted-angular-date-range-picker.d.ts +310 -0
- package/types/slotted-angular-date-range-picker.d.ts.map +1 -0
- package/types/slotted-angular-datetime-field.d.ts +362 -0
- package/types/slotted-angular-datetime-field.d.ts.map +1 -0
- package/types/slotted-angular-datetime-picker.d.ts +370 -0
- package/types/slotted-angular-datetime-picker.d.ts.map +1 -0
- package/types/slotted-angular-datetime-range-picker.d.ts +459 -0
- package/types/slotted-angular-datetime-range-picker.d.ts.map +1 -0
- package/types/slotted-angular-description-list.d.ts +281 -0
- package/types/slotted-angular-description-list.d.ts.map +1 -0
- package/types/slotted-angular-detail-panel.d.ts +240 -0
- package/types/slotted-angular-detail-panel.d.ts.map +1 -0
- package/types/slotted-angular-dialog.d.ts +497 -0
- package/types/slotted-angular-dialog.d.ts.map +1 -0
- package/types/slotted-angular-divider.d.ts +40 -0
- package/types/slotted-angular-divider.d.ts.map +1 -0
- package/types/slotted-angular-drawer.d.ts +532 -0
- package/types/slotted-angular-drawer.d.ts.map +1 -0
- package/types/slotted-angular-entity-picker.d.ts +338 -0
- package/types/slotted-angular-entity-picker.d.ts.map +1 -0
- package/types/slotted-angular-event-calendar.d.ts +574 -0
- package/types/slotted-angular-event-calendar.d.ts.map +1 -0
- package/types/slotted-angular-field-group.d.ts +152 -0
- package/types/slotted-angular-field-group.d.ts.map +1 -0
- package/types/slotted-angular-field.d.ts +535 -0
- package/types/slotted-angular-field.d.ts.map +1 -0
- package/types/slotted-angular-filter-bar.d.ts +573 -0
- package/types/slotted-angular-filter-bar.d.ts.map +1 -0
- package/types/slotted-angular-form.d.ts +298 -0
- package/types/slotted-angular-form.d.ts.map +1 -0
- package/types/slotted-angular-fullscreen.d.ts +145 -0
- package/types/slotted-angular-fullscreen.d.ts.map +1 -0
- package/types/slotted-angular-grid.d.ts +50 -0
- package/types/slotted-angular-grid.d.ts.map +1 -0
- package/types/slotted-angular-highlight.d.ts +93 -0
- package/types/slotted-angular-highlight.d.ts.map +1 -0
- package/types/slotted-angular-hover-card.d.ts +140 -0
- package/types/slotted-angular-hover-card.d.ts.map +1 -0
- package/types/slotted-angular-i18n.d.ts +46 -0
- package/types/slotted-angular-i18n.d.ts.map +1 -0
- package/types/slotted-angular-icon.d.ts +94 -0
- package/types/slotted-angular-icon.d.ts.map +1 -0
- package/types/slotted-angular-image.d.ts +251 -0
- package/types/slotted-angular-image.d.ts.map +1 -0
- package/types/slotted-angular-import-export-center.d.ts +351 -0
- package/types/slotted-angular-import-export-center.d.ts.map +1 -0
- package/types/slotted-angular-inline-message.d.ts +195 -0
- package/types/slotted-angular-inline-message.d.ts.map +1 -0
- package/types/slotted-angular-inline.d.ts +41 -0
- package/types/slotted-angular-inline.d.ts.map +1 -0
- package/types/slotted-angular-kbd.d.ts +174 -0
- package/types/slotted-angular-kbd.d.ts.map +1 -0
- package/types/slotted-angular-link.d.ts +94 -0
- package/types/slotted-angular-link.d.ts.map +1 -0
- package/types/slotted-angular-list-item.d.ts +210 -0
- package/types/slotted-angular-list-item.d.ts.map +1 -0
- package/types/slotted-angular-list.d.ts +176 -0
- package/types/slotted-angular-list.d.ts.map +1 -0
- package/types/slotted-angular-listbox.d.ts +470 -0
- package/types/slotted-angular-listbox.d.ts.map +1 -0
- package/types/slotted-angular-loading-overlay.d.ts +219 -0
- package/types/slotted-angular-loading-overlay.d.ts.map +1 -0
- package/types/slotted-angular-markdown.d.ts +172 -0
- package/types/slotted-angular-markdown.d.ts.map +1 -0
- package/types/slotted-angular-menu.d.ts +448 -0
- package/types/slotted-angular-menu.d.ts.map +1 -0
- package/types/slotted-angular-menubar.d.ts +90 -0
- package/types/slotted-angular-menubar.d.ts.map +1 -0
- package/types/slotted-angular-message-scroller.d.ts +151 -0
- package/types/slotted-angular-message-scroller.d.ts.map +1 -0
- package/types/slotted-angular-message.d.ts +348 -0
- package/types/slotted-angular-message.d.ts.map +1 -0
- package/types/slotted-angular-multi-select.d.ts +462 -0
- package/types/slotted-angular-multi-select.d.ts.map +1 -0
- package/types/slotted-angular-navigation-menu.d.ts +309 -0
- package/types/slotted-angular-navigation-menu.d.ts.map +1 -0
- package/types/slotted-angular-notification-center.d.ts +318 -0
- package/types/slotted-angular-notification-center.d.ts.map +1 -0
- package/types/slotted-angular-number-field.d.ts +402 -0
- package/types/slotted-angular-number-field.d.ts.map +1 -0
- package/types/slotted-angular-otp-input.d.ts +286 -0
- package/types/slotted-angular-otp-input.d.ts.map +1 -0
- package/types/slotted-angular-page-header.d.ts +334 -0
- package/types/slotted-angular-page-header.d.ts.map +1 -0
- package/types/slotted-angular-page.d.ts +141 -0
- package/types/slotted-angular-page.d.ts.map +1 -0
- package/types/slotted-angular-pagination.d.ts +213 -0
- package/types/slotted-angular-pagination.d.ts.map +1 -0
- package/types/slotted-angular-popover.d.ts +366 -0
- package/types/slotted-angular-popover.d.ts.map +1 -0
- package/types/slotted-angular-progress-indicator.d.ts +312 -0
- package/types/slotted-angular-progress-indicator.d.ts.map +1 -0
- package/types/slotted-angular-prompt-composer.d.ts +242 -0
- package/types/slotted-angular-prompt-composer.d.ts.map +1 -0
- package/types/slotted-angular-prose.d.ts +171 -0
- package/types/slotted-angular-prose.d.ts.map +1 -0
- package/types/slotted-angular-radio-group.d.ts +268 -0
- package/types/slotted-angular-radio-group.d.ts.map +1 -0
- package/types/slotted-angular-rating.d.ts +374 -0
- package/types/slotted-angular-rating.d.ts.map +1 -0
- package/types/slotted-angular-result-state.d.ts +217 -0
- package/types/slotted-angular-result-state.d.ts.map +1 -0
- package/types/slotted-angular-saved-views.d.ts +198 -0
- package/types/slotted-angular-saved-views.d.ts.map +1 -0
- package/types/slotted-angular-scroll-area.d.ts +186 -0
- package/types/slotted-angular-scroll-area.d.ts.map +1 -0
- package/types/slotted-angular-section.d.ts +143 -0
- package/types/slotted-angular-section.d.ts.map +1 -0
- package/types/slotted-angular-segmented-control.d.ts +251 -0
- package/types/slotted-angular-segmented-control.d.ts.map +1 -0
- package/types/slotted-angular-select.d.ts +507 -0
- package/types/slotted-angular-select.d.ts.map +1 -0
- package/types/slotted-angular-side-navigation.d.ts +373 -0
- package/types/slotted-angular-side-navigation.d.ts.map +1 -0
- package/types/slotted-angular-skeleton.d.ts +198 -0
- package/types/slotted-angular-skeleton.d.ts.map +1 -0
- package/types/slotted-angular-slider.d.ts +216 -0
- package/types/slotted-angular-slider.d.ts.map +1 -0
- package/types/slotted-angular-sparkline.d.ts +106 -0
- package/types/slotted-angular-sparkline.d.ts.map +1 -0
- package/types/slotted-angular-split-button.d.ts +180 -0
- package/types/slotted-angular-split-button.d.ts.map +1 -0
- package/types/slotted-angular-splitter.d.ts +206 -0
- package/types/slotted-angular-splitter.d.ts.map +1 -0
- package/types/slotted-angular-stack.d.ts +38 -0
- package/types/slotted-angular-stack.d.ts.map +1 -0
- package/types/slotted-angular-stat-card.d.ts +232 -0
- package/types/slotted-angular-stat-card.d.ts.map +1 -0
- package/types/slotted-angular-status-indicator.d.ts +106 -0
- package/types/slotted-angular-status-indicator.d.ts.map +1 -0
- package/types/slotted-angular-stepper.d.ts +198 -0
- package/types/slotted-angular-stepper.d.ts.map +1 -0
- package/types/slotted-angular-switch.d.ts +243 -0
- package/types/slotted-angular-switch.d.ts.map +1 -0
- package/types/slotted-angular-table-of-contents.d.ts +210 -0
- package/types/slotted-angular-table-of-contents.d.ts.map +1 -0
- package/types/slotted-angular-table.d.ts +888 -0
- package/types/slotted-angular-table.d.ts.map +1 -0
- package/types/slotted-angular-tabs.d.ts +340 -0
- package/types/slotted-angular-tabs.d.ts.map +1 -0
- package/types/slotted-angular-tag.d.ts +279 -0
- package/types/slotted-angular-tag.d.ts.map +1 -0
- package/types/slotted-angular-tags-input.d.ts +302 -0
- package/types/slotted-angular-tags-input.d.ts.map +1 -0
- package/types/slotted-angular-text-field.d.ts +334 -0
- package/types/slotted-angular-text-field.d.ts.map +1 -0
- package/types/slotted-angular-textarea.d.ts +150 -0
- package/types/slotted-angular-textarea.d.ts.map +1 -0
- package/types/slotted-angular-theme.d.ts +26 -0
- package/types/slotted-angular-theme.d.ts.map +1 -0
- package/types/slotted-angular-time-field.d.ts +300 -0
- package/types/slotted-angular-time-field.d.ts.map +1 -0
- package/types/slotted-angular-time-picker.d.ts +260 -0
- package/types/slotted-angular-time-picker.d.ts.map +1 -0
- package/types/slotted-angular-time-range-picker.d.ts +401 -0
- package/types/slotted-angular-time-range-picker.d.ts.map +1 -0
- package/types/slotted-angular-timeline.d.ts +329 -0
- package/types/slotted-angular-timeline.d.ts.map +1 -0
- package/types/slotted-angular-toast.d.ts +340 -0
- package/types/slotted-angular-toast.d.ts.map +1 -0
- package/types/slotted-angular-toggle-group.d.ts +167 -0
- package/types/slotted-angular-toggle-group.d.ts.map +1 -0
- package/types/slotted-angular-toggle.d.ts +106 -0
- package/types/slotted-angular-toggle.d.ts.map +1 -0
- package/types/slotted-angular-toolbar.d.ts +252 -0
- package/types/slotted-angular-toolbar.d.ts.map +1 -0
- package/types/slotted-angular-tooltip.d.ts +388 -0
- package/types/slotted-angular-tooltip.d.ts.map +1 -0
- package/types/slotted-angular-top-navigation.d.ts +442 -0
- package/types/slotted-angular-top-navigation.d.ts.map +1 -0
- package/types/slotted-angular-tour.d.ts +440 -0
- package/types/slotted-angular-tour.d.ts.map +1 -0
- package/types/slotted-angular-transfer.d.ts +296 -0
- package/types/slotted-angular-transfer.d.ts.map +1 -0
- package/types/slotted-angular-tree.d.ts +499 -0
- package/types/slotted-angular-tree.d.ts.map +1 -0
- package/types/slotted-angular-typography.d.ts +89 -0
- package/types/slotted-angular-typography.d.ts.map +1 -0
- package/types/slotted-angular-upload.d.ts +365 -0
- package/types/slotted-angular-upload.d.ts.map +1 -0
- package/types/slotted-angular-visually-hidden.d.ts +19 -0
- package/types/slotted-angular-visually-hidden.d.ts.map +1 -0
- package/types/slotted-angular-wizard.d.ts +441 -0
- package/types/slotted-angular-wizard.d.ts.map +1 -0
- package/types/slotted-angular.d.ts +3 -0
- package/types/slotted-angular.d.ts.map +1 -0
|
@@ -0,0 +1,1929 @@
|
|
|
1
|
+
<!-- index: ./index.md -->
|
|
2
|
+
# drawer
|
|
3
|
+
|
|
4
|
+
`data-ui="drawer"` · Panel that slides in from an edge.
|
|
5
|
+
|
|
6
|
+
## Examples
|
|
7
|
+
|
|
8
|
+
### Playground
|
|
9
|
+
|
|
10
|
+
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.
|
|
11
|
+
|
|
12
|
+
Excerpt — not a complete module
|
|
13
|
+
|
|
14
|
+
```html
|
|
15
|
+
<button slButton [slDrawerTrigger]="d">Abrir detalhes</button>
|
|
16
|
+
<sl-drawer #d="slDrawer">
|
|
17
|
+
<header slDrawerHeader>
|
|
18
|
+
<h2 slDrawerTitle>Fatura 4471</h2>
|
|
19
|
+
<p slDrawerDescription>Emitida em 12 de agosto.</p>
|
|
20
|
+
<button slDrawerClose></button>
|
|
21
|
+
</header>
|
|
22
|
+
<div slDrawerBody>
|
|
23
|
+
<input slTextField aria-label="Observação" />
|
|
24
|
+
</div>
|
|
25
|
+
<footer slDrawerFooter>
|
|
26
|
+
<button slButton size="sm" variant="ghost" tone="secondary">Cancelar</button>
|
|
27
|
+
<button slButton size="sm">Salvar</button>
|
|
28
|
+
</footer>
|
|
29
|
+
</sl-drawer>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### A layer over the page, or a panel beside it
|
|
33
|
+
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
Excerpt — not a complete module
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<div style="display: grid; grid-template-columns: auto minmax(0, 1fr)">
|
|
40
|
+
<sl-drawer [mode]="wide() ? 'inline' : 'overlay'" [(open)]="open" side="start">
|
|
41
|
+
<nav slDrawerBody aria-label="Seções">…</nav>
|
|
42
|
+
</sl-drawer>
|
|
43
|
+
<main>…</main>
|
|
44
|
+
</div>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Which edge it comes from
|
|
48
|
+
|
|
49
|
+
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.
|
|
50
|
+
|
|
51
|
+
Excerpt — not a complete module
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<sl-drawer side="bottom" [(open)]="open">
|
|
55
|
+
<div slDrawerBody>…</div>
|
|
56
|
+
</sl-drawer>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### How much room the panel takes
|
|
60
|
+
|
|
61
|
+
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.
|
|
62
|
+
|
|
63
|
+
Excerpt — not a complete module
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<sl-drawer size="lg">…</sl-drawer>
|
|
67
|
+
|
|
68
|
+
<!-- An exact measure is the token the steps resolve into. -->
|
|
69
|
+
<sl-drawer style="--slotted-drawer-extent: 27rem">…</sl-drawer>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### An edge the reader can move — with a keyboard
|
|
73
|
+
|
|
74
|
+
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.
|
|
75
|
+
|
|
76
|
+
Example
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { Component, computed, signal } from '@angular/core';
|
|
80
|
+
import { SlButton } from '@slotted/angular/button';
|
|
81
|
+
import {
|
|
82
|
+
SlDescriptionList,
|
|
83
|
+
SlDescriptionListDescription,
|
|
84
|
+
SlDescriptionListItem,
|
|
85
|
+
SlDescriptionListTerm,
|
|
86
|
+
} from '@slotted/angular/description-list';
|
|
87
|
+
import {
|
|
88
|
+
SlDrawer,
|
|
89
|
+
SlDrawerBody,
|
|
90
|
+
SlDrawerClose,
|
|
91
|
+
SlDrawerDescription,
|
|
92
|
+
SlDrawerHeader,
|
|
93
|
+
SlDrawerResizer,
|
|
94
|
+
SlDrawerTitle,
|
|
95
|
+
SlDrawerTrigger,
|
|
96
|
+
} from '@slotted/angular/drawer';
|
|
97
|
+
|
|
98
|
+
const LINES = [
|
|
99
|
+
{ term: 'Arabica beans, 5 kg', value: '6 cases, $420.00' },
|
|
100
|
+
{ term: 'Oat milk, 12 × 1 L', value: '4 cases, $192.00' },
|
|
101
|
+
{ term: 'Paper cups, 16 oz, 1,000 per case', value: '4 cases, $628.00' },
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
@Component({
|
|
105
|
+
selector: 'app-drawer-resize',
|
|
106
|
+
imports: [
|
|
107
|
+
SlButton,
|
|
108
|
+
SlDescriptionList,
|
|
109
|
+
SlDescriptionListDescription,
|
|
110
|
+
SlDescriptionListItem,
|
|
111
|
+
SlDescriptionListTerm,
|
|
112
|
+
SlDrawer,
|
|
113
|
+
SlDrawerBody,
|
|
114
|
+
SlDrawerClose,
|
|
115
|
+
SlDrawerDescription,
|
|
116
|
+
SlDrawerHeader,
|
|
117
|
+
SlDrawerResizer,
|
|
118
|
+
SlDrawerTitle,
|
|
119
|
+
SlDrawerTrigger,
|
|
120
|
+
],
|
|
121
|
+
template: `
|
|
122
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
123
|
+
View order lines
|
|
124
|
+
</button>
|
|
125
|
+
<sl-drawer #drawer="slDrawer" [maxExtent]="0.8" [minExtent]="0.25" [(extent)]="extent">
|
|
126
|
+
<header slDrawerHeader>
|
|
127
|
+
<h2 slDrawerTitle>Order SO-1182 lines</h2>
|
|
128
|
+
<p slDrawerDescription>Width: {{ width() }}.</p>
|
|
129
|
+
<button slDrawerClose></button>
|
|
130
|
+
</header>
|
|
131
|
+
<div slDrawerBody>
|
|
132
|
+
<div slDescriptionList>
|
|
133
|
+
@for (line of lines; track line.term) {
|
|
134
|
+
<div slDescriptionListItem>
|
|
135
|
+
<dt slDescriptionListTerm>{{ line.term }}</dt>
|
|
136
|
+
<dd slDescriptionListDescription>{{ line.value }}</dd>
|
|
137
|
+
</div>
|
|
138
|
+
}
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
<div slDrawerResizer></div>
|
|
142
|
+
</sl-drawer>
|
|
143
|
+
`,
|
|
144
|
+
})
|
|
145
|
+
export class DrawerResize {
|
|
146
|
+
readonly lines = LINES;
|
|
147
|
+
readonly extent = signal<number | undefined>(undefined);
|
|
148
|
+
readonly width = computed(() => {
|
|
149
|
+
const extent = this.extent();
|
|
150
|
+
return extent === undefined ? 'the md step' : `${Math.round(extent * 100)}% of the window`;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Stops the sheet lands on
|
|
156
|
+
|
|
157
|
+
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.
|
|
158
|
+
|
|
159
|
+
Excerpt — not a complete module
|
|
160
|
+
|
|
161
|
+
```html
|
|
162
|
+
<sl-drawer side="bottom" [snapPoints]="[0.3, 0.6, 0.95]" [(extent)]="extent">
|
|
163
|
+
<div slDrawerResizer></div>
|
|
164
|
+
<div slDrawerBody>…</div>
|
|
165
|
+
</sl-drawer>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### A bottom sheet as a phone draws one
|
|
169
|
+
|
|
170
|
+
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.
|
|
171
|
+
|
|
172
|
+
Example
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import { Component, computed, signal } from '@angular/core';
|
|
176
|
+
import { SlButton } from '@slotted/angular/button';
|
|
177
|
+
import {
|
|
178
|
+
SlDrawer,
|
|
179
|
+
SlDrawerBody,
|
|
180
|
+
SlDrawerClose,
|
|
181
|
+
SlDrawerDescription,
|
|
182
|
+
SlDrawerFooter,
|
|
183
|
+
SlDrawerHeader,
|
|
184
|
+
SlDrawerResizer,
|
|
185
|
+
SlDrawerTitle,
|
|
186
|
+
SlDrawerTrigger,
|
|
187
|
+
} from '@slotted/angular/drawer';
|
|
188
|
+
import { SlFieldGroup, SlFieldGroupLegend } from '@slotted/angular/field-group';
|
|
189
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
190
|
+
import { SlRadio, SlRadioGroup } from '@slotted/angular/radio-group';
|
|
191
|
+
import { SlText } from '@slotted/angular/typography';
|
|
192
|
+
|
|
193
|
+
const WINDOWS = [
|
|
194
|
+
{ value: 'morning', label: 'Thursday 8 October, 8 AM to noon' },
|
|
195
|
+
{ value: 'afternoon', label: 'Thursday 8 October, 1 to 5 PM' },
|
|
196
|
+
{ value: 'friday', label: 'Friday 9 October, 8 AM to noon' },
|
|
197
|
+
];
|
|
198
|
+
|
|
199
|
+
@Component({
|
|
200
|
+
selector: 'app-drawer-sheet',
|
|
201
|
+
imports: [
|
|
202
|
+
SlButton,
|
|
203
|
+
SlDrawer,
|
|
204
|
+
SlDrawerBody,
|
|
205
|
+
SlDrawerClose,
|
|
206
|
+
SlDrawerDescription,
|
|
207
|
+
SlDrawerFooter,
|
|
208
|
+
SlDrawerHeader,
|
|
209
|
+
SlDrawerResizer,
|
|
210
|
+
SlDrawerTitle,
|
|
211
|
+
SlDrawerTrigger,
|
|
212
|
+
SlFieldGroup,
|
|
213
|
+
SlFieldGroupLegend,
|
|
214
|
+
SlInline,
|
|
215
|
+
SlRadio,
|
|
216
|
+
SlRadioGroup,
|
|
217
|
+
SlText,
|
|
218
|
+
],
|
|
219
|
+
template: `
|
|
220
|
+
<div slInline align="center" [gap]="3">
|
|
221
|
+
<span slText size="sm">Pickup: {{ pickupLabel() }}</span>
|
|
222
|
+
<button slButton size="sm" tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
223
|
+
Reschedule
|
|
224
|
+
</button>
|
|
225
|
+
<sl-drawer #drawer="slDrawer" side="bottom" [open]="open()" (openChange)="toggle($event)">
|
|
226
|
+
<div slDrawerResizer></div>
|
|
227
|
+
<header slDrawerHeader>
|
|
228
|
+
<h2 slDrawerTitle>Reschedule pickup</h2>
|
|
229
|
+
<p slDrawerDescription>Shipment SH-4471, UPS Ground from Reno, NV.</p>
|
|
230
|
+
<button slDrawerClose></button>
|
|
231
|
+
</header>
|
|
232
|
+
<div slDrawerBody>
|
|
233
|
+
<fieldset slFieldGroup>
|
|
234
|
+
<legend slFieldGroupLegend>Pickup window</legend>
|
|
235
|
+
<div slRadioGroup [value]="draft()" (valueChange)="draft.set($event.value ?? draft())">
|
|
236
|
+
@for (window of windows; track window.value) {
|
|
237
|
+
<div slRadio [value]="window.value">{{ window.label }}</div>
|
|
238
|
+
}
|
|
239
|
+
</div>
|
|
240
|
+
</fieldset>
|
|
241
|
+
</div>
|
|
242
|
+
<footer slDrawerFooter>
|
|
243
|
+
<button slButton variant="ghost" tone="secondary" (click)="open.set(false)">
|
|
244
|
+
Cancel
|
|
245
|
+
</button>
|
|
246
|
+
<button slButton (click)="reschedule()">Reschedule</button>
|
|
247
|
+
</footer>
|
|
248
|
+
</sl-drawer>
|
|
249
|
+
</div>
|
|
250
|
+
`,
|
|
251
|
+
})
|
|
252
|
+
export class DrawerSheet {
|
|
253
|
+
readonly windows = WINDOWS;
|
|
254
|
+
readonly open = signal(false);
|
|
255
|
+
readonly pickup = signal('morning');
|
|
256
|
+
readonly draft = signal(this.pickup());
|
|
257
|
+
readonly pickupLabel = computed(
|
|
258
|
+
() => WINDOWS.find((window) => window.value === this.pickup())?.label,
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
toggle(next: boolean): void {
|
|
262
|
+
if (next) this.draft.set(this.pickup());
|
|
263
|
+
this.open.set(next);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
reschedule(): void {
|
|
267
|
+
this.pickup.set(this.draft());
|
|
268
|
+
this.open.set(false);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### A sheet over a page that stays in use
|
|
274
|
+
|
|
275
|
+
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.
|
|
276
|
+
|
|
277
|
+
Excerpt — not a complete module
|
|
278
|
+
|
|
279
|
+
```html
|
|
280
|
+
<sl-drawer
|
|
281
|
+
side="bottom"
|
|
282
|
+
[snapPoints]="[0.25, 0.6, 0.95]"
|
|
283
|
+
[(extent)]="extent"
|
|
284
|
+
[scrimFrom]="0.6"
|
|
285
|
+
[modal]="false"
|
|
286
|
+
outsidePress="none"
|
|
287
|
+
>
|
|
288
|
+
…
|
|
289
|
+
</sl-drawer>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### A sheet above the virtual keyboard
|
|
293
|
+
|
|
294
|
+
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.
|
|
295
|
+
|
|
296
|
+
Excerpt — not a complete module
|
|
297
|
+
|
|
298
|
+
```html
|
|
299
|
+
<sl-drawer side="bottom" [(open)]="reminding">
|
|
300
|
+
<header slDrawerHeader><h2 slDrawerTitle>Enviar lembrete</h2></header>
|
|
301
|
+
<div slDrawerBody>
|
|
302
|
+
<input slTextField aria-label="Nota para o cliente" />
|
|
303
|
+
</div>
|
|
304
|
+
<footer slDrawerFooter>…</footer>
|
|
305
|
+
</sl-drawer>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### A drawer the page behind can still be used
|
|
309
|
+
|
|
310
|
+
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.
|
|
311
|
+
|
|
312
|
+
Excerpt — not a complete module
|
|
313
|
+
|
|
314
|
+
```html
|
|
315
|
+
<sl-drawer [modal]="false" [(open)]="open">
|
|
316
|
+
<div slDrawerBody>…</div>
|
|
317
|
+
</sl-drawer>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Refusing a close, and refusing it once
|
|
321
|
+
|
|
322
|
+
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.
|
|
323
|
+
|
|
324
|
+
Excerpt — not a complete module
|
|
325
|
+
|
|
326
|
+
```html
|
|
327
|
+
<sl-drawer [(open)]="open" (openChangeRequest)="guard($event)">…</sl-drawer>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Where focus goes, and where it comes back to
|
|
331
|
+
|
|
332
|
+
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.
|
|
333
|
+
|
|
334
|
+
Excerpt — not a complete module
|
|
335
|
+
|
|
336
|
+
```html
|
|
337
|
+
<sl-drawer [initialFocus]="search">
|
|
338
|
+
<div slDrawerBody>
|
|
339
|
+
<input #search slTextField aria-label="Buscar" />
|
|
340
|
+
</div>
|
|
341
|
+
</sl-drawer>
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Open before the content arrived
|
|
345
|
+
|
|
346
|
+
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.
|
|
347
|
+
|
|
348
|
+
Example
|
|
349
|
+
|
|
350
|
+
```ts
|
|
351
|
+
import { Component, effect, signal } from '@angular/core';
|
|
352
|
+
import { SlButton } from '@slotted/angular/button';
|
|
353
|
+
import {
|
|
354
|
+
SlDescriptionList,
|
|
355
|
+
SlDescriptionListDescription,
|
|
356
|
+
SlDescriptionListItem,
|
|
357
|
+
SlDescriptionListTerm,
|
|
358
|
+
} from '@slotted/angular/description-list';
|
|
359
|
+
import {
|
|
360
|
+
SlDrawer,
|
|
361
|
+
SlDrawerBody,
|
|
362
|
+
SlDrawerClose,
|
|
363
|
+
SlDrawerDescription,
|
|
364
|
+
SlDrawerHeader,
|
|
365
|
+
SlDrawerTitle,
|
|
366
|
+
SlDrawerTrigger,
|
|
367
|
+
} from '@slotted/angular/drawer';
|
|
368
|
+
import { SlSkeleton, SlSkeletonRegion } from '@slotted/angular/skeleton';
|
|
369
|
+
|
|
370
|
+
interface Shipment {
|
|
371
|
+
carrier: string;
|
|
372
|
+
tracking: string;
|
|
373
|
+
packages: string;
|
|
374
|
+
delivery: string;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const FIELDS: { key: keyof Shipment; term: string; width: string }[] = [
|
|
378
|
+
{ key: 'carrier', term: 'Carrier', width: '6rem' },
|
|
379
|
+
{ key: 'tracking', term: 'Tracking number', width: '11rem' },
|
|
380
|
+
{ key: 'packages', term: 'Packages', width: '8rem' },
|
|
381
|
+
{ key: 'delivery', term: 'Estimated delivery', width: '9rem' },
|
|
382
|
+
];
|
|
383
|
+
|
|
384
|
+
@Component({
|
|
385
|
+
selector: 'app-drawer-loading',
|
|
386
|
+
imports: [
|
|
387
|
+
SlButton,
|
|
388
|
+
SlDescriptionList,
|
|
389
|
+
SlDescriptionListDescription,
|
|
390
|
+
SlDescriptionListItem,
|
|
391
|
+
SlDescriptionListTerm,
|
|
392
|
+
SlDrawer,
|
|
393
|
+
SlDrawerBody,
|
|
394
|
+
SlDrawerClose,
|
|
395
|
+
SlDrawerDescription,
|
|
396
|
+
SlDrawerHeader,
|
|
397
|
+
SlDrawerTitle,
|
|
398
|
+
SlDrawerTrigger,
|
|
399
|
+
SlSkeleton,
|
|
400
|
+
SlSkeletonRegion,
|
|
401
|
+
],
|
|
402
|
+
template: `
|
|
403
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
404
|
+
Track shipment SH-4471
|
|
405
|
+
</button>
|
|
406
|
+
<sl-drawer #drawer="slDrawer" [loading]="shipment() === null" [(open)]="open">
|
|
407
|
+
<header slDrawerHeader>
|
|
408
|
+
<h2 slDrawerTitle>Shipment SH-4471</h2>
|
|
409
|
+
<p slDrawerDescription>Order SO-1182 for Contoso Foods, Seattle.</p>
|
|
410
|
+
<button slDrawerClose></button>
|
|
411
|
+
</header>
|
|
412
|
+
<div slDrawerBody>
|
|
413
|
+
<div
|
|
414
|
+
slSkeletonRegion
|
|
415
|
+
[delay]="200"
|
|
416
|
+
[loading]="shipment() === null"
|
|
417
|
+
[messages]="{ label: 'Loading shipment' }"
|
|
418
|
+
[minDuration]="400"
|
|
419
|
+
>
|
|
420
|
+
<div slDescriptionList>
|
|
421
|
+
@for (field of fields; track field.key) {
|
|
422
|
+
<div slDescriptionListItem>
|
|
423
|
+
<dt slDescriptionListTerm>{{ field.term }}</dt>
|
|
424
|
+
<dd slDescriptionListDescription>
|
|
425
|
+
@if (shipment(); as loaded) {
|
|
426
|
+
{{ loaded[field.key] }}
|
|
427
|
+
} @else {
|
|
428
|
+
<span slSkeleton [inlineSize]="field.width"></span>
|
|
429
|
+
}
|
|
430
|
+
</dd>
|
|
431
|
+
</div>
|
|
432
|
+
}
|
|
433
|
+
</div>
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
</sl-drawer>
|
|
437
|
+
`,
|
|
438
|
+
})
|
|
439
|
+
export class DrawerLoading {
|
|
440
|
+
readonly fields = FIELDS;
|
|
441
|
+
readonly open = signal(false);
|
|
442
|
+
readonly shipment = signal<Shipment | null>(null);
|
|
443
|
+
|
|
444
|
+
constructor() {
|
|
445
|
+
effect((onCleanup) => {
|
|
446
|
+
if (!this.open()) return;
|
|
447
|
+
this.shipment.set(null);
|
|
448
|
+
const timer = setTimeout(
|
|
449
|
+
() =>
|
|
450
|
+
this.shipment.set({
|
|
451
|
+
carrier: 'UPS Ground',
|
|
452
|
+
tracking: '1Z 999 AA1 01 2345 6784',
|
|
453
|
+
packages: '3, 18.4 kg in total',
|
|
454
|
+
delivery: 'Thursday, 8 October',
|
|
455
|
+
}),
|
|
456
|
+
1200,
|
|
457
|
+
);
|
|
458
|
+
onCleanup(() => clearTimeout(timer));
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### A drawer opened from a drawer
|
|
465
|
+
|
|
466
|
+
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.
|
|
467
|
+
|
|
468
|
+
Example
|
|
469
|
+
|
|
470
|
+
```ts
|
|
471
|
+
import { Component } from '@angular/core';
|
|
472
|
+
import { SlButton } from '@slotted/angular/button';
|
|
473
|
+
import {
|
|
474
|
+
SlDescriptionList,
|
|
475
|
+
SlDescriptionListDescription,
|
|
476
|
+
SlDescriptionListItem,
|
|
477
|
+
SlDescriptionListTerm,
|
|
478
|
+
} from '@slotted/angular/description-list';
|
|
479
|
+
import {
|
|
480
|
+
SlDrawer,
|
|
481
|
+
SlDrawerBody,
|
|
482
|
+
SlDrawerClose,
|
|
483
|
+
SlDrawerDescription,
|
|
484
|
+
SlDrawerHeader,
|
|
485
|
+
SlDrawerTitle,
|
|
486
|
+
SlDrawerTrigger,
|
|
487
|
+
} from '@slotted/angular/drawer';
|
|
488
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
489
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
490
|
+
|
|
491
|
+
const ORDER = [
|
|
492
|
+
{ term: 'Customer', value: 'Contoso Foods' },
|
|
493
|
+
{ term: 'Items', value: '14 cases, 3 products' },
|
|
494
|
+
{ term: 'Total', value: '$1,240.00' },
|
|
495
|
+
];
|
|
496
|
+
|
|
497
|
+
const CUSTOMER = [
|
|
498
|
+
{ term: 'Account', value: 'C-0042' },
|
|
499
|
+
{ term: 'Contact', value: 'Ana Ruiz, ap@contoso.com' },
|
|
500
|
+
{ term: 'Open orders', value: '3, $4,815.50 in total' },
|
|
501
|
+
{ term: 'Payment terms', value: 'Net 30' },
|
|
502
|
+
];
|
|
503
|
+
|
|
504
|
+
@Component({
|
|
505
|
+
selector: 'app-drawer-nested',
|
|
506
|
+
imports: [
|
|
507
|
+
SlButton,
|
|
508
|
+
SlDescriptionList,
|
|
509
|
+
SlDescriptionListDescription,
|
|
510
|
+
SlDescriptionListItem,
|
|
511
|
+
SlDescriptionListTerm,
|
|
512
|
+
SlDrawer,
|
|
513
|
+
SlDrawerBody,
|
|
514
|
+
SlDrawerClose,
|
|
515
|
+
SlDrawerDescription,
|
|
516
|
+
SlDrawerHeader,
|
|
517
|
+
SlDrawerTitle,
|
|
518
|
+
SlDrawerTrigger,
|
|
519
|
+
SlInline,
|
|
520
|
+
SlStack,
|
|
521
|
+
],
|
|
522
|
+
template: `
|
|
523
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="order">
|
|
524
|
+
View order SO-1182
|
|
525
|
+
</button>
|
|
526
|
+
<sl-drawer #order="slDrawer">
|
|
527
|
+
<header slDrawerHeader>
|
|
528
|
+
<h2 slDrawerTitle>Order SO-1182</h2>
|
|
529
|
+
<p slDrawerDescription>Placed on 2 October 2026.</p>
|
|
530
|
+
<button slDrawerClose></button>
|
|
531
|
+
</header>
|
|
532
|
+
<div slDrawerBody>
|
|
533
|
+
<div slStack [gap]="5">
|
|
534
|
+
<div slDescriptionList>
|
|
535
|
+
@for (detail of orderDetails; track detail.term) {
|
|
536
|
+
<div slDescriptionListItem>
|
|
537
|
+
<dt slDescriptionListTerm>{{ detail.term }}</dt>
|
|
538
|
+
<dd slDescriptionListDescription>{{ detail.value }}</dd>
|
|
539
|
+
</div>
|
|
540
|
+
}
|
|
541
|
+
</div>
|
|
542
|
+
<div slInline>
|
|
543
|
+
<button
|
|
544
|
+
slButton
|
|
545
|
+
size="sm"
|
|
546
|
+
tone="secondary"
|
|
547
|
+
variant="outline"
|
|
548
|
+
[slDrawerTrigger]="customer"
|
|
549
|
+
>
|
|
550
|
+
View customer
|
|
551
|
+
</button>
|
|
552
|
+
</div>
|
|
553
|
+
<sl-drawer #customer="slDrawer" size="sm">
|
|
554
|
+
<header slDrawerHeader>
|
|
555
|
+
<h2 slDrawerTitle>Contoso Foods</h2>
|
|
556
|
+
<p slDrawerDescription>Customer since March 2021.</p>
|
|
557
|
+
<button slDrawerClose></button>
|
|
558
|
+
</header>
|
|
559
|
+
<div slDrawerBody>
|
|
560
|
+
<div slDescriptionList>
|
|
561
|
+
@for (detail of customerDetails; track detail.term) {
|
|
562
|
+
<div slDescriptionListItem>
|
|
563
|
+
<dt slDescriptionListTerm>{{ detail.term }}</dt>
|
|
564
|
+
<dd slDescriptionListDescription>{{ detail.value }}</dd>
|
|
565
|
+
</div>
|
|
566
|
+
}
|
|
567
|
+
</div>
|
|
568
|
+
</div>
|
|
569
|
+
</sl-drawer>
|
|
570
|
+
</div>
|
|
571
|
+
</div>
|
|
572
|
+
</sl-drawer>
|
|
573
|
+
`,
|
|
574
|
+
})
|
|
575
|
+
export class DrawerNested {
|
|
576
|
+
readonly orderDetails = ORDER;
|
|
577
|
+
readonly customerDetails = CUSTOMER;
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### Content the family did not choose
|
|
582
|
+
|
|
583
|
+
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.
|
|
584
|
+
|
|
585
|
+
Excerpt — not a complete module
|
|
586
|
+
|
|
587
|
+
```html
|
|
588
|
+
<sl-drawer>
|
|
589
|
+
<header slDrawerHeader>
|
|
590
|
+
<h2 slDrawerTitle>{{ fileName }}</h2>
|
|
591
|
+
</header>
|
|
592
|
+
<div slDrawerBody>{{ longText }}</div>
|
|
593
|
+
<footer slDrawerFooter><button slButton>Salvar</button></footer>
|
|
594
|
+
</sl-drawer>
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### The parts are the consumer’s own elements
|
|
598
|
+
|
|
599
|
+
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.
|
|
600
|
+
|
|
601
|
+
Excerpt — not a complete module
|
|
602
|
+
|
|
603
|
+
```html
|
|
604
|
+
<button slButton variant="outline" [slDrawerTrigger]="d">Abrir</button>
|
|
605
|
+
<sl-drawer #d="slDrawer" mode="inline" side="start">
|
|
606
|
+
<nav slDrawerBody aria-label="Seções">…</nav>
|
|
607
|
+
</sl-drawer>
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### What an application decides once
|
|
611
|
+
|
|
612
|
+
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.
|
|
613
|
+
|
|
614
|
+
Example
|
|
615
|
+
|
|
616
|
+
```ts
|
|
617
|
+
import { Component } from '@angular/core';
|
|
618
|
+
import { SlButton } from '@slotted/angular/button';
|
|
619
|
+
import {
|
|
620
|
+
provideDrawerDefaults,
|
|
621
|
+
SlDrawer,
|
|
622
|
+
SlDrawerBody,
|
|
623
|
+
SlDrawerClose,
|
|
624
|
+
SlDrawerHeader,
|
|
625
|
+
SlDrawerTitle,
|
|
626
|
+
SlDrawerTrigger,
|
|
627
|
+
} from '@slotted/angular/drawer';
|
|
628
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
629
|
+
import { SlText } from '@slotted/angular/typography';
|
|
630
|
+
|
|
631
|
+
@Component({
|
|
632
|
+
selector: 'app-drawer-defaults',
|
|
633
|
+
imports: [
|
|
634
|
+
SlButton,
|
|
635
|
+
SlDrawer,
|
|
636
|
+
SlDrawerBody,
|
|
637
|
+
SlDrawerClose,
|
|
638
|
+
SlDrawerHeader,
|
|
639
|
+
SlDrawerTitle,
|
|
640
|
+
SlDrawerTrigger,
|
|
641
|
+
SlInline,
|
|
642
|
+
SlText,
|
|
643
|
+
],
|
|
644
|
+
providers: [provideDrawerDefaults({ side: 'start', size: 'sm' })],
|
|
645
|
+
template: `
|
|
646
|
+
<div slInline [gap]="2">
|
|
647
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="warehouses">
|
|
648
|
+
Warehouses
|
|
649
|
+
</button>
|
|
650
|
+
<sl-drawer #warehouses="slDrawer">
|
|
651
|
+
<header slDrawerHeader>
|
|
652
|
+
<h2 slDrawerTitle>Warehouses</h2>
|
|
653
|
+
<button slDrawerClose></button>
|
|
654
|
+
</header>
|
|
655
|
+
<div slDrawerBody>
|
|
656
|
+
<span slText size="sm">From the start edge and small, both from the provider.</span>
|
|
657
|
+
</div>
|
|
658
|
+
</sl-drawer>
|
|
659
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="carriers">
|
|
660
|
+
Carriers
|
|
661
|
+
</button>
|
|
662
|
+
<sl-drawer #carriers="slDrawer" size="lg">
|
|
663
|
+
<header slDrawerHeader>
|
|
664
|
+
<h2 slDrawerTitle>Carriers</h2>
|
|
665
|
+
<button slDrawerClose></button>
|
|
666
|
+
</header>
|
|
667
|
+
<div slDrawerBody>
|
|
668
|
+
<span slText size="sm">
|
|
669
|
+
From the start edge, from the provider, and large because this drawer says so.
|
|
670
|
+
</span>
|
|
671
|
+
</div>
|
|
672
|
+
</sl-drawer>
|
|
673
|
+
</div>
|
|
674
|
+
`,
|
|
675
|
+
})
|
|
676
|
+
export class DrawerDefaults {}
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
### What a reader hears, and what they can reach
|
|
680
|
+
|
|
681
|
+
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.
|
|
682
|
+
|
|
683
|
+
Excerpt — not a complete module
|
|
684
|
+
|
|
685
|
+
```html
|
|
686
|
+
<sl-drawer mode="inline" side="start">
|
|
687
|
+
<header slDrawerHeader><h2 slDrawerTitle>Coleções</h2></header>
|
|
688
|
+
<div slDrawerResizer></div>
|
|
689
|
+
</sl-drawer>
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
### detail-panel.ts
|
|
693
|
+
|
|
694
|
+
Example
|
|
695
|
+
|
|
696
|
+
```ts
|
|
697
|
+
import { Component, signal } from '@angular/core';
|
|
698
|
+
import { SlBadge } from '@slotted/angular/badge';
|
|
699
|
+
import { SlButton } from '@slotted/angular/button';
|
|
700
|
+
import {
|
|
701
|
+
SlDescriptionList,
|
|
702
|
+
SlDescriptionListDescription,
|
|
703
|
+
SlDescriptionListItem,
|
|
704
|
+
SlDescriptionListTerm,
|
|
705
|
+
} from '@slotted/angular/description-list';
|
|
706
|
+
import {
|
|
707
|
+
SlDrawer,
|
|
708
|
+
SlDrawerBody,
|
|
709
|
+
SlDrawerClose,
|
|
710
|
+
SlDrawerDescription,
|
|
711
|
+
SlDrawerHeader,
|
|
712
|
+
SlDrawerTitle,
|
|
713
|
+
} from '@slotted/angular/drawer';
|
|
714
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
715
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
716
|
+
import {
|
|
717
|
+
SlTable,
|
|
718
|
+
SlTableBody,
|
|
719
|
+
SlTableCell,
|
|
720
|
+
SlTableColumnHeader,
|
|
721
|
+
SlTableContent,
|
|
722
|
+
SlTableHead,
|
|
723
|
+
SlTableRow,
|
|
724
|
+
SlTableRowHeader,
|
|
725
|
+
} from '@slotted/angular/table';
|
|
726
|
+
import { SlVisuallyHidden } from '@slotted/angular/visually-hidden';
|
|
727
|
+
|
|
728
|
+
const ORDERS = [
|
|
729
|
+
{
|
|
730
|
+
id: 'SO-1182',
|
|
731
|
+
customer: 'Contoso Foods',
|
|
732
|
+
city: 'Seattle, WA',
|
|
733
|
+
status: 'Ready to ship',
|
|
734
|
+
tone: 'accent',
|
|
735
|
+
items: '14 cases, 3 products',
|
|
736
|
+
total: '$1,240.00',
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
id: 'SO-1183',
|
|
740
|
+
customer: 'Fabrikam Grocers',
|
|
741
|
+
city: 'Portland, OR',
|
|
742
|
+
status: 'Shipped',
|
|
743
|
+
tone: 'success',
|
|
744
|
+
items: '6 cases, 2 products',
|
|
745
|
+
total: '$386.50',
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
id: 'SO-1184',
|
|
749
|
+
customer: 'Tailspin Market',
|
|
750
|
+
city: 'Boise, ID',
|
|
751
|
+
status: 'On hold',
|
|
752
|
+
tone: 'warning',
|
|
753
|
+
items: '22 cases, 5 products',
|
|
754
|
+
total: '$2,075.25',
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
id: 'SO-1185',
|
|
758
|
+
customer: 'Adventure Works',
|
|
759
|
+
city: 'Denver, CO',
|
|
760
|
+
status: 'Ready to ship',
|
|
761
|
+
tone: 'accent',
|
|
762
|
+
items: '9 cases, 4 products',
|
|
763
|
+
total: '$918.00',
|
|
764
|
+
},
|
|
765
|
+
] as const;
|
|
766
|
+
|
|
767
|
+
type Order = (typeof ORDERS)[number];
|
|
768
|
+
|
|
769
|
+
@Component({
|
|
770
|
+
selector: 'app-drawer-detail-panel',
|
|
771
|
+
imports: [
|
|
772
|
+
SlBadge,
|
|
773
|
+
SlButton,
|
|
774
|
+
SlDescriptionList,
|
|
775
|
+
SlDescriptionListDescription,
|
|
776
|
+
SlDescriptionListItem,
|
|
777
|
+
SlDescriptionListTerm,
|
|
778
|
+
SlDrawer,
|
|
779
|
+
SlDrawerBody,
|
|
780
|
+
SlDrawerClose,
|
|
781
|
+
SlDrawerDescription,
|
|
782
|
+
SlDrawerHeader,
|
|
783
|
+
SlDrawerTitle,
|
|
784
|
+
SlInline,
|
|
785
|
+
SlStack,
|
|
786
|
+
SlTable,
|
|
787
|
+
SlTableBody,
|
|
788
|
+
SlTableCell,
|
|
789
|
+
SlTableColumnHeader,
|
|
790
|
+
SlTableContent,
|
|
791
|
+
SlTableHead,
|
|
792
|
+
SlTableRow,
|
|
793
|
+
SlTableRowHeader,
|
|
794
|
+
SlVisuallyHidden,
|
|
795
|
+
],
|
|
796
|
+
template: `
|
|
797
|
+
<div slTable [columns]="4">
|
|
798
|
+
<div slTableContent>
|
|
799
|
+
<thead slTableHead>
|
|
800
|
+
<tr slTableRow>
|
|
801
|
+
<th slTableColumnHeader>Order</th>
|
|
802
|
+
<th slTableColumnHeader>Customer</th>
|
|
803
|
+
<th slTableColumnHeader numeric>Total</th>
|
|
804
|
+
<th slTableColumnHeader><span slVisuallyHidden>Actions</span></th>
|
|
805
|
+
</tr>
|
|
806
|
+
</thead>
|
|
807
|
+
<tbody slTableBody>
|
|
808
|
+
@for (row of orders; track row.id) {
|
|
809
|
+
<tr slTableRow [value]="row.id">
|
|
810
|
+
<th slTableRowHeader>{{ row.id }}</th>
|
|
811
|
+
<td slTableCell>{{ row.customer }}</td>
|
|
812
|
+
<td slTableCell numeric>{{ row.total }}</td>
|
|
813
|
+
<td slTableCell>
|
|
814
|
+
<button
|
|
815
|
+
slButton
|
|
816
|
+
size="sm"
|
|
817
|
+
tone="secondary"
|
|
818
|
+
variant="ghost"
|
|
819
|
+
[attr.aria-label]="'View ' + row.id"
|
|
820
|
+
(click)="view(row)"
|
|
821
|
+
>
|
|
822
|
+
View
|
|
823
|
+
</button>
|
|
824
|
+
</td>
|
|
825
|
+
</tr>
|
|
826
|
+
}
|
|
827
|
+
</tbody>
|
|
828
|
+
</div>
|
|
829
|
+
</div>
|
|
830
|
+
<sl-drawer [modal]="false" outsidePress="none" [scrimFrom]="1" size="sm" [(open)]="open">
|
|
831
|
+
<header slDrawerHeader>
|
|
832
|
+
<h2 slDrawerTitle>Order {{ order().id }}</h2>
|
|
833
|
+
<p slDrawerDescription>{{ order().customer }}, {{ order().city }}</p>
|
|
834
|
+
<button slDrawerClose></button>
|
|
835
|
+
</header>
|
|
836
|
+
<div slDrawerBody>
|
|
837
|
+
<div slStack [gap]="4">
|
|
838
|
+
<div slInline>
|
|
839
|
+
<span slBadge [tone]="order().tone">{{ order().status }}</span>
|
|
840
|
+
</div>
|
|
841
|
+
<div slDescriptionList>
|
|
842
|
+
<div slDescriptionListItem>
|
|
843
|
+
<dt slDescriptionListTerm>Items</dt>
|
|
844
|
+
<dd slDescriptionListDescription>{{ order().items }}</dd>
|
|
845
|
+
</div>
|
|
846
|
+
<div slDescriptionListItem>
|
|
847
|
+
<dt slDescriptionListTerm>Total</dt>
|
|
848
|
+
<dd slDescriptionListDescription>{{ order().total }}</dd>
|
|
849
|
+
</div>
|
|
850
|
+
</div>
|
|
851
|
+
</div>
|
|
852
|
+
</div>
|
|
853
|
+
</sl-drawer>
|
|
854
|
+
`,
|
|
855
|
+
})
|
|
856
|
+
export class DrawerDetailPanel {
|
|
857
|
+
readonly orders = ORDERS;
|
|
858
|
+
readonly open = signal(false);
|
|
859
|
+
readonly order = signal<Order>(ORDERS[0]);
|
|
860
|
+
|
|
861
|
+
view(row: Order): void {
|
|
862
|
+
this.order.set(row);
|
|
863
|
+
this.open.set(true);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
### filters.ts
|
|
869
|
+
|
|
870
|
+
Example
|
|
871
|
+
|
|
872
|
+
```ts
|
|
873
|
+
import { Component, computed, signal } from '@angular/core';
|
|
874
|
+
import { SlButton } from '@slotted/angular/button';
|
|
875
|
+
import { SlCheckbox } from '@slotted/angular/checkbox';
|
|
876
|
+
import { SlCheckboxGroup } from '@slotted/angular/checkbox-group';
|
|
877
|
+
import {
|
|
878
|
+
SlDrawer,
|
|
879
|
+
SlDrawerBody,
|
|
880
|
+
SlDrawerClose,
|
|
881
|
+
SlDrawerFooter,
|
|
882
|
+
SlDrawerHeader,
|
|
883
|
+
SlDrawerTitle,
|
|
884
|
+
SlDrawerTrigger,
|
|
885
|
+
} from '@slotted/angular/drawer';
|
|
886
|
+
import { SlFieldGroup, SlFieldGroupLegend } from '@slotted/angular/field-group';
|
|
887
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
888
|
+
import { SlRadio, SlRadioGroup } from '@slotted/angular/radio-group';
|
|
889
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
890
|
+
import { SlText } from '@slotted/angular/typography';
|
|
891
|
+
|
|
892
|
+
const ORDERS = [
|
|
893
|
+
{ id: 'SO-1182', status: 'processing', warehouse: 'RNO' },
|
|
894
|
+
{ id: 'SO-1183', status: 'shipped', warehouse: 'CMH' },
|
|
895
|
+
{ id: 'SO-1184', status: 'on-hold', warehouse: 'RNO' },
|
|
896
|
+
{ id: 'SO-1185', status: 'processing', warehouse: 'SAV' },
|
|
897
|
+
{ id: 'SO-1186', status: 'shipped', warehouse: 'RNO' },
|
|
898
|
+
{ id: 'SO-1187', status: 'processing', warehouse: 'CMH' },
|
|
899
|
+
{ id: 'SO-1188', status: 'on-hold', warehouse: 'SAV' },
|
|
900
|
+
{ id: 'SO-1189', status: 'processing', warehouse: 'RNO' },
|
|
901
|
+
];
|
|
902
|
+
|
|
903
|
+
interface Filters {
|
|
904
|
+
statuses: readonly string[];
|
|
905
|
+
warehouse: string;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
const ALL: Filters = { statuses: ['processing', 'shipped', 'on-hold'], warehouse: 'any' };
|
|
909
|
+
|
|
910
|
+
const matching = (filters: Filters) =>
|
|
911
|
+
ORDERS.filter(
|
|
912
|
+
(order) =>
|
|
913
|
+
filters.statuses.includes(order.status) &&
|
|
914
|
+
(filters.warehouse === 'any' || order.warehouse === filters.warehouse),
|
|
915
|
+
).length;
|
|
916
|
+
|
|
917
|
+
@Component({
|
|
918
|
+
selector: 'app-drawer-filters',
|
|
919
|
+
imports: [
|
|
920
|
+
SlButton,
|
|
921
|
+
SlCheckbox,
|
|
922
|
+
SlCheckboxGroup,
|
|
923
|
+
SlDrawer,
|
|
924
|
+
SlDrawerBody,
|
|
925
|
+
SlDrawerClose,
|
|
926
|
+
SlDrawerFooter,
|
|
927
|
+
SlDrawerHeader,
|
|
928
|
+
SlDrawerTitle,
|
|
929
|
+
SlDrawerTrigger,
|
|
930
|
+
SlFieldGroup,
|
|
931
|
+
SlFieldGroupLegend,
|
|
932
|
+
SlInline,
|
|
933
|
+
SlRadio,
|
|
934
|
+
SlRadioGroup,
|
|
935
|
+
SlStack,
|
|
936
|
+
SlText,
|
|
937
|
+
],
|
|
938
|
+
template: `
|
|
939
|
+
<div slInline align="center" [gap]="3">
|
|
940
|
+
<span slText size="sm">{{ shown() }} of {{ total }} orders</span>
|
|
941
|
+
<button slButton size="sm" tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
942
|
+
Filters
|
|
943
|
+
</button>
|
|
944
|
+
<sl-drawer #drawer="slDrawer" size="sm" [open]="open()" (openChange)="toggle($event)">
|
|
945
|
+
<header slDrawerHeader>
|
|
946
|
+
<h2 slDrawerTitle>Filter orders</h2>
|
|
947
|
+
<button slDrawerClose></button>
|
|
948
|
+
</header>
|
|
949
|
+
<div slDrawerBody>
|
|
950
|
+
<div slStack [gap]="6">
|
|
951
|
+
<fieldset slFieldGroup>
|
|
952
|
+
<legend slFieldGroupLegend>Status</legend>
|
|
953
|
+
<div
|
|
954
|
+
slCheckboxGroup
|
|
955
|
+
[value]="draft().statuses"
|
|
956
|
+
(valueChange)="draft.set({ statuses: $event.value, warehouse: draft().warehouse })"
|
|
957
|
+
>
|
|
958
|
+
<div slCheckbox value="processing">Processing</div>
|
|
959
|
+
<div slCheckbox value="shipped">Shipped</div>
|
|
960
|
+
<div slCheckbox value="on-hold">On hold</div>
|
|
961
|
+
</div>
|
|
962
|
+
</fieldset>
|
|
963
|
+
<fieldset slFieldGroup>
|
|
964
|
+
<legend slFieldGroupLegend>Warehouse</legend>
|
|
965
|
+
<div
|
|
966
|
+
slRadioGroup
|
|
967
|
+
[value]="draft().warehouse"
|
|
968
|
+
(valueChange)="
|
|
969
|
+
draft.set({ statuses: draft().statuses, warehouse: $event.value ?? 'any' })
|
|
970
|
+
"
|
|
971
|
+
>
|
|
972
|
+
<div slRadio value="any">Any warehouse</div>
|
|
973
|
+
<div slRadio value="RNO">Reno, NV</div>
|
|
974
|
+
<div slRadio value="CMH">Columbus, OH</div>
|
|
975
|
+
<div slRadio value="SAV">Savannah, GA</div>
|
|
976
|
+
</div>
|
|
977
|
+
</fieldset>
|
|
978
|
+
</div>
|
|
979
|
+
</div>
|
|
980
|
+
<footer slDrawerFooter>
|
|
981
|
+
<button slButton variant="ghost" tone="secondary" (click)="draft.set(all)">Reset</button>
|
|
982
|
+
<button slButton (click)="apply()">Show {{ count() }} orders</button>
|
|
983
|
+
</footer>
|
|
984
|
+
</sl-drawer>
|
|
985
|
+
</div>
|
|
986
|
+
`,
|
|
987
|
+
})
|
|
988
|
+
export class DrawerFilters {
|
|
989
|
+
readonly all = ALL;
|
|
990
|
+
readonly total = ORDERS.length;
|
|
991
|
+
readonly open = signal(false);
|
|
992
|
+
readonly applied = signal<Filters>(ALL);
|
|
993
|
+
readonly draft = signal<Filters>(ALL);
|
|
994
|
+
readonly shown = computed(() => matching(this.applied()));
|
|
995
|
+
readonly count = computed(() => matching(this.draft()));
|
|
996
|
+
|
|
997
|
+
toggle(next: boolean): void {
|
|
998
|
+
if (next) this.draft.set(this.applied());
|
|
999
|
+
this.open.set(next);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
apply(): void {
|
|
1003
|
+
this.applied.set(this.draft());
|
|
1004
|
+
this.open.set(false);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
### form.ts
|
|
1010
|
+
|
|
1011
|
+
Example
|
|
1012
|
+
|
|
1013
|
+
```ts
|
|
1014
|
+
import { Component, computed, signal } from '@angular/core';
|
|
1015
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1016
|
+
import {
|
|
1017
|
+
SlDrawer,
|
|
1018
|
+
SlDrawerBody,
|
|
1019
|
+
SlDrawerClose,
|
|
1020
|
+
SlDrawerDescription,
|
|
1021
|
+
SlDrawerFooter,
|
|
1022
|
+
SlDrawerHeader,
|
|
1023
|
+
SlDrawerTitle,
|
|
1024
|
+
SlDrawerTrigger,
|
|
1025
|
+
} from '@slotted/angular/drawer';
|
|
1026
|
+
import { SlField, SlFieldError, SlFieldLabel } from '@slotted/angular/field';
|
|
1027
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
1028
|
+
import { SlSelect, SlSelectItem } from '@slotted/angular/select';
|
|
1029
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
1030
|
+
import { SlTextField, SlTextFieldInput } from '@slotted/angular/text-field';
|
|
1031
|
+
import { SlText } from '@slotted/angular/typography';
|
|
1032
|
+
|
|
1033
|
+
const TERMS = [
|
|
1034
|
+
{ value: 'due', label: 'Due on receipt' },
|
|
1035
|
+
{ value: 'net-15', label: 'Net 15' },
|
|
1036
|
+
{ value: 'net-30', label: 'Net 30' },
|
|
1037
|
+
{ value: 'net-60', label: 'Net 60' },
|
|
1038
|
+
];
|
|
1039
|
+
|
|
1040
|
+
const CUSTOMER = { name: 'Contoso Foods', email: 'ap@contoso.com', terms: 'net-30' };
|
|
1041
|
+
|
|
1042
|
+
const termsLabel = (value: string) => TERMS.find((option) => option.value === value)?.label;
|
|
1043
|
+
|
|
1044
|
+
function nameError(value: string): string {
|
|
1045
|
+
return value.trim() === '' ? 'Enter the name printed on invoices.' : '';
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
function emailError(value: string): string {
|
|
1049
|
+
if (value.trim() === '') return 'Enter the address invoices are sent to.';
|
|
1050
|
+
if (!/^\S+@\S+\.\S+$/.test(value)) return 'Enter an address like ap@contoso.com.';
|
|
1051
|
+
return '';
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
@Component({
|
|
1055
|
+
selector: 'app-drawer-form',
|
|
1056
|
+
imports: [
|
|
1057
|
+
SlButton,
|
|
1058
|
+
SlDrawer,
|
|
1059
|
+
SlDrawerBody,
|
|
1060
|
+
SlDrawerClose,
|
|
1061
|
+
SlDrawerDescription,
|
|
1062
|
+
SlDrawerFooter,
|
|
1063
|
+
SlDrawerHeader,
|
|
1064
|
+
SlDrawerTitle,
|
|
1065
|
+
SlDrawerTrigger,
|
|
1066
|
+
SlField,
|
|
1067
|
+
SlFieldError,
|
|
1068
|
+
SlFieldLabel,
|
|
1069
|
+
SlInline,
|
|
1070
|
+
SlSelect,
|
|
1071
|
+
SlSelectItem,
|
|
1072
|
+
SlStack,
|
|
1073
|
+
SlText,
|
|
1074
|
+
SlTextField,
|
|
1075
|
+
SlTextFieldInput,
|
|
1076
|
+
],
|
|
1077
|
+
template: `
|
|
1078
|
+
<div slInline align="center" [gap]="3">
|
|
1079
|
+
<span slText role="status" size="sm" tone="muted">
|
|
1080
|
+
{{ customer().name }}, {{ customer().email }}, {{ termsLabel(customer().terms) }}
|
|
1081
|
+
</span>
|
|
1082
|
+
<button slButton [slDrawerTrigger]="drawer">Edit customer</button>
|
|
1083
|
+
<sl-drawer #drawer="slDrawer" [open]="open()" (openChange)="toggle($event)">
|
|
1084
|
+
<header slDrawerHeader>
|
|
1085
|
+
<h2 slDrawerTitle>Edit customer</h2>
|
|
1086
|
+
<p slDrawerDescription>Account C-0042, customer since March 2021.</p>
|
|
1087
|
+
<button slDrawerClose></button>
|
|
1088
|
+
</header>
|
|
1089
|
+
<div slDrawerBody>
|
|
1090
|
+
<form id="edit-customer" novalidate (submit)="submit($event)">
|
|
1091
|
+
<div slStack [gap]="4">
|
|
1092
|
+
<div slField required [invalid]="errors()?.name ? true : undefined">
|
|
1093
|
+
<label slFieldLabel>Company name</label>
|
|
1094
|
+
<div slTextField>
|
|
1095
|
+
<input
|
|
1096
|
+
slTextFieldInput
|
|
1097
|
+
autocomplete="organization"
|
|
1098
|
+
[value]="name()"
|
|
1099
|
+
(valueChange)="name.set($event.value)"
|
|
1100
|
+
/>
|
|
1101
|
+
</div>
|
|
1102
|
+
<span slFieldError live="polite" reserve>{{ errors()?.name }}</span>
|
|
1103
|
+
</div>
|
|
1104
|
+
<div slField required [invalid]="errors()?.email ? true : undefined">
|
|
1105
|
+
<label slFieldLabel>Billing email</label>
|
|
1106
|
+
<div slTextField>
|
|
1107
|
+
<input
|
|
1108
|
+
slTextFieldInput
|
|
1109
|
+
type="email"
|
|
1110
|
+
[value]="email()"
|
|
1111
|
+
(valueChange)="email.set($event.value)"
|
|
1112
|
+
/>
|
|
1113
|
+
</div>
|
|
1114
|
+
<span slFieldError live="polite" reserve>{{ errors()?.email }}</span>
|
|
1115
|
+
</div>
|
|
1116
|
+
<div slField>
|
|
1117
|
+
<label slFieldLabel>Payment terms</label>
|
|
1118
|
+
<sl-select [items]="terms" [(value)]="term">
|
|
1119
|
+
@for (option of terms; track option.value) {
|
|
1120
|
+
<sl-select-item [value]="option.value">{{ option.label }}</sl-select-item>
|
|
1121
|
+
}
|
|
1122
|
+
</sl-select>
|
|
1123
|
+
</div>
|
|
1124
|
+
</div>
|
|
1125
|
+
</form>
|
|
1126
|
+
</div>
|
|
1127
|
+
<footer slDrawerFooter>
|
|
1128
|
+
<button slButton variant="ghost" tone="secondary" (click)="open.set(false)">
|
|
1129
|
+
Cancel
|
|
1130
|
+
</button>
|
|
1131
|
+
<button slButton type="submit" form="edit-customer">Save customer</button>
|
|
1132
|
+
</footer>
|
|
1133
|
+
</sl-drawer>
|
|
1134
|
+
</div>
|
|
1135
|
+
`,
|
|
1136
|
+
})
|
|
1137
|
+
export class DrawerForm {
|
|
1138
|
+
readonly terms = TERMS;
|
|
1139
|
+
readonly termsLabel = termsLabel;
|
|
1140
|
+
readonly open = signal(false);
|
|
1141
|
+
readonly customer = signal(CUSTOMER);
|
|
1142
|
+
readonly name = signal(CUSTOMER.name);
|
|
1143
|
+
readonly email = signal(CUSTOMER.email);
|
|
1144
|
+
readonly term = signal<string | null>(CUSTOMER.terms);
|
|
1145
|
+
readonly submitted = signal(false);
|
|
1146
|
+
readonly errors = computed(() =>
|
|
1147
|
+
this.submitted() ? { name: nameError(this.name()), email: emailError(this.email()) } : null,
|
|
1148
|
+
);
|
|
1149
|
+
|
|
1150
|
+
toggle(next: boolean): void {
|
|
1151
|
+
if (next) {
|
|
1152
|
+
this.name.set(this.customer().name);
|
|
1153
|
+
this.email.set(this.customer().email);
|
|
1154
|
+
this.term.set(this.customer().terms);
|
|
1155
|
+
this.submitted.set(false);
|
|
1156
|
+
}
|
|
1157
|
+
this.open.set(next);
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
submit(event: Event): void {
|
|
1161
|
+
event.preventDefault();
|
|
1162
|
+
this.submitted.set(true);
|
|
1163
|
+
if (nameError(this.name()) !== '' || emailError(this.email()) !== '') return;
|
|
1164
|
+
this.customer.set({
|
|
1165
|
+
name: this.name().trim(),
|
|
1166
|
+
email: this.email().trim(),
|
|
1167
|
+
terms: this.term() ?? this.customer().terms,
|
|
1168
|
+
});
|
|
1169
|
+
this.open.set(false);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
```
|
|
1173
|
+
|
|
1174
|
+
### inline.ts
|
|
1175
|
+
|
|
1176
|
+
Example
|
|
1177
|
+
|
|
1178
|
+
```ts
|
|
1179
|
+
import { Component, computed, signal } from '@angular/core';
|
|
1180
|
+
import { SlBadge } from '@slotted/angular/badge';
|
|
1181
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1182
|
+
import { SlCheckbox } from '@slotted/angular/checkbox';
|
|
1183
|
+
import { SlCheckboxGroup } from '@slotted/angular/checkbox-group';
|
|
1184
|
+
import { SlDrawer, SlDrawerBody, SlDrawerTrigger } from '@slotted/angular/drawer';
|
|
1185
|
+
import { SlFieldGroup, SlFieldGroupLegend } from '@slotted/angular/field-group';
|
|
1186
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
1187
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
1188
|
+
import { SlText } from '@slotted/angular/typography';
|
|
1189
|
+
|
|
1190
|
+
const STATUSES = [
|
|
1191
|
+
{ value: 'processing', label: 'Processing', tone: 'accent' },
|
|
1192
|
+
{ value: 'shipped', label: 'Shipped', tone: 'success' },
|
|
1193
|
+
{ value: 'on-hold', label: 'On hold', tone: 'warning' },
|
|
1194
|
+
] as const;
|
|
1195
|
+
|
|
1196
|
+
const ORDERS = [
|
|
1197
|
+
{ id: 'SO-1182', customer: 'Contoso Foods', status: 'processing' },
|
|
1198
|
+
{ id: 'SO-1183', customer: 'Fabrikam Grocers', status: 'shipped' },
|
|
1199
|
+
{ id: 'SO-1184', customer: 'Tailspin Market', status: 'on-hold' },
|
|
1200
|
+
{ id: 'SO-1185', customer: 'Adventure Works', status: 'processing' },
|
|
1201
|
+
{ id: 'SO-1186', customer: 'Litware Deli', status: 'shipped' },
|
|
1202
|
+
] as const;
|
|
1203
|
+
|
|
1204
|
+
@Component({
|
|
1205
|
+
selector: 'app-drawer-inline',
|
|
1206
|
+
imports: [
|
|
1207
|
+
SlBadge,
|
|
1208
|
+
SlButton,
|
|
1209
|
+
SlCheckbox,
|
|
1210
|
+
SlCheckboxGroup,
|
|
1211
|
+
SlDrawer,
|
|
1212
|
+
SlDrawerBody,
|
|
1213
|
+
SlDrawerTrigger,
|
|
1214
|
+
SlFieldGroup,
|
|
1215
|
+
SlFieldGroupLegend,
|
|
1216
|
+
SlInline,
|
|
1217
|
+
SlStack,
|
|
1218
|
+
SlText,
|
|
1219
|
+
],
|
|
1220
|
+
template: `
|
|
1221
|
+
<div slStack [gap]="3">
|
|
1222
|
+
<div slInline>
|
|
1223
|
+
<button slButton size="sm" tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
1224
|
+
Filters
|
|
1225
|
+
</button>
|
|
1226
|
+
</div>
|
|
1227
|
+
<div
|
|
1228
|
+
style="
|
|
1229
|
+
display: flex;
|
|
1230
|
+
flex-wrap: wrap;
|
|
1231
|
+
min-block-size: 16rem;
|
|
1232
|
+
border: 1px solid var(--slotted-border-subtle);
|
|
1233
|
+
border-radius: var(--slotted-radius-lg);
|
|
1234
|
+
overflow: hidden;
|
|
1235
|
+
"
|
|
1236
|
+
>
|
|
1237
|
+
<sl-drawer #drawer="slDrawer" mode="inline" side="start" size="sm" [(open)]="open">
|
|
1238
|
+
<div slDrawerBody>
|
|
1239
|
+
<fieldset slFieldGroup>
|
|
1240
|
+
<legend slFieldGroupLegend>Status</legend>
|
|
1241
|
+
<div slCheckboxGroup [value]="statuses()" (valueChange)="statuses.set($event.value)">
|
|
1242
|
+
@for (status of options; track status.value) {
|
|
1243
|
+
<div slCheckbox [value]="status.value">{{ status.label }}</div>
|
|
1244
|
+
}
|
|
1245
|
+
</div>
|
|
1246
|
+
</fieldset>
|
|
1247
|
+
</div>
|
|
1248
|
+
</sl-drawer>
|
|
1249
|
+
<div slStack [gap]="3" style="flex: 1 1 12rem; padding: var(--slotted-space-6)">
|
|
1250
|
+
<span slText size="sm" tone="muted">{{ shown().length }} of {{ total }} orders</span>
|
|
1251
|
+
@for (order of shown(); track order.id) {
|
|
1252
|
+
<div slInline align="center" [gap]="3" justify="between">
|
|
1253
|
+
<div slStack [gap]="0">
|
|
1254
|
+
<span slText size="sm" weight="semibold">{{ order.id }}</span>
|
|
1255
|
+
<span slText size="sm" tone="muted">{{ order.customer }}</span>
|
|
1256
|
+
</div>
|
|
1257
|
+
<span slBadge [tone]="statusOf(order.status).tone">
|
|
1258
|
+
{{ statusOf(order.status).label }}
|
|
1259
|
+
</span>
|
|
1260
|
+
</div>
|
|
1261
|
+
}
|
|
1262
|
+
</div>
|
|
1263
|
+
</div>
|
|
1264
|
+
</div>
|
|
1265
|
+
`,
|
|
1266
|
+
})
|
|
1267
|
+
export class DrawerInline {
|
|
1268
|
+
readonly options = STATUSES;
|
|
1269
|
+
readonly total = ORDERS.length;
|
|
1270
|
+
readonly open = signal(true);
|
|
1271
|
+
readonly statuses = signal<readonly string[]>(['processing', 'on-hold']);
|
|
1272
|
+
readonly shown = computed(() => ORDERS.filter((order) => this.statuses().includes(order.status)));
|
|
1273
|
+
|
|
1274
|
+
statusOf(value: string) {
|
|
1275
|
+
return STATUSES.find((item) => item.value === value)!;
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
### long-content.ts
|
|
1281
|
+
|
|
1282
|
+
Example
|
|
1283
|
+
|
|
1284
|
+
```ts
|
|
1285
|
+
import { Component, signal } from '@angular/core';
|
|
1286
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1287
|
+
import {
|
|
1288
|
+
SlDrawer,
|
|
1289
|
+
SlDrawerBody,
|
|
1290
|
+
SlDrawerClose,
|
|
1291
|
+
SlDrawerDescription,
|
|
1292
|
+
SlDrawerFooter,
|
|
1293
|
+
SlDrawerHeader,
|
|
1294
|
+
SlDrawerTitle,
|
|
1295
|
+
SlDrawerTrigger,
|
|
1296
|
+
} from '@slotted/angular/drawer';
|
|
1297
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
1298
|
+
import { SlText } from '@slotted/angular/typography';
|
|
1299
|
+
|
|
1300
|
+
const EVENTS = [
|
|
1301
|
+
{ at: 'Oct 6, 7:42 AM', what: 'Out for delivery, Seattle, WA' },
|
|
1302
|
+
{ at: 'Oct 6, 5:10 AM', what: 'Arrived at the delivery facility, Seattle, WA' },
|
|
1303
|
+
{ at: 'Oct 5, 11:58 PM', what: 'Departed facility, Portland, OR' },
|
|
1304
|
+
{ at: 'Oct 5, 9:20 PM', what: 'Arrived at facility, Portland, OR' },
|
|
1305
|
+
{ at: 'Oct 5, 2:04 PM', what: 'Departed facility, Medford, OR' },
|
|
1306
|
+
{ at: 'Oct 5, 10:37 AM', what: 'Arrived at facility, Medford, OR' },
|
|
1307
|
+
{ at: 'Oct 4, 11:15 PM', what: 'Departed facility, Sacramento, CA' },
|
|
1308
|
+
{ at: 'Oct 4, 6:48 PM', what: 'Arrived at facility, Sacramento, CA' },
|
|
1309
|
+
{ at: 'Oct 4, 1:30 PM', what: 'Departed facility, Reno, NV' },
|
|
1310
|
+
{ at: 'Oct 4, 9:02 AM', what: 'Processed at the origin facility, Reno, NV' },
|
|
1311
|
+
{ at: 'Oct 3, 6:15 PM', what: 'Picked up from the Northwind warehouse, Reno, NV' },
|
|
1312
|
+
{ at: 'Oct 3, 4:40 PM', what: 'Weighed and labelled: 3 packages, 18.4 kg' },
|
|
1313
|
+
{ at: 'Oct 3, 2:12 PM', what: 'Packed at station 4, Reno, NV' },
|
|
1314
|
+
{ at: 'Oct 3, 11:05 AM', what: 'Picked from aisles 12, 14 and 21' },
|
|
1315
|
+
{ at: 'Oct 2, 4:55 PM', what: 'Released to the warehouse' },
|
|
1316
|
+
{ at: 'Oct 2, 4:31 PM', what: 'Payment captured, card ending 4242' },
|
|
1317
|
+
];
|
|
1318
|
+
|
|
1319
|
+
@Component({
|
|
1320
|
+
selector: 'app-drawer-long-content',
|
|
1321
|
+
imports: [
|
|
1322
|
+
SlButton,
|
|
1323
|
+
SlDrawer,
|
|
1324
|
+
SlDrawerBody,
|
|
1325
|
+
SlDrawerClose,
|
|
1326
|
+
SlDrawerDescription,
|
|
1327
|
+
SlDrawerFooter,
|
|
1328
|
+
SlDrawerHeader,
|
|
1329
|
+
SlDrawerTitle,
|
|
1330
|
+
SlDrawerTrigger,
|
|
1331
|
+
SlStack,
|
|
1332
|
+
SlText,
|
|
1333
|
+
],
|
|
1334
|
+
template: `
|
|
1335
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
1336
|
+
Tracking history
|
|
1337
|
+
</button>
|
|
1338
|
+
<sl-drawer #drawer="slDrawer" [(open)]="open">
|
|
1339
|
+
<header slDrawerHeader>
|
|
1340
|
+
<h2 slDrawerTitle>Tracking 1Z999AA10123456784</h2>
|
|
1341
|
+
<p slDrawerDescription>Shipment SH-4471, 16 events since 2 October.</p>
|
|
1342
|
+
<button slDrawerClose></button>
|
|
1343
|
+
</header>
|
|
1344
|
+
<div slDrawerBody>
|
|
1345
|
+
<div slStack [gap]="4">
|
|
1346
|
+
@for (event of events; track event.at) {
|
|
1347
|
+
<div slStack [gap]="0">
|
|
1348
|
+
<span slText size="sm" tone="muted">{{ event.at }}</span>
|
|
1349
|
+
<span slText size="sm">{{ event.what }}</span>
|
|
1350
|
+
</div>
|
|
1351
|
+
}
|
|
1352
|
+
</div>
|
|
1353
|
+
</div>
|
|
1354
|
+
<footer slDrawerFooter>
|
|
1355
|
+
<button slButton variant="ghost" tone="secondary" (click)="open.set(false)">Close</button>
|
|
1356
|
+
<button slButton>Email to customer</button>
|
|
1357
|
+
</footer>
|
|
1358
|
+
</sl-drawer>
|
|
1359
|
+
`,
|
|
1360
|
+
})
|
|
1361
|
+
export class DrawerLongContent {
|
|
1362
|
+
readonly events = EVENTS;
|
|
1363
|
+
readonly open = signal(false);
|
|
1364
|
+
}
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
### non-modal.ts
|
|
1368
|
+
|
|
1369
|
+
Example
|
|
1370
|
+
|
|
1371
|
+
```ts
|
|
1372
|
+
import { Component } from '@angular/core';
|
|
1373
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1374
|
+
import {
|
|
1375
|
+
SlDescriptionList,
|
|
1376
|
+
SlDescriptionListDescription,
|
|
1377
|
+
SlDescriptionListItem,
|
|
1378
|
+
SlDescriptionListTerm,
|
|
1379
|
+
} from '@slotted/angular/description-list';
|
|
1380
|
+
import {
|
|
1381
|
+
SlDrawer,
|
|
1382
|
+
SlDrawerBody,
|
|
1383
|
+
SlDrawerClose,
|
|
1384
|
+
SlDrawerDescription,
|
|
1385
|
+
SlDrawerHeader,
|
|
1386
|
+
SlDrawerTitle,
|
|
1387
|
+
SlDrawerTrigger,
|
|
1388
|
+
} from '@slotted/angular/drawer';
|
|
1389
|
+
import { SlField, SlFieldDescription, SlFieldLabel } from '@slotted/angular/field';
|
|
1390
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
1391
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
1392
|
+
import { SlTextField, SlTextFieldInput } from '@slotted/angular/text-field';
|
|
1393
|
+
|
|
1394
|
+
const RATES = [
|
|
1395
|
+
{ term: 'UPS Ground', value: '$38.40, 3 business days' },
|
|
1396
|
+
{ term: 'FedEx Home Delivery', value: '$41.15, 3 business days' },
|
|
1397
|
+
{ term: 'UPS 2nd Day Air', value: '$96.80, 2 business days' },
|
|
1398
|
+
{ term: 'FedEx Priority Overnight', value: '$184.25, next business day' },
|
|
1399
|
+
];
|
|
1400
|
+
|
|
1401
|
+
@Component({
|
|
1402
|
+
selector: 'app-drawer-non-modal',
|
|
1403
|
+
imports: [
|
|
1404
|
+
SlButton,
|
|
1405
|
+
SlDescriptionList,
|
|
1406
|
+
SlDescriptionListDescription,
|
|
1407
|
+
SlDescriptionListItem,
|
|
1408
|
+
SlDescriptionListTerm,
|
|
1409
|
+
SlDrawer,
|
|
1410
|
+
SlDrawerBody,
|
|
1411
|
+
SlDrawerClose,
|
|
1412
|
+
SlDrawerDescription,
|
|
1413
|
+
SlDrawerHeader,
|
|
1414
|
+
SlDrawerTitle,
|
|
1415
|
+
SlDrawerTrigger,
|
|
1416
|
+
SlField,
|
|
1417
|
+
SlFieldDescription,
|
|
1418
|
+
SlFieldLabel,
|
|
1419
|
+
SlInline,
|
|
1420
|
+
SlStack,
|
|
1421
|
+
SlTextField,
|
|
1422
|
+
SlTextFieldInput,
|
|
1423
|
+
],
|
|
1424
|
+
template: `
|
|
1425
|
+
<div slStack [gap]="4">
|
|
1426
|
+
<div slField>
|
|
1427
|
+
<label slFieldLabel>Shipping charge</label>
|
|
1428
|
+
<div slTextField>
|
|
1429
|
+
<input slTextFieldInput inputmode="decimal" placeholder="0.00" />
|
|
1430
|
+
</div>
|
|
1431
|
+
<span slFieldDescription>Charged to Contoso Foods on invoice INV-2041.</span>
|
|
1432
|
+
</div>
|
|
1433
|
+
<div slInline>
|
|
1434
|
+
<button slButton size="sm" tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
1435
|
+
Show carrier rates
|
|
1436
|
+
</button>
|
|
1437
|
+
</div>
|
|
1438
|
+
<sl-drawer #drawer="slDrawer" [modal]="false" outsidePress="none" [scrimFrom]="1" size="sm">
|
|
1439
|
+
<header slDrawerHeader>
|
|
1440
|
+
<h2 slDrawerTitle>Carrier rates</h2>
|
|
1441
|
+
<p slDrawerDescription>3 packages, 18.4 kg, Reno to Seattle.</p>
|
|
1442
|
+
<button slDrawerClose></button>
|
|
1443
|
+
</header>
|
|
1444
|
+
<div slDrawerBody>
|
|
1445
|
+
<div slDescriptionList>
|
|
1446
|
+
@for (rate of rates; track rate.term) {
|
|
1447
|
+
<div slDescriptionListItem>
|
|
1448
|
+
<dt slDescriptionListTerm>{{ rate.term }}</dt>
|
|
1449
|
+
<dd slDescriptionListDescription>{{ rate.value }}</dd>
|
|
1450
|
+
</div>
|
|
1451
|
+
}
|
|
1452
|
+
</div>
|
|
1453
|
+
</div>
|
|
1454
|
+
</sl-drawer>
|
|
1455
|
+
</div>
|
|
1456
|
+
`,
|
|
1457
|
+
})
|
|
1458
|
+
export class DrawerNonModal {
|
|
1459
|
+
readonly rates = RATES;
|
|
1460
|
+
}
|
|
1461
|
+
```
|
|
1462
|
+
|
|
1463
|
+
### pin.ts
|
|
1464
|
+
|
|
1465
|
+
Example
|
|
1466
|
+
|
|
1467
|
+
```ts
|
|
1468
|
+
import { Component, signal } from '@angular/core';
|
|
1469
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1470
|
+
import {
|
|
1471
|
+
SlDescriptionList,
|
|
1472
|
+
SlDescriptionListDescription,
|
|
1473
|
+
SlDescriptionListItem,
|
|
1474
|
+
SlDescriptionListTerm,
|
|
1475
|
+
} from '@slotted/angular/description-list';
|
|
1476
|
+
import {
|
|
1477
|
+
SlDrawer,
|
|
1478
|
+
SlDrawerBody,
|
|
1479
|
+
SlDrawerClose,
|
|
1480
|
+
SlDrawerFooter,
|
|
1481
|
+
SlDrawerHeader,
|
|
1482
|
+
SlDrawerTitle,
|
|
1483
|
+
SlDrawerTrigger,
|
|
1484
|
+
} from '@slotted/angular/drawer';
|
|
1485
|
+
import { SlField, SlFieldLabel } from '@slotted/angular/field';
|
|
1486
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
1487
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
1488
|
+
import { SlTextarea } from '@slotted/angular/textarea';
|
|
1489
|
+
|
|
1490
|
+
const DETAILS = [
|
|
1491
|
+
{ term: 'Customer', value: 'Contoso Foods, Seattle' },
|
|
1492
|
+
{ term: 'Items', value: '14 cases, 3 products' },
|
|
1493
|
+
{ term: 'Warehouse', value: 'Reno, NV' },
|
|
1494
|
+
];
|
|
1495
|
+
|
|
1496
|
+
@Component({
|
|
1497
|
+
selector: 'app-drawer-pin',
|
|
1498
|
+
imports: [
|
|
1499
|
+
SlButton,
|
|
1500
|
+
SlDescriptionList,
|
|
1501
|
+
SlDescriptionListDescription,
|
|
1502
|
+
SlDescriptionListItem,
|
|
1503
|
+
SlDescriptionListTerm,
|
|
1504
|
+
SlDrawer,
|
|
1505
|
+
SlDrawerBody,
|
|
1506
|
+
SlDrawerClose,
|
|
1507
|
+
SlDrawerFooter,
|
|
1508
|
+
SlDrawerHeader,
|
|
1509
|
+
SlDrawerTitle,
|
|
1510
|
+
SlDrawerTrigger,
|
|
1511
|
+
SlField,
|
|
1512
|
+
SlFieldLabel,
|
|
1513
|
+
SlInline,
|
|
1514
|
+
SlStack,
|
|
1515
|
+
SlTextarea,
|
|
1516
|
+
],
|
|
1517
|
+
template: `
|
|
1518
|
+
<div slStack [gap]="3">
|
|
1519
|
+
<div slInline>
|
|
1520
|
+
<button slButton size="sm" tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
1521
|
+
Notes
|
|
1522
|
+
</button>
|
|
1523
|
+
</div>
|
|
1524
|
+
<div
|
|
1525
|
+
style="
|
|
1526
|
+
display: flex;
|
|
1527
|
+
flex-wrap: wrap;
|
|
1528
|
+
min-block-size: 18rem;
|
|
1529
|
+
border: 1px solid var(--slotted-border-subtle);
|
|
1530
|
+
border-radius: var(--slotted-radius-lg);
|
|
1531
|
+
overflow: hidden;
|
|
1532
|
+
"
|
|
1533
|
+
>
|
|
1534
|
+
<div style="flex: 1 1 12rem; padding: var(--slotted-space-6)">
|
|
1535
|
+
<div slDescriptionList>
|
|
1536
|
+
@for (detail of details; track detail.term) {
|
|
1537
|
+
<div slDescriptionListItem>
|
|
1538
|
+
<dt slDescriptionListTerm>{{ detail.term }}</dt>
|
|
1539
|
+
<dd slDescriptionListDescription>{{ detail.value }}</dd>
|
|
1540
|
+
</div>
|
|
1541
|
+
}
|
|
1542
|
+
</div>
|
|
1543
|
+
</div>
|
|
1544
|
+
<sl-drawer
|
|
1545
|
+
#drawer="slDrawer"
|
|
1546
|
+
size="sm"
|
|
1547
|
+
[mode]="pinned() ? 'inline' : 'overlay'"
|
|
1548
|
+
[(open)]="open"
|
|
1549
|
+
>
|
|
1550
|
+
<header slDrawerHeader>
|
|
1551
|
+
<h2 slDrawerTitle>Notes on SO-1182</h2>
|
|
1552
|
+
<button slDrawerClose></button>
|
|
1553
|
+
</header>
|
|
1554
|
+
<div slDrawerBody>
|
|
1555
|
+
<div slField>
|
|
1556
|
+
<label slFieldLabel>Note for the warehouse</label>
|
|
1557
|
+
<textarea
|
|
1558
|
+
slTextarea
|
|
1559
|
+
placeholder="Pallet height, dock number, contact on site"
|
|
1560
|
+
></textarea>
|
|
1561
|
+
</div>
|
|
1562
|
+
</div>
|
|
1563
|
+
<footer slDrawerFooter>
|
|
1564
|
+
<button
|
|
1565
|
+
slButton
|
|
1566
|
+
size="sm"
|
|
1567
|
+
tone="secondary"
|
|
1568
|
+
variant="outline"
|
|
1569
|
+
(click)="pinned.set(!pinned())"
|
|
1570
|
+
>
|
|
1571
|
+
{{ pinned() ? 'Unpin' : 'Pin beside the order' }}
|
|
1572
|
+
</button>
|
|
1573
|
+
</footer>
|
|
1574
|
+
</sl-drawer>
|
|
1575
|
+
</div>
|
|
1576
|
+
</div>
|
|
1577
|
+
`,
|
|
1578
|
+
})
|
|
1579
|
+
export class DrawerPin {
|
|
1580
|
+
readonly details = DETAILS;
|
|
1581
|
+
readonly open = signal(false);
|
|
1582
|
+
readonly pinned = signal(false);
|
|
1583
|
+
}
|
|
1584
|
+
```
|
|
1585
|
+
|
|
1586
|
+
### sides.ts
|
|
1587
|
+
|
|
1588
|
+
Example
|
|
1589
|
+
|
|
1590
|
+
```ts
|
|
1591
|
+
import { Component } from '@angular/core';
|
|
1592
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1593
|
+
import {
|
|
1594
|
+
SlDrawer,
|
|
1595
|
+
SlDrawerBody,
|
|
1596
|
+
SlDrawerClose,
|
|
1597
|
+
SlDrawerHeader,
|
|
1598
|
+
SlDrawerTitle,
|
|
1599
|
+
SlDrawerTrigger,
|
|
1600
|
+
} from '@slotted/angular/drawer';
|
|
1601
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
1602
|
+
import { SlText } from '@slotted/angular/typography';
|
|
1603
|
+
|
|
1604
|
+
const SIDES = [
|
|
1605
|
+
{
|
|
1606
|
+
side: 'start',
|
|
1607
|
+
label: 'Start',
|
|
1608
|
+
title: 'Warehouses',
|
|
1609
|
+
body: 'Reno, Columbus and Savannah. A panel from the start edge suits navigation between sites.',
|
|
1610
|
+
},
|
|
1611
|
+
{
|
|
1612
|
+
side: 'end',
|
|
1613
|
+
label: 'End',
|
|
1614
|
+
title: 'Order SO-1182',
|
|
1615
|
+
body: 'Contoso Foods, 14 cases. The end edge is the default and suits the details of a row.',
|
|
1616
|
+
},
|
|
1617
|
+
{
|
|
1618
|
+
side: 'top',
|
|
1619
|
+
label: 'Top',
|
|
1620
|
+
title: 'Carrier notice',
|
|
1621
|
+
body: 'UPS pickups from Reno run two hours late today. A panel from the top suits a notice that belongs to the whole screen.',
|
|
1622
|
+
},
|
|
1623
|
+
{
|
|
1624
|
+
side: 'bottom',
|
|
1625
|
+
label: 'Bottom',
|
|
1626
|
+
title: '3 orders selected',
|
|
1627
|
+
body: 'SO-1182, SO-1183 and SO-1184. A sheet from the bottom suits actions on a phone, within reach of the thumb.',
|
|
1628
|
+
},
|
|
1629
|
+
] as const;
|
|
1630
|
+
|
|
1631
|
+
@Component({
|
|
1632
|
+
selector: 'app-drawer-sides',
|
|
1633
|
+
imports: [
|
|
1634
|
+
SlButton,
|
|
1635
|
+
SlDrawer,
|
|
1636
|
+
SlDrawerBody,
|
|
1637
|
+
SlDrawerClose,
|
|
1638
|
+
SlDrawerHeader,
|
|
1639
|
+
SlDrawerTitle,
|
|
1640
|
+
SlDrawerTrigger,
|
|
1641
|
+
SlInline,
|
|
1642
|
+
SlText,
|
|
1643
|
+
],
|
|
1644
|
+
template: `
|
|
1645
|
+
<div slInline [gap]="2">
|
|
1646
|
+
@for (item of sides; track item.side) {
|
|
1647
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
1648
|
+
{{ item.label }}
|
|
1649
|
+
</button>
|
|
1650
|
+
<sl-drawer #drawer="slDrawer" [side]="item.side">
|
|
1651
|
+
<header slDrawerHeader>
|
|
1652
|
+
<h2 slDrawerTitle>{{ item.title }}</h2>
|
|
1653
|
+
<button slDrawerClose></button>
|
|
1654
|
+
</header>
|
|
1655
|
+
<div slDrawerBody>
|
|
1656
|
+
<span slText size="sm">{{ item.body }}</span>
|
|
1657
|
+
</div>
|
|
1658
|
+
</sl-drawer>
|
|
1659
|
+
}
|
|
1660
|
+
</div>
|
|
1661
|
+
`,
|
|
1662
|
+
})
|
|
1663
|
+
export class DrawerSides {
|
|
1664
|
+
readonly sides = SIDES;
|
|
1665
|
+
}
|
|
1666
|
+
```
|
|
1667
|
+
|
|
1668
|
+
### sizes.ts
|
|
1669
|
+
|
|
1670
|
+
Example
|
|
1671
|
+
|
|
1672
|
+
```ts
|
|
1673
|
+
import { Component } from '@angular/core';
|
|
1674
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1675
|
+
import {
|
|
1676
|
+
SlDrawer,
|
|
1677
|
+
SlDrawerBody,
|
|
1678
|
+
SlDrawerClose,
|
|
1679
|
+
SlDrawerHeader,
|
|
1680
|
+
SlDrawerTitle,
|
|
1681
|
+
SlDrawerTrigger,
|
|
1682
|
+
} from '@slotted/angular/drawer';
|
|
1683
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
1684
|
+
import { SlText } from '@slotted/angular/typography';
|
|
1685
|
+
|
|
1686
|
+
const SIZES = [
|
|
1687
|
+
{ size: 'sm', body: '18rem. One field or a short list, such as the carrier for a shipment.' },
|
|
1688
|
+
{ size: 'md', body: '24rem, the default. The details of an order or a short form.' },
|
|
1689
|
+
{ size: 'lg', body: '30rem. A record with a table of lines, such as the items of an order.' },
|
|
1690
|
+
{ size: 'xl', body: '40rem. Two columns, such as a customer and their open orders.' },
|
|
1691
|
+
{ size: 'full', body: 'The whole screen. A task that needs every column, such as a pick list.' },
|
|
1692
|
+
] as const;
|
|
1693
|
+
|
|
1694
|
+
@Component({
|
|
1695
|
+
selector: 'app-drawer-sizes',
|
|
1696
|
+
imports: [
|
|
1697
|
+
SlButton,
|
|
1698
|
+
SlDrawer,
|
|
1699
|
+
SlDrawerBody,
|
|
1700
|
+
SlDrawerClose,
|
|
1701
|
+
SlDrawerHeader,
|
|
1702
|
+
SlDrawerTitle,
|
|
1703
|
+
SlDrawerTrigger,
|
|
1704
|
+
SlInline,
|
|
1705
|
+
SlText,
|
|
1706
|
+
],
|
|
1707
|
+
template: `
|
|
1708
|
+
<div slInline [gap]="2">
|
|
1709
|
+
@for (item of sizes; track item.size) {
|
|
1710
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
1711
|
+
{{ item.size }}
|
|
1712
|
+
</button>
|
|
1713
|
+
<sl-drawer #drawer="slDrawer" [size]="item.size">
|
|
1714
|
+
<header slDrawerHeader>
|
|
1715
|
+
<h2 slDrawerTitle>Shipment SH-4471</h2>
|
|
1716
|
+
<button slDrawerClose></button>
|
|
1717
|
+
</header>
|
|
1718
|
+
<div slDrawerBody>
|
|
1719
|
+
<span slText size="sm">{{ item.body }}</span>
|
|
1720
|
+
</div>
|
|
1721
|
+
</sl-drawer>
|
|
1722
|
+
}
|
|
1723
|
+
</div>
|
|
1724
|
+
`,
|
|
1725
|
+
})
|
|
1726
|
+
export class DrawerSizes {
|
|
1727
|
+
readonly sizes = SIZES;
|
|
1728
|
+
}
|
|
1729
|
+
```
|
|
1730
|
+
|
|
1731
|
+
### snap-points.ts
|
|
1732
|
+
|
|
1733
|
+
Example
|
|
1734
|
+
|
|
1735
|
+
```ts
|
|
1736
|
+
import { Component, signal } from '@angular/core';
|
|
1737
|
+
import { SlBadge } from '@slotted/angular/badge';
|
|
1738
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1739
|
+
import {
|
|
1740
|
+
SlDrawer,
|
|
1741
|
+
SlDrawerBody,
|
|
1742
|
+
SlDrawerClose,
|
|
1743
|
+
SlDrawerDescription,
|
|
1744
|
+
SlDrawerHeader,
|
|
1745
|
+
SlDrawerResizer,
|
|
1746
|
+
SlDrawerTitle,
|
|
1747
|
+
SlDrawerTrigger,
|
|
1748
|
+
} from '@slotted/angular/drawer';
|
|
1749
|
+
import { SlInline } from '@slotted/angular/inline';
|
|
1750
|
+
import { SlStack } from '@slotted/angular/stack';
|
|
1751
|
+
import { SlText } from '@slotted/angular/typography';
|
|
1752
|
+
|
|
1753
|
+
const SHIPMENTS = [
|
|
1754
|
+
{ id: 'SH-4471', to: 'Contoso Foods, Seattle', status: 'In transit', tone: 'accent' },
|
|
1755
|
+
{ id: 'SH-4472', to: 'Fabrikam Grocers, Portland', status: 'In transit', tone: 'accent' },
|
|
1756
|
+
{ id: 'SH-4473', to: 'Tailspin Market, Boise', status: 'Delayed', tone: 'warning' },
|
|
1757
|
+
{ id: 'SH-4474', to: 'Adventure Works, Denver', status: 'In transit', tone: 'accent' },
|
|
1758
|
+
{
|
|
1759
|
+
id: 'SH-4475',
|
|
1760
|
+
to: 'Litware Deli, Salt Lake City',
|
|
1761
|
+
status: 'Out for delivery',
|
|
1762
|
+
tone: 'success',
|
|
1763
|
+
},
|
|
1764
|
+
{ id: 'SH-4476', to: 'Proseware Cafe, Spokane', status: 'In transit', tone: 'accent' },
|
|
1765
|
+
{ id: 'SH-4477', to: 'Wingtip Bakery, Eugene', status: 'Delayed', tone: 'warning' },
|
|
1766
|
+
{ id: 'SH-4478', to: 'Coho Winery, Walla Walla', status: 'Out for delivery', tone: 'success' },
|
|
1767
|
+
{ id: 'SH-4479', to: 'Northwind Outlet, Reno', status: 'In transit', tone: 'accent' },
|
|
1768
|
+
{ id: 'SH-4480', to: 'Fourth Coffee, Tacoma', status: 'In transit', tone: 'accent' },
|
|
1769
|
+
] as const;
|
|
1770
|
+
|
|
1771
|
+
@Component({
|
|
1772
|
+
selector: 'app-drawer-snap-points',
|
|
1773
|
+
imports: [
|
|
1774
|
+
SlBadge,
|
|
1775
|
+
SlButton,
|
|
1776
|
+
SlDrawer,
|
|
1777
|
+
SlDrawerBody,
|
|
1778
|
+
SlDrawerClose,
|
|
1779
|
+
SlDrawerDescription,
|
|
1780
|
+
SlDrawerHeader,
|
|
1781
|
+
SlDrawerResizer,
|
|
1782
|
+
SlDrawerTitle,
|
|
1783
|
+
SlDrawerTrigger,
|
|
1784
|
+
SlInline,
|
|
1785
|
+
SlStack,
|
|
1786
|
+
SlText,
|
|
1787
|
+
],
|
|
1788
|
+
template: `
|
|
1789
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
1790
|
+
Shipments in transit
|
|
1791
|
+
</button>
|
|
1792
|
+
<sl-drawer #drawer="slDrawer" side="bottom" [snapPoints]="[0.4, 0.9]" [(extent)]="extent">
|
|
1793
|
+
<div slDrawerResizer></div>
|
|
1794
|
+
<header slDrawerHeader>
|
|
1795
|
+
<h2 slDrawerTitle>Shipments in transit</h2>
|
|
1796
|
+
<p slDrawerDescription>10 shipments left the Reno warehouse this week.</p>
|
|
1797
|
+
<button slDrawerClose></button>
|
|
1798
|
+
</header>
|
|
1799
|
+
<div slDrawerBody>
|
|
1800
|
+
<div slStack [gap]="3">
|
|
1801
|
+
@for (shipment of shipments; track shipment.id) {
|
|
1802
|
+
<div slInline align="center" [gap]="3" justify="between">
|
|
1803
|
+
<div slStack [gap]="0">
|
|
1804
|
+
<span slText size="sm" weight="semibold">{{ shipment.id }}</span>
|
|
1805
|
+
<span slText size="sm" tone="muted">{{ shipment.to }}</span>
|
|
1806
|
+
</div>
|
|
1807
|
+
<span slBadge [tone]="shipment.tone">{{ shipment.status }}</span>
|
|
1808
|
+
</div>
|
|
1809
|
+
}
|
|
1810
|
+
</div>
|
|
1811
|
+
</div>
|
|
1812
|
+
</sl-drawer>
|
|
1813
|
+
`,
|
|
1814
|
+
})
|
|
1815
|
+
export class DrawerSnapPoints {
|
|
1816
|
+
readonly shipments = SHIPMENTS;
|
|
1817
|
+
readonly extent = signal<number | undefined>(0.4);
|
|
1818
|
+
}
|
|
1819
|
+
```
|
|
1820
|
+
|
|
1821
|
+
### unsaved-changes.ts
|
|
1822
|
+
|
|
1823
|
+
Example
|
|
1824
|
+
|
|
1825
|
+
```ts
|
|
1826
|
+
import { Component, signal } from '@angular/core';
|
|
1827
|
+
import { SlButton } from '@slotted/angular/button';
|
|
1828
|
+
import {
|
|
1829
|
+
SlDrawer,
|
|
1830
|
+
SlDrawerBody,
|
|
1831
|
+
SlDrawerClose,
|
|
1832
|
+
SlDrawerDescription,
|
|
1833
|
+
SlDrawerFooter,
|
|
1834
|
+
SlDrawerHeader,
|
|
1835
|
+
SlDrawerTitle,
|
|
1836
|
+
SlDrawerTrigger,
|
|
1837
|
+
} from '@slotted/angular/drawer';
|
|
1838
|
+
import type { DrawerChangeRequest } from '@slotted/angular/drawer';
|
|
1839
|
+
import { SlField, SlFieldLabel } from '@slotted/angular/field';
|
|
1840
|
+
import { SlInlineMessage } from '@slotted/angular/inline-message';
|
|
1841
|
+
import { SlTextarea } from '@slotted/angular/textarea';
|
|
1842
|
+
|
|
1843
|
+
@Component({
|
|
1844
|
+
selector: 'app-drawer-unsaved-changes',
|
|
1845
|
+
imports: [
|
|
1846
|
+
SlButton,
|
|
1847
|
+
SlDrawer,
|
|
1848
|
+
SlDrawerBody,
|
|
1849
|
+
SlDrawerClose,
|
|
1850
|
+
SlDrawerDescription,
|
|
1851
|
+
SlDrawerFooter,
|
|
1852
|
+
SlDrawerHeader,
|
|
1853
|
+
SlDrawerTitle,
|
|
1854
|
+
SlDrawerTrigger,
|
|
1855
|
+
SlField,
|
|
1856
|
+
SlFieldLabel,
|
|
1857
|
+
SlInlineMessage,
|
|
1858
|
+
SlTextarea,
|
|
1859
|
+
],
|
|
1860
|
+
template: `
|
|
1861
|
+
<button slButton tone="secondary" variant="outline" [slDrawerTrigger]="drawer">
|
|
1862
|
+
Delivery instructions
|
|
1863
|
+
</button>
|
|
1864
|
+
<sl-drawer #drawer="slDrawer" [(open)]="open" (openChangeRequest)="guard($event)">
|
|
1865
|
+
<header slDrawerHeader>
|
|
1866
|
+
<h2 slDrawerTitle>Delivery instructions</h2>
|
|
1867
|
+
<p slDrawerDescription>Order SO-1182, printed on the packing slip.</p>
|
|
1868
|
+
<button slDrawerClose></button>
|
|
1869
|
+
</header>
|
|
1870
|
+
<div slDrawerBody>
|
|
1871
|
+
<div slField>
|
|
1872
|
+
<label slFieldLabel>Instructions for the carrier</label>
|
|
1873
|
+
<textarea slTextarea [value]="draft()" (valueChange)="edit($event.value)"></textarea>
|
|
1874
|
+
</div>
|
|
1875
|
+
</div>
|
|
1876
|
+
<footer slDrawerFooter>
|
|
1877
|
+
@if (confirming()) {
|
|
1878
|
+
<p slInlineMessage live="polite" tone="warning">
|
|
1879
|
+
Discard your changes to the instructions?
|
|
1880
|
+
</p>
|
|
1881
|
+
<button slButton variant="ghost" tone="secondary" (click)="confirming.set(false)">
|
|
1882
|
+
Keep editing
|
|
1883
|
+
</button>
|
|
1884
|
+
<button slButton tone="danger" (click)="close()">Discard</button>
|
|
1885
|
+
} @else {
|
|
1886
|
+
<button slButton variant="ghost" tone="secondary" (click)="cancel()">Cancel</button>
|
|
1887
|
+
<button slButton (click)="save()">Save</button>
|
|
1888
|
+
}
|
|
1889
|
+
</footer>
|
|
1890
|
+
</sl-drawer>
|
|
1891
|
+
`,
|
|
1892
|
+
})
|
|
1893
|
+
export class DrawerUnsavedChanges {
|
|
1894
|
+
readonly open = signal(false);
|
|
1895
|
+
readonly saved = signal('Leave at the loading dock, door 3.');
|
|
1896
|
+
readonly draft = signal(this.saved());
|
|
1897
|
+
readonly confirming = signal(false);
|
|
1898
|
+
|
|
1899
|
+
guard(request: DrawerChangeRequest): void {
|
|
1900
|
+
if (request.value) {
|
|
1901
|
+
this.draft.set(this.saved());
|
|
1902
|
+
this.confirming.set(false);
|
|
1903
|
+
} else if (this.draft() !== this.saved()) {
|
|
1904
|
+
request.cancel();
|
|
1905
|
+
this.confirming.set(true);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1909
|
+
edit(value: string): void {
|
|
1910
|
+
this.draft.set(value);
|
|
1911
|
+
this.confirming.set(false);
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
cancel(): void {
|
|
1915
|
+
if (this.draft() === this.saved()) this.close();
|
|
1916
|
+
else this.confirming.set(true);
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
save(): void {
|
|
1920
|
+
this.saved.set(this.draft());
|
|
1921
|
+
this.close();
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
close(): void {
|
|
1925
|
+
this.confirming.set(false);
|
|
1926
|
+
this.open.set(false);
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
```
|