@hypoth-ui/cli 0.0.1 → 0.1.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 +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,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accordion component - collapsible sections for organizing content.
|
|
3
|
+
*
|
|
4
|
+
* Implements WAI-ARIA Accordion pattern with keyboard navigation.
|
|
5
|
+
*
|
|
6
|
+
* @element ds-accordion
|
|
7
|
+
*
|
|
8
|
+
* @slot - Accordion items (ds-accordion-item)
|
|
9
|
+
*
|
|
10
|
+
* @fires ds:change - Fired when expanded items change
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```html
|
|
14
|
+
* <ds-accordion type="single" default-value="item-1" collapsible>
|
|
15
|
+
* <ds-accordion-item value="item-1">
|
|
16
|
+
* <ds-accordion-trigger>Section 1</ds-accordion-trigger>
|
|
17
|
+
* <ds-accordion-content>Content 1</ds-accordion-content>
|
|
18
|
+
* </ds-accordion-item>
|
|
19
|
+
* <ds-accordion-item value="item-2">
|
|
20
|
+
* <ds-accordion-trigger>Section 2</ds-accordion-trigger>
|
|
21
|
+
* <ds-accordion-content>Content 2</ds-accordion-content>
|
|
22
|
+
* </ds-accordion-item>
|
|
23
|
+
* </ds-accordion>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { type RovingFocus, createRovingFocus } from "@hypoth-ui/primitives-dom";
|
|
28
|
+
import { html } from "lit";
|
|
29
|
+
import { property, state } from "lit/decorators.js";
|
|
30
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
31
|
+
import { emitEvent } from "../../events/emit.js";
|
|
32
|
+
import { define } from "../../registry/define.js";
|
|
33
|
+
|
|
34
|
+
// Import child components
|
|
35
|
+
import type { DsAccordionItem } from "./accordion-item.js";
|
|
36
|
+
import "./accordion-item.js";
|
|
37
|
+
import "./accordion-trigger.js";
|
|
38
|
+
import "./accordion-content.js";
|
|
39
|
+
|
|
40
|
+
export type AccordionType = "single" | "multiple";
|
|
41
|
+
export type AccordionOrientation = "horizontal" | "vertical";
|
|
42
|
+
|
|
43
|
+
export class DsAccordion extends DSElement {
|
|
44
|
+
/** Type: single (one open) or multiple (many open) */
|
|
45
|
+
@property({ reflect: true })
|
|
46
|
+
type: AccordionType = "single";
|
|
47
|
+
|
|
48
|
+
/** Controlled value (string for single, JSON array for multiple) */
|
|
49
|
+
@property()
|
|
50
|
+
value: string | undefined;
|
|
51
|
+
|
|
52
|
+
/** Default value (string for single, JSON array for multiple) */
|
|
53
|
+
@property({ attribute: "default-value" })
|
|
54
|
+
defaultValue: string | undefined;
|
|
55
|
+
|
|
56
|
+
/** Allow collapsing all items in single mode */
|
|
57
|
+
@property({ type: Boolean, reflect: true })
|
|
58
|
+
collapsible = false;
|
|
59
|
+
|
|
60
|
+
/** Keyboard navigation orientation */
|
|
61
|
+
@property({ reflect: true })
|
|
62
|
+
orientation: AccordionOrientation = "vertical";
|
|
63
|
+
|
|
64
|
+
/** Internal tracked value(s) */
|
|
65
|
+
@state()
|
|
66
|
+
private internalValue: Set<string> = new Set();
|
|
67
|
+
|
|
68
|
+
private rovingFocus: RovingFocus | null = null;
|
|
69
|
+
|
|
70
|
+
/** Whether we're in controlled mode */
|
|
71
|
+
private get isControlled(): boolean {
|
|
72
|
+
return this.value !== undefined;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Current expanded values */
|
|
76
|
+
get expandedValues(): Set<string> {
|
|
77
|
+
if (this.isControlled) {
|
|
78
|
+
return this.parseValue(this.value);
|
|
79
|
+
}
|
|
80
|
+
return this.internalValue;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private parseValue(value: string | undefined): Set<string> {
|
|
84
|
+
if (!value) return new Set();
|
|
85
|
+
|
|
86
|
+
// Try parsing as JSON array
|
|
87
|
+
if (value.startsWith("[")) {
|
|
88
|
+
try {
|
|
89
|
+
const arr = JSON.parse(value);
|
|
90
|
+
return new Set(Array.isArray(arr) ? arr : []);
|
|
91
|
+
} catch {
|
|
92
|
+
return new Set();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Single value
|
|
97
|
+
return new Set([value]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
override connectedCallback(): void {
|
|
101
|
+
super.connectedCallback();
|
|
102
|
+
|
|
103
|
+
// Initialize internal value from default
|
|
104
|
+
if (!this.isControlled && this.defaultValue) {
|
|
105
|
+
this.internalValue = this.parseValue(this.defaultValue);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Listen for item toggle events
|
|
109
|
+
this.addEventListener("ds:accordion-toggle", this.handleItemToggle as EventListener);
|
|
110
|
+
|
|
111
|
+
// Setup roving focus after DOM is ready
|
|
112
|
+
requestAnimationFrame(() => {
|
|
113
|
+
this.setupRovingFocus();
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
override disconnectedCallback(): void {
|
|
118
|
+
super.disconnectedCallback();
|
|
119
|
+
this.removeEventListener("ds:accordion-toggle", this.handleItemToggle as EventListener);
|
|
120
|
+
this.rovingFocus?.destroy();
|
|
121
|
+
this.rovingFocus = null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private setupRovingFocus(): void {
|
|
125
|
+
this.rovingFocus = createRovingFocus({
|
|
126
|
+
container: this,
|
|
127
|
+
selector: "ds-accordion-trigger:not([aria-disabled='true'])",
|
|
128
|
+
direction: this.orientation,
|
|
129
|
+
loop: true,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Toggle an item's expanded state.
|
|
135
|
+
*/
|
|
136
|
+
public toggleItem(value: string): void {
|
|
137
|
+
const items = this.querySelectorAll("ds-accordion-item") as NodeListOf<DsAccordionItem>;
|
|
138
|
+
const item = Array.from(items).find((i) => i.value === value);
|
|
139
|
+
if (!item || item.disabled) return;
|
|
140
|
+
|
|
141
|
+
const currentExpanded = this.expandedValues;
|
|
142
|
+
const isExpanded = currentExpanded.has(value);
|
|
143
|
+
|
|
144
|
+
let newValue: Set<string>;
|
|
145
|
+
|
|
146
|
+
if (this.type === "single") {
|
|
147
|
+
if (isExpanded) {
|
|
148
|
+
// Collapse if collapsible is true
|
|
149
|
+
newValue = this.collapsible ? new Set() : currentExpanded;
|
|
150
|
+
} else {
|
|
151
|
+
// Expand this item (collapse others)
|
|
152
|
+
newValue = new Set([value]);
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
// Multiple mode
|
|
156
|
+
newValue = new Set(currentExpanded);
|
|
157
|
+
if (isExpanded) {
|
|
158
|
+
newValue.delete(value);
|
|
159
|
+
} else {
|
|
160
|
+
newValue.add(value);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Update state
|
|
165
|
+
if (!this.isControlled) {
|
|
166
|
+
this.internalValue = newValue;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Emit change event
|
|
170
|
+
const eventValue =
|
|
171
|
+
this.type === "single"
|
|
172
|
+
? (Array.from(newValue)[0] ?? "")
|
|
173
|
+
: JSON.stringify(Array.from(newValue));
|
|
174
|
+
|
|
175
|
+
emitEvent(this, "ds:change", { detail: { value: eventValue } });
|
|
176
|
+
this.updateItems();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private handleItemToggle = (event: CustomEvent<{ value: string }>): void => {
|
|
180
|
+
this.toggleItem(event.detail.value);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
override updated(changedProperties: Map<string, unknown>): void {
|
|
184
|
+
if (
|
|
185
|
+
changedProperties.has("value") ||
|
|
186
|
+
changedProperties.has("internalValue") ||
|
|
187
|
+
changedProperties.has("defaultValue")
|
|
188
|
+
) {
|
|
189
|
+
this.updateItems();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private updateItems(): void {
|
|
194
|
+
const expanded = this.expandedValues;
|
|
195
|
+
|
|
196
|
+
const items = this.querySelectorAll("ds-accordion-item") as NodeListOf<DsAccordionItem>;
|
|
197
|
+
for (const item of items) {
|
|
198
|
+
item.setExpanded(expanded.has(item.value));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
override render() {
|
|
203
|
+
return html`<slot></slot>`;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
define("ds-accordion", DsAccordion);
|
|
208
|
+
|
|
209
|
+
declare global {
|
|
210
|
+
interface HTMLElementTagNameMap {
|
|
211
|
+
"ds-accordion": DsAccordion;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accordion component barrel exports.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
DsAccordion,
|
|
7
|
+
type AccordionType,
|
|
8
|
+
type AccordionOrientation,
|
|
9
|
+
} from "./accordion.js";
|
|
10
|
+
export { DsAccordionItem } from "./accordion-item.js";
|
|
11
|
+
export { DsAccordionTrigger } from "./accordion-trigger.js";
|
|
12
|
+
export { DsAccordionContent } from "./accordion-content.js";
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Alert React Component
|
|
5
|
+
*
|
|
6
|
+
* Contextual feedback messages for user notifications.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { type HTMLAttributes, type ReactNode, forwardRef, useCallback } from "react";
|
|
10
|
+
|
|
11
|
+
export type AlertVariant = "info" | "success" | "warning" | "error";
|
|
12
|
+
|
|
13
|
+
export interface AlertProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
|
|
14
|
+
/** Visual variant */
|
|
15
|
+
variant?: AlertVariant;
|
|
16
|
+
/** Alert title */
|
|
17
|
+
title?: string;
|
|
18
|
+
/** Whether the alert can be closed */
|
|
19
|
+
closable?: boolean;
|
|
20
|
+
/** Hide the default icon */
|
|
21
|
+
hideIcon?: boolean;
|
|
22
|
+
/** Custom icon element */
|
|
23
|
+
icon?: ReactNode;
|
|
24
|
+
/** Action slot content */
|
|
25
|
+
action?: ReactNode;
|
|
26
|
+
/** Callback when close button is clicked */
|
|
27
|
+
onClose?: () => void;
|
|
28
|
+
/** Alert content/description */
|
|
29
|
+
children?: ReactNode;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* SVG icons for different alert variants
|
|
34
|
+
*/
|
|
35
|
+
const VARIANT_ICONS: Record<AlertVariant, ReactNode> = {
|
|
36
|
+
info: (
|
|
37
|
+
<svg className="ds-alert__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
38
|
+
<path
|
|
39
|
+
fillRule="evenodd"
|
|
40
|
+
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z"
|
|
41
|
+
clipRule="evenodd"
|
|
42
|
+
/>
|
|
43
|
+
</svg>
|
|
44
|
+
),
|
|
45
|
+
success: (
|
|
46
|
+
<svg className="ds-alert__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
47
|
+
<path
|
|
48
|
+
fillRule="evenodd"
|
|
49
|
+
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z"
|
|
50
|
+
clipRule="evenodd"
|
|
51
|
+
/>
|
|
52
|
+
</svg>
|
|
53
|
+
),
|
|
54
|
+
warning: (
|
|
55
|
+
<svg className="ds-alert__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
56
|
+
<path
|
|
57
|
+
fillRule="evenodd"
|
|
58
|
+
d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z"
|
|
59
|
+
clipRule="evenodd"
|
|
60
|
+
/>
|
|
61
|
+
</svg>
|
|
62
|
+
),
|
|
63
|
+
error: (
|
|
64
|
+
<svg className="ds-alert__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
65
|
+
<path
|
|
66
|
+
fillRule="evenodd"
|
|
67
|
+
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z"
|
|
68
|
+
clipRule="evenodd"
|
|
69
|
+
/>
|
|
70
|
+
</svg>
|
|
71
|
+
),
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const CLOSE_ICON = (
|
|
75
|
+
<svg className="ds-alert__close-icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
76
|
+
<path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" />
|
|
77
|
+
</svg>
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get the ARIA role based on variant.
|
|
82
|
+
*/
|
|
83
|
+
function getRole(variant: AlertVariant): "alert" | "status" {
|
|
84
|
+
return variant === "error" || variant === "warning" ? "alert" : "status";
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Alert component for contextual feedback messages.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```tsx
|
|
92
|
+
* // Basic usage
|
|
93
|
+
* <Alert variant="success" title="Success">
|
|
94
|
+
* Your changes have been saved.
|
|
95
|
+
* </Alert>
|
|
96
|
+
*
|
|
97
|
+
* // Closable alert
|
|
98
|
+
* <Alert variant="error" title="Error" closable onClose={() => setShowAlert(false)}>
|
|
99
|
+
* An error occurred while saving.
|
|
100
|
+
* </Alert>
|
|
101
|
+
*
|
|
102
|
+
* // With action
|
|
103
|
+
* <Alert variant="warning" title="Warning" action={<Button size="sm">Undo</Button>}>
|
|
104
|
+
* This action cannot be reversed.
|
|
105
|
+
* </Alert>
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export const Alert = forwardRef<HTMLDivElement, AlertProps>(
|
|
109
|
+
(
|
|
110
|
+
{
|
|
111
|
+
variant = "info",
|
|
112
|
+
title,
|
|
113
|
+
closable = false,
|
|
114
|
+
hideIcon = false,
|
|
115
|
+
icon,
|
|
116
|
+
action,
|
|
117
|
+
onClose,
|
|
118
|
+
children,
|
|
119
|
+
className,
|
|
120
|
+
...restProps
|
|
121
|
+
},
|
|
122
|
+
ref
|
|
123
|
+
) => {
|
|
124
|
+
const role = getRole(variant);
|
|
125
|
+
|
|
126
|
+
const handleClose = useCallback(() => {
|
|
127
|
+
onClose?.();
|
|
128
|
+
}, [onClose]);
|
|
129
|
+
|
|
130
|
+
const handleKeyDown = useCallback(
|
|
131
|
+
(event: React.KeyboardEvent) => {
|
|
132
|
+
if (event.key === "Escape" && closable) {
|
|
133
|
+
handleClose();
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
[closable, handleClose]
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const alertClassName = ["ds-alert", className].filter(Boolean).join(" ");
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<div
|
|
143
|
+
ref={ref}
|
|
144
|
+
className={alertClassName}
|
|
145
|
+
role={role}
|
|
146
|
+
aria-live={role === "alert" ? "assertive" : "polite"}
|
|
147
|
+
data-variant={variant}
|
|
148
|
+
data-closable={closable || undefined}
|
|
149
|
+
onKeyDown={handleKeyDown}
|
|
150
|
+
{...restProps}
|
|
151
|
+
>
|
|
152
|
+
{!hideIcon && (icon || VARIANT_ICONS[variant])}
|
|
153
|
+
|
|
154
|
+
<div className="ds-alert__content">
|
|
155
|
+
{title && <p className="ds-alert__title">{title}</p>}
|
|
156
|
+
|
|
157
|
+
<div className="ds-alert__description">{children}</div>
|
|
158
|
+
|
|
159
|
+
{action && <div className="ds-alert__action">{action}</div>}
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
{closable && (
|
|
163
|
+
<button
|
|
164
|
+
className="ds-alert__close"
|
|
165
|
+
type="button"
|
|
166
|
+
aria-label="Dismiss alert"
|
|
167
|
+
onClick={handleClose}
|
|
168
|
+
>
|
|
169
|
+
{CLOSE_ICON}
|
|
170
|
+
</button>
|
|
171
|
+
)}
|
|
172
|
+
</div>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
Alert.displayName = "Alert";
|
|
@@ -0,0 +1,167 @@
|
|
|
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 { DSElement } from "../../base/ds-element.js";
|
|
5
|
+
import { emitEvent } from "../../events/emit.js";
|
|
6
|
+
import { define } from "../../registry/define.js";
|
|
7
|
+
|
|
8
|
+
export type AlertVariant = "info" | "success" | "warning" | "error";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* SVG icons for different alert variants
|
|
12
|
+
*/
|
|
13
|
+
const VARIANT_ICONS: Record<AlertVariant, TemplateResult> = {
|
|
14
|
+
info: html`<svg class="ds-alert__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
15
|
+
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z" clip-rule="evenodd" />
|
|
16
|
+
</svg>`,
|
|
17
|
+
success: html`<svg class="ds-alert__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
18
|
+
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" />
|
|
19
|
+
</svg>`,
|
|
20
|
+
warning: html`<svg class="ds-alert__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
21
|
+
<path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z" clip-rule="evenodd" />
|
|
22
|
+
</svg>`,
|
|
23
|
+
error: html`<svg class="ds-alert__icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
24
|
+
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" />
|
|
25
|
+
</svg>`,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const CLOSE_ICON = html`<svg class="ds-alert__close-icon" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
29
|
+
<path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" />
|
|
30
|
+
</svg>`;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Alert component for contextual feedback messages.
|
|
34
|
+
*
|
|
35
|
+
* @element ds-alert
|
|
36
|
+
* @slot - Default slot for alert description/content
|
|
37
|
+
* @slot icon - Custom icon content
|
|
38
|
+
* @slot action - Action button slot
|
|
39
|
+
*
|
|
40
|
+
* @fires ds:close - Fired when close button is clicked
|
|
41
|
+
*
|
|
42
|
+
* @csspart alert - The alert container
|
|
43
|
+
* @csspart icon - The icon container
|
|
44
|
+
* @csspart content - The content container
|
|
45
|
+
* @csspart title - The title element
|
|
46
|
+
* @csspart description - The description slot container
|
|
47
|
+
* @csspart close - The close button
|
|
48
|
+
*
|
|
49
|
+
* @cssprop --ds-alert-bg - Background color
|
|
50
|
+
* @cssprop --ds-alert-fg - Text color
|
|
51
|
+
* @cssprop --ds-alert-border - Border color
|
|
52
|
+
* @cssprop --ds-alert-icon - Icon color
|
|
53
|
+
*/
|
|
54
|
+
export class DsAlert extends DSElement {
|
|
55
|
+
static override styles = [];
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The visual variant of the alert.
|
|
59
|
+
*/
|
|
60
|
+
@property({ type: String, reflect: true })
|
|
61
|
+
variant: AlertVariant = "info";
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The alert title.
|
|
65
|
+
*/
|
|
66
|
+
@property({ type: String })
|
|
67
|
+
alertTitle = "";
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Whether the alert can be closed.
|
|
71
|
+
*/
|
|
72
|
+
@property({ type: Boolean, reflect: true })
|
|
73
|
+
closable = false;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Hide the default icon.
|
|
77
|
+
*/
|
|
78
|
+
@property({ type: Boolean, attribute: "hide-icon" })
|
|
79
|
+
hideIcon = false;
|
|
80
|
+
|
|
81
|
+
private handleClose(): void {
|
|
82
|
+
emitEvent(this, "ds:close", {});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private handleKeyDown(event: KeyboardEvent): void {
|
|
86
|
+
if (event.key === "Escape" && this.closable) {
|
|
87
|
+
this.handleClose();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get the ARIA role based on variant.
|
|
93
|
+
* Error and warning use 'alert' for immediate announcement.
|
|
94
|
+
* Info and success use 'status' for polite announcement.
|
|
95
|
+
*/
|
|
96
|
+
private getRole(): "alert" | "status" {
|
|
97
|
+
return this.variant === "error" || this.variant === "warning" ? "alert" : "status";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
override render(): TemplateResult {
|
|
101
|
+
const classes = {
|
|
102
|
+
"ds-alert": true,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return html`
|
|
106
|
+
<div
|
|
107
|
+
part="alert"
|
|
108
|
+
class=${classMap(classes)}
|
|
109
|
+
role=${this.getRole()}
|
|
110
|
+
aria-live=${this.getRole() === "alert" ? "assertive" : "polite"}
|
|
111
|
+
data-variant=${this.variant}
|
|
112
|
+
?data-closable=${this.closable}
|
|
113
|
+
@keydown=${this.handleKeyDown}
|
|
114
|
+
>
|
|
115
|
+
${
|
|
116
|
+
!this.hideIcon
|
|
117
|
+
? html`
|
|
118
|
+
<slot name="icon">
|
|
119
|
+
${VARIANT_ICONS[this.variant]}
|
|
120
|
+
</slot>
|
|
121
|
+
`
|
|
122
|
+
: nothing
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
<div part="content" class="ds-alert__content">
|
|
126
|
+
${
|
|
127
|
+
this.alertTitle
|
|
128
|
+
? html`<p part="title" class="ds-alert__title">${this.alertTitle}</p>`
|
|
129
|
+
: nothing
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
<div part="description" class="ds-alert__description">
|
|
133
|
+
<slot></slot>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<slot name="action" class="ds-alert__action"></slot>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
${
|
|
140
|
+
this.closable
|
|
141
|
+
? html`
|
|
142
|
+
<button
|
|
143
|
+
part="close"
|
|
144
|
+
class="ds-alert__close"
|
|
145
|
+
type="button"
|
|
146
|
+
aria-label="Dismiss alert"
|
|
147
|
+
@click=${this.handleClose}
|
|
148
|
+
>
|
|
149
|
+
${CLOSE_ICON}
|
|
150
|
+
</button>
|
|
151
|
+
`
|
|
152
|
+
: nothing
|
|
153
|
+
}
|
|
154
|
+
</div>
|
|
155
|
+
`;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Register the component
|
|
160
|
+
define("ds-alert", DsAlert);
|
|
161
|
+
|
|
162
|
+
// TypeScript declaration for HTML
|
|
163
|
+
declare global {
|
|
164
|
+
interface HTMLElementTagNameMap {
|
|
165
|
+
"ds-alert": DsAlert;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DsAlert, type AlertVariant } from "./alert.js";
|