@hypoth-ui/cli 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +19 -115
- package/dist/{add-PDBC4JTE.js → add-V5PW73GC.js} +29 -17
- package/dist/{chunk-5LTQ2XVL.js → chunk-27CLUUVC.js} +0 -2
- package/dist/{chunk-YPKFYE45.js → chunk-NWIRSZUQ.js} +6 -13
- package/dist/{chunk-GJ6JOQ3Q.js → chunk-PBK72SJJ.js} +1 -1
- package/dist/{diff-BQEXG7HU.js → diff-776UATCA.js} +2 -2
- package/dist/index.js +5 -5
- package/dist/{init-7AZXYAPJ.js → init-GDU2PW7K.js} +10 -13
- package/dist/{list-X6ZLM2NQ.js → list-XDP5I537.js} +3 -3
- package/package.json +16 -12
- package/registry/components.json +1820 -206
- package/templates/accordion/index.tsx +266 -0
- package/templates/accordion/wc/accordion-content.ts +113 -0
- package/templates/accordion/wc/accordion-item.ts +111 -0
- package/templates/accordion/wc/accordion-trigger.ts +105 -0
- package/templates/accordion/wc/accordion.ts +213 -0
- package/templates/accordion/wc/index.ts +12 -0
- package/templates/alert/index.tsx +177 -0
- package/templates/alert/wc/alert.ts +167 -0
- package/templates/alert/wc/index.ts +1 -0
- package/templates/alert-dialog/index.tsx +360 -0
- package/templates/alert-dialog/wc/alert-dialog-action.ts +43 -0
- package/templates/alert-dialog/wc/alert-dialog-cancel.ts +43 -0
- package/templates/alert-dialog/wc/alert-dialog-content.ts +42 -0
- package/templates/alert-dialog/wc/alert-dialog-description.ts +34 -0
- package/templates/alert-dialog/wc/alert-dialog-footer.ts +25 -0
- package/templates/alert-dialog/wc/alert-dialog-header.ts +25 -0
- package/templates/alert-dialog/wc/alert-dialog-title.ts +34 -0
- package/templates/alert-dialog/wc/alert-dialog-trigger.ts +46 -0
- package/templates/alert-dialog/wc/alert-dialog.ts +302 -0
- package/templates/alert-dialog/wc/index.ts +13 -0
- package/templates/aspect-ratio/index.tsx +50 -0
- package/templates/aspect-ratio/wc/aspect-ratio.ts +78 -0
- package/templates/aspect-ratio/wc/index.ts +5 -0
- package/templates/avatar/avatar-group.tsx +88 -0
- package/templates/avatar/avatar.tsx +124 -0
- package/templates/avatar/index.tsx +33 -0
- package/templates/avatar/wc/avatar-group.ts +112 -0
- package/templates/avatar/wc/avatar.ts +184 -0
- package/templates/avatar/wc/index.ts +5 -0
- package/templates/badge/index.tsx +140 -0
- package/templates/badge/wc/badge.ts +119 -0
- package/templates/badge/wc/index.ts +9 -0
- package/templates/breadcrumb/index.tsx +157 -0
- package/templates/breadcrumb/wc/breadcrumb-item.ts +30 -0
- package/templates/breadcrumb/wc/breadcrumb-link.ts +70 -0
- package/templates/breadcrumb/wc/breadcrumb-list.ts +30 -0
- package/templates/breadcrumb/wc/breadcrumb-page.ts +32 -0
- package/templates/breadcrumb/wc/breadcrumb-separator.ts +31 -0
- package/templates/breadcrumb/wc/breadcrumb.ts +55 -0
- package/templates/breadcrumb/wc/index.ts +10 -0
- package/templates/button/button.tsx +119 -0
- package/templates/button/index.ts +1 -0
- package/templates/button/wc/button.ts +169 -0
- package/templates/calendar/index.tsx +149 -0
- package/templates/calendar/wc/calendar.ts +316 -0
- package/templates/calendar/wc/index.ts +4 -0
- package/templates/card/index.tsx +108 -0
- package/templates/card/wc/card-content.ts +25 -0
- package/templates/card/wc/card-footer.ts +25 -0
- package/templates/card/wc/card-header.ts +25 -0
- package/templates/card/wc/card.ts +43 -0
- package/templates/card/wc/index.ts +8 -0
- package/templates/checkbox/checkbox.tsx +85 -0
- package/templates/checkbox/wc/checkbox.ts +247 -0
- package/templates/collapsible/index.tsx +172 -0
- package/templates/collapsible/wc/collapsible-content.ts +97 -0
- package/templates/collapsible/wc/collapsible-trigger.ts +39 -0
- package/templates/collapsible/wc/collapsible.ts +143 -0
- package/templates/collapsible/wc/index.ts +7 -0
- package/templates/combobox/combobox-content.tsx +141 -0
- package/templates/combobox/combobox-context.ts +36 -0
- package/templates/combobox/combobox-empty.tsx +38 -0
- package/templates/combobox/combobox-input.tsx +159 -0
- package/templates/combobox/combobox-loading.tsx +38 -0
- package/templates/combobox/combobox-option.tsx +99 -0
- package/templates/combobox/combobox-root.tsx +207 -0
- package/templates/combobox/combobox-tag.tsx +62 -0
- package/templates/combobox/index.ts +62 -0
- package/templates/combobox/wc/combobox-content.ts +97 -0
- package/templates/combobox/wc/combobox-input.ts +134 -0
- package/templates/combobox/wc/combobox-option.ts +111 -0
- package/templates/combobox/wc/combobox-tag.ts +103 -0
- package/templates/combobox/wc/combobox.ts +981 -0
- package/templates/combobox/wc/index.ts +5 -0
- package/templates/command/index.tsx +279 -0
- package/templates/command/wc/command-empty.ts +24 -0
- package/templates/command/wc/command-group.ts +60 -0
- package/templates/command/wc/command-input.ts +136 -0
- package/templates/command/wc/command-item.ts +78 -0
- package/templates/command/wc/command-list.ts +103 -0
- package/templates/command/wc/command-loading.ts +24 -0
- package/templates/command/wc/command-separator.ts +23 -0
- package/templates/command/wc/command.ts +176 -0
- package/templates/context-menu/index.tsx +262 -0
- package/templates/context-menu/wc/context-menu-content.ts +41 -0
- package/templates/context-menu/wc/context-menu-item.ts +83 -0
- package/templates/context-menu/wc/context-menu-label.ts +30 -0
- package/templates/context-menu/wc/context-menu-separator.ts +28 -0
- package/templates/context-menu/wc/context-menu.ts +324 -0
- package/templates/context-menu/wc/index.ts +9 -0
- package/templates/data-table/index.tsx +263 -0
- package/templates/data-table/wc/data-table.ts +405 -0
- package/templates/data-table/wc/index.ts +10 -0
- package/templates/date-picker/date-picker-calendar.tsx +352 -0
- package/templates/date-picker/date-picker-content.tsx +121 -0
- package/templates/date-picker/date-picker-context.ts +46 -0
- package/templates/date-picker/date-picker-root.tsx +201 -0
- package/templates/date-picker/date-picker-trigger.tsx +95 -0
- package/templates/date-picker/index.ts +44 -0
- package/templates/date-picker/wc/date-picker-calendar.ts +457 -0
- package/templates/date-picker/wc/date-picker.ts +592 -0
- package/templates/date-picker/wc/date-utils.ts +467 -0
- package/templates/date-picker/wc/index.ts +3 -0
- package/templates/dialog/dialog-close.tsx +57 -0
- package/templates/dialog/dialog-content.tsx +106 -0
- package/templates/dialog/dialog-context.ts +24 -0
- package/templates/dialog/dialog-description.tsx +51 -0
- package/templates/dialog/dialog-root.tsx +104 -0
- package/templates/dialog/dialog-title.tsx +38 -0
- package/templates/dialog/dialog-trigger.tsx +94 -0
- package/templates/dialog/index.ts +52 -0
- package/templates/dialog/wc/dialog-content.ts +59 -0
- package/templates/dialog/wc/dialog-description.ts +58 -0
- package/templates/dialog/wc/dialog-title.ts +56 -0
- package/templates/dialog/wc/dialog.ts +411 -0
- package/templates/drawer/index.tsx +263 -0
- package/templates/drawer/wc/drawer-content.ts +150 -0
- package/templates/drawer/wc/drawer-description.ts +34 -0
- package/templates/drawer/wc/drawer-footer.ts +25 -0
- package/templates/drawer/wc/drawer-header.ts +25 -0
- package/templates/drawer/wc/drawer-title.ts +34 -0
- package/templates/drawer/wc/drawer.ts +348 -0
- package/templates/drawer/wc/index.ts +10 -0
- package/templates/dropdown-menu/index.tsx +454 -0
- package/templates/dropdown-menu/wc/dropdown-menu-checkbox-item.ts +93 -0
- package/templates/dropdown-menu/wc/dropdown-menu-content.ts +43 -0
- package/templates/dropdown-menu/wc/dropdown-menu-item.ts +85 -0
- package/templates/dropdown-menu/wc/dropdown-menu-label.ts +31 -0
- package/templates/dropdown-menu/wc/dropdown-menu-radio-group.ts +80 -0
- package/templates/dropdown-menu/wc/dropdown-menu-radio-item.ts +101 -0
- package/templates/dropdown-menu/wc/dropdown-menu-separator.ts +28 -0
- package/templates/dropdown-menu/wc/dropdown-menu.ts +358 -0
- package/templates/dropdown-menu/wc/index.ts +12 -0
- package/templates/field/field-description.tsx +39 -0
- package/templates/field/field-error.tsx +37 -0
- package/templates/field/field.tsx +46 -0
- package/templates/field/index.ts +4 -0
- package/templates/field/label.tsx +40 -0
- package/templates/field/wc/field-description.ts +42 -0
- package/templates/field/wc/field-error.ts +46 -0
- package/templates/field/wc/field.ts +210 -0
- package/templates/field/wc/label.ts +54 -0
- package/templates/file-upload/file-upload-context.ts +26 -0
- package/templates/file-upload/file-upload-dropzone.tsx +111 -0
- package/templates/file-upload/file-upload-input.tsx +86 -0
- package/templates/file-upload/file-upload-item.tsx +105 -0
- package/templates/file-upload/file-upload-root.tsx +115 -0
- package/templates/file-upload/index.ts +50 -0
- package/templates/file-upload/wc/file-upload.ts +380 -0
- package/templates/file-upload/wc/index.ts +1 -0
- package/templates/hover-card/index.tsx +203 -0
- package/templates/hover-card/wc/hover-card-content.ts +50 -0
- package/templates/hover-card/wc/hover-card.ts +382 -0
- package/templates/hover-card/wc/index.ts +6 -0
- package/templates/icon/icon.tsx +76 -0
- package/templates/icon/wc/icon-adapter.ts +108 -0
- package/templates/icon/wc/icon.ts +161 -0
- package/templates/input/input.tsx +130 -0
- package/templates/input/wc/input.ts +216 -0
- package/templates/layout/app-shell.tsx +177 -0
- package/templates/layout/box.tsx +53 -0
- package/templates/layout/center.tsx +42 -0
- package/templates/layout/container.tsx +43 -0
- package/templates/layout/flow.tsx +83 -0
- package/templates/layout/grid.tsx +79 -0
- package/templates/layout/index.ts +33 -0
- package/templates/layout/inline.tsx +16 -0
- package/templates/layout/page.tsx +43 -0
- package/templates/layout/section.tsx +39 -0
- package/templates/layout/spacer.tsx +30 -0
- package/templates/layout/split.tsx +47 -0
- package/templates/layout/stack.tsx +16 -0
- package/templates/layout/wc/app-shell.ts +58 -0
- package/templates/layout/wc/box.ts +117 -0
- package/templates/layout/wc/center.ts +78 -0
- package/templates/layout/wc/container.ts +77 -0
- package/templates/layout/wc/flow.ts +149 -0
- package/templates/layout/wc/footer.ts +57 -0
- package/templates/layout/wc/grid.ts +142 -0
- package/templates/layout/wc/header.ts +57 -0
- package/templates/layout/wc/index.ts +41 -0
- package/templates/layout/wc/main.ts +46 -0
- package/templates/layout/wc/page.ts +81 -0
- package/templates/layout/wc/section.ts +65 -0
- package/templates/layout/wc/spacer.ts +77 -0
- package/templates/layout/wc/split.ts +94 -0
- package/templates/layout/wc/wrap.ts +93 -0
- package/templates/layout/wrap.tsx +46 -0
- package/templates/link/link.tsx +109 -0
- package/templates/link/wc/link.ts +124 -0
- package/templates/list/index.tsx +55 -0
- package/templates/list/list-item.tsx +117 -0
- package/templates/list/list.tsx +115 -0
- package/templates/list/wc/index.ts +5 -0
- package/templates/list/wc/list-item.ts +127 -0
- package/templates/list/wc/list.ts +114 -0
- package/templates/menu/index.ts +49 -0
- package/templates/menu/menu-content.tsx +109 -0
- package/templates/menu/menu-context.ts +17 -0
- package/templates/menu/menu-item.tsx +108 -0
- package/templates/menu/menu-label.tsx +32 -0
- package/templates/menu/menu-root.tsx +108 -0
- package/templates/menu/menu-separator.tsx +24 -0
- package/templates/menu/menu-trigger.tsx +104 -0
- package/templates/menu/wc/menu-content.ts +67 -0
- package/templates/menu/wc/menu-item.ts +109 -0
- package/templates/menu/wc/menu.ts +449 -0
- package/templates/navigation-menu/index.tsx +328 -0
- package/templates/navigation-menu/wc/index.ts +12 -0
- package/templates/navigation-menu/wc/navigation-menu-content.ts +30 -0
- package/templates/navigation-menu/wc/navigation-menu-indicator.ts +30 -0
- package/templates/navigation-menu/wc/navigation-menu-item.ts +60 -0
- package/templates/navigation-menu/wc/navigation-menu-link.ts +97 -0
- package/templates/navigation-menu/wc/navigation-menu-list.ts +30 -0
- package/templates/navigation-menu/wc/navigation-menu-trigger.ts +110 -0
- package/templates/navigation-menu/wc/navigation-menu-viewport.ts +85 -0
- package/templates/navigation-menu/wc/navigation-menu.ts +272 -0
- package/templates/number-input/index.ts +46 -0
- package/templates/number-input/number-input-context.ts +38 -0
- package/templates/number-input/number-input-decrement.tsx +53 -0
- package/templates/number-input/number-input-field.tsx +93 -0
- package/templates/number-input/number-input-increment.tsx +53 -0
- package/templates/number-input/number-input-root.tsx +137 -0
- package/templates/number-input/wc/index.ts +1 -0
- package/templates/number-input/wc/number-input.ts +283 -0
- package/templates/pagination/index.tsx +198 -0
- package/templates/pagination/wc/index.ts +11 -0
- package/templates/pagination/wc/pagination-content.ts +30 -0
- package/templates/pagination/wc/pagination-ellipsis.ts +28 -0
- package/templates/pagination/wc/pagination-item.ts +30 -0
- package/templates/pagination/wc/pagination-link.ts +76 -0
- package/templates/pagination/wc/pagination-next.ts +69 -0
- package/templates/pagination/wc/pagination-previous.ts +69 -0
- package/templates/pagination/wc/pagination.ts +156 -0
- package/templates/pin-input/index.ts +39 -0
- package/templates/pin-input/pin-input-context.ts +30 -0
- package/templates/pin-input/pin-input-field.tsx +186 -0
- package/templates/pin-input/pin-input-root.tsx +120 -0
- package/templates/pin-input/wc/index.ts +1 -0
- package/templates/pin-input/wc/pin-input.ts +259 -0
- package/templates/popover/popover.tsx +121 -0
- package/templates/popover/wc/popover-content.ts +66 -0
- package/templates/popover/wc/popover.ts +343 -0
- package/templates/progress/index.tsx +117 -0
- package/templates/progress/wc/index.ts +4 -0
- package/templates/progress/wc/progress.ts +174 -0
- package/templates/radio/radio.tsx +43 -0
- package/templates/radio/wc/radio-group.ts +261 -0
- package/templates/radio/wc/radio.ts +145 -0
- package/templates/scroll-area/index.tsx +144 -0
- package/templates/scroll-area/wc/index.ts +8 -0
- package/templates/scroll-area/wc/scroll-area-scrollbar.ts +143 -0
- package/templates/scroll-area/wc/scroll-area-thumb.ts +225 -0
- package/templates/scroll-area/wc/scroll-area-viewport.ts +120 -0
- package/templates/scroll-area/wc/scroll-area.ts +63 -0
- package/templates/select/index.ts +57 -0
- package/templates/select/select-content.tsx +243 -0
- package/templates/select/select-context.ts +30 -0
- package/templates/select/select-group.tsx +53 -0
- package/templates/select/select-label.tsx +34 -0
- package/templates/select/select-option.tsx +97 -0
- package/templates/select/select-root.tsx +153 -0
- package/templates/select/select-separator.tsx +27 -0
- package/templates/select/select-trigger.tsx +112 -0
- package/templates/select/select-value.tsx +48 -0
- package/templates/select/wc/index.ts +6 -0
- package/templates/select/wc/select-content.ts +89 -0
- package/templates/select/wc/select-group.ts +82 -0
- package/templates/select/wc/select-label.ts +49 -0
- package/templates/select/wc/select-option.ts +111 -0
- package/templates/select/wc/select-trigger.ts +101 -0
- package/templates/select/wc/select.ts +840 -0
- package/templates/separator/index.tsx +49 -0
- package/templates/separator/wc/index.ts +5 -0
- package/templates/separator/wc/separator.ts +60 -0
- package/templates/sheet/index.tsx +291 -0
- package/templates/sheet/wc/index.ts +12 -0
- package/templates/sheet/wc/sheet-close.ts +43 -0
- package/templates/sheet/wc/sheet-content.ts +47 -0
- package/templates/sheet/wc/sheet-description.ts +34 -0
- package/templates/sheet/wc/sheet-footer.ts +25 -0
- package/templates/sheet/wc/sheet-header.ts +25 -0
- package/templates/sheet/wc/sheet-overlay.ts +23 -0
- package/templates/sheet/wc/sheet-title.ts +34 -0
- package/templates/sheet/wc/sheet.ts +336 -0
- package/templates/skeleton/index.tsx +131 -0
- package/templates/skeleton/wc/index.ts +10 -0
- package/templates/skeleton/wc/skeleton.ts +107 -0
- package/templates/slider/index.ts +41 -0
- package/templates/slider/slider-context.ts +36 -0
- package/templates/slider/slider-range.tsx +59 -0
- package/templates/slider/slider-root.tsx +166 -0
- package/templates/slider/slider-thumb.tsx +213 -0
- package/templates/slider/slider-track.tsx +113 -0
- package/templates/slider/wc/index.ts +1 -0
- package/templates/slider/wc/slider.ts +465 -0
- package/templates/spinner/spinner.tsx +64 -0
- package/templates/spinner/wc/spinner.ts +70 -0
- package/templates/stepper/index.tsx +230 -0
- package/templates/stepper/wc/index.ts +12 -0
- package/templates/stepper/wc/stepper-content.ts +30 -0
- package/templates/stepper/wc/stepper-description.ts +25 -0
- package/templates/stepper/wc/stepper-indicator.ts +30 -0
- package/templates/stepper/wc/stepper-item.ts +55 -0
- package/templates/stepper/wc/stepper-separator.ts +29 -0
- package/templates/stepper/wc/stepper-title.ts +25 -0
- package/templates/stepper/wc/stepper-trigger.ts +67 -0
- package/templates/stepper/wc/stepper.ts +164 -0
- package/templates/switch/switch.tsx +90 -0
- package/templates/switch/wc/switch.ts +228 -0
- package/templates/table/body.tsx +21 -0
- package/templates/table/cell.tsx +44 -0
- package/templates/table/head.tsx +112 -0
- package/templates/table/header.tsx +21 -0
- package/templates/table/index.tsx +93 -0
- package/templates/table/root.tsx +82 -0
- package/templates/table/row.tsx +36 -0
- package/templates/table/wc/index.ts +9 -0
- package/templates/table/wc/table-body.ts +32 -0
- package/templates/table/wc/table-cell.ts +58 -0
- package/templates/table/wc/table-head.ts +129 -0
- package/templates/table/wc/table-header.ts +32 -0
- package/templates/table/wc/table-row.ts +50 -0
- package/templates/table/wc/table.ts +93 -0
- package/templates/tabs/index.tsx +222 -0
- package/templates/tabs/wc/index.ts +8 -0
- package/templates/tabs/wc/tabs-content.ts +82 -0
- package/templates/tabs/wc/tabs-list.ts +56 -0
- package/templates/tabs/wc/tabs-trigger.ts +136 -0
- package/templates/tabs/wc/tabs.ts +202 -0
- package/templates/tag/index.tsx +186 -0
- package/templates/tag/wc/index.ts +4 -0
- package/templates/tag/wc/tag.ts +166 -0
- package/templates/text/text.tsx +100 -0
- package/templates/text/wc/text.ts +94 -0
- package/templates/textarea/textarea.tsx +134 -0
- package/templates/textarea/wc/textarea.ts +280 -0
- package/templates/time-picker/index.ts +42 -0
- package/templates/time-picker/time-picker-context.ts +28 -0
- package/templates/time-picker/time-picker-root.tsx +113 -0
- package/templates/time-picker/time-picker-segment.tsx +91 -0
- package/templates/time-picker/wc/index.ts +1 -0
- package/templates/time-picker/wc/time-picker.ts +221 -0
- package/templates/toast/index.tsx +71 -0
- package/templates/toast/provider.tsx +228 -0
- package/templates/toast/toast.tsx +142 -0
- package/templates/toast/use-toast.ts +89 -0
- package/templates/toast/wc/index.ts +15 -0
- package/templates/toast/wc/toast-controller.ts +282 -0
- package/templates/toast/wc/toast-provider.ts +161 -0
- package/templates/toast/wc/toast.ts +165 -0
- package/templates/tooltip/tooltip.tsx +62 -0
- package/templates/tooltip/wc/tooltip-content.ts +64 -0
- package/templates/tooltip/wc/tooltip.ts +289 -0
- package/templates/tree/index.tsx +60 -0
- package/templates/tree/tree-item.tsx +131 -0
- package/templates/tree/tree.tsx +138 -0
- package/templates/tree/wc/index.ts +11 -0
- package/templates/tree/wc/tree-item.ts +273 -0
- package/templates/tree/wc/tree-utils.ts +143 -0
- package/templates/tree/wc/tree.ts +139 -0
- package/templates/visually-hidden/visually-hidden.tsx +45 -0
- package/templates/visually-hidden/wc/visually-hidden.ts +64 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DrawerContent component - container for drawer content with swipe support.
|
|
3
|
+
*
|
|
4
|
+
* @element ds-drawer-content
|
|
5
|
+
*
|
|
6
|
+
* @slot - Drawer content (header, body, footer)
|
|
7
|
+
*
|
|
8
|
+
* @fires ds:drawer-close - Fired when swipe gesture dismisses drawer
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { html } from "lit";
|
|
12
|
+
import { property, state } from "lit/decorators.js";
|
|
13
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
14
|
+
import { emitEvent } from "../../events/emit.js";
|
|
15
|
+
import { define } from "../../registry/define.js";
|
|
16
|
+
import type { DrawerSide } from "./drawer.js";
|
|
17
|
+
|
|
18
|
+
export class DsDrawerContent extends DSElement {
|
|
19
|
+
/** Side of the screen the drawer appears from (set by parent) */
|
|
20
|
+
@property({ reflect: true })
|
|
21
|
+
side: DrawerSide = "bottom";
|
|
22
|
+
|
|
23
|
+
/** Data state for animations */
|
|
24
|
+
@property({ attribute: "data-state", reflect: true })
|
|
25
|
+
dataState: "open" | "closed" = "closed";
|
|
26
|
+
|
|
27
|
+
/** Whether swipe-to-dismiss is enabled (set by parent) */
|
|
28
|
+
@property({ type: Boolean, attribute: "swipe-dismiss" })
|
|
29
|
+
swipeDismiss = true;
|
|
30
|
+
|
|
31
|
+
/** Current swipe offset during drag */
|
|
32
|
+
@state()
|
|
33
|
+
private swipeOffset = 0;
|
|
34
|
+
|
|
35
|
+
/** Whether currently dragging */
|
|
36
|
+
@state()
|
|
37
|
+
private isDragging = false;
|
|
38
|
+
|
|
39
|
+
private startY = 0;
|
|
40
|
+
private startX = 0;
|
|
41
|
+
|
|
42
|
+
override connectedCallback(): void {
|
|
43
|
+
super.connectedCallback();
|
|
44
|
+
|
|
45
|
+
// Add touch event listeners for swipe-to-dismiss
|
|
46
|
+
this.addEventListener("touchstart", this.handleTouchStart, { passive: true });
|
|
47
|
+
this.addEventListener("touchmove", this.handleTouchMove, { passive: false });
|
|
48
|
+
this.addEventListener("touchend", this.handleTouchEnd, { passive: true });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
override disconnectedCallback(): void {
|
|
52
|
+
super.disconnectedCallback();
|
|
53
|
+
this.removeEventListener("touchstart", this.handleTouchStart);
|
|
54
|
+
this.removeEventListener("touchmove", this.handleTouchMove);
|
|
55
|
+
this.removeEventListener("touchend", this.handleTouchEnd);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private handleTouchStart = (event: TouchEvent): void => {
|
|
59
|
+
if (!this.swipeDismiss) return;
|
|
60
|
+
|
|
61
|
+
const touch = event.touches[0];
|
|
62
|
+
if (!touch) return;
|
|
63
|
+
|
|
64
|
+
this.startY = touch.clientY;
|
|
65
|
+
this.startX = touch.clientX;
|
|
66
|
+
this.isDragging = true;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
private handleTouchMove = (event: TouchEvent): void => {
|
|
70
|
+
if (!this.swipeDismiss || !this.isDragging) return;
|
|
71
|
+
|
|
72
|
+
const touch = event.touches[0];
|
|
73
|
+
if (!touch) return;
|
|
74
|
+
|
|
75
|
+
const deltaY = touch.clientY - this.startY;
|
|
76
|
+
const deltaX = touch.clientX - this.startX;
|
|
77
|
+
|
|
78
|
+
// Calculate offset based on side
|
|
79
|
+
let offset = 0;
|
|
80
|
+
switch (this.side) {
|
|
81
|
+
case "bottom":
|
|
82
|
+
offset = Math.max(0, deltaY);
|
|
83
|
+
break;
|
|
84
|
+
case "top":
|
|
85
|
+
offset = Math.max(0, -deltaY);
|
|
86
|
+
break;
|
|
87
|
+
case "left":
|
|
88
|
+
offset = Math.max(0, -deltaX);
|
|
89
|
+
break;
|
|
90
|
+
case "right":
|
|
91
|
+
offset = Math.max(0, deltaX);
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (offset > 0) {
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
this.swipeOffset = offset;
|
|
98
|
+
this.updateSwipeTransform();
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
private handleTouchEnd = (): void => {
|
|
103
|
+
if (!this.swipeDismiss || !this.isDragging) return;
|
|
104
|
+
|
|
105
|
+
this.isDragging = false;
|
|
106
|
+
|
|
107
|
+
// If swiped more than 100px or 30% of content height, close
|
|
108
|
+
const threshold = Math.min(100, this.offsetHeight * 0.3);
|
|
109
|
+
|
|
110
|
+
if (this.swipeOffset > threshold) {
|
|
111
|
+
emitEvent(this, "ds:drawer-close", { bubbles: true });
|
|
112
|
+
} else {
|
|
113
|
+
// Reset position
|
|
114
|
+
this.swipeOffset = 0;
|
|
115
|
+
this.style.transform = "";
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
private updateSwipeTransform(): void {
|
|
120
|
+
switch (this.side) {
|
|
121
|
+
case "bottom":
|
|
122
|
+
this.style.transform = `translateY(${this.swipeOffset}px)`;
|
|
123
|
+
break;
|
|
124
|
+
case "top":
|
|
125
|
+
this.style.transform = `translateY(-${this.swipeOffset}px)`;
|
|
126
|
+
break;
|
|
127
|
+
case "left":
|
|
128
|
+
this.style.transform = `translateX(-${this.swipeOffset}px)`;
|
|
129
|
+
break;
|
|
130
|
+
case "right":
|
|
131
|
+
this.style.transform = `translateX(${this.swipeOffset}px)`;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
override render() {
|
|
137
|
+
return html`
|
|
138
|
+
<div class="ds-drawer__handle"></div>
|
|
139
|
+
<slot></slot>
|
|
140
|
+
`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
define("ds-drawer-content", DsDrawerContent);
|
|
145
|
+
|
|
146
|
+
declare global {
|
|
147
|
+
interface HTMLElementTagNameMap {
|
|
148
|
+
"ds-drawer-content": DsDrawerContent;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DrawerDescription component - description for the drawer.
|
|
3
|
+
*
|
|
4
|
+
* @element ds-drawer-description
|
|
5
|
+
*
|
|
6
|
+
* @slot - Description content
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { html } from "lit";
|
|
10
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
11
|
+
import { define } from "../../registry/define.js";
|
|
12
|
+
|
|
13
|
+
export class DsDrawerDescription extends DSElement {
|
|
14
|
+
override connectedCallback(): void {
|
|
15
|
+
super.connectedCallback();
|
|
16
|
+
|
|
17
|
+
// Generate ID if not present (for aria-describedby)
|
|
18
|
+
if (!this.id) {
|
|
19
|
+
this.id = `drawer-desc-${crypto.randomUUID().slice(0, 8)}`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
override render() {
|
|
24
|
+
return html`<slot></slot>`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
define("ds-drawer-description", DsDrawerDescription);
|
|
29
|
+
|
|
30
|
+
declare global {
|
|
31
|
+
interface HTMLElementTagNameMap {
|
|
32
|
+
"ds-drawer-description": DsDrawerDescription;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DrawerFooter component - footer section for drawer actions.
|
|
3
|
+
*
|
|
4
|
+
* @element ds-drawer-footer
|
|
5
|
+
*
|
|
6
|
+
* @slot - Footer content (action buttons)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { html } from "lit";
|
|
10
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
11
|
+
import { define } from "../../registry/define.js";
|
|
12
|
+
|
|
13
|
+
export class DsDrawerFooter extends DSElement {
|
|
14
|
+
override render() {
|
|
15
|
+
return html`<slot></slot>`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
define("ds-drawer-footer", DsDrawerFooter);
|
|
20
|
+
|
|
21
|
+
declare global {
|
|
22
|
+
interface HTMLElementTagNameMap {
|
|
23
|
+
"ds-drawer-footer": DsDrawerFooter;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DrawerHeader component - header section for drawer.
|
|
3
|
+
*
|
|
4
|
+
* @element ds-drawer-header
|
|
5
|
+
*
|
|
6
|
+
* @slot - Header content (title and description)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { html } from "lit";
|
|
10
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
11
|
+
import { define } from "../../registry/define.js";
|
|
12
|
+
|
|
13
|
+
export class DsDrawerHeader extends DSElement {
|
|
14
|
+
override render() {
|
|
15
|
+
return html`<slot></slot>`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
define("ds-drawer-header", DsDrawerHeader);
|
|
20
|
+
|
|
21
|
+
declare global {
|
|
22
|
+
interface HTMLElementTagNameMap {
|
|
23
|
+
"ds-drawer-header": DsDrawerHeader;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DrawerTitle component - title for the drawer.
|
|
3
|
+
*
|
|
4
|
+
* @element ds-drawer-title
|
|
5
|
+
*
|
|
6
|
+
* @slot - Title content
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { html } from "lit";
|
|
10
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
11
|
+
import { define } from "../../registry/define.js";
|
|
12
|
+
|
|
13
|
+
export class DsDrawerTitle extends DSElement {
|
|
14
|
+
override connectedCallback(): void {
|
|
15
|
+
super.connectedCallback();
|
|
16
|
+
|
|
17
|
+
// Generate ID if not present (for aria-labelledby)
|
|
18
|
+
if (!this.id) {
|
|
19
|
+
this.id = `drawer-title-${crypto.randomUUID().slice(0, 8)}`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
override render() {
|
|
24
|
+
return html`<slot></slot>`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
define("ds-drawer-title", DsDrawerTitle);
|
|
29
|
+
|
|
30
|
+
declare global {
|
|
31
|
+
interface HTMLElementTagNameMap {
|
|
32
|
+
"ds-drawer-title": DsDrawerTitle;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drawer component - mobile-optimized slide-in panel with swipe gestures.
|
|
3
|
+
*
|
|
4
|
+
* Drawer is a Sheet variant optimized for mobile with touch gesture support.
|
|
5
|
+
* It slides in from the bottom by default and can be dismissed by swiping down.
|
|
6
|
+
*
|
|
7
|
+
* @element ds-drawer
|
|
8
|
+
*
|
|
9
|
+
* @slot trigger - Button or element that opens the drawer
|
|
10
|
+
* @slot - Drawer content (ds-drawer-content)
|
|
11
|
+
*
|
|
12
|
+
* @fires ds:open - Fired when drawer opens
|
|
13
|
+
* @fires ds:close - Fired when drawer closes
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```html
|
|
17
|
+
* <ds-drawer>
|
|
18
|
+
* <button slot="trigger">Open Menu</button>
|
|
19
|
+
* <ds-drawer-content>
|
|
20
|
+
* <ds-drawer-header>
|
|
21
|
+
* <ds-drawer-title>Navigation</ds-drawer-title>
|
|
22
|
+
* </ds-drawer-header>
|
|
23
|
+
* <nav>Menu items...</nav>
|
|
24
|
+
* </ds-drawer-content>
|
|
25
|
+
* </ds-drawer>
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import {
|
|
30
|
+
type DialogBehavior,
|
|
31
|
+
type Presence,
|
|
32
|
+
createDialogBehavior,
|
|
33
|
+
createPresence,
|
|
34
|
+
prefersReducedMotion,
|
|
35
|
+
} from "@hypoth-ui/primitives-dom";
|
|
36
|
+
import { html } from "lit";
|
|
37
|
+
import { property, state } from "lit/decorators.js";
|
|
38
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
39
|
+
import { StandardEvents, emitEvent } from "../../events/emit.js";
|
|
40
|
+
import { define } from "../../registry/define.js";
|
|
41
|
+
import { devWarn, hasRequiredChild, Warnings } from "../../utils/dev-warnings.js";
|
|
42
|
+
|
|
43
|
+
// Import child components to ensure they're registered
|
|
44
|
+
import type { DsDrawerContent } from "./drawer-content.js";
|
|
45
|
+
import "./drawer-content.js";
|
|
46
|
+
import "./drawer-header.js";
|
|
47
|
+
import "./drawer-footer.js";
|
|
48
|
+
import "./drawer-title.js";
|
|
49
|
+
import "./drawer-description.js";
|
|
50
|
+
|
|
51
|
+
export type DrawerSide = "top" | "right" | "bottom" | "left";
|
|
52
|
+
|
|
53
|
+
export class DsDrawer extends DSElement {
|
|
54
|
+
/** Whether the drawer is open */
|
|
55
|
+
@property({ type: Boolean, reflect: true })
|
|
56
|
+
open = false;
|
|
57
|
+
|
|
58
|
+
/** Side of the screen the drawer appears from */
|
|
59
|
+
@property({ reflect: true })
|
|
60
|
+
side: DrawerSide = "bottom";
|
|
61
|
+
|
|
62
|
+
/** Whether swipe-to-dismiss is enabled */
|
|
63
|
+
@property({ type: Boolean, attribute: "swipe-dismiss" })
|
|
64
|
+
swipeDismiss = true;
|
|
65
|
+
|
|
66
|
+
/** Whether Escape key closes the drawer */
|
|
67
|
+
@property({ type: Boolean, attribute: "close-on-escape" })
|
|
68
|
+
closeOnEscape = true;
|
|
69
|
+
|
|
70
|
+
/** Whether clicking the overlay closes the drawer */
|
|
71
|
+
@property({ type: Boolean, attribute: "close-on-overlay" })
|
|
72
|
+
closeOnOverlay = true;
|
|
73
|
+
|
|
74
|
+
/** Whether to animate open/close transitions */
|
|
75
|
+
@property({ type: Boolean })
|
|
76
|
+
animated = true;
|
|
77
|
+
|
|
78
|
+
/** Whether the drawer is closing (for animation) */
|
|
79
|
+
@state()
|
|
80
|
+
private isClosing = false;
|
|
81
|
+
|
|
82
|
+
private dialogBehavior: DialogBehavior | null = null;
|
|
83
|
+
private presence: Presence | null = null;
|
|
84
|
+
|
|
85
|
+
override connectedCallback(): void {
|
|
86
|
+
super.connectedCallback();
|
|
87
|
+
|
|
88
|
+
// Listen for trigger clicks via event delegation
|
|
89
|
+
this.addEventListener("click", this.handleTriggerClick);
|
|
90
|
+
|
|
91
|
+
// Listen for close requests from child components
|
|
92
|
+
this.addEventListener("ds:drawer-close", this.handleCloseRequest as EventListener);
|
|
93
|
+
|
|
94
|
+
// Initialize dialog behavior
|
|
95
|
+
this.initDialogBehavior();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
override disconnectedCallback(): void {
|
|
99
|
+
super.disconnectedCallback();
|
|
100
|
+
this.removeEventListener("click", this.handleTriggerClick);
|
|
101
|
+
this.removeEventListener("ds:drawer-close", this.handleCloseRequest as EventListener);
|
|
102
|
+
this.cleanup();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Initializes the dialog behavior primitive.
|
|
107
|
+
*/
|
|
108
|
+
private initDialogBehavior(): void {
|
|
109
|
+
this.dialogBehavior = createDialogBehavior({
|
|
110
|
+
defaultOpen: this.open,
|
|
111
|
+
role: "dialog",
|
|
112
|
+
closeOnEscape: this.closeOnEscape,
|
|
113
|
+
closeOnOutsideClick: this.closeOnOverlay,
|
|
114
|
+
onOpenChange: (open) => {
|
|
115
|
+
// Sync state when behavior changes (e.g., from escape or outside click)
|
|
116
|
+
if (!open && this.open) {
|
|
117
|
+
this.handleBehaviorClose();
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Set trigger element if one exists
|
|
123
|
+
const trigger = this.querySelector('[slot="trigger"]') as HTMLElement | null;
|
|
124
|
+
if (trigger) {
|
|
125
|
+
this.dialogBehavior.setTriggerElement(trigger);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Handles close triggered by the behavior (escape/outside click).
|
|
131
|
+
*/
|
|
132
|
+
private handleBehaviorClose(): void {
|
|
133
|
+
const content = this.querySelector("ds-drawer-content") as DsDrawerContent | null;
|
|
134
|
+
|
|
135
|
+
// If animated, use presence for exit animation
|
|
136
|
+
if (this.animated && content && !prefersReducedMotion()) {
|
|
137
|
+
this.isClosing = true;
|
|
138
|
+
|
|
139
|
+
// Create presence for exit animation
|
|
140
|
+
this.presence = createPresence({
|
|
141
|
+
onExitComplete: () => {
|
|
142
|
+
this.completeClose();
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
this.presence.hide(content);
|
|
146
|
+
} else {
|
|
147
|
+
// No animation - close immediately
|
|
148
|
+
this.open = false;
|
|
149
|
+
this.isClosing = false;
|
|
150
|
+
emitEvent(this, StandardEvents.CLOSE);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Opens the drawer.
|
|
156
|
+
*/
|
|
157
|
+
public show(): void {
|
|
158
|
+
if (this.open) return;
|
|
159
|
+
|
|
160
|
+
// Store trigger element for focus return
|
|
161
|
+
const trigger = this.querySelector('[slot="trigger"]') as HTMLElement | null;
|
|
162
|
+
if (trigger) {
|
|
163
|
+
this.dialogBehavior?.setTriggerElement(trigger);
|
|
164
|
+
} else if (document.activeElement instanceof HTMLElement) {
|
|
165
|
+
this.dialogBehavior?.setTriggerElement(document.activeElement);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
this.open = true;
|
|
169
|
+
this.dialogBehavior?.open();
|
|
170
|
+
emitEvent(this, StandardEvents.OPEN);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Closes the drawer.
|
|
175
|
+
*/
|
|
176
|
+
public close(): void {
|
|
177
|
+
if (!this.open) return;
|
|
178
|
+
|
|
179
|
+
const content = this.querySelector("ds-drawer-content") as DsDrawerContent | null;
|
|
180
|
+
|
|
181
|
+
// Close the behavior (deactivates focus trap and dismiss layer)
|
|
182
|
+
this.dialogBehavior?.close();
|
|
183
|
+
|
|
184
|
+
// If animated, use presence for exit animation
|
|
185
|
+
if (this.animated && content && !prefersReducedMotion()) {
|
|
186
|
+
this.isClosing = true;
|
|
187
|
+
|
|
188
|
+
// Create presence for exit animation
|
|
189
|
+
this.presence = createPresence({
|
|
190
|
+
onExitComplete: () => {
|
|
191
|
+
this.completeClose();
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
this.presence.hide(content);
|
|
195
|
+
} else {
|
|
196
|
+
// No animation - close immediately
|
|
197
|
+
this.open = false;
|
|
198
|
+
this.isClosing = false;
|
|
199
|
+
emitEvent(this, StandardEvents.CLOSE);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Completes the close after exit animation.
|
|
205
|
+
*/
|
|
206
|
+
private completeClose(): void {
|
|
207
|
+
this.presence?.destroy();
|
|
208
|
+
this.presence = null;
|
|
209
|
+
this.open = false;
|
|
210
|
+
this.isClosing = false;
|
|
211
|
+
emitEvent(this, StandardEvents.CLOSE);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private handleTriggerClick = (event: Event): void => {
|
|
215
|
+
const target = event.target as HTMLElement;
|
|
216
|
+
const trigger = target.closest('[slot="trigger"]');
|
|
217
|
+
|
|
218
|
+
if (trigger && this.contains(trigger)) {
|
|
219
|
+
// Store trigger before opening
|
|
220
|
+
this.dialogBehavior?.setTriggerElement(trigger as HTMLElement);
|
|
221
|
+
this.show();
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
private handleCloseRequest = (): void => {
|
|
226
|
+
this.close();
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
private handleOverlayClick = (): void => {
|
|
230
|
+
if (this.closeOnOverlay) {
|
|
231
|
+
this.close();
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
private cleanup(): void {
|
|
236
|
+
this.dialogBehavior?.destroy();
|
|
237
|
+
this.dialogBehavior = null;
|
|
238
|
+
this.presence?.destroy();
|
|
239
|
+
this.presence = null;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
override async updated(changedProperties: Map<string, unknown>): Promise<void> {
|
|
243
|
+
super.updated(changedProperties);
|
|
244
|
+
|
|
245
|
+
if (changedProperties.has("open")) {
|
|
246
|
+
const content = this.querySelector("ds-drawer-content") as DsDrawerContent | null;
|
|
247
|
+
|
|
248
|
+
if (this.open) {
|
|
249
|
+
// Wait for the next microtask to ensure DOM is committed
|
|
250
|
+
await this.updateComplete;
|
|
251
|
+
|
|
252
|
+
// Set data-state to open for entry animation
|
|
253
|
+
if (content) {
|
|
254
|
+
content.dataState = "open";
|
|
255
|
+
content.side = this.side;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Set content element on behavior (activates focus trap and dismiss layer)
|
|
259
|
+
this.dialogBehavior?.setContentElement(content);
|
|
260
|
+
this.updateContentAccessibility();
|
|
261
|
+
} else {
|
|
262
|
+
// Clear content element on behavior
|
|
263
|
+
this.dialogBehavior?.setContentElement(null);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Sync behavior options when they change
|
|
268
|
+
if (changedProperties.has("closeOnEscape") || changedProperties.has("closeOnOverlay")) {
|
|
269
|
+
// Re-create behavior with new options
|
|
270
|
+
const wasOpen = this.dialogBehavior?.state.open;
|
|
271
|
+
this.dialogBehavior?.destroy();
|
|
272
|
+
this.initDialogBehavior();
|
|
273
|
+
if (wasOpen) {
|
|
274
|
+
this.dialogBehavior?.open();
|
|
275
|
+
const content = this.querySelector("ds-drawer-content") as HTMLElement | null;
|
|
276
|
+
this.dialogBehavior?.setContentElement(content);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Updates accessibility attributes on drawer content.
|
|
283
|
+
*/
|
|
284
|
+
private updateContentAccessibility(): void {
|
|
285
|
+
const content = this.querySelector("ds-drawer-content");
|
|
286
|
+
if (!content || !this.dialogBehavior) return;
|
|
287
|
+
|
|
288
|
+
// Get props from behavior
|
|
289
|
+
const contentProps = this.dialogBehavior.getContentProps();
|
|
290
|
+
|
|
291
|
+
// Set role on content
|
|
292
|
+
content.setAttribute("role", "dialog");
|
|
293
|
+
content.setAttribute("aria-modal", contentProps["aria-modal"]);
|
|
294
|
+
|
|
295
|
+
// Dev warning: Check for required drawer title
|
|
296
|
+
if (!hasRequiredChild(this, "ds-drawer-title") && !this.getAttribute("aria-label")) {
|
|
297
|
+
devWarn(Warnings.dialogMissingTitle("ds-drawer"));
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Connect title via aria-labelledby
|
|
301
|
+
const title = this.querySelector("ds-drawer-title");
|
|
302
|
+
if (title) {
|
|
303
|
+
const titleProps = this.dialogBehavior.getTitleProps();
|
|
304
|
+
if (!title.id) {
|
|
305
|
+
title.id = titleProps.id;
|
|
306
|
+
}
|
|
307
|
+
content.setAttribute("aria-labelledby", title.id);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Connect description via aria-describedby
|
|
311
|
+
const description = this.querySelector("ds-drawer-description");
|
|
312
|
+
if (description) {
|
|
313
|
+
const descProps = this.dialogBehavior.getDescriptionProps();
|
|
314
|
+
if (!description.id) {
|
|
315
|
+
description.id = descProps.id;
|
|
316
|
+
}
|
|
317
|
+
content.setAttribute("aria-describedby", description.id);
|
|
318
|
+
this.dialogBehavior.setHasDescription(true);
|
|
319
|
+
} else {
|
|
320
|
+
// Dev warning: Title without description
|
|
321
|
+
if (title) {
|
|
322
|
+
devWarn(Warnings.dialogMissingDescription("ds-drawer"));
|
|
323
|
+
}
|
|
324
|
+
this.dialogBehavior.setHasDescription(false);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
override render() {
|
|
329
|
+
return html`
|
|
330
|
+
<slot name="trigger"></slot>
|
|
331
|
+
<div
|
|
332
|
+
class="ds-drawer__overlay"
|
|
333
|
+
?hidden=${!this.open}
|
|
334
|
+
?data-closing=${this.isClosing}
|
|
335
|
+
@click=${this.handleOverlayClick}
|
|
336
|
+
></div>
|
|
337
|
+
<slot ?hidden=${!this.open}></slot>
|
|
338
|
+
`;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
define("ds-drawer", DsDrawer);
|
|
343
|
+
|
|
344
|
+
declare global {
|
|
345
|
+
interface HTMLElementTagNameMap {
|
|
346
|
+
"ds-drawer": DsDrawer;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drawer component exports.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { DsDrawer, type DrawerSide } from "./drawer.js";
|
|
6
|
+
export { DsDrawerContent } from "./drawer-content.js";
|
|
7
|
+
export { DsDrawerHeader } from "./drawer-header.js";
|
|
8
|
+
export { DsDrawerFooter } from "./drawer-footer.js";
|
|
9
|
+
export { DsDrawerTitle } from "./drawer-title.js";
|
|
10
|
+
export { DsDrawerDescription } from "./drawer-description.js";
|