@svelte-atoms/core 1.0.0-alpha.23 → 1.0.0-alpha.25

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.
Files changed (56) hide show
  1. package/README.md +645 -645
  2. package/dist/components/accordion/accordion-root.svelte.d.ts +2 -2
  3. package/dist/components/alert/alert-actions.svelte.d.ts +1 -0
  4. package/dist/components/alert/alert-close-button.svelte.d.ts +1 -0
  5. package/dist/components/alert/alert-content.svelte.d.ts +1 -0
  6. package/dist/components/atom/html-atom.svelte +151 -4
  7. package/dist/components/atom/html-atom.svelte.d.ts +4 -2
  8. package/dist/components/atom/types.d.ts +7 -0
  9. package/dist/components/button/button.stories.svelte +57 -17
  10. package/dist/components/button/button.stories.svelte.d.ts +6 -14
  11. package/dist/components/checkbox/checkbox.svelte.d.ts +1 -1
  12. package/dist/components/combobox/combobox-root.svelte.d.ts +2 -2
  13. package/dist/components/datagrid/datagrid.stories.svelte +75 -75
  14. package/dist/components/drawer/drawer-backdrop.svelte.d.ts +1 -0
  15. package/dist/components/icon/icon.svelte.d.ts +1 -0
  16. package/dist/components/input/input-placeholder.svelte +56 -56
  17. package/dist/components/input/input-placeholder.svelte.d.ts +1 -0
  18. package/dist/components/input/input-root.svelte +79 -79
  19. package/dist/components/input/input-root.svelte.d.ts +1 -0
  20. package/dist/components/input/input-value.svelte +113 -113
  21. package/dist/components/input/input-value.svelte.d.ts +1 -1
  22. package/dist/components/input/input.stories.svelte +38 -38
  23. package/dist/components/label/label.svelte.d.ts +1 -0
  24. package/dist/components/layer/layer-inner.svelte.d.ts +1 -0
  25. package/dist/components/layer/layer-root.svelte.d.ts +1 -0
  26. package/dist/components/popover/popover-arrow.svelte.d.ts +1 -0
  27. package/dist/components/portal/portal-inner.svelte.d.ts +1 -0
  28. package/dist/components/portal/portal-root.svelte.d.ts +1 -0
  29. package/dist/components/portal/teleport.svelte.d.ts +1 -0
  30. package/dist/components/radio/radio.svelte.d.ts +2 -2
  31. package/dist/components/root/root.svelte +121 -103
  32. package/dist/components/root/root.svelte.d.ts +1 -0
  33. package/dist/components/stack/stack-root.svelte.d.ts +1 -0
  34. package/dist/components/toast/toast-description.svelte.d.ts +1 -0
  35. package/dist/components/toast/toast-root.svelte.d.ts +1 -0
  36. package/dist/components/toast/toast-title.svelte.d.ts +1 -0
  37. package/dist/components/tree/tree-header.svelte.d.ts +1 -0
  38. package/dist/context/preset.svelte.d.ts +3 -0
  39. package/dist/runes/index.d.ts +3 -0
  40. package/dist/runes/index.js +3 -0
  41. package/dist/runes/reduced-motion.svelte.d.ts +23 -0
  42. package/dist/runes/reduced-motion.svelte.js +41 -0
  43. package/dist/utils/index.d.ts +1 -0
  44. package/dist/utils/index.js +1 -0
  45. package/dist/utils/variant.d.ts +213 -0
  46. package/dist/utils/variant.js +137 -0
  47. package/llm/composition.md +395 -0
  48. package/llm/crafting.md +838 -0
  49. package/llm/motion.md +970 -0
  50. package/llm/philosophy.md +23 -0
  51. package/llm/preset-variant-integration.md +516 -0
  52. package/llm/preset.md +383 -0
  53. package/llm/styling.md +216 -0
  54. package/llm/usage.md +46 -0
  55. package/llm/variants.md +712 -0
  56. package/package.json +2 -1
