@svelte-atoms/core 1.0.0-alpha.44 → 1.0.0-alpha.46

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 (178) hide show
  1. package/README.md +13 -0
  2. package/dist/components/accordion/item/accordion-item-body.svelte +5 -8
  3. package/dist/components/accordion/item/accordion-item-header.svelte +0 -13
  4. package/dist/components/accordion/item/accordion-item-indicator.svelte +0 -12
  5. package/dist/components/accordion/item/accordion-item-root.svelte +0 -12
  6. package/dist/components/alert/alert-actions.svelte +0 -12
  7. package/dist/components/alert/alert-close-button.svelte +0 -12
  8. package/dist/components/alert/alert-content.svelte +0 -12
  9. package/dist/components/alert/alert-description.svelte +0 -12
  10. package/dist/components/alert/alert-icon.svelte +0 -12
  11. package/dist/components/alert/alert-root.svelte +1 -13
  12. package/dist/components/alert/alert-title.svelte +0 -12
  13. package/dist/components/atom/html-atom.svelte +31 -17
  14. package/dist/components/atom/types.d.ts +9 -0
  15. package/dist/components/atom/utils/base.d.ts +6 -0
  16. package/dist/components/atom/utils/base.js +8 -0
  17. package/dist/components/atom/utils/cache.d.ts +17 -0
  18. package/dist/components/atom/utils/cache.js +134 -0
  19. package/dist/components/atom/utils/classes.d.ts +14 -0
  20. package/dist/components/atom/utils/classes.js +42 -0
  21. package/dist/components/atom/utils/constants.d.ts +9 -0
  22. package/dist/components/atom/utils/constants.js +9 -0
  23. package/dist/components/atom/utils/index.d.ts +6 -0
  24. package/dist/components/atom/utils/index.js +5 -0
  25. package/dist/components/atom/utils/preset.d.ts +22 -0
  26. package/dist/components/atom/utils/preset.js +94 -0
  27. package/dist/components/atom/utils/props.d.ts +13 -0
  28. package/dist/components/atom/utils/props.js +60 -0
  29. package/dist/components/atom/utils/variants.d.ts +31 -0
  30. package/dist/components/atom/utils/variants.js +270 -0
  31. package/dist/components/card/card-body.svelte +0 -12
  32. package/dist/components/card/card-description.svelte +0 -12
  33. package/dist/components/card/card-footer.svelte +0 -12
  34. package/dist/components/card/card-header.svelte +0 -12
  35. package/dist/components/card/card-media.svelte +0 -12
  36. package/dist/components/card/card-root.svelte +0 -12
  37. package/dist/components/card/card-subtitle.svelte +0 -12
  38. package/dist/components/card/card-title.svelte +0 -12
  39. package/dist/components/collapsible/collapsible-body.svelte +5 -12
  40. package/dist/components/collapsible/collapsible-header.svelte +0 -12
  41. package/dist/components/collapsible/collapsible-indicator.svelte +0 -12
  42. package/dist/components/collapsible/collapsible-root.svelte +0 -12
  43. package/dist/components/combobox/combobox-control.svelte +0 -12
  44. package/dist/components/combobox/combobox-item.svelte +0 -12
  45. package/dist/components/combobox/combobox-item.svelte.d.ts +0 -6
  46. package/dist/components/combobox/index.d.ts +1 -1
  47. package/dist/components/container/container.svelte +0 -12
  48. package/dist/components/datagrid/column/datagrid-column-sort-icon.svelte +3 -12
  49. package/dist/components/datagrid/column/datagrid-column-sort-icon.svelte.d.ts +0 -6
  50. package/dist/components/datagrid/datagrid-body.svelte +17 -1
  51. package/dist/components/dialog/dialog-body.svelte +0 -12
  52. package/dist/components/dialog/dialog-close-button.svelte +0 -12
  53. package/dist/components/dialog/dialog-close.svelte +0 -12
  54. package/dist/components/dialog/dialog-content.svelte +4 -12
  55. package/dist/components/dialog/dialog-description.svelte +0 -12
  56. package/dist/components/dialog/dialog-footer.svelte +0 -12
  57. package/dist/components/dialog/dialog-header.svelte +0 -12
  58. package/dist/components/dialog/dialog-title.svelte +0 -12
  59. package/dist/components/dialog/index.d.ts +3 -0
  60. package/dist/components/dialog/index.js +3 -0
  61. package/dist/components/drawer/drawer-backdrop.svelte +0 -12
  62. package/dist/components/drawer/drawer-body.svelte +0 -12
  63. package/dist/components/drawer/drawer-content.svelte +5 -12
  64. package/dist/components/drawer/drawer-description.svelte +0 -12
  65. package/dist/components/drawer/drawer-footer.svelte +0 -12
  66. package/dist/components/drawer/drawer-header.svelte +0 -12
  67. package/dist/components/drawer/drawer-root.svelte +5 -4
  68. package/dist/components/drawer/drawer-title.svelte +0 -12
  69. package/dist/components/dropdown/dropdown-placeholder.svelte +0 -6
  70. package/dist/components/dropdown/dropdown-placeholder.svelte.d.ts +0 -6
  71. package/dist/components/dropdown/dropdown-query.svelte +0 -12
  72. package/dist/components/dropdown-menu/bond.svelte.d.ts +0 -4
  73. package/dist/components/dropdown-menu/dropdown-menu-content.svelte +0 -12
  74. package/dist/components/dropdown-menu/dropdown-menu-content.svelte.d.ts +0 -6
  75. package/dist/components/dropdown-menu/index.d.ts +1 -1
  76. package/dist/components/form/field/bond.svelte.d.ts +29 -17
  77. package/dist/components/form/field/bond.svelte.js +73 -49
  78. package/dist/components/form/field/field-control.svelte +21 -18
  79. package/dist/components/form/field/field-label.svelte +2 -2
  80. package/dist/components/form/field/field-root.svelte +2 -1
  81. package/dist/components/index.d.ts +2 -0
  82. package/dist/components/index.js +2 -0
  83. package/dist/components/input/input-file-control.svelte +0 -12
  84. package/dist/components/input/input-icon.svelte +3 -3
  85. package/dist/components/input/input-number-control.svelte +28 -35
  86. package/dist/components/input/input-text-control.svelte +8 -3
  87. package/dist/components/input/input-url-control.svelte +2 -2
  88. package/dist/components/input/types.d.ts +4 -4
  89. package/dist/components/kbd/index.d.ts +3 -0
  90. package/dist/components/kbd/index.js +3 -0
  91. package/dist/components/kbd/kbd.svelte +19 -0
  92. package/dist/components/kbd/kbd.svelte.d.ts +4 -0
  93. package/dist/components/kbd/shortcut.svelte +38 -0
  94. package/dist/components/kbd/shortcut.svelte.d.ts +4 -0
  95. package/dist/components/kbd/types.d.ts +20 -0
  96. package/dist/components/kbd/types.js +1 -0
  97. package/dist/components/layer/layer-inner.svelte +0 -12
  98. package/dist/components/layer/layer-root.svelte +0 -12
  99. package/dist/components/menu/menu-content.svelte +0 -12
  100. package/dist/components/menu/menu-content.svelte.d.ts +0 -6
  101. package/dist/components/popover/bond.svelte.d.ts +29 -1
  102. package/dist/components/popover/bond.svelte.js +55 -2
  103. package/dist/components/popover/index.d.ts +1 -0
  104. package/dist/components/popover/index.js +1 -0
  105. package/dist/components/popover/popover-arrow.svelte +4 -2
  106. package/dist/components/popover/popover-content.svelte +17 -90
  107. package/dist/components/popover/popover-overlay.svelte +98 -0
  108. package/dist/components/popover/popover-overlay.svelte.d.ts +4 -0
  109. package/dist/components/popover/popover-trigger.svelte +9 -0
  110. package/dist/components/popover/strategies/floating.svelte +10 -10
  111. package/dist/components/popover/types.d.ts +7 -2
  112. package/dist/components/portal/portal-inner.svelte +0 -12
  113. package/dist/components/portal/portal-root.svelte +0 -12
  114. package/dist/components/portal/types.d.ts +1 -1
  115. package/dist/components/progress/index.d.ts +3 -0
  116. package/dist/components/progress/index.js +3 -0
  117. package/dist/components/progress/progress-circular.svelte +99 -0
  118. package/dist/components/progress/progress-circular.svelte.d.ts +6 -0
  119. package/dist/components/progress/progress-linear.svelte +66 -0
  120. package/dist/components/progress/progress-linear.svelte.d.ts +6 -0
  121. package/dist/components/progress/types.d.ts +18 -0
  122. package/dist/components/progress/types.js +1 -0
  123. package/dist/components/scrollable/scrollable-container.svelte +0 -12
  124. package/dist/components/scrollable/scrollable-content.svelte +0 -12
  125. package/dist/components/scrollable/scrollable-root.svelte +0 -12
  126. package/dist/components/scrollable/scrollable-thumb.svelte +1 -12
  127. package/dist/components/scrollable/scrollable-track.svelte +0 -12
  128. package/dist/components/select/bond.svelte.d.ts +0 -4
  129. package/dist/components/select/index.d.ts +1 -1
  130. package/dist/components/select/select-placeholder.svelte +0 -6
  131. package/dist/components/select/select-placeholder.svelte.d.ts +0 -6
  132. package/dist/components/sidebar/sidebar-content.svelte +5 -12
  133. package/dist/components/stack/bond.svelte.js +6 -0
  134. package/dist/components/stack/stack-item.svelte +4 -0
  135. package/dist/components/switch/switch.svelte +2 -0
  136. package/dist/components/tabs/tab/tab-header.svelte +4 -4
  137. package/dist/components/tabs/tabs-body.svelte +0 -2
  138. package/dist/components/tabs/tabs-root.svelte +11 -3
  139. package/dist/components/toast/atoms.d.ts +1 -1
  140. package/dist/components/toast/atoms.js +1 -1
  141. package/dist/components/toast/attachments.svelte.d.ts +10 -2
  142. package/dist/components/toast/attachments.svelte.js +9 -1
  143. package/dist/components/toast/bond.svelte.d.ts +73 -0
  144. package/dist/components/toast/bond.svelte.js +132 -0
  145. package/dist/components/toast/index.d.ts +1 -1
  146. package/dist/components/toast/index.js +1 -1
  147. package/dist/components/toast/toast-close.svelte +47 -0
  148. package/dist/components/toast/toast-close.svelte.d.ts +26 -0
  149. package/dist/components/toast/toast-description.svelte +16 -24
  150. package/dist/components/toast/toast-description.svelte.d.ts +15 -19
  151. package/dist/components/toast/toast-root.svelte +36 -26
  152. package/dist/components/toast/toast-root.svelte.d.ts +16 -15
  153. package/dist/components/toast/toast-title.svelte +17 -22
  154. package/dist/components/toast/toast-title.svelte.d.ts +13 -13
  155. package/dist/components/toast/toaster.svelte.d.ts +38 -0
  156. package/dist/components/toast/toaster.svelte.js +107 -0
  157. package/dist/components/toast/types.d.ts +13 -21
  158. package/dist/components/tree/tree-body.svelte +5 -12
  159. package/dist/components/tree/tree-header.svelte +0 -12
  160. package/dist/components/tree/tree-indicator.svelte +0 -12
  161. package/dist/components/tree/tree-root.svelte +0 -12
  162. package/dist/context/preset.svelte.d.ts +53 -37
  163. package/dist/context/preset.svelte.js +29 -3
  164. package/package.json +1 -1
  165. package/dist/components/atom/utils.d.ts +0 -44
  166. package/dist/components/atom/utils.js +0 -275
  167. package/dist/components/popover/popover-engine.svelte +0 -118
  168. package/dist/components/popover/popover-engine.svelte.d.ts +0 -3
  169. package/dist/components/toast/bond.d.ts +0 -35
  170. package/dist/components/toast/bond.js +0 -59
  171. package/dist/components/toast/manager.svelte.d.ts +0 -38
  172. package/dist/components/toast/manager.svelte.js +0 -82
  173. package/dist/components/toast/toast-root-managed.svelte +0 -64
  174. package/dist/components/toast/toast-root-managed.svelte.d.ts +0 -7
  175. package/dist/components/toast/toast-toaster.svelte +0 -42
  176. package/dist/components/toast/toast-toaster.svelte.d.ts +0 -4
  177. /package/dist/components/popover/{motion.d.ts → motion.svelte.d.ts} +0 -0
  178. /package/dist/components/popover/{motion.js → motion.svelte.js} +0 -0
