@svelte-atoms/core 1.0.0-alpha.27 → 1.0.0-alpha.29

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 (186) hide show
  1. package/README.md +852 -645
  2. package/dist/components/accordion/accordion-root.svelte +61 -61
  3. package/dist/components/accordion/item/accordion-item-body.svelte +42 -42
  4. package/dist/components/accordion/item/accordion-item-header.svelte +50 -50
  5. package/dist/components/accordion/item/accordion-item-indicator.svelte +50 -50
  6. package/dist/components/accordion/item/accordion-item-root.svelte +65 -65
  7. package/dist/components/alert/alert-actions.svelte +43 -42
  8. package/dist/components/alert/alert-close-button.svelte +70 -72
  9. package/dist/components/alert/alert-content.svelte +43 -42
  10. package/dist/components/alert/alert-description.svelte +42 -41
  11. package/dist/components/alert/alert-icon.svelte +47 -46
  12. package/dist/components/alert/alert-root.svelte +103 -102
  13. package/dist/components/alert/alert-title.svelte +42 -41
  14. package/dist/components/alert/alert.stories.svelte +384 -23
  15. package/dist/components/alert/alert.stories.svelte.d.ts +2 -5
  16. package/dist/components/atom/html-atom.svelte +207 -201
  17. package/dist/components/atom/html-atom.svelte.d.ts +1 -1
  18. package/dist/components/atom/snippet-renderer.svelte +5 -0
  19. package/dist/components/atom/snippet-renderer.svelte.d.ts +5 -0
  20. package/dist/components/avatar/avatar.stories.svelte.d.ts +1 -1
  21. package/dist/components/badge/badge.stories.svelte.d.ts +1 -1
  22. package/dist/components/breadcrumb/breadcrumb.stories.svelte.d.ts +1 -1
  23. package/dist/components/button/button.stories.svelte +17 -14
  24. package/dist/components/calendar/atoms.d.ts +5 -0
  25. package/dist/components/calendar/atoms.js +5 -0
  26. package/dist/components/calendar/bond.svelte.d.ts +72 -0
  27. package/dist/components/calendar/bond.svelte.js +132 -0
  28. package/dist/components/calendar/calendar-body.svelte +107 -0
  29. package/dist/components/calendar/calendar-body.svelte.d.ts +8 -0
  30. package/dist/components/calendar/calendar-day.svelte +96 -0
  31. package/dist/components/calendar/calendar-day.svelte.d.ts +4 -0
  32. package/dist/components/calendar/calendar-header.svelte +29 -0
  33. package/dist/components/calendar/calendar-header.svelte.d.ts +6 -0
  34. package/dist/components/calendar/calendar-root.svelte +206 -0
  35. package/dist/components/calendar/calendar-root.svelte.d.ts +8 -0
  36. package/dist/components/calendar/calendar-week-day.svelte +34 -0
  37. package/dist/components/calendar/calendar-week-day.svelte.d.ts +9 -0
  38. package/dist/components/calendar/calendar.css +26 -0
  39. package/dist/components/calendar/calendar.stories.svelte +31 -0
  40. package/dist/components/calendar/calendar.stories.svelte.d.ts +26 -0
  41. package/dist/components/calendar/index.d.ts +4 -0
  42. package/dist/components/calendar/index.js +4 -0
  43. package/dist/components/calendar/runes.svelte.d.ts +3 -0
  44. package/dist/components/calendar/runes.svelte.js +25 -0
  45. package/dist/components/calendar/types.d.ts +62 -0
  46. package/dist/components/calendar/types.js +1 -0
  47. package/dist/components/card/card-body.svelte +39 -39
  48. package/dist/components/card/card-description.svelte +41 -41
  49. package/dist/components/card/card-footer.svelte +41 -41
  50. package/dist/components/card/card-header.svelte +41 -41
  51. package/dist/components/card/card-media.svelte +41 -41
  52. package/dist/components/card/card-root.svelte +91 -91
  53. package/dist/components/card/card-subtitle.svelte +41 -41
  54. package/dist/components/card/card-title.svelte +45 -45
  55. package/dist/components/collapsible/collapsible-body.svelte +39 -39
  56. package/dist/components/collapsible/collapsible-header.svelte +39 -39
  57. package/dist/components/collapsible/collapsible-indicator.svelte +50 -50
  58. package/dist/components/collapsible/collapsible-root.svelte +66 -66
  59. package/dist/components/combobox/combobox-root.svelte +65 -65
  60. package/dist/components/container/container.stories.svelte.d.ts +1 -1
  61. package/dist/components/contextmenu/contextmenu-trigger.svelte.d.ts +1 -1
  62. package/dist/components/datagrid/bond.svelte.d.ts +2 -2
  63. package/dist/components/datagrid/datagrid-body.svelte +37 -37
  64. package/dist/components/datagrid/datagrid-checkbox.svelte +101 -101
  65. package/dist/components/datagrid/datagrid-footer.svelte +34 -34
  66. package/dist/components/datagrid/datagrid-header.svelte +49 -49
  67. package/dist/components/datagrid/datagrid-root.svelte +2 -2
  68. package/dist/components/datagrid/datagrid.css +5 -47
  69. package/dist/components/datagrid/td/datagrid-td.svelte +66 -66
  70. package/dist/components/datagrid/th/datagrid-th.svelte +106 -106
  71. package/dist/components/datagrid/tr/datagrid-tr.svelte +88 -88
  72. package/dist/components/datagrid/types.d.ts +1 -1
  73. package/dist/components/date-picker/atoms.d.ts +3 -0
  74. package/dist/components/date-picker/atoms.js +3 -0
  75. package/dist/components/date-picker/bond.svelte.d.ts +67 -0
  76. package/dist/components/date-picker/bond.svelte.js +174 -0
  77. package/dist/components/date-picker/date-picker-calendar.svelte +67 -0
  78. package/dist/components/date-picker/date-picker-calendar.svelte.d.ts +4 -0
  79. package/dist/components/date-picker/date-picker-header.svelte +100 -0
  80. package/dist/components/date-picker/date-picker-header.svelte.d.ts +4 -0
  81. package/dist/components/date-picker/date-picker-months.svelte +142 -0
  82. package/dist/components/date-picker/date-picker-months.svelte.d.ts +4 -0
  83. package/dist/components/date-picker/date-picker-root.svelte +95 -0
  84. package/dist/components/date-picker/date-picker-root.svelte.d.ts +4 -0
  85. package/dist/components/date-picker/date-picker-years.svelte +205 -0
  86. package/dist/components/date-picker/date-picker-years.svelte.d.ts +4 -0
  87. package/dist/components/date-picker/date-picker.stories.svelte +42 -0
  88. package/dist/components/date-picker/date-picker.stories.svelte.d.ts +3 -0
  89. package/dist/components/date-picker/index.d.ts +3 -0
  90. package/dist/components/date-picker/index.js +3 -0
  91. package/dist/components/date-picker/types.d.ts +53 -0
  92. package/dist/components/date-picker/types.js +1 -0
  93. package/dist/components/dialog/dialog-body.svelte +39 -39
  94. package/dist/components/dialog/dialog-close-button.svelte +58 -58
  95. package/dist/components/dialog/dialog-content.svelte +1 -1
  96. package/dist/components/dialog/dialog-description.svelte +40 -40
  97. package/dist/components/dialog/dialog-footer.svelte +39 -39
  98. package/dist/components/dialog/dialog-header.svelte +39 -39
  99. package/dist/components/dialog/dialog-root.svelte +110 -110
  100. package/dist/components/dialog/dialog-title.svelte +41 -41
  101. package/dist/components/drawer/drawer-backdrop.svelte +38 -38
  102. package/dist/components/drawer/drawer-body.svelte +42 -42
  103. package/dist/components/drawer/drawer-content.svelte +42 -42
  104. package/dist/components/drawer/drawer-description.svelte +44 -44
  105. package/dist/components/drawer/drawer-footer.svelte +41 -41
  106. package/dist/components/drawer/drawer-header.svelte +43 -43
  107. package/dist/components/drawer/drawer-root.svelte +93 -93
  108. package/dist/components/drawer/drawer-title.svelte +44 -44
  109. package/dist/components/dropdown/dropdown-query.svelte +54 -54
  110. package/dist/components/dropdown/dropdown-root.svelte +59 -59
  111. package/dist/components/dropdown/dropdown-trigger.svelte +41 -41
  112. package/dist/components/dropdown/dropdown-value.svelte +60 -60
  113. package/dist/components/element/types.d.ts +1 -1
  114. package/dist/components/form/bond.svelte.d.ts +1 -1
  115. package/dist/components/form/field/field-control.svelte +48 -48
  116. package/dist/components/form/field/field-label.svelte +24 -24
  117. package/dist/components/form/field/field-root.svelte +59 -59
  118. package/dist/components/icon/icon.svelte +44 -44
  119. package/dist/components/image/image.stories.svelte.d.ts +1 -1
  120. package/dist/components/index.d.ts +4 -0
  121. package/dist/components/index.js +4 -0
  122. package/dist/components/input/input-control.svelte +103 -103
  123. package/dist/components/label/label.svelte +25 -25
  124. package/dist/components/lazy/index.d.ts +1 -0
  125. package/dist/components/lazy/index.js +1 -0
  126. package/dist/components/lazy/lazy.stories.svelte +35 -0
  127. package/dist/components/lazy/lazy.stories.svelte.d.ts +19 -0
  128. package/dist/components/lazy/lazy.svelte +28 -0
  129. package/dist/components/lazy/lazy.svelte.d.ts +5 -0
  130. package/dist/components/lazy/types.d.ts +10 -0
  131. package/dist/components/lazy/types.js +1 -0
  132. package/dist/components/menu/menu-list.svelte +40 -39
  133. package/dist/components/menu/menu-list.svelte.d.ts +1 -0
  134. package/dist/components/popover/popover-arrow.svelte +111 -111
  135. package/dist/components/popover/popover-content.svelte +178 -139
  136. package/dist/components/popover/popover-root.svelte +16 -17
  137. package/dist/components/popover/popover.stories.svelte +0 -15
  138. package/dist/components/portal/portal-root.svelte +83 -83
  139. package/dist/components/portal/teleport.svelte +50 -50
  140. package/dist/components/qr-code/index.d.ts +2 -0
  141. package/dist/components/qr-code/index.js +2 -0
  142. package/dist/components/qr-code/qr-code.stories.svelte +27 -0
  143. package/dist/components/qr-code/qr-code.stories.svelte.d.ts +26 -0
  144. package/dist/components/qr-code/qr-code.svelte +75 -0
  145. package/dist/components/qr-code/qr-code.svelte.d.ts +4 -0
  146. package/dist/components/qr-code/types.d.ts +14 -0
  147. package/dist/components/qr-code/types.js +1 -0
  148. package/dist/components/radio/radio.svelte +109 -109
  149. package/dist/components/radio/types.svelte.d.ts +1 -1
  150. package/dist/components/scrollable/scrollable-container.svelte +82 -82
  151. package/dist/components/scrollable/scrollable-content.svelte +41 -41
  152. package/dist/components/scrollable/scrollable-root.svelte +100 -100
  153. package/dist/components/scrollable/scrollable-thumb.svelte +75 -75
  154. package/dist/components/scrollable/scrollable-track.svelte +59 -59
  155. package/dist/components/scrollable/scrollable.stories.svelte.d.ts +1 -1
  156. package/dist/components/sidebar/bond.svelte.d.ts +0 -5
  157. package/dist/components/sidebar/bond.svelte.js +1 -12
  158. package/dist/components/sidebar/sidebar-content.svelte +39 -39
  159. package/dist/components/sidebar/sidebar-content.svelte.d.ts +2 -2
  160. package/dist/components/sidebar/sidebar-root.svelte +41 -68
  161. package/dist/components/sidebar/sidebar-root.svelte.d.ts +2 -2
  162. package/dist/components/sidebar/sidebar.stories.svelte +54 -52
  163. package/dist/components/sidebar/types.d.ts +6 -6
  164. package/dist/components/tabs/tab/tab-body.svelte +52 -52
  165. package/dist/components/tabs/tab/tab-description.svelte +41 -41
  166. package/dist/components/tabs/tab/tab-header.svelte +71 -71
  167. package/dist/components/tabs/tab/tab-root.svelte +86 -86
  168. package/dist/components/toast/toast-description.svelte +38 -38
  169. package/dist/components/toast/toast-root.svelte +61 -61
  170. package/dist/components/toast/toast-title.svelte +35 -35
  171. package/dist/components/tree/tree-body.svelte +39 -39
  172. package/dist/components/tree/tree-header.svelte +54 -54
  173. package/dist/components/tree/tree-indicator.svelte +40 -40
  174. package/dist/components/tree/tree-root.svelte +65 -65
  175. package/dist/components/virtual/virtual-root.svelte +239 -239
  176. package/dist/context/preset.svelte.d.ts +1 -1
  177. package/dist/icons/icon-arrow-down.svelte.d.ts +1 -1
  178. package/dist/icons/icon-checkmark.svelte.d.ts +1 -1
  179. package/dist/icons/icon-close.svelte.d.ts +1 -1
  180. package/dist/icons/icon-more-vert.svelte.d.ts +1 -1
  181. package/dist/runes/container.svelte.d.ts +2 -2
  182. package/dist/shared/bond.svelte.d.ts +1 -1
  183. package/dist/utils/state.d.ts +1 -1
  184. package/dist/utils/state.js +2 -1
  185. package/llm/variants.md +650 -103
  186. package/package.json +465 -437
