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

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 (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +289 -853
  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 -65
  6. package/dist/components/accordion/accordion.stories.svelte +70 -70
  7. package/dist/components/accordion/item/accordion-item-body.svelte +44 -44
  8. package/dist/components/accordion/item/accordion-item-header.svelte +51 -51
  9. package/dist/components/accordion/item/accordion-item-indicator.svelte +51 -51
  10. package/dist/components/accordion/item/accordion-item-root.svelte +66 -66
  11. package/dist/components/alert/alert-close-button.svelte +66 -66
  12. package/dist/components/alert/alert-description.svelte +42 -42
  13. package/dist/components/alert/alert-root.svelte +68 -68
  14. package/dist/components/atom/html-atom.svelte +26 -194
  15. package/dist/components/atom/types.d.ts +3 -2
  16. package/dist/components/atom/utils.d.ts +37 -0
  17. package/dist/components/atom/utils.js +208 -0
  18. package/dist/components/breadcrumb/breadcrumb-item.svelte +1 -1
  19. package/dist/components/breadcrumb/breadcrumb-separator.svelte +5 -1
  20. package/dist/components/breadcrumb/breadcrumb.stories.svelte +16 -16
  21. package/dist/components/calendar/calendar-day.svelte +101 -101
  22. package/dist/components/checkbox/checkbox.svelte +159 -159
  23. package/dist/components/collapsible/bond.svelte.js +2 -1
  24. package/dist/components/collapsible/collapsible-body.svelte +3 -2
  25. package/dist/components/collapsible/motion.svelte.d.ts +6 -0
  26. package/dist/components/collapsible/motion.svelte.js +15 -0
  27. package/dist/components/combobox/atoms.d.ts +3 -3
  28. package/dist/components/combobox/atoms.js +3 -3
  29. package/dist/components/combobox/bond.svelte.d.ts +6 -6
  30. package/dist/components/combobox/bond.svelte.js +3 -26
  31. package/dist/components/combobox/combobox-control.svelte +52 -52
  32. package/dist/components/combobox/{compobox-item.svelte → combobox-item.svelte} +62 -68
  33. package/dist/components/combobox/combobox-item.svelte.d.ts +12 -0
  34. package/dist/components/combobox/combobox.stories.svelte +50 -0
  35. package/dist/components/combobox/combobox.stories.svelte.d.ts +3 -0
  36. package/dist/components/datagrid/tr/datagrid-tr.svelte +90 -90
  37. package/dist/components/date-picker/bond.svelte.d.ts +15 -5
  38. package/dist/components/date-picker/bond.svelte.js +6 -11
  39. package/dist/components/date-picker/date-picker-calendar.svelte +1 -8
  40. package/dist/components/dialog/bond.svelte.js +5 -20
  41. package/dist/components/dialog/dialog-content.svelte +44 -44
  42. package/dist/components/dialog/dialog-root.svelte +91 -91
  43. package/dist/components/drawer/bond.svelte.d.ts +18 -16
  44. package/dist/components/drawer/bond.svelte.js +8 -18
  45. package/dist/components/drawer/drawer-content.svelte +49 -49
  46. package/dist/components/drawer/drawer-root.svelte +5 -4
  47. package/dist/components/drawer/drawer.stories.svelte +141 -144
  48. package/dist/components/drawer/motion.js +1 -1
  49. package/dist/components/dropdown/atoms.d.ts +1 -1
  50. package/dist/components/dropdown/atoms.js +1 -1
  51. package/dist/components/dropdown/bond.svelte.d.ts +21 -22
  52. package/dist/components/dropdown/bond.svelte.js +29 -53
  53. package/dist/components/dropdown/dropdown-root.svelte +65 -59
  54. package/dist/components/dropdown/dropdown-values.svelte +17 -17
  55. package/dist/components/dropdown/dropdown-values.svelte.d.ts +1 -2
  56. package/dist/components/dropdown/dropdown.stories.svelte +83 -80
  57. package/dist/components/dropdown/index.d.ts +1 -0
  58. package/dist/components/dropdown/index.js +1 -0
  59. package/dist/components/dropdown/item/attachments.svelte.d.ts +2 -2
  60. package/dist/components/dropdown/item/attachments.svelte.js +2 -2
  61. package/dist/components/dropdown/item/controller.svelte.d.ts +34 -0
  62. package/dist/components/dropdown/item/controller.svelte.js +82 -0
  63. package/dist/components/dropdown/item/dropdown-item.svelte +109 -102
  64. package/dist/components/dropdown/item/dropdown-item.svelte.d.ts +13 -28
  65. package/dist/components/dropdown/item/index.d.ts +3 -0
  66. package/dist/components/dropdown/item/index.js +3 -0
  67. package/dist/components/dropdown/item/types.d.ts +29 -0
  68. package/dist/components/dropdown/item/types.js +1 -0
  69. package/dist/components/list/list-item.svelte +20 -20
  70. package/dist/components/menu/atoms.d.ts +8 -3
  71. package/dist/components/menu/atoms.js +8 -3
  72. package/dist/components/menu/bond.svelte.d.ts +54 -0
  73. package/dist/components/menu/bond.svelte.js +132 -0
  74. package/dist/components/menu/index.d.ts +1 -0
  75. package/dist/components/menu/index.js +1 -0
  76. package/dist/components/menu/item/controller.svelte.d.ts +26 -0
  77. package/dist/components/menu/item/controller.svelte.js +69 -0
  78. package/dist/components/menu/item/index.d.ts +2 -0
  79. package/dist/components/menu/item/index.js +2 -0
  80. package/dist/components/menu/item/menu-item.svelte +103 -0
  81. package/dist/components/menu/item/menu-item.svelte.d.ts +31 -0
  82. package/dist/components/menu/item/types.d.ts +62 -0
  83. package/dist/components/menu/item/types.js +1 -0
  84. package/dist/components/menu/{menu-list.svelte → menu-content.svelte} +40 -40
  85. package/dist/components/menu/{menu-list.svelte.d.ts → menu-content.svelte.d.ts} +3 -3
  86. package/dist/components/menu/menu-root.svelte +15 -0
  87. package/dist/components/menu/menu-root.svelte.d.ts +8 -0
  88. package/dist/components/menu/menu.stories.svelte +33 -33
  89. package/dist/components/menu/types.d.ts +0 -7
  90. package/dist/components/popover/bond.svelte.d.ts +11 -14
  91. package/dist/components/popover/bond.svelte.js +27 -44
  92. package/dist/components/popover/popover-content.svelte +137 -137
  93. package/dist/components/popover/popover.stories.svelte +37 -49
  94. package/dist/components/portal/active-portal.svelte +29 -29
  95. package/dist/components/portal/portal-root.svelte +76 -76
  96. package/dist/components/portal/teleport.svelte +49 -49
  97. package/dist/components/radio/radio.svelte +109 -109
  98. package/dist/components/root/index.d.ts +1 -0
  99. package/dist/components/root/index.js +1 -0
  100. package/dist/components/root/l0-portal.svelte +8 -0
  101. package/dist/components/root/l0-portal.svelte.d.ts +26 -0
  102. package/dist/components/root/l1-portal.svelte +7 -0
  103. package/dist/components/root/l1-portal.svelte.d.ts +26 -0
  104. package/dist/components/root/root.css +119 -119
  105. package/dist/components/root/root.svelte +17 -18
  106. package/dist/components/root/root.svelte.d.ts +2 -6
  107. package/dist/components/root/toasts-portal.svelte +7 -0
  108. package/dist/components/root/toasts-portal.svelte.d.ts +26 -0
  109. package/dist/components/root/types.d.ts +17 -0
  110. package/dist/components/sidebar/motion.svelte.js +3 -3
  111. package/dist/components/sidebar/sidebar-content.svelte +40 -40
  112. package/dist/components/textarea/textarea-input.svelte +9 -9
  113. package/dist/components/textarea/textarea-root.svelte +9 -9
  114. package/dist/components/tooltip/tooltip-trigger.svelte +39 -39
  115. package/dist/components/tree/index.d.ts +1 -0
  116. package/dist/components/tree/index.js +1 -0
  117. package/dist/components/tree/motion.svelte.d.ts +6 -0
  118. package/dist/components/tree/motion.svelte.js +14 -0
  119. package/dist/components/tree/tree-body.svelte +4 -3
  120. package/dist/context/preset.svelte.d.ts +3 -1
  121. package/dist/icons/icon-copy.svelte +6 -6
  122. package/dist/utils/dom.svelte.d.ts +2 -0
  123. package/dist/utils/dom.svelte.js +21 -0
  124. package/dist/utils/function.d.ts +1 -1
  125. package/dist/utils/promise.svelte.d.ts +5 -0
  126. package/dist/utils/promise.svelte.js +20 -0
  127. package/package.json +4 -2
  128. package/dist/components/combobox/compobox-item.svelte.d.ts +0 -34
  129. package/dist/components/combobox/compobox.stories.svelte +0 -51
  130. package/dist/components/combobox/compobox.stories.svelte.d.ts +0 -3
  131. package/dist/components/dropdown/item/bond.svelte.d.ts +0 -42
  132. package/dist/components/dropdown/item/bond.svelte.js +0 -99
  133. package/dist/components/menu/menu-item.svelte +0 -69
  134. package/dist/components/menu/menu-item.svelte.d.ts +0 -37
  135. package/dist/utils/markdown-to-llm.d.ts +0 -28
  136. package/dist/utils/markdown-to-llm.js +0 -76
@@ -1,144 +1,141 @@
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
- {@attach clickoutDrawer((_, bond) => {
35
- bond?.state?.close?.();
36
- })}
37
- >
38
- <Drawer_.Header class="flex items-center justify-between">
39
- <div class="flex flex-col">
40
- <Drawer_.Title class="text-lg font-semibold">Drawer Title</Drawer_.Title>
41
- <Drawer_.Description class="text-sm break-all whitespace-break-spaces text-neutral-500"
42
- >Ac bibendum laoreet lacinia purus duis. Hendrerit quam purus maecenas tincidunt letius
43
- finibus vel tortor sociosqu proin vulputate. Consectetur velit eleifend purus mi
44
- pulvinar si tristique litora mollis lobortis.</Drawer_.Description
45
- >
46
- </div>
47
- </Drawer_.Header>
48
- <div>
49
- <div>Svelte Fluent</div>
50
- </div>
51
- </Drawer_.Content>
52
- </Drawer_.Root>
53
-
54
- <button
55
- class="bg-red-500 p-2"
56
- onclick={() => {
57
- isOpen = !isOpen;
58
- }}>Open</button
59
- >
60
- </Story>
61
-
62
- <Story name="Top" args={{}}>
63
- <Drawer_.Root
64
- bind:open={isOpen}
65
- class=" border backdrop-blur-md backdrop-grayscale-100"
66
- animate={animateDrawerRoot({})}
67
- >
68
- <Drawer_.Content
69
- class="border-border flex w-md min-w-full flex-col border-b p-8 whitespace-nowrap shadow-md"
70
- animate={animateDrawerContent({ ease: 'easeOut', side: 'top' })}
71
- {@attach clickoutDrawer((_, bond) => {
72
- bond?.state?.close?.();
73
- })}
74
- >
75
- <div>
76
- <div>Svelte Fluent</div>
77
- </div>
78
- </Drawer_.Content>
79
- </Drawer_.Root>
80
-
81
- <button
82
- class="bg-red-500 p-2"
83
- onclick={() => {
84
- isOpen = !isOpen;
85
- }}>Open</button
86
- >
87
- </Story>
88
-
89
- <Story name="Right" args={{}}>
90
- <Drawer_.Root
91
- bind:open={isOpen}
92
- class=" border backdrop-blur-md backdrop-grayscale-100"
93
- animate={animateDrawerRoot({})}
94
- >
95
- <Drawer_.Content
96
- class="border-border shadow-foreground/50 inset-y-0 flex w-md flex-col border-l p-8 whitespace-nowrap shadow-sm"
97
- animate={animateDrawerContent({ ease: 'easeOut', side: 'right' })}
98
- {@attach clickoutDrawer((_, bond) => {
99
- bond?.state?.close?.();
100
- })}
101
- >
102
- <div>
103
- <div>Svelte Fluent</div>
104
- </div>
105
- </Drawer_.Content>
106
- </Drawer_.Root>
107
-
108
- <button
109
- class="bg-red-500 p-2"
110
- onclick={() => {
111
- isOpen = !isOpen;
112
- }}>Open</button
113
- >
114
- </Story>
115
-
116
- <Story name="Bottom" args={{}}>
117
- <Drawer_.Root
118
- bind:open={isOpen}
119
- class=" border backdrop-blur-md backdrop-grayscale-100"
120
- initial={(node) => {
121
- animate(node, { opacity: +isOpen }, { duration: 0 });
122
- }}
123
- animate={animateDrawerRoot()}
124
- >
125
- <Drawer_.Content
126
- class="border-border flex w-md min-w-full flex-col border-t p-8 whitespace-nowrap shadow-md"
127
- animate={animateDrawerContent({ ease: 'easeOut', side: 'bottom' })}
128
- {@attach clickoutDrawer((_, bond) => {
129
- bond?.state?.close?.();
130
- })}
131
- >
132
- <div>
133
- <div>Svelte Fluent</div>
134
- </div>
135
- </Drawer_.Content>
136
- </Drawer_.Root>
137
-
138
- <button
139
- class="bg-red-500 p-2"
140
- onclick={() => {
141
- isOpen = !isOpen;
142
- }}>Open</button
143
- >
144
- </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>
@@ -4,11 +4,11 @@ import { DrawerBond } from '.';
4
4
  export function animateDrawerContent(params) {
5
5
  const { duration = DURATION.fast / 1000, delay = 0, ease = 'easeInOut', side = 'left' } = params;
6
6
  const bond = DrawerBond.get();
7
- const isOpen = bond?.state.props.open ?? false;
8
7
  const mainProp = side === 'left' || side === 'right' ? 'x' : 'y';
9
8
  const crossProp = mainProp === 'x' ? 'y' : 'x';
10
9
  const d = side === 'left' || side === 'top' ? -1 : 1;
11
10
  return (node) => {
11
+ const isOpen = bond?.state.props.open ?? false;
12
12
  animate(node, {
13
13
  [mainProp]: isOpen ? 0 : d * 100 + '%',
14
14
  [crossProp]: 0,
@@ -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, Divider, Title, Group } 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, Divider, Title, Group } from '../menu/atoms';
9
+ export { Content, List, Divider, Title, Group } from '../menu/atoms';
@@ -1,30 +1,35 @@
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
- onchange?: (node: HTMLElement, position: import("@floating-ui/core").ComputePositionReturn) => void;
17
- id: string;
15
+ content(): {
18
16
  role: string;
17
+ 'aria-multiselectable': boolean;
18
+ 'aria-activedescendant': string | undefined;
19
+ 'aria-orientation': "vertical";
20
+ onkeydown: (ev: KeyboardEvent) => void;
21
+ id: string;
19
22
  'aria-modal': boolean;
20
23
  'aria-labelledby': string;
21
- 'aria-hidden': boolean;
22
- inert: string | undefined;
24
+ inert: boolean | undefined;
23
25
  tabindex: number;
24
26
  'data-atom': string;
25
27
  'data-kind': string;
26
28
  'data-active': boolean;
27
- onkeydown: ((ev: KeyboardEvent) => void) | undefined;
29
+ };
30
+ item(): {
31
+ role: string;
32
+ onkeyup: (ev: KeyboardEvent) => void;
28
33
  };
29
34
  placeholder(): {
30
35
  [x: symbol]: (node: HTMLElement) => void;
@@ -33,21 +38,15 @@ export declare class DropdownBond<Props extends DropdownStateProps = DropdownSta
33
38
  'data-atom': string;
34
39
  'data-kind': string;
35
40
  };
36
- static getContext<Props extends DropdownStateProps = DropdownStateProps, State extends DropdownBondState<Props> = DropdownBondState<Props>, Elements extends PopoverDomElements = PopoverDomElements>(): DropdownBond<Props, State, Elements> | undefined;
37
- 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>;
38
43
  }
39
- export declare class DropdownBondState<Props extends DropdownStateProps = DropdownStateProps> extends PopoverState<Props> {
44
+ export declare class DropdownBondState<Props extends DropdownStateProps = DropdownStateProps> extends MenuBondState<Props> {
40
45
  #private;
41
- constructor(props: () => DropdownStateProps);
42
- get selectedItems(): DropdownItemBond<unknown>[];
43
- get highlightedItem(): DropdownItemBond<unknown> | null;
46
+ constructor(props: () => Props);
47
+ get selectedItems(): DropdownItemController<unknown>[];
44
48
  get query(): string;
45
49
  set query(value: string);
46
- mountItem<I>(id: string, item: DropdownItemBond<I>): () => void;
47
- unmountItem(id: string): void;
48
- item(id: string): DropdownItemBond<unknown> | undefined;
49
50
  select(ids: string[]): void;
50
51
  unselect(ids: string[]): void;
51
- highlightNextItem(): void;
52
- highlightPreviousItem(): void;
53
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
  }
@@ -1,59 +1,65 @@
1
- <script lang="ts" generics="T">
2
- import { defineProperty, defineState } from '../../utils';
3
- import { DropdownBond, DropdownBondState, type DropdownStateProps } from './bond.svelte';
4
-
5
- let {
6
- open = $bindable(false),
7
- value = $bindable(),
8
- values = $bindable(),
9
- multiple = false,
10
- disabled = false,
11
- placements = ['bottom-start', 'bottom-end', 'top-start', 'top-end'],
12
- placement = 'bottom-start',
13
- offset = 1,
14
- keys = [],
15
- factory = _factory,
16
- children = undefined,
17
- onquerychange = undefined,
18
- ...restProps
19
- } = $props();
20
-
21
- const bondProps = defineState<DropdownStateProps>(
22
- [
23
- defineProperty(
24
- 'open',
25
- () => open,
26
- (v) => {
27
- open = v;
28
- }
29
- ),
30
- defineProperty(
31
- 'values',
32
- () => (multiple ? values : [value].filter(Boolean)),
33
- (v) => {
34
- values = v;
35
- value = v[0];
36
- }
37
- ),
38
- defineProperty('multiple', () => multiple),
39
- defineProperty('disabled', () => disabled),
40
- defineProperty('placement', () => placement),
41
- defineProperty('offset', () => offset),
42
- defineProperty('placements', () => placements ?? []),
43
- defineProperty('keys', () => keys ?? [])
44
- ],
45
- () => ({ onquerychange })
46
- );
47
- const bond = factory(bondProps).share();
48
-
49
- function _factory(props: typeof bondProps) {
50
- const bondState = new DropdownBondState<T>(() => props);
51
- return new DropdownBond(bondState);
52
- }
53
-
54
- export function getBond() {
55
- return bond;
56
- }
57
- </script>
58
-
59
- {@render children?.({ dropdown: bond })}
1
+ <script lang="ts" generics="T">
2
+ import { defineProperty, defineState } from '../../utils';
3
+ import { DropdownBond, DropdownBondState, type DropdownStateProps } from './bond.svelte';
4
+
5
+ let {
6
+ open = $bindable(false),
7
+ value = $bindable(),
8
+ values = $bindable(),
9
+ multiple = false,
10
+ disabled = false,
11
+ placements = ['bottom-start', 'bottom-end', 'top-start', 'top-end'],
12
+ placement = 'bottom-start',
13
+ offset = 1,
14
+ keys = [],
15
+ factory = _factory,
16
+ children = undefined,
17
+ onquerychange = undefined,
18
+ ...restProps
19
+ } = $props();
20
+
21
+ const bondProps = defineState<DropdownStateProps>(
22
+ [
23
+ defineProperty(
24
+ 'open',
25
+ () => open,
26
+ (v) => {
27
+ open = v;
28
+ }
29
+ ),
30
+ defineProperty(
31
+ 'values',
32
+ () => (multiple ? values : [value].filter(Boolean)),
33
+ (v) => {
34
+ values = v;
35
+ value = v[0];
36
+ }
37
+ ),
38
+ defineProperty('multiple', () => multiple),
39
+ defineProperty('disabled', () => disabled),
40
+ defineProperty('placement', () => placement),
41
+ defineProperty('offset', () => offset),
42
+ defineProperty('placements', () => placements ?? []),
43
+ defineProperty('keys', () => keys ?? [])
44
+ ],
45
+ () => ({ onquerychange })
46
+ );
47
+ const bond = factory(bondProps).share();
48
+
49
+ function _factory(props: typeof bondProps) {
50
+ const bondState = new DropdownBondState(() => props);
51
+ return new DropdownBond(bondState);
52
+ }
53
+
54
+ export function getBond() {
55
+ return bond;
56
+ }
57
+
58
+ $effect(() => {
59
+ return () => {
60
+ bond.destroy();
61
+ };
62
+ });
63
+ </script>
64
+
65
+ {@render children?.({ dropdown: bond })}