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

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 (125) hide show
  1. package/dist/components/atom/html-atom.svelte +95 -93
  2. package/dist/components/atom/html-atom.svelte.d.ts +1 -1
  3. package/dist/components/button/button.svelte +31 -31
  4. package/dist/components/chip/chip.svelte +41 -0
  5. package/dist/components/chip/chip.svelte.d.ts +6 -0
  6. package/dist/components/chip/index.d.ts +1 -0
  7. package/dist/components/chip/index.js +1 -0
  8. package/dist/components/chip/types.d.ts +11 -0
  9. package/dist/components/chip/types.js +1 -0
  10. package/dist/components/combobox/atoms.d.ts +2 -1
  11. package/dist/components/combobox/atoms.js +2 -1
  12. package/dist/components/combobox/bond.svelte.d.ts +16 -13
  13. package/dist/components/combobox/bond.svelte.js +57 -13
  14. package/dist/components/combobox/combobox-control.svelte +27 -13
  15. package/dist/components/combobox/combobox-control.svelte.d.ts +2 -10
  16. package/dist/components/combobox/combobox-item.svelte +3 -3
  17. package/dist/components/combobox/combobox-root.svelte +65 -65
  18. package/dist/components/combobox/combobox-root.svelte.d.ts +4 -4
  19. package/dist/components/combobox/combobox-selections.svelte +17 -0
  20. package/dist/components/combobox/combobox-selections.svelte.d.ts +4 -0
  21. package/dist/components/combobox/combobox.stories.svelte +25 -12
  22. package/dist/components/combobox/types.d.ts +17 -3
  23. package/dist/components/dropdown/atoms.d.ts +2 -3
  24. package/dist/components/dropdown/atoms.js +3 -3
  25. package/dist/components/dropdown/bond.svelte.d.ts +4 -4
  26. package/dist/components/dropdown/bond.svelte.js +10 -11
  27. package/dist/components/dropdown/dropdown-query.svelte +43 -54
  28. package/dist/components/dropdown/dropdown-query.svelte.d.ts +3 -34
  29. package/dist/components/dropdown/dropdown-root.svelte +15 -2
  30. package/dist/components/dropdown/dropdown-root.svelte.d.ts +4 -16
  31. package/dist/components/dropdown/dropdown-selection.svelte +55 -0
  32. package/dist/components/dropdown/{dropdown-value.svelte.d.ts → dropdown-selection.svelte.d.ts} +5 -15
  33. package/dist/components/dropdown/dropdown-selections.svelte +62 -0
  34. package/dist/components/dropdown/dropdown-selections.svelte.d.ts +5 -0
  35. package/dist/components/dropdown/dropdown.stories.svelte +93 -49
  36. package/dist/components/dropdown/index.d.ts +5 -1
  37. package/dist/components/dropdown/index.js +5 -1
  38. package/dist/components/dropdown/item/controller.svelte.d.ts +1 -1
  39. package/dist/components/dropdown/item/controller.svelte.js +2 -2
  40. package/dist/components/dropdown/item/dropdown-item.svelte +0 -2
  41. package/dist/components/dropdown/runes.svelte.d.ts +6 -2
  42. package/dist/components/dropdown/runes.svelte.js +1 -1
  43. package/dist/components/dropdown/types.d.ts +34 -2
  44. package/dist/components/index.d.ts +2 -0
  45. package/dist/components/index.js +2 -0
  46. package/dist/components/menu/bond.svelte.js +4 -2
  47. package/dist/components/menu/item/controller.svelte.d.ts +1 -0
  48. package/dist/components/menu/item/controller.svelte.js +5 -0
  49. package/dist/components/popover/bond.svelte.js +1 -2
  50. package/dist/components/root/root.css +119 -119
  51. package/dist/components/stepper/README.md +38 -0
  52. package/dist/components/stepper/atoms.d.ts +5 -0
  53. package/dist/components/stepper/atoms.js +5 -0
  54. package/dist/components/stepper/attachments.svelte.d.ts +2 -0
  55. package/dist/components/stepper/attachments.svelte.js +5 -0
  56. package/dist/components/stepper/bond.svelte.d.ts +56 -0
  57. package/dist/components/stepper/bond.svelte.js +99 -0
  58. package/dist/components/stepper/index.d.ts +3 -0
  59. package/dist/components/stepper/index.js +3 -0
  60. package/dist/components/stepper/step/README.md +97 -0
  61. package/dist/components/stepper/step/atoms.d.ts +7 -0
  62. package/dist/components/stepper/step/atoms.js +7 -0
  63. package/dist/components/stepper/step/attachments.svelte.d.ts +2 -0
  64. package/dist/components/stepper/step/attachments.svelte.js +5 -0
  65. package/dist/components/stepper/step/bond.svelte.d.ts +99 -0
  66. package/dist/components/stepper/step/bond.svelte.js +153 -0
  67. package/dist/components/stepper/step/index.d.ts +3 -0
  68. package/dist/components/stepper/step/index.js +2 -0
  69. package/dist/components/stepper/step/step-body.svelte +39 -0
  70. package/dist/components/stepper/step/step-body.svelte.d.ts +26 -0
  71. package/dist/components/stepper/step/step-description.svelte +33 -0
  72. package/dist/components/stepper/step/step-description.svelte.d.ts +26 -0
  73. package/dist/components/stepper/step/step-header.svelte +34 -0
  74. package/dist/components/stepper/step/step-header.svelte.d.ts +26 -0
  75. package/dist/components/stepper/step/step-indicator.svelte +63 -0
  76. package/dist/components/stepper/step/step-indicator.svelte.d.ts +26 -0
  77. package/dist/components/stepper/step/step-root.svelte +42 -0
  78. package/dist/components/stepper/step/step-root.svelte.d.ts +31 -0
  79. package/dist/components/stepper/step/step-separator.svelte +48 -0
  80. package/dist/components/stepper/step/step-separator.svelte.d.ts +26 -0
  81. package/dist/components/stepper/step/step-title.svelte +33 -0
  82. package/dist/components/stepper/step/step-title.svelte.d.ts +26 -0
  83. package/dist/components/stepper/step/types.d.ts +91 -0
  84. package/dist/components/stepper/step/types.js +1 -0
  85. package/dist/components/stepper/stepper-body.svelte +43 -0
  86. package/dist/components/stepper/stepper-body.svelte.d.ts +26 -0
  87. package/dist/components/stepper/stepper-content.svelte +45 -0
  88. package/dist/components/stepper/stepper-content.svelte.d.ts +26 -0
  89. package/dist/components/stepper/stepper-footer.svelte +31 -0
  90. package/dist/components/stepper/stepper-footer.svelte.d.ts +26 -0
  91. package/dist/components/stepper/stepper-header.svelte +39 -0
  92. package/dist/components/stepper/stepper-header.svelte.d.ts +26 -0
  93. package/dist/components/stepper/stepper-root.svelte +60 -0
  94. package/dist/components/stepper/stepper-root.svelte.d.ts +31 -0
  95. package/dist/components/stepper/stepper.stories.svelte +264 -0
  96. package/dist/components/stepper/stepper.stories.svelte.d.ts +4 -0
  97. package/dist/components/stepper/types.d.ts +63 -0
  98. package/dist/components/stepper/types.js +1 -0
  99. package/dist/components/tabs/atoms.d.ts +1 -0
  100. package/dist/components/tabs/atoms.js +1 -0
  101. package/dist/components/tabs/bond.svelte.d.ts +18 -5
  102. package/dist/components/tabs/bond.svelte.js +13 -0
  103. package/dist/components/tabs/tab/bond.svelte.d.ts +7 -7
  104. package/dist/components/tabs/tab/bond.svelte.js +9 -15
  105. package/dist/components/tabs/tab/tab-body.svelte +43 -52
  106. package/dist/components/tabs/tab/tab-description.svelte +33 -41
  107. package/dist/components/tabs/tab/tab-header.svelte +61 -71
  108. package/dist/components/tabs/tab/tab-header.svelte.d.ts +1 -1
  109. package/dist/components/tabs/tab/tab-root.svelte +51 -86
  110. package/dist/components/tabs/tab/tab-root.svelte.d.ts +1 -7
  111. package/dist/components/tabs/tabs-body.svelte +35 -41
  112. package/dist/components/tabs/tabs-body.svelte.d.ts +2 -11
  113. package/dist/components/tabs/tabs-content.svelte +51 -0
  114. package/dist/components/tabs/tabs-content.svelte.d.ts +26 -0
  115. package/dist/components/tabs/tabs-header.svelte +32 -40
  116. package/dist/components/tabs/tabs-header.svelte.d.ts +2 -10
  117. package/dist/components/tabs/tabs-root.svelte +55 -66
  118. package/dist/components/tabs/tabs-root.svelte.d.ts +5 -16
  119. package/dist/components/tabs/tabs.stories.svelte +70 -56
  120. package/dist/components/tabs/types.d.ts +24 -29
  121. package/dist/context/preset.svelte.d.ts +1 -1
  122. package/package.json +33 -6
  123. package/dist/components/dropdown/dropdown-value.svelte +0 -60
  124. package/dist/components/dropdown/dropdown-values.svelte +0 -17
  125. package/dist/components/dropdown/dropdown-values.svelte.d.ts +0 -5
