@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,16 @@
|
|
|
1
|
+
import { forwardRef } from "react";
|
|
2
|
+
import { Flow, type FlowProps } from "./flow.js";
|
|
3
|
+
|
|
4
|
+
export interface StackProps extends Omit<FlowProps, "direction"> {
|
|
5
|
+
/** Gap between children. Supports responsive object syntax. */
|
|
6
|
+
gap?: FlowProps["gap"];
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Stack is a Flow with direction="column".
|
|
11
|
+
*/
|
|
12
|
+
export const Stack = forwardRef<HTMLElement, StackProps>((props, ref) => {
|
|
13
|
+
return <Flow ref={ref} direction="column" {...props} />;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
Stack.displayName = "Stack";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppShell Web Component
|
|
3
|
+
*
|
|
4
|
+
* Application structure with landmark regions using CSS Grid.
|
|
5
|
+
*
|
|
6
|
+
* @element ds-app-shell
|
|
7
|
+
* @slot header - Header region
|
|
8
|
+
* @slot sidebar - Sidebar region
|
|
9
|
+
* @slot - Default slot for main content
|
|
10
|
+
* @slot footer - Footer region
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { type TemplateResult, html } from "lit";
|
|
14
|
+
import { property } from "lit/decorators.js";
|
|
15
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
16
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
17
|
+
import { define } from "../../registry/define.js";
|
|
18
|
+
|
|
19
|
+
type SidebarPosition = "left" | "right" | "none";
|
|
20
|
+
|
|
21
|
+
export class DsAppShell extends DSElement {
|
|
22
|
+
static override styles = [];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Sidebar position.
|
|
26
|
+
*/
|
|
27
|
+
@property({ type: String, reflect: true, attribute: "sidebar-position" })
|
|
28
|
+
sidebarPosition: SidebarPosition = "none";
|
|
29
|
+
|
|
30
|
+
override render(): TemplateResult {
|
|
31
|
+
const classes = {
|
|
32
|
+
"ds-app-shell": true,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return html`
|
|
36
|
+
<div
|
|
37
|
+
class=${classMap(classes)}
|
|
38
|
+
data-sidebar=${this.sidebarPosition}
|
|
39
|
+
data-layout="app-shell"
|
|
40
|
+
>
|
|
41
|
+
<slot name="header"></slot>
|
|
42
|
+
${this.sidebarPosition !== "none" ? html`<slot name="sidebar"></slot>` : null}
|
|
43
|
+
<slot></slot>
|
|
44
|
+
<slot name="footer"></slot>
|
|
45
|
+
</div>
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Register the component
|
|
51
|
+
define("ds-app-shell", DsAppShell);
|
|
52
|
+
|
|
53
|
+
// TypeScript declaration for HTML
|
|
54
|
+
declare global {
|
|
55
|
+
interface HTMLElementTagNameMap {
|
|
56
|
+
"ds-app-shell": DsAppShell;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Box Web Component
|
|
3
|
+
*
|
|
4
|
+
* Token-only styling escape hatch for padding, background, and radius.
|
|
5
|
+
*
|
|
6
|
+
* @element ds-box
|
|
7
|
+
* @slot - Default slot for children
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { type TemplateResult, html } from "lit";
|
|
11
|
+
import { property } from "lit/decorators.js";
|
|
12
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
13
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
14
|
+
import { define } from "../../registry/define.js";
|
|
15
|
+
import type { RadiusToken, SpacingToken, SurfaceToken } from "../../types/layout-tokens.js";
|
|
16
|
+
import { RADIUS_TOKENS, SPACING_TOKENS, SURFACE_TOKENS } from "../../types/layout-tokens.js";
|
|
17
|
+
import { validateToken } from "../../utils/token-validator.js";
|
|
18
|
+
|
|
19
|
+
export class DsBox extends DSElement {
|
|
20
|
+
static override styles = [];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Padding (all sides).
|
|
24
|
+
*/
|
|
25
|
+
@property({ type: String, reflect: true })
|
|
26
|
+
p?: SpacingToken;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Horizontal padding.
|
|
30
|
+
*/
|
|
31
|
+
@property({ type: String, reflect: true })
|
|
32
|
+
px?: SpacingToken;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Vertical padding.
|
|
36
|
+
*/
|
|
37
|
+
@property({ type: String, reflect: true })
|
|
38
|
+
py?: SpacingToken;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Background color token.
|
|
42
|
+
*/
|
|
43
|
+
@property({ type: String, reflect: true })
|
|
44
|
+
bg?: SurfaceToken;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Border radius token.
|
|
48
|
+
*/
|
|
49
|
+
@property({ type: String, reflect: true })
|
|
50
|
+
radius?: RadiusToken;
|
|
51
|
+
|
|
52
|
+
override connectedCallback(): void {
|
|
53
|
+
super.connectedCallback();
|
|
54
|
+
this.validateProps();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
override updated(changedProperties: Map<string, unknown>): void {
|
|
58
|
+
super.updated(changedProperties);
|
|
59
|
+
if (
|
|
60
|
+
changedProperties.has("p") ||
|
|
61
|
+
changedProperties.has("px") ||
|
|
62
|
+
changedProperties.has("py") ||
|
|
63
|
+
changedProperties.has("bg") ||
|
|
64
|
+
changedProperties.has("radius")
|
|
65
|
+
) {
|
|
66
|
+
this.validateProps();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private validateProps(): void {
|
|
71
|
+
if (this.p) {
|
|
72
|
+
validateToken(this.p, SPACING_TOKENS, "p", "ds-box");
|
|
73
|
+
}
|
|
74
|
+
if (this.px) {
|
|
75
|
+
validateToken(this.px, SPACING_TOKENS, "px", "ds-box");
|
|
76
|
+
}
|
|
77
|
+
if (this.py) {
|
|
78
|
+
validateToken(this.py, SPACING_TOKENS, "py", "ds-box");
|
|
79
|
+
}
|
|
80
|
+
if (this.bg) {
|
|
81
|
+
validateToken(this.bg, SURFACE_TOKENS, "bg", "ds-box");
|
|
82
|
+
}
|
|
83
|
+
if (this.radius) {
|
|
84
|
+
validateToken(this.radius, RADIUS_TOKENS, "radius", "ds-box");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override render(): TemplateResult {
|
|
89
|
+
const classes = {
|
|
90
|
+
"ds-box": true,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return html`
|
|
94
|
+
<div
|
|
95
|
+
class=${classMap(classes)}
|
|
96
|
+
data-p=${this.p || ""}
|
|
97
|
+
data-px=${this.px || ""}
|
|
98
|
+
data-py=${this.py || ""}
|
|
99
|
+
data-bg=${this.bg || ""}
|
|
100
|
+
data-radius=${this.radius || ""}
|
|
101
|
+
data-layout="box"
|
|
102
|
+
>
|
|
103
|
+
<slot></slot>
|
|
104
|
+
</div>
|
|
105
|
+
`;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Register the component
|
|
110
|
+
define("ds-box", DsBox);
|
|
111
|
+
|
|
112
|
+
// TypeScript declaration for HTML
|
|
113
|
+
declare global {
|
|
114
|
+
interface HTMLElementTagNameMap {
|
|
115
|
+
"ds-box": DsBox;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Center Web Component
|
|
3
|
+
*
|
|
4
|
+
* Centers content horizontally/vertically with optional max-width.
|
|
5
|
+
*
|
|
6
|
+
* @element ds-center
|
|
7
|
+
* @slot - Default slot for centered content
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { type TemplateResult, html } from "lit";
|
|
11
|
+
import { property } from "lit/decorators.js";
|
|
12
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
13
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
14
|
+
import { define } from "../../registry/define.js";
|
|
15
|
+
import type { ContainerSizeToken } from "../../types/layout-tokens.js";
|
|
16
|
+
import { CONTAINER_SIZE_TOKENS } from "../../types/layout-tokens.js";
|
|
17
|
+
import { validateToken } from "../../utils/token-validator.js";
|
|
18
|
+
|
|
19
|
+
export class DsCenter extends DSElement {
|
|
20
|
+
static override styles = [];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Maximum width constraint.
|
|
24
|
+
*/
|
|
25
|
+
@property({ type: String, reflect: true, attribute: "max-width" })
|
|
26
|
+
maxWidth?: ContainerSizeToken;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Enable vertical centering.
|
|
30
|
+
*/
|
|
31
|
+
@property({ type: Boolean, reflect: true })
|
|
32
|
+
vertical = false;
|
|
33
|
+
|
|
34
|
+
override connectedCallback(): void {
|
|
35
|
+
super.connectedCallback();
|
|
36
|
+
this.validateProps();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
override updated(changedProperties: Map<string, unknown>): void {
|
|
40
|
+
super.updated(changedProperties);
|
|
41
|
+
if (changedProperties.has("maxWidth")) {
|
|
42
|
+
this.validateProps();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private validateProps(): void {
|
|
47
|
+
if (this.maxWidth) {
|
|
48
|
+
validateToken(this.maxWidth, CONTAINER_SIZE_TOKENS, "max-width", "ds-center");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override render(): TemplateResult {
|
|
53
|
+
const classes = {
|
|
54
|
+
"ds-center": true,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return html`
|
|
58
|
+
<div
|
|
59
|
+
class=${classMap(classes)}
|
|
60
|
+
data-max-width=${this.maxWidth || ""}
|
|
61
|
+
?data-vertical=${this.vertical}
|
|
62
|
+
data-layout="center"
|
|
63
|
+
>
|
|
64
|
+
<slot></slot>
|
|
65
|
+
</div>
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Register the component
|
|
71
|
+
define("ds-center", DsCenter);
|
|
72
|
+
|
|
73
|
+
// TypeScript declaration for HTML
|
|
74
|
+
declare global {
|
|
75
|
+
interface HTMLElementTagNameMap {
|
|
76
|
+
"ds-center": DsCenter;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Container Web Component
|
|
3
|
+
*
|
|
4
|
+
* Constrains content width with responsive max-widths and padding.
|
|
5
|
+
*
|
|
6
|
+
* @element ds-container
|
|
7
|
+
* @slot - Default slot for children
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { type TemplateResult, html } from "lit";
|
|
11
|
+
import { property } from "lit/decorators.js";
|
|
12
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
13
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
14
|
+
import { define } from "../../registry/define.js";
|
|
15
|
+
import type { ContainerSizeToken, SpacingToken } from "../../types/layout-tokens.js";
|
|
16
|
+
import { CONTAINER_SIZE_TOKENS, SPACING_TOKENS } from "../../types/layout-tokens.js";
|
|
17
|
+
import { validateToken } from "../../utils/token-validator.js";
|
|
18
|
+
|
|
19
|
+
export class DsContainer extends DSElement {
|
|
20
|
+
static override styles = [];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Maximum width constraint.
|
|
24
|
+
*/
|
|
25
|
+
@property({ type: String, reflect: true })
|
|
26
|
+
size: ContainerSizeToken = "lg";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Horizontal padding.
|
|
30
|
+
*/
|
|
31
|
+
@property({ type: String, reflect: true })
|
|
32
|
+
padding: SpacingToken = "md";
|
|
33
|
+
|
|
34
|
+
override connectedCallback(): void {
|
|
35
|
+
super.connectedCallback();
|
|
36
|
+
this.validateProps();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
override updated(changedProperties: Map<string, unknown>): void {
|
|
40
|
+
super.updated(changedProperties);
|
|
41
|
+
if (changedProperties.has("size") || changedProperties.has("padding")) {
|
|
42
|
+
this.validateProps();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private validateProps(): void {
|
|
47
|
+
validateToken(this.size, CONTAINER_SIZE_TOKENS, "size", "ds-container");
|
|
48
|
+
validateToken(this.padding, SPACING_TOKENS, "padding", "ds-container");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
override render(): TemplateResult {
|
|
52
|
+
const classes = {
|
|
53
|
+
"ds-container": true,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return html`
|
|
57
|
+
<div
|
|
58
|
+
class=${classMap(classes)}
|
|
59
|
+
data-size=${this.size}
|
|
60
|
+
data-padding=${this.padding}
|
|
61
|
+
data-layout="container"
|
|
62
|
+
>
|
|
63
|
+
<slot></slot>
|
|
64
|
+
</div>
|
|
65
|
+
`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Register the component
|
|
70
|
+
define("ds-container", DsContainer);
|
|
71
|
+
|
|
72
|
+
// TypeScript declaration for HTML
|
|
73
|
+
declare global {
|
|
74
|
+
interface HTMLElementTagNameMap {
|
|
75
|
+
"ds-container": DsContainer;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flow Web Component
|
|
3
|
+
*
|
|
4
|
+
* Primary 1D layout primitive with responsive direction switching.
|
|
5
|
+
* Replaces separate Stack/Inline components with unified API.
|
|
6
|
+
*
|
|
7
|
+
* @element ds-flow
|
|
8
|
+
* @slot - Default slot for children
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { type TemplateResult, html } from "lit";
|
|
12
|
+
import { property } from "lit/decorators.js";
|
|
13
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
14
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
15
|
+
import { define } from "../../registry/define.js";
|
|
16
|
+
import type {
|
|
17
|
+
FlexAlign,
|
|
18
|
+
FlexDirection,
|
|
19
|
+
FlexJustify,
|
|
20
|
+
FlexWrap,
|
|
21
|
+
SpacingToken,
|
|
22
|
+
} from "../../types/layout-tokens.js";
|
|
23
|
+
import {
|
|
24
|
+
FLEX_ALIGN_VALUES,
|
|
25
|
+
FLEX_DIRECTION_VALUES,
|
|
26
|
+
FLEX_JUSTIFY_VALUES,
|
|
27
|
+
SPACING_TOKENS,
|
|
28
|
+
} from "../../types/layout-tokens.js";
|
|
29
|
+
import {
|
|
30
|
+
generateResponsiveClasses,
|
|
31
|
+
getBaseValue,
|
|
32
|
+
isResponsiveValue,
|
|
33
|
+
} from "../../utils/responsive.js";
|
|
34
|
+
import { validateResponsiveToken, validateToken } from "../../utils/token-validator.js";
|
|
35
|
+
|
|
36
|
+
export class DsFlow extends DSElement {
|
|
37
|
+
static override styles = [];
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Flex direction. Supports responsive syntax: "base:column md:row"
|
|
41
|
+
*/
|
|
42
|
+
@property({ type: String, reflect: true })
|
|
43
|
+
direction = "row";
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Gap between children. Supports responsive syntax: "base:sm md:lg"
|
|
47
|
+
*/
|
|
48
|
+
@property({ type: String, reflect: true })
|
|
49
|
+
gap = "none";
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Cross-axis alignment.
|
|
53
|
+
*/
|
|
54
|
+
@property({ type: String, reflect: true })
|
|
55
|
+
align: FlexAlign = "stretch";
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Main-axis alignment.
|
|
59
|
+
*/
|
|
60
|
+
@property({ type: String, reflect: true })
|
|
61
|
+
justify: FlexJustify = "start";
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Flex wrap behavior.
|
|
65
|
+
*/
|
|
66
|
+
@property({ type: String, reflect: true })
|
|
67
|
+
wrap: FlexWrap = "nowrap";
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Use inline-flex instead of flex.
|
|
71
|
+
*/
|
|
72
|
+
@property({ type: Boolean, reflect: true })
|
|
73
|
+
inline = false;
|
|
74
|
+
|
|
75
|
+
override connectedCallback(): void {
|
|
76
|
+
super.connectedCallback();
|
|
77
|
+
this.validateProps();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
override updated(changedProperties: Map<string, unknown>): void {
|
|
81
|
+
super.updated(changedProperties);
|
|
82
|
+
if (
|
|
83
|
+
changedProperties.has("direction") ||
|
|
84
|
+
changedProperties.has("gap") ||
|
|
85
|
+
changedProperties.has("align") ||
|
|
86
|
+
changedProperties.has("justify")
|
|
87
|
+
) {
|
|
88
|
+
this.validateProps();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private validateProps(): void {
|
|
93
|
+
validateResponsiveToken(this.direction, FLEX_DIRECTION_VALUES, "direction", "ds-flow");
|
|
94
|
+
validateResponsiveToken(this.gap, SPACING_TOKENS, "gap", "ds-flow");
|
|
95
|
+
validateToken(this.align, FLEX_ALIGN_VALUES, "align", "ds-flow");
|
|
96
|
+
validateToken(this.justify, FLEX_JUSTIFY_VALUES, "justify", "ds-flow");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
override render(): TemplateResult {
|
|
100
|
+
// Get base values for data attributes
|
|
101
|
+
const baseDirection = isResponsiveValue(this.direction)
|
|
102
|
+
? getBaseValue<FlexDirection>(this.direction)
|
|
103
|
+
: (this.direction as FlexDirection);
|
|
104
|
+
|
|
105
|
+
const baseGap = isResponsiveValue(this.gap)
|
|
106
|
+
? getBaseValue<SpacingToken>(this.gap)
|
|
107
|
+
: (this.gap as SpacingToken);
|
|
108
|
+
|
|
109
|
+
// Generate responsive classes
|
|
110
|
+
const directionClasses = isResponsiveValue(this.direction)
|
|
111
|
+
? generateResponsiveClasses("flow", "dir", this.direction)
|
|
112
|
+
: [];
|
|
113
|
+
|
|
114
|
+
const gapClasses = isResponsiveValue(this.gap)
|
|
115
|
+
? generateResponsiveClasses("flow", "gap", this.gap)
|
|
116
|
+
: [];
|
|
117
|
+
|
|
118
|
+
const classes = {
|
|
119
|
+
"ds-flow": true,
|
|
120
|
+
"ds-flow--inline": this.inline,
|
|
121
|
+
...Object.fromEntries(directionClasses.map((c) => [c, true])),
|
|
122
|
+
...Object.fromEntries(gapClasses.map((c) => [c, true])),
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
return html`
|
|
126
|
+
<div
|
|
127
|
+
class=${classMap(classes)}
|
|
128
|
+
data-direction=${baseDirection}
|
|
129
|
+
data-gap=${baseGap}
|
|
130
|
+
data-align=${this.align}
|
|
131
|
+
data-justify=${this.justify}
|
|
132
|
+
data-wrap=${this.wrap}
|
|
133
|
+
data-layout="flow"
|
|
134
|
+
>
|
|
135
|
+
<slot></slot>
|
|
136
|
+
</div>
|
|
137
|
+
`;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Register the component
|
|
142
|
+
define("ds-flow", DsFlow);
|
|
143
|
+
|
|
144
|
+
// TypeScript declaration for HTML
|
|
145
|
+
declare global {
|
|
146
|
+
interface HTMLElementTagNameMap {
|
|
147
|
+
"ds-flow": DsFlow;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Footer Web Component
|
|
3
|
+
*
|
|
4
|
+
* Landmark footer with sticky and safe-area support.
|
|
5
|
+
*
|
|
6
|
+
* @element ds-footer
|
|
7
|
+
* @slot - Default slot for footer content
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { type TemplateResult, html } from "lit";
|
|
11
|
+
import { property } from "lit/decorators.js";
|
|
12
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
13
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
14
|
+
import { define } from "../../registry/define.js";
|
|
15
|
+
|
|
16
|
+
export class DsFooter extends DSElement {
|
|
17
|
+
static override styles = [];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Enable sticky positioning.
|
|
21
|
+
*/
|
|
22
|
+
@property({ type: Boolean, reflect: true })
|
|
23
|
+
sticky = false;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Enable safe area insets.
|
|
27
|
+
*/
|
|
28
|
+
@property({ type: Boolean, reflect: true, attribute: "safe-area" })
|
|
29
|
+
safeArea = false;
|
|
30
|
+
|
|
31
|
+
override render(): TemplateResult {
|
|
32
|
+
const classes = {
|
|
33
|
+
"ds-footer": true,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return html`
|
|
37
|
+
<footer
|
|
38
|
+
class=${classMap(classes)}
|
|
39
|
+
?data-sticky=${this.sticky}
|
|
40
|
+
?data-safe-area=${this.safeArea}
|
|
41
|
+
data-layout="footer"
|
|
42
|
+
>
|
|
43
|
+
<slot></slot>
|
|
44
|
+
</footer>
|
|
45
|
+
`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Register the component
|
|
50
|
+
define("ds-footer", DsFooter);
|
|
51
|
+
|
|
52
|
+
// TypeScript declaration for HTML
|
|
53
|
+
declare global {
|
|
54
|
+
interface HTMLElementTagNameMap {
|
|
55
|
+
"ds-footer": DsFooter;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid Web Component
|
|
3
|
+
*
|
|
4
|
+
* 2D grid layout with responsive columns.
|
|
5
|
+
*
|
|
6
|
+
* @element ds-grid
|
|
7
|
+
* @slot - Default slot for grid items
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { type TemplateResult, html } from "lit";
|
|
11
|
+
import { property } from "lit/decorators.js";
|
|
12
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
13
|
+
import { DSElement } from "../../base/ds-element.js";
|
|
14
|
+
import { define } from "../../registry/define.js";
|
|
15
|
+
import type { SpacingToken } from "../../types/layout-tokens.js";
|
|
16
|
+
import { SPACING_TOKENS } from "../../types/layout-tokens.js";
|
|
17
|
+
import {
|
|
18
|
+
generateResponsiveClasses,
|
|
19
|
+
getBaseValue,
|
|
20
|
+
isResponsiveValue,
|
|
21
|
+
} from "../../utils/responsive.js";
|
|
22
|
+
import { validateResponsiveToken, validateToken } from "../../utils/token-validator.js";
|
|
23
|
+
|
|
24
|
+
const COLUMN_VALUES = [
|
|
25
|
+
"1",
|
|
26
|
+
"2",
|
|
27
|
+
"3",
|
|
28
|
+
"4",
|
|
29
|
+
"5",
|
|
30
|
+
"6",
|
|
31
|
+
"7",
|
|
32
|
+
"8",
|
|
33
|
+
"9",
|
|
34
|
+
"10",
|
|
35
|
+
"11",
|
|
36
|
+
"12",
|
|
37
|
+
"auto-fit",
|
|
38
|
+
"auto-fill",
|
|
39
|
+
] as const;
|
|
40
|
+
|
|
41
|
+
export class DsGrid extends DSElement {
|
|
42
|
+
static override styles = [];
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Number of columns. Supports responsive syntax: "base:1 md:2 lg:3"
|
|
46
|
+
*/
|
|
47
|
+
@property({ type: String, reflect: true })
|
|
48
|
+
columns = "1";
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Gap between grid items. Supports responsive syntax: "base:sm lg:lg"
|
|
52
|
+
*/
|
|
53
|
+
@property({ type: String, reflect: true })
|
|
54
|
+
gap = "md";
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Row gap override.
|
|
58
|
+
*/
|
|
59
|
+
@property({ type: String, reflect: true, attribute: "row-gap" })
|
|
60
|
+
rowGap?: SpacingToken;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Column gap override.
|
|
64
|
+
*/
|
|
65
|
+
@property({ type: String, reflect: true, attribute: "column-gap" })
|
|
66
|
+
columnGap?: SpacingToken;
|
|
67
|
+
|
|
68
|
+
override connectedCallback(): void {
|
|
69
|
+
super.connectedCallback();
|
|
70
|
+
this.validateProps();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
override updated(changedProperties: Map<string, unknown>): void {
|
|
74
|
+
super.updated(changedProperties);
|
|
75
|
+
if (
|
|
76
|
+
changedProperties.has("columns") ||
|
|
77
|
+
changedProperties.has("gap") ||
|
|
78
|
+
changedProperties.has("rowGap") ||
|
|
79
|
+
changedProperties.has("columnGap")
|
|
80
|
+
) {
|
|
81
|
+
this.validateProps();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private validateProps(): void {
|
|
86
|
+
validateResponsiveToken(this.columns, COLUMN_VALUES, "columns", "ds-grid");
|
|
87
|
+
validateResponsiveToken(this.gap, SPACING_TOKENS, "gap", "ds-grid");
|
|
88
|
+
if (this.rowGap) {
|
|
89
|
+
validateToken(this.rowGap, SPACING_TOKENS, "row-gap", "ds-grid");
|
|
90
|
+
}
|
|
91
|
+
if (this.columnGap) {
|
|
92
|
+
validateToken(this.columnGap, SPACING_TOKENS, "column-gap", "ds-grid");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
override render(): TemplateResult {
|
|
97
|
+
// Get base values for data attributes
|
|
98
|
+
const baseColumns = isResponsiveValue(this.columns) ? getBaseValue(this.columns) : this.columns;
|
|
99
|
+
|
|
100
|
+
const baseGap = isResponsiveValue(this.gap)
|
|
101
|
+
? getBaseValue<SpacingToken>(this.gap)
|
|
102
|
+
: (this.gap as SpacingToken);
|
|
103
|
+
|
|
104
|
+
// Generate responsive classes
|
|
105
|
+
const columnsClasses = isResponsiveValue(this.columns)
|
|
106
|
+
? generateResponsiveClasses("grid", "cols", this.columns)
|
|
107
|
+
: [];
|
|
108
|
+
|
|
109
|
+
const gapClasses = isResponsiveValue(this.gap)
|
|
110
|
+
? generateResponsiveClasses("grid", "gap", this.gap)
|
|
111
|
+
: [];
|
|
112
|
+
|
|
113
|
+
const classes = {
|
|
114
|
+
"ds-grid": true,
|
|
115
|
+
...Object.fromEntries(columnsClasses.map((c) => [c, true])),
|
|
116
|
+
...Object.fromEntries(gapClasses.map((c) => [c, true])),
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
return html`
|
|
120
|
+
<div
|
|
121
|
+
class=${classMap(classes)}
|
|
122
|
+
data-columns=${baseColumns}
|
|
123
|
+
data-gap=${baseGap}
|
|
124
|
+
data-row-gap=${this.rowGap || ""}
|
|
125
|
+
data-column-gap=${this.columnGap || ""}
|
|
126
|
+
data-layout="grid"
|
|
127
|
+
>
|
|
128
|
+
<slot></slot>
|
|
129
|
+
</div>
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Register the component
|
|
135
|
+
define("ds-grid", DsGrid);
|
|
136
|
+
|
|
137
|
+
// TypeScript declaration for HTML
|
|
138
|
+
declare global {
|
|
139
|
+
interface HTMLElementTagNameMap {
|
|
140
|
+
"ds-grid": DsGrid;
|
|
141
|
+
}
|
|
142
|
+
}
|