@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,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sheet component - slide-in overlay panel from screen edge.
|
|
3
|
+
*
|
|
4
|
+
* Provides a modal overlay that slides in from any edge of the screen.
|
|
5
|
+
* Follows WAI-ARIA Dialog (Modal) pattern.
|
|
6
|
+
*
|
|
7
|
+
* @element ds-sheet
|
|
8
|
+
*
|
|
9
|
+
* @slot trigger - Button or element that opens the sheet
|
|
10
|
+
* @slot - Sheet content (ds-sheet-content)
|
|
11
|
+
*
|
|
12
|
+
* @fires ds:open - Fired when sheet opens
|
|
13
|
+
* @fires ds:close - Fired when sheet closes
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```html
|
|
17
|
+
* <ds-sheet>
|
|
18
|
+
* <button slot="trigger">Open Settings</button>
|
|
19
|
+
* <ds-sheet-content side="right">
|
|
20
|
+
* <ds-sheet-header>
|
|
21
|
+
* <ds-sheet-title>Settings</ds-sheet-title>
|
|
22
|
+
* <ds-sheet-description>Adjust your preferences</ds-sheet-description>
|
|
23
|
+
* </ds-sheet-header>
|
|
24
|
+
* <div>Settings content...</div>
|
|
25
|
+
* <ds-sheet-footer>
|
|
26
|
+
* <ds-sheet-close>Close</ds-sheet-close>
|
|
27
|
+
* </ds-sheet-footer>
|
|
28
|
+
* </ds-sheet-content>
|
|
29
|
+
* </ds-sheet>
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import {
|
|
34
|
+
type DialogBehavior,
|
|
35
|
+
type Presence,
|
|
36
|
+
createDialogBehavior,
|
|
37
|
+
createPresence,
|
|
38
|
+
prefersReducedMotion,
|
|
39
|
+
} from "@hypoth-ui/primitives-dom";
|
|
40
|
+
import { html } from "lit";
|
|
41
|
+
import { property, state } from "lit/decorators.js";
|
|
42
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
43
|
+
import { StandardEvents, emitEvent } from "../../events/emit.js";
|
|
44
|
+
import { define } from "../../registry/define.js";
|
|
45
|
+
import { devWarn, hasRequiredChild, Warnings } from "../../utils/dev-warnings.js";
|
|
46
|
+
|
|
47
|
+
// Import child components to ensure they're registered
|
|
48
|
+
import type { DsSheetContent } from "./sheet-content.js";
|
|
49
|
+
import "./sheet-content.js";
|
|
50
|
+
import "./sheet-overlay.js";
|
|
51
|
+
import "./sheet-header.js";
|
|
52
|
+
import "./sheet-footer.js";
|
|
53
|
+
import "./sheet-title.js";
|
|
54
|
+
import "./sheet-description.js";
|
|
55
|
+
import "./sheet-close.js";
|
|
56
|
+
|
|
57
|
+
export class DsSheet extends DSElement {
|
|
58
|
+
/** Whether the sheet is open */
|
|
59
|
+
@property({ type: Boolean, reflect: true })
|
|
60
|
+
open = false;
|
|
61
|
+
|
|
62
|
+
/** Whether Escape key closes the sheet */
|
|
63
|
+
@property({ type: Boolean, attribute: "close-on-escape" })
|
|
64
|
+
closeOnEscape = true;
|
|
65
|
+
|
|
66
|
+
/** Whether clicking the overlay closes the sheet */
|
|
67
|
+
@property({ type: Boolean, attribute: "close-on-overlay" })
|
|
68
|
+
closeOnOverlay = true;
|
|
69
|
+
|
|
70
|
+
/** Whether to animate open/close transitions */
|
|
71
|
+
@property({ type: Boolean })
|
|
72
|
+
animated = true;
|
|
73
|
+
|
|
74
|
+
/** Whether the sheet is closing (for animation) */
|
|
75
|
+
@state()
|
|
76
|
+
private isClosing = false;
|
|
77
|
+
|
|
78
|
+
private dialogBehavior: DialogBehavior | null = null;
|
|
79
|
+
private presence: Presence | null = null;
|
|
80
|
+
|
|
81
|
+
override connectedCallback(): void {
|
|
82
|
+
super.connectedCallback();
|
|
83
|
+
|
|
84
|
+
// Listen for trigger clicks via event delegation
|
|
85
|
+
this.addEventListener("click", this.handleTriggerClick);
|
|
86
|
+
|
|
87
|
+
// Listen for close requests from child components
|
|
88
|
+
this.addEventListener("ds:sheet-close", this.handleCloseRequest as EventListener);
|
|
89
|
+
|
|
90
|
+
// Initialize dialog behavior
|
|
91
|
+
this.initDialogBehavior();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
override disconnectedCallback(): void {
|
|
95
|
+
super.disconnectedCallback();
|
|
96
|
+
this.removeEventListener("click", this.handleTriggerClick);
|
|
97
|
+
this.removeEventListener("ds:sheet-close", this.handleCloseRequest as EventListener);
|
|
98
|
+
this.cleanup();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Initializes the dialog behavior primitive.
|
|
103
|
+
*/
|
|
104
|
+
private initDialogBehavior(): void {
|
|
105
|
+
this.dialogBehavior = createDialogBehavior({
|
|
106
|
+
defaultOpen: this.open,
|
|
107
|
+
role: "dialog",
|
|
108
|
+
closeOnEscape: this.closeOnEscape,
|
|
109
|
+
closeOnOutsideClick: this.closeOnOverlay,
|
|
110
|
+
onOpenChange: (open) => {
|
|
111
|
+
// Sync state when behavior changes (e.g., from escape or outside click)
|
|
112
|
+
if (!open && this.open) {
|
|
113
|
+
this.handleBehaviorClose();
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Set trigger element if one exists
|
|
119
|
+
const trigger = this.querySelector('[slot="trigger"]') as HTMLElement | null;
|
|
120
|
+
if (trigger) {
|
|
121
|
+
this.dialogBehavior.setTriggerElement(trigger);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Handles close triggered by the behavior (escape/outside click).
|
|
127
|
+
*/
|
|
128
|
+
private handleBehaviorClose(): void {
|
|
129
|
+
const content = this.querySelector("ds-sheet-content") as DsSheetContent | null;
|
|
130
|
+
|
|
131
|
+
// If animated, use presence for exit animation
|
|
132
|
+
if (this.animated && content && !prefersReducedMotion()) {
|
|
133
|
+
this.isClosing = true;
|
|
134
|
+
|
|
135
|
+
// Create presence for exit animation
|
|
136
|
+
this.presence = createPresence({
|
|
137
|
+
onExitComplete: () => {
|
|
138
|
+
this.completeClose();
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
this.presence.hide(content);
|
|
142
|
+
} else {
|
|
143
|
+
// No animation - close immediately
|
|
144
|
+
this.open = false;
|
|
145
|
+
this.isClosing = false;
|
|
146
|
+
emitEvent(this, StandardEvents.CLOSE);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Opens the sheet.
|
|
152
|
+
*/
|
|
153
|
+
public show(): void {
|
|
154
|
+
if (this.open) return;
|
|
155
|
+
|
|
156
|
+
// Store trigger element for focus return
|
|
157
|
+
const trigger = this.querySelector('[slot="trigger"]') as HTMLElement | null;
|
|
158
|
+
if (trigger) {
|
|
159
|
+
this.dialogBehavior?.setTriggerElement(trigger);
|
|
160
|
+
} else if (document.activeElement instanceof HTMLElement) {
|
|
161
|
+
this.dialogBehavior?.setTriggerElement(document.activeElement);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.open = true;
|
|
165
|
+
this.dialogBehavior?.open();
|
|
166
|
+
emitEvent(this, StandardEvents.OPEN);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Closes the sheet.
|
|
171
|
+
*/
|
|
172
|
+
public close(): void {
|
|
173
|
+
if (!this.open) return;
|
|
174
|
+
|
|
175
|
+
const content = this.querySelector("ds-sheet-content") as DsSheetContent | null;
|
|
176
|
+
|
|
177
|
+
// Close the behavior (deactivates focus trap and dismiss layer)
|
|
178
|
+
this.dialogBehavior?.close();
|
|
179
|
+
|
|
180
|
+
// If animated, use presence for exit animation
|
|
181
|
+
if (this.animated && content && !prefersReducedMotion()) {
|
|
182
|
+
this.isClosing = true;
|
|
183
|
+
|
|
184
|
+
// Create presence for exit animation
|
|
185
|
+
this.presence = createPresence({
|
|
186
|
+
onExitComplete: () => {
|
|
187
|
+
this.completeClose();
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
this.presence.hide(content);
|
|
191
|
+
} else {
|
|
192
|
+
// No animation - close immediately
|
|
193
|
+
this.open = false;
|
|
194
|
+
this.isClosing = false;
|
|
195
|
+
emitEvent(this, StandardEvents.CLOSE);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Completes the close after exit animation.
|
|
201
|
+
*/
|
|
202
|
+
private completeClose(): void {
|
|
203
|
+
this.presence?.destroy();
|
|
204
|
+
this.presence = null;
|
|
205
|
+
this.open = false;
|
|
206
|
+
this.isClosing = false;
|
|
207
|
+
emitEvent(this, StandardEvents.CLOSE);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private handleTriggerClick = (event: Event): void => {
|
|
211
|
+
const target = event.target as HTMLElement;
|
|
212
|
+
const trigger = target.closest('[slot="trigger"]');
|
|
213
|
+
|
|
214
|
+
if (trigger && this.contains(trigger)) {
|
|
215
|
+
// Store trigger before opening
|
|
216
|
+
this.dialogBehavior?.setTriggerElement(trigger as HTMLElement);
|
|
217
|
+
this.show();
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
private handleCloseRequest = (): void => {
|
|
222
|
+
this.close();
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
private cleanup(): void {
|
|
226
|
+
this.dialogBehavior?.destroy();
|
|
227
|
+
this.dialogBehavior = null;
|
|
228
|
+
this.presence?.destroy();
|
|
229
|
+
this.presence = null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
override async updated(changedProperties: Map<string, unknown>): Promise<void> {
|
|
233
|
+
super.updated(changedProperties);
|
|
234
|
+
|
|
235
|
+
if (changedProperties.has("open")) {
|
|
236
|
+
const content = this.querySelector("ds-sheet-content") as DsSheetContent | null;
|
|
237
|
+
|
|
238
|
+
if (this.open) {
|
|
239
|
+
// Wait for the next microtask to ensure DOM is committed
|
|
240
|
+
await this.updateComplete;
|
|
241
|
+
|
|
242
|
+
// Set data-state to open for entry animation
|
|
243
|
+
if (content) {
|
|
244
|
+
content.dataState = "open";
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Set content element on behavior (activates focus trap and dismiss layer)
|
|
248
|
+
this.dialogBehavior?.setContentElement(content);
|
|
249
|
+
this.updateContentAccessibility();
|
|
250
|
+
} else {
|
|
251
|
+
// Clear content element on behavior
|
|
252
|
+
this.dialogBehavior?.setContentElement(null);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Sync behavior options when they change
|
|
257
|
+
if (changedProperties.has("closeOnEscape") || changedProperties.has("closeOnOverlay")) {
|
|
258
|
+
// Re-create behavior with new options
|
|
259
|
+
const wasOpen = this.dialogBehavior?.state.open;
|
|
260
|
+
this.dialogBehavior?.destroy();
|
|
261
|
+
this.initDialogBehavior();
|
|
262
|
+
if (wasOpen) {
|
|
263
|
+
this.dialogBehavior?.open();
|
|
264
|
+
const content = this.querySelector("ds-sheet-content") as HTMLElement | null;
|
|
265
|
+
this.dialogBehavior?.setContentElement(content);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Updates accessibility attributes on sheet content.
|
|
272
|
+
*/
|
|
273
|
+
private updateContentAccessibility(): void {
|
|
274
|
+
const content = this.querySelector("ds-sheet-content");
|
|
275
|
+
if (!content || !this.dialogBehavior) return;
|
|
276
|
+
|
|
277
|
+
// Get props from behavior
|
|
278
|
+
const contentProps = this.dialogBehavior.getContentProps();
|
|
279
|
+
|
|
280
|
+
// Set role on content
|
|
281
|
+
content.setAttribute("role", "dialog");
|
|
282
|
+
content.setAttribute("aria-modal", contentProps["aria-modal"]);
|
|
283
|
+
|
|
284
|
+
// Dev warning: Check for required sheet title
|
|
285
|
+
if (!hasRequiredChild(this, "ds-sheet-title") && !this.getAttribute("aria-label")) {
|
|
286
|
+
devWarn(Warnings.dialogMissingTitle("ds-sheet"));
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Connect title via aria-labelledby
|
|
290
|
+
const title = this.querySelector("ds-sheet-title");
|
|
291
|
+
if (title) {
|
|
292
|
+
const titleProps = this.dialogBehavior.getTitleProps();
|
|
293
|
+
if (!title.id) {
|
|
294
|
+
title.id = titleProps.id;
|
|
295
|
+
}
|
|
296
|
+
content.setAttribute("aria-labelledby", title.id);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Connect description via aria-describedby
|
|
300
|
+
const description = this.querySelector("ds-sheet-description");
|
|
301
|
+
if (description) {
|
|
302
|
+
const descProps = this.dialogBehavior.getDescriptionProps();
|
|
303
|
+
if (!description.id) {
|
|
304
|
+
description.id = descProps.id;
|
|
305
|
+
}
|
|
306
|
+
content.setAttribute("aria-describedby", description.id);
|
|
307
|
+
this.dialogBehavior.setHasDescription(true);
|
|
308
|
+
} else {
|
|
309
|
+
// Dev warning: Title without description
|
|
310
|
+
if (title) {
|
|
311
|
+
devWarn(Warnings.dialogMissingDescription("ds-sheet"));
|
|
312
|
+
}
|
|
313
|
+
this.dialogBehavior.setHasDescription(false);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
override render() {
|
|
318
|
+
return html`
|
|
319
|
+
<slot name="trigger"></slot>
|
|
320
|
+
<ds-sheet-overlay
|
|
321
|
+
?hidden=${!this.open}
|
|
322
|
+
?data-closing=${this.isClosing}
|
|
323
|
+
@click=${this.closeOnOverlay ? this.handleCloseRequest : undefined}
|
|
324
|
+
></ds-sheet-overlay>
|
|
325
|
+
<slot ?hidden=${!this.open}></slot>
|
|
326
|
+
`;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
define("ds-sheet", DsSheet);
|
|
331
|
+
|
|
332
|
+
declare global {
|
|
333
|
+
interface HTMLElementTagNameMap {
|
|
334
|
+
"ds-sheet": DsSheet;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type HTMLAttributes, createElement, forwardRef } from "react";
|
|
4
|
+
import "@hypoth-ui/wc";
|
|
5
|
+
import {
|
|
6
|
+
type ResponsiveProp,
|
|
7
|
+
generateResponsiveDataAttr,
|
|
8
|
+
isResponsiveObject,
|
|
9
|
+
resolveResponsiveValue,
|
|
10
|
+
} from "../../primitives/responsive.js";
|
|
11
|
+
|
|
12
|
+
export type SkeletonVariant = "text" | "circular" | "rectangular" | "rounded";
|
|
13
|
+
export type SkeletonSize = "xs" | "sm" | "md" | "lg" | "xl";
|
|
14
|
+
export type SkeletonWidth = "full" | "3/4" | "1/2" | "1/4";
|
|
15
|
+
export type SkeletonAnimation = "wave" | "pulse" | "none";
|
|
16
|
+
|
|
17
|
+
export interface SkeletonProps extends Omit<HTMLAttributes<HTMLElement>, "children"> {
|
|
18
|
+
/**
|
|
19
|
+
* Shape variant.
|
|
20
|
+
* @default "text"
|
|
21
|
+
*/
|
|
22
|
+
variant?: SkeletonVariant;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Size preset for height - supports responsive object syntax.
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* // Single value
|
|
29
|
+
* <Skeleton size="md" />
|
|
30
|
+
*
|
|
31
|
+
* // Responsive
|
|
32
|
+
* <Skeleton size={{ base: "sm", md: "lg" }} />
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
size?: ResponsiveProp<SkeletonSize>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Width preset.
|
|
39
|
+
*/
|
|
40
|
+
width?: SkeletonWidth;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Custom width (CSS value).
|
|
44
|
+
*/
|
|
45
|
+
customWidth?: string;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Custom height (CSS value).
|
|
49
|
+
*/
|
|
50
|
+
customHeight?: string;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Animation type.
|
|
54
|
+
* @default "wave"
|
|
55
|
+
*/
|
|
56
|
+
animation?: SkeletonAnimation;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Accessible label for screen readers.
|
|
60
|
+
* @default "Loading..."
|
|
61
|
+
*/
|
|
62
|
+
label?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Skeleton loading placeholder component for content that is loading.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* // Text skeleton
|
|
71
|
+
* <Skeleton variant="text" width="3/4" />
|
|
72
|
+
*
|
|
73
|
+
* // Circular avatar skeleton
|
|
74
|
+
* <Skeleton variant="circular" customWidth="40px" customHeight="40px" />
|
|
75
|
+
*
|
|
76
|
+
* // Card skeleton layout
|
|
77
|
+
* <div className="space-y-2">
|
|
78
|
+
* <Skeleton variant="rectangular" customHeight="200px" />
|
|
79
|
+
* <Skeleton variant="text" width="1/2" />
|
|
80
|
+
* <Skeleton variant="text" />
|
|
81
|
+
* <Skeleton variant="text" width="3/4" />
|
|
82
|
+
* </div>
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export const Skeleton = forwardRef<HTMLElement, SkeletonProps>(function Skeleton(
|
|
86
|
+
{
|
|
87
|
+
variant = "text",
|
|
88
|
+
size,
|
|
89
|
+
width,
|
|
90
|
+
customWidth,
|
|
91
|
+
customHeight,
|
|
92
|
+
animation = "wave",
|
|
93
|
+
label = "Loading...",
|
|
94
|
+
className,
|
|
95
|
+
...props
|
|
96
|
+
},
|
|
97
|
+
ref
|
|
98
|
+
) {
|
|
99
|
+
// Resolve responsive size - use base value for the WC attribute
|
|
100
|
+
const resolvedSize = size ? resolveResponsiveValue(size, "md") : undefined;
|
|
101
|
+
const isResponsive = size ? isResponsiveObject(size) : false;
|
|
102
|
+
const responsiveSizeAttr = isResponsive && size ? generateResponsiveDataAttr(size) : undefined;
|
|
103
|
+
|
|
104
|
+
return createElement("ds-skeleton", {
|
|
105
|
+
ref,
|
|
106
|
+
variant,
|
|
107
|
+
size: resolvedSize,
|
|
108
|
+
width,
|
|
109
|
+
"custom-width": customWidth,
|
|
110
|
+
"custom-height": customHeight,
|
|
111
|
+
animation,
|
|
112
|
+
label,
|
|
113
|
+
class: className,
|
|
114
|
+
// Add responsive data attribute for CSS targeting
|
|
115
|
+
"data-size-responsive": responsiveSizeAttr,
|
|
116
|
+
...props,
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// TypeScript declaration for JSX
|
|
121
|
+
declare global {
|
|
122
|
+
namespace JSX {
|
|
123
|
+
interface IntrinsicElements {
|
|
124
|
+
"ds-skeleton": SkeletonProps & {
|
|
125
|
+
ref?: React.Ref<HTMLElement>;
|
|
126
|
+
"custom-width"?: string;
|
|
127
|
+
"custom-height"?: string;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type TemplateResult, html, nothing } from "lit";
|
|
2
|
+
import { property } from "lit/decorators.js";
|
|
3
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
4
|
+
import { styleMap } from "lit/directives/style-map.js";
|
|
5
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
6
|
+
import { define } from "../../registry/define.js";
|
|
7
|
+
|
|
8
|
+
export type SkeletonVariant = "text" | "circular" | "rectangular" | "rounded";
|
|
9
|
+
export type SkeletonSize = "xs" | "sm" | "md" | "lg" | "xl";
|
|
10
|
+
export type SkeletonWidth = "full" | "3/4" | "1/2" | "1/4";
|
|
11
|
+
export type SkeletonAnimation = "wave" | "pulse" | "none";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Skeleton loading placeholder component.
|
|
15
|
+
*
|
|
16
|
+
* @element ds-skeleton
|
|
17
|
+
*
|
|
18
|
+
* @cssprop --ds-skeleton-bg - Background color
|
|
19
|
+
* @cssprop --ds-skeleton-highlight - Shimmer highlight color
|
|
20
|
+
* @cssprop --ds-skeleton-radius - Border radius
|
|
21
|
+
*/
|
|
22
|
+
export class DsSkeleton extends DSElement {
|
|
23
|
+
static override styles = [];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Shape variant.
|
|
27
|
+
*/
|
|
28
|
+
@property({ type: String, reflect: true })
|
|
29
|
+
variant: SkeletonVariant = "text";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Size preset for height.
|
|
33
|
+
*/
|
|
34
|
+
@property({ type: String, reflect: true })
|
|
35
|
+
size?: SkeletonSize;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Width preset.
|
|
39
|
+
*/
|
|
40
|
+
@property({ type: String, reflect: true })
|
|
41
|
+
width?: SkeletonWidth;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Custom width (CSS value).
|
|
45
|
+
*/
|
|
46
|
+
@property({ type: String, attribute: "custom-width" })
|
|
47
|
+
customWidth = "";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Custom height (CSS value).
|
|
51
|
+
*/
|
|
52
|
+
@property({ type: String, attribute: "custom-height" })
|
|
53
|
+
customHeight = "";
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Animation type.
|
|
57
|
+
*/
|
|
58
|
+
@property({ type: String, reflect: true })
|
|
59
|
+
animation: SkeletonAnimation = "wave";
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Accessible label for screen readers.
|
|
63
|
+
*/
|
|
64
|
+
@property({ type: String })
|
|
65
|
+
label = "Loading...";
|
|
66
|
+
|
|
67
|
+
override render(): TemplateResult {
|
|
68
|
+
const classes = {
|
|
69
|
+
"ds-skeleton": true,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const styles: Record<string, string> = {};
|
|
73
|
+
if (this.customWidth) {
|
|
74
|
+
styles.width = this.customWidth;
|
|
75
|
+
}
|
|
76
|
+
if (this.customHeight) {
|
|
77
|
+
styles.height = this.customHeight;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return html`
|
|
81
|
+
<div
|
|
82
|
+
class=${classMap(classes)}
|
|
83
|
+
role="status"
|
|
84
|
+
aria-busy="true"
|
|
85
|
+
aria-label=${this.label}
|
|
86
|
+
data-variant=${this.variant}
|
|
87
|
+
data-size=${this.size || nothing}
|
|
88
|
+
data-width=${!this.customWidth && this.width ? this.width : nothing}
|
|
89
|
+
data-animation=${this.animation}
|
|
90
|
+
?data-no-animation=${this.animation === "none"}
|
|
91
|
+
style=${Object.keys(styles).length > 0 ? styleMap(styles) : nothing}
|
|
92
|
+
>
|
|
93
|
+
<span class="ds-visually-hidden">${this.label}</span>
|
|
94
|
+
</div>
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Register the component
|
|
100
|
+
define("ds-skeleton", DsSkeleton);
|
|
101
|
+
|
|
102
|
+
// TypeScript declaration for HTML
|
|
103
|
+
declare global {
|
|
104
|
+
interface HTMLElementTagNameMap {
|
|
105
|
+
"ds-skeleton": DsSkeleton;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slider compound component for numeric value selection.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```tsx
|
|
6
|
+
* // Single value slider
|
|
7
|
+
* <Slider.Root min={0} max={100} onValueChange={(v) => console.log(v)}>
|
|
8
|
+
* <Slider.Track className="slider-track">
|
|
9
|
+
* <Slider.Range className="slider-range" />
|
|
10
|
+
* <Slider.Thumb className="slider-thumb" />
|
|
11
|
+
* </Slider.Track>
|
|
12
|
+
* </Slider.Root>
|
|
13
|
+
*
|
|
14
|
+
* // Range slider
|
|
15
|
+
* <Slider.Root range min={0} max={1000} onRangeChange={(r) => console.log(r)}>
|
|
16
|
+
* <Slider.Track className="slider-track">
|
|
17
|
+
* <Slider.Range className="slider-range" />
|
|
18
|
+
* <Slider.Thumb type="min" aria-label="Minimum" />
|
|
19
|
+
* <Slider.Thumb type="max" aria-label="Maximum" />
|
|
20
|
+
* </Slider.Track>
|
|
21
|
+
* </Slider.Root>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export { SliderRoot, type SliderRootProps } from "./slider-root.js";
|
|
26
|
+
export { SliderTrack, type SliderTrackProps } from "./slider-track.js";
|
|
27
|
+
export { SliderRange, type SliderRangeProps } from "./slider-range.js";
|
|
28
|
+
export { SliderThumb, type SliderThumbProps } from "./slider-thumb.js";
|
|
29
|
+
export { useSliderContext, type SliderContextValue } from "./slider-context.js";
|
|
30
|
+
|
|
31
|
+
export const Slider = {
|
|
32
|
+
Root: SliderRoot,
|
|
33
|
+
Track: SliderTrack,
|
|
34
|
+
Range: SliderRange,
|
|
35
|
+
Thumb: SliderThumb,
|
|
36
|
+
} as const;
|
|
37
|
+
|
|
38
|
+
import { SliderRange } from "./slider-range.js";
|
|
39
|
+
import { SliderRoot } from "./slider-root.js";
|
|
40
|
+
import { SliderThumb } from "./slider-thumb.js";
|
|
41
|
+
import { SliderTrack } from "./slider-track.js";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slider context for compound component pattern.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { SliderBehavior } from "@hypoth-ui/primitives-dom";
|
|
6
|
+
import { createCompoundContext } from "../../utils/create-context.js";
|
|
7
|
+
|
|
8
|
+
export interface SliderContextValue {
|
|
9
|
+
/** Slider behavior instance */
|
|
10
|
+
behavior: SliderBehavior;
|
|
11
|
+
/** Current value (single mode) */
|
|
12
|
+
value: number;
|
|
13
|
+
/** Set value (single mode) */
|
|
14
|
+
setValue: (value: number) => void;
|
|
15
|
+
/** Range values */
|
|
16
|
+
rangeValue: { min: number; max: number };
|
|
17
|
+
/** Set range values */
|
|
18
|
+
setRangeValue: (range: { min: number; max: number }) => void;
|
|
19
|
+
/** Whether in range mode */
|
|
20
|
+
range: boolean;
|
|
21
|
+
/** Min constraint */
|
|
22
|
+
min: number;
|
|
23
|
+
/** Max constraint */
|
|
24
|
+
max: number;
|
|
25
|
+
/** Step increment */
|
|
26
|
+
step: number;
|
|
27
|
+
/** Orientation */
|
|
28
|
+
orientation: "horizontal" | "vertical";
|
|
29
|
+
/** Disabled state */
|
|
30
|
+
disabled: boolean;
|
|
31
|
+
/** Value text formatter */
|
|
32
|
+
formatValueText?: (value: number) => string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const [SliderProvider, useSliderContext] =
|
|
36
|
+
createCompoundContext<SliderContextValue>("Slider");
|