@svelte-atoms/core 1.0.0-alpha.30 → 1.0.0-alpha.31

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 (147) hide show
  1. package/README.md +853 -852
  2. package/dist/components/accordion/accordion-root.svelte +7 -3
  3. package/dist/components/accordion/accordion.stories.svelte +7 -82
  4. package/dist/components/accordion/item/accordion-item-body.svelte +44 -42
  5. package/dist/components/accordion/item/accordion-item-header.svelte +51 -50
  6. package/dist/components/accordion/item/accordion-item-indicator.svelte +51 -50
  7. package/dist/components/accordion/item/accordion-item-root.svelte +66 -65
  8. package/dist/components/accordion/item/bond.svelte.d.ts +2 -0
  9. package/dist/components/accordion/item/index.d.ts +3 -0
  10. package/dist/components/accordion/item/index.js +3 -0
  11. package/dist/components/accordion/item/motion.svelte.d.ts +15 -0
  12. package/dist/components/accordion/item/motion.svelte.js +30 -0
  13. package/dist/components/accordion/item/types.d.ts +7 -24
  14. package/dist/components/alert/alert-close-button.svelte +66 -70
  15. package/dist/components/alert/alert-description.svelte +42 -42
  16. package/dist/components/alert/alert-description.svelte.d.ts +3 -6
  17. package/dist/components/alert/alert-root.svelte +68 -103
  18. package/dist/components/alert/alert-root.svelte.d.ts +2 -2
  19. package/dist/components/alert/alert.stories.svelte +400 -400
  20. package/dist/components/alert/bond.svelte.d.ts +0 -13
  21. package/dist/components/alert/bond.svelte.js +0 -32
  22. package/dist/components/alert/types.d.ts +8 -32
  23. package/dist/components/atom/html-atom.svelte +261 -261
  24. package/dist/components/avatar/avatar.stories.svelte +22 -22
  25. package/dist/components/badge/badge.stories.svelte +12 -12
  26. package/dist/components/badge/badge.svelte +19 -19
  27. package/dist/components/breadcrumb/breadcrumb.stories.svelte +5 -5
  28. package/dist/components/button/button.stories.svelte +27 -27
  29. package/dist/components/calendar/calendar-day.svelte +101 -96
  30. package/dist/components/calendar/calendar.stories.svelte +26 -26
  31. package/dist/components/card/card-body.svelte +39 -39
  32. package/dist/components/card/card-footer.svelte +41 -41
  33. package/dist/components/card/card-root.svelte +91 -91
  34. package/dist/components/card/card.stories.svelte +133 -133
  35. package/dist/components/checkbox/checkbox.stories.svelte +22 -22
  36. package/dist/components/checkbox/checkbox.svelte +6 -2
  37. package/dist/components/collapsible/collapsible.stories.svelte +172 -172
  38. package/dist/components/combobox/atoms.d.ts +1 -1
  39. package/dist/components/combobox/atoms.js +1 -1
  40. package/dist/components/combobox/combobox-root.svelte +65 -65
  41. package/dist/components/combobox/compobox.stories.svelte +51 -51
  42. package/dist/components/combobox/index.d.ts +1 -0
  43. package/dist/components/container/container.stories.svelte +20 -20
  44. package/dist/components/container/container.svelte.d.ts +1 -1
  45. package/dist/components/datagrid/datagrid.stories.svelte +72 -72
  46. package/dist/components/datagrid/tr/bond.svelte.d.ts +4 -2
  47. package/dist/components/datagrid/tr/bond.svelte.js +9 -7
  48. package/dist/components/datagrid/tr/datagrid-tr.svelte +90 -88
  49. package/dist/components/date-picker/date-picker-calendar.svelte +67 -67
  50. package/dist/components/date-picker/date-picker-root.svelte +95 -95
  51. package/dist/components/date-picker/date-picker.stories.svelte +35 -35
  52. package/dist/components/dialog/bond.svelte.d.ts +13 -3
  53. package/dist/components/dialog/bond.svelte.js +66 -5
  54. package/dist/components/dialog/dialog-content.svelte +44 -62
  55. package/dist/components/dialog/dialog-root.svelte +91 -110
  56. package/dist/components/dialog/dialog.stories.svelte +64 -64
  57. package/dist/components/dialog/motion.svelte.d.ts +13 -0
  58. package/dist/components/dialog/motion.svelte.js +44 -0
  59. package/dist/components/drawer/attachments.svelte.d.ts +1 -1
  60. package/dist/components/drawer/attachments.svelte.js +1 -3
  61. package/dist/components/drawer/bond.svelte.d.ts +24 -5
  62. package/dist/components/drawer/bond.svelte.js +77 -11
  63. package/dist/components/drawer/drawer-content.svelte +6 -14
  64. package/dist/components/drawer/drawer.stories.svelte +27 -95
  65. package/dist/components/drawer/index.d.ts +2 -0
  66. package/dist/components/drawer/index.js +2 -0
  67. package/dist/components/drawer/motion.d.ts +15 -0
  68. package/dist/components/drawer/motion.js +28 -0
  69. package/dist/components/dropdown/atoms.d.ts +1 -1
  70. package/dist/components/dropdown/atoms.js +1 -1
  71. package/dist/components/dropdown/bond.svelte.d.ts +5 -1
  72. package/dist/components/dropdown/dropdown-root.svelte +59 -59
  73. package/dist/components/dropdown/dropdown.stories.svelte +80 -80
  74. package/dist/components/dropdown/index.d.ts +1 -0
  75. package/dist/components/form/form.stories.svelte +96 -96
  76. package/dist/components/image/image.stories.svelte +20 -20
  77. package/dist/components/input/input.stories.svelte +35 -35
  78. package/dist/components/label/label.stories.svelte +15 -15
  79. package/dist/components/lazy/lazy.stories.svelte +28 -28
  80. package/dist/components/link/link.stories.svelte +15 -15
  81. package/dist/components/list/list-item.svelte +20 -20
  82. package/dist/components/menu/atoms.d.ts +1 -0
  83. package/dist/components/menu/atoms.js +1 -0
  84. package/dist/components/menu/index.d.ts +2 -1
  85. package/dist/components/menu/index.js +1 -1
  86. package/dist/components/menu/menu-item.svelte +69 -51
  87. package/dist/components/menu/menu-item.svelte.d.ts +1 -0
  88. package/dist/components/menu/menu.stories.svelte +33 -33
  89. package/dist/components/popover/bond.svelte.d.ts +20 -7
  90. package/dist/components/popover/bond.svelte.js +80 -27
  91. package/dist/components/popover/motion.d.ts +6 -0
  92. package/dist/components/popover/motion.js +56 -0
  93. package/dist/components/popover/popover-arrow.svelte +111 -111
  94. package/dist/components/popover/popover-content.svelte +34 -72
  95. package/dist/components/popover/popover-indicator.svelte +44 -44
  96. package/dist/components/popover/popover-root.svelte +48 -48
  97. package/dist/components/popover/popover.stories.svelte +3 -3
  98. package/dist/components/popover/types.d.ts +9 -7
  99. package/dist/components/portal/active-portal.svelte +29 -22
  100. package/dist/components/portal/active-portal.svelte.d.ts +2 -9
  101. package/dist/components/portal/portal-root.svelte +76 -83
  102. package/dist/components/portal/portal-root.svelte.d.ts +4 -6
  103. package/dist/components/portal/teleport.svelte +49 -50
  104. package/dist/components/portal/teleport.svelte.d.ts +3 -4
  105. package/dist/components/qr-code/qr-code.stories.svelte +18 -18
  106. package/dist/components/radio/radio-group.stories.svelte +41 -41
  107. package/dist/components/radio/radio.stories.svelte +17 -17
  108. package/dist/components/radio/radio.svelte +1 -1
  109. package/dist/components/radio/types.d.ts +98 -0
  110. package/dist/components/radio/types.js +2 -0
  111. package/dist/components/root/root.svelte +13 -30
  112. package/dist/components/root/root.svelte.d.ts +1 -1
  113. package/dist/components/scrollable/scrollable-root.svelte.d.ts +2 -2
  114. package/dist/components/scrollable/scrollable.stories.svelte +116 -116
  115. package/dist/components/sidebar/index.d.ts +2 -0
  116. package/dist/components/sidebar/index.js +2 -0
  117. package/dist/components/sidebar/motion.svelte.d.ts +11 -0
  118. package/dist/components/sidebar/motion.svelte.js +16 -0
  119. package/dist/components/sidebar/sidebar-content.svelte +3 -13
  120. package/dist/components/sidebar/sidebar-root.svelte +39 -39
  121. package/dist/components/sidebar/sidebar.stories.svelte +43 -43
  122. package/dist/components/sidebar/types.d.ts +2 -12
  123. package/dist/components/tabs/tabs.stories.svelte +56 -56
  124. package/dist/components/textarea/atoms.d.ts +1 -0
  125. package/dist/components/textarea/atoms.js +1 -0
  126. package/dist/components/textarea/textarea-input.svelte +9 -6
  127. package/dist/components/textarea/textarea-root.svelte +9 -9
  128. package/dist/components/textarea/textarea-root.svelte.d.ts +2 -0
  129. package/dist/components/tooltip/tooltip-trigger.svelte +2 -2
  130. package/dist/components/tooltip/tooltip-trigger.svelte.d.ts +1 -0
  131. package/dist/components/tooltip/tooltip.stories.svelte +32 -32
  132. package/dist/components/tree/tree.stories.svelte +142 -142
  133. package/dist/icons/icon-copy.svelte +6 -0
  134. package/dist/{components/radio/types.svelte.d.ts → icons/icon-copy.svelte.d.ts} +3 -3
  135. package/dist/utils/markdown-to-llm.d.ts +28 -0
  136. package/dist/utils/markdown-to-llm.js +76 -0
  137. package/package.json +1 -2
  138. package/dist/components/radio/types.svelte +0 -0
  139. package/llm/composition.md +0 -395
  140. package/llm/crafting.md +0 -838
  141. package/llm/motion.md +0 -970
  142. package/llm/philosophy.md +0 -23
  143. package/llm/preset-variant-integration.md +0 -516
  144. package/llm/preset.md +0 -383
  145. package/llm/styling.md +0 -216
  146. package/llm/usage.md +0 -46
  147. package/llm/variants.md +0 -1259
