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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +176 -739
  3. package/dist/attachments/index.d.ts +1 -0
  4. package/dist/attachments/index.js +1 -0
  5. package/dist/components/accordion/accordion-root.svelte +65 -61
  6. package/dist/components/accordion/accordion.stories.svelte +70 -145
  7. package/dist/components/accordion/item/accordion-item-body.svelte +6 -4
  8. package/dist/components/accordion/item/accordion-item-header.svelte +2 -1
  9. package/dist/components/accordion/item/accordion-item-indicator.svelte +2 -1
  10. package/dist/components/accordion/item/accordion-item-root.svelte +2 -1
  11. package/dist/components/accordion/item/bond.svelte.d.ts +2 -0
  12. package/dist/components/accordion/item/index.d.ts +3 -0
  13. package/dist/components/accordion/item/index.js +3 -0
  14. package/dist/components/accordion/item/motion.svelte.d.ts +15 -0
  15. package/dist/components/accordion/item/motion.svelte.js +30 -0
  16. package/dist/components/accordion/item/types.d.ts +7 -24
  17. package/dist/components/alert/alert-close-button.svelte +32 -36
  18. package/dist/components/alert/alert-description.svelte +1 -1
  19. package/dist/components/alert/alert-description.svelte.d.ts +3 -6
  20. package/dist/components/alert/alert-root.svelte +3 -38
  21. package/dist/components/alert/alert-root.svelte.d.ts +2 -2
  22. package/dist/components/alert/alert.stories.svelte +400 -400
  23. package/dist/components/alert/bond.svelte.d.ts +0 -13
  24. package/dist/components/alert/bond.svelte.js +0 -32
  25. package/dist/components/alert/types.d.ts +8 -32
  26. package/dist/components/atom/html-atom.svelte +93 -261
  27. package/dist/components/atom/types.d.ts +3 -2
  28. package/dist/components/atom/utils.d.ts +37 -0
  29. package/dist/components/atom/utils.js +208 -0
  30. package/dist/components/avatar/avatar.stories.svelte +22 -22
  31. package/dist/components/badge/badge.stories.svelte +12 -12
  32. package/dist/components/badge/badge.svelte +19 -19
  33. package/dist/components/breadcrumb/breadcrumb-item.svelte +1 -1
  34. package/dist/components/breadcrumb/breadcrumb-separator.svelte +5 -1
  35. package/dist/components/breadcrumb/breadcrumb.stories.svelte +16 -16
  36. package/dist/components/button/button.stories.svelte +27 -27
  37. package/dist/components/calendar/calendar-day.svelte +9 -4
  38. package/dist/components/calendar/calendar.stories.svelte +26 -26
  39. package/dist/components/card/card-body.svelte +39 -39
  40. package/dist/components/card/card-footer.svelte +41 -41
  41. package/dist/components/card/card-root.svelte +91 -91
  42. package/dist/components/card/card.stories.svelte +133 -133
  43. package/dist/components/checkbox/checkbox.stories.svelte +22 -22
  44. package/dist/components/checkbox/checkbox.svelte +159 -155
  45. package/dist/components/collapsible/bond.svelte.js +2 -1
  46. package/dist/components/collapsible/collapsible-body.svelte +3 -2
  47. package/dist/components/collapsible/collapsible.stories.svelte +172 -172
  48. package/dist/components/collapsible/motion.svelte.d.ts +6 -0
  49. package/dist/components/collapsible/motion.svelte.js +15 -0
  50. package/dist/components/combobox/atoms.d.ts +3 -3
  51. package/dist/components/combobox/atoms.js +3 -3
  52. package/dist/components/combobox/bond.svelte.d.ts +6 -6
  53. package/dist/components/combobox/bond.svelte.js +3 -26
  54. package/dist/components/combobox/combobox-control.svelte +52 -52
  55. package/dist/components/combobox/{compobox-item.svelte → combobox-item.svelte} +62 -68
  56. package/dist/components/combobox/combobox-item.svelte.d.ts +12 -0
  57. package/dist/components/combobox/combobox-root.svelte +65 -65
  58. package/dist/components/combobox/combobox.stories.svelte +50 -0
  59. package/dist/components/combobox/combobox.stories.svelte.d.ts +3 -0
  60. package/dist/components/combobox/index.d.ts +1 -0
  61. package/dist/components/container/container.stories.svelte +20 -20
  62. package/dist/components/container/container.svelte.d.ts +1 -1
  63. package/dist/components/datagrid/datagrid.stories.svelte +72 -72
  64. package/dist/components/datagrid/tr/bond.svelte.d.ts +4 -2
  65. package/dist/components/datagrid/tr/bond.svelte.js +9 -7
  66. package/dist/components/datagrid/tr/datagrid-tr.svelte +9 -7
  67. package/dist/components/date-picker/bond.svelte.d.ts +15 -5
  68. package/dist/components/date-picker/bond.svelte.js +5 -11
  69. package/dist/components/date-picker/date-picker-calendar.svelte +2 -2
  70. package/dist/components/date-picker/date-picker-root.svelte +95 -95
  71. package/dist/components/date-picker/date-picker.stories.svelte +35 -35
  72. package/dist/components/dialog/bond.svelte.d.ts +13 -3
  73. package/dist/components/dialog/bond.svelte.js +52 -6
  74. package/dist/components/dialog/dialog-content.svelte +2 -20
  75. package/dist/components/dialog/dialog-root.svelte +3 -22
  76. package/dist/components/dialog/dialog.stories.svelte +64 -64
  77. package/dist/components/dialog/motion.svelte.d.ts +13 -0
  78. package/dist/components/dialog/motion.svelte.js +44 -0
  79. package/dist/components/drawer/attachments.svelte.d.ts +1 -1
  80. package/dist/components/drawer/attachments.svelte.js +1 -3
  81. package/dist/components/drawer/bond.svelte.d.ts +30 -9
  82. package/dist/components/drawer/bond.svelte.js +80 -24
  83. package/dist/components/drawer/drawer-content.svelte +49 -57
  84. package/dist/components/drawer/drawer-root.svelte +5 -4
  85. package/dist/components/drawer/drawer.stories.svelte +141 -212
  86. package/dist/components/drawer/index.d.ts +2 -0
  87. package/dist/components/drawer/index.js +2 -0
  88. package/dist/components/drawer/motion.d.ts +15 -0
  89. package/dist/components/drawer/motion.js +28 -0
  90. package/dist/components/dropdown/atoms.d.ts +1 -1
  91. package/dist/components/dropdown/atoms.js +1 -1
  92. package/dist/components/dropdown/bond.svelte.d.ts +22 -19
  93. package/dist/components/dropdown/bond.svelte.js +29 -53
  94. package/dist/components/dropdown/dropdown-root.svelte +7 -1
  95. package/dist/components/dropdown/dropdown-values.svelte +17 -17
  96. package/dist/components/dropdown/dropdown-values.svelte.d.ts +1 -2
  97. package/dist/components/dropdown/dropdown.stories.svelte +13 -10
  98. package/dist/components/dropdown/index.d.ts +2 -0
  99. package/dist/components/dropdown/index.js +1 -0
  100. package/dist/components/dropdown/item/attachments.svelte.d.ts +2 -2
  101. package/dist/components/dropdown/item/attachments.svelte.js +2 -2
  102. package/dist/components/dropdown/item/controller.svelte.d.ts +34 -0
  103. package/dist/components/dropdown/item/controller.svelte.js +82 -0
  104. package/dist/components/dropdown/item/dropdown-item.svelte +109 -102
  105. package/dist/components/dropdown/item/dropdown-item.svelte.d.ts +13 -28
  106. package/dist/components/dropdown/item/index.d.ts +3 -0
  107. package/dist/components/dropdown/item/index.js +3 -0
  108. package/dist/components/dropdown/item/types.d.ts +29 -0
  109. package/dist/components/dropdown/item/types.js +1 -0
  110. package/dist/components/form/form.stories.svelte +96 -96
  111. package/dist/components/image/image.stories.svelte +20 -20
  112. package/dist/components/input/input.stories.svelte +35 -35
  113. package/dist/components/label/label.stories.svelte +15 -15
  114. package/dist/components/lazy/lazy.stories.svelte +28 -28
  115. package/dist/components/link/link.stories.svelte +15 -15
  116. package/dist/components/list/list-item.svelte +2 -2
  117. package/dist/components/menu/atoms.d.ts +9 -3
  118. package/dist/components/menu/atoms.js +9 -3
  119. package/dist/components/menu/bond.svelte.d.ts +54 -0
  120. package/dist/components/menu/bond.svelte.js +132 -0
  121. package/dist/components/menu/index.d.ts +3 -1
  122. package/dist/components/menu/index.js +2 -1
  123. package/dist/components/menu/item/controller.svelte.d.ts +26 -0
  124. package/dist/components/menu/item/controller.svelte.js +69 -0
  125. package/dist/components/menu/item/index.d.ts +2 -0
  126. package/dist/components/menu/item/index.js +2 -0
  127. package/dist/components/menu/item/menu-item.svelte +103 -0
  128. package/dist/components/menu/item/menu-item.svelte.d.ts +31 -0
  129. package/dist/components/menu/item/types.d.ts +62 -0
  130. package/dist/components/menu/item/types.js +1 -0
  131. package/dist/components/menu/{menu-list.svelte → menu-content.svelte} +40 -40
  132. package/dist/components/menu/{menu-list.svelte.d.ts → menu-content.svelte.d.ts} +3 -3
  133. package/dist/components/menu/menu-root.svelte +15 -0
  134. package/dist/components/menu/menu-root.svelte.d.ts +8 -0
  135. package/dist/components/menu/menu.stories.svelte +5 -5
  136. package/dist/components/menu/types.d.ts +0 -7
  137. package/dist/components/popover/bond.svelte.d.ts +18 -8
  138. package/dist/components/popover/bond.svelte.js +76 -40
  139. package/dist/components/popover/motion.d.ts +6 -0
  140. package/dist/components/popover/motion.js +56 -0
  141. package/dist/components/popover/popover-arrow.svelte +111 -111
  142. package/dist/components/popover/popover-content.svelte +137 -175
  143. package/dist/components/popover/popover-indicator.svelte +44 -44
  144. package/dist/components/popover/popover-root.svelte +48 -48
  145. package/dist/components/popover/popover.stories.svelte +37 -49
  146. package/dist/components/popover/types.d.ts +9 -7
  147. package/dist/components/portal/active-portal.svelte +12 -5
  148. package/dist/components/portal/active-portal.svelte.d.ts +2 -9
  149. package/dist/components/portal/portal-root.svelte +1 -8
  150. package/dist/components/portal/portal-root.svelte.d.ts +4 -6
  151. package/dist/components/portal/teleport.svelte +1 -2
  152. package/dist/components/portal/teleport.svelte.d.ts +3 -4
  153. package/dist/components/qr-code/qr-code.stories.svelte +18 -18
  154. package/dist/components/radio/radio-group.stories.svelte +41 -41
  155. package/dist/components/radio/radio.stories.svelte +17 -17
  156. package/dist/components/radio/radio.svelte +109 -109
  157. package/dist/components/radio/types.d.ts +98 -0
  158. package/dist/components/radio/types.js +2 -0
  159. package/dist/components/root/index.d.ts +1 -0
  160. package/dist/components/root/index.js +1 -0
  161. package/dist/components/root/l0-portal.svelte +8 -0
  162. package/dist/components/{radio/types.svelte.d.ts → root/l0-portal.svelte.d.ts} +3 -3
  163. package/dist/components/root/l1-portal.svelte +7 -0
  164. package/dist/components/root/l1-portal.svelte.d.ts +26 -0
  165. package/dist/components/root/root.css +119 -119
  166. package/dist/components/root/root.svelte +26 -44
  167. package/dist/components/root/root.svelte.d.ts +2 -6
  168. package/dist/components/root/toasts-portal.svelte +7 -0
  169. package/dist/components/root/toasts-portal.svelte.d.ts +26 -0
  170. package/dist/components/root/types.d.ts +17 -0
  171. package/dist/components/scrollable/scrollable-root.svelte.d.ts +2 -2
  172. package/dist/components/scrollable/scrollable.stories.svelte +116 -116
  173. package/dist/components/sidebar/index.d.ts +2 -0
  174. package/dist/components/sidebar/index.js +2 -0
  175. package/dist/components/sidebar/motion.svelte.d.ts +11 -0
  176. package/dist/components/sidebar/motion.svelte.js +16 -0
  177. package/dist/components/sidebar/sidebar-content.svelte +40 -50
  178. package/dist/components/sidebar/sidebar-root.svelte +39 -39
  179. package/dist/components/sidebar/sidebar.stories.svelte +43 -43
  180. package/dist/components/sidebar/types.d.ts +2 -12
  181. package/dist/components/tabs/tabs.stories.svelte +56 -56
  182. package/dist/components/textarea/atoms.d.ts +1 -0
  183. package/dist/components/textarea/atoms.js +1 -0
  184. package/dist/components/textarea/textarea-input.svelte +4 -1
  185. package/dist/components/textarea/textarea-root.svelte +2 -2
  186. package/dist/components/textarea/textarea-root.svelte.d.ts +2 -0
  187. package/dist/components/tooltip/tooltip-trigger.svelte +39 -39
  188. package/dist/components/tooltip/tooltip-trigger.svelte.d.ts +1 -0
  189. package/dist/components/tooltip/tooltip.stories.svelte +32 -32
  190. package/dist/components/tree/index.d.ts +1 -0
  191. package/dist/components/tree/index.js +1 -0
  192. package/dist/components/tree/motion.svelte.d.ts +6 -0
  193. package/dist/components/tree/motion.svelte.js +14 -0
  194. package/dist/components/tree/tree-body.svelte +4 -3
  195. package/dist/components/tree/tree.stories.svelte +142 -142
  196. package/dist/context/preset.svelte.d.ts +3 -1
  197. package/dist/icons/icon-copy.svelte +6 -0
  198. package/dist/icons/icon-copy.svelte.d.ts +26 -0
  199. package/dist/utils/dom.svelte.d.ts +2 -0
  200. package/dist/utils/dom.svelte.js +21 -0
  201. package/dist/utils/function.d.ts +1 -1
  202. package/dist/utils/promise.svelte.d.ts +5 -0
  203. package/dist/utils/promise.svelte.js +20 -0
  204. package/package.json +4 -3
  205. package/dist/components/combobox/compobox-item.svelte.d.ts +0 -34
  206. package/dist/components/combobox/compobox.stories.svelte +0 -51
  207. package/dist/components/combobox/compobox.stories.svelte.d.ts +0 -3
  208. package/dist/components/dropdown/item/bond.svelte.d.ts +0 -42
  209. package/dist/components/dropdown/item/bond.svelte.js +0 -99
  210. package/dist/components/menu/menu-item.svelte +0 -51
  211. package/dist/components/menu/menu-item.svelte.d.ts +0 -36
  212. package/dist/components/radio/types.svelte +0 -0
  213. package/llm/composition.md +0 -395
  214. package/llm/crafting.md +0 -838
  215. package/llm/motion.md +0 -970
  216. package/llm/philosophy.md +0 -23
  217. package/llm/preset-variant-integration.md +0 -516
  218. package/llm/preset.md +0 -383
  219. package/llm/styling.md +0 -216
  220. package/llm/usage.md +0 -46
  221. package/llm/variants.md +0 -1259