package/README.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @svelte-atoms/core
2
2
 
3
+ > ⚠️ **Package renamed:** `@svelte-atoms/core` has moved to [`@ixirjs/ui`](https://www.npmjs.com/package/@ixirjs/ui).
4
+ >
5
+ > This package is deprecated and no longer maintained. To migrate:
6
+ >
7
+ > ```bash
8
+ > npm uninstall @svelte-atoms/core
9
+ > npm install @ixirjs/ui
10
+ > ```
11
+ >
12
+ > Then update your imports from `'@svelte-atoms/core'` to `'@ixirjs/ui'`.
13
+ >
14
+ > Source: [github.com/ixirjs/ui](https://github.com/ixirjs/ui)
15
+
3
16
  > A modern, headless, and accessible Svelte 5 UI component library built for composability and extensibility.
4
17
 
5
18
  [![npm version](https://img.shields.io/npm/v/@svelte-atoms/core.svg)](https://www.npmjs.com/package/@svelte-atoms/core)
@@ -12,10 +12,10 @@
12
12
  children = undefined,
13
13
  onmount = undefined,
14
14
  ondestroy = undefined,
15
- animate = undefined,
16
- enter = enterAccordionItemBody(),
17
- exit = exitAccordionItemBody(),
18
- initial = undefined,
15
+ fallback = {
16
+ enter: enterAccordionItemBody(),
17
+ exit: exitAccordionItemBody()
18
+ },
19
19
  preset = 'accordion.item.body',
20
20
  ...restProps
21
21
  }: AccordionItemBodyProps<E, B> = $props();
@@ -35,10 +35,7 @@
35
35
  class={['border-border box-content h-0 opacity-0', '$preset', klass]}
36
36
  onmount={onmount?.bind(bond.state)}
37
37
  ondestroy={ondestroy?.bind(bond.state)}
38
- animate={animate?.bind(bond.state)}
39
- enter={enter?.bind(bond.state)}
40
- exit={exit?.bind(bond.state)}
41
- initial={initial?.bind(bond.state)}
38
+ {fallback}
42
39
  {...bodyProps}
43
40
  >
44
41
  {@render children?.({ accordionItem: bond })}
@@ -7,13 +7,6 @@
7
7
  class: klass = '',
8
8
  as = 'button',
9
9
  children = undefined,
10
- onpointerdown = undefined,
11
- onmount = undefined,
12
- ondestroy = undefined,
13
- animate = undefined,
14
- enter = undefined,
15
- exit = undefined,
16
- initial = undefined,
17
10
  preset = 'accordion.item.header',
18
11
  ...restProps
19
12
  }: AccordionItemHeaderProps = $props();
@@ -36,12 +29,6 @@
36
29
  '$preset',
37
30
  klass
38
31
  ]}