@@ -1,261 +1,261 @@
1
- <script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- import type { Base, HtmlAtomProps, SnippetBase } from './types';
4
- import { RootBond } from '../root';
5
- import { HtmlElement } from '../element';
6
- import { cn, type ClassValue, type VariantDefinition } from '../../utils';
7
- import { getPreset } from '../../context';
8
- import type { PresetModuleName } from '../../context/preset.svelte';
9
- import type { Bond } from '../../shared';
10
- import SnippetRenderer from './snippet-renderer.svelte';
11
- import type { Component } from 'svelte';
12
- import { call } from '../../utils/function';
13
-
14
- type Element = HTMLElementTagNameMap[E];
15
-
16
- const rootBond = RootBond.get();
17
-
18
- let {
19
- class: klass = '',
20
- as = 'div',
21
- base = undefined,
22
- preset: presetKey = undefined,
23
- bond = undefined,
24
- variants = undefined,
25
- children: childrenProp = undefined,
26
- ...restProps
27
- }: HtmlAtomProps<E, B> & Omit<HTMLAttributes<Element>, 'children'> = $props();
28
-
29
- /**
30
- * Resolve variant definition to props
31
- */
32
- // Cache for resolved variants to avoid recomputation
33
- // Key: JSON stringified combination of variant props
34
- const variantCache = new Map<string, Record<string, any>>();
35
-
36
- // Memoize preset resolution - only recompute when presetKey or bond changes
37
- const preset = $derived.by(() => {
38
- if (!presetKey) return undefined;
39
- const result = getPreset(presetKey as PresetModuleName)?.apply?.(bond, [bond]);
40
- // Handle deferred preset result (factory function)
41
- return call(result);
42
- });
43
-
44
- const presetProps = $derived(preset?.variants);
45
-
46
- // Resolve local variants - either VariantDefinition or function
47
- const localVariants = $derived.by(() => {
48
- if (!variants) return undefined;
49
-
50
- // If it's a function, call it directly
51
- if (typeof variants === 'function') {
52
- return variants(bond as Bond, restProps);
53
- }
54
-
55
- // Otherwise it's a VariantDefinition, resolve it
56
- return resolveVariants(variants, bond as Bond, restProps);
57
- });
58
-
59
- // Merge preset variants with local variants
60
- // Memoized to avoid recomputation when inputs haven't changed
61
- const mergedVariants = $derived.by(() => {
62
- // No variants at all
63
- if (!presetProps && !localVariants) return undefined;
64
-
65
- // Only preset variants (raw object from preset)
66
- if (presetProps && !localVariants) {
67
- // Convert preset variants to VariantDefinition-like structure
68
- const variantDef: VariantDefinition<any> = {
69
- class: preset?.class ?? '',
70
- variants: presetProps,
71
- compounds: preset?.compounds ?? [],
72
- defaults: preset?.defaults ?? {}
73
- };
74
- return resolveVariants(variantDef, bond as Bond, restProps);
75
- }
76
-
77
- // Only local variants
78
- if (!presetProps && localVariants) {
79
- return localVariants;
80
- }
81
-
82
- // Both exist - merge them
83
- // When both preset and local variants exist, we need to merge the resolved props
84
- const presetVariantDef: VariantDefinition<any> = {
85
- class: preset?.class ?? '',
86
- variants: presetProps ?? {},
87
- compounds: preset?.compounds ?? [],
88
- defaults: preset?.defaults ?? {}
89
- };
90
-
91
- const presetResolved = resolveVariants(presetVariantDef, bond as Bond, restProps);
92
-
93
- // Merge the resolved variant props
94
- // Local variant classes and attributes override preset
95
- const presetClasses = Array.isArray(presetResolved.class)
96
- ? presetResolved.class
97
- : [presetResolved.class];
98
- const localClasses = Array.isArray(localVariants?.class)
99
- ? localVariants.class
100
- : [localVariants?.class];
101
-
102
- return {
103
- class: [...presetClasses, ...localClasses].filter(Boolean),
104
- ...presetResolved,
105
- ...localVariants
106
- };
107
- });
108
-
109
- const presetClassString = $derived(cn(preset?.class));
110
-
111
- const _klass = $derived.by(() => {
112
- const klassStr = cn(klass ?? '');
113
- // Check for $preset placeholder first
114
- if (!klassStr.includes('$preset')) {
115
- // No placeholder - normal merge: variants override direct class
116
- return cn(klass, mergedVariants?.class ?? '');
117
- }
118
-
119
- // Has placeholder - calculate position and inject preset classes
120
- const parts = klassStr.split('$preset');
121
-
122
- // Only keep the last $preset placeholder
123
- const beforeLastPlaceholder = parts.slice(0, -1).join('');
124
- const afterLastPlaceholder = parts[parts.length - 1];
125
-
126
- // Merge: before + preset + variants + after
127
- return cn(
128
- beforeLastPlaceholder,
129
- presetClassString,
130
- mergedVariants?.class ?? '',
131
- afterLastPlaceholder
132
- );
133
- });
134
-
135
- const _base = $derived(base ?? preset?.base);
136
- const _as = $derived(as ?? preset?.as);
137
- const _restProps = $derived.by(() => {
138
- const {
139
- class: klassPreset,
140
- base,
141
- as,
142
- variants: presetProps,
143
- ...restPresetProps
144
- } = preset ?? {};
145
- const { class: variantClass, ...variantsRestProps } = mergedVariants ?? {};
146
-
147
- return { ...restPresetProps, ...variantsRestProps, ...restProps };
148
- });
149
-
150
- const isSnippet = $derived(typeof _base === 'function' && _base.length === 1 && !_base.prototype);
151
-
152
- const snippet = $derived(_base as SnippetBase);
153
-
154
- const atom = rootBond?.state?.props?.renderers?.html ?? HtmlElement;
155
-
156
- const renderer = $derived.by(() => {
157
- if (isSnippet)
158
- return {
159
- component: SnippetRenderer,
160
- props: { snippet: snippet, class: _klass, as: _as, children: childrenProp, ..._restProps }
161
- };
162
-
163
- return {
164
- component: base ?? atom,
165
- props: { class: _klass, as: _as, ..._restProps }
166
- };
167
- }) as { component: Component; props: Record<string, any> };
168
-
169
- function resolveVariants(
170
- def: VariantDefinition<any>,
171
- bond: Bond | null | undefined,
172
- props: Record<string, any>
173
- ): Record<string, any> {
174
- const { variants: variantMap, compounds, defaults, class: baseClass } = def;
175
-
176
- // Merge props with defaults
177
- const finalProps = { ...defaults, ...props };
178
-
179
- // Create cache key from final props (only variant-related props)
180
- const variantKeys = variantMap ? Object.keys(variantMap) : [];
181
- const relevantProps = Object.fromEntries(
182
- Object.entries(finalProps).filter(([key]) => variantKeys.includes(key))
183
- );
184
- const cacheKey = JSON.stringify({ relevantProps, baseClass, compounds });
185
-
186
- // Check cache
187
- if (variantCache.has(cacheKey)) {
188
- return variantCache.get(cacheKey)!;
189
- }
190
-
191
- const classes: ClassValue[] = [];
192
- const attributes: Record<string, any> = {};
193
-
194
- // Add base class
195
- if (baseClass) classes.push(baseClass);
196
-
197
- // Add variant classes
198
- if (variantMap) {
199
- for (const [key, value] of Object.entries(finalProps)) {
200
- const variantValue = variantMap[key]?.[value as string];
201
- if (variantValue !== undefined) {
202
- const resolved = typeof variantValue === 'function' ? variantValue(bond) : variantValue;
203
-
204
- if (typeof resolved === 'string') {
205
- classes.push(resolved);
206
- } else if (typeof resolved === 'object' && resolved !== null) {
207
- if ('class' in resolved) {
208
- classes.push(resolved.class);
209
- }
210
- // Add other attributes
211
- Object.entries(resolved).forEach(([k, v]) => {
212
- if (k !== 'class') {
213
- attributes[k] = v;
214
- }
215
- });
216
- }
217
- }
218
- }
219
- }
220
-
221
- // Add compound variants
222
- if (compounds) {
223
- for (const compound of compounds) {
224
- const { class: compoundClass, ...compoundProps } = compound;
225
- const matches = Object.entries(compoundProps).every(
226
- ([key, value]) => finalProps[key] === value
227
- );
228
- if (matches) {
229
- if (compoundClass) classes.push(compoundClass);
230
- // Add compound attributes
231
- Object.entries(compound).forEach(([k, v]) => {
232
- if (k !== 'class' && !Object.keys(compoundProps).includes(k)) {
233
- attributes[k] = v;
234
- }
235
- });
236
- }
237
- }
238
- }
239
-
240
- const result = {
241
- class: classes,
242
- ...attributes
243
- };
244
-
245
- // Store in cache (limit cache size to prevent memory leaks)
246
- if (variantCache.size > 100) {
247
- // Clear oldest entry (first in Map)
248
- const firstKey = variantCache.keys().next().value;
249
- if (firstKey) variantCache.delete(firstKey);
250
- }
251
- variantCache.set(cacheKey, result);
252
-
253
- return result;
254
- }
255
- </script>
256
-
257
- <renderer.component {...renderer.props}>
258
- {#snippet children(args: any)}
259
- {@render (childrenProp as any)?.(args)}
260
- {/snippet}
261
- </renderer.component>
1
+ <script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { Base, HtmlAtomProps, SnippetBase } from './types';
4
+ import { RootBond } from '../root';
5
+ import { HtmlElement } from '../element';
6
+ import { cn, type ClassValue, type VariantDefinition } from '../../utils';
7
+ import { getPreset } from '../../context';
8
+ import type { PresetModuleName } from '../../context/preset.svelte';
9
+ import type { Bond } from '../../shared';
10
+ import SnippetRenderer from './snippet-renderer.svelte';
11
+ import type { Component } from 'svelte';
12
+ import { call } from '../../utils/function';
13
+
14
+ type Element = HTMLElementTagNameMap[E];
15
+
16
+ const rootBond = RootBond.get();
17
+
18
+ let {
19
+ class: klass = '',
20
+ as = 'div',
21
+ base = undefined,
22
+ preset: presetKey = undefined,
23
+ bond = undefined,
24
+ variants = undefined,
25
+ children: childrenProp = undefined,
26
+ ...restProps
27
+ }: HtmlAtomProps<E, B> & Omit<HTMLAttributes<Element>, 'children'> = $props();
28
+
29
+ /**
30
+ * Resolve variant definition to props
31
+ */
32
+ // Cache for resolved variants to avoid recomputation
33
+ // Key: JSON stringified combination of variant props
34
+ const variantCache = new Map<string, Record<string, any>>();
35
+
36
+ // Memoize preset resolution - only recompute when presetKey or bond changes
37
+ const preset = $derived.by(() => {
38
+ if (!presetKey) return undefined;
39
+ const result = getPreset(presetKey as PresetModuleName)?.apply?.(bond, [bond]);
40
+ // Handle deferred preset result (factory function)
41
+ return call(result);
42
+ });
43
+
44
+ const presetProps = $derived(preset?.variants);
45
+
46
+ // Resolve local variants - either VariantDefinition or function
47
+ const localVariants = $derived.by(() => {
48
+ if (!variants) return undefined;
49
+
50
+ // If it's a function, call it directly
51
+ if (typeof variants === 'function') {
52
+ return variants(bond as Bond, restProps);
53
+ }
54
+
55
+ // Otherwise it's a VariantDefinition, resolve it
56
+ return resolveVariants(variants, bond as Bond, restProps);
57
+ });
58
+
59
+ // Merge preset variants with local variants
60
+ // Memoized to avoid recomputation when inputs haven't changed
61
+ const mergedVariants = $derived.by(() => {
62
+ // No variants at all
63
+ if (!presetProps && !localVariants) return undefined;
64
+
65
+ // Only preset variants (raw object from preset)
66
+ if (presetProps && !localVariants) {
67
+ // Convert preset variants to VariantDefinition-like structure
68
+ const variantDef: VariantDefinition<any> = {
69
+ class: preset?.class ?? '',
70
+ variants: presetProps,
71
+ compounds: preset?.compounds ?? [],
72
+ defaults: preset?.defaults ?? {}
73
+ };
74
+ return resolveVariants(variantDef, bond as Bond, restProps);
75
+ }
76
+
77
+ // Only local variants
78
+ if (!presetProps && localVariants) {
79
+ return localVariants;
80
+ }
81
+
82
+ // Both exist - merge them
83
+ // When both preset and local variants exist, we need to merge the resolved props
84
+ const presetVariantDef: VariantDefinition<any> = {
85
+ class: preset?.class ?? '',
86
+ variants: presetProps ?? {},
87
+ compounds: preset?.compounds ?? [],
88
+ defaults: preset?.defaults ?? {}
89
+ };
90
+
91
+ const presetResolved = resolveVariants(presetVariantDef, bond as Bond, restProps);
92
+
93
+ // Merge the resolved variant props
94
+ // Local variant classes and attributes override preset
95
+ const presetClasses = Array.isArray(presetResolved.class)
96
+ ? presetResolved.class
97
+ : [presetResolved.class];
98
+ const localClasses = Array.isArray(localVariants?.class)
99
+ ? localVariants.class
100
+ : [localVariants?.class];
101
+
102
+ return {
103
+ class: [...presetClasses, ...localClasses].filter(Boolean),
104
+ ...presetResolved,
105
+ ...localVariants
106
+ };
107
+ });
108
+
109
+ const presetClassString = $derived(cn(preset?.class));
110
+
111
+ const _klass = $derived.by(() => {
112
+ const klassStr = cn(klass ?? '');
113
+ // Check for $preset placeholder first
114
+ if (!klassStr.includes('$preset')) {
115
+ // No placeholder - normal merge: variants override direct class
116
+ return cn(klass, mergedVariants?.class ?? '');
117
+ }
118
+
119
+ // Has placeholder - calculate position and inject preset classes
120
+ const parts = klassStr.split('$preset');
121
+
122
+ // Only keep the last $preset placeholder
123
+ const beforeLastPlaceholder = parts.slice(0, -1).join('');
124
+ const afterLastPlaceholder = parts[parts.length - 1];
125
+
126
+ // Merge: before + preset + variants + after
127
+ return cn(
128
+ beforeLastPlaceholder,
129
+ presetClassString,
130
+ mergedVariants?.class ?? '',
131
+ afterLastPlaceholder
132
+ );
133
+ });
134
+
135
+ const _base = $derived(base ?? preset?.base);
136
+ const _as = $derived(as ?? preset?.as);
137
+ const _restProps = $derived.by(() => {
138
+ const {
139
+ class: klassPreset,
140
+ base,
141
+ as,
142
+ variants: presetProps,
143
+ ...restPresetProps
144
+ } = preset ?? {};
145
+ const { class: variantClass, ...variantsRestProps } = mergedVariants ?? {};
146
+
147
+ return { ...restPresetProps, ...variantsRestProps, ...restProps };
148
+ });
149
+
150
+ const isSnippet = $derived(typeof _base === 'function' && _base.length === 1 && !_base.prototype);
151
+
152
+ const snippet = $derived(_base as SnippetBase);
153
+
154
+ const atom = rootBond?.state?.props?.renderers?.html ?? HtmlElement;
155
+
156
+ const renderer = $derived.by(() => {
157
+ if (isSnippet)
158
+ return {
159
+ component: SnippetRenderer,
160
+ props: { snippet: snippet, class: _klass, as: _as, children: childrenProp, ..._restProps }
161
+ };
162
+
163
+ return {
164
+ component: base ?? atom,
165
+ props: { class: _klass, as: _as, ..._restProps }
166
+ };
167
+ }) as { component: Component; props: Record<string, any> };
168
+
169
+ function resolveVariants(
170
+ def: VariantDefinition<any>,
171
+ bond: Bond | null | undefined,
172
+ props: Record<string, any>
173
+ ): Record<string, any> {
174
+ const { variants: variantMap, compounds, defaults, class: baseClass } = def;
175
+
176
+ // Merge props with defaults
177
+ const finalProps = { ...defaults, ...props };
178
+
179
+ // Create cache key from final props (only variant-related props)
180
+ const variantKeys = variantMap ? Object.keys(variantMap) : [];
181
+ const relevantProps = Object.fromEntries(
182
+ Object.entries(finalProps).filter(([key]) => variantKeys.includes(key))
183
+ );
184
+ const cacheKey = JSON.stringify({ relevantProps, baseClass, compounds });
185
+
186
+ // Check cache
187
+ if (variantCache.has(cacheKey)) {
188
+ return variantCache.get(cacheKey)!;
189
+ }
190
+
191
+ const classes: ClassValue[] = [];
192
+ const attributes: Record<string, any> = {};
193
+
194
+ // Add base class
195
+ if (baseClass) classes.push(baseClass);
196
+
197
+ // Add variant classes
198
+ if (variantMap) {
199
+ for (const [key, value] of Object.entries(finalProps)) {
200
+ const variantValue = variantMap[key]?.[value as string];
201
+ if (variantValue !== undefined) {
202
+ const resolved = typeof variantValue === 'function' ? variantValue(bond) : variantValue;
203
+
204
+ if (typeof resolved === 'string') {
205
+ classes.push(resolved);
206
+ } else if (typeof resolved === 'object' && resolved !== null) {
207
+ if ('class' in resolved) {
208
+ classes.push(resolved.class);
209
+ }
210
+ // Add other attributes
211
+ Object.entries(resolved).forEach(([k, v]) => {
212
+ if (k !== 'class') {
213
+ attributes[k] = v;
214
+ }
215
+ });
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+ // Add compound variants
222
+ if (compounds) {
223
+ for (const compound of compounds) {
224
+ const { class: compoundClass, ...compoundProps } = compound;
225
+ const matches = Object.entries(compoundProps).every(
226
+ ([key, value]) => finalProps[key] === value
227
+ );
228
+ if (matches) {
229
+ if (compoundClass) classes.push(compoundClass);
230
+ // Add compound attributes
231
+ Object.entries(compound).forEach(([k, v]) => {
232
+ if (k !== 'class' && !Object.keys(compoundProps).includes(k)) {
233
+ attributes[k] = v;
234
+ }
235
+ });
236
+ }
237
+ }
238
+ }
239
+
240
+ const result = {
241
+ class: classes,
242
+ ...attributes
243
+ };
244
+
245
+ // Store in cache (limit cache size to prevent memory leaks)
246
+ if (variantCache.size > 100) {
247
+ // Clear oldest entry (first in Map)
248
+ const firstKey = variantCache.keys().next().value;
249
+ if (firstKey) variantCache.delete(firstKey);
250
+ }
251
+ variantCache.set(cacheKey, result);
252
+
253
+ return result;
254
+ }
255
+ </script>
256
+
257
+ <renderer.component {...renderer.props}>
258
+ {#snippet children(args: any)}
259
+ {@render (childrenProp as any)?.(args)}
260
+ {/snippet}
261
+ </renderer.component>
@@ -1,22 +1,22 @@
1
- <script module>
2
- import { defineMeta } from '@storybook/addon-svelte-csf';
3
- import AvatarCmp from './avatar.svelte';
4
- import CalendarRegularIcon from '../../icons/icon-arrow-down.svelte';
5
-
6
- const { Story } = defineMeta({
7
- title: 'ATOMS/Avatar'
8
- });
9
- </script>
10
-
11
- <Story name="Avatar">
12
- <div class="flex h-full w-full items-center justify-center gap-4">
13
- <AvatarCmp alt="Abdelhalim Riache" />
14
-
15
- <AvatarCmp src={CalendarRegularIcon} alt="Abdelhalim Riache" />
16
-
17
- <AvatarCmp
18
- src="https://sevennaturalwonders.org/wp-content/uploads/2023/12/1-Mount-Fuji.jpg"
19
- alt="Mount Fuji"
20
- />
21
- </div>
22
- </Story>
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import AvatarCmp from './avatar.svelte';
4
+ import CalendarRegularIcon from '../../icons/icon-arrow-down.svelte';
5
+
6
+ const { Story } = defineMeta({
7
+ title: 'ATOMS/Avatar'
8
+ });
9
+ </script>
10
+
11
+ <Story name="Avatar">
12
+ <div class="flex h-full w-full items-center justify-center gap-4">
13
+ <AvatarCmp alt="Abdelhalim Riache" />
14
+
15
+ <AvatarCmp src={CalendarRegularIcon} alt="Abdelhalim Riache" />
16
+
17
+ <AvatarCmp
18
+ src="https://sevennaturalwonders.org/wp-content/uploads/2023/12/1-Mount-Fuji.jpg"
19
+ alt="Mount Fuji"
20
+ />
21
+ </div>
22
+ </Story>
@@ -1,12 +1,12 @@
1
- <script module>
2
- import { defineMeta } from '@storybook/addon-svelte-csf';
3
- import { Badge as BadgeModule } from '.';
4
-
5
- const { Story } = defineMeta({
6
- title: 'ATOMS/Badge'
7
- });
8
- </script>
9
-
10
- <Story name="Badge">
11
- <BadgeModule>Badge</BadgeModule>
12
- </Story>
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import { Badge as BadgeModule } from '.';
4
+
5
+ const { Story } = defineMeta({
6
+ title: 'ATOMS/Badge'
7
+ });
8
+ </script>
9
+
10
+ <Story name="Badge">
11
+ <BadgeModule>Badge</BadgeModule>
12
+ </Story>
@@ -1,19 +1,19 @@
1
- <script lang="ts">
2
- import { HtmlAtom } from '../atom';
3
- import type { BadgeProps } from './types';
4
-
5
- let { class: klass = '', as = 'span', children = undefined, ...restProps }: BadgeProps = $props();
6
- </script>
7
-
8
- <HtmlAtom
9
- preset="badge"
10
- class={[
11
- 'bg-foreground/10 border-border text-foreground inline-flex h-auto w-fit items-center rounded-full px-2.5 py-0.5 text-xs font-medium',
12
- '$preset',
13
- klass
14
- ]}
15
- {as}
16
- {...restProps}
17
- >
18
- {@render children?.()}
19
- </HtmlAtom>
1
+ <script lang="ts">
2
+ import { HtmlAtom } from '../atom';
3
+ import type { BadgeProps } from './types';
4
+
5
+ let { class: klass = '', as = 'span', children = undefined, ...restProps }: BadgeProps = $props();
6
+ </script>
7
+
8
+ <HtmlAtom
9
+ preset="badge"
10
+ class={[
11
+ 'bg-foreground/10 border-border text-foreground inline-flex h-auto w-fit items-center rounded-full px-2.5 py-0.5 text-xs font-medium',
12
+ '$preset',
13
+ klass
14
+ ]}
15
+ {as}
16
+ {...restProps}
17
+ >
18
+ {@render children?.()}
19
+ </HtmlAtom>
@@ -8,9 +8,9 @@
8
8
  </script>
9
9
 
10
10
  <Story name="Breadcrumb">
11
- <BreadcrumbModule.Root>
12
- <BreadcrumbModule.Item href="/">Home</BreadcrumbModule.Item>
13
- <BreadcrumbModule.Separator>/</BreadcrumbModule.Separator>
14
- <BreadcrumbModule.Item href="/vehicles">Vehicles</BreadcrumbModule.Item>
15
- </BreadcrumbModule.Root>
11
+ <BreadcrumbModule.Root>
12
+ <BreadcrumbModule.Item href="/">Home</BreadcrumbModule.Item>
13
+ <BreadcrumbModule.Separator>/</BreadcrumbModule.Separator>
14
+ <BreadcrumbModule.Item href="/vehicles">Vehicles</BreadcrumbModule.Item>
15
+ </BreadcrumbModule.Root>
16
16
  </Story>