@@ -0,0 +1,23 @@
1
+ The Atomic Svelte philosophy is centered around creating a modular, composable UI library that treats components as fundamental building blocks. Here are the core principles:
2
+
3
+ # 🧱 Atomic Architecture
4
+
5
+ The philosophy is built around the concept of "atoms" - self-contained, reusable UI components that encapsulate their own state and DOM management. Think of it like chemistry: components are the basic elements that can be combined to create more complex molecules (UI patterns).
6
+
7
+ # Core Structure
8
+
9
+ Atoms: The smallest composable UI pieces - fundamental building blocks
10
+ Bonds: The logic that holds atoms together and enables synchronization between them
11
+ Protons, Neutrons, Electrons: Functions that can be attached to atoms to add incremental functionality
12
+
13
+ # Key Philosophy Points
14
+
15
+ 🔗 Context-Driven Communication: Components communicate through Svelte's context API, enabling powerful parent-child relationships without prop drilling.
16
+
17
+ - ♿ Accessibility First: Every component includes proper ARIA attributes, keyboard navigation, and focus management out of the box.
18
+ - 🎨 Headless & Stylable: Components are headless by default, giving you complete control over styling while providing sensible defaults.
19
+ - ⚡ Reactive by Design: Leverages Svelte's fine-grained reactivity system for optimal performance and smooth user interactions.
20
+ - 🔧 Highly Extensible: Easily extend components with custom behaviors, animations, and styling while maintaining core functionality.
21
+ - 🎯 Type Safety: Fully written in TypeScript with comprehensive type definitions for a robust development experience.
22
+
23
+ The philosophy treats the library as "raw material" - providing low-level, customizable, scalable UI components that teams can use to build their own custom design systems rather than prescriptive, opinionated components. This approach gives developers maximum flexibility while ensuring consistency and accessibility across their applications.
@@ -0,0 +1,516 @@
1
+ # Preset-Variant Integration
2
+
3
+ ## Overview
4
+
5
+ The variant system is deeply integrated with the preset system in @svelte-atoms/core, providing a powerful theming architecture that combines:
6
+
7
+ - **Global variants** via presets (app-level theming)
8
+ - **Local variants** via component props (component-level customization)
9
+ - **Intelligent merging** that respects the hierarchy
10
+
11
+ ## Architecture
12
+
13
+ ```
14
+ ┌─────────────────────────────────────────────────────┐
15
+ │ Theme Layer (Preset System) │
16
+ │ │
17
+ │ setPreset({ │
18
+ │ button: () => ({ │
19
+ │ class: 'font-medium', // Base styling │
20
+ │ variants: { // Global variant defs │
21
+ │ base: 'rounded-md', │
22
+ │ variants: { │
23
+ │ variant: { primary: '...', secondary: '...' }│
24
+ │ size: { sm: '...', md: '...', lg: '...' } │
25
+ │ } │
26
+ │ } │
27
+ │ }) │
28
+ │ }) │
29
+ └─────────────────────────────────────────────────────┘
30
+
31
+ [MERGE STRATEGY]
32
+
33
+ ┌─────────────────────────────────────────────────────┐
34
+ │ Component Layer (Local Variants) │
35
+ │ │
36
+ │ <HtmlAtom │
37
+ │ preset="button" │
38
+ │ variants={localVariants} // Overrides/extends │
39
+ │ variant="primary" │
40
+ │ size="lg" │
41
+ │ /> │
42
+ └─────────────────────────────────────────────────────┘
43
+
44
+ [RESOLUTION]
45
+
46
+ ┌─────────────────────────────────────────────────────┐
47
+ │ Final Output │
48
+ │ │
49
+ │ class: merged classes from preset + local + props │
50
+ │ attributes: aria-*, data-*, role, etc. │
51
+ └─────────────────────────────────────────────────────┘
52
+ ```
53
+
54
+ ## Merge Strategy
55
+
56
+ ### 1. Variant Definition Merging
57
+
58
+ When both preset and component define variants, they merge as follows:
59
+
60
+ ```typescript
61
+ {
62
+ base: localVariants.base ?? presetVariants.base,
63
+
64
+ variants: merge(
65
+ presetVariants.variants ?? {},
66
+ localVariants.variants ?? {}
67
+ ),
68
+
69
+ compoundVariants: [
70
+ ...(presetVariants.compoundVariants ?? []),
71
+ ...(localVariants.compoundVariants ?? [])
72
+ ],
73
+
74
+ defaultVariants: merge(
75
+ presetVariants.defaultVariants ?? {},
76
+ localVariants.defaultVariants ?? {}
77
+ )
78
+ }
79
+ ```
80
+
81
+ **Rules:**
82
+
83
+ - Local `base` overrides preset `base`
84
+ - Local variants **merge** with preset variants (not replace)
85
+ - Compound variants from both are **concatenated**
86
+ - Default variants **merge** (local overrides preset)
87
+
88
+ ### 2. Class Resolution Order
89
+
90
+ ```
91
+ Final Class = [
92
+ preset.class, // 1. Preset base class
93
+ preset.variants.base, // 2. Preset variant base
94
+ mergedVariants.base, // 3. Merged variant base (local overrides)
95
+ variantClasses, // 4. Resolved variant classes
96
+ compoundClasses, // 5. Compound variant classes
97
+ component.class // 6. Component class prop (highest priority)
98
+ ]
99
+ ```
100
+
101
+ ### 3. Props Merging
102
+
103
+ ```typescript
104
+ {
105
+ ...preset (excluding: class, base, as, variants),
106
+ ...variantAttributes (aria-*, data-*, role, etc.),
107
+ ...componentProps (user-provided props - highest priority)
108
+ }
109
+ ```
110
+
111
+ ## Usage Patterns
112
+
113
+ ### Pattern 1: Pure Preset (No Local Variants)
114
+
115
+ **Best for:** Consistent components that don't need customization
116
+
117
+ ```typescript
118
+ // Theme.svelte
119
+ setPreset({
120
+ badge: () => ({
121
+ variants: {
122
+ base: 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-semibold',
123
+ variants: {
124
+ variant: {
125
+ default: 'bg-primary text-primary-foreground',
126
+ secondary: 'bg-secondary text-secondary-foreground',
127
+ destructive: 'bg-destructive text-destructive-foreground',
128
+ outline: 'border border-input'
129
+ }
130
+ },
131
+ defaultVariants: {
132
+ variant: 'default'
133
+ }
134
+ }
135
+ })
136
+ });
137
+ ```
138
+
139
+ ```svelte
140
+ <!-- Badge.svelte -->
141
+ <HtmlAtom preset="badge" {variant} {...props}>
142
+ {@render children?.()}
143
+ </HtmlAtom>
144
+ ```
145
+
146
+ **Result:** Uses 100% preset variants, no local customization
147
+
148
+ ---
149
+
150
+ ### Pattern 2: Preset + Local Extension
151
+
152
+ **Best for:** Components that need additional variants beyond theme
153
+
154
+ ```typescript
155
+ // Theme.svelte
156
+ setPreset({
157
+ button: () => ({
158
+ variants: {
159
+ base: 'rounded-md font-medium',
160
+ variants: {
161
+ variant: {
162
+ default: 'bg-primary text-primary-foreground',
163
+ secondary: 'bg-secondary text-secondary-foreground'
164
+ },
165
+ size: {
166
+ sm: 'h-8 px-3',
167
+ md: 'h-10 px-4',
168
+ lg: 'h-12 px-6'
169
+ }
170
+ },
171
+ defaultVariants: {
172
+ variant: 'default',
173
+ size: 'md'
174
+ }
175
+ }
176
+ })
177
+ });
178
+ ```
179
+
180
+ ```svelte
181
+ <!-- IconButton.svelte -->
182
+ <script>
183
+ import { defineVariants } from '@svelte-atoms/core/utils';
184
+
185
+ // Extend preset with icon-specific variants
186
+ const iconVariants = defineVariants({
187
+ variants: {
188
+ // Add new variant key not in preset
189
+ iconPosition: {
190
+ left: 'flex-row',
191
+ right: 'flex-row-reverse',
192
+ top: 'flex-col',
193
+ bottom: 'flex-col-reverse'
194
+ }
195
+ },
196
+ defaultVariants: {
197
+ iconPosition: 'left'
198
+ }
199
+ });
200
+ </script>
201
+
202
+ <HtmlAtom preset="button" variants={iconVariants} {variant} {size} {iconPosition} {...props}>
203
+ {@render children?.()}
204
+ </HtmlAtom>
205
+ ```
206
+
207
+ **Result:** Gets `variant` and `size` from preset, adds `iconPosition` locally
208
+
209
+ ---
210
+
211
+ ### Pattern 3: Preset Override
212
+
213
+ **Best for:** Special cases that need to completely override preset variants
214
+
215
+ ```typescript
216
+ // Theme.svelte
217
+ setPreset({
218
+ button: () => ({
219
+ variants: {
220
+ base: 'rounded-md',
221
+ variants: {
222
+ variant: {
223
+ default: 'bg-primary text-primary-foreground',
224
+ destructive: 'bg-destructive text-destructive-foreground'
225
+ }
226
+ }
227
+ }
228
+ })
229
+ });
230
+ ```
231
+
232
+ ```svelte
233
+ <!-- GradientButton.svelte -->
234
+ <script>
235
+ import { defineVariants } from '@svelte-atoms/core/utils';
236
+
237
+ // Override preset variants completely
238
+ const gradientVariants = defineVariants({
239
+ base: 'rounded-full', // Overrides preset base
240
+ variants: {
241
+ variant: {
242
+ // Overrides preset variants
243
+ purple: 'bg-gradient-to-r from-purple-500 to-pink-500',
244
+ blue: 'bg-gradient-to-r from-blue-500 to-cyan-500',
245
+ green: 'bg-gradient-to-r from-green-500 to-emerald-500'
246
+ }
247
+ },
248
+ defaultVariants: {
249
+ variant: 'purple'
250
+ }
251
+ });
252
+ </script>
253
+
254
+ <HtmlAtom preset="button" variants={gradientVariants} {variant} {...props}>
255
+ {@render children?.()}
256
+ </HtmlAtom>
257
+ ```
258
+
259
+ **Result:** Local variants completely replace preset variants for matching keys
260
+
261
+ ---
262
+
263
+ ### Pattern 4: Pure Local (No Preset)
264
+
265
+ **Best for:** One-off components that don't need global theming
266
+
267
+ ```svelte
268
+ <script>
269
+ import { defineVariants } from '@svelte-atoms/core/utils';
270
+
271
+ const customVariants = defineVariants({
272
+ base: 'custom-base-class',
273
+ variants: {
274
+ custom: {
275
+ a: 'class-a',
276
+ b: 'class-b'
277
+ }
278
+ }
279
+ });
280
+ </script>
281
+
282
+ <HtmlAtom variants={customVariants} custom="a" {...props}>
283
+ {@render children?.()}
284
+ </HtmlAtom>
285
+ ```
286
+
287
+ **Result:** No preset used, 100% local variant definition
288
+
289
+ ---
290
+
291
+ ### Pattern 5: Dynamic Variants with Bond
292
+
293
+ **Best for:** Reactive variants that change based on component state
294
+
295
+ ```typescript
296
+ // Theme.svelte
297
+ setPreset({
298
+ accordion: () => ({
299
+ variants: {
300
+ base: 'border rounded-md',
301
+ variants: {
302
+ state: {
303
+ // Function receives bond for reactive styling
304
+ open: (bond) => ({
305
+ class: bond?.state?.isOpen ? 'bg-accent' : 'bg-background',
306
+ 'aria-expanded': bond?.state?.isOpen,
307
+ 'data-state': bond?.state?.isOpen ? 'open' : 'closed'
308
+ })
309
+ }
310
+ }
311
+ }
312
+ })
313
+ });
314
+ ```
315
+
316
+ ```svelte
317
+ <!-- Accordion.svelte -->
318
+ <script>
319
+ import { AccordionBond } from './bond.svelte';
320
+
321
+ const bond = new AccordionBond(state).share();
322
+ </script>
323
+
324
+ <HtmlAtom preset="accordion" {bond} state="open" {...props}>
325
+ {@render children?.({ accordion: bond })}
326
+ </HtmlAtom>
327
+ ```
328
+
329
+ **Result:** Variants reactively update when `bond.state.isOpen` changes
330
+
331
+ ## Advanced Features
332
+
333
+ ### 1. Nested Preset Keys
334
+
335
+ Organize related components with dot notation:
336
+
337
+ ```typescript
338
+ setPreset({
339
+ card: () => ({
340
+ /* ... */
341
+ }),
342
+ 'card.header': () => ({
343
+ /* ... */
344
+ }),
345
+ 'card.body': () => ({
346
+ /* ... */
347
+ }),
348
+ 'card.footer': () => ({
349
+ /* ... */
350
+ })
351
+ });
352
+ ```
353
+
354
+ ```svelte
355
+ <HtmlAtom preset="card.header" />
356
+ ```
357
+
358
+ ### 2. Compound Variants
359
+
360
+ Apply classes when multiple conditions match:
361
+
362
+ ```typescript
363
+ setPreset({
364
+ button: () => ({
365
+ variants: {
366
+ variants: {
367
+ variant: { default: '...', destructive: '...' },
368
+ size: { sm: '...', lg: '...' }
369
+ },
370
+ compoundVariants: [
371
+ {
372
+ variant: 'destructive',
373
+ size: 'lg',
374
+ class: 'font-bold uppercase', // Applied ONLY when both match
375
+ 'aria-label': 'Warning'
376
+ }
377
+ ]
378
+ }
379
+ })
380
+ });
381
+ ```
382
+
383
+ ### 3. Variant Attributes
384
+
385
+ Variants can return more than just classes:
386
+
387
+ ```typescript
388
+ variants: {
389
+ variant: {
390
+ destructive: {
391
+ class: 'bg-destructive text-destructive-foreground',
392
+ role: 'alert',
393
+ 'aria-label': 'Destructive action',
394
+ 'data-variant': 'destructive'
395
+ }
396
+ }
397
+ }
398
+ ```
399
+
400
+ ### 4. Preset Class + Variant Base
401
+
402
+ Use both for layered styling:
403
+
404
+ ```typescript
405
+ setPreset({
406
+ button: () => ({
407
+ class: 'inline-flex items-center justify-center', // Always applied
408
+ variants: {
409
+ base: 'rounded-md transition-colors', // Variant base (can be overridden)
410
+ variants: {
411
+ /* ... */
412
+ }
413
+ }
414
+ })
415
+ });
416
+ ```
417
+
418
+ **Final class order:**
419
+
420
+ 1. `preset.class`
421
+ 2. `preset.variants.base`
422
+ 3. Local variant base (if overriding)
423
+ 4. Variant classes
424
+ 5. Component class prop
425
+
426
+ ## Migration from Old System
427
+
428
+ ### Before (Old Function-based)
429
+
430
+ ```svelte
431
+ <script>
432
+ const variants = (bond, props) => {
433
+ const { variant, size } = props;
434
+ const classes = [];
435
+
436
+ if (variant === 'primary') classes.push('bg-blue-500');
437
+ if (size === 'sm') classes.push('px-2 py-1');
438
+
439
+ return { class: classes.join(' ') };
440
+ };
441
+ </script>
442
+
443
+ <HtmlAtom {variants} {variant} {size} />
444
+ ```
445
+
446
+ ### After (New Variant System)
447
+
448
+ ```typescript
449
+ // In preset (recommended)
450
+ setPreset({
451
+ button: () => ({
452
+ variants: {
453
+ variants: {
454
+ variant: {
455
+ primary: 'bg-blue-500'
456
+ },
457
+ size: {
458
+ sm: 'px-2 py-1'
459
+ }
460
+ }
461
+ }
462
+ })
463
+ });
464
+ ```
465
+
466
+ ```svelte
467
+ <HtmlAtom preset="button" {variant} {size} />
468
+ ```
469
+
470
+ **OR** local only:
471
+
472
+ ```svelte
473
+ <script>
474
+ import { defineVariants } from '@svelte-atoms/core/utils';
475
+
476
+ const buttonVariants = defineVariants({
477
+ variants: {
478
+ variant: { primary: 'bg-blue-500' },
479
+ size: { sm: 'px-2 py-1' }
480
+ }
481
+ });
482
+ </script>
483
+
484
+ <HtmlAtom variants={buttonVariants} {variant} {size} />
485
+ ```
486
+
487
+ ## Best Practices
488
+
489
+ ### ✅ DO
490
+
491
+ 1. **Use presets for global variants** that should be consistent across the app
492
+ 2. **Use local variants** to extend or override for special cases
493
+ 3. **Use `class` prop in preset** for base styling that always applies
494
+ 4. **Use `variants.base`** for styling that can be overridden locally
495
+ 5. **Return attributes from variants** (aria-_, data-_, role) for accessibility
496
+
497
+ ### ❌ DON'T
498
+
499
+ 1. **Don't duplicate variants** in both preset and local unless overriding
500
+ 2. **Don't use `base` prop for CSS classes** (conflicts with component/snippet prop)
501
+ 3. **Don't over-nest presets** - keep hierarchy shallow
502
+ 4. **Don't forget default variants** - they make components easier to use
503
+
504
+ ## Summary
505
+
506
+ The preset-variant integration provides:
507
+
508
+ ✅ **Global theming** via preset system
509
+ ✅ **Local customization** via component variants
510
+ ✅ **Intelligent merging** that respects hierarchy
511
+ ✅ **Type safety** with TypeScript
512
+ ✅ **Reactive variants** with bond state access
513
+ ✅ **Attribute support** beyond just classes
514
+ ✅ **Backward compatible** with function-based variants
515
+
516
+ This architecture gives you the flexibility of both global consistency and local control.