39
- onmount={onmount?.bind(bond.state)}
40
- ondestroy={ondestroy?.bind(bond.state)}
41
- animate={animate?.bind(bond.state)}
42
- enter={enter?.bind(bond.state)}
43
- exit={exit?.bind(bond.state)}
44
- initial={initial?.bind(bond.state)}
45
32
  tabindex={as !== 'button' ? 0 : undefined}
46
33
  {...headerProps}
47
34
  >
@@ -12,12 +12,6 @@
12
12
  let {
13
13
  class: klass = '',
14
14
  children = undefined,
15
- onmount = undefined,
16
- ondestroy = undefined,
17
- animate = _animate,
18
- enter = undefined,
19
- exit = undefined,
20
- initial = undefined,
21
15
  preset = 'accordion.item.indicator',
22
16
  ...restProps
23
17
  }: AccordionItemIndicatorProps<E, B> = $props();
@@ -35,12 +29,6 @@
35
29
  <HtmlAtom
36
30
  {preset}
37
31
  class={['border-border pointer-events-none flex items-center justify-center', '$preset', klass]}
38
- onmount={onmount?.bind(bond.state)}
39
- ondestroy={ondestroy?.bind(bond.state)}
40
- animate={animate?.bind(bond.state)}
41
- enter={enter?.bind(bond.state)}
42
- exit={exit?.bind(bond.state)}
43
- initial={initial?.bind(bond.state)}
44
32
  {...indicatorProps}