@@ -1,212 +1,141 @@
1
- <script module>
2
- import { animate } from 'motion';
3
- import { defineMeta } from '@storybook/addon-svelte-csf';
4
- import { Drawer as Drawer_ } from '.';
5
- import { DrawerBond } from './bond.svelte';
6
- import { on } from '../../attachments/event.svelte';
7
-
8
- // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
9
- const { Story } = defineMeta({
10
- title: 'Atoms/Drawer',
11
- // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
12
-
13
- parameters: {
14
- // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
15
- layout: 'fullscreen'
16
- },
17
- args: {}
18
- });
19
- </script>
20
-
21
- <script lang="ts">
22
- let isOpen = $state(false);
23
- </script>
24
-
25
- <Story name="Left" args={{}}>
26
- <Drawer_.Root
27
- class=" border backdrop-blur-md backdrop-grayscale-100"
28
- bind:open={isOpen}
29
- initial={(node) => {
30
- animate(node, { opacity: +isOpen }, { duration: 0 });
31
- }}
32
- animate={(node) => {
33
- animate(node, { opacity: +isOpen }, { duration: 0.3 }).finished.then(() => {
34
- if (!isOpen) node.close?.();
35
- });
36
- }}
37
- {@attach (node) => {
38
- const bond = DrawerBond.get();
39
-
40
- return on('click', (ev) => {
41
- bond?.state?.close?.();
42
- })(node);
43
- }}
44
- >
45
- <Drawer_.Content
46
- class="border-border flex min-h-full w-md flex-col border-r p-8 whitespace-nowrap shadow-md"
47
- initial={(node) => {
48
- animate(node, { x: isOpen ? 0 : -100 + '%' } as any, { duration: 0 });
49
- }}
50
- animate={(node) => {
51
- animate(node, { x: isOpen ? 0 : -100 + '%' } as any, { duration: 0.2, ease: 'easeOut' });
52
- }}
53
- >
54
- <Drawer_.Header class="flex items-center justify-between">
55
- <div class="flex flex-col">
56
- <Drawer_.Title class="text-lg font-semibold">Drawer Title</Drawer_.Title>
57
- <Drawer_.Description class="text-sm break-all whitespace-break-spaces text-neutral-500"
58
- >Ac bibendum laoreet lacinia purus duis. Hendrerit quam purus maecenas tincidunt letius
59
- finibus vel tortor sociosqu proin vulputate. Consectetur velit eleifend purus mi
60
- pulvinar si tristique litora mollis lobortis.</Drawer_.Description
61
- >
62
- </div>
63
- </Drawer_.Header>
64
- <div>
65
- <div>Svelte Fluent</div>
66
- </div>
67
- </Drawer_.Content>
68
- </Drawer_.Root>
69
-
70
- <button
71
- class="bg-red-500 p-2"
72
- onclick={() => {
73
- isOpen = !isOpen;
74
- }}>Open</button
75
- >
76
- </Story>
77
-
78
- <Story name="Top" args={{}}>
79
- <Drawer_.Root
80
- class=" border backdrop-blur-md backdrop-grayscale-100"
81
- bind:open={isOpen}
82
- initial={(node) => animate(node, { opacity: +isOpen }, { duration: 0 })}
83
- animate={(node) => {
84
- animate(node, { opacity: +isOpen }, { duration: 0.3 }).finished.then(() => {
85
- if (!isOpen) node.close?.();
86
- });
87
- }}
88
- {@attach (node) => {
89
- const bond = DrawerBond.get();
90
-
91
- return on('click', (ev) => {
92
- bond?.state?.close?.();
93
- })(node);
94
- }}
95
- >
96
- <Drawer_.Content
97
- class="border-border flex w-md min-w-full flex-col border-b p-8 whitespace-nowrap shadow-md"
98
- initial={(node) => {
99
- animate(node, { y: isOpen ? 0 : -100 + '%' } as any, { duration: 0 });
100
- }}
101
- animate={(node) => {
102
- animate(node, { y: isOpen ? 0 : -100 + '%' } as any, { duration: 0.2, ease: 'easeOut' });
103
- }}
104
- >
105
- <div>
106
- <div>Svelte Fluent</div>
107
- </div>
108
- </Drawer_.Content>
109
- </Drawer_.Root>
110
-
111
- <button
112
- class="bg-red-500 p-2"
113
- onclick={() => {
114
- isOpen = !isOpen;
115
- }}>Open</button
116
- >
117
- </Story>
118
-
119
- <Story name="Right" args={{}}>
120
- <Drawer_.Root
121
- class=" border backdrop-blur-md backdrop-grayscale-100"
122
- bind:open={isOpen}
123
- initial={(node) => {
124
- animate(node, { opacity: +isOpen }, { duration: 0 });
125
- }}
126
- animate={(node) => {
127
- animate(node, { opacity: +isOpen }, { duration: 0.3 }).finished.then(() => {
128
- if (!isOpen) node.close?.();
129
- });
130
- }}
131
- {@attach (node) => {
132
- const bond = DrawerBond.get();
133
-
134
- return on('click', (ev) => {
135
- bond?.state?.close?.();
136
- })(node);
137
- }}
138
- >
139
- <Drawer_.Content
140
- class="border-border shadow-foreground/50 inset-y-0 flex w-md flex-col border-l p-8 whitespace-nowrap shadow-lg"
141
- initial={(node) => {
142
- animate(node, { x: isOpen ? 0 : 100 + '%', right: 0 } as any, { duration: 0 });
143
- }}
144
- animate={(node) => {
145
- animate(node, { x: isOpen ? 0 : 100 + '%', right: 0 } as any, {
146
- duration: 0.2,
147
- ease: 'easeOut'
148
- });
149
- }}
150
- {@attach on('click', (ev) => {
151
- ev.stopPropagation();
152
- })}
153
- >
154
- <div>
155
- <div>Svelte Fluent</div>
156
- </div>
157
- </Drawer_.Content>
158
- </Drawer_.Root>
159
-
160
- <button
161
- class="bg-red-500 p-2"
162
- onclick={() => {
163
- isOpen = !isOpen;
164
- }}>Open</button
165
- >
166
- </Story>
167
-
168
- <Story name="Bottom" args={{}}>
169
- <Drawer_.Root
170
- class=" border backdrop-blur-md backdrop-grayscale-100"
171
- bind:open={isOpen}
172
- initial={(node) => {
173
- animate(node, { opacity: +isOpen }, { duration: 0 });
174
- }}
175
- animate={(node) => {
176
- animate(node, { opacity: +isOpen }, { duration: 0.3 }).finished.then(() => {
177
- if (!isOpen) node.close?.();
178
- });
179
- }}
180
- {@attach (node) => {
181
- const bond = DrawerBond.get();
182
-
183
- return on('click', (ev) => {
184
- bond?.state?.close?.();
185
- })(node);
186
- }}
187
- >
188
- <Drawer_.Content
189
- class="border-border flex w-md min-w-full flex-col border-t p-8 whitespace-nowrap shadow-md"
190
- initial={(node) => {
191
- animate(node, { y: isOpen ? 0 : 100 + '%', bottom: 0 } as any, { duration: 0 });
192
- }}
193
- animate={(node) => {
194
- animate(node, { y: isOpen ? 0 : 100 + '%', bottom: 0 } as any, {
195
- duration: 0.2,
196
- ease: 'easeOut'
197
- });
198
- }}
199
- >
200
- <div>
201
- <div>Svelte Fluent</div>
202
- </div>
203
- </Drawer_.Content>
204
- </Drawer_.Root>
205
-
206
- <button
207
- class="bg-red-500 p-2"
208
- onclick={() => {
209
- isOpen = !isOpen;
210
- }}>Open</button
211
- >
212
- </Story>
1
+ <script module>
2
+ import { animate } from 'motion';
3
+ import { defineMeta } from '@storybook/addon-svelte-csf';
4
+ import { clickoutDrawer, Drawer as Drawer_ } from '.';
5
+
6
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
+ const { Story } = defineMeta({
8
+ title: 'Atoms/Drawer',
9
+ // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
10
+
11
+ parameters: {
12
+ // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
13
+ layout: 'fullscreen'
14
+ },
15
+ args: {}
16
+ });
17
+ </script>
18
+
19
+ <script lang="ts">
20
+ import { animateDrawerContent, animateDrawerRoot } from './motion';
21
+
22
+ let isOpen = $state(false);
23
+ </script>
24
+
25
+ <Story name="Left" args={{}}>
26
+ <Drawer_.Root
27
+ bind:open={isOpen}
28
+ class=" border backdrop-blur-md backdrop-grayscale-100"
29
+ animate={animateDrawerRoot({})}
30
+ >
31
+ <Drawer_.Content
32
+ class="border-border flex min-h-full w-md flex-col border-r p-8 whitespace-nowrap shadow-md"
33
+ animate={animateDrawerContent({ ease: 'easeOut', side: 'left' })}
34
+ >
35
+ <Drawer_.Header class="flex items-center justify-between">
36
+ <div class="flex flex-col">
37
+ <Drawer_.Title class="text-lg font-semibold">Drawer Title</Drawer_.Title>
38
+ <Drawer_.Description class="text-sm break-all whitespace-break-spaces text-neutral-500"
39
+ >Ac bibendum laoreet lacinia purus duis. Hendrerit quam purus maecenas tincidunt letius
40
+ finibus vel tortor sociosqu proin vulputate. Consectetur velit eleifend purus mi
41
+ pulvinar si tristique litora mollis lobortis.</Drawer_.Description
42
+ >
43
+ </div>
44
+ </Drawer_.Header>
45
+ <div>
46
+ <div>Svelte Fluent</div>
47
+ </div>
48
+ </Drawer_.Content>
49
+ </Drawer_.Root>
50
+
51
+ <button
52
+ class="bg-red-500 p-2"
53
+ onclick={() => {
54
+ isOpen = !isOpen;
55
+ }}>Open</button
56
+ >
57
+ </Story>
58
+
59
+ <Story name="Top" args={{}}>
60
+ <Drawer_.Root
61
+ bind:open={isOpen}
62
+ class=" border backdrop-blur-md backdrop-grayscale-100"
63
+ animate={animateDrawerRoot({})}
64
+ >
65
+ <Drawer_.Content
66
+ class="border-border flex w-md min-w-full flex-col border-b p-8 whitespace-nowrap shadow-md"
67
+ animate={animateDrawerContent({ ease: 'easeOut', side: 'top' })}
68
+ {@attach clickoutDrawer((_, bond) => {
69
+ bond?.state?.close?.();
70
+ })}
71
+ >
72
+ <div>
73
+ <div>Svelte Fluent</div>
74
+ </div>
75
+ </Drawer_.Content>
76
+ </Drawer_.Root>
77
+
78
+ <button
79
+ class="bg-red-500 p-2"
80
+ onclick={() => {
81
+ isOpen = !isOpen;
82
+ }}>Open</button
83
+ >
84
+ </Story>
85
+
86
+ <Story name="Right" args={{}}>
87
+ <Drawer_.Root
88
+ bind:open={isOpen}
89
+ class=" border backdrop-blur-md backdrop-grayscale-100"
90
+ animate={animateDrawerRoot({})}
91
+ >
92
+ <Drawer_.Content
93
+ class="border-border shadow-foreground/50 inset-y-0 flex w-md flex-col border-l p-8 whitespace-nowrap shadow-sm"
94
+ animate={animateDrawerContent({ ease: 'easeOut', side: 'right' })}
95
+ {@attach clickoutDrawer((_, bond) => {
96
+ bond?.state?.close?.();
97
+ })}
98
+ >
99
+ <div>
100
+ <div>Svelte Fluent</div>
101
+ </div>
102
+ </Drawer_.Content>
103
+ </Drawer_.Root>
104
+
105
+ <button
106
+ class="bg-red-500 p-2"
107
+ onclick={() => {
108
+ isOpen = !isOpen;
109
+ }}>Open</button
110
+ >
111
+ </Story>
112
+
113
+ <Story name="Bottom" args={{}}>
114
+ <Drawer_.Root
115
+ bind:open={isOpen}
116
+ class=" border backdrop-blur-md backdrop-grayscale-100"
117
+ initial={(node) => {
118
+ animate(node, { opacity: +isOpen }, { duration: 0 });
119
+ }}
120
+ animate={animateDrawerRoot()}
121
+ >
122
+ <Drawer_.Content
123
+ class="border-border flex w-md min-w-full flex-col border-t p-8 whitespace-nowrap shadow-md"
124
+ animate={animateDrawerContent({ ease: 'easeOut', side: 'bottom' })}
125
+ {@attach clickoutDrawer((_, bond) => {
126
+ bond?.state?.close?.();
127
+ })}
128
+ >
129
+ <div>
130
+ <div>Svelte Fluent</div>
131
+ </div>
132
+ </Drawer_.Content>
133
+ </Drawer_.Root>
134
+
135
+ <button
136
+ class="bg-red-500 p-2"
137
+ onclick={() => {
138
+ isOpen = !isOpen;
139
+ }}>Open</button
140
+ >
141
+ </Story>
@@ -1,4 +1,6 @@
1
1
  export * as Drawer from './atoms';