@@ -1,111 +1,111 @@
1
- <script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- import { animate as motion } from 'motion';
4
- import { HtmlAtom, type Base } from '../atom';
5
- import { PopoverBond } from './bond.svelte';
6
- import type { PopoverArrowProps } from './types';
7
-
8
- type Element = HTMLElementTagNameMap[E];
9
-
10
- const bond = PopoverBond.get();
11
-
12
- if (!bond) {
13
- throw new Error('');
14
- }
15
-
16
- let {
17
- class: klass = '',
18
- children = undefined,
19
- onmount = undefined,
20
- ondestroy = undefined,
21
- animate = _animate,
22
- enter = undefined,
23
- exit = undefined,
24
- initial = undefined,
25
- ...restProps
26
- }: PopoverArrowProps<E, B> & HTMLAttributes<Element> = $props();
27
-
28
- const position = $derived(bond.position);
29
- const middlewareArrowData = $derived(position?.middlewareData?.arrow);
30
- const isReady = $derived(!!middlewareArrowData);
31
- const side = $derived(position?.placement?.split('-')[0] ?? 'top');
32
-
33
- const arrowProps = $derived({
34
- ...bond.arrow(),
35
- ...restProps
36
- });
37
-
38
- // Rotation based on placement side
39
- const rotation = $derived.by(() => {
40
- switch (side) {
41
- case 'top':
42
- return 180;
43
- case 'bottom':
44
- return 0;
45
- case 'left':
46
- return 90;
47
- case 'right':
48
- return -90;
49
- default:
50
- return 0;
51
- }
52
- });
53
-
54
- function _animate(node: HTMLElement) {
55
- if (!middlewareArrowData) {
56
- return;
57
- }
58
-
59
- const { x, y } = middlewareArrowData;
60
-
61
- const isMainAxis = side === 'top' || side === 'bottom';
62
-
63
- const crossAxisStyle = isMainAxis
64
- ? {
65
- left: 0
66
- }
67
- : {
68
- top: 0
69
- };
70
-
71
- motion(
72
- node,
73
- {
74
- x: x ?? 0,
75
- y: y ?? 0,
76
- opacity: 1,
77
- ...crossAxisStyle
78
- },
79
- { duration: 0 }
80
- );
81
- }
82
- </script>
83
-
84
- <HtmlAtom
85
- {bond}
86
- preset="popover.arrow"
87
- class={['text-border border-border pointer-events-none absolute opacity-0', '$preset', klass]}
88
- onmount={onmount?.bind(bond.state)}
89
- ondestroy={ondestroy?.bind(bond.state)}
90
- animate={animate?.bind(bond.state)}
91
- enter={enter?.bind(bond.state)}
92
- exit={exit?.bind(bond.state)}
93
- initial={initial?.bind(bond.state)}
94
- style="{side}: 100%;"
95
- {...arrowProps}
96
- >
97
- {#if children}
98
- {@render children({ popover: bond })}
99
- {:else}
100
- <svg
101
- width="12"
102
- height="12"
103
- viewBox="0 0 12 12"
104
- fill="none"
105
- xmlns="http://www.w3.org/2000/svg"
106
- style="transform: rotate({rotation}deg);"
107
- >
108
- <path d="M0 12L6 6L12 12H0Z" fill="currentColor" stroke="none" />
109
- </svg>
110
- {/if}
111
- </HtmlAtom>
1
+ <script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { animate as motion } from 'motion';
4
+ import { HtmlAtom, type Base } from '../atom';
5
+ import { PopoverBond } from './bond.svelte';
6
+ import type { PopoverArrowProps } from './types';
7
+
8
+ type Element = HTMLElementTagNameMap[E];
9
+
10
+ const bond = PopoverBond.get();
11
+
12
+ if (!bond) {
13
+ throw new Error('');
14
+ }
15
+
16
+ let {
17
+ class: klass = '',
18
+ children = undefined,
19
+ onmount = undefined,
20
+ ondestroy = undefined,
21
+ animate = _animate,
22
+ enter = undefined,
23
+ exit = undefined,
24
+ initial = undefined,
25
+ ...restProps
26
+ }: PopoverArrowProps<E, B> & HTMLAttributes<Element> = $props();
27
+
28
+ const position = $derived(bond.position);
29
+ const middlewareArrowData = $derived(position?.middlewareData?.arrow);
30
+ const isReady = $derived(!!middlewareArrowData);
31
+ const side = $derived(position?.placement?.split('-')[0] ?? 'top');
32
+
33
+ const arrowProps = $derived({
34
+ ...bond.arrow(),
35
+ ...restProps
36
+ });
37
+
38
+ // Rotation based on placement side
39
+ const rotation = $derived.by(() => {
40
+ switch (side) {
41
+ case 'top':
42
+ return 180;
43
+ case 'bottom':
44
+ return 0;
45
+ case 'left':
46
+ return 90;
47
+ case 'right':
48
+ return -90;
49
+ default:
50
+ return 0;
51
+ }
52
+ });
53
+
54
+ function _animate(node: HTMLElement) {
55
+ if (!middlewareArrowData) {
56
+ return;
57
+ }
58
+
59
+ const { x, y } = middlewareArrowData;
60
+
61
+ const isMainAxis = side === 'top' || side === 'bottom';
62
+
63
+ const crossAxisStyle = isMainAxis
64
+ ? {
65
+ left: 0
66
+ }
67
+ : {
68
+ top: 0
69
+ };
70
+
71
+ motion(
72
+ node,
73
+ {
74
+ x: x ?? 0,
75
+ y: y ?? 0,
76
+ opacity: 1,
77
+ ...crossAxisStyle
78
+ },
79
+ { duration: 0 }
80
+ );
81
+ }
82
+ </script>
83
+
84
+ <HtmlAtom
85
+ {bond}
86
+ preset="popover.arrow"
87
+ class={['text-border border-border pointer-events-none absolute opacity-0', '$preset', klass]}
88
+ onmount={onmount?.bind(bond.state)}
89
+ ondestroy={ondestroy?.bind(bond.state)}
90
+ animate={animate?.bind(bond.state)}
91
+ enter={enter?.bind(bond.state)}
92
+ exit={exit?.bind(bond.state)}
93
+ initial={initial?.bind(bond.state)}
94
+ style="{side}: 100%;"
95
+ {...arrowProps}
96
+ >
97
+ {#if children}
98
+ {@render children({ popover: bond })}
99
+ {:else}
100
+ <svg
101
+ width="12"
102
+ height="12"
103
+ viewBox="0 0 12 12"
104
+ fill="none"
105
+ xmlns="http://www.w3.org/2000/svg"
106
+ style="transform: rotate({rotation}deg);"
107
+ >
108
+ <path d="M0 12L6 6L12 12H0Z" fill="currentColor" stroke="none" />
109
+ </svg>
110
+ {/if}
111
+ </HtmlAtom>
@@ -1,139 +1,178 @@
1
- <script lang="ts" generics="E extends HtmlElementTagName, B extends Base = Base">
2
- import { animate as motion } from 'motion';
3
- import { PortalBond, PortalsBond, Teleport } from '../portal';
4
- import { HtmlAtom, type Base } from '../atom';
5
- import type { HtmlElementTagName, HtmlElementType } from '../element';
6
- import { DURATION } from '../../shared';
7
- import { PopoverBond } from './bond.svelte';
8
- import type { AnimateParams, PopoverContentProps } from './types';
9
-
10
- type Element = HtmlElementType<E>;
11
-
12
- const bond = PopoverBond.get();
13
- const activePortalBond = (() => {
14
- const key = bond.state.props.portal;
15
- if (key instanceof PortalBond) {
16
- return key;
17
- }
18
-
19
- let portal: PortalBond | undefined | null = undefined;
20
-
21
- if (typeof key === 'string') {
22
- portal = PortalsBond.get()?.state.get(key);
23
- console.error('portal was not found');
24
- }
25
-
26
- return portal ?? PortalBond.get();
27
- })();
28
-
29
- if (!bond) {
30
- throw new Error('<PopoverOverlay /> must be used within a <Popover />');
31
- }
32
-
33
- let {
34
- class: klass = '',
35
- children = undefined,
36
- onmount = undefined,
37
- ondestroy = undefined,
38
- animate = _animate,
39
- enter = undefined,
40
- exit = undefined,
41
- initial = undefined,
42
- ...restProps
43
- }: PopoverContentProps<E, B> = $props();
44
-
45
- const isOpen = $derived(bond.state.isOpen && !!bond.elements.trigger);
46
- const portalId = $derived(activePortalBond?.id);
47
-
48
- const position = $derived(bond.position);
49
- const placement = $derived(position?.placement);
50
-
51
- const x = $derived(position?.x ?? 0);
52
- const y = $derived(position?.y ?? 0);
53
-
54
- const dy = $derived(placement?.startsWith('top') ? -1 : placement?.startsWith('bottom') ? 1 : 0);
55
- const dx = $derived(placement?.startsWith('left') ? -1 : placement?.startsWith('right') ? 1 : 0);
56
-
57
- const offset = $derived(bond.state.props.offset);
58
-
59
- const xOffset = $derived(dx * offset);
60
- const yOffset = $derived(dy * offset);
61
-
62
- let isInitialized = false;
63
-
64
- function _containerInitial(this: typeof bond.state, node: Element) {
65
- const openAsNumber = +this.isOpen;
66
-
67
- const deltaArrow = position?.middlewareData?.arrow ? 1 : 0;
68
- const arrowClientWidth = bond?.elements.arrow?.clientWidth ?? 0;
69
- const arrowClientHeight = bond?.elements.arrow?.clientHeight ?? 0;
70
-
71
- const _x = x + xOffset * openAsNumber + deltaArrow * dx * arrowClientWidth;
72
- const _y = y + yOffset * openAsNumber + deltaArrow * dy * arrowClientHeight;
73
-
74
- node.style.transform = `translate3d(${_x}px, ${_y}px, 1px)`;
75
-
76
- isInitialized = true;
77
- }
78
-
79
- function _containerAnimate(this: typeof bond.state, node: Element, _?: AnimateParams) {
80
- if (!isInitialized) {
81
- return;
82
- }
83
-
84
- const openAsNumber = +this.isOpen;
85
-
86
- const deltaArrow = position?.middlewareData?.arrow ? 1 : 0;
87
- const arrowClientWidth = bond?.elements.arrow?.clientWidth ?? 0;
88
- const arrowClientHeight = bond?.elements.arrow?.clientHeight ?? 0;
89
-
90
- const _x = x + xOffset * openAsNumber + deltaArrow * dx * arrowClientWidth;
91
- const _y = y + yOffset * openAsNumber + deltaArrow * dy * arrowClientHeight;
92
-
93
- node.style.transform = `translate3d(${_x}px, ${_y}px, 1px)`;
94
- }
95
-
96
- function _animate(this: typeof bond.state, node: Element) {
97
- const isOpen = this.isOpen;
98
-
99
- motion(
100
- node,
101
- {
102
- opacity: +isOpen,
103
- y: (isOpen ? 0 : -1) * dy * 8
104
- },
105
- { duration: DURATION.fast / 1000 }
106
- );
107
- }
108
- </script>
109
-
110
- <Teleport
111
- portal={portalId ?? 'root.l0'}
112
- as="div"
113
- class={[
114
- 'pointer-events-auto absolute top-0 left-0 h-min w-fit',
115
- !isOpen && 'pointer-events-none'
116
- ]}
117
- initial={_containerInitial?.bind(bond.state)}
118
- animate={_containerAnimate?.bind(bond.state)}
119
- {...bond.content({ onchange: _containerInitial })}
120
- >
121
- <HtmlAtom
122
- {bond}
123
- preset="popover.content"
124
- class={[
125
- 'popover-content bg-popover text-popover-foreground border-border rounded-md border p-2 opacity-0 shadow-lg',
126
- '$preset',
127
- klass
128
- ]}
129
- enter={enter?.bind(bond.state)}
130
- exit={exit?.bind(bond.state)}
131
- initial={initial?.bind(bond.state)}
132
- animate={animate?.bind(bond.state)}
133
- onmount={onmount?.bind(bond.state)}
134
- ondestroy={ondestroy?.bind(bond.state)}
135
- {...restProps}
136
- >
137
- {@render children?.({ popover: bond })}
138
- </HtmlAtom>
139
- </Teleport>
1
+ <script lang="ts" generics="E extends HtmlElementTagName, B extends Base = Base">
2
+ import { animate as motion } from 'motion';
3
+ import { PortalBond, PortalsBond, Teleport } from '../portal';
4
+ import { HtmlAtom, type Base } from '../atom';
5
+ import type { HtmlElementTagName, HtmlElementType } from '../element';
6
+ import { DURATION } from '../../shared';
7
+ import { PopoverBond } from './bond.svelte';
8
+ import type { AnimateParams, PopoverContentProps } from './types';
9
+
10
+ type Element = HtmlElementType<E>;
11
+
12
+ const bond = PopoverBond.get();
13
+ const activePortalBond = (() => {
14
+ const key = bond.state.props.portal;
15
+ if (key instanceof PortalBond) {
16
+ return key;
17
+ }
18
+
19
+ let portal: PortalBond | undefined | null = undefined;
20
+
21
+ if (typeof key === 'string') {
22
+ portal = PortalsBond.get()?.state.get(key);
23
+ console.error('portal was not found');
24
+ }
25
+
26
+ return portal ?? PortalBond.get();
27
+ })();
28
+
29
+ if (!bond) {
30
+ throw new Error('<PopoverOverlay /> must be used within a <Popover />');
31
+ }
32
+
33
+ let {
34
+ class: klass = '',
35
+ children = undefined,
36
+ onmount = undefined,
37
+ ondestroy = undefined,
38
+ animate = _animate,
39
+ enter = undefined,
40
+ exit = undefined,
41
+ initial = undefined,
42
+ ...restProps
43
+ }: PopoverContentProps<E, B> = $props();
44
+
45
+ const isOpen = $derived(bond.state.isOpen && !!bond.elements.trigger);
46
+ const portalId = $derived(activePortalBond?.id);
47
+
48
+ const position = $derived(bond.position);
49
+ const placement = $derived(position?.placement);
50
+
51
+ const x = $derived(position?.x ?? 0);
52
+ const y = $derived(position?.y ?? 0);
53
+
54
+ const dy = $derived(placement?.startsWith('top') ? -1 : placement?.startsWith('bottom') ? 1 : 0);
55
+ const dx = $derived(placement?.startsWith('left') ? -1 : placement?.startsWith('right') ? 1 : 0);
56
+
57
+ const offset = $derived(bond.state.props.offset);
58
+
59
+ const xOffset = $derived(dx * offset);
60
+ const yOffset = $derived(dy * offset);
61
+
62
+ const openAsNumber = $derived(+isOpen);
63
+ const deltaArrow = $derived(position?.middlewareData?.arrow ? 1 : 0);
64
+
65
+ let isInitialized = false;
66
+
67
+ function _containerInitial(this: typeof bond.state, node: Element) {
68
+ const arrowClientWidth = bond?.elements.arrow?.clientWidth ?? 0;
69
+ const arrowClientHeight = bond?.elements.arrow?.clientHeight ?? 0;
70
+
71
+ const _x = x + xOffset * openAsNumber + deltaArrow * dx * arrowClientWidth;
72
+ const _y = y + yOffset * openAsNumber + deltaArrow * dy * arrowClientHeight;
73
+
74
+ node.style.transform = `translate3d(${_x}px, ${_y}px, 1px)`;
75
+
76
+ isInitialized = true;
77
+ }
78
+
79
+ function _containerAnimate(this: typeof bond.state, node: Element, _?: AnimateParams) {
80
+ if (!isInitialized) {
81
+ return;
82
+ }
83
+
84
+ const deltaArrow = position?.middlewareData?.arrow ? 1 : 0;
85
+ const arrowClientWidth = bond?.elements.arrow?.clientWidth ?? 0;
86
+ const arrowClientHeight = bond?.elements.arrow?.clientHeight ?? 0;
87
+
88
+ const _x = x + xOffset * openAsNumber + deltaArrow * dx * arrowClientWidth;
89
+ const _y = y + yOffset * openAsNumber + deltaArrow * dy * arrowClientHeight;
90
+
91
+ node.style.transform = `translate3d(${_x}px, ${_y}px, 1px)`;
92
+ }
93
+
94
+ let isOpened = false;
95
+
96
+ function _animate(this: typeof bond.state, node: Element) {
97
+ const isOpen = this.isOpen;
98
+
99
+ const arrowClientWidth = bond?.elements.arrow?.clientWidth ?? 0;
100
+ const arrowClientHeight = bond?.elements.arrow?.clientHeight ?? 0;
101
+
102
+ const _x = openAsNumber * dx;
103
+ const _y = openAsNumber * dy;
104
+
105
+ const getTransformOrigin = () => {
106
+ switch (placement) {
107
+ case 'top':
108
+ case 'top-start':
109
+ case 'top-end':
110
+ return 'bottom';
111
+ case 'bottom':
112
+ case 'bottom-start':
113
+ case 'bottom-end':
114
+ return 'top';
115
+ case 'left':
116
+ case 'left-start':
117
+ case 'left-end':
118
+ return 'right';
119
+ case 'right':
120
+ case 'right-start':
121
+ case 'right-end':
122
+ return 'left';
123
+ default:
124
+ return 'center';
125
+ }
126
+ };
127
+
128
+ const transformOrigin = getTransformOrigin();
129
+
130
+ const from = isOpened ? 1 : 0.95;
131
+
132
+ motion(
133
+ node,
134
+ {
135
+ opacity: openAsNumber,
136
+ y: _y + dy * (!isOpen ? -1 : 0) * (arrowClientHeight + yOffset),
137
+ x: _x + dx * (!isOpen ? -1 : 0) * (arrowClientWidth + xOffset),
138
+ scaleY: dy ? (isOpen ? [from, 1] : [1, 0.8]) : undefined,
139
+ scaleX: dx ? (isOpen ? [from, 1] : [1, 0.8]) : undefined,
140
+ transformOrigin
141
+ },
142
+ { duration: DURATION.fast / 1000 }
143
+ );
144
+
145
+ isOpened = isOpen;
146
+ }
147
+ </script>
148
+
149
+ <Teleport
150
+ portal={portalId ?? 'root.l0'}
151
+ as="div"
152
+ class={[
153
+ 'pointer-events-auto absolute top-0 left-0 h-min w-fit',
154
+ !isOpen && 'pointer-events-none'
155
+ ]}
156
+ initial={_containerInitial?.bind(bond.state)}
157
+ animate={_containerAnimate?.bind(bond.state)}
158
+ {...bond.content({ onchange: _containerInitial })}
159
+ >
160
+ <HtmlAtom
161
+ {bond}
162
+ preset="popover.content"
163
+ class={[
164
+ 'popover-content bg-popover text-popover-foreground border-border rounded-md border p-2 opacity-0 shadow-lg',
165
+ '$preset',
166
+ klass
167
+ ]}
168
+ enter={enter?.bind(bond.state)}
169
+ exit={exit?.bind(bond.state)}
170
+ initial={initial?.bind(bond.state)}
171
+ animate={animate?.bind(bond.state)}
172
+ onmount={onmount?.bind(bond.state)}
173
+ ondestroy={ondestroy?.bind(bond.state)}
174
+ {...restProps}
175
+ >
176
+ {@render children?.({ popover: bond })}
177
+ </HtmlAtom>
178
+ </Teleport>
@@ -15,23 +15,22 @@
15
15
  children = undefined
16
16
  }: PopoverRootProps = $props();
17
17
 
18
- const bondProps = defineState<PopoverStateProps>(
19
- [
20
- defineProperty(
21
- 'open',
22
- () => open,
23
- (v) => {
24
- open = v;
25
- }
26
- ),
27
- defineProperty('disabled', () => disabled),
28
- defineProperty('placement', () => placement),
29
- defineProperty('offset', () => offset),
30
- defineProperty('placements', () => placements ?? []),
31
- defineProperty('portal', () => portal)
32
- ],
33
- () => ({ extend })
34
- );
18
+ const bondProps = defineState<PopoverStateProps>([
19
+ defineProperty(
20
+ 'open',
21
+ () => open,
22
+ (v) => {
23
+ open = v;
24
+ }
25
+ ),
26
+ defineProperty('disabled', () => disabled),
27
+ defineProperty('placement', () => placement),
28
+ defineProperty('offset', () => offset),
29
+ defineProperty('placements', () => placements ?? []),
30
+ defineProperty('portal', () => portal),
31
+ defineProperty('extend', () => extend)
32
+ ]);
33
+
35
34
  const bond = factory(bondProps).share();
36
35
 
37
36
  function _factory(props: typeof bondProps) {
@@ -3,7 +3,6 @@
3
3
  import { Popover as Popover_ } from '.';
4
4
  import Root from '../root/root.svelte';
5
5
  import { clickoutPopover } from './attachments.svelte';
6
- import { animate } from 'motion';
7
6
  import { Button } from '../button';
8
7
 
9
8
  // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
@@ -42,20 +41,6 @@
42
41
  atom.state.close();
43
42
  })}
44
43
  class="bg-card"
45
- animate={function (this, node) {
46
- const isOpen = this.isOpen;
47
-
48
- const m = animate(
49
- node,
50
- {
51
- y: (isOpen ? 0 : -1) * 8,
52
- opacity: +isOpen
53
- },
54
- {
55
- duration: 0.1
56
- }
57
- );
58
- }}
59
44
  >
60
45
  <div>Hello World !</div>
61
46
  <Popover_.Arrow />