45
33
  >
46
34
  {#if children}
@@ -17,12 +17,6 @@
17
17
  disabled = false,
18
18
  factory = _factory,
19
19
  children = undefined,
20
- onmount = undefined,
21
- ondestroy = undefined,
22
- animate = undefined,
23
- enter = undefined,
24
- exit = undefined,
25
- initial = undefined,
26
20
  preset = 'accordion.item',
27
21
  ...restProps
28
22
  }: AccordionItemRootProps<E, B> = $props();
@@ -55,12 +49,6 @@
55
49
  {bond}
56
50
  {preset}
57
51
  class={['border-border', '$preset', klass]}
58
- onmount={onmount?.bind(bond.state)}
59
- ondestroy={ondestroy?.bind(bond.state)}
60
- animate={animate?.bind(bond.state)}
61
- enter={enter?.bind(bond.state)}
62
- exit={exit?.bind(bond.state)}
63
- initial={initial?.bind(bond.state)}
64
52
  {...rootProps}
65
53
  >
66
54
  {@render children?.({ accordionItem: bond })}
@@ -12,12 +12,6 @@
12
12
  class: klass = '',
13
13
  preset = 'alert.actions',
14
14
  children = undefined,
15
- onmount = undefined,
16
- ondestroy = undefined,
17
- animate = undefined,
18
- enter = undefined,
19
- exit = undefined,
20
- initial = undefined,
21
15
  ...restProps
22
16
  }: AlertActionsProps<E, B> & HTMLAttributes<Element> = $props();
23
17
 
@@ -31,12 +25,6 @@
31
25
  {bond}
32
26
  {preset}
33
27
  class={['alert-actions border-border mt-3 flex items-center gap-2', '$preset', klass]}
34
- onmount={onmount?.bind(bond.state)}
35
- ondestroy={ondestroy?.bind(bond.state)}
36
- animate={animate?.bind(bond.state)}
37
- enter={enter?.bind(bond.state)}
38
- exit={exit?.bind(bond.state)}
39
- initial={initial?.bind(bond.state)}
40
28
  {...actionsProps}
41
29
  >
42
30
  {@render children?.({ alert: bond! })}
@@ -17,12 +17,6 @@
17
17
  as = 'button' as E,
18
18
  preset = 'alert.close-button',
19
19
  children = undefined,
20
- onmount = undefined,
21
- ondestroy = undefined,
22
- animate = undefined,
23
- enter = undefined,
24
- exit = undefined,
25
- initial = undefined,
26
20
  ...restProps
27
21
  }: AlertCloseButtonProps<E, B> & HTMLAttributes<Element> = $props();
28
22
 
@@ -41,12 +35,6 @@
41
35
  '$preset',
42
36
  klass
43
37
  ]}
44
- onmount={onmount?.bind(bond.state)}
45
- ondestroy={ondestroy?.bind(bond.state)}
46
- animate={animate?.bind(bond.state)}
47
- enter={enter?.bind(bond.state)}
48
- exit={exit?.bind(bond.state)}
49
- initial={initial?.bind(bond.state)}
50
38
  {...closeButtonProps}
51
39
  >
52
40
  {#if children}
@@ -12,12 +12,6 @@
12
12
  class: klass = '',
13
13
  preset = 'alert.content',
14
14
  children = undefined,
15
- onmount = undefined,
16
- ondestroy = undefined,
17
- animate = undefined,
18
- enter = undefined,
19
- exit = undefined,
20
- initial = undefined,
21
15
  ...restProps
22
16
  }: AlertContentProps<E, B> & HTMLAttributes<Element> = $props();