2
2
  export { clickoutDrawer, closeDrawer, openDrawer, drawer, toggleDrawer } from './attachments.svelte';
3
3
  export { DrawerBond, type DrawerBondElements, type DrawerBondProps, DrawerBondState } from './bond.svelte';
4
+ export * from './attachments.svelte';
5
+ export * from './motion';
4
6
  export * from './types';
@@ -1,4 +1,6 @@
1
1
  export * as Drawer from './atoms';
2
2
  export { clickoutDrawer, closeDrawer, openDrawer, drawer, toggleDrawer } from './attachments.svelte';
3
3
  export { DrawerBond, DrawerBondState } from './bond.svelte';
4
+ export * from './attachments.svelte';
5
+ export * from './motion';
4
6
  export * from './types';
@@ -0,0 +1,15 @@
1
+ import { type Easing } from 'motion';
2
+ type AnimateDrawerContentParams = {
3
+ duration?: number;
4
+ delay?: number;
5
+ ease?: Easing | Easing[];
6
+ side?: 'left' | 'right' | 'top' | 'bottom';
7
+ };
8
+ export declare function animateDrawerContent(params: AnimateDrawerContentParams): (node: HTMLElement) => void;
9
+ type AnimateDrawerRootParams = {
10
+ duration?: number;
11
+ delay?: number;
12
+ ease?: Easing | Easing[];
13
+ };
14
+ export declare function animateDrawerRoot(params?: AnimateDrawerRootParams): (node: HTMLElement) => void;
15
+ export {};
@@ -0,0 +1,28 @@
1
+ import { animate } from 'motion';
2
+ import { DURATION } from '../../shared';
3
+ import { DrawerBond } from '.';
4
+ export function animateDrawerContent(params) {
5
+ const { duration = DURATION.fast / 1000, delay = 0, ease = 'easeInOut', side = 'left' } = params;
6
+ const bond = DrawerBond.get();
7
+ const mainProp = side === 'left' || side === 'right' ? 'x' : 'y';
8
+ const crossProp = mainProp === 'x' ? 'y' : 'x';
9
+ const d = side === 'left' || side === 'top' ? -1 : 1;
10
+ return (node) => {
11
+ const isOpen = bond?.state.props.open ?? false;
12
+ animate(node, {
13
+ [mainProp]: isOpen ? 0 : d * 100 + '%',
14
+ [crossProp]: 0,
15
+ left: 'unset',
16
+ right: 'unset',
17
+ [side]: 0
18
+ }, { duration, ease, delay });
19
+ };
20
+ }
21
+ export function animateDrawerRoot(params = {}) {
22
+ const { duration = DURATION.fast / 1000, delay = 0, ease = 'easeInOut' } = params;
23
+ return (node) => {
24
+ const bond = DrawerBond.get();
25
+ const isOpen = bond?.state.props.open ?? false;
26
+ animate(node, { opacity: +isOpen }, { duration, ease, delay });
27
+ };
28
+ }
@@ -6,4 +6,4 @@ export { default as Query } from './dropdown-query.svelte';
6
6
  export { default as Value } from './dropdown-value.svelte';
