@svelte-atoms/core 1.0.0-alpha.25 β 1.0.0-alpha.27
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/README.md +645 -645
- package/dist/components/accordion/accordion-root.svelte +61 -79
- package/dist/components/accordion/accordion-root.svelte.d.ts +2 -15
- package/dist/components/accordion/index.d.ts +2 -1
- package/dist/components/accordion/index.js +2 -1
- package/dist/components/accordion/item/accordion-item-body.svelte +42 -52
- package/dist/components/accordion/item/accordion-item-body.svelte.d.ts +2 -8
- package/dist/components/accordion/item/accordion-item-header.svelte +50 -56
- package/dist/components/accordion/item/accordion-item-header.svelte.d.ts +3 -20
- package/dist/components/accordion/item/accordion-item-indicator.svelte +50 -59
- package/dist/components/accordion/item/accordion-item-indicator.svelte.d.ts +2 -8
- package/dist/components/accordion/item/accordion-item-root.svelte +65 -79
- package/dist/components/accordion/item/accordion-item-root.svelte.d.ts +2 -12
- package/dist/components/accordion/item/index.d.ts +1 -0
- package/dist/components/accordion/item/types.d.ts +52 -0
- package/dist/components/accordion/item/types.js +1 -0
- package/dist/components/accordion/types.d.ts +21 -0
- package/dist/components/accordion/types.js +1 -0
- package/dist/components/alert/alert-actions.svelte +42 -52
- package/dist/components/alert/alert-actions.svelte.d.ts +3 -30
- package/dist/components/alert/alert-close-button.svelte +72 -79
- package/dist/components/alert/alert-close-button.svelte.d.ts +8 -35
- package/dist/components/alert/alert-content.svelte +42 -52
- package/dist/components/alert/alert-content.svelte.d.ts +3 -30
- package/dist/components/alert/alert-description.svelte +41 -51
- package/dist/components/alert/alert-description.svelte.d.ts +7 -10
- package/dist/components/alert/alert-icon.svelte +46 -56
- package/dist/components/alert/alert-icon.svelte.d.ts +2 -8
- package/dist/components/alert/alert-root.svelte +102 -118
- package/dist/components/alert/alert-root.svelte.d.ts +2 -13
- package/dist/components/alert/alert-title.svelte +41 -51
- package/dist/components/alert/alert-title.svelte.d.ts +2 -8
- package/dist/components/alert/index.d.ts +1 -0
- package/dist/components/alert/index.js +1 -0
- package/dist/components/alert/types.d.ts +85 -0
- package/dist/components/alert/types.js +1 -0
- package/dist/components/atom/html-atom.svelte +201 -217
- package/dist/components/atom/html-atom.svelte.d.ts +2 -22
- package/dist/components/atom/types.d.ts +7 -2
- package/dist/components/avatar/types.d.ts +7 -2
- package/dist/components/badge/badge.svelte +1 -1
- package/dist/components/badge/types.d.ts +7 -2
- package/dist/components/breadcrumb/breadcrumb-item.svelte +1 -1
- package/dist/components/breadcrumb/breadcrumb-root.svelte +1 -1
- package/dist/components/breadcrumb/breadcrumb-separator.svelte +1 -1
- package/dist/components/button/button.stories.svelte +57 -57
- package/dist/components/button/button.svelte +1 -1
- package/dist/components/button/button.svelte.d.ts +4 -1
- package/dist/components/button/index.d.ts +1 -0
- package/dist/components/button/index.js +1 -0
- package/dist/components/button/types.d.ts +8 -3
- package/dist/components/card/card-body.svelte +39 -45
- package/dist/components/card/card-body.svelte.d.ts +7 -4
- package/dist/components/card/card-description.svelte +41 -48
- package/dist/components/card/card-description.svelte.d.ts +7 -7
- package/dist/components/card/card-footer.svelte +41 -48
- package/dist/components/card/card-footer.svelte.d.ts +7 -4
- package/dist/components/card/card-header.svelte +41 -48
- package/dist/components/card/card-header.svelte.d.ts +7 -4
- package/dist/components/card/card-media.svelte +41 -48
- package/dist/components/card/card-media.svelte.d.ts +7 -4
- package/dist/components/card/card-root.svelte +91 -91
- package/dist/components/card/card-root.svelte.d.ts +1 -1
- package/dist/components/card/card-subtitle.svelte +41 -48
- package/dist/components/card/card-subtitle.svelte.d.ts +12 -9
- package/dist/components/card/card-title.svelte +45 -48
- package/dist/components/card/card-title.svelte.d.ts +12 -9
- package/dist/components/card/index.d.ts +1 -0
- package/dist/components/card/index.js +1 -0
- package/dist/components/card/types.d.ts +57 -2
- package/dist/components/checkbox/checkbox.svelte +39 -28
- package/dist/components/checkbox/types.d.ts +7 -2
- package/dist/components/collapsible/collapsible-body.svelte +39 -52
- package/dist/components/collapsible/collapsible-body.svelte.d.ts +2 -9
- package/dist/components/collapsible/collapsible-header.svelte +39 -52
- package/dist/components/collapsible/collapsible-header.svelte.d.ts +2 -9
- package/dist/components/collapsible/collapsible-indicator.svelte +50 -65
- package/dist/components/collapsible/collapsible-indicator.svelte.d.ts +3 -10
- package/dist/components/collapsible/collapsible-root.svelte +66 -85
- package/dist/components/collapsible/collapsible-root.svelte.d.ts +2 -14
- package/dist/components/collapsible/index.d.ts +1 -0
- package/dist/components/collapsible/index.js +1 -0
- package/dist/components/collapsible/types.d.ts +54 -0
- package/dist/components/collapsible/types.js +1 -0
- package/dist/components/combobox/atoms.d.ts +5 -1
- package/dist/components/combobox/atoms.js +5 -1
- package/dist/components/combobox/{combobox-input.svelte β combobox-control.svelte} +3 -3
- package/dist/components/combobox/{combobox-input.svelte.d.ts β combobox-control.svelte.d.ts} +3 -3
- package/dist/components/combobox/combobox-root.svelte +65 -68
- package/dist/components/combobox/combobox-root.svelte.d.ts +5 -18
- package/dist/components/combobox/combobox-trigger.svelte +1 -1
- package/dist/components/combobox/compobox-item.svelte +1 -1
- package/dist/components/combobox/index.d.ts +1 -0
- package/dist/components/combobox/index.js +1 -0
- package/dist/components/combobox/types.d.ts +25 -0
- package/dist/components/combobox/types.js +1 -0
- package/dist/components/container/container.svelte +1 -1
- package/dist/components/container/types.d.ts +7 -2
- package/dist/components/contextmenu/types.d.ts +8 -0
- package/dist/components/contextmenu/types.js +1 -0
- package/dist/components/datagrid/datagrid-body.svelte +37 -44
- package/dist/components/datagrid/datagrid-body.svelte.d.ts +17 -20
- package/dist/components/datagrid/datagrid-checkbox.svelte +101 -108
- package/dist/components/datagrid/datagrid-checkbox.svelte.d.ts +4 -6
- package/dist/components/datagrid/datagrid-footer.svelte +34 -34
- package/dist/components/datagrid/datagrid-footer.svelte.d.ts +1 -1
- package/dist/components/datagrid/datagrid-header.svelte +49 -49
- package/dist/components/datagrid/datagrid-header.svelte.d.ts +1 -1
- package/dist/components/datagrid/datagrid-root.svelte +59 -59
- package/dist/components/datagrid/datagrid-root.svelte.d.ts +1 -1
- package/dist/components/datagrid/datagrid.stories.svelte +75 -75
- package/dist/components/datagrid/td/datagrid-td.svelte +66 -80
- package/dist/components/datagrid/td/datagrid-td.svelte.d.ts +7 -16
- package/dist/components/datagrid/th/datagrid-th-sort-icon.svelte +1 -1
- package/dist/components/datagrid/th/datagrid-th.svelte +106 -127
- package/dist/components/datagrid/th/datagrid-th.svelte.d.ts +2 -20
- package/dist/components/datagrid/tr/bond.svelte.d.ts +3 -1
- package/dist/components/datagrid/tr/bond.svelte.js +4 -2
- package/dist/components/datagrid/tr/datagrid-tr.svelte +88 -103
- package/dist/components/datagrid/tr/datagrid-tr.svelte.d.ts +2 -18
- package/dist/components/datagrid/types.d.ts +85 -37
- package/dist/components/dialog/dialog-body.svelte +39 -45
- package/dist/components/dialog/dialog-body.svelte.d.ts +2 -2
- package/dist/components/dialog/dialog-close-button.svelte +58 -61
- package/dist/components/dialog/dialog-close-button.svelte.d.ts +7 -7
- package/dist/components/dialog/dialog-content.svelte +62 -71
- package/dist/components/dialog/dialog-content.svelte.d.ts +2 -2
- package/dist/components/dialog/dialog-description.svelte +40 -46
- package/dist/components/dialog/dialog-description.svelte.d.ts +2 -2
- package/dist/components/dialog/dialog-footer.svelte +39 -45
- package/dist/components/dialog/dialog-footer.svelte.d.ts +2 -2
- package/dist/components/dialog/dialog-header.svelte +39 -45
- package/dist/components/dialog/dialog-header.svelte.d.ts +2 -2
- package/dist/components/dialog/dialog-root.svelte +110 -120
- package/dist/components/dialog/dialog-root.svelte.d.ts +2 -10
- package/dist/components/dialog/dialog-title.svelte +41 -47
- package/dist/components/dialog/dialog-title.svelte.d.ts +7 -7
- package/dist/components/dialog/index.d.ts +1 -0
- package/dist/components/dialog/index.js +1 -0
- package/dist/components/dialog/types.d.ts +67 -0
- package/dist/components/dialog/types.js +1 -0
- package/dist/components/divider/types.d.ts +10 -0
- package/dist/components/divider/types.js +1 -0
- package/dist/components/drawer/drawer-backdrop.svelte +38 -47
- package/dist/components/drawer/drawer-backdrop.svelte.d.ts +3 -26
- package/dist/components/drawer/drawer-body.svelte +42 -56
- package/dist/components/drawer/drawer-body.svelte.d.ts +3 -16
- package/dist/components/drawer/drawer-content.svelte +42 -55
- package/dist/components/drawer/drawer-content.svelte.d.ts +3 -14
- package/dist/components/drawer/drawer-description.svelte +44 -57
- package/dist/components/drawer/drawer-description.svelte.d.ts +3 -14
- package/dist/components/drawer/drawer-footer.svelte +41 -54
- package/dist/components/drawer/drawer-footer.svelte.d.ts +3 -14
- package/dist/components/drawer/drawer-header.svelte +43 -56
- package/dist/components/drawer/drawer-header.svelte.d.ts +3 -14
- package/dist/components/drawer/drawer-root.svelte +93 -113
- package/dist/components/drawer/drawer-root.svelte.d.ts +3 -31
- package/dist/components/drawer/drawer-title.svelte +44 -57
- package/dist/components/drawer/drawer-title.svelte.d.ts +3 -14
- package/dist/components/drawer/index.d.ts +1 -0
- package/dist/components/drawer/index.js +1 -0
- package/dist/components/drawer/types.d.ts +86 -0
- package/dist/components/drawer/types.js +1 -0
- package/dist/components/dropdown/dropdown-placeholder.svelte +1 -1
- package/dist/components/dropdown/dropdown-query.svelte +54 -53
- package/dist/components/dropdown/dropdown-query.svelte.d.ts +11 -10
- package/dist/components/dropdown/dropdown-root.svelte +59 -59
- package/dist/components/dropdown/dropdown-trigger.svelte +41 -52
- package/dist/components/dropdown/dropdown-trigger.svelte.d.ts +1 -8
- package/dist/components/dropdown/dropdown-value.svelte +60 -62
- package/dist/components/dropdown/index.d.ts +1 -0
- package/dist/components/dropdown/index.js +1 -0
- package/dist/components/dropdown/item/bond.svelte.d.ts +4 -0
- package/dist/components/dropdown/item/bond.svelte.js +9 -0
- package/dist/components/dropdown/item/dropdown-item.svelte +10 -6
- package/dist/components/dropdown/types.d.ts +37 -0
- package/dist/components/dropdown/types.js +1 -0
- package/dist/components/element/html-element.svelte.d.ts +2 -14
- package/dist/components/element/svg-element.svelte.d.ts +2 -14
- package/dist/components/element/types.d.ts +14 -7
- package/dist/components/form/field/bond.svelte.d.ts +8 -0
- package/dist/components/form/field/bond.svelte.js +13 -1
- package/dist/components/form/field/field-control.svelte +48 -58
- package/dist/components/form/field/field-control.svelte.d.ts +5 -19
- package/dist/components/form/field/field-label.svelte +24 -31
- package/dist/components/form/field/field-label.svelte.d.ts +1 -2
- package/dist/components/form/field/field-root.svelte +59 -88
- package/dist/components/form/field/field-root.svelte.d.ts +5 -20
- package/dist/components/form/form.stories.svelte +3 -3
- package/dist/components/form/index.d.ts +1 -0
- package/dist/components/form/index.js +1 -0
- package/dist/components/form/types.d.ts +76 -0
- package/dist/components/form/types.js +1 -0
- package/dist/components/icon/icon.svelte +44 -55
- package/dist/components/icon/icon.svelte.d.ts +4 -29
- package/dist/components/icon/types.d.ts +11 -7
- package/dist/components/input/atoms.d.ts +5 -1
- package/dist/components/input/atoms.js +5 -1
- package/dist/components/input/index.d.ts +1 -0
- package/dist/components/input/index.js +1 -0
- package/dist/components/input/{input-value.svelte β input-control.svelte} +14 -24
- package/dist/components/input/input-control.svelte.d.ts +26 -0
- package/dist/components/input/input-icon.svelte +1 -1
- package/dist/components/input/input-icon.svelte.d.ts +1 -1
- package/dist/components/input/input-placeholder.svelte +54 -56
- package/dist/components/input/input-placeholder.svelte.d.ts +2 -19
- package/dist/components/input/input-root.svelte +5 -12
- package/dist/components/input/input-root.svelte.d.ts +3 -20
- package/dist/components/input/input.stories.svelte +2 -2
- package/dist/components/input/types.d.ts +33 -0
- package/dist/components/input/types.js +1 -0
- package/dist/components/label/index.d.ts +1 -0
- package/dist/components/label/index.js +1 -0
- package/dist/components/label/label.svelte +25 -41
- package/dist/components/label/label.svelte.d.ts +3 -27
- package/dist/components/label/types.d.ts +11 -0
- package/dist/components/label/types.js +1 -0
- package/dist/components/layer/layer-inner.svelte.d.ts +2 -19
- package/dist/components/layer/layer-root.svelte.d.ts +2 -19
- package/dist/components/layer/types.d.ts +11 -0
- package/dist/components/layer/types.js +1 -0
- package/dist/components/link/types.d.ts +8 -0
- package/dist/components/link/types.js +1 -0
- package/dist/components/list/list-group.svelte +1 -1
- package/dist/components/list/list-item.svelte +1 -1
- package/dist/components/list/list-root.svelte +6 -1
- package/dist/components/list/list-title.svelte +1 -1
- package/dist/components/list/types.d.ts +8 -0
- package/dist/components/list/types.js +1 -0
- package/dist/components/menu/index.d.ts +1 -0
- package/dist/components/menu/index.js +1 -0
- package/dist/components/menu/menu-list.svelte +1 -1
- package/dist/components/menu/types.d.ts +15 -0
- package/dist/components/menu/types.js +1 -0
- package/dist/components/popover/bond.svelte.d.ts +2 -0
- package/dist/components/popover/bond.svelte.js +1 -1
- package/dist/components/popover/index.d.ts +1 -0
- package/dist/components/popover/index.js +1 -0
- package/dist/components/popover/popover-arrow.svelte +111 -117
- package/dist/components/popover/popover-arrow.svelte.d.ts +3 -20
- package/dist/components/popover/popover-content.svelte +139 -147
- package/dist/components/popover/popover-content.svelte.d.ts +3 -17
- package/dist/components/popover/popover-indicator.svelte +1 -1
- package/dist/components/popover/popover-root.svelte +4 -18
- package/dist/components/popover/popover-root.svelte.d.ts +1 -15
- package/dist/components/popover/popover-trigger.svelte +3 -12
- package/dist/components/popover/popover-trigger.svelte.d.ts +2 -8
- package/dist/components/popover/types.d.ts +61 -0
- package/dist/components/popover/types.js +1 -0
- package/dist/components/portal/active-portal.svelte +8 -2
- package/dist/components/portal/active-portal.svelte.d.ts +2 -2
- package/dist/components/portal/index.d.ts +1 -0
- package/dist/components/portal/index.js +1 -0
- package/dist/components/portal/portal-inner.svelte +1 -1
- package/dist/components/portal/portal-inner.svelte.d.ts +2 -19
- package/dist/components/portal/portal-root.svelte +83 -88
- package/dist/components/portal/portal-root.svelte.d.ts +2 -22
- package/dist/components/portal/teleport.svelte +50 -49
- package/dist/components/portal/teleport.svelte.d.ts +5 -23
- package/dist/components/portal/types.d.ts +39 -0
- package/dist/components/portal/types.js +1 -0
- package/dist/components/radio/radio-group.stories.svelte +4 -4
- package/dist/components/radio/radio.svelte +109 -109
- package/dist/components/radio/radio.svelte.d.ts +14 -36
- package/dist/components/root/root.css +24 -66
- package/dist/components/root/root.svelte +121 -121
- package/dist/components/root/types.d.ts +8 -0
- package/dist/components/root/types.js +1 -0
- package/dist/components/scrollable/index.d.ts +1 -0
- package/dist/components/scrollable/index.js +1 -0
- package/dist/components/scrollable/scrollable-container.svelte +82 -89
- package/dist/components/scrollable/scrollable-container.svelte.d.ts +2 -6
- package/dist/components/scrollable/scrollable-content.svelte +41 -51
- package/dist/components/scrollable/scrollable-content.svelte.d.ts +1 -6
- package/dist/components/scrollable/scrollable-root.svelte +100 -120
- package/dist/components/scrollable/scrollable-root.svelte.d.ts +3 -19
- package/dist/components/scrollable/scrollable-thumb.svelte +75 -86
- package/dist/components/scrollable/scrollable-thumb.svelte.d.ts +1 -7
- package/dist/components/scrollable/scrollable-track.svelte +59 -70
- package/dist/components/scrollable/scrollable-track.svelte.d.ts +1 -7
- package/dist/components/scrollable/types.d.ts +62 -0
- package/dist/components/scrollable/types.js +1 -0
- package/dist/components/sidebar/index.d.ts +1 -0
- package/dist/components/sidebar/index.js +1 -0
- package/dist/components/sidebar/sidebar-content.svelte +2 -16
- package/dist/components/sidebar/sidebar-content.svelte.d.ts +2 -9
- package/dist/components/sidebar/sidebar-root.svelte +4 -23
- package/dist/components/sidebar/sidebar-root.svelte.d.ts +2 -13
- package/dist/components/sidebar/types.d.ts +30 -0
- package/dist/components/sidebar/types.js +1 -0
- package/dist/components/stack/stack-item.svelte +5 -1
- package/dist/components/stack/stack-root.svelte +5 -1
- package/dist/components/stack/stack-root.svelte.d.ts +2 -19
- package/dist/components/stack/types.d.ts +12 -0
- package/dist/components/stack/types.js +1 -0
- package/dist/components/tabs/index.d.ts +1 -0
- package/dist/components/tabs/index.js +1 -0
- package/dist/components/tabs/tab/tab-body.svelte +52 -61
- package/dist/components/tabs/tab/tab-body.svelte.d.ts +2 -8
- package/dist/components/tabs/tab/tab-description.svelte +41 -50
- package/dist/components/tabs/tab/tab-description.svelte.d.ts +2 -8
- package/dist/components/tabs/tab/tab-header.svelte +71 -81
- package/dist/components/tabs/tab/tab-header.svelte.d.ts +2 -11
- package/dist/components/tabs/tab/tab-root.svelte +86 -81
- package/dist/components/tabs/tabs-body.svelte +1 -1
- package/dist/components/tabs/tabs-header.svelte +1 -1
- package/dist/components/tabs/tabs-root.svelte +1 -1
- package/dist/components/tabs/types.d.ts +55 -0
- package/dist/components/tabs/types.js +1 -0
- package/dist/components/textarea/index.d.ts +1 -0
- package/dist/components/textarea/index.js +1 -0
- package/dist/components/textarea/textarea-input.svelte +2 -1
- package/dist/components/textarea/types.d.ts +28 -0
- package/dist/components/textarea/types.js +1 -0
- package/dist/components/toast/index.d.ts +1 -0
- package/dist/components/toast/index.js +1 -0
- package/dist/components/toast/toast-description.svelte +38 -44
- package/dist/components/toast/toast-description.svelte.d.ts +8 -34
- package/dist/components/toast/toast-root.svelte +61 -74
- package/dist/components/toast/toast-root.svelte.d.ts +4 -43
- package/dist/components/toast/toast-title.svelte +35 -43
- package/dist/components/toast/toast-title.svelte.d.ts +2 -34
- package/dist/components/toast/types.d.ts +40 -0
- package/dist/components/toast/types.js +1 -0
- package/dist/components/tooltip/types.d.ts +13 -0
- package/dist/components/tooltip/types.js +1 -0
- package/dist/components/tree/index.d.ts +1 -0
- package/dist/components/tree/index.js +1 -0
- package/dist/components/tree/tree-body.svelte +39 -50
- package/dist/components/tree/tree-body.svelte.d.ts +2 -10
- package/dist/components/tree/tree-header.svelte +54 -66
- package/dist/components/tree/tree-header.svelte.d.ts +3 -29
- package/dist/components/tree/tree-indicator.svelte +40 -50
- package/dist/components/tree/tree-indicator.svelte.d.ts +3 -9
- package/dist/components/tree/tree-root.svelte +65 -80
- package/dist/components/tree/tree-root.svelte.d.ts +2 -12
- package/dist/components/tree/types.d.ts +59 -0
- package/dist/components/tree/types.js +1 -0
- package/dist/components/virtual/types.d.ts +23 -0
- package/dist/components/virtual/types.js +1 -0
- package/dist/components/virtual/virtual-root.svelte +239 -258
- package/dist/components/virtual/virtual-root.svelte.d.ts +1 -18
- package/dist/context/preset.svelte.d.ts +1 -1
- package/llm/composition.md +395 -395
- package/llm/crafting.md +838 -838
- package/llm/motion.md +970 -970
- package/llm/philosophy.md +23 -23
- package/llm/preset-variant-integration.md +516 -516
- package/llm/preset.md +383 -383
- package/llm/styling.md +216 -216
- package/llm/usage.md +46 -46
- package/llm/variants.md +712 -712
- package/package.json +437 -437
- package/dist/components/input/input-value.svelte.d.ts +0 -19
package/README.md
CHANGED
|
@@ -1,645 +1,645 @@
|
|
|
1
|
-
# βοΈ @svelte-atoms/core
|
|
2
|
-
|
|
3
|
-
> A modern, modular, and accessible Svelte 5 UI component library built with composability at its core.
|
|
4
|
-
|
|
5
|
-
**@svelte-atoms/core** is a comprehensive Svelte component library that provides fundamental building blocks ("atoms") for creating sophisticated, interactive design systems. Each component is designed with accessibility, type safety, and developer experience in mind. Built with Svelte 5 runes for optimal reactivity and performance.
|
|
6
|
-
|
|
7
|
-
[](https://www.npmjs.com/package/@svelte-atoms/core)
|
|
8
|
-
[ | Collapsible content sections | β
|
|
|
58
|
-
| [**Breadcrumb**](docs/components/breadcrumb.md) | Navigation hierarchy | β
|
|
|
59
|
-
| [**Sidebar**](docs/components/sidebar.md) | Collapsible side navigation | β
|
|
|
60
|
-
| [**Tabs**](docs/components/tabs.md) | Tabbed interfaces | β
|
|
|
61
|
-
| [**Tree**](docs/components/tree.md) | Hierarchical data structures | β
|
|
|
62
|
-
| **Stepper** | Multi-step process indicator | β |
|
|
63
|
-
| **Pagination** | Page navigation controls | β |
|
|
64
|
-
|
|
65
|
-
### Forms & Input
|
|
66
|
-
|
|
67
|
-
| Component | Description | Status |
|
|
68
|
-
| ------------------------------------------- | ------------------------------------ | ------ |
|
|
69
|
-
| [**Button**](docs/components/button.md) | Interactive buttons with variants | β
|
|
|
70
|
-
| [**Checkbox**](docs/components/checkbox.md) | Multi-select inputs | β
|
|
|
71
|
-
| [**Combobox**](docs/components/combobox.md) | Searchable select inputs | β
|
|
|
72
|
-
| [**Input**](docs/components/input.md) | Text input fields | β
|
|
|
73
|
-
| [**Radio**](docs/components/radio.md) | Single-select inputs | β
|
|
|
74
|
-
| **Slider** | Range input controls | β |
|
|
75
|
-
| **Switch** | Toggle controls | β |
|
|
76
|
-
| [**Textarea**](docs/components/textarea.md) | Multi-line text inputs | β
|
|
|
77
|
-
| [**Form**](docs/components/form.md) | Form validation and state management | β
|
|
|
78
|
-
| **DatePicker** | Date selection component | β |
|
|
79
|
-
| **TimePicker** | Time selection component | β |
|
|
80
|
-
| **FileUpload** | File upload component | β |
|
|
81
|
-
| **ColorPicker** | Color selection component | β |
|
|
82
|
-
| **Rating** | Star rating component | β |
|
|
83
|
-
|
|
84
|
-
### Data Display
|
|
85
|
-
|
|
86
|
-
| Component | Description | Status |
|
|
87
|
-
| ------------------------------------------- | --------------------------- | ------ |
|
|
88
|
-
| [**Avatar**](docs/components/avatar.md) | User profile images | β
|
|
|
89
|
-
| [**Badge**](docs/components/badge.md) | Status indicators | β
|
|
|
90
|
-
| [**DataGrid**](docs/components/datagrid.md) | Advanced data tables | β
|
|
|
91
|
-
| [**Divider**](docs/components/divider.md) | Content separators | β
|
|
|
92
|
-
| [**Icon**](docs/components/icon.md) | Scalable icons | β
|
|
|
93
|
-
| [**Label**](docs/components/label.md) | Form labels | β
|
|
|
94
|
-
| [**Link**](docs/components/link.md) | Navigation links | β
|
|
|
95
|
-
| [**List**](docs/components/list.md) | Structured lists | β
|
|
|
96
|
-
| [**Card**](docs/components/card.md) | Content containers | β
|
|
|
97
|
-
| **Table** | Simple data tables | β |
|
|
98
|
-
| **Chip** | Compact information display | β |
|
|
99
|
-
| **Progress** | Progress indicators | β |
|
|
100
|
-
| **Skeleton** | Loading placeholders | β |
|
|
101
|
-
| **Timeline** | Event timeline display | β |
|
|
102
|
-
| **Calendar** | Date display component | β |
|
|
103
|
-
|
|
104
|
-
### Overlays & Feedback
|
|
105
|
-
|
|
106
|
-
| Component | Description | Status |
|
|
107
|
-
| ------------------------------------------------- | ------------------------ | ------ |
|
|
108
|
-
| [**Dialog**](docs/components/dialog.md) | Modal dialogs | β
|
|
|
109
|
-
| [**Dropdown**](docs/components/dropdown.md) | Contextual menus | β
|
|
|
110
|
-
| [**Popover**](docs/components/popover.md) | Contextual information | β
|
|
|
111
|
-
| [**Toast**](docs/components/toast.md) | Notification messages | β
|
|
|
112
|
-
| [**Tooltip**](docs/components/tooltip.md) | Contextual hints | β
|
|
|
113
|
-
| [**ContextMenu**](docs/components/contextmenu.md) | Right-click menus | β
|
|
|
114
|
-
| [**Drawer**](docs/components/drawer.md) | Slide-out panels | β
|
|
|
115
|
-
| [**Alert**](docs/components/alert.md) | Alert messages | β
|
|
|
116
|
-
| **Banner** | Full-width notifications | β |
|
|
117
|
-
| **Spotlight** | Feature highlighting | β |
|
|
118
|
-
|
|
119
|
-
### Utilities & Layout
|
|
120
|
-
|
|
121
|
-
| Component | Description | Status |
|
|
122
|
-
| ------------------------------------------------- | ----------------------------------- | ------ |
|
|
123
|
-
| [**Portal**](docs/components/portal.md) | Declare a portal anywhere in DOM | β
|
|
|
124
|
-
| **Teleport** | Render content in a specific portal | β
|
|
|
125
|
-
| **Root** | Application root container | β
|
|
|
126
|
-
| [**Layer**](docs/components/layer.md) | Layer management utility | β
|
|
|
127
|
-
| [**Collapsible**](docs/components/collapsible.md) | Generic collapsible wrapper | β
|
|
|
128
|
-
| **Container** | Layout container | β
|
|
|
129
|
-
| [**Scrollable**](docs/components/scrollable.md) | Custom scrollbar component | β
|
|
|
130
|
-
| [**Stack**](docs/components/stack.md) | Flexible layout stacking component | β
|
|
|
131
|
-
| **Spacer** | Space management utility | β |
|
|
132
|
-
| **VirtualList** | Virtual scrolling list | β |
|
|
133
|
-
|
|
134
|
-
---
|
|
135
|
-
|
|
136
|
-
## ποΈ Architecture
|
|
137
|
-
|
|
138
|
-
The library is organized into distinct layers for maximum maintainability and extensibility:
|
|
139
|
-
|
|
140
|
-
```
|
|
141
|
-
src/lib/
|
|
142
|
-
βββ components/ # 30+ Core UI components
|
|
143
|
-
βββ shared/ # Base classes (Bond, BondState) and utilities
|
|
144
|
-
βββ helpers/ # Helper functions and components
|
|
145
|
-
βββ attachments/ # DOM attachment utilities
|
|
146
|
-
βββ runes/ # Reactive utilities (Svelte 5 runes)
|
|
147
|
-
βββ types/ # TypeScript type definitions
|
|
148
|
-
βββ utils/ # General utility functions
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Bond Pattern
|
|
152
|
-
|
|
153
|
-
Each component follows a consistent Bond pattern:
|
|
154
|
-
|
|
155
|
-
- **Bond Class**: Manages component state and DOM interactions
|
|
156
|
-
- **BondState Class**: Holds reactive component state using Svelte 5 runes
|
|
157
|
-
- **Context Methods**: Static `CONTEXT_KEY`, `get()`, and `set()` methods for component communication
|
|
158
|
-
- **Component Files**: Svelte components that use the Bond for behavior
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
class MyComponentBond extends Bond<MyComponentBondState> {
|
|
162
|
-
static CONTEXT_KEY = '@atoms/context/my-component';
|
|
163
|
-
|
|
164
|
-
static get(): MyComponentBond | undefined {
|
|
165
|
-
return getContext(MyComponentBond.CONTEXT_KEY);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
static set(bond: MyComponentBond): MyComponentBond {
|
|
169
|
-
return setContext(MyComponentBond.CONTEXT_KEY, bond);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## π Quick Start
|
|
177
|
-
|
|
178
|
-
### Installation
|
|
179
|
-
|
|
180
|
-
```bash
|
|
181
|
-
# npm
|
|
182
|
-
npm install @svelte-atoms/core
|
|
183
|
-
|
|
184
|
-
# yarn
|
|
185
|
-
yarn install @svelte-atoms/core
|
|
186
|
-
|
|
187
|
-
# pnpm
|
|
188
|
-
pnpm add @svelte-atoms/core
|
|
189
|
-
|
|
190
|
-
# bun
|
|
191
|
-
bun add @svelte-atoms/core
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Basic Usage
|
|
195
|
-
|
|
196
|
-
```svelte
|
|
197
|
-
<script lang="ts">
|
|
198
|
-
import { Button, Dialog, Input } from '@svelte-atoms/core';
|
|
199
|
-
|
|
200
|
-
let dialogOpen = $state(false);
|
|
201
|
-
let inputValue = '';
|
|
202
|
-
</script>
|
|
203
|
-
|
|
204
|
-
<!-- Simple Button -->
|
|
205
|
-
<Button onclick={() => (dialogOpen = true)}>Open Dialog</Button>
|
|
206
|
-
|
|
207
|
-
<!-- Dialog with Input -->
|
|
208
|
-
<Dialog.Root bind:open={dialogOpen}>
|
|
209
|
-
<Dialog.Content>
|
|
210
|
-
<Dialog.Header>
|
|
211
|
-
<Dialog.Title>Enter your name</Dialog.Title>
|
|
212
|
-
</Dialog.Header>
|
|
213
|
-
<Dialog.Body>
|
|
214
|
-
<Input.Root>
|
|
215
|
-
<Input.Value bind:value={inputValue} placeholder="Your name...">
|
|
216
|
-
</Input.Root>
|
|
217
|
-
</Dialog.Body>
|
|
218
|
-
<Dialog.Footer>
|
|
219
|
-
<Button.Root onclick={() => (dialogOpen = false)}>Cancel</Button.Root>
|
|
220
|
-
<Button.Root variant="primary" onclick={() => (dialogOpen = false)}>Confirm</Button.Root>
|
|
221
|
-
</Dialog.Footer>
|
|
222
|
-
</Dialog.Content>
|
|
223
|
-
</Dialog.Root>
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Advanced Usage with Bonds
|
|
227
|
-
|
|
228
|
-
For more control, you can use the Bond system directly:
|
|
229
|
-
|
|
230
|
-
```svelte
|
|
231
|
-
<script lang="ts">
|
|
232
|
-
import { DialogBond, DialogBondState } from '@svelte-atoms/core/dialog';
|
|
233
|
-
|
|
234
|
-
const { open = false, disable = false } = $props();
|
|
235
|
-
|
|
236
|
-
const bondProps = defineState(
|
|
237
|
-
[
|
|
238
|
-
defineProperty(
|
|
239
|
-
'open',
|
|
240
|
-
() => open,
|
|
241
|
-
(v) => (open = v)
|
|
242
|
-
),
|
|
243
|
-
defineProperty('disable', () => disable)
|
|
244
|
-
],
|
|
245
|
-
{
|
|
246
|
-
// Other props
|
|
247
|
-
}
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
// Create dialog state
|
|
251
|
-
const dialogState = new DialogBondState(() => bondProps);
|
|
252
|
-
|
|
253
|
-
// Create dialog bond
|
|
254
|
-
// Make available via context
|
|
255
|
-
const dialogBond = new DialogBond(dialogState).share();
|
|
256
|
-
</script>
|
|
257
|
-
|
|
258
|
-
<div {...dialogBond.root()}>
|
|
259
|
-
<button {...dialogBond.trigger()} onclick={() => dialogBond.state.toggle()}>
|
|
260
|
-
Toggle Dialog
|
|
261
|
-
</button>
|
|
262
|
-
|
|
263
|
-
{#if open}
|
|
264
|
-
<div {...dialogBond.overlay()}>
|
|
265
|
-
<div {...dialogBond.content()}>
|
|
266
|
-
<h2 {...dialogBond.title()}>Dialog Title</h2>
|
|
267
|
-
<p>Dialog content goes here...</p>
|
|
268
|
-
<button onclick={() => dialogBond.state.close()}>Close</button>
|
|
269
|
-
</div>
|
|
270
|
-
</div>
|
|
271
|
-
{/if}
|
|
272
|
-
</div>
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Advanced Usage With Composition
|
|
276
|
-
|
|
277
|
-
This example demonstrates the power of component composition by combining `Dropdown`, `Input`, and animation capabilities to create a searchable multi-select dropdown with smooth transitions:
|
|
278
|
-
|
|
279
|
-
```svelte
|
|
280
|
-
<script lang="ts">
|
|
281
|
-
import { Dropdown, Input, Root, filter } from '@svelte-atoms/core';
|
|
282
|
-
import { flip } from 'svelte/animate';
|
|
283
|
-
|
|
284
|
-
// Sample data
|
|
285
|
-
let data = [
|
|
286
|
-
{ id: 1, value: 'apple', text: 'Apple' },
|
|
287
|
-
{ id: 2, value: 'banana', text: 'Banana' },
|
|
288
|
-
{ id: 3, value: 'cherry', text: 'Cherry' },
|
|
289
|
-
{ id: 4, value: 'date', text: 'Date' },
|
|
290
|
-
{ id: 5, value: 'elderberry', text: 'Elderberry' }
|
|
291
|
-
];
|
|
292
|
-
|
|
293
|
-
let open = $state(false);
|
|
294
|
-
// Filter items based on search query
|
|
295
|
-
const dd = filter(
|
|
296
|
-
() => data,
|
|
297
|
-
(query, item) => item.text.toLowerCase().includes(query.toLowerCase())
|
|
298
|
-
);
|
|
299
|
-
</script>
|
|
300
|
-
|
|
301
|
-
<Root class="items-center justify-center p-4">
|
|
302
|
-
<!-- Multi-select dropdown with search functionality -->
|
|
303
|
-
<Dropdown.Root
|
|
304
|
-
bind:open
|
|
305
|
-
multiple
|
|
306
|
-
keys={data.map((item) => item.value)}
|
|
307
|
-
onquerychange={(q) => (dd.query = q)}
|
|
308
|
-
>
|
|
309
|
-
{#snippet children({ dropdown })}
|
|
310
|
-
<!-- Compose Dropdown.Trigger with Input.Root for a custom trigger -->
|
|
311
|
-
<Dropdown.Trigger
|
|
312
|
-
base={Input.Root}
|
|
313
|
-
class="h-auto min-h-12 max-w-sm min-w-sm items-center gap-2 rounded-sm px-4 transition-colors duration-200"
|
|
314
|
-
onclick={(ev) => {
|
|
315
|
-
ev.preventDefault();
|
|
316
|
-
|
|
317
|
-
dropdown.state.open();
|
|
318
|
-
}}
|
|
319
|
-
>
|
|
320
|
-
<!-- Display selected values with animation -->
|
|
321
|
-
{#each dropdown?.state?.selectedItems ?? [] as item (item.id)}
|
|
322
|
-
<div animate:flip={{ duration: 200 }}>
|
|
323
|
-
<ADropdown.Value value={item.value} class="text-foreground/80">
|
|
324
|
-
{item.text}
|
|
325
|
-
</ADropdown.Value>
|
|
326
|
-
</div>
|
|
327
|
-
{/each}
|
|
328
|
-
|
|
329
|
-
<!-- Inline search input within the trigger -->
|
|
330
|
-
<Dropdown.Query class="flex-1 px-1" placeholder="Search for fruits..." />
|
|
331
|
-
</Dropdown.Trigger>
|
|
332
|
-
|
|
333
|
-
<!-- Dropdown list with filtered items -->
|
|
334
|
-
<Dropdown.List>
|
|
335
|
-
{#each dd.current as item (item.id)}
|
|
336
|
-
<div animate:flip={{ duration: 200 }}>
|
|
337
|
-
<Dropdown.Item value={item.value}>{item.text}</Dropdown.Item>
|
|
338
|
-
</div>
|
|
339
|
-
{/each}
|
|
340
|
-
</Dropdown.List>
|
|
341
|
-
{/snippet}
|
|
342
|
-
</Dropdown.Root>
|
|
343
|
-
</Root>
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
**Key composition features demonstrated:**
|
|
347
|
-
|
|
348
|
-
- **Component Fusion**: Using `base={Input.Root}` to compose Dropdown.Trigger with Input styling and behavior
|
|
349
|
-
- **Snippet Patterns**: Accessing internal state through snippets for custom rendering
|
|
350
|
-
- **Reactive Filtering**: Combining search query state with reactive effects for real-time filtering
|
|
351
|
-
- **Smooth Animations**: Using Svelte's `flip` animation for seamless list transitions
|
|
352
|
-
- **Multi-Select State**: Managing complex selection state through the Bond pattern
|
|
353
|
-
|
|
354
|
-
---
|
|
355
|
-
|
|
356
|
-
## π Documentation
|
|
357
|
-
|
|
358
|
-
### Component Examples
|
|
359
|
-
|
|
360
|
-
#### Dropdown with Multiple Selection
|
|
361
|
-
|
|
362
|
-
```svelte
|
|
363
|
-
<script lang="ts">
|
|
364
|
-
import { Dropdown } from '@svelte-atoms/core';
|
|
365
|
-
|
|
366
|
-
let selectedValues = ['option1'];
|
|
367
|
-
const options = [
|
|
368
|
-
{ value: 'option1', label: 'Option 1' },
|
|
369
|
-
{ value: 'option2', label: 'Option 2' },
|
|
370
|
-
{ value: 'option3', label: 'Option 3' }
|
|
371
|
-
];
|
|
372
|
-
</script>
|
|
373
|
-
|
|
374
|
-
<Dropdown.Root multiple bind:values={selectedValues}>
|
|
375
|
-
<!-- Access internal bond -->
|
|
376
|
-
{#snippet children({ dropdown })}
|
|
377
|
-
<Dropdown.Trigger>
|
|
378
|
-
Select options ({selectedValues.length} selected)
|
|
379
|
-
</Dropdown.Trigger>
|
|
380
|
-
|
|
381
|
-
<Dropdown.Content>
|
|
382
|
-
{#each options as option}
|
|
383
|
-
<Dropdown.Item value={option.value}>
|
|
384
|
-
{option.label}
|
|
385
|
-
</Dropdown.Item>
|
|
386
|
-
{/each}
|
|
387
|
-
</Dropdown.Content>
|
|
388
|
-
{/snippet}
|
|
389
|
-
</Dropdown.Root>
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
#### Form with Validation
|
|
393
|
-
|
|
394
|
-
```svelte
|
|
395
|
-
<script lang="ts">
|
|
396
|
-
import { Form, Input, Button } from '@svelte-atoms/core';
|
|
397
|
-
import { z } from 'zod';
|
|
398
|
-
|
|
399
|
-
const schema = z.object({
|
|
400
|
-
email: z.string().email('Invalid email address'),
|
|
401
|
-
password: z.string().min(8, 'Password must be at least 8 characters')
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
let formData = { email: '', password: '' };
|
|
405
|
-
let errors = {};
|
|
406
|
-
</script>
|
|
407
|
-
|
|
408
|
-
<Form {schema} bind:value={formData} bind:errors>
|
|
409
|
-
<Field name="email">
|
|
410
|
-
<Field.Label>Email</Field.Label>
|
|
411
|
-
<Field.Control>
|
|
412
|
-
<Input.Root type="email" placeholder="Enter your email" bind:value={formData.email} />
|
|
413
|
-
</Field.Control>
|
|
414
|
-
{#if errors.email}
|
|
415
|
-
<Form.Error>{errors.email}</Form.Error>
|
|
416
|
-
{/if}
|
|
417
|
-
</.Field>
|
|
418
|
-
|
|
419
|
-
<Field name="password">
|
|
420
|
-
<Field.Label>Password</Field.Label>
|
|
421
|
-
<Field.Control>
|
|
422
|
-
<Input.Root
|
|
423
|
-
type="password"
|
|
424
|
-
placeholder="Enter your password"
|
|
425
|
-
bind:value={formData.password}
|
|
426
|
-
/>
|
|
427
|
-
</Field.Control>
|
|
428
|
-
{#if errors.password}
|
|
429
|
-
<Field.Error>{errors.password}</Field.Error>
|
|
430
|
-
{/if}
|
|
431
|
-
</.Field>
|
|
432
|
-
|
|
433
|
-
<Button type="submit">Submit</Button>
|
|
434
|
-
</Form>
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
#### Data Grid with Sorting and Selection
|
|
438
|
-
|
|
439
|
-
```svelte
|
|
440
|
-
<script lang="ts">
|
|
441
|
-
import { DataGrid, Checkbox } from '@svelte-atoms/core';
|
|
442
|
-
|
|
443
|
-
let data = [
|
|
444
|
-
{ id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
|
|
445
|
-
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
|
|
446
|
-
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', role: 'Editor' }
|
|
447
|
-
];
|
|
448
|
-
|
|
449
|
-
let selectedRows = [];
|
|
450
|
-
</script>
|
|
451
|
-
|
|
452
|
-
<DataGrid.Root {data} bind:selectedRows multiple>
|
|
453
|
-
<DataGrid.Header>
|
|
454
|
-
<DataGrid.Tr>
|
|
455
|
-
<DataGrid.Th>
|
|
456
|
-
<Checkbox />
|
|
457
|
-
</DataGrid.Th>
|
|
458
|
-
<DataGrid.Th sortable="name">Name</DataGrid.Th>
|
|
459
|
-
<DataGrid.Th sortable="email">Email</DataGrid.Th>
|
|
460
|
-
<DataGrid.Th>Role</DataGrid.Th>
|
|
461
|
-
</DataGrid.Tr>
|
|
462
|
-
</DataGrid.Header>
|
|
463
|
-
|
|
464
|
-
<DataGrid.Body>
|
|
465
|
-
{#each data as row}
|
|
466
|
-
<DataGrid.Tr value={row.id}>
|
|
467
|
-
<DataGrid.Td>
|
|
468
|
-
<Checkbox.Root value={row.id} />
|
|
469
|
-
</DataGrid.Td>
|
|
470
|
-
<DataGrid.Td>{row.name}</DataGrid.Td>
|
|
471
|
-
<DataGrid.Td>{row.email}</DataGrid.Td>
|
|
472
|
-
<DataGrid.Td>{row.role}</DataGrid.Td>
|
|
473
|
-
</DataGrid.Tr>
|
|
474
|
-
{/each}
|
|
475
|
-
</DataGrid.Body>
|
|
476
|
-
</DataGrid.Root>
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
---
|
|
480
|
-
|
|
481
|
-
## π¨ Styling
|
|
482
|
-
|
|
483
|
-
@svelte-atoms/core is completely headless, giving you full control over styling. Here are some approaches:
|
|
484
|
-
|
|
485
|
-
### Using Vanilla CSS
|
|
486
|
-
|
|
487
|
-
```css
|
|
488
|
-
/* Default button styles */
|
|
489
|
-
.btn {
|
|
490
|
-
@apply rounded-md px-4 py-2 font-medium transition-colors;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
.btn-primary {
|
|
494
|
-
@apply bg-blue-600 text-white hover:bg-blue-700;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
.btn-secondary {
|
|
498
|
-
@apply bg-gray-200 text-gray-900 hover:bg-gray-300;
|
|
499
|
-
}
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
### Using Tailwind CSS
|
|
503
|
-
|
|
504
|
-
```svelte
|
|
505
|
-
<Button class="rounded-md bg-blue-600 px-4 py-2 text-white hover:bg-blue-700">Styled Button</Button>
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
---
|
|
509
|
-
|
|
510
|
-
## π§ͺ Development
|
|
511
|
-
|
|
512
|
-
### Setup
|
|
513
|
-
|
|
514
|
-
1. **Clone the repository:**
|
|
515
|
-
|
|
516
|
-
```bash
|
|
517
|
-
git clone https://github.com/ryu-man/svelte-atoms.git
|
|
518
|
-
cd svelte-atoms
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
2. **Install dependencies:**
|
|
522
|
-
|
|
523
|
-
```bash
|
|
524
|
-
bun install
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
3. **Start development server:**
|
|
528
|
-
|
|
529
|
-
```bash
|
|
530
|
-
bun dev
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
4. **Run Storybook:**
|
|
534
|
-
```bash
|
|
535
|
-
bun run storybook:dev
|
|
536
|
-
```
|
|
537
|
-
|
|
538
|
-
### Building
|
|
539
|
-
|
|
540
|
-
```bash
|
|
541
|
-
# Build library
|
|
542
|
-
bun run build
|
|
543
|
-
|
|
544
|
-
# Build Storybook
|
|
545
|
-
bun run storybook:build
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
---
|
|
549
|
-
|
|
550
|
-
<!-- ## π€ Contributing
|
|
551
|
-
|
|
552
|
-
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. -->
|
|
553
|
-
|
|
554
|
-
<!-- ### Development Workflow
|
|
555
|
-
|
|
556
|
-
1. Fork the repository
|
|
557
|
-
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
558
|
-
3. Make your changes and add tests
|
|
559
|
-
4. Run the test suite: `bun test`
|
|
560
|
-
5. Commit your changes: `git commit -m 'Add amazing feature'`
|
|
561
|
-
6. Push to the branch: `git push origin feature/amazing-feature`
|
|
562
|
-
7. Open a Pull Request -->
|
|
563
|
-
|
|
564
|
-
### Creating New Components
|
|
565
|
-
|
|
566
|
-
When adding new components, follow these guidelines:
|
|
567
|
-
|
|
568
|
-
1. **Create the bond structure:**
|
|
569
|
-
|
|
570
|
-
```
|
|
571
|
-
src/lib/atoms/my-component/
|
|
572
|
-
βββ bond.svelte.ts # Core bond logic (Bond + BondState classes)
|
|
573
|
-
βββ index.ts # Public exports
|
|
574
|
-
βββ atoms.ts # Component exports
|
|
575
|
-
βββ my-component-root.svelte # Use namespace pattern when building complex component
|
|
576
|
-
βββ my-component-content.svelte
|
|
577
|
-
βββ README.md # Component documentation
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
2. **Implement accessibility features:**
|
|
581
|
-
- ARIA attributes
|
|
582
|
-
- Keyboard navigation
|
|
583
|
-
- Focus management
|
|
584
|
-
- Screen reader support
|
|
585
|
-
|
|
586
|
-
3. **Add comprehensive tests:**
|
|
587
|
-
- Unit tests for bond logic
|
|
588
|
-
- Component integration tests
|
|
589
|
-
- Accessibility tests
|
|
590
|
-
|
|
591
|
-
4. **Create Storybook stories:**
|
|
592
|
-
- Basic usage examples
|
|
593
|
-
- Advanced configurations
|
|
594
|
-
- Interactive demos
|
|
595
|
-
|
|
596
|
-
---
|
|
597
|
-
|
|
598
|
-
## π Resources
|
|
599
|
-
|
|
600
|
-
- **[Documentation](https://svelte-atoms.dev)** - Comprehensive documentation
|
|
601
|
-
- **[Storybook](https://storybook.svelte-atoms.dev/)** - Interactive component documentation
|
|
602
|
-
- **[GitHub](https://github.com/ryu-man/svelte-atoms)** - Source code and issues
|
|
603
|
-
- **[@svelte-atoms/alchemist](../alchimist)** - Data visualization companion library
|
|
604
|
-
|
|
605
|
-
---
|
|
606
|
-
|
|
607
|
-
## πΊοΈ Roadmap
|
|
608
|
-
|
|
609
|
-
### v1.0.0 (Current - Alpha)
|
|
610
|
-
|
|
611
|
-
- β
Bond architecture with Svelte 5 runes
|
|
612
|
-
- β
35+ essential components
|
|
613
|
-
- β
TypeScript support
|
|
614
|
-
- β
Accessibility features
|
|
615
|
-
- β
Storybook documentation
|
|
616
|
-
- β
Standardized context pattern
|
|
617
|
-
|
|
618
|
-
---
|
|
619
|
-
|
|
620
|
-
## π License
|
|
621
|
-
|
|
622
|
-
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
623
|
-
|
|
624
|
-
---
|
|
625
|
-
|
|
626
|
-
## π Acknowledgements
|
|
627
|
-
|
|
628
|
-
- [Svelte](https://svelte.dev/) - The amazing framework that powers this library
|
|
629
|
-
- [Motion](https://motion.dev/) - For handling internal default animations
|
|
630
|
-
- [Floating UI](https://floating-ui.com/) - For advanced positioning logic
|
|
631
|
-
- [Tailwind CSS](https://tailwindcss.com/) - For styling
|
|
632
|
-
- [Storybook](https://storybook.js.org/) - For component documentation and testing
|
|
633
|
-
- [Vitest](https://vitest.dev/) - For fast and reliable testing
|
|
634
|
-
- [Playwright](https://playwright.dev/) - For end-to-end testing
|
|
635
|
-
|
|
636
|
-
---
|
|
637
|
-
|
|
638
|
-
<div align="center">
|
|
639
|
-
<p>Built with β€οΈ by the Svelte Atoms team</p>
|
|
640
|
-
<!-- <p>
|
|
641
|
-
<a href="https://github.com/ryu-man/svelte-atoms">GitHub</a> β’
|
|
642
|
-
<a href="https://svelte-atoms.dev">Documentation</a> β’
|
|
643
|
-
<a href="https://storybook.svelte-atoms.dev">Storybook</a>
|
|
644
|
-
</p> -->
|
|
645
|
-
</div>
|
|
1
|
+
# βοΈ @svelte-atoms/core
|
|
2
|
+
|
|
3
|
+
> A modern, modular, and accessible Svelte 5 UI component library built with composability at its core.
|
|
4
|
+
|
|
5
|
+
**@svelte-atoms/core** is a comprehensive Svelte component library that provides fundamental building blocks ("atoms") for creating sophisticated, interactive design systems. Each component is designed with accessibility, type safety, and developer experience in mind. Built with Svelte 5 runes for optimal reactivity and performance.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@svelte-atoms/core)
|
|
8
|
+
[](https://deepwiki.com/svelte-atoms/core)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## β¨ Features
|
|
14
|
+
|
|
15
|
+
### π§± **Bond Architecture**
|
|
16
|
+
|
|
17
|
+
Built around the concept of "Bonds" - self-contained, reusable state management classes that encapsulate component state and DOM interactions. Each component uses the Bond pattern for consistent, predictable behavior across complex interactions. Simple components like Button don't require the Bond pattern as they have minimal state management needs.
|
|
18
|
+
|
|
19
|
+
### π **Context-Driven Communication**
|
|
20
|
+
|
|
21
|
+
Components seamlessly communicate through Svelte's context API using standardized static methods (`Bond.get()` / `Bond.set()`) of the Bond class, enabling powerful parent-child relationships without prop drilling.
|
|
22
|
+
|
|
23
|
+
### βΏ **Accessibility First**
|
|
24
|
+
|
|
25
|
+
Every component includes proper ARIA attributes, keyboard navigation, and focus management out of the box.
|
|
26
|
+
|
|
27
|
+
### π§ **Highly Extensible**
|
|
28
|
+
|
|
29
|
+
Easily extend components with custom behaviors, animations, and styling while maintaining the core functionality.
|
|
30
|
+
|
|
31
|
+
### π― **Type Safety**
|
|
32
|
+
|
|
33
|
+
Fully written in TypeScript with comprehensive type definitions for a robust development experience.
|
|
34
|
+
|
|
35
|
+
### β‘ **Reactive by Design**
|
|
36
|
+
|
|
37
|
+
Leverages Svelte's fine-grained reactivity system for optimal performance and smooth user interactions.
|
|
38
|
+
|
|
39
|
+
### π¨ **Headless & Stylable**
|
|
40
|
+
|
|
41
|
+
Components are headless by default, giving you complete control over styling while providing sensible defaults.
|
|
42
|
+
|
|
43
|
+
### π§© **Composable**
|
|
44
|
+
|
|
45
|
+
Build complex UIs by combining simple, reusable components. Each component is designed to work seamlessly with others through the Bond pattern and context API. Create sophisticated features like multi-level dropdowns, nested accordions, or custom form controls by composing atomic components together.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## π¦ Available Components
|
|
50
|
+
|
|
51
|
+
Our comprehensive collection of UI components with implementation status:
|
|
52
|
+
|
|
53
|
+
### Layout & Navigation
|
|
54
|
+
|
|
55
|
+
| Component | Description | Status |
|
|
56
|
+
| ----------------------------------------------- | ---------------------------- | ------ |
|
|
57
|
+
| [**Accordion**](docs/components/accordion.md) | Collapsible content sections | β
|
|
|
58
|
+
| [**Breadcrumb**](docs/components/breadcrumb.md) | Navigation hierarchy | β
|
|
|
59
|
+
| [**Sidebar**](docs/components/sidebar.md) | Collapsible side navigation | β
|
|
|
60
|
+
| [**Tabs**](docs/components/tabs.md) | Tabbed interfaces | β
|
|
|
61
|
+
| [**Tree**](docs/components/tree.md) | Hierarchical data structures | β
|
|
|
62
|
+
| **Stepper** | Multi-step process indicator | β |
|
|
63
|
+
| **Pagination** | Page navigation controls | β |
|
|
64
|
+
|
|
65
|
+
### Forms & Input
|
|
66
|
+
|
|
67
|
+
| Component | Description | Status |
|
|
68
|
+
| ------------------------------------------- | ------------------------------------ | ------ |
|
|
69
|
+
| [**Button**](docs/components/button.md) | Interactive buttons with variants | β
|
|
|
70
|
+
| [**Checkbox**](docs/components/checkbox.md) | Multi-select inputs | β
|
|
|
71
|
+
| [**Combobox**](docs/components/combobox.md) | Searchable select inputs | β
|
|
|
72
|
+
| [**Input**](docs/components/input.md) | Text input fields | β
|
|
|
73
|
+
| [**Radio**](docs/components/radio.md) | Single-select inputs | β
|
|
|
74
|
+
| **Slider** | Range input controls | β |
|
|
75
|
+
| **Switch** | Toggle controls | β |
|
|
76
|
+
| [**Textarea**](docs/components/textarea.md) | Multi-line text inputs | β
|
|
|
77
|
+
| [**Form**](docs/components/form.md) | Form validation and state management | β
|
|
|
78
|
+
| **DatePicker** | Date selection component | β |
|
|
79
|
+
| **TimePicker** | Time selection component | β |
|
|
80
|
+
| **FileUpload** | File upload component | β |
|
|
81
|
+
| **ColorPicker** | Color selection component | β |
|
|
82
|
+
| **Rating** | Star rating component | β |
|
|
83
|
+
|
|
84
|
+
### Data Display
|
|
85
|
+
|
|
86
|
+
| Component | Description | Status |
|
|
87
|
+
| ------------------------------------------- | --------------------------- | ------ |
|
|
88
|
+
| [**Avatar**](docs/components/avatar.md) | User profile images | β
|
|
|
89
|
+
| [**Badge**](docs/components/badge.md) | Status indicators | β
|
|
|
90
|
+
| [**DataGrid**](docs/components/datagrid.md) | Advanced data tables | β
|
|
|
91
|
+
| [**Divider**](docs/components/divider.md) | Content separators | β
|
|
|
92
|
+
| [**Icon**](docs/components/icon.md) | Scalable icons | β
|
|
|
93
|
+
| [**Label**](docs/components/label.md) | Form labels | β
|
|
|
94
|
+
| [**Link**](docs/components/link.md) | Navigation links | β
|
|
|
95
|
+
| [**List**](docs/components/list.md) | Structured lists | β
|
|
|
96
|
+
| [**Card**](docs/components/card.md) | Content containers | β
|
|
|
97
|
+
| **Table** | Simple data tables | β |
|
|
98
|
+
| **Chip** | Compact information display | β |
|
|
99
|
+
| **Progress** | Progress indicators | β |
|
|
100
|
+
| **Skeleton** | Loading placeholders | β |
|
|
101
|
+
| **Timeline** | Event timeline display | β |
|
|
102
|
+
| **Calendar** | Date display component | β |
|
|
103
|
+
|
|
104
|
+
### Overlays & Feedback
|
|
105
|
+
|
|
106
|
+
| Component | Description | Status |
|
|
107
|
+
| ------------------------------------------------- | ------------------------ | ------ |
|
|
108
|
+
| [**Dialog**](docs/components/dialog.md) | Modal dialogs | β
|
|
|
109
|
+
| [**Dropdown**](docs/components/dropdown.md) | Contextual menus | β
|
|
|
110
|
+
| [**Popover**](docs/components/popover.md) | Contextual information | β
|
|
|
111
|
+
| [**Toast**](docs/components/toast.md) | Notification messages | β
|
|
|
112
|
+
| [**Tooltip**](docs/components/tooltip.md) | Contextual hints | β
|
|
|
113
|
+
| [**ContextMenu**](docs/components/contextmenu.md) | Right-click menus | β
|
|
|
114
|
+
| [**Drawer**](docs/components/drawer.md) | Slide-out panels | β
|
|
|
115
|
+
| [**Alert**](docs/components/alert.md) | Alert messages | β
|
|
|
116
|
+
| **Banner** | Full-width notifications | β |
|
|
117
|
+
| **Spotlight** | Feature highlighting | β |
|
|
118
|
+
|
|
119
|
+
### Utilities & Layout
|
|
120
|
+
|
|
121
|
+
| Component | Description | Status |
|
|
122
|
+
| ------------------------------------------------- | ----------------------------------- | ------ |
|
|
123
|
+
| [**Portal**](docs/components/portal.md) | Declare a portal anywhere in DOM | β
|
|
|
124
|
+
| **Teleport** | Render content in a specific portal | β
|
|
|
125
|
+
| **Root** | Application root container | β
|
|
|
126
|
+
| [**Layer**](docs/components/layer.md) | Layer management utility | β
|
|
|
127
|
+
| [**Collapsible**](docs/components/collapsible.md) | Generic collapsible wrapper | β
|
|
|
128
|
+
| **Container** | Layout container | β
|
|
|
129
|
+
| [**Scrollable**](docs/components/scrollable.md) | Custom scrollbar component | β
|
|
|
130
|
+
| [**Stack**](docs/components/stack.md) | Flexible layout stacking component | β
|
|
|
131
|
+
| **Spacer** | Space management utility | β |
|
|
132
|
+
| **VirtualList** | Virtual scrolling list | β |
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## ποΈ Architecture
|
|
137
|
+
|
|
138
|
+
The library is organized into distinct layers for maximum maintainability and extensibility:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
src/lib/
|
|
142
|
+
βββ components/ # 30+ Core UI components
|
|
143
|
+
βββ shared/ # Base classes (Bond, BondState) and utilities
|
|
144
|
+
βββ helpers/ # Helper functions and components
|
|
145
|
+
βββ attachments/ # DOM attachment utilities
|
|
146
|
+
βββ runes/ # Reactive utilities (Svelte 5 runes)
|
|
147
|
+
βββ types/ # TypeScript type definitions
|
|
148
|
+
βββ utils/ # General utility functions
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Bond Pattern
|
|
152
|
+
|
|
153
|
+
Each component follows a consistent Bond pattern:
|
|
154
|
+
|
|
155
|
+
- **Bond Class**: Manages component state and DOM interactions
|
|
156
|
+
- **BondState Class**: Holds reactive component state using Svelte 5 runes
|
|
157
|
+
- **Context Methods**: Static `CONTEXT_KEY`, `get()`, and `set()` methods for component communication
|
|
158
|
+
- **Component Files**: Svelte components that use the Bond for behavior
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
class MyComponentBond extends Bond<MyComponentBondState> {
|
|
162
|
+
static CONTEXT_KEY = '@atoms/context/my-component';
|
|
163
|
+
|
|
164
|
+
static get(): MyComponentBond | undefined {
|
|
165
|
+
return getContext(MyComponentBond.CONTEXT_KEY);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static set(bond: MyComponentBond): MyComponentBond {
|
|
169
|
+
return setContext(MyComponentBond.CONTEXT_KEY, bond);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## π Quick Start
|
|
177
|
+
|
|
178
|
+
### Installation
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# npm
|
|
182
|
+
npm install @svelte-atoms/core
|
|
183
|
+
|
|
184
|
+
# yarn
|
|
185
|
+
yarn install @svelte-atoms/core
|
|
186
|
+
|
|
187
|
+
# pnpm
|
|
188
|
+
pnpm add @svelte-atoms/core
|
|
189
|
+
|
|
190
|
+
# bun
|
|
191
|
+
bun add @svelte-atoms/core
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Basic Usage
|
|
195
|
+
|
|
196
|
+
```svelte
|
|
197
|
+
<script lang="ts">
|
|
198
|
+
import { Button, Dialog, Input } from '@svelte-atoms/core';
|
|
199
|
+
|
|
200
|
+
let dialogOpen = $state(false);
|
|
201
|
+
let inputValue = '';
|
|
202
|
+
</script>
|
|
203
|
+
|
|
204
|
+
<!-- Simple Button -->
|
|
205
|
+
<Button onclick={() => (dialogOpen = true)}>Open Dialog</Button>
|
|
206
|
+
|
|
207
|
+
<!-- Dialog with Input -->
|
|
208
|
+
<Dialog.Root bind:open={dialogOpen}>
|
|
209
|
+
<Dialog.Content>
|
|
210
|
+
<Dialog.Header>
|
|
211
|
+
<Dialog.Title>Enter your name</Dialog.Title>
|
|
212
|
+
</Dialog.Header>
|
|
213
|
+
<Dialog.Body>
|
|
214
|
+
<Input.Root>
|
|
215
|
+
<Input.Value bind:value={inputValue} placeholder="Your name...">
|
|
216
|
+
</Input.Root>
|
|
217
|
+
</Dialog.Body>
|
|
218
|
+
<Dialog.Footer>
|
|
219
|
+
<Button.Root onclick={() => (dialogOpen = false)}>Cancel</Button.Root>
|
|
220
|
+
<Button.Root variant="primary" onclick={() => (dialogOpen = false)}>Confirm</Button.Root>
|
|
221
|
+
</Dialog.Footer>
|
|
222
|
+
</Dialog.Content>
|
|
223
|
+
</Dialog.Root>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Advanced Usage with Bonds
|
|
227
|
+
|
|
228
|
+
For more control, you can use the Bond system directly:
|
|
229
|
+
|
|
230
|
+
```svelte
|
|
231
|
+
<script lang="ts">
|
|
232
|
+
import { DialogBond, DialogBondState } from '@svelte-atoms/core/dialog';
|
|
233
|
+
|
|
234
|
+
const { open = false, disable = false } = $props();
|
|
235
|
+
|
|
236
|
+
const bondProps = defineState(
|
|
237
|
+
[
|
|
238
|
+
defineProperty(
|
|
239
|
+
'open',
|
|
240
|
+
() => open,
|
|
241
|
+
(v) => (open = v)
|
|
242
|
+
),
|
|
243
|
+
defineProperty('disable', () => disable)
|
|
244
|
+
],
|
|
245
|
+
{
|
|
246
|
+
// Other props
|
|
247
|
+
}
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// Create dialog state
|
|
251
|
+
const dialogState = new DialogBondState(() => bondProps);
|
|
252
|
+
|
|
253
|
+
// Create dialog bond
|
|
254
|
+
// Make available via context
|
|
255
|
+
const dialogBond = new DialogBond(dialogState).share();
|
|
256
|
+
</script>
|
|
257
|
+
|
|
258
|
+
<div {...dialogBond.root()}>
|
|
259
|
+
<button {...dialogBond.trigger()} onclick={() => dialogBond.state.toggle()}>
|
|
260
|
+
Toggle Dialog
|
|
261
|
+
</button>
|
|
262
|
+
|
|
263
|
+
{#if open}
|
|
264
|
+
<div {...dialogBond.overlay()}>
|
|
265
|
+
<div {...dialogBond.content()}>
|
|
266
|
+
<h2 {...dialogBond.title()}>Dialog Title</h2>
|
|
267
|
+
<p>Dialog content goes here...</p>
|
|
268
|
+
<button onclick={() => dialogBond.state.close()}>Close</button>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
{/if}
|
|
272
|
+
</div>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Advanced Usage With Composition
|
|
276
|
+
|
|
277
|
+
This example demonstrates the power of component composition by combining `Dropdown`, `Input`, and animation capabilities to create a searchable multi-select dropdown with smooth transitions:
|
|
278
|
+
|
|
279
|
+
```svelte
|
|
280
|
+
<script lang="ts">
|
|
281
|
+
import { Dropdown, Input, Root, filter } from '@svelte-atoms/core';
|
|
282
|
+
import { flip } from 'svelte/animate';
|
|
283
|
+
|
|
284
|
+
// Sample data
|
|
285
|
+
let data = [
|
|
286
|
+
{ id: 1, value: 'apple', text: 'Apple' },
|
|
287
|
+
{ id: 2, value: 'banana', text: 'Banana' },
|
|
288
|
+
{ id: 3, value: 'cherry', text: 'Cherry' },
|
|
289
|
+
{ id: 4, value: 'date', text: 'Date' },
|
|
290
|
+
{ id: 5, value: 'elderberry', text: 'Elderberry' }
|
|
291
|
+
];
|
|
292
|
+
|
|
293
|
+
let open = $state(false);
|
|
294
|
+
// Filter items based on search query
|
|
295
|
+
const dd = filter(
|
|
296
|
+
() => data,
|
|
297
|
+
(query, item) => item.text.toLowerCase().includes(query.toLowerCase())
|
|
298
|
+
);
|
|
299
|
+
</script>
|
|
300
|
+
|
|
301
|
+
<Root class="items-center justify-center p-4">
|
|
302
|
+
<!-- Multi-select dropdown with search functionality -->
|
|
303
|
+
<Dropdown.Root
|
|
304
|
+
bind:open
|
|
305
|
+
multiple
|
|
306
|
+
keys={data.map((item) => item.value)}
|
|
307
|
+
onquerychange={(q) => (dd.query = q)}
|
|
308
|
+
>
|
|
309
|
+
{#snippet children({ dropdown })}
|
|
310
|
+
<!-- Compose Dropdown.Trigger with Input.Root for a custom trigger -->
|
|
311
|
+
<Dropdown.Trigger
|
|
312
|
+
base={Input.Root}
|
|
313
|
+
class="h-auto min-h-12 max-w-sm min-w-sm items-center gap-2 rounded-sm px-4 transition-colors duration-200"
|
|
314
|
+
onclick={(ev) => {
|
|
315
|
+
ev.preventDefault();
|
|
316
|
+
|
|
317
|
+
dropdown.state.open();
|
|
318
|
+
}}
|
|
319
|
+
>
|
|
320
|
+
<!-- Display selected values with animation -->
|
|
321
|
+
{#each dropdown?.state?.selectedItems ?? [] as item (item.id)}
|
|
322
|
+
<div animate:flip={{ duration: 200 }}>
|
|
323
|
+
<ADropdown.Value value={item.value} class="text-foreground/80">
|
|
324
|
+
{item.text}
|
|
325
|
+
</ADropdown.Value>
|
|
326
|
+
</div>
|
|
327
|
+
{/each}
|
|
328
|
+
|
|
329
|
+
<!-- Inline search input within the trigger -->
|
|
330
|
+
<Dropdown.Query class="flex-1 px-1" placeholder="Search for fruits..." />
|
|
331
|
+
</Dropdown.Trigger>
|
|
332
|
+
|
|
333
|
+
<!-- Dropdown list with filtered items -->
|
|
334
|
+
<Dropdown.List>
|
|
335
|
+
{#each dd.current as item (item.id)}
|
|
336
|
+
<div animate:flip={{ duration: 200 }}>
|
|
337
|
+
<Dropdown.Item value={item.value}>{item.text}</Dropdown.Item>
|
|
338
|
+
</div>
|
|
339
|
+
{/each}
|
|
340
|
+
</Dropdown.List>
|
|
341
|
+
{/snippet}
|
|
342
|
+
</Dropdown.Root>
|
|
343
|
+
</Root>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Key composition features demonstrated:**
|
|
347
|
+
|
|
348
|
+
- **Component Fusion**: Using `base={Input.Root}` to compose Dropdown.Trigger with Input styling and behavior
|
|
349
|
+
- **Snippet Patterns**: Accessing internal state through snippets for custom rendering
|
|
350
|
+
- **Reactive Filtering**: Combining search query state with reactive effects for real-time filtering
|
|
351
|
+
- **Smooth Animations**: Using Svelte's `flip` animation for seamless list transitions
|
|
352
|
+
- **Multi-Select State**: Managing complex selection state through the Bond pattern
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## π Documentation
|
|
357
|
+
|
|
358
|
+
### Component Examples
|
|
359
|
+
|
|
360
|
+
#### Dropdown with Multiple Selection
|
|
361
|
+
|
|
362
|
+
```svelte
|
|
363
|
+
<script lang="ts">
|
|
364
|
+
import { Dropdown } from '@svelte-atoms/core';
|
|
365
|
+
|
|
366
|
+
let selectedValues = ['option1'];
|
|
367
|
+
const options = [
|
|
368
|
+
{ value: 'option1', label: 'Option 1' },
|
|
369
|
+
{ value: 'option2', label: 'Option 2' },
|
|
370
|
+
{ value: 'option3', label: 'Option 3' }
|
|
371
|
+
];
|
|
372
|
+
</script>
|
|
373
|
+
|
|
374
|
+
<Dropdown.Root multiple bind:values={selectedValues}>
|
|
375
|
+
<!-- Access internal bond -->
|
|
376
|
+
{#snippet children({ dropdown })}
|
|
377
|
+
<Dropdown.Trigger>
|
|
378
|
+
Select options ({selectedValues.length} selected)
|
|
379
|
+
</Dropdown.Trigger>
|
|
380
|
+
|
|
381
|
+
<Dropdown.Content>
|
|
382
|
+
{#each options as option}
|
|
383
|
+
<Dropdown.Item value={option.value}>
|
|
384
|
+
{option.label}
|
|
385
|
+
</Dropdown.Item>
|
|
386
|
+
{/each}
|
|
387
|
+
</Dropdown.Content>
|
|
388
|
+
{/snippet}
|
|
389
|
+
</Dropdown.Root>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
#### Form with Validation
|
|
393
|
+
|
|
394
|
+
```svelte
|
|
395
|
+
<script lang="ts">
|
|
396
|
+
import { Form, Input, Button } from '@svelte-atoms/core';
|
|
397
|
+
import { z } from 'zod';
|
|
398
|
+
|
|
399
|
+
const schema = z.object({
|
|
400
|
+
email: z.string().email('Invalid email address'),
|
|
401
|
+
password: z.string().min(8, 'Password must be at least 8 characters')
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
let formData = { email: '', password: '' };
|
|
405
|
+
let errors = {};
|
|
406
|
+
</script>
|
|
407
|
+
|
|
408
|
+
<Form {schema} bind:value={formData} bind:errors>
|
|
409
|
+
<Field name="email">
|
|
410
|
+
<Field.Label>Email</Field.Label>
|
|
411
|
+
<Field.Control>
|
|
412
|
+
<Input.Root type="email" placeholder="Enter your email" bind:value={formData.email} />
|
|
413
|
+
</Field.Control>
|
|
414
|
+
{#if errors.email}
|
|
415
|
+
<Form.Error>{errors.email}</Form.Error>
|
|
416
|
+
{/if}
|
|
417
|
+
</.Field>
|
|
418
|
+
|
|
419
|
+
<Field name="password">
|
|
420
|
+
<Field.Label>Password</Field.Label>
|
|
421
|
+
<Field.Control>
|
|
422
|
+
<Input.Root
|
|
423
|
+
type="password"
|
|
424
|
+
placeholder="Enter your password"
|
|
425
|
+
bind:value={formData.password}
|
|
426
|
+
/>
|
|
427
|
+
</Field.Control>
|
|
428
|
+
{#if errors.password}
|
|
429
|
+
<Field.Error>{errors.password}</Field.Error>
|
|
430
|
+
{/if}
|
|
431
|
+
</.Field>
|
|
432
|
+
|
|
433
|
+
<Button type="submit">Submit</Button>
|
|
434
|
+
</Form>
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
#### Data Grid with Sorting and Selection
|
|
438
|
+
|
|
439
|
+
```svelte
|
|
440
|
+
<script lang="ts">
|
|
441
|
+
import { DataGrid, Checkbox } from '@svelte-atoms/core';
|
|
442
|
+
|
|
443
|
+
let data = [
|
|
444
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin' },
|
|
445
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User' },
|
|
446
|
+
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', role: 'Editor' }
|
|
447
|
+
];
|
|
448
|
+
|
|
449
|
+
let selectedRows = [];
|
|
450
|
+
</script>
|
|
451
|
+
|
|
452
|
+
<DataGrid.Root {data} bind:selectedRows multiple>
|
|
453
|
+
<DataGrid.Header>
|
|
454
|
+
<DataGrid.Tr>
|
|
455
|
+
<DataGrid.Th>
|
|
456
|
+
<Checkbox />
|
|
457
|
+
</DataGrid.Th>
|
|
458
|
+
<DataGrid.Th sortable="name">Name</DataGrid.Th>
|
|
459
|
+
<DataGrid.Th sortable="email">Email</DataGrid.Th>
|
|
460
|
+
<DataGrid.Th>Role</DataGrid.Th>
|
|
461
|
+
</DataGrid.Tr>
|
|
462
|
+
</DataGrid.Header>
|
|
463
|
+
|
|
464
|
+
<DataGrid.Body>
|
|
465
|
+
{#each data as row}
|
|
466
|
+
<DataGrid.Tr value={row.id}>
|
|
467
|
+
<DataGrid.Td>
|
|
468
|
+
<Checkbox.Root value={row.id} />
|
|
469
|
+
</DataGrid.Td>
|
|
470
|
+
<DataGrid.Td>{row.name}</DataGrid.Td>
|
|
471
|
+
<DataGrid.Td>{row.email}</DataGrid.Td>
|
|
472
|
+
<DataGrid.Td>{row.role}</DataGrid.Td>
|
|
473
|
+
</DataGrid.Tr>
|
|
474
|
+
{/each}
|
|
475
|
+
</DataGrid.Body>
|
|
476
|
+
</DataGrid.Root>
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## π¨ Styling
|
|
482
|
+
|
|
483
|
+
@svelte-atoms/core is completely headless, giving you full control over styling. Here are some approaches:
|
|
484
|
+
|
|
485
|
+
### Using Vanilla CSS
|
|
486
|
+
|
|
487
|
+
```css
|
|
488
|
+
/* Default button styles */
|
|
489
|
+
.btn {
|
|
490
|
+
@apply rounded-md px-4 py-2 font-medium transition-colors;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
.btn-primary {
|
|
494
|
+
@apply bg-blue-600 text-white hover:bg-blue-700;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
.btn-secondary {
|
|
498
|
+
@apply bg-gray-200 text-gray-900 hover:bg-gray-300;
|
|
499
|
+
}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Using Tailwind CSS
|
|
503
|
+
|
|
504
|
+
```svelte
|
|
505
|
+
<Button class="rounded-md bg-blue-600 px-4 py-2 text-white hover:bg-blue-700">Styled Button</Button>
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## π§ͺ Development
|
|
511
|
+
|
|
512
|
+
### Setup
|
|
513
|
+
|
|
514
|
+
1. **Clone the repository:**
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
git clone https://github.com/ryu-man/svelte-atoms.git
|
|
518
|
+
cd svelte-atoms
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
2. **Install dependencies:**
|
|
522
|
+
|
|
523
|
+
```bash
|
|
524
|
+
bun install
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
3. **Start development server:**
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
bun dev
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
4. **Run Storybook:**
|
|
534
|
+
```bash
|
|
535
|
+
bun run storybook:dev
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Building
|
|
539
|
+
|
|
540
|
+
```bash
|
|
541
|
+
# Build library
|
|
542
|
+
bun run build
|
|
543
|
+
|
|
544
|
+
# Build Storybook
|
|
545
|
+
bun run storybook:build
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
<!-- ## π€ Contributing
|
|
551
|
+
|
|
552
|
+
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. -->
|
|
553
|
+
|
|
554
|
+
<!-- ### Development Workflow
|
|
555
|
+
|
|
556
|
+
1. Fork the repository
|
|
557
|
+
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
558
|
+
3. Make your changes and add tests
|
|
559
|
+
4. Run the test suite: `bun test`
|
|
560
|
+
5. Commit your changes: `git commit -m 'Add amazing feature'`
|
|
561
|
+
6. Push to the branch: `git push origin feature/amazing-feature`
|
|
562
|
+
7. Open a Pull Request -->
|
|
563
|
+
|
|
564
|
+
### Creating New Components
|
|
565
|
+
|
|
566
|
+
When adding new components, follow these guidelines:
|
|
567
|
+
|
|
568
|
+
1. **Create the bond structure:**
|
|
569
|
+
|
|
570
|
+
```
|
|
571
|
+
src/lib/atoms/my-component/
|
|
572
|
+
βββ bond.svelte.ts # Core bond logic (Bond + BondState classes)
|
|
573
|
+
βββ index.ts # Public exports
|
|
574
|
+
βββ atoms.ts # Component exports
|
|
575
|
+
βββ my-component-root.svelte # Use namespace pattern when building complex component
|
|
576
|
+
βββ my-component-content.svelte
|
|
577
|
+
βββ README.md # Component documentation
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
2. **Implement accessibility features:**
|
|
581
|
+
- ARIA attributes
|
|
582
|
+
- Keyboard navigation
|
|
583
|
+
- Focus management
|
|
584
|
+
- Screen reader support
|
|
585
|
+
|
|
586
|
+
3. **Add comprehensive tests:**
|
|
587
|
+
- Unit tests for bond logic
|
|
588
|
+
- Component integration tests
|
|
589
|
+
- Accessibility tests
|
|
590
|
+
|
|
591
|
+
4. **Create Storybook stories:**
|
|
592
|
+
- Basic usage examples
|
|
593
|
+
- Advanced configurations
|
|
594
|
+
- Interactive demos
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## π Resources
|
|
599
|
+
|
|
600
|
+
- **[Documentation](https://svelte-atoms.dev)** - Comprehensive documentation
|
|
601
|
+
- **[Storybook](https://storybook.svelte-atoms.dev/)** - Interactive component documentation
|
|
602
|
+
- **[GitHub](https://github.com/ryu-man/svelte-atoms)** - Source code and issues
|
|
603
|
+
- **[@svelte-atoms/alchemist](../alchimist)** - Data visualization companion library
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
## πΊοΈ Roadmap
|
|
608
|
+
|
|
609
|
+
### v1.0.0 (Current - Alpha)
|
|
610
|
+
|
|
611
|
+
- β
Bond architecture with Svelte 5 runes
|
|
612
|
+
- β
35+ essential components
|
|
613
|
+
- β
TypeScript support
|
|
614
|
+
- β
Accessibility features
|
|
615
|
+
- β
Storybook documentation
|
|
616
|
+
- β
Standardized context pattern
|
|
617
|
+
|
|
618
|
+
---
|
|
619
|
+
|
|
620
|
+
## π License
|
|
621
|
+
|
|
622
|
+
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
623
|
+
|
|
624
|
+
---
|
|
625
|
+
|
|
626
|
+
## π Acknowledgements
|
|
627
|
+
|
|
628
|
+
- [Svelte](https://svelte.dev/) - The amazing framework that powers this library
|
|
629
|
+
- [Motion](https://motion.dev/) - For handling internal default animations
|
|
630
|
+
- [Floating UI](https://floating-ui.com/) - For advanced positioning logic
|
|
631
|
+
- [Tailwind CSS](https://tailwindcss.com/) - For styling
|
|
632
|
+
- [Storybook](https://storybook.js.org/) - For component documentation and testing
|
|
633
|
+
- [Vitest](https://vitest.dev/) - For fast and reliable testing
|
|
634
|
+
- [Playwright](https://playwright.dev/) - For end-to-end testing
|
|
635
|
+
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
<div align="center">
|
|
639
|
+
<p>Built with β€οΈ by the Svelte Atoms team</p>
|
|
640
|
+
<!-- <p>
|
|
641
|
+
<a href="https://github.com/ryu-man/svelte-atoms">GitHub</a> β’
|
|
642
|
+
<a href="https://svelte-atoms.dev">Documentation</a> β’
|
|
643
|
+
<a href="https://storybook.svelte-atoms.dev">Storybook</a>
|
|
644
|
+
</p> -->
|
|
645
|
+
</div>
|