23
17
 
@@ -31,12 +25,6 @@
31
25
  {bond}
32
26
  {preset}
33
27
  class={['alert-content border-border flex-1 space-y-1', '$preset', klass]}
34
- onmount={onmount?.bind(bond.state)}
35
- ondestroy={ondestroy?.bind(bond.state)}
36
- animate={animate?.bind(bond.state)}
37
- enter={enter?.bind(bond.state)}
38
- exit={exit?.bind(bond.state)}
39
- initial={initial?.bind(bond.state)}
40
28
  {...contentProps}
41
29
  >
42
30
  {@render children?.({ alert: bond! })}
@@ -10,12 +10,6 @@
10
10
  as = 'p' as E,
11
11
  preset = 'alert.description',
12
12
  children = undefined,
13
- onmount = undefined,
14
- ondestroy = undefined,
15
- animate = undefined,
16
- enter = undefined,
17
- exit = undefined,
18
- initial = undefined,
19
13
  ...restProps
20
14
  }: AlertDescriptionProps<E, B> = $props();
21
15
 
@@ -29,12 +23,6 @@
29
23
  {bond}
30
24
  {preset}
31
25
  class={['alert-description border-border mt-1 text-sm leading-relaxed', '$preset', klass]}
32
- onmount={onmount?.bind(bond.state)}
33
- ondestroy={ondestroy?.bind(bond.state)}
34
- animate={animate?.bind(bond.state)}
35
- enter={enter?.bind(bond.state)}
36
- exit={exit?.bind(bond.state)}
37
- initial={initial?.bind(bond.state)}
38
26
  {as}
39
27
  {...descriptionProps}
40
28
  >
@@ -11,12 +11,6 @@
11
11
  base = Icon,
12
12
  preset = 'alert.icon',
13
13
  children = undefined,
14
- onmount = undefined,
15
- ondestroy = undefined,
16
- animate = undefined,
17
- enter = undefined,
18
- exit = undefined,
19
- initial = undefined,
20
14
  ...restProps
21
15
  }: AlertIconProps<E, B> = $props();
22
16
 
@@ -35,12 +29,6 @@
35
29
  '$preset',
36
30
  klass
37
31
  ]}
38
- onmount={onmount?.bind(bond.state)}
39
- ondestroy={ondestroy?.bind(bond.state)}
40
- animate={animate?.bind(bond.state)}
41
- enter={enter?.bind(bond.state)}
42
- exit={exit?.bind(bond.state)}
43
- initial={initial?.bind(bond.state)}
44
32
  {...iconProps}
45
33
  >
46
34
  {@render children?.({ alert: bond! })}
@@ -11,13 +11,7 @@
11
11
  disabled = false,
12
12
  extend = {},
13
13
  factory = _factory,
14
- children = undefined,
15
- onmount = undefined,
16
- ondestroy = undefined,
17
- animate = undefined,
18
- enter = undefined,
19
- exit = undefined,
20
- initial = undefined,
14
+ children,
21
15
  ...restProps
22
16
  }: AlertRootProps<E, B> = $props();
23
17
 
@@ -56,12 +50,6 @@
56
50
  klass
57
51
  ]}
58
52
  {bond}
59
- onmount={onmount?.bind(bond.state)}
60
- ondestroy={ondestroy?.bind(bond.state)}
61
- animate={animate?.bind(bond.state)}
62
- enter={enter?.bind(bond.state)}
63
- exit={exit?.bind(bond.state)}
64
- initial={initial?.bind(bond.state)}
65
53
  {...rootProps}
66
54
  >
67
55
  {@render children?.({ alert: bond })}
@@ -10,12 +10,6 @@
10
10
  class: klass = '',
11
11
  preset = 'alert.title',
12
12
  children = undefined,
13
- onmount = undefined,
14
- ondestroy = undefined,
15
- animate = undefined,
16
- enter = undefined,
17
- exit = undefined,
18
- initial = undefined,
19
13
  ...restProps
20
14
  }: AlertTitleProps<E, B> = $props();
21
15
 
@@ -30,12 +24,6 @@
30
24
  {bond}
31
25
  {preset}
32
26
  class={['alert-title border-border text-sm leading-tight font-medium', '$preset', klass]}
33
- onmount={onmount?.bind(bond.state)}
34
- ondestroy={ondestroy?.bind(bond.state)}
35
- animate={animate?.bind(bond.state)}
36
- enter={enter?.bind(bond.state)}
37
- exit={exit?.bind(bond.state)}
38
- initial={initial?.bind(bond.state)}
39
27
  {...titleProps}
40
28
  >
41
29
  {@render children?.({ alert: bond! })}
@@ -20,12 +20,13 @@
20
20
 
21
21
  let {
22
22
  class: klass = '',
23
- as = 'div',
23
+ as = undefined,
24
24
  base = undefined,
25
25
  preset: presetKey = undefined,
26
26
  bond = undefined,
27
27
  variants = undefined,
28
- children: childrenProp = undefined,
28
+ fallback = undefined,
29
+ children: children = undefined,
29
30
  ...restProps
30
31
  }: HtmlAtomProps<E, B> = $props();