7
7
  export { default as Values } from './dropdown-values.svelte';
8
8
  export { Arrow, Indicator } from '../popover/atoms';
9
- export { List } from '../menu/atoms';
9
+ export { Content, List, Divider, Title, Group } from '../menu/atoms';
@@ -6,4 +6,4 @@ export { default as Query } from './dropdown-query.svelte';
6
6
  export { default as Value } from './dropdown-value.svelte';
7
7
  export { default as Values } from './dropdown-values.svelte';
8
8
  export { Arrow, Indicator } from '../popover/atoms';
9
- export { List } from '../menu/atoms';
9
+ export { Content, List, Divider, Title, Group } from '../menu/atoms';
@@ -1,27 +1,36 @@
1
- import { PopoverBond, PopoverState, type PopoverDomElements, type PopoverStateProps } from '../popover/bond.svelte';
2
- import type { DropdownItemBond } from './item/bond.svelte';
3
- export type DropdownStateProps = PopoverStateProps & {
1
+ import { MenuBond, MenuBondState, type MenuBondElements, type MenuBondProps } from '../menu/bond.svelte';
2
+ import type { DropdownItemController } from './item/controller.svelte';
3
+ export type DropdownStateProps = MenuBondProps & {
4
4
  values?: string[];
5
5
  value?: string;
6
6
  multiple?: boolean;
7
7
  keys?: string[];
8
8
  onquerychange?: (query: string) => void;
9
9
  };
10
- export type DropdownBondElements = PopoverDomElements & {
10
+ export type DropdownBondElements = MenuBondElements & {
11
11
  placeholder?: HTMLElement;
12
12
  };
13
- export declare class DropdownBond<Props extends DropdownStateProps = DropdownStateProps, State extends DropdownBondState<Props> = DropdownBondState<Props>, Elements extends DropdownBondElements = DropdownBondElements> extends PopoverBond<Props, State, Elements> {
13
+ export declare class DropdownBond<Props extends DropdownStateProps = DropdownStateProps, State extends DropdownBondState<Props> = DropdownBondState<Props>, Elements extends DropdownBondElements = DropdownBondElements> extends MenuBond<Props, State, Elements> {
14
14
  constructor(state: State);
15
- content(props?: Record<string, unknown>): {
16
- id: string;
15
+ content(): {
17
16
  role: string;
17
+ 'aria-multiselectable': boolean;
18
+ 'aria-activedescendant': string | undefined;
19
+ 'aria-orientation': "vertical";
20
+ onkeydown: (ev: KeyboardEvent) => void;
21
+ id: string;
18
22
  'aria-modal': boolean;
19
23
  'aria-labelledby': string;
20
- 'aria-controlledby': string;
24
+ inert: boolean | undefined;
25
+ tabindex: number;
21
26
  'data-atom': string;
22
27
  'data-kind': string;
23
28
  'data-active': boolean;
24
29
  };
30
+ item(): {
31
+ role: string;
32
+ onkeyup: (ev: KeyboardEvent) => void;
33
+ };
25
34
  placeholder(): {
26
35
  [x: symbol]: (node: HTMLElement) => void;
27
36
  id: string;
@@ -29,21 +38,15 @@ export declare class DropdownBond<Props extends DropdownStateProps = DropdownSta
29
38
  'data-atom': string;
30
39
  'data-kind': string;
31
40
  };
32
- static getContext<Props extends DropdownStateProps = DropdownStateProps, State extends DropdownBondState<Props> = DropdownBondState<Props>, Elements extends PopoverDomElements = PopoverDomElements>(): DropdownBond<Props, State, Elements> | undefined;
33
- static setContext<Props extends DropdownStateProps = DropdownStateProps, State extends DropdownBondState<Props> = DropdownBondState<Props>, Elements extends PopoverDomElements = PopoverDomElements>(context: DropdownBond<Props, State, Elements>): DropdownBond<Props, State, Elements>;
41
+ static get<Props extends DropdownStateProps = DropdownStateProps, State extends DropdownBondState<Props> = DropdownBondState<Props>, Elements extends DropdownBondElements = DropdownBondElements>(): DropdownBond<Props, State, Elements> | undefined;
42
+ static set<Props extends DropdownStateProps = DropdownStateProps, State extends DropdownBondState<Props> = DropdownBondState<Props>, Elements extends DropdownBondElements = DropdownBondElements>(context: DropdownBond<Props, State, Elements>): DropdownBond<Props, State, Elements>;
34
43
  }
35
- export declare class DropdownBondState<Props extends DropdownStateProps = DropdownStateProps> extends PopoverState<Props> {
44
+ export declare class DropdownBondState<Props extends DropdownStateProps = DropdownStateProps> extends MenuBondState<Props> {
36
45
  #private;
37
- constructor(props: () => DropdownStateProps);
38
- get selectedItems(): DropdownItemBond<unknown>[];
39
- get highlightedItem(): DropdownItemBond<unknown> | null;
46
+ constructor(props: () => Props);
47
+ get selectedItems(): DropdownItemController<unknown>[];
40
48
  get query(): string;
41
49
  set query(value: string);
42
- mountItem<I>(id: string, item: DropdownItemBond<I>): () => void;
43
- unmountItem(id: string): void;
44
- item(id: string): DropdownItemBond<unknown> | undefined;
45
50
  select(ids: string[]): void;
46
51
  unselect(ids: string[]): void;
47
- highlightNextItem(): void;
48
- highlightPreviousItem(): void;
49
52
  }
@@ -1,23 +1,33 @@
1
- import { SvelteMap } from 'svelte/reactivity';
2
- import { PopoverBond, PopoverState } from '../popover/bond.svelte';
3
1
  import { untrack } from 'svelte';
4
2
  import { createAttachmentKey } from 'svelte/attachments';
3
+ import { MenuBond, MenuBondState } from '../menu/bond.svelte';
5
4
  const DROPDOWN_ELEMENTS_KIND = {
6
5
  placeholder: 'dropdown-placeholder',
7
6
  arrow: 'popover-arrow',
8
- overlay: 'popover-overlay',
9
- trigger: 'popover-trigger'
7
+ trigger: 'popover-trigger',
8
+ content: 'popover-content',
9
+ indicator: 'popover-indicator'
10
10
  };
11
- export class DropdownBond extends PopoverBond {
11
+ export class DropdownBond extends MenuBond {
12
12
  constructor(state) {
13
13
  super(state);
14
14
  }
15
- content(props) {
15
+ content() {
16
16
  const isMultiselect = this.state.props.multiple ?? false;
17
- return super.content({
17
+ const highlightedId = this.state.highlightedItem?.id;
18
+ return {
19
+ ...super.content(),
20
+ role: 'listbox',
18
21
  'aria-multiselectable': isMultiselect,
19
- ...props
20
- });
22
+ 'aria-activedescendant': highlightedId ? `item-${highlightedId}` : undefined,
23
+ 'aria-orientation': 'vertical'
24
+ };
25
+ }
26
+ item() {
27
+ return {
28
+ ...super.item(),
29
+ role: 'option'
30
+ };
21
31
  }
22
32
  placeholder() {
23
33
  const id = [DROPDOWN_ELEMENTS_KIND.placeholder, this.id].join('-');
@@ -33,36 +43,24 @@ export class DropdownBond extends PopoverBond {
33
43
  }
34
44
  // static get = getDropdownContext;
35
45
  // static set = setDropdownContext;
36
- static getContext() {
37
- return PopoverBond.get();
46
+ static get() {
47
+ return MenuBond.get();
38
48
  }
39
- static setContext(context) {
40
- return PopoverBond.set(context);
49
+ static set(context) {
50
+ return MenuBond.set(context);
41
51
  }
42
52
  }
43
- export class DropdownBondState extends PopoverState {
44
- // eslint-disable-next-line svelte/prefer-svelte-reactivity
45
- #keys = new Set();
46
- #items = new SvelteMap();
47
- #selectedItems = $derived(this.props.values?.map((value) => this.#items.get(value)).filter(Boolean) ?? []);
48
- #index = $state(-1);
49
- #highlightedItem = $derived(this.#items.values().toArray()[this.#index] ?? null);
53
+ export class DropdownBondState extends MenuBondState {
54
+ #selectedItems = $derived(this.props.values
55
+ ?.map((value) => this.items.get(value))
56
+ .filter(Boolean) ?? []);
50
57
  #query = $state('');
51
58
  constructor(props) {
52
59
  super(props);
53
- $effect(() => {
54
- this.#keys.clear();
55
- for (const key of this.props.keys ?? []) {
56
- this.#keys.add(key);
57
- }
58
- });
59
60
  }
60
61
  get selectedItems() {
61
62
  return this.#selectedItems;
62
63
  }
63
- get highlightedItem() {
64
- return this.#highlightedItem;
65
- }
66
64
  get query() {
67
65
  return this.#query;
68
66
  }
@@ -70,18 +68,6 @@ export class DropdownBondState extends PopoverState {
70
68
  this.#query = value;
71
69
  this.props.onquerychange?.(value);
72
70
  }
73
- mountItem(id, item) {
74
- this.#items.set(id, item);
75
- return () => this.unmountItem(id);
76
- }
77
- unmountItem(id) {
78
- if (this.#keys.has(id))
79
- return; // keep the item if it's still in the data source
80
- this.#items.delete(id);
81
- }
82
- item(id) {
83
- return this.#items.get(id);
84
- }
85
71
  select(ids) {
86
72
  if (untrack(() => this.props.multiple)) {
87
73
  // eslint-disable-next-line svelte/prefer-svelte-reactivity
@@ -89,7 +75,8 @@ export class DropdownBondState extends PopoverState {
89
75
  this.props.values = [...sequence];
90
76
  }
91
77
  else {
92
- this.props.values = [ids[0]].filter(Boolean);
78
+ const value = ids[0];
79
+ this.props.values = value ? [value] : [];
93
80
  }
94
81
  }
95
82
  unselect(ids) {
@@ -100,15 +87,4 @@ export class DropdownBondState extends PopoverState {
100
87
  }
101
88
  this.props.values = [...sequence];
102
89
  }
103
- highlightNextItem() {
104
- const length = this.#items.size;
105
- this.#index = Math.min((this.#index + 1) % length, length - 1);
106
- }
107
- highlightPreviousItem() {
108
- if (this.#index <= 0) {
109
- this.#index = this.#items.size - 1;
110
- return;
111
- }
112
- this.#index = Math.max(this.#index - 1, 0);
113
- }
114
90
  }
@@ -47,13 +47,19 @@
47
47
  const bond = factory(bondProps).share();
48
48
 
49
49
  function _factory(props: typeof bondProps) {
50
- const bondState = new DropdownBondState<T>(() => props);
50
+ const bondState = new DropdownBondState(() => props);
51
51
  return new DropdownBond(bondState);
52
52
  }
53
53
 
54
54
  export function getBond() {
55
55
  return bond;
56
56
  }
57
+
58
+ $effect(() => {
59
+ return () => {
60
+ bond.destroy();
61
+ };
62
+ });
57
63
  </script>
58
64
 
59
65
  {@render children?.({ dropdown: bond })}