@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,90 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import {
|
|
3
|
+
type HTMLAttributes,
|
|
4
|
+
createElement,
|
|
5
|
+
forwardRef,
|
|
6
|
+
useCallback,
|
|
7
|
+
useEffect,
|
|
8
|
+
useRef,
|
|
9
|
+
} from "react";
|
|
10
|
+
|
|
11
|
+
export interface SwitchProps extends Omit<HTMLAttributes<HTMLElement>, "onChange"> {
|
|
12
|
+
/** Switch name */
|
|
13
|
+
name?: string;
|
|
14
|
+
/** Whether checked/on */
|
|
15
|
+
checked?: boolean;
|
|
16
|
+
/** Default checked state (uncontrolled) */
|
|
17
|
+
defaultChecked?: boolean;
|
|
18
|
+
/** Whether disabled */
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/** Whether required */
|
|
21
|
+
required?: boolean;
|
|
22
|
+
/** Change handler */
|
|
23
|
+
onChange?: (checked: boolean, event: Event) => void;
|
|
24
|
+
/** Switch label content */
|
|
25
|
+
children?: React.ReactNode;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* React wrapper for ds-switch Web Component.
|
|
30
|
+
* Toggle switch with role="switch".
|
|
31
|
+
*/
|
|
32
|
+
export const Switch = forwardRef<HTMLElement, SwitchProps>((props, forwardedRef) => {
|
|
33
|
+
const {
|
|
34
|
+
name,
|
|
35
|
+
checked,
|
|
36
|
+
defaultChecked,
|
|
37
|
+
disabled = false,
|
|
38
|
+
required = false,
|
|
39
|
+
onChange,
|
|
40
|
+
children,
|
|
41
|
+
className,
|
|
42
|
+
...rest
|
|
43
|
+
} = props;
|
|
44
|
+
|
|
45
|
+
const internalRef = useRef<HTMLElement>(null);
|
|
46
|
+
|
|
47
|
+
// Store handler in ref for stable callback reference
|
|
48
|
+
const onChangeRef = useRef(onChange);
|
|
49
|
+
onChangeRef.current = onChange;
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (typeof forwardedRef === "function") {
|
|
53
|
+
forwardedRef(internalRef.current);
|
|
54
|
+
} else if (forwardedRef) {
|
|
55
|
+
(forwardedRef as React.MutableRefObject<HTMLElement | null>).current = internalRef.current;
|
|
56
|
+
}
|
|
57
|
+
}, [forwardedRef]);
|
|
58
|
+
|
|
59
|
+
// Stable handler that reads from ref
|
|
60
|
+
const handleChange = useCallback((event: Event) => {
|
|
61
|
+
const customEvent = event as CustomEvent<{ checked: boolean }>;
|
|
62
|
+
onChangeRef.current?.(customEvent.detail.checked, event);
|
|
63
|
+
}, []);
|
|
64
|
+
|
|
65
|
+
// Handle change events - no handler deps needed
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
const element = internalRef.current;
|
|
68
|
+
if (!element) return;
|
|
69
|
+
|
|
70
|
+
element.addEventListener("ds:change", handleChange);
|
|
71
|
+
return () => element.removeEventListener("ds:change", handleChange);
|
|
72
|
+
}, [handleChange]);
|
|
73
|
+
|
|
74
|
+
return createElement(
|
|
75
|
+
"ds-switch",
|
|
76
|
+
{
|
|
77
|
+
ref: internalRef,
|
|
78
|
+
name,
|
|
79
|
+
checked: checked || undefined,
|
|
80
|
+
"default-checked": defaultChecked || undefined,
|
|
81
|
+
disabled: disabled || undefined,
|
|
82
|
+
required: required || undefined,
|
|
83
|
+
class: className,
|
|
84
|
+
...rest,
|
|
85
|
+
},
|
|
86
|
+
children
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
Switch.displayName = "Switch";
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import type { PropertyValues } from "lit";
|
|
3
|
+
import { property, state } from "lit/decorators.js";
|
|
4
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
5
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
6
|
+
import { FormAssociatedMixin } from "../../base/form-associated.js";
|
|
7
|
+
import type { ValidationFlags } from "../../base/form-associated.js";
|
|
8
|
+
import { StandardEvents, emitEvent } from "../../events/emit.js";
|
|
9
|
+
import { define } from "../../registry/define.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Toggle switch for boolean settings with role="switch" semantics and native form participation.
|
|
13
|
+
*
|
|
14
|
+
* Uses ElementInternals for form association - values are submitted with the form
|
|
15
|
+
* and the switch participates in constraint validation.
|
|
16
|
+
*
|
|
17
|
+
* @element ds-switch
|
|
18
|
+
* @fires ds:change - Fired on state change with { checked }
|
|
19
|
+
* @fires ds:invalid - Fired when customValidation is true and validation fails
|
|
20
|
+
*
|
|
21
|
+
* @slot - Switch label
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```html
|
|
25
|
+
* <form>
|
|
26
|
+
* <ds-switch name="notifications">Enable notifications</ds-switch>
|
|
27
|
+
* <button type="submit">Submit</button>
|
|
28
|
+
* </form>
|
|
29
|
+
*
|
|
30
|
+
* <ds-field>
|
|
31
|
+
* <ds-label>Dark Mode</ds-label>
|
|
32
|
+
* <ds-switch name="darkMode" custom-validation>Enable dark mode</ds-switch>
|
|
33
|
+
* <ds-field-description>Switch between light and dark themes</ds-field-description>
|
|
34
|
+
* <ds-field-error></ds-field-error>
|
|
35
|
+
* </ds-field>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export class DsSwitch extends FormAssociatedMixin(DSElement) {
|
|
39
|
+
/** Checked (on) state */
|
|
40
|
+
@property({ type: Boolean, reflect: true })
|
|
41
|
+
checked = false;
|
|
42
|
+
|
|
43
|
+
/** ARIA describedby - IDs of elements that describe this switch */
|
|
44
|
+
@state()
|
|
45
|
+
private ariaDescribedBy?: string;
|
|
46
|
+
|
|
47
|
+
/** Label text captured from slot */
|
|
48
|
+
@state()
|
|
49
|
+
private labelText = "";
|
|
50
|
+
|
|
51
|
+
/** Unique ID for label association */
|
|
52
|
+
@state()
|
|
53
|
+
private labelId = "";
|
|
54
|
+
|
|
55
|
+
/** Default checked state for form reset */
|
|
56
|
+
private _defaultChecked = false;
|
|
57
|
+
|
|
58
|
+
private attributeObserver: MutationObserver | null = null;
|
|
59
|
+
|
|
60
|
+
override connectedCallback(): void {
|
|
61
|
+
// Capture label text before Lit renders
|
|
62
|
+
this.labelText = this.textContent?.trim() ?? "";
|
|
63
|
+
// Generate unique ID for label
|
|
64
|
+
this.labelId = `switch-label-${crypto.randomUUID().slice(0, 8)}`;
|
|
65
|
+
// Store default checked state
|
|
66
|
+
this._defaultChecked = this.checked;
|
|
67
|
+
|
|
68
|
+
super.connectedCallback();
|
|
69
|
+
|
|
70
|
+
// Set default value for form association
|
|
71
|
+
if (!this.value) {
|
|
72
|
+
this.value = "on";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Observe ARIA attribute changes on the host element
|
|
76
|
+
this.attributeObserver = new MutationObserver((mutations) => {
|
|
77
|
+
for (const mutation of mutations) {
|
|
78
|
+
if (mutation.type === "attributes") {
|
|
79
|
+
this.syncAriaAttributes();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
this.attributeObserver.observe(this, {
|
|
85
|
+
attributes: true,
|
|
86
|
+
attributeFilter: ["aria-describedby", "aria-invalid", "aria-required", "aria-disabled"],
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Initial sync
|
|
90
|
+
this.syncAriaAttributes();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
override disconnectedCallback(): void {
|
|
94
|
+
super.disconnectedCallback();
|
|
95
|
+
this.attributeObserver?.disconnect();
|
|
96
|
+
this.attributeObserver = null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Syncs ARIA attributes from the host element to internal state.
|
|
101
|
+
*/
|
|
102
|
+
private syncAriaAttributes(): void {
|
|
103
|
+
this.ariaDescribedBy = this.getAttribute("aria-describedby") ?? undefined;
|
|
104
|
+
|
|
105
|
+
// Sync required state from aria-required
|
|
106
|
+
const ariaRequired = this.getAttribute("aria-required");
|
|
107
|
+
if (ariaRequired === "true") {
|
|
108
|
+
this.required = true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Sync disabled state from aria-disabled
|
|
112
|
+
const ariaDisabled = this.getAttribute("aria-disabled");
|
|
113
|
+
if (ariaDisabled === "true") {
|
|
114
|
+
this.disabled = true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Toggles the switch state.
|
|
120
|
+
*/
|
|
121
|
+
private toggle(): void {
|
|
122
|
+
if (this.disabled) return;
|
|
123
|
+
|
|
124
|
+
this.checked = !this.checked;
|
|
125
|
+
|
|
126
|
+
emitEvent(this, StandardEvents.CHANGE, {
|
|
127
|
+
detail: {
|
|
128
|
+
checked: this.checked,
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private handleClick = (event: Event): void => {
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
this.toggle();
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
private handleKeyDown = (event: KeyboardEvent): void => {
|
|
139
|
+
// Both Space and Enter keys toggle the switch (distinct from checkbox)
|
|
140
|
+
if ((event.key === " " || event.key === "Enter") && !this.disabled) {
|
|
141
|
+
event.preventDefault();
|
|
142
|
+
this.toggle();
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// Form association implementation
|
|
147
|
+
|
|
148
|
+
protected getFormValue(): string | null {
|
|
149
|
+
return this.checked ? this.value : null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
protected getValidationAnchor(): HTMLElement | undefined {
|
|
153
|
+
return this.querySelector(".ds-switch__control") as HTMLElement | undefined;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
protected getValidationFlags(): ValidationFlags {
|
|
157
|
+
if (this.required && !this.checked) {
|
|
158
|
+
return { valueMissing: true };
|
|
159
|
+
}
|
|
160
|
+
return {};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
protected getValidationMessage(flags: ValidationFlags): string {
|
|
164
|
+
if (flags.valueMissing) {
|
|
165
|
+
return "Please turn this switch on to proceed";
|
|
166
|
+
}
|
|
167
|
+
return "";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
protected shouldUpdateFormValue(changedProperties: PropertyValues): boolean {
|
|
171
|
+
return changedProperties.has("checked");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
protected shouldUpdateValidity(changedProperties: PropertyValues): boolean {
|
|
175
|
+
return changedProperties.has("checked");
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
protected onFormReset(): void {
|
|
179
|
+
this.checked = this._defaultChecked;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
protected onFormStateRestore(
|
|
183
|
+
state: string | File | FormData | null,
|
|
184
|
+
_mode: "restore" | "autocomplete"
|
|
185
|
+
): void {
|
|
186
|
+
if (typeof state === "string") {
|
|
187
|
+
this.checked = state === this.value;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
override render() {
|
|
192
|
+
return html`
|
|
193
|
+
<div
|
|
194
|
+
class="ds-switch"
|
|
195
|
+
part="container"
|
|
196
|
+
@click=${this.handleClick}
|
|
197
|
+
>
|
|
198
|
+
<div
|
|
199
|
+
role="switch"
|
|
200
|
+
part="control"
|
|
201
|
+
class="ds-switch__control"
|
|
202
|
+
tabindex=${this.disabled ? -1 : 0}
|
|
203
|
+
aria-checked=${this.checked ? "true" : "false"}
|
|
204
|
+
aria-disabled=${this.disabled ? "true" : "false"}
|
|
205
|
+
aria-required=${this.required ? "true" : "false"}
|
|
206
|
+
aria-labelledby=${this.labelId}
|
|
207
|
+
aria-describedby=${ifDefined(this.ariaDescribedBy)}
|
|
208
|
+
@keydown=${this.handleKeyDown}
|
|
209
|
+
>
|
|
210
|
+
<span class="ds-switch__track" part="track">
|
|
211
|
+
<span class="ds-switch__thumb" part="thumb"></span>
|
|
212
|
+
</span>
|
|
213
|
+
</div>
|
|
214
|
+
<span id=${this.labelId} class="ds-switch__label" part="label">
|
|
215
|
+
${this.labelText}
|
|
216
|
+
</span>
|
|
217
|
+
</div>
|
|
218
|
+
`;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
define("ds-switch", DsSwitch);
|
|
223
|
+
|
|
224
|
+
declare global {
|
|
225
|
+
interface HTMLElementTagNameMap {
|
|
226
|
+
"ds-switch": DsSwitch;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type HTMLAttributes, type ReactNode, createElement, forwardRef } from "react";
|
|
4
|
+
import "@hypoth-ui/wc";
|
|
5
|
+
|
|
6
|
+
export interface TableBodyProps extends HTMLAttributes<HTMLElement> {
|
|
7
|
+
/**
|
|
8
|
+
* Table body rows.
|
|
9
|
+
*/
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Table body component (tbody).
|
|
15
|
+
*/
|
|
16
|
+
export const TableBody = forwardRef<HTMLElement, TableBodyProps>(function TableBody(
|
|
17
|
+
{ children, className, ...props },
|
|
18
|
+
ref
|
|
19
|
+
) {
|
|
20
|
+
return createElement("ds-table-body", { ref, class: className, ...props }, children);
|
|
21
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type HTMLAttributes, type ReactNode, createElement, forwardRef } from "react";
|
|
4
|
+
import "@hypoth-ui/wc";
|
|
5
|
+
import type { TableAlign } from "./head.js";
|
|
6
|
+
|
|
7
|
+
export interface TableCellProps extends HTMLAttributes<HTMLElement> {
|
|
8
|
+
/**
|
|
9
|
+
* Text alignment.
|
|
10
|
+
* @default "left"
|
|
11
|
+
*/
|
|
12
|
+
align?: TableAlign;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Column span.
|
|
16
|
+
* @default 1
|
|
17
|
+
*/
|
|
18
|
+
colSpan?: number;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Row span.
|
|
22
|
+
* @default 1
|
|
23
|
+
*/
|
|
24
|
+
rowSpan?: number;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Cell content.
|
|
28
|
+
*/
|
|
29
|
+
children?: ReactNode;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Table cell component (td).
|
|
34
|
+
*/
|
|
35
|
+
export const TableCell = forwardRef<HTMLElement, TableCellProps>(function TableCell(
|
|
36
|
+
{ align = "left", colSpan = 1, rowSpan = 1, children, className, ...props },
|
|
37
|
+
ref
|
|
38
|
+
) {
|
|
39
|
+
return createElement(
|
|
40
|
+
"ds-table-cell",
|
|
41
|
+
{ ref, align, colspan: colSpan, rowspan: rowSpan, class: className, ...props },
|
|
42
|
+
children
|
|
43
|
+
);
|
|
44
|
+
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type HTMLAttributes,
|
|
5
|
+
type ReactNode,
|
|
6
|
+
createElement,
|
|
7
|
+
forwardRef,
|
|
8
|
+
useEffect,
|
|
9
|
+
useRef,
|
|
10
|
+
} from "react";
|
|
11
|
+
import "@hypoth-ui/wc";
|
|
12
|
+
|
|
13
|
+
export type TableAlign = "left" | "center" | "right";
|
|
14
|
+
export type SortDirection = "asc" | "desc" | "none";
|
|
15
|
+
|
|
16
|
+
export interface TableHeadProps extends HTMLAttributes<HTMLElement> {
|
|
17
|
+
/**
|
|
18
|
+
* Column key for sorting.
|
|
19
|
+
*/
|
|
20
|
+
column?: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Text alignment.
|
|
24
|
+
* @default "left"
|
|
25
|
+
*/
|
|
26
|
+
align?: TableAlign;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether this column is sortable.
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
sortable?: boolean;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Current sort direction.
|
|
36
|
+
* @default "none"
|
|
37
|
+
*/
|
|
38
|
+
sortDirection?: SortDirection;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Column width (CSS value).
|
|
42
|
+
*/
|
|
43
|
+
width?: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Callback when sort is triggered.
|
|
47
|
+
*/
|
|
48
|
+
onSort?: (column: string, direction: SortDirection) => void;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Header cell content.
|
|
52
|
+
*/
|
|
53
|
+
children?: ReactNode;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Table header cell component (th).
|
|
58
|
+
*/
|
|
59
|
+
export const TableHead = forwardRef<HTMLElement, TableHeadProps>(function TableHead(
|
|
60
|
+
{
|
|
61
|
+
column,
|
|
62
|
+
align = "left",
|
|
63
|
+
sortable = false,
|
|
64
|
+
sortDirection = "none",
|
|
65
|
+
width,
|
|
66
|
+
onSort,
|
|
67
|
+
children,
|
|
68
|
+
className,
|
|
69
|
+
...props
|
|
70
|
+
},
|
|
71
|
+
forwardedRef
|
|
72
|
+
) {
|
|
73
|
+
const internalRef = useRef<HTMLElement>(null);
|
|
74
|
+
|
|
75
|
+
// Sync forwarded ref
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (typeof forwardedRef === "function") {
|
|
78
|
+
forwardedRef(internalRef.current);
|
|
79
|
+
} else if (forwardedRef) {
|
|
80
|
+
(forwardedRef as React.MutableRefObject<HTMLElement | null>).current = internalRef.current;
|
|
81
|
+
}
|
|
82
|
+
}, [forwardedRef]);
|
|
83
|
+
|
|
84
|
+
// Set up event listeners
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
const element = internalRef.current;
|
|
87
|
+
if (!element) return;
|
|
88
|
+
|
|
89
|
+
const handleSort = (e: Event) => {
|
|
90
|
+
const event = e as CustomEvent<{ column: string; direction: SortDirection }>;
|
|
91
|
+
onSort?.(event.detail.column, event.detail.direction);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
element.addEventListener("ds:sort", handleSort);
|
|
95
|
+
return () => element.removeEventListener("ds:sort", handleSort);
|
|
96
|
+
}, [onSort]);
|
|
97
|
+
|
|
98
|
+
return createElement(
|
|
99
|
+
"ds-table-head",
|
|
100
|
+
{
|
|
101
|
+
ref: internalRef,
|
|
102
|
+
column,
|
|
103
|
+
align,
|
|
104
|
+
sortable: sortable || undefined,
|
|
105
|
+
"sort-direction": sortDirection,
|
|
106
|
+
width,
|
|
107
|
+
class: className,
|
|
108
|
+
...props,
|
|
109
|
+
},
|
|
110
|
+
children
|
|
111
|
+
);
|
|
112
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type HTMLAttributes, type ReactNode, createElement, forwardRef } from "react";
|
|
4
|
+
import "@hypoth-ui/wc";
|
|
5
|
+
|
|
6
|
+
export interface TableHeaderProps extends HTMLAttributes<HTMLElement> {
|
|
7
|
+
/**
|
|
8
|
+
* Table header rows.
|
|
9
|
+
*/
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Table header component (thead).
|
|
15
|
+
*/
|
|
16
|
+
export const TableHeader = forwardRef<HTMLElement, TableHeaderProps>(function TableHeader(
|
|
17
|
+
{ children, className, ...props },
|
|
18
|
+
ref
|
|
19
|
+
) {
|
|
20
|
+
return createElement("ds-table-header", { ref, class: className, ...props }, children);
|
|
21
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Table compound component exports
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { TableBody } from "./body.js";
|
|
8
|
+
import { TableCell } from "./cell.js";
|
|
9
|
+
import { TableHead } from "./head.js";
|
|
10
|
+
import { TableHeader } from "./header.js";
|
|
11
|
+
import { TableRoot } from "./root.js";
|
|
12
|
+
import { TableRow } from "./row.js";
|
|
13
|
+
|
|
14
|
+
export type { TableRootProps, TableSize } from "./root.js";
|
|
15
|
+
export type { TableHeaderProps } from "./header.js";
|
|
16
|
+
export type { TableBodyProps } from "./body.js";
|
|
17
|
+
export type { TableRowProps } from "./row.js";
|
|
18
|
+
export type { TableHeadProps, TableAlign, SortDirection } from "./head.js";
|
|
19
|
+
export type { TableCellProps } from "./cell.js";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Table compound component for structured data display.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <Table striped>
|
|
27
|
+
* <Table.Header>
|
|
28
|
+
* <Table.Row>
|
|
29
|
+
* <Table.Head sortable column="name" onSort={handleSort}>Name</Table.Head>
|
|
30
|
+
* <Table.Head>Email</Table.Head>
|
|
31
|
+
* </Table.Row>
|
|
32
|
+
* </Table.Header>
|
|
33
|
+
* <Table.Body>
|
|
34
|
+
* <Table.Row>
|
|
35
|
+
* <Table.Cell>John Doe</Table.Cell>
|
|
36
|
+
* <Table.Cell>john@example.com</Table.Cell>
|
|
37
|
+
* </Table.Row>
|
|
38
|
+
* </Table.Body>
|
|
39
|
+
* </Table>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export const Table = Object.assign(TableRoot, {
|
|
43
|
+
Header: TableHeader,
|
|
44
|
+
Body: TableBody,
|
|
45
|
+
Row: TableRow,
|
|
46
|
+
Head: TableHead,
|
|
47
|
+
Cell: TableCell,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export { TableHeader, TableBody, TableRow, TableHead, TableCell };
|
|
51
|
+
|
|
52
|
+
// TypeScript declarations for JSX
|
|
53
|
+
declare global {
|
|
54
|
+
namespace JSX {
|
|
55
|
+
interface IntrinsicElements {
|
|
56
|
+
"ds-table": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
57
|
+
ref?: React.Ref<HTMLElement>;
|
|
58
|
+
size?: string;
|
|
59
|
+
striped?: boolean;
|
|
60
|
+
borderless?: boolean;
|
|
61
|
+
fixed?: boolean;
|
|
62
|
+
"sticky-header"?: boolean;
|
|
63
|
+
caption?: string;
|
|
64
|
+
};
|
|
65
|
+
"ds-table-header": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
66
|
+
ref?: React.Ref<HTMLElement>;
|
|
67
|
+
};
|
|
68
|
+
"ds-table-body": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
69
|
+
ref?: React.Ref<HTMLElement>;
|
|
70
|
+
};
|
|
71
|
+
"ds-table-row": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
72
|
+
ref?: React.Ref<HTMLElement>;
|
|
73
|
+
"row-id"?: string;
|
|
74
|
+
selected?: boolean;
|
|
75
|
+
};
|
|
76
|
+
"ds-table-head": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
77
|
+
ref?: React.Ref<HTMLElement>;
|
|
78
|
+
column?: string;
|
|
79
|
+
align?: string;
|
|
80
|
+
sortable?: boolean;
|
|
81
|
+
"sort-direction"?: string;
|
|
82
|
+
width?: string;
|
|
83
|
+
"onDs-sort"?: (event: CustomEvent) => void;
|
|
84
|
+
};
|
|
85
|
+
"ds-table-cell": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
86
|
+
ref?: React.Ref<HTMLElement>;
|
|
87
|
+
align?: string;
|
|
88
|
+
colspan?: number;
|
|
89
|
+
rowspan?: number;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { type HTMLAttributes, type ReactNode, createElement, forwardRef } from "react";
|
|
4
|
+
import "@hypoth-ui/wc";
|
|
5
|
+
|
|
6
|
+
export type TableSize = "compact" | "default" | "spacious";
|
|
7
|
+
|
|
8
|
+
export interface TableRootProps extends HTMLAttributes<HTMLElement> {
|
|
9
|
+
/**
|
|
10
|
+
* Size variant.
|
|
11
|
+
* @default "default"
|
|
12
|
+
*/
|
|
13
|
+
size?: TableSize;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Whether to show striped rows.
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
striped?: boolean;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Whether to remove borders.
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
borderless?: boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Whether to use fixed layout.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
fixed?: boolean;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Whether header is sticky.
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
stickyHeader?: boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Accessible caption for screen readers.
|
|
41
|
+
*/
|
|
42
|
+
caption?: string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Table content.
|
|
46
|
+
*/
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Table root component.
|
|
52
|
+
*/
|
|
53
|
+
export const TableRoot = forwardRef<HTMLElement, TableRootProps>(function TableRoot(
|
|
54
|
+
{
|
|
55
|
+
size = "default",
|
|
56
|
+
striped = false,
|
|
57
|
+
borderless = false,
|
|
58
|
+
fixed = false,
|
|
59
|
+
stickyHeader = false,
|
|
60
|
+
caption,
|
|
61
|
+
children,
|
|
62
|
+
className,
|
|
63
|
+
...props
|
|
64
|
+
},
|
|
65
|
+
ref
|
|
66
|
+
) {
|
|
67
|
+
return createElement(
|
|
68
|
+
"ds-table",
|
|
69
|
+
{
|
|
70
|
+
ref,
|
|
71
|
+
size,
|
|
72
|
+
striped: striped || undefined,
|
|
73
|
+
borderless: borderless || undefined,
|
|
74
|
+
fixed: fixed || undefined,
|
|
75
|
+
"sticky-header": stickyHeader || undefined,
|
|
76
|
+
caption,
|
|
77
|
+
class: className,
|
|
78
|
+
...props,
|
|
79
|
+
},
|
|
80
|
+
children
|
|
81
|
+
);
|
|
82
|
+
});
|