31
32
 
@@ -59,26 +60,39 @@
59
60
 
60
61
  const finalBase = $derived(base ?? preset?.base);
61
62
  const finalAs = $derived(as ?? preset?.as);
62
- const finalRestProps = $derived(extractRestProps(preset, mergedVariants, restProps));
63
+ const finalRestProps = $derived(extractRestProps(preset, mergedVariants, restProps, fallback));
63
64
 
64
65
  const atom = $derived(rootBond?.state?.props?.renderers?.html ?? HtmlElement);
65
66
 
66
- const renderer = $derived.by(() => {
67
- if (isSnippetBase(finalBase))
67
+ // Memoize the snippet check so the renderer component / props don't both
68
+ // recompute it on every reactive tick.
69
+ const baseIsSnippet = $derived(isSnippetBase(finalBase));
70
+
71
+ // Track the renderer component and its props as INDEPENDENT signals.
72
+ // - `rendererComponent` only flips when the underlying base/atom changes,
73
+ // so Svelte won't tear down + remount when only props change.
74
+ // - `rendererProps` re-allocates when any prop changes, but doesn't drag
75
+ // the component identity with it (no nested `{ component, props }` wrapper).
76
+ const RendererComponent = $derived(
77
+ baseIsSnippet ? (SnippetRenderer as unknown as Component) : ((finalBase ?? atom) as Component)
78
+ );
79
+
80
+ const rendererProps = $derived.by((): Record<string, unknown> => {
81
+ if (baseIsSnippet) {
68
82
  return {
69
- component: SnippetRenderer,
70
- props: { snippet: finalBase, class: finalKlass, as: finalAs, children: childrenProp, ...finalRestProps }
83
+ snippet: finalBase,
84
+ class: finalKlass,
85
+ as: finalAs,
86
+ children: children,
87
+ ...finalRestProps
71
88
  };
89
+ }
90
+ return { class: finalKlass, as: finalAs, ...finalRestProps };
91
+ });
72
92
 
73
- return {
74
- component: finalBase ?? atom,
75
- props: { class: finalKlass, as: finalAs, ...finalRestProps }
76
- };
77
- }) as { component: Component; props: Record<string, any> };
93
+ function forwardChildren(...args: any[]) {
94
+ return children?.(...args);
95
+ }
78
96
  </script>
79
97
 
