@svelte-atoms/core 1.0.0-alpha.30 β 1.0.0-alpha.32
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 +176 -739
- package/dist/attachments/index.d.ts +1 -0
- package/dist/attachments/index.js +1 -0
- package/dist/components/accordion/accordion-root.svelte +65 -61
- package/dist/components/accordion/accordion.stories.svelte +70 -145
- package/dist/components/accordion/item/accordion-item-body.svelte +6 -4
- package/dist/components/accordion/item/accordion-item-header.svelte +2 -1
- package/dist/components/accordion/item/accordion-item-indicator.svelte +2 -1
- package/dist/components/accordion/item/accordion-item-root.svelte +2 -1
- package/dist/components/accordion/item/bond.svelte.d.ts +2 -0
- package/dist/components/accordion/item/index.d.ts +3 -0
- package/dist/components/accordion/item/index.js +3 -0
- package/dist/components/accordion/item/motion.svelte.d.ts +15 -0
- package/dist/components/accordion/item/motion.svelte.js +30 -0
- package/dist/components/accordion/item/types.d.ts +7 -24
- package/dist/components/alert/alert-close-button.svelte +32 -36
- package/dist/components/alert/alert-description.svelte +1 -1
- package/dist/components/alert/alert-description.svelte.d.ts +3 -6
- package/dist/components/alert/alert-root.svelte +3 -38
- package/dist/components/alert/alert-root.svelte.d.ts +2 -2
- package/dist/components/alert/alert.stories.svelte +400 -400
- package/dist/components/alert/bond.svelte.d.ts +0 -13
- package/dist/components/alert/bond.svelte.js +0 -32
- package/dist/components/alert/types.d.ts +8 -32
- package/dist/components/atom/html-atom.svelte +93 -261
- package/dist/components/atom/types.d.ts +3 -2
- package/dist/components/atom/utils.d.ts +37 -0
- package/dist/components/atom/utils.js +208 -0
- package/dist/components/avatar/avatar.stories.svelte +22 -22
- package/dist/components/badge/badge.stories.svelte +12 -12
- package/dist/components/badge/badge.svelte +19 -19
- package/dist/components/breadcrumb/breadcrumb-item.svelte +1 -1
- package/dist/components/breadcrumb/breadcrumb-separator.svelte +5 -1
- package/dist/components/breadcrumb/breadcrumb.stories.svelte +16 -16
- package/dist/components/button/button.stories.svelte +27 -27
- package/dist/components/calendar/calendar-day.svelte +9 -4
- package/dist/components/calendar/calendar.stories.svelte +26 -26
- package/dist/components/card/card-body.svelte +39 -39
- package/dist/components/card/card-footer.svelte +41 -41
- package/dist/components/card/card-root.svelte +91 -91
- package/dist/components/card/card.stories.svelte +133 -133
- package/dist/components/checkbox/checkbox.stories.svelte +22 -22
- package/dist/components/checkbox/checkbox.svelte +159 -155
- package/dist/components/collapsible/bond.svelte.js +2 -1
- package/dist/components/collapsible/collapsible-body.svelte +3 -2
- package/dist/components/collapsible/collapsible.stories.svelte +172 -172
- package/dist/components/collapsible/motion.svelte.d.ts +6 -0
- package/dist/components/collapsible/motion.svelte.js +15 -0
- package/dist/components/combobox/atoms.d.ts +3 -3
- package/dist/components/combobox/atoms.js +3 -3
- package/dist/components/combobox/bond.svelte.d.ts +6 -6
- package/dist/components/combobox/bond.svelte.js +3 -26
- package/dist/components/combobox/combobox-control.svelte +52 -52
- package/dist/components/combobox/{compobox-item.svelte β combobox-item.svelte} +62 -68
- package/dist/components/combobox/combobox-item.svelte.d.ts +12 -0
- package/dist/components/combobox/combobox-root.svelte +65 -65
- package/dist/components/combobox/combobox.stories.svelte +50 -0
- package/dist/components/combobox/combobox.stories.svelte.d.ts +3 -0
- package/dist/components/combobox/index.d.ts +1 -0
- package/dist/components/container/container.stories.svelte +20 -20
- package/dist/components/container/container.svelte.d.ts +1 -1
- package/dist/components/datagrid/datagrid.stories.svelte +72 -72
- package/dist/components/datagrid/tr/bond.svelte.d.ts +4 -2
- package/dist/components/datagrid/tr/bond.svelte.js +9 -7
- package/dist/components/datagrid/tr/datagrid-tr.svelte +9 -7
- package/dist/components/date-picker/bond.svelte.d.ts +15 -5
- package/dist/components/date-picker/bond.svelte.js +5 -11
- package/dist/components/date-picker/date-picker-calendar.svelte +2 -2
- package/dist/components/date-picker/date-picker-root.svelte +95 -95
- package/dist/components/date-picker/date-picker.stories.svelte +35 -35
- package/dist/components/dialog/bond.svelte.d.ts +13 -3
- package/dist/components/dialog/bond.svelte.js +52 -6
- package/dist/components/dialog/dialog-content.svelte +2 -20
- package/dist/components/dialog/dialog-root.svelte +3 -22
- package/dist/components/dialog/dialog.stories.svelte +64 -64
- package/dist/components/dialog/motion.svelte.d.ts +13 -0
- package/dist/components/dialog/motion.svelte.js +44 -0
- package/dist/components/drawer/attachments.svelte.d.ts +1 -1
- package/dist/components/drawer/attachments.svelte.js +1 -3
- package/dist/components/drawer/bond.svelte.d.ts +30 -9
- package/dist/components/drawer/bond.svelte.js +80 -24
- package/dist/components/drawer/drawer-content.svelte +49 -57
- package/dist/components/drawer/drawer-root.svelte +5 -4
- package/dist/components/drawer/drawer.stories.svelte +141 -212
- package/dist/components/drawer/index.d.ts +2 -0
- package/dist/components/drawer/index.js +2 -0
- package/dist/components/drawer/motion.d.ts +15 -0
- package/dist/components/drawer/motion.js +28 -0
- package/dist/components/dropdown/atoms.d.ts +1 -1
- package/dist/components/dropdown/atoms.js +1 -1
- package/dist/components/dropdown/bond.svelte.d.ts +22 -19
- package/dist/components/dropdown/bond.svelte.js +29 -53
- package/dist/components/dropdown/dropdown-root.svelte +7 -1
- package/dist/components/dropdown/dropdown-values.svelte +17 -17
- package/dist/components/dropdown/dropdown-values.svelte.d.ts +1 -2
- package/dist/components/dropdown/dropdown.stories.svelte +13 -10
- package/dist/components/dropdown/index.d.ts +2 -0
- package/dist/components/dropdown/index.js +1 -0
- package/dist/components/dropdown/item/attachments.svelte.d.ts +2 -2
- package/dist/components/dropdown/item/attachments.svelte.js +2 -2
- package/dist/components/dropdown/item/controller.svelte.d.ts +34 -0
- package/dist/components/dropdown/item/controller.svelte.js +82 -0
- package/dist/components/dropdown/item/dropdown-item.svelte +109 -102
- package/dist/components/dropdown/item/dropdown-item.svelte.d.ts +13 -28
- package/dist/components/dropdown/item/index.d.ts +3 -0
- package/dist/components/dropdown/item/index.js +3 -0
- package/dist/components/dropdown/item/types.d.ts +29 -0
- package/dist/components/dropdown/item/types.js +1 -0
- package/dist/components/form/form.stories.svelte +96 -96
- package/dist/components/image/image.stories.svelte +20 -20
- package/dist/components/input/input.stories.svelte +35 -35
- package/dist/components/label/label.stories.svelte +15 -15
- package/dist/components/lazy/lazy.stories.svelte +28 -28
- package/dist/components/link/link.stories.svelte +15 -15
- package/dist/components/list/list-item.svelte +2 -2
- package/dist/components/menu/atoms.d.ts +9 -3
- package/dist/components/menu/atoms.js +9 -3
- package/dist/components/menu/bond.svelte.d.ts +54 -0
- package/dist/components/menu/bond.svelte.js +132 -0
- package/dist/components/menu/index.d.ts +3 -1
- package/dist/components/menu/index.js +2 -1
- package/dist/components/menu/item/controller.svelte.d.ts +26 -0
- package/dist/components/menu/item/controller.svelte.js +69 -0
- package/dist/components/menu/item/index.d.ts +2 -0
- package/dist/components/menu/item/index.js +2 -0
- package/dist/components/menu/item/menu-item.svelte +103 -0
- package/dist/components/menu/item/menu-item.svelte.d.ts +31 -0
- package/dist/components/menu/item/types.d.ts +62 -0
- package/dist/components/menu/item/types.js +1 -0
- package/dist/components/menu/{menu-list.svelte β menu-content.svelte} +40 -40
- package/dist/components/menu/{menu-list.svelte.d.ts β menu-content.svelte.d.ts} +3 -3
- package/dist/components/menu/menu-root.svelte +15 -0
- package/dist/components/menu/menu-root.svelte.d.ts +8 -0
- package/dist/components/menu/menu.stories.svelte +5 -5
- package/dist/components/menu/types.d.ts +0 -7
- package/dist/components/popover/bond.svelte.d.ts +18 -8
- package/dist/components/popover/bond.svelte.js +76 -40
- package/dist/components/popover/motion.d.ts +6 -0
- package/dist/components/popover/motion.js +56 -0
- package/dist/components/popover/popover-arrow.svelte +111 -111
- package/dist/components/popover/popover-content.svelte +137 -175
- package/dist/components/popover/popover-indicator.svelte +44 -44
- package/dist/components/popover/popover-root.svelte +48 -48
- package/dist/components/popover/popover.stories.svelte +37 -49
- package/dist/components/popover/types.d.ts +9 -7
- package/dist/components/portal/active-portal.svelte +12 -5
- package/dist/components/portal/active-portal.svelte.d.ts +2 -9
- package/dist/components/portal/portal-root.svelte +1 -8
- package/dist/components/portal/portal-root.svelte.d.ts +4 -6
- package/dist/components/portal/teleport.svelte +1 -2
- package/dist/components/portal/teleport.svelte.d.ts +3 -4
- package/dist/components/qr-code/qr-code.stories.svelte +18 -18
- package/dist/components/radio/radio-group.stories.svelte +41 -41
- package/dist/components/radio/radio.stories.svelte +17 -17
- package/dist/components/radio/radio.svelte +109 -109
- package/dist/components/radio/types.d.ts +98 -0
- package/dist/components/radio/types.js +2 -0
- package/dist/components/root/index.d.ts +1 -0
- package/dist/components/root/index.js +1 -0
- package/dist/components/root/l0-portal.svelte +8 -0
- package/dist/components/{radio/types.svelte.d.ts β root/l0-portal.svelte.d.ts} +3 -3
- package/dist/components/root/l1-portal.svelte +7 -0
- package/dist/components/root/l1-portal.svelte.d.ts +26 -0
- package/dist/components/root/root.css +119 -119
- package/dist/components/root/root.svelte +26 -44
- package/dist/components/root/root.svelte.d.ts +2 -6
- package/dist/components/root/toasts-portal.svelte +7 -0
- package/dist/components/root/toasts-portal.svelte.d.ts +26 -0
- package/dist/components/root/types.d.ts +17 -0
- package/dist/components/scrollable/scrollable-root.svelte.d.ts +2 -2
- package/dist/components/scrollable/scrollable.stories.svelte +116 -116
- package/dist/components/sidebar/index.d.ts +2 -0
- package/dist/components/sidebar/index.js +2 -0
- package/dist/components/sidebar/motion.svelte.d.ts +11 -0
- package/dist/components/sidebar/motion.svelte.js +16 -0
- package/dist/components/sidebar/sidebar-content.svelte +40 -50
- package/dist/components/sidebar/sidebar-root.svelte +39 -39
- package/dist/components/sidebar/sidebar.stories.svelte +43 -43
- package/dist/components/sidebar/types.d.ts +2 -12
- package/dist/components/tabs/tabs.stories.svelte +56 -56
- package/dist/components/textarea/atoms.d.ts +1 -0
- package/dist/components/textarea/atoms.js +1 -0
- package/dist/components/textarea/textarea-input.svelte +4 -1
- package/dist/components/textarea/textarea-root.svelte +2 -2
- package/dist/components/textarea/textarea-root.svelte.d.ts +2 -0
- package/dist/components/tooltip/tooltip-trigger.svelte +39 -39
- package/dist/components/tooltip/tooltip-trigger.svelte.d.ts +1 -0
- package/dist/components/tooltip/tooltip.stories.svelte +32 -32
- package/dist/components/tree/index.d.ts +1 -0
- package/dist/components/tree/index.js +1 -0
- package/dist/components/tree/motion.svelte.d.ts +6 -0
- package/dist/components/tree/motion.svelte.js +14 -0
- package/dist/components/tree/tree-body.svelte +4 -3
- package/dist/components/tree/tree.stories.svelte +142 -142
- package/dist/context/preset.svelte.d.ts +3 -1
- package/dist/icons/icon-copy.svelte +6 -0
- package/dist/icons/icon-copy.svelte.d.ts +26 -0
- package/dist/utils/dom.svelte.d.ts +2 -0
- package/dist/utils/dom.svelte.js +21 -0
- package/dist/utils/function.d.ts +1 -1
- package/dist/utils/promise.svelte.d.ts +5 -0
- package/dist/utils/promise.svelte.js +20 -0
- package/package.json +4 -3
- package/dist/components/combobox/compobox-item.svelte.d.ts +0 -34
- package/dist/components/combobox/compobox.stories.svelte +0 -51
- package/dist/components/combobox/compobox.stories.svelte.d.ts +0 -3
- package/dist/components/dropdown/item/bond.svelte.d.ts +0 -42
- package/dist/components/dropdown/item/bond.svelte.js +0 -99
- package/dist/components/menu/menu-item.svelte +0 -51
- package/dist/components/menu/menu-item.svelte.d.ts +0 -36
- package/dist/components/radio/types.svelte +0 -0
- package/llm/composition.md +0 -395
- package/llm/crafting.md +0 -838
- package/llm/motion.md +0 -970
- package/llm/philosophy.md +0 -23
- package/llm/preset-variant-integration.md +0 -516
- package/llm/preset.md +0 -383
- package/llm/styling.md +0 -216
- package/llm/usage.md +0 -46
- package/llm/variants.md +0 -1259
package/README.md
CHANGED
|
@@ -1,194 +1,34 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @svelte-atoms/core
|
|
2
2
|
|
|
3
3
|
> A modern, modular, and accessible Svelte 5 UI component library built with composability at its core.
|
|
4
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
5
|
[](https://www.npmjs.com/package/@svelte-atoms/core)
|
|
8
6
|
[](https://deepwiki.com/svelte-atoms/core)
|
|
9
7
|
[](LICENSE)
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## β¨ Features
|
|
14
|
-
|
|
15
|
-
### π§± **Bond Architecture**
|
|
16
|
-
|
|
17
|
-
Self-contained state management classes that encapsulate component logic and DOM interactions. Bonds communicate through Svelte's context API using standardized `Bond.get()` / `Bond.set()` methods, enabling parent-child relationships without prop drilling.
|
|
18
|
-
|
|
19
|
-
### βΏ **Accessibility First**
|
|
20
|
-
|
|
21
|
-
Every component includes proper ARIA attributes, keyboard navigation, and focus management out of the box.
|
|
22
|
-
|
|
23
|
-
### π§ **Highly Extensible**
|
|
24
|
-
|
|
25
|
-
Easily extend components with custom behaviors, animations, and styling while maintaining the core functionality.
|
|
26
|
-
|
|
27
|
-
### π― **Type Safety**
|
|
28
|
-
|
|
29
|
-
Fully written in TypeScript with comprehensive type definitions for a robust development experience.
|
|
30
|
-
|
|
31
|
-
### β‘ **Reactive by Design**
|
|
32
|
-
|
|
33
|
-
Leverages Svelte's fine-grained reactivity system for optimal performance and smooth user interactions.
|
|
34
|
-
|
|
35
|
-
### π¨ **Headless & Stylable**
|
|
36
|
-
|
|
37
|
-
Components are headless by default, giving you complete control over styling while providing sensible defaults.
|
|
38
|
-
|
|
39
|
-
### π§© **Composable**
|
|
40
|
-
|
|
41
|
-
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.
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## π¦ Available Components
|
|
46
|
-
|
|
47
|
-
Our comprehensive collection of UI components with implementation status:
|
|
48
|
-
|
|
49
|
-
### Layout & Navigation
|
|
50
|
-
|
|
51
|
-
| Component | Description | Status |
|
|
52
|
-
| ----------------------------------------------- | ---------------------------- | ------ |
|
|
53
|
-
| [**Accordion**](docs/components/accordion.md) | Collapsible content sections | β
|
|
|
54
|
-
| [**Breadcrumb**](docs/components/breadcrumb.md) | Navigation hierarchy | β
|
|
|
55
|
-
| [**Sidebar**](docs/components/sidebar.md) | Collapsible side navigation | β
|
|
|
56
|
-
| [**Tabs**](docs/components/tabs.md) | Tabbed interfaces | β
|
|
|
57
|
-
| [**Tree**](docs/components/tree.md) | Hierarchical data structures | β
|
|
|
58
|
-
| **Stepper** | Multi-step process indicator | β |
|
|
59
|
-
| **Pagination** | Page navigation controls | β |
|
|
60
|
-
|
|
61
|
-
### Forms & Input
|
|
62
|
-
|
|
63
|
-
| Component | Description | Status |
|
|
64
|
-
| ------------------------------------------- | ------------------------------------ | ------ |
|
|
65
|
-
| [**Button**](docs/components/button.md) | Interactive buttons with variants | β
|
|
|
66
|
-
| [**Checkbox**](docs/components/checkbox.md) | Multi-select inputs | β
|
|
|
67
|
-
| [**Combobox**](docs/components/combobox.md) | Searchable select inputs | β
|
|
|
68
|
-
| [**Input**](docs/components/input.md) | Text input fields | β
|
|
|
69
|
-
| [**Radio**](docs/components/radio.md) | Single-select inputs | β
|
|
|
70
|
-
| **Slider** | Range input controls | β |
|
|
71
|
-
| **Switch** | Toggle controls | β |
|
|
72
|
-
| [**Textarea**](docs/components/textarea.md) | Multi-line text inputs | β
|
|
|
73
|
-
| [**Form**](docs/components/form.md) | Form validation and state management | β
|
|
|
74
|
-
| **DatePicker** | Date selection component | β
|
|
|
75
|
-
| **TimePicker** | Time selection component | β |
|
|
76
|
-
| **FileUpload** | File upload component | β |
|
|
77
|
-
| **ColorPicker** | Color selection component | β |
|
|
78
|
-
| **Rating** | Star rating component | β |
|
|
79
|
-
|
|
80
|
-
### Data Display
|
|
81
|
-
|
|
82
|
-
| Component | Description | Status |
|
|
83
|
-
| ------------------------------------------- | --------------------------- | ------ |
|
|
84
|
-
| [**Avatar**](docs/components/avatar.md) | User profile images | β
|
|
|
85
|
-
| [**Badge**](docs/components/badge.md) | Status indicators | β
|
|
|
86
|
-
| [**DataGrid**](docs/components/datagrid.md) | Advanced data tables | β
|
|
|
87
|
-
| [**Divider**](docs/components/divider.md) | Content separators | β
|
|
|
88
|
-
| [**Icon**](docs/components/icon.md) | Scalable icons | β
|
|
|
89
|
-
| [**Label**](docs/components/label.md) | Form labels | β
|
|
|
90
|
-
| [**Link**](docs/components/link.md) | Navigation links | β
|
|
|
91
|
-
| [**List**](docs/components/list.md) | Structured lists | β
|
|
|
92
|
-
| [**Card**](docs/components/card.md) | Content containers | β
|
|
|
93
|
-
| **Table** | Simple data tables | β |
|
|
94
|
-
| **Chip** | Compact information display | β |
|
|
95
|
-
| **Progress** | Progress indicators | β |
|
|
96
|
-
| **Skeleton** | Loading placeholders | β |
|
|
97
|
-
| **Timeline** | Event timeline display | β |
|
|
98
|
-
| **Calendar** | Date display component | β
|
|
|
99
|
-
| **QRCode** | QR code generator | β
|
|
|
100
|
-
|
|
101
|
-
### Overlays & Feedback
|
|
102
|
-
|
|
103
|
-
| Component | Description | Status |
|
|
104
|
-
| ------------------------------------------------- | ------------------------ | ------ |
|
|
105
|
-
| [**Dialog**](docs/components/dialog.md) | Modal dialogs | β
|
|
|
106
|
-
| [**Dropdown**](docs/components/dropdown.md) | Contextual menus | β
|
|
|
107
|
-
| [**Popover**](docs/components/popover.md) | Contextual information | β
|
|
|
108
|
-
| [**Toast**](docs/components/toast.md) | Notification messages | β
|
|
|
109
|
-
| [**Tooltip**](docs/components/tooltip.md) | Contextual hints | β
|
|
|
110
|
-
| [**ContextMenu**](docs/components/contextmenu.md) | Right-click menus | β
|
|
|
111
|
-
| [**Drawer**](docs/components/drawer.md) | Slide-out panels | β
|
|
|
112
|
-
| [**Alert**](docs/components/alert.md) | Alert messages | β
|
|
|
113
|
-
| **Banner** | Full-width notifications | β |
|
|
114
|
-
| **Spotlight** | Feature highlighting | β |
|
|
115
|
-
|
|
116
|
-
### Utilities & Layout
|
|
117
|
-
|
|
118
|
-
| Component | Description | Status |
|
|
119
|
-
| ------------------------------------------------- | ----------------------------------- | ------ |
|
|
120
|
-
| [**Portal**](docs/components/portal.md) | Declare a portal anywhere in DOM | β
|
|
|
121
|
-
| **Teleport** | Render content in a specific portal | β
|
|
|
122
|
-
| **Root** | Application root container | β
|
|
|
123
|
-
| [**Layer**](docs/components/layer.md) | Layer management utility | β
|
|
|
124
|
-
| [**Collapsible**](docs/components/collapsible.md) | Generic collapsible wrapper | β
|
|
|
125
|
-
| **Container** | Layout container | β
|
|
|
126
|
-
| [**Scrollable**](docs/components/scrollable.md) | Custom scrollbar component | β
|
|
|
127
|
-
| [**Stack**](docs/components/stack.md) | Flexible layout stacking component | β
|
|
|
128
|
-
| **Spacer** | Space management utility | β |
|
|
129
|
-
| **VirtualList** | Virtual scrolling list | β |
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## ποΈ Architecture
|
|
134
|
-
|
|
135
|
-
The library is organized into distinct layers for maximum maintainability and extensibility:
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
src/lib/
|
|
139
|
-
βββ components/ # 30+ Core UI components
|
|
140
|
-
βββ shared/ # Base classes (Bond, BondState) and utilities
|
|
141
|
-
βββ helpers/ # Helper functions and components
|
|
142
|
-
βββ attachments/ # DOM attachment utilities
|
|
143
|
-
βββ runes/ # Reactive utilities (Svelte 5 runes)
|
|
144
|
-
βββ types/ # TypeScript type definitions
|
|
145
|
-
βββ utils/ # General utility functions
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Bond Pattern
|
|
9
|
+
## Features
|
|
149
10
|
|
|
150
|
-
|
|
11
|
+
- **Bond Architecture** - Self-contained state management with context-based communication
|
|
12
|
+
- **Accessible** - ARIA attributes, keyboard navigation, and focus management included
|
|
13
|
+
- **Type Safe** - Full TypeScript support with comprehensive type definitions
|
|
14
|
+
- **Headless** - Complete styling control with sensible defaults
|
|
15
|
+
- **Composable** - Build complex UIs by combining simple, reusable components
|
|
16
|
+
- **Svelte 5 Runes** - Optimized reactivity and performance
|
|
151
17
|
|
|
152
|
-
|
|
153
|
-
- **BondState Class**: Holds reactive component state using Svelte 5 runes
|
|
154
|
-
- **Context Methods**: Static `CONTEXT_KEY`, `get()`, and `set()` methods for component communication
|
|
155
|
-
- **Component Files**: Svelte components that use the Bond for behavior
|
|
18
|
+
## Documentation
|
|
156
19
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
static CONTEXT_KEY = '@atoms/context/my-component';
|
|
160
|
-
|
|
161
|
-
static get(): MyComponentBond | undefined {
|
|
162
|
-
return getContext(MyComponentBond.CONTEXT_KEY);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
static set(bond: MyComponentBond): MyComponentBond {
|
|
166
|
-
return setContext(MyComponentBond.CONTEXT_KEY, bond);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
## π Quick Start
|
|
20
|
+
- **[Documentation](https://sacore.netlify.app/)** - Complete guides, API references, and examples
|
|
21
|
+
- **[Storybook](https://statuesque-boba-0fb888.netlify.app/)** - Interactive component playground
|
|
174
22
|
|
|
175
|
-
|
|
23
|
+
## Installation
|
|
176
24
|
|
|
177
25
|
```bash
|
|
178
|
-
# npm
|
|
179
26
|
npm install @svelte-atoms/core
|
|
180
|
-
|
|
181
|
-
# yarn
|
|
182
|
-
yarn install @svelte-atoms/core
|
|
183
|
-
|
|
184
|
-
# pnpm
|
|
185
|
-
pnpm add @svelte-atoms/core
|
|
186
|
-
|
|
187
|
-
# bun
|
|
188
|
-
bun add @svelte-atoms/core
|
|
189
27
|
```
|
|
190
28
|
|
|
191
|
-
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Basic Example
|
|
192
32
|
|
|
193
33
|
```svelte
|
|
194
34
|
<script lang="ts">
|
|
@@ -198,10 +38,8 @@ bun add @svelte-atoms/core
|
|
|
198
38
|
let inputValue = '';
|
|
199
39
|
</script>
|
|
200
40
|
|
|
201
|
-
<!-- Simple Button -->
|
|
202
41
|
<Button onclick={() => (dialogOpen = true)}>Open Dialog</Button>
|
|
203
42
|
|
|
204
|
-
<!-- Dialog with Input -->
|
|
205
43
|
<Dialog.Root bind:open={dialogOpen}>
|
|
206
44
|
<Dialog.Content>
|
|
207
45
|
<Dialog.Header>
|
|
@@ -209,644 +47,243 @@ bun add @svelte-atoms/core
|
|
|
209
47
|
</Dialog.Header>
|
|
210
48
|
<Dialog.Body>
|
|
211
49
|
<Input.Root>
|
|
212
|
-
<Input.
|
|
50
|
+
<Input.Control bind:value={inputValue} placeholder="Your name..." />
|
|
213
51
|
</Input.Root>
|
|
214
52
|
</Dialog.Body>
|
|
215
53
|
<Dialog.Footer>
|
|
216
|
-
<Button
|
|
217
|
-
<Button
|
|
54
|
+
<Button onclick={() => (dialogOpen = false)}>Cancel</Button>
|
|
55
|
+
<Button variant="primary" onclick={() => (dialogOpen = false)}>Confirm</Button>
|
|
218
56
|
</Dialog.Footer>
|
|
219
57
|
</Dialog.Content>
|
|
220
58
|
</Dialog.Root>
|
|
221
59
|
```
|
|
222
60
|
|
|
223
|
-
###
|
|
224
|
-
|
|
225
|
-
For more control, you can use the Bond system directly:
|
|
226
|
-
|
|
227
|
-
```svelte
|
|
228
|
-
<script lang="ts">
|
|
229
|
-
import { DialogBond, DialogBondState } from '@svelte-atoms/core/dialog';
|
|
230
|
-
|
|
231
|
-
const { open = false, disable = false } = $props();
|
|
232
|
-
|
|
233
|
-
const bondProps = defineState(
|
|
234
|
-
[
|
|
235
|
-
defineProperty(
|
|
236
|
-
'open',
|
|
237
|
-
() => open,
|
|
238
|
-
(v) => (open = v)
|
|
239
|
-
),
|
|
240
|
-
defineProperty('disable', () => disable)
|
|
241
|
-
],
|
|
242
|
-
{
|
|
243
|
-
// Other props
|
|
244
|
-
}
|
|
245
|
-
);
|
|
246
|
-
|
|
247
|
-
// Create dialog state
|
|
248
|
-
const dialogState = new DialogBondState(() => bondProps);
|
|
249
|
-
|
|
250
|
-
// Create dialog bond
|
|
251
|
-
// Make available via context
|
|
252
|
-
const dialogBond = new DialogBond(dialogState).share();
|
|
253
|
-
</script>
|
|
254
|
-
|
|
255
|
-
<div {...dialogBond.root()}>
|
|
256
|
-
<button {...dialogBond.trigger()} onclick={() => dialogBond.state.toggle()}>
|
|
257
|
-
Toggle Dialog
|
|
258
|
-
</button>
|
|
259
|
-
|
|
260
|
-
{#if open}
|
|
261
|
-
<div {...dialogBond.overlay()}>
|
|
262
|
-
<div {...dialogBond.content()}>
|
|
263
|
-
<h2 {...dialogBond.title()}>Dialog Title</h2>
|
|
264
|
-
<p>Dialog content goes here...</p>
|
|
265
|
-
<button onclick={() => dialogBond.state.close()}>Close</button>
|
|
266
|
-
</div>
|
|
267
|
-
</div>
|
|
268
|
-
{/if}
|
|
269
|
-
</div>
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
### Advanced Usage With Composition
|
|
61
|
+
### Composable Components
|
|
273
62
|
|
|
274
|
-
|
|
63
|
+
Combine components to create complex UIs:
|
|
275
64
|
|
|
276
65
|
```svelte
|
|
277
66
|
<script lang="ts">
|
|
278
67
|
import { Dropdown, Input, Root, filter } from '@svelte-atoms/core';
|
|
279
68
|
import { flip } from 'svelte/animate';
|
|
280
69
|
|
|
281
|
-
// Sample data
|
|
282
70
|
let data = [
|
|
283
71
|
{ id: 1, value: 'apple', text: 'Apple' },
|
|
284
72
|
{ id: 2, value: 'banana', text: 'Banana' },
|
|
285
|
-
{ id: 3, value: 'cherry', text: 'Cherry' }
|
|
286
|
-
{ id: 4, value: 'date', text: 'Date' },
|
|
287
|
-
{ id: 5, value: 'elderberry', text: 'Elderberry' }
|
|
73
|
+
{ id: 3, value: 'cherry', text: 'Cherry' }
|
|
288
74
|
];
|
|
289
75
|
|
|
290
76
|
let open = $state(false);
|
|
291
|
-
// Filter items based on search query
|
|
292
77
|
const dd = filter(
|
|
293
78
|
() => data,
|
|
294
79
|
(query, item) => item.text.toLowerCase().includes(query.toLowerCase())
|
|
295
80
|
);
|
|
296
81
|
</script>
|
|
297
82
|
|
|
298
|
-
<Root
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
keys={data.map((item) => item.value)}
|
|
304
|
-
onquerychange={(q) => (dd.query = q)}
|
|
305
|
-
>
|
|
306
|
-
{#snippet children({ dropdown })}
|
|
307
|
-
<!-- Compose Dropdown.Trigger with Input.Root for a custom trigger -->
|
|
308
|
-
<Dropdown.Trigger
|
|
309
|
-
base={Input.Root}
|
|
310
|
-
class="h-auto min-h-12 max-w-sm min-w-sm items-center gap-2 rounded-sm px-4 transition-colors duration-200"
|
|
311
|
-
onclick={(ev) => {
|
|
312
|
-
ev.preventDefault();
|
|
313
|
-
|
|
314
|
-
dropdown.state.open();
|
|
315
|
-
}}
|
|
316
|
-
>
|
|
317
|
-
<!-- Display selected values with animation -->
|
|
318
|
-
{#each dropdown?.state?.selectedItems ?? [] as item (item.id)}
|
|
319
|
-
<div animate:flip={{ duration: 200 }}>
|
|
320
|
-
<ADropdown.Value value={item.value} class="text-foreground/80">
|
|
321
|
-
{item.text}
|
|
322
|
-
</ADropdown.Value>
|
|
323
|
-
</div>
|
|
324
|
-
{/each}
|
|
325
|
-
|
|
326
|
-
<!-- Inline search input within the trigger -->
|
|
327
|
-
<Dropdown.Query class="flex-1 px-1" placeholder="Search for fruits..." />
|
|
328
|
-
</Dropdown.Trigger>
|
|
329
|
-
|
|
330
|
-
<!-- Dropdown list with filtered items -->
|
|
331
|
-
<Dropdown.List>
|
|
332
|
-
{#each dd.current as item (item.id)}
|
|
333
|
-
<div animate:flip={{ duration: 200 }}>
|
|
334
|
-
<Dropdown.Item value={item.value}>{item.text}</Dropdown.Item>
|
|
335
|
-
</div>
|
|
336
|
-
{/each}
|
|
337
|
-
</Dropdown.List>
|
|
338
|
-
{/snippet}
|
|
339
|
-
</Dropdown.Root>
|
|
340
|
-
</Root>
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
**Key composition features demonstrated:**
|
|
344
|
-
|
|
345
|
-
- **Component Fusion**: Using `base={Input.Root}` to compose Dropdown.Trigger with Input styling and behavior
|
|
346
|
-
- **Snippet Patterns**: Accessing internal state through snippets for custom rendering
|
|
347
|
-
- **Reactive Filtering**: Combining search query state with reactive effects for real-time filtering
|
|
348
|
-
- **Smooth Animations**: Using Svelte's `flip` animation for seamless list transitions
|
|
349
|
-
- **Multi-Select State**: Managing complex selection state through the Bond pattern
|
|
350
|
-
|
|
351
|
-
### Creating Custom Variants
|
|
352
|
-
|
|
353
|
-
@svelte-atoms/core provides a powerful variant system using `defineVariants()` that allows you to create type-safe, reusable component variations with support for compound variants, defaults, and bond state integration.
|
|
354
|
-
|
|
355
|
-
#### Basic Variant Definition
|
|
356
|
-
|
|
357
|
-
```typescript
|
|
358
|
-
import { defineVariants, type VariantPropsType } from '@svelte-atoms/core/utils';
|
|
359
|
-
|
|
360
|
-
const buttonVariants = defineVariants({
|
|
361
|
-
class: 'inline-flex items-center justify-center rounded-md font-medium transition-colors',
|
|
362
|
-
variants: {
|
|
363
|
-
variant: {
|
|
364
|
-
primary: 'bg-blue-500 text-white hover:bg-blue-600',
|
|
365
|
-
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
|
|
366
|
-
ghost: 'hover:bg-gray-100'
|
|
367
|
-
},
|
|
368
|
-
size: {
|
|
369
|
-
sm: 'h-8 px-3 text-sm',
|
|
370
|
-
md: 'h-10 px-4',
|
|
371
|
-
lg: 'h-12 px-6 text-lg'
|
|
372
|
-
}
|
|
373
|
-
},
|
|
374
|
-
compounds: [
|
|
375
|
-
{
|
|
376
|
-
variant: 'primary',
|
|
377
|
-
size: 'lg',
|
|
378
|
-
class: 'shadow-md font-semibold'
|
|
379
|
-
}
|
|
380
|
-
],
|
|
381
|
-
defaults: {
|
|
382
|
-
variant: 'primary',
|
|
383
|
-
size: 'md'
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// Extract type-safe props
|
|
388
|
-
type ButtonVariantProps = VariantPropsType<typeof buttonVariants>;
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
#### Local vs Global Variants
|
|
392
|
-
|
|
393
|
-
**Local Variants** - Define variants directly in your component:
|
|
394
|
-
|
|
395
|
-
```svelte
|
|
396
|
-
<script lang="ts">
|
|
397
|
-
import { HtmlAtom } from '@svelte-atoms/core';
|
|
398
|
-
import { defineVariants, type VariantPropsType } from '@svelte-atoms/core/utils';
|
|
399
|
-
|
|
400
|
-
const buttonVariants = defineVariants({
|
|
401
|
-
class: 'rounded-md font-medium',
|
|
402
|
-
variants: {
|
|
403
|
-
variant: {
|
|
404
|
-
primary: 'bg-blue-500 text-white',
|
|
405
|
-
secondary: 'bg-gray-500 text-white'
|
|
406
|
-
},
|
|
407
|
-
size: {
|
|
408
|
-
sm: 'px-2 py-1 text-sm',
|
|
409
|
-
md: 'px-4 py-2 text-base'
|
|
410
|
-
}
|
|
411
|
-
},
|
|
412
|
-
defaults: {
|
|
413
|
-
variant: 'primary',
|
|
414
|
-
size: 'md'
|
|
415
|
-
}
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
type ButtonProps = VariantPropsType<typeof buttonVariants> & {
|
|
419
|
-
disabled?: boolean;
|
|
420
|
-
class?: string;
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
let { variant, size, disabled = false, class: klass = '', ...props }: ButtonProps = $props();
|
|
424
|
-
|
|
425
|
-
const variantProps = $derived(buttonVariants(null, { variant, size }));
|
|
426
|
-
</script>
|
|
427
|
-
|
|
428
|
-
<HtmlAtom
|
|
429
|
-
as="button"
|
|
430
|
-
variants={variantProps}
|
|
431
|
-
{disabled}
|
|
432
|
-
class={[variantProps.class, klass]}
|
|
433
|
-
{...props}
|
|
83
|
+
<Dropdown.Root
|
|
84
|
+
bind:open
|
|
85
|
+
multiple
|
|
86
|
+
keys={data.map((item) => item.value)}
|
|
87
|
+
onquerychange={(q) => (dd.query = q)}
|
|
434
88
|
>
|
|
435
|
-
{@render children?.()}
|
|
436
|
-
</HtmlAtom>
|
|
437
|
-
```
|
|
438
|
-
|
|
439
|
-
**Global Variants** - Define variants in your theme/preset configuration:
|
|
440
|
-
|
|
441
|
-
```typescript
|
|
442
|
-
// +layout.svelte or theme configuration
|
|
443
|
-
import { setPreset } from '@svelte-atoms/core/context';
|
|
444
|
-
|
|
445
|
-
setPreset({
|
|
446
|
-
button: () => ({
|
|
447
|
-
class: 'inline-flex items-center justify-center rounded-md font-medium transition-colors',
|
|
448
|
-
variants: {
|
|
449
|
-
variant: {
|
|
450
|
-
default: {
|
|
451
|
-
class: 'bg-primary text-primary-foreground hover:bg-primary/90'
|
|
452
|
-
},
|
|
453
|
-
destructive: {
|
|
454
|
-
class: 'bg-destructive text-destructive-foreground hover:bg-destructive/90'
|
|
455
|
-
},
|
|
456
|
-
outline: {
|
|
457
|
-
class: 'border border-input bg-background hover:bg-accent'
|
|
458
|
-
}
|
|
459
|
-
},
|
|
460
|
-
size: {
|
|
461
|
-
default: 'h-10 px-4 py-2',
|
|
462
|
-
sm: 'h-9 px-3',
|
|
463
|
-
lg: 'h-11 px-8'
|
|
464
|
-
}
|
|
465
|
-
},
|
|
466
|
-
compounds: [
|
|
467
|
-
{
|
|
468
|
-
variant: 'default',
|
|
469
|
-
size: 'lg',
|
|
470
|
-
class: 'text-base font-semibold'
|
|
471
|
-
}
|
|
472
|
-
],
|
|
473
|
-
defaults: {
|
|
474
|
-
variant: 'default',
|
|
475
|
-
size: 'default'
|
|
476
|
-
}
|
|
477
|
-
})
|
|
478
|
-
});
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
#### Extending Global Variants
|
|
482
|
-
|
|
483
|
-
Combine global presets with local extensions:
|
|
484
|
-
|
|
485
|
-
```svelte
|
|
486
|
-
<script lang="ts">
|
|
487
|
-
import { HtmlAtom } from '@svelte-atoms/core';
|
|
488
|
-
import { defineVariants } from '@svelte-atoms/core/utils';
|
|
489
|
-
|
|
490
|
-
// Extend preset variants with local additions
|
|
491
|
-
const extendedVariants = defineVariants({
|
|
492
|
-
variants: {
|
|
493
|
-
variant: {
|
|
494
|
-
// Add new variants not in preset
|
|
495
|
-
gradient: {
|
|
496
|
-
class: 'bg-gradient-to-r from-purple-500 to-pink-500 text-white'
|
|
497
|
-
},
|
|
498
|
-
neon: {
|
|
499
|
-
class: 'bg-black text-green-400 border-2 border-green-400'
|
|
500
|
-
}
|
|
501
|
-
},
|
|
502
|
-
// Add new variant dimension
|
|
503
|
-
animated: {
|
|
504
|
-
true: 'animate-pulse',
|
|
505
|
-
false: ''
|
|
506
|
-
}
|
|
507
|
-
},
|
|
508
|
-
defaults: {
|
|
509
|
-
animated: false
|
|
510
|
-
}
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
let { variant, size, animated, ...props } = $props();
|
|
514
|
-
</script>
|
|
515
|
-
|
|
516
|
-
<HtmlAtom
|
|
517
|
-
preset="button"
|
|
518
|
-
variants={extendedVariants}
|
|
519
|
-
as="button"
|
|
520
|
-
{variant}
|
|
521
|
-
{size}
|
|
522
|
-
{animated}
|
|
523
|
-
{...props}
|
|
524
|
-
>
|
|
525
|
-
{@render children?.()}
|
|
526
|
-
</HtmlAtom>
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
#### Bond-Reactive Variants
|
|
530
|
-
|
|
531
|
-
Variants can react to component state through the Bond pattern:
|
|
532
|
-
|
|
533
|
-
```typescript
|
|
534
|
-
const accordionVariants = defineVariants({
|
|
535
|
-
class: 'border rounded-md transition-all',
|
|
536
|
-
variants: {
|
|
537
|
-
state: {
|
|
538
|
-
open: (bond) => ({
|
|
539
|
-
class: bond?.state?.isOpen ? 'bg-blue-50 border-blue-200' : 'bg-white',
|
|
540
|
-
'aria-expanded': bond?.state?.isOpen,
|
|
541
|
-
'data-state': bond?.state?.isOpen ? 'open' : 'closed'
|
|
542
|
-
})
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
// Usage with bond
|
|
548
|
-
const bond = AccordionBond.get();
|
|
549
|
-
const variantProps = $derived(accordionVariants(bond, { state: 'open' }));
|
|
550
|
-
```
|
|
551
|
-
|
|
552
|
-
**Variant Features:**
|
|
553
|
-
|
|
554
|
-
- β
**Type Safety** - Automatic TypeScript inference
|
|
555
|
-
- β
**Compound Variants** - Apply styles when multiple conditions match
|
|
556
|
-
- β
**Default Values** - Specify fallback variant values
|
|
557
|
-
- β
**Bond Integration** - Access component state for reactive styling
|
|
558
|
-
- β
**Return Attributes** - Not just classes, any HTML attributes
|
|
559
|
-
- β
**Extensible** - Combine global presets with local variants
|
|
560
|
-
|
|
561
|
-
---
|
|
562
|
-
|
|
563
|
-
## π Documentation
|
|
564
|
-
|
|
565
|
-
### Component Examples
|
|
566
|
-
|
|
567
|
-
#### Dropdown with Multiple Selection
|
|
568
|
-
|
|
569
|
-
```svelte
|
|
570
|
-
<script lang="ts">
|
|
571
|
-
import { Dropdown } from '@svelte-atoms/core';
|
|
572
|
-
|
|
573
|
-
let selectedValues = ['option1'];
|
|
574
|
-
const options = [
|
|
575
|
-
{ value: 'option1', label: 'Option 1' },
|
|
576
|
-
{ value: 'option2', label: 'Option 2' },
|
|
577
|
-
{ value: 'option3', label: 'Option 3' }
|
|
578
|
-
];
|
|
579
|
-
</script>
|
|
580
|
-
|
|
581
|
-
<Dropdown.Root multiple bind:values={selectedValues}>
|
|
582
|
-
<!-- Access internal bond -->
|
|
583
89
|
{#snippet children({ dropdown })}
|
|
584
|
-
<Dropdown.Trigger
|
|
585
|
-
|
|
90
|
+
<Dropdown.Trigger
|
|
91
|
+
base={Input.Root}
|
|
92
|
+
onclick={(ev) => {
|
|
93
|
+
ev.preventDefault();
|
|
94
|
+
dropdown.state.open();
|
|
95
|
+
}}
|
|
96
|
+
>
|
|
97
|
+
{#each dropdown?.state?.selectedItems ?? [] as item (item.id)}
|
|
98
|
+
<div animate:flip={{ duration: 200 }}>
|
|
99
|
+
<Dropdown.Value value={item.value}>{item.text}</Dropdown.Value>
|
|
100
|
+
</div>
|
|
101
|
+
{/each}
|
|
102
|
+
<Dropdown.Query placeholder="Search..." />
|
|
586
103
|
</Dropdown.Trigger>
|
|
587
104
|
|
|
588
105
|
<Dropdown.Content>
|
|
589
|
-
{#each
|
|
590
|
-
<
|
|
591
|
-
{
|
|
592
|
-
</
|
|
106
|
+
{#each dd.current as item (item.id)}
|
|
107
|
+
<div animate:flip={{ duration: 200 }}>
|
|
108
|
+
<Dropdown.Item value={item.value}>{item.text}</Dropdown.Item>
|
|
109
|
+
</div>
|
|
593
110
|
{/each}
|
|
594
111
|
</Dropdown.Content>
|
|
595
112
|
{/snippet}
|
|
596
113
|
</Dropdown.Root>
|
|
597
114
|
```
|
|
598
115
|
|
|
599
|
-
|
|
116
|
+
### Extensibility with `as` and `base` Props
|
|
117
|
+
|
|
118
|
+
Transform components into any element or wrap them with custom logic:
|
|
600
119
|
|
|
601
120
|
```svelte
|
|
602
121
|
<script lang="ts">
|
|
603
|
-
import {
|
|
604
|
-
import { z } from 'zod';
|
|
605
|
-
|
|
606
|
-
const schema = z.object({
|
|
607
|
-
email: z.string().email('Invalid email address'),
|
|
608
|
-
password: z.string().min(8, 'Password must be at least 8 characters')
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
let formData = { email: '', password: '' };
|
|
612
|
-
let errors = {};
|
|
122
|
+
import { Button, Popover, Input } from '@svelte-atoms/core';
|
|
613
123
|
</script>
|
|
614
124
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
<
|
|
627
|
-
<
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
/>
|
|
634
|
-
</Field.Control>
|
|
635
|
-
{#if errors.password}
|
|
636
|
-
<Field.Error>{errors.password}</Field.Error>
|
|
637
|
-
{/if}
|
|
638
|
-
</.Field>
|
|
639
|
-
|
|
640
|
-
<Button type="submit">Submit</Button>
|
|
641
|
-
</Form>
|
|
125
|
+
<!-- Use Button as Popover trigger -->
|
|
126
|
+
<Popover.Root>
|
|
127
|
+
<Popover.Trigger base={Button} variant="outline">Open Popover</Popover.Trigger>
|
|
128
|
+
<Popover.Content class="p-4">
|
|
129
|
+
<h4 class="font-semibold">Settings</h4>
|
|
130
|
+
<p class="text-sm">Configure your preferences here.</p>
|
|
131
|
+
</Popover.Content>
|
|
132
|
+
</Popover.Root>
|
|
133
|
+
|
|
134
|
+
<!-- Use Input.Root as Popover trigger -->
|
|
135
|
+
<Popover.Root>
|
|
136
|
+
<Popover.Trigger base={Input.Root}>
|
|
137
|
+
<Input.Control placeholder="Click to open popover..." readonly />
|
|
138
|
+
</Popover.Trigger>
|
|
139
|
+
<Popover.Content class="p-4">
|
|
140
|
+
<p class="text-sm">Popover triggered by an input field</p>
|
|
141
|
+
</Popover.Content>
|
|
142
|
+
</Popover.Root>
|
|
642
143
|
```
|
|
643
144
|
|
|
644
|
-
|
|
145
|
+
### Working with Animations
|
|
146
|
+
|
|
147
|
+
Seamlessly integrate with Svelte's animation system:
|
|
645
148
|
|
|
646
149
|
```svelte
|
|
647
150
|
<script lang="ts">
|
|
648
|
-
import {
|
|
151
|
+
import { List, Button } from '@svelte-atoms/core';
|
|
152
|
+
import { flip } from 'svelte/animate';
|
|
153
|
+
import { slide } from 'svelte/transition';
|
|
649
154
|
|
|
650
|
-
let
|
|
651
|
-
{ id: 1,
|
|
652
|
-
{ id: 2,
|
|
653
|
-
{ id: 3,
|
|
654
|
-
];
|
|
155
|
+
let items = $state([
|
|
156
|
+
{ id: 1, text: 'Task 1' },
|
|
157
|
+
{ id: 2, text: 'Task 2' },
|
|
158
|
+
{ id: 3, text: 'Task 3' }
|
|
159
|
+
]);
|
|
655
160
|
|
|
656
|
-
|
|
161
|
+
function removeItem(id: number) {
|
|
162
|
+
items = items.filter((item) => item.id !== id);
|
|
163
|
+
}
|
|
657
164
|
</script>
|
|
658
165
|
|
|
659
|
-
<
|
|
660
|
-
|
|
661
|
-
<
|
|
662
|
-
<
|
|
663
|
-
<
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
</DataGrid.Header>
|
|
670
|
-
|
|
671
|
-
<DataGrid.Body>
|
|
672
|
-
{#each data as row}
|
|
673
|
-
<DataGrid.Tr value={row.id}>
|
|
674
|
-
<DataGrid.Td>
|
|
675
|
-
<Checkbox.Root value={row.id} />
|
|
676
|
-
</DataGrid.Td>
|
|
677
|
-
<DataGrid.Td>{row.name}</DataGrid.Td>
|
|
678
|
-
<DataGrid.Td>{row.email}</DataGrid.Td>
|
|
679
|
-
<DataGrid.Td>{row.role}</DataGrid.Td>
|
|
680
|
-
</DataGrid.Tr>
|
|
681
|
-
{/each}
|
|
682
|
-
</DataGrid.Body>
|
|
683
|
-
</DataGrid.Root>
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
---
|
|
687
|
-
|
|
688
|
-
## π¨ Styling
|
|
689
|
-
|
|
690
|
-
@svelte-atoms/core is completely headless, giving you full control over styling. Here are some approaches:
|
|
691
|
-
|
|
692
|
-
### Using Vanilla CSS
|
|
693
|
-
|
|
694
|
-
```css
|
|
695
|
-
/* Default button styles */
|
|
696
|
-
.btn {
|
|
697
|
-
@apply rounded-md px-4 py-2 font-medium transition-colors;
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
.btn-primary {
|
|
701
|
-
@apply bg-blue-600 text-white hover:bg-blue-700;
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
.btn-secondary {
|
|
705
|
-
@apply bg-gray-200 text-gray-900 hover:bg-gray-300;
|
|
706
|
-
}
|
|
166
|
+
<List.Root>
|
|
167
|
+
{#each items as item (item.id)}
|
|
168
|
+
<div animate:flip={{ duration: 300 }}>
|
|
169
|
+
<List.Item>
|
|
170
|
+
<span>{item.text}</span>
|
|
171
|
+
<Button size="sm" onclick={() => removeItem(item.id)}>Remove</Button>
|
|
172
|
+
</List.Item>
|
|
173
|
+
</div>
|
|
174
|
+
{/each}
|
|
175
|
+
</List.Root>
|
|
707
176
|
```
|
|
708
177
|
|
|
709
|
-
|
|
178
|
+
Advanced animation with lifecycle hooks using Motion:
|
|
710
179
|
|
|
711
180
|
```svelte
|
|
712
|
-
<
|
|
713
|
-
|
|
181
|
+
<script lang="ts">
|
|
182
|
+
import { Dialog, Button, toTransitionConfig } from '@svelte-atoms/core';
|
|
183
|
+
import { animate } from 'motion';
|
|
714
184
|
|
|
715
|
-
|
|
185
|
+
let open = $state(false);
|
|
186
|
+
</script>
|
|
716
187
|
|
|
717
|
-
|
|
188
|
+
<Button onclick={() => (open = true)}>Open Dialog</Button>
|
|
189
|
+
|
|
190
|
+
<Dialog.Root bind:open>
|
|
191
|
+
<Dialog.Overlay
|
|
192
|
+
initial={(node) => {
|
|
193
|
+
node.style.opacity = '0';
|
|
194
|
+
}}
|
|
195
|
+
enter={(node) => {
|
|
196
|
+
const duration = 0.2;
|
|
197
|
+
const animation = animate(node, { opacity: 1 }, { duration });
|
|
198
|
+
return { duration };
|
|
199
|
+
}}
|
|
200
|
+
exit={(node) => {
|
|
201
|
+
const duration = 0.1;
|
|
202
|
+
const animation = animate(node, { opacity: 0 }, { duration: 0.1 });
|
|
203
|
+
return { duration };
|
|
204
|
+
}}
|
|
205
|
+
/>
|
|
206
|
+
<Dialog.Content
|
|
207
|
+
initial={(node) => {
|
|
208
|
+
node.style.opacity = '0';
|
|
209
|
+
node.style.scale = '0.95';
|
|
210
|
+
}}
|
|
211
|
+
enter={(node) => {
|
|
212
|
+
const duration = 0.3;
|
|
213
|
+
const animation = animate(node, { opacity: 1, scale: 1 }, { duration, easing: 'ease-out' });
|
|
214
|
+
return { duration };
|
|
215
|
+
}}
|
|
216
|
+
exit={(node) => {
|
|
217
|
+
const animation = animate(node, { opacity: 0, scale: 0.95 }, { duration, easing: 'ease-in' });
|
|
218
|
+
return { duration };
|
|
219
|
+
}}
|
|
220
|
+
>
|
|
221
|
+
<Dialog.Header>
|
|
222
|
+
<Dialog.Title>Animated Dialog</Dialog.Title>
|
|
223
|
+
</Dialog.Header>
|
|
224
|
+
<Dialog.Body>
|
|
225
|
+
<p>This dialog animates with custom Motion transitions using lifecycle hooks.</p>
|
|
226
|
+
</Dialog.Body>
|
|
227
|
+
<Dialog.Footer>
|
|
228
|
+
<Button onclick={() => (open = false)}>Close</Button>
|
|
229
|
+
</Dialog.Footer>
|
|
230
|
+
</Dialog.Content>
|
|
231
|
+
</Dialog.Root>
|
|
232
|
+
```
|
|
718
233
|
|
|
719
|
-
###
|
|
234
|
+
### Styling with Variants
|
|
720
235
|
|
|
721
|
-
|
|
236
|
+
Variants can be created locally at component level or globally in the preset configuration:
|
|
722
237
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
cd svelte-atoms
|
|
726
|
-
```
|
|
238
|
+
```typescript
|
|
239
|
+
import { defineVariants } from '@svelte-atoms/core/utils';
|
|
727
240
|
|
|
728
|
-
|
|
241
|
+
const buttonVariants = defineVariants({
|
|
242
|
+
class: 'inline-flex items-center justify-center rounded-md font-medium',
|
|
243
|
+
variants: {
|
|
244
|
+
variant: {
|
|
245
|
+
primary: 'bg-blue-500 text-white hover:bg-blue-600',
|
|
246
|
+
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300'
|
|
247
|
+
},
|
|
248
|
+
size: {
|
|
249
|
+
sm: 'h-8 px-3 text-sm',
|
|
250
|
+
md: 'h-10 px-4',
|
|
251
|
+
lg: 'h-12 px-6 text-lg'
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
defaults: {
|
|
255
|
+
variant: 'primary',
|
|
256
|
+
size: 'md'
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
```
|
|
729
260
|
|
|
730
|
-
|
|
731
|
-
bun install
|
|
732
|
-
```
|
|
261
|
+
## Development
|
|
733
262
|
|
|
734
|
-
|
|
263
|
+
```bash
|
|
264
|
+
# Clone repository
|
|
265
|
+
git clone https://github.com/svelte-atoms/core.git
|
|
266
|
+
cd svelte-atoms
|
|
735
267
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
```
|
|
268
|
+
# Install dependencies
|
|
269
|
+
bun install
|
|
739
270
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
bun run storybook:dev
|
|
743
|
-
```
|
|
271
|
+
# Start dev server
|
|
272
|
+
bun dev
|
|
744
273
|
|
|
745
|
-
|
|
274
|
+
# Run tests
|
|
275
|
+
bun test
|
|
746
276
|
|
|
747
|
-
```bash
|
|
748
277
|
# Build library
|
|
749
278
|
bun run build
|
|
750
|
-
|
|
751
|
-
# Build Storybook
|
|
752
|
-
bun run storybook:build
|
|
753
279
|
```
|
|
754
280
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
<!-- ## π€ Contributing
|
|
758
|
-
|
|
759
|
-
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. -->
|
|
760
|
-
|
|
761
|
-
<!-- ### Development Workflow
|
|
762
|
-
|
|
763
|
-
1. Fork the repository
|
|
764
|
-
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
765
|
-
3. Make your changes and add tests
|
|
766
|
-
4. Run the test suite: `bun test`
|
|
767
|
-
5. Commit your changes: `git commit -m 'Add amazing feature'`
|
|
768
|
-
6. Push to the branch: `git push origin feature/amazing-feature`
|
|
769
|
-
7. Open a Pull Request -->
|
|
770
|
-
|
|
771
|
-
### Creating New Components
|
|
772
|
-
|
|
773
|
-
When adding new components, follow these guidelines:
|
|
774
|
-
|
|
775
|
-
1. **Create the bond structure:**
|
|
776
|
-
|
|
777
|
-
```
|
|
778
|
-
src/lib/atoms/my-component/
|
|
779
|
-
βββ bond.svelte.ts # Core bond logic (Bond + BondState classes)
|
|
780
|
-
βββ index.ts # Public exports
|
|
781
|
-
βββ atoms.ts # Component exports
|
|
782
|
-
βββ my-component-root.svelte # Use namespace pattern when building complex component
|
|
783
|
-
βββ my-component-content.svelte
|
|
784
|
-
βββ README.md # Component documentation
|
|
785
|
-
```
|
|
786
|
-
|
|
787
|
-
2. **Implement accessibility features:**
|
|
788
|
-
- ARIA attributes
|
|
789
|
-
- Keyboard navigation
|
|
790
|
-
- Focus management
|
|
791
|
-
- Screen reader support
|
|
792
|
-
|
|
793
|
-
3. **Add comprehensive tests:**
|
|
794
|
-
- Unit tests for bond logic
|
|
795
|
-
- Component integration tests
|
|
796
|
-
- Accessibility tests
|
|
797
|
-
|
|
798
|
-
4. **Create Storybook stories:**
|
|
799
|
-
- Basic usage examples
|
|
800
|
-
- Advanced configurations
|
|
801
|
-
- Interactive demos
|
|
802
|
-
|
|
803
|
-
---
|
|
804
|
-
|
|
805
|
-
## π Resources
|
|
806
|
-
|
|
807
|
-
- **[Documentation](https://svelte-atoms.dev)** - Comprehensive documentation
|
|
808
|
-
- **[Storybook](https://storybook.svelte-atoms.dev/)** - Interactive component documentation
|
|
809
|
-
- **[GitHub](https://github.com/ryu-man/svelte-atoms)** - Source code and issues
|
|
810
|
-
- **[@svelte-atoms/alchemist](../alchimist)** - Data visualization companion library
|
|
811
|
-
|
|
812
|
-
---
|
|
813
|
-
|
|
814
|
-
## πΊοΈ Roadmap
|
|
815
|
-
|
|
816
|
-
### v1.0.0 (Current - Alpha)
|
|
817
|
-
|
|
818
|
-
- β
Bond architecture with Svelte 5 runes
|
|
819
|
-
- β
35+ essential components
|
|
820
|
-
- β
TypeScript support
|
|
821
|
-
- β
Accessibility features
|
|
822
|
-
- β
Storybook documentation
|
|
823
|
-
- β
Standardized context pattern
|
|
824
|
-
|
|
825
|
-
---
|
|
826
|
-
|
|
827
|
-
## π License
|
|
828
|
-
|
|
829
|
-
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
830
|
-
|
|
831
|
-
---
|
|
832
|
-
|
|
833
|
-
## π Acknowledgements
|
|
281
|
+
## License
|
|
834
282
|
|
|
835
|
-
- [
|
|
836
|
-
- [Motion](https://motion.dev/) - For handling internal default animations
|
|
837
|
-
- [Floating UI](https://floating-ui.com/) - For advanced positioning logic
|
|
838
|
-
- [Tailwind CSS](https://tailwindcss.com/) - For styling
|
|
839
|
-
- [Storybook](https://storybook.js.org/) - For component documentation and testing
|
|
840
|
-
- [Vitest](https://vitest.dev/) - For fast and reliable testing
|
|
841
|
-
- [Playwright](https://playwright.dev/) - For end-to-end testing
|
|
283
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
842
284
|
|
|
843
285
|
---
|
|
844
286
|
|
|
845
287
|
<div align="center">
|
|
846
288
|
<p>Built with β€οΈ by the Svelte Atoms team</p>
|
|
847
|
-
<!-- <p>
|
|
848
|
-
<a href="https://github.com/ryu-man/svelte-atoms">GitHub</a> β’
|
|
849
|
-
<a href="https://svelte-atoms.dev">Documentation</a> β’
|
|
850
|
-
<a href="https://storybook.svelte-atoms.dev">Storybook</a>
|
|
851
|
-
</p> -->
|
|
852
289
|
</div>
|