@@ -1,93 +1,95 @@
1
- <script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- import type { Base, HtmlAtomProps, SnippetBase } from './types';
4
- import { RootBond } from '../root';
5
- import { HtmlElement } from '../element';
6
- import { getPreset } from '../../context';
7
- import type { PresetModuleName } from '../../context/preset.svelte';
8
- import SnippetRenderer from './snippet-renderer.svelte';
9
- import type { Component } from 'svelte';
10
- import type { ClassValue } from '../../utils';
11
- import {
12
- resolvePreset,
13
- resolveLocalVariants,
14
- mergeVariants,
15
- mergeClassesWithPreset,
16
- extractRestProps,
17
- isSnippetBase
18
- } from './utils';
19
-
20
- type Element = HTMLElementTagNameMap[E];
21
-
22
- const rootBond = RootBond.get();
23
-
24
- let {
25
- class: klass = '',
26
- as = 'div',
27
- base = undefined,
28
- preset: presetKey = undefined,
29
- bond = undefined,
30
- variants = undefined,
31
- children: childrenProp = undefined,
32
- ...restProps
33
- }: HtmlAtomProps<E, B> & Omit<HTMLAttributes<Element>, 'children'> = $props();
34
-
35
- // Memoize preset resolution - only recompute when presetKey or bond changes
36
- const preset = $derived.by(() => {
37
- if (!presetKey) return undefined;
38
- const result = getPreset(presetKey as PresetModuleName)?.apply?.(bond, [bond]);
39
- return resolvePreset(result);
40
- });
41
-
42
- const presetVariantsProps = $derived(preset?.variants);
43
-
44
- // Resolve local variants - either VariantDefinition or function
45
- const localVariants = $derived(resolveLocalVariants(variants, bond, restProps));
46
-
47
- // Merge preset variants with local variants
48
- // Memoized to avoid recomputation when inputs haven't changed
49
- const mergedVariants = $derived.by(() => {
50
- return mergeVariants(
51
- presetVariantsProps,
52
- preset?.class,
53
- preset?.compounds,
54
- preset?.defaults,
55
- localVariants,
56
- bond,
57
- restProps
58
- );
59
- });
60
-
61
- const _klass = $derived(
62
- mergeClassesWithPreset(klass, preset?.class, mergedVariants?.class as ClassValue)
63
- );
64
-
65
- const _base = $derived(base ?? preset?.base);
66
- const _as = $derived(as ?? preset?.as);
67
- const _restProps = $derived(extractRestProps(preset, mergedVariants, restProps));
68
-
69
- const isSnippet = $derived(isSnippetBase(_base));
70
-
71
- const snippet = $derived(_base as SnippetBase);
72
-
73
- const atom = rootBond?.state?.props?.renderers?.html ?? HtmlElement;
74
-
75
- const renderer = $derived.by(() => {
76
- if (isSnippet)
77
- return {
78
- component: SnippetRenderer,
79
- props: { snippet: snippet, class: _klass, as: _as, children: childrenProp, ..._restProps }
80
- };
81
-
82
- return {
83
- component: base ?? atom,
84
- props: { class: _klass, as: _as, ..._restProps }
85
- };
86
- }) as { component: Component; props: Record<string, any> };
87
- </script>
88
-
89
- <renderer.component {...renderer.props}>
90
- {#snippet children(args: any)}
91
- {@render (childrenProp as any)?.(args)}
92
- {/snippet}
93
- </renderer.component>
1
+ <script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { Base, HtmlAtomProps, SnippetBase } from './types';
4
+ import { RootBond } from '../root';
5
+ import { HtmlElement } from '../element';
6
+ import { getPreset } from '../../context';
7
+ import type { PresetModuleName } from '../../context/preset.svelte';
8
+ import SnippetRenderer from './snippet-renderer.svelte';
9
+ import type { Component } from 'svelte';
10
+ import type { ClassValue } from '../../utils';
11
+ import {
12
+ resolvePreset,
13
+ resolveLocalVariants,
14
+ mergeVariants,
15
+ mergeClassesWithPreset,
16
+ extractRestProps,
17
+ isSnippetBase
18
+ } from './utils';
19
+
20
+ type Element = HTMLElementTagNameMap[E];
21
+
22
+ type Props = Omit<HTMLAttributes<Element>, 'children'> & HtmlAtomProps<E, B>;
23
+
24
+ const rootBond = RootBond.get();
25
+
26
+ let {
27
+ class: klass = '',
28
+ as = 'div',
29
+ base = undefined,
30
+ preset: presetKey = undefined,
31
+ bond = undefined,
32
+ variants = undefined,
33
+ children: childrenProp = undefined,
34
+ ...restProps
35
+ }: Props = $props();
36
+
37
+ // Memoize preset resolution - only recompute when presetKey or bond changes
38
+ const preset = $derived.by(() => {
39
+ if (!presetKey) return undefined;
40
+ const result = getPreset(presetKey as PresetModuleName)?.apply?.(bond, [bond]);
41
+ return resolvePreset(result);
42
+ });
43
+
44
+ const presetVariantsProps = $derived(preset?.variants);
45
+
46
+ // Resolve local variants - either VariantDefinition or function
47
+ const localVariants = $derived(resolveLocalVariants(variants, bond, restProps));
48
+
49
+ // Merge preset variants with local variants
50
+ // Memoized to avoid recomputation when inputs haven't changed
51
+ const mergedVariants = $derived.by(() => {
52
+ return mergeVariants(
53
+ presetVariantsProps,
54
+ preset?.class,
55
+ preset?.compounds,
56
+ preset?.defaults,
57
+ localVariants,
58
+ bond,
59
+ restProps
60
+ );
61
+ });
62
+
63
+ const _klass = $derived(
64
+ mergeClassesWithPreset(klass, preset?.class, mergedVariants?.class as ClassValue)
65
+ );
66
+
67
+ const _base = $derived(base ?? preset?.base);
68
+ const _as = $derived(as ?? preset?.as);
69
+ const _restProps = $derived(extractRestProps(preset, mergedVariants, restProps));
70
+
71
+ const isSnippet = $derived(isSnippetBase(_base));
72
+
73
+ const snippet = $derived(_base as SnippetBase);
74
+
75
+ const atom = rootBond?.state?.props?.renderers?.html ?? HtmlElement;
76
+
77
+ const renderer = $derived.by(() => {
78
+ if (isSnippet)
79
+ return {
80
+ component: SnippetRenderer,
81
+ props: { snippet: snippet, class: _klass, as: _as, children: childrenProp, ..._restProps }
82
+ };
83
+
84
+ return {
85
+ component: _base ?? atom,
86
+ props: { class: _klass, as: _as, ..._restProps }
87
+ };
88
+ }) as { component: Component; props: Record<string, any> };
89
+ </script>
90
+
91
+ <renderer.component {...renderer.props}>
92
+ {#snippet children(args: any)}
93
+ {@render (childrenProp as any)?.(args)}
94
+ {/snippet}
95
+ </renderer.component>
@@ -1,7 +1,7 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
2
  import type { Base, HtmlAtomProps } from './types';
3
3
  declare function $$render<E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base>(): {
4
- props: HtmlAtomProps<E, B> & Omit<HTMLAttributes<HTMLElementTagNameMap[E]>, "children">;
4
+ props: Omit<HTMLAttributes<HTMLElementTagNameMap[E]>, "children"> & HtmlAtomProps<E, B>;
5
5
  exports: {};
6
6
  bindings: "";
7
7
  slots: {};
@@ -1,31 +1,31 @@
1
- <script lang="ts">
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- import type { ButtonProps } from './types';
4
- import { HtmlAtom } from '../atom';
5
-
6
- let {
7
- class: klass = '',
8
- type = 'button',
9
- preset = 'button',
10
- children = undefined,
11
- ...restProps
12
- }: ButtonProps & HTMLAttributes<HTMLButtonElement> = $props();
13
-
14
- const buttonProps = $derived({
15
- ...restProps,
16
- type
17
- });
18
- </script>
19
-
20
- <HtmlAtom
21
- {preset}
22
- as="button"
23
- class={[
24
- 'button text-primary-foreground bg-primary border-border hover:bg-primary/95 active:bg-primary/90 disabled:bg-muted disabled:text-muted-foreground w-fit cursor-pointer rounded-md px-3 py-2 transition-colors duration-200',
25
- '$preset',
26
- klass
27
- ]}
28
- {...buttonProps}
29
- >
30
- {@render children?.()}
31
- </HtmlAtom>
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { ButtonProps } from './types';
4
+ import { HtmlAtom } from '../atom';
5
+
6
+ let {
7
+ class: klass = '',
8
+ type = 'button',
9
+ preset = 'button',
10
+ children = undefined,
11
+ ...restProps
12
+ }: ButtonProps & HTMLAttributes<HTMLButtonElement> = $props();
13
+
14
+ const buttonProps = $derived({
15
+ ...restProps,
16
+ type
17
+ });
18
+ </script>
19
+
20
+ <HtmlAtom
21
+ {preset}
22
+ as="button"
23
+ class={[
24
+ 'button text-primary-foreground bg-primary border-border hover:bg-primary/95 active:bg-primary/90 disabled:bg-muted disabled:text-muted-foreground w-fit cursor-pointer rounded-md px-3 py-2 transition-colors duration-200',
25
+ '$preset',
26
+ klass
27
+ ]}
28
+ {...buttonProps}
29
+ >
30
+ {@render children?.()}
31
+ </HtmlAtom>
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { HtmlAtom } from '../atom';
4
+ import { Icon } from '../icon';
5
+ import type { ChipProps } from './types';
6
+ import CloseIcon from '../../icons/icon-close.svelte';
7
+
8
+ let {
9
+ class: klass = '',
10
+ preset = 'chip',
11
+ children = undefined,
12
+ icon = undefined,
13
+ onclose = undefined,
14
+ ...restProps
15
+ }: ChipProps & HTMLAttributes<HTMLButtonElement> = $props();
16
+ </script>
17
+
18
+ <HtmlAtom
19
+ {preset}
20
+ as="div"
21
+ class={[
22
+ 'chip text-foreground bg-foreground/5 border-border hover:bg-foreground/10 active:bg-foreground/15 disabled:bg-muted disabled:text-muted-foreground w-fit cursor-pointer rounded-md px-3 py-1 transition-colors duration-100',
23
+ '$preset',
24
+ klass
25
+ ]}
26
+ {...restProps}
27
+ >
28
+ {@render children?.()}
29
+
30
+ <button
31
+ class="bg-foreground/0 hover:bg-foreground/5 active:bg-foreground/10 inline-flex aspect-square h-full cursor-pointer items-center justify-center rounded-xs p-0.5"
32
+ type="button"
33
+ onclick={onclose}
34
+ >
35
+ {#if icon}
36
+ {@render icon?.()}
37
+ {:else}
38
+ <Icon src={CloseIcon} class="h-full" />
39
+ {/if}
40
+ </button>
41
+ </HtmlAtom>
@@ -0,0 +1,6 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import type { ChipProps } from './types';
3
+ type $$ComponentProps = ChipProps & HTMLAttributes<HTMLButtonElement>;
4
+ declare const Chip: import("svelte").Component<$$ComponentProps, {}, "">;
5
+ type Chip = ReturnType<typeof Chip>;
6
+ export default Chip;
@@ -0,0 +1 @@
1
+ export { default as Chip } from './chip.svelte';
@@ -0,0 +1 @@
1
+ export { default as Chip } from './chip.svelte';
@@ -0,0 +1,11 @@
1
+ import type { HtmlAtomProps } from '../atom/types';
2
+ import type { Snippet } from 'svelte';
3
+ /**
4
+ * Extend this interface to add custom button properties in your application.
5
+ */
6
+ export interface ChipExtendProps {
7
+ }
8
+ export interface ChipProps extends HtmlAtomProps<'button'>, ChipExtendProps {
9
+ children?: Snippet<[]>;
10
+ icon?: Snippet<[]>;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -6,4 +6,5 @@ export { default as Item } from './combobox-item.svelte';
6
6
  */
7
7
  export { default as Input } from './combobox-control.svelte';
8
8
  export { default as Control } from './combobox-control.svelte';
9
- export { Arrow, Indicator, Content, List, Group, Divider, Title } from '../dropdown/atoms';
9
+ export { default as Selections } from './combobox-selections.svelte';
10
+ export { Arrow, Indicator, Content, List, Group, Divider, Title, Selection, Placeholder } from '../dropdown/atoms';
@@ -6,4 +6,5 @@ export { default as Item } from './combobox-item.svelte';
6
6
  */
7
7
  export { default as Input } from './combobox-control.svelte';
8
8
  export { default as Control } from './combobox-control.svelte';
9
- export { Arrow, Indicator, Content, List, Group, Divider, Title } from '../dropdown/atoms';
9
+ export { default as Selections } from './combobox-selections.svelte';
10
+ export { Arrow, Indicator, Content, List, Group, Divider, Title, Selection, Placeholder } from '../dropdown/atoms';
@@ -1,15 +1,12 @@
1
- import { type PopoverDomElements, type PopoverStateProps } from '../popover/bond.svelte';
2
- import { DropdownBond, DropdownBondState } from '../dropdown/bond.svelte';
3
- export type ComboboxBondProps = PopoverStateProps & {
4
- value?: string;
5
- query?: string;
6
- text?: string;
7
- };
1
+ import { type PopoverDomElements } from '../popover/bond.svelte';
2
+ import { DropdownBond, DropdownBondState, type DropdownStateProps } from '../dropdown/bond.svelte';
3
+ import type { ComboboxSelection } from './types';
4
+ export type ComboboxBondProps = DropdownStateProps & {};
8
5
  export type ComboboxBondElements = PopoverDomElements & {
9
6
  input: HTMLInputElement;
10
7
  };
11
- export declare class ComboboxBond<T = unknown> extends DropdownBond<ComboboxBondProps, ComboboxBondState<T>, ComboboxBondElements> {
12
- constructor(s: ComboboxBondState<T>);
8
+ export declare class ComboboxBond extends DropdownBond<ComboboxBondProps, ComboboxBondState, ComboboxBondElements> {
9
+ constructor(s: ComboboxBondState);
13
10
  control(): {
14
11
  [x: symbol]: (node: HTMLInputElement) => void;
15
12
  'data-atom': string;
@@ -21,12 +18,18 @@ export declare class ComboboxBond<T = unknown> extends DropdownBond<ComboboxBond
21
18
  'aria-activedescendant': string | undefined;
22
19
  'aria-disabled': boolean;
23
20
  tabindex: number;
24
- oninput: (ev: Event) => void;
21
+ oninput: () => void;
25
22
  onkeydown: (ev: KeyboardEvent) => void;
26
23
  };
27
- static get: typeof DropdownBond.get;
28
- static set: typeof DropdownBond.set;
24
+ static get(): ComboboxBond | undefined;
25
+ static set(context: ComboboxBond): ComboboxBond;
29
26
  }
30
- export declare class ComboboxBondState<T> extends DropdownBondState<ComboboxBondProps> {
27
+ export declare class ComboboxBondState extends DropdownBondState<ComboboxBondProps> {
28
+ #private;
31
29
  constructor(props: () => ComboboxBondProps);
30
+ addSelection(label: string): void;
31
+ deleteSelection(id: string): void;
32
+ get userSelections(): ComboboxSelection[];
33
+ get allSelections(): ComboboxSelection[];
34
+ protected updateLabels(): void;
32
35
  }
@@ -1,11 +1,14 @@
1
1
  import {} from '../popover/bond.svelte';
2
2
  import { DropdownBond, DropdownBondState } from '../dropdown/bond.svelte';
3
3
  import { createAttachmentKey } from 'svelte/attachments';
4
+ import { SvelteMap } from 'svelte/reactivity';
5
+ import { nanoid } from 'nanoid';
4
6
  export class ComboboxBond extends DropdownBond {
5
7
  constructor(s) {
6
8
  super(s);
7
9
  }
8
10
  control() {
11
+ const isMultiselect = this.state.props.multiple ?? false;
9
12
  return {
10
13
  'data-atom': `trigger-${this.id}`,
11
14
  'data-kind': 'combobox-input',
@@ -13,35 +16,76 @@ export class ComboboxBond extends DropdownBond {
13
16
  'aria-autocomplete': 'list',
14
17
  'aria-expanded': this.state.props.open ?? false,
15
18
  'aria-controls': `overlay-${this.id}`,
16
- 'aria-activedescendant': this.state.selectedItems.at(0)?.id
17
- ? `item-${this.state.selectedItems.at(0)?.id}`
19
+ 'aria-activedescendant': this.state.selections.at(0)?.id
20
+ ? `item-${this.state.selections.at(0)?.id}`
18
21
  : undefined,
19
22
  'aria-disabled': this.state.props.disabled ?? false,
20
23
  tabindex: this.state.props.disabled ? -1 : 0,
21
- oninput: (ev) => {
22
- const target = ev.target;
23
- this.state.props.query = target.value;
24
+ oninput: () => {
25
+ if (!isMultiselect) {
26
+ this.state.props.values = [];
27
+ }
24
28
  },
25
29
  onkeydown: (ev) => {
26
30
  if (this.state.props.disabled)
27
31
  return;
32
+ if (ev.key === 'Enter' && isMultiselect) {
33
+ const currentTarget = ev.currentTarget;
34
+ const value = currentTarget.value.trim();
35
+ if (value !== '') {
36
+ this.state.addSelection(value);
37
+ }
38
+ }
28
39
  },
29
40
  [createAttachmentKey()]: (node) => {
30
41
  this.elements.input = node;
31
42
  }
32
43
  };
33
44
  }
34
- static get = DropdownBond.get;
35
- static set = DropdownBond.set;
45
+ static get() {
46
+ return super.get();
47
+ }
48
+ static set(context) {
49
+ return super.set(context);
50
+ }
36
51
  }
37
52
  export class ComboboxBondState extends DropdownBondState {
38
- // #items: Map<string, DropdownItemAtom<T>> = new SvelteMap();
39
- // #selectedItems = $derived(
40
- // this.props.values?.map((id) => this.#items.get(id)).filter(Boolean) ?? []
41
- // ) as DropdownItemAtom<T>[];
42
- // #value: string = $state('');
43
- // #query: string = $state('');
53
+ #userSelections = new SvelteMap();
44
54
  constructor(props) {
45
55
  super(props);
46
56
  }
57
+ addSelection(label) {
58
+ const id = nanoid();
59
+ // eslint-disable-next-line svelte/prefer-svelte-reactivity
60
+ const createdAt = new Date();
61
+ this.#userSelections.set(id, {
62
+ id,
63
+ label,
64
+ createdAt,
65
+ unselect: () => this.deleteSelection(id)
66
+ });
67
+ this.updateLabels();
68
+ }
69
+ deleteSelection(id) {
70
+ this.#userSelections.delete(id);
71
+ this.updateLabels();
72
+ }
73
+ get userSelections() {
74
+ return Array.from(this.#userSelections.values());
75
+ }
76
+ get allSelections() {
77
+ const itemSelections = this.selections.map((controller) => ({
78
+ id: controller.id,
79
+ label: controller.label,
80
+ createdAt: controller.createdAt, // default date for items from the list
81
+ controller,
82
+ unselect: () => this.unselect([controller.id])
83
+ }));
84
+ return [...itemSelections, ...this.userSelections].sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
85
+ }
86
+ updateLabels() {
87
+ const labels = this.allSelections.map((s) => s.label);
88
+ this.props.labels = labels;
89
+ this.props.label = labels[0] ?? '';
90
+ }
47
91
  }
@@ -1,15 +1,17 @@
1
1
  <script lang="ts">
2
- import { onMount } from 'svelte';
2
+ import { onMount, untrack } from 'svelte';
3
3
  import { Input } from '../input';
4
4
  import { ComboboxBond } from './bond.svelte';
5
+ import type { ComboboxControlProps } from './types';
5
6
 
6
- const bond = ComboboxBond.get() as ComboboxBond<{}>;
7
+ const bond = ComboboxBond.get() as ComboboxBond;
7
8
 
8
9
  if (!bond) {
9
10
  throw new Error('Combobox atom was not found');
10
11
  }
11
12
 
12
13
  let {
14
+ value = $bindable(),
13
15
  class: klass = '',
14
16
  children = undefined,
15
17
  onmount = undefined,
@@ -19,7 +21,7 @@
19
21
  exit = undefined,
20
22
  initial = undefined,
21
23
  ...restProps
22
- } = $props();
24
+ }: ComboboxControlProps = $props();
23
25
 
24
26
  let isMounted = $state(false);
25
27
 
@@ -27,18 +29,31 @@
27
29
  isMounted = true;
28
30
  });
29
31
 
30
- const isMultiple = $derived(bond?.state.props?.multiple ?? false);
31
- const selectedText = $derived(
32
- isMounted || isMultiple ? (bond.state.selectedItems.at(0)?.text ?? '') : ''
33
- );
32
+ const isMultiselect = untrack(() => bond.state.props.multiple);
34
33
 
35
- const value = $derived(
36
- bond?.state.props?.query ?? (bond?.state.props?.text || selectedText || '')
37
- );
34
+ $effect(() => {
35
+ bond.state.allSelections;
36
+
37
+ if (isMultiselect) {
38
+ value = '';
39
+ } else {
40
+ value = untrack(() => bond.state.props.label);
41
+ }
42
+ });
43
+
44
+ const comboboxProps = $derived({
45
+ ...bond.control(),
46
+ ...restProps
47
+ });
38
48
  </script>
39
49
 
40
50
  <Input.Control
41
- {value}
51
+ bind:value={
52
+ () => value,
53
+ (v) => {
54
+ value = v;
55
+ }
56
+ }
42
57
  preset="combobox.control"
43
58
  class={['border-border flex-1 py-1', '$preset', klass]}
44
59
  enter={enter?.bind(bond.state)}
@@ -47,6 +62,5 @@
47
62
  animate={animate?.bind(bond.state)}
48
63
  onmount={onmount?.bind(bond.state)}
49
64
  ondestroy={ondestroy?.bind(bond.state)}
50
- {...bond.control()}
51
- {...restProps}
65
+ {...comboboxProps}
52
66
  />
@@ -1,12 +1,4 @@
1
- declare const ComboboxControl: import("svelte").Component<{
2
- class?: string;
3
- children?: any;
4
- onmount?: any;
5
- ondestroy?: any;
6
- animate?: any;
7
- enter?: any;
8
- exit?: any;
9
- initial?: any;
10
- } & Record<string, any>, {}, "">;
1
+ import type { ComboboxControlProps } from './types';
2
+ declare const ComboboxControl: import("svelte").Component<ComboboxControlProps, {}, "value">;
11
3
  type ComboboxControl = ReturnType<typeof ComboboxControl>;
12
4
  export default ComboboxControl;
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { on } from '../../attachments';
7
7
 
8
- const bond = ComboboxBond.get() as ComboboxBond<{}>;
8
+ const bond = ComboboxBond.get() as ComboboxBond;
9
9
 
10
10
  if (!bond) {
11
11
  throw new Error('Combobox atom was not found');
@@ -38,9 +38,9 @@
38
38
  | undefined;
39
39
 
40
40
  // Set selected item text
41
- bond.state.props.text = textElement?.innerText ?? '';
41
+ bond.state.props.label = textElement?.innerText ?? '';
42
42
  // Clear input query
43
- bond.state.props.query = '';
43
+ bond.state.props.label = '';
44
44
 
45
45
  item?.toggle();
46
46