80
- <renderer.component {...renderer.props}>
81
- {#snippet children(args: any)}
82
- {@render (childrenProp as any)?.(args)}
83
- {/snippet}
84
- </renderer.component>
98
+ <RendererComponent {...rendererProps} children={forwardChildren} />
@@ -65,5 +65,14 @@ export interface HtmlAtomProps<E extends HtmlElementTagName = HtmlElementTagName
65
65
  * ```
66
66
  */
67
67
  variants?: Variants;
68
+ /**
69
+ * Fallback props applied **before** the preset, so user/preset configuration
70
+ * overrides them. Useful for component implementers who want sensible
71
+ * defaults (e.g. `animate`, `enter`, `exit`, `initial`) without preventing
72
+ * downstream consumers from customizing via presets.
73
+ *
74
+ * Merge order (last wins): `fallback` → `preset` → `variants` → `restProps`.
75
+ */
76
+ fallback?: Record<string, any> | undefined;
68
77
  }
69
78
  export type { ElementType };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Returns `true` when `base` is a Svelte 5 snippet (compiled to an arrow function
3
+ * with no `.prototype`), as opposed to a component (compiled to a named function
4
+ * that does have a `.prototype`).
5
+ */
6
+ export declare function isSnippetBase(base: unknown): boolean;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Returns `true` when `base` is a Svelte 5 snippet (compiled to an arrow function
3
+ * with no `.prototype`), as opposed to a component (compiled to a named function
4
+ * that does have a `.prototype`).
5
+ */
6
+ export function isSnippetBase(base) {
7
+ return typeof base === 'function' && !base.prototype;
8
+ }
@@ -0,0 +1,17 @@
1
+ import type { Bond } from '../../../shared';
2
+ export type ResolvedProps = Record<string, unknown>;
3
+ export declare const MAX_CACHE_SIZE = 100;
4
+ export declare function getCacheMap(bond: Bond | null | undefined): Map<string, ResolvedProps>;
5
+ export declare function getDefCacheMap(def: object, bond: Bond | null | undefined): Map<string, ResolvedProps>;
6
+ /**
7
+ * Performs a true-LRU lookup (touch on hit) and returns the cached value, or
8
+ * `undefined` if absent. Avoids the FIFO eviction bug of the previous impl.
9
+ */
10
+ export declare function lruGet<V>(map: Map<string, V>, key: string): V | undefined;
11
+ /** Insert with capacity eviction of the least-recently-used entry. */
12
+ export declare function lruSet<V>(map: Map<string, V>, key: string, value: V, max: number): void;
13
+ export declare function getCachedOwnKeys(obj: object | null | undefined): readonly string[];
14
+ /** Returns true if `obj` has at least one own enumerable key. */
15
+ export declare function hasOwnKeys(obj: object): boolean;
16
+ export declare function hasOwnKeysCached(obj: object | null | undefined): boolean;
17
+ export declare function getCompoundConditionKeys(compound: object): string[];
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Two-level cache for resolved variants (legacy / public API).
3
+ *
4
+ * - Outer key: bond instance (WeakMap — automatically GC'd when the bond is destroyed).
5
+ * - Inner key: JSON-stringified variant-relevant props.
6
+ * - Bond-less calls share a single flat Map.
7
+ *
8
+ * Kept exported for backward compatibility. Internal callers prefer
9
+ * `getDefCacheMap` which avoids global cross-component cache pollution.
10
+ */
11
+ const variantCacheByBond = new WeakMap();
12
+ const variantCacheNoBond = new Map();
13
+ export const MAX_CACHE_SIZE = 100;
14
+ export function getCacheMap(bond) {
15
+ if (!bond)
16
+ return variantCacheNoBond;
17
+ let map = variantCacheByBond.get(bond);
18
+ if (!map) {
19
+ map = new Map();
20
+ variantCacheByBond.set(bond, map);
21
+ }
22
+ return map;
23
+ }
24
+ /**
25
+ * Per-definition cache. The cache map is scoped to a `(def, bond)` pair, so
26
+ * different atoms never share the same eviction window — eliminating the
27
+ * cross-component thrash of the legacy global Map.
28
+ *
29
+ * `def` is keyed by reference via WeakMap, so cache entries are GC'd when
30
+ * the variant definition is no longer reachable.
31
+ */
32
+ const defCacheBondMap = new WeakMap();
33
+ const defCacheNoBondMap = new WeakMap();
34
+ export function getDefCacheMap(def, bond) {
35
+ if (!bond) {
36
+ let m = defCacheNoBondMap.get(def);
37
+ if (!m) {
38
+ m = new Map();
39
+ defCacheNoBondMap.set(def, m);
40
+ }
41
+ return m;
42
+ }
43
+ const bondKey = bond;
44
+ let inner = defCacheBondMap.get(bondKey);
45
+ if (!inner) {
46
+ inner = new WeakMap();
47
+ defCacheBondMap.set(bondKey, inner);
48
+ }
49
+ let m = inner.get(def);
50
+ if (!m) {
51
+ m = new Map();
52
+ inner.set(def, m);
53
+ }
54
+ return m;
55
+ }
56
+ /**
57
+ * Performs a true-LRU lookup (touch on hit) and returns the cached value, or
58
+ * `undefined` if absent. Avoids the FIFO eviction bug of the previous impl.
59
+ */
60
+ export function lruGet(map, key) {
61
+ const v = map.get(key);
62
+ if (v === undefined)
63
+ return undefined;
64
+ // Re-insert to mark as most-recently-used (Map preserves insertion order).
65
+ map.delete(key);
66
+ map.set(key, v);
67
+ return v;
68
+ }
69
+ /** Insert with capacity eviction of the least-recently-used entry. */
70
+ export function lruSet(map, key, value, max) {
71
+ if (map.size >= max) {
72
+ const firstKey = map.keys().next().value;
73
+ if (firstKey !== undefined)
74
+ map.delete(firstKey);
75
+ }
76
+ map.set(key, value);
77
+ }
78
+ /**
79
+ * Cached `Object.keys(obj)` keyed by `obj` reference. Variant maps are stable
80
+ * per definition, so we avoid re-allocating the keys array every render.
81
+ */
82
+ const ownKeysCache = new WeakMap();
83
+ const EMPTY_KEYS = Object.freeze([]);
84
+ export function getCachedOwnKeys(obj) {
85
+ if (!obj)
86
+ return EMPTY_KEYS;
87
+ let keys = ownKeysCache.get(obj);
88
+ if (!keys) {
89
+ keys = Object.keys(obj);
90
+ ownKeysCache.set(obj, keys);
91
+ }
92
+ return keys;
93
+ }
94
+ /** Returns true if `obj` has at least one own enumerable key. */
95
+ export function hasOwnKeys(obj) {
96
+ for (const k in obj)
97
+ if (Object.hasOwn(obj, k))
98
+ return true;
99
+ return false;
100
+ }
101
+ /**
102
+ * Cached `hasOwnKeys` keyed weakly by the input object. Defaults objects are
103
+ * stable per variant definition, so we avoid re-walking the prototype chain
104
+ * on every render. Sentinel `null` is treated as "no" without consuming a slot.
105
+ */
106
+ const hasOwnKeysCache = new WeakMap();
107
+ export function hasOwnKeysCached(obj) {
108
+ if (!obj)
109
+ return false;
110
+ const cached = hasOwnKeysCache.get(obj);
111
+ if (cached !== undefined)
112
+ return cached;
113
+ const result = hasOwnKeys(obj);
114
+ hasOwnKeysCache.set(obj, result);
115
+ return result;
116
+ }
117
+ /**
118
+ * Cached non-`class` keys for a compound variant condition. Compounds are
119
+ * stable per variant definition, so their condition keys never change.
120
+ * Weakly keyed → freed when the compound object is unreachable.
121
+ */
122
+ const compoundKeysCache = new WeakMap();
123
+ export function getCompoundConditionKeys(compound) {
124
+ let keys = compoundKeysCache.get(compound);
125
+ if (!keys) {
126
+ keys = [];
127
+ for (const k in compound) {
128
+ if (Object.hasOwn(compound, k) && k !== 'class')
129
+ keys.push(k);
130
+ }
131
+ compoundKeysCache.set(compound, keys);
132
+ }
133
+ return keys;
134
+ }
@@ -0,0 +1,14 @@
1
+ import { type ClassValue } from '../../../utils';
2
+ /**
3
+ * Merges user-supplied class, preset class, and resolved variant class into a
4
+ * single Tailwind-safe class string.
5
+ *
6
+ * Supports the special `$preset` placeholder inside the user class string, which
7
+ * lets the caller control exactly where the preset classes are injected.
8
+ *
9
+ * Rules:
10
+ * - No `$preset` → normal merge: `cn(userClass, variantClass)`.
11
+ * - Has `$preset` → only the **last** occurrence acts as the injection point:
12
+ * `beforePlaceholder + presetClass + variantClass + afterPlaceholder`.
13
+ */
14
+ export declare function mergeClassesWithPreset(userClass: string | ClassValue | undefined, presetClass: ClassValue | undefined, variantClass: ClassValue | undefined): string;
@@ -0,0 +1,42 @@
1
+ import { cn } from '../../../utils';
2
+ /**
3
+ * Merges user-supplied class, preset class, and resolved variant class into a
4
+ * single Tailwind-safe class string.
5
+ *
6
+ * Supports the special `$preset` placeholder inside the user class string, which
7
+ * lets the caller control exactly where the preset classes are injected.
8
+ *
9
+ * Rules:
10
+ * - No `$preset` → normal merge: `cn(userClass, variantClass)`.
11
+ * - Has `$preset` → only the **last** occurrence acts as the injection point:
12
+ * `beforePlaceholder + presetClass + variantClass + afterPlaceholder`.
13
+ */
14
+ export function mergeClassesWithPreset(userClass, presetClass, variantClass) {
15
+ // Fast path: user class is a plain string and contains no `$preset` placeholder
16
+ // — by far the most common case. Skip the prelim `cn()` call entirely.
17
+ if (typeof userClass === 'string') {
18
+ if (userClass.indexOf('$preset') === -1) {
19
+ return cn(userClass, variantClass ?? '');
20
+ }
21
+ }
22
+ else if (userClass == null) {
23
+ return cn(variantClass ?? '');
24
+ }
25
+ else {
26
+ // Non-string ClassValue (array/object) — must run through `cn()` first
27
+ // to detect a `$preset` placeholder potentially nested inside.
28
+ const merged = cn(userClass);
29
+ if (merged.indexOf('$preset') === -1) {
30
+ return cn(merged, variantClass ?? '');
31
+ }
32
+ const lastIdx = merged.lastIndexOf('$preset');
33
+ return cn(merged.slice(0, lastIdx), cn(presetClass), variantClass ?? '', merged.slice(lastIdx + '$preset'.length));
34
+ }
35
+ // Slow path: `$preset` placeholder resolution for string `userClass`.
36
+ const klassStr = userClass;
37
+ const lastIdx = klassStr.lastIndexOf('$preset');
38
+ const beforeLastPlaceholder = klassStr.slice(0, lastIdx);
39
+ const afterLastPlaceholder = klassStr.slice(lastIdx + '$preset'.length);
40
+ const presetClassString = cn(presetClass);
41
+ return cn(beforeLastPlaceholder, presetClassString, variantClass ?? '', afterLastPlaceholder);
42
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Props stripped when spreading preset props onto the element.
3
+ * These are internal atom configuration keys that are not valid DOM attributes.
4
+ */
5
+ export declare const PRESET_SKIP: Set<string>;
6
+ /**
7
+ * Props stripped when spreading resolved variant objects.
8
+ */
9
+ export declare const VARIANTS_SKIP: Set<string>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Props stripped when spreading preset props onto the element.
3
+ * These are internal atom configuration keys that are not valid DOM attributes.
4
+ */
5
+ export const PRESET_SKIP = new Set(['class', 'base', 'as', 'variants', 'compounds', 'defaults']);
6
+ /**
7
+ * Props stripped when spreading resolved variant objects.
8
+ */
9
+ export const VARIANTS_SKIP = new Set(['class', 'variants', 'compounds', 'defaults']);
@@ -0,0 +1,6 @@
1
+ export { resolvePreset } from './preset';
2
+ export { isSnippetBase } from './base';
3
+ export { mergeClassesWithPreset } from './classes';
4
+ export { resolveVariants, mergeVariants, resolveLocalVariants } from './variants';
5
+ export { extractRestProps } from './props';
6
+ export type { ResolvedProps } from './cache';
@@ -0,0 +1,5 @@
1
+ export { resolvePreset } from './preset';
2
+ export { isSnippetBase } from './base';
3
+ export { mergeClassesWithPreset } from './classes';
4
+ export { resolveVariants, mergeVariants, resolveLocalVariants } from './variants';
5
+ export { extractRestProps } from './props';