lithesome 0.2.4 → 0.3.0

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 (70) hide show
  1. package/dist/components/Accordion/Accordion.svelte +3 -4
  2. package/dist/components/Accordion/AccordionButton.svelte +3 -6
  3. package/dist/components/Accordion/AccordionContent.svelte +3 -4
  4. package/dist/components/Accordion/AccordionHeading.svelte +3 -4
  5. package/dist/components/Accordion/AccordionItem.svelte +3 -4
  6. package/dist/components/Checkbox/Checkbox.svelte +7 -5
  7. package/dist/components/Checkbox/Checkbox.svelte.d.ts +1 -0
  8. package/dist/components/Combobox/Combobox.svelte +55 -0
  9. package/dist/components/Combobox/Combobox.svelte.d.ts +50 -0
  10. package/dist/components/Combobox/ComboboxDropdown.svelte +83 -0
  11. package/dist/components/Combobox/ComboboxDropdown.svelte.d.ts +33 -0
  12. package/dist/components/Combobox/ComboboxInput.svelte +82 -0
  13. package/dist/components/Combobox/ComboboxInput.svelte.d.ts +23 -0
  14. package/dist/components/Combobox/ComboboxOption.svelte +75 -0
  15. package/dist/components/Combobox/ComboboxOption.svelte.d.ts +25 -0
  16. package/dist/components/Combobox/context.svelte.d.ts +40 -0
  17. package/dist/components/Combobox/context.svelte.js +136 -0
  18. package/dist/components/Combobox/index.d.ts +4 -0
  19. package/dist/components/Combobox/index.js +4 -0
  20. package/dist/components/Menu/Menu.svelte +3 -4
  21. package/dist/components/Menu/MenuDropdown.svelte +4 -4
  22. package/dist/components/Menu/MenuItem.svelte +3 -4
  23. package/dist/components/Menu/MenuTrigger.svelte +9 -3
  24. package/dist/components/Modal/Modal.svelte +11 -4
  25. package/dist/components/Modal/ModalContent.svelte +3 -4
  26. package/dist/components/Modal/ModalDescription.svelte +3 -4
  27. package/dist/components/Modal/ModalOverlay.svelte +6 -3
  28. package/dist/components/Modal/ModalOverlay.svelte.d.ts +2 -2
  29. package/dist/components/Modal/ModalTitle.svelte +3 -4
  30. package/dist/components/Pin/Pin.svelte +4 -5
  31. package/dist/components/Pin/PinInput.svelte +32 -24
  32. package/dist/components/Pin/PinInput.svelte.d.ts +3 -3
  33. package/dist/components/Pin/PinValue.svelte +3 -4
  34. package/dist/components/Pin/PinValue.svelte.d.ts +2 -2
  35. package/dist/components/Popover/Popover.svelte +3 -4
  36. package/dist/components/Popover/PopoverContent.svelte +4 -4
  37. package/dist/components/Popover/PopoverTrigger.svelte +10 -4
  38. package/dist/components/RadioGroup/RadioGroup.svelte +11 -4
  39. package/dist/components/RadioGroup/RadioGroupItem.svelte +4 -4
  40. package/dist/components/Select/Select.svelte +5 -7
  41. package/dist/components/Select/Select.svelte.d.ts +16 -18
  42. package/dist/components/Select/SelectDropdown.svelte +4 -4
  43. package/dist/components/Select/SelectOption.svelte +39 -21
  44. package/dist/components/Select/SelectOption.svelte.d.ts +1 -0
  45. package/dist/components/Select/SelectTrigger.svelte +4 -4
  46. package/dist/components/Select/SelectValue.svelte +4 -5
  47. package/dist/components/Select/SelectValue.svelte.d.ts +3 -3
  48. package/dist/components/Select/context.svelte.d.ts +9 -11
  49. package/dist/components/Select/context.svelte.js +23 -22
  50. package/dist/components/Tabs/Tabs.svelte +2 -3
  51. package/dist/components/Tabs/TabsButton.svelte +3 -3
  52. package/dist/components/Tabs/TabsContent.svelte +2 -3
  53. package/dist/components/Tabs/TabsList.svelte +2 -3
  54. package/dist/index.d.ts +1 -0
  55. package/dist/index.js +1 -0
  56. package/dist/internal/helpers/anchor.js +1 -1
  57. package/dist/internal/helpers/element.d.ts +28 -0
  58. package/dist/internal/helpers/element.js +40 -1
  59. package/dist/internal/helpers/is.d.ts +3 -0
  60. package/dist/internal/helpers/is.js +3 -0
  61. package/dist/internal/helpers/keyboard.js +4 -1
  62. package/dist/internal/helpers/log.d.ts +3 -0
  63. package/dist/internal/helpers/log.js +5 -0
  64. package/dist/internal/helpers/utils.svelte.d.ts +34 -0
  65. package/dist/internal/helpers/{utils.js → utils.svelte.js} +28 -7
  66. package/dist/internal/index.d.ts +2 -1
  67. package/dist/internal/index.js +2 -1
  68. package/dist/internal/types.d.ts +1 -0
  69. package/package.json +2 -2
  70. package/dist/internal/helpers/utils.d.ts +0 -15
@@ -4,16 +4,15 @@ const contextName = "accordion-context";
4
4
  export const context = () => getContext(contextName);
5
5
  </script>
6
6
 
7
- <script>import { createUID, useActions } from "../../internal/index.js";
7
+ <script>import { createUID, useActions, classProp } from "../../internal/index.js";
8
8
  import { setContext } from "svelte";
9
- let { children, use = [], class: klass, self, single, ...props } = $props();
9
+ let { children, use = [], class: klass, self = $bindable(), single, ...props } = $props();
10
10
  const { uid } = createUID("accordion");
11
11
  const API = createContext(uid, single);
12
12
  const active = $derived(API.activeItems.length > 0);
13
- const classProp = $derived(typeof klass === "function" ? klass({ active }) : klass);
14
13
  setContext(contextName, API);
15
14
  </script>
16
15
 
17
- <div bind:this={self} use:useActions={use} id={uid()} class={classProp} data-accordion="" {...props}>
16
+ <div bind:this={self} use:useActions={use} id={uid()} class={classProp(klass, { active })} data-accordion="" {...props}>
18
17
  {@render children({ active })}
19
18
  </div>
@@ -1,14 +1,11 @@
1
1
  <script>import { context } from "./Accordion.svelte";
2
- import { useActions } from "../../internal/index.js";
2
+ import { useActions, classProp } from "../../internal/index.js";
3
3
  import { getContext } from "svelte";
4
- let { children, class: klass, use = [], self, onClick, ...props } = $props();
4
+ let { children, class: klass, use = [], self = $bindable(), onClick, ...props } = $props();
5
5
  const API = context();
6
6
  const itemId = getContext("accordionitem-id");
7
7
  const active = $derived(API.activeItems.includes(itemId));
8
8
  const item = $derived(API.items.find((el) => el.id === itemId));
9
- const classProp = $derived(
10
- typeof klass === "function" ? klass({ active, disabled: item?.disabled || false }) : klass
11
- );
12
9
  const handleClick = (e) => {
13
10
  onClick?.(e);
14
11
  if (!item?.disabled)
@@ -20,7 +17,7 @@ const handleClick = (e) => {
20
17
  type="button"
21
18
  bind:this={self}
22
19
  use:useActions={use}
23
- class={classProp}
20
+ class={classProp(klass, { active, disabled: item?.disabled || false })}
24
21
  aria-expanded={active}
25
22
  aria-disabled={item?.disabled}
26
23
  aria-controls={active ? API.uid('content') : undefined}
@@ -1,17 +1,16 @@
1
1
  <script>import { context } from "./Accordion.svelte";
2
- import { useActions, getTransition } from "../../internal/index.js";
2
+ import { useActions, getTransition, classProp } from "../../internal/index.js";
3
3
  import { getContext } from "svelte";
4
- let { children, class: klass, use = [], self, transition, ...props } = $props();
4
+ let { children, class: klass, use = [], self = $bindable(), transition, ...props } = $props();
5
5
  const API = context();
6
6
  const itemId = getContext("accordionitem-id");
7
7
  const active = $derived(API.activeItems.includes(itemId));
8
- const classProp = $derived(typeof klass === "function" ? klass({ active }) : klass);
9
8
  const _transition = getTransition(transition);
10
9
  const attrs = $derived({
11
10
  id: API.uid("content"),
12
11
  "data-accordioncontent": "",
13
12
  "data-active": active || void 0,
14
- class: classProp
13
+ class: classProp(klass, { active })
15
14
  });
16
15
  </script>
17
16
 
@@ -1,12 +1,11 @@
1
- <script>import { useActions } from "../../internal/index.js";
2
- let { children, class: klass, use = [], level = 3, self, ...props } = $props();
3
- const classProp = $derived(typeof klass === "function" ? klass({}) : klass);
1
+ <script>import { useActions, classProp } from "../../internal/index.js";
2
+ let { children, class: klass, use = [], level = 3, self = $bindable(), ...props } = $props();
4
3
  </script>
5
4
 
6
5
  <div
7
6
  bind:this={self}
8
7
  use:useActions={use}
9
- class={classProp}
8
+ class={classProp(klass)}
10
9
  role="heading"
11
10
  aria-level={level}
12
11
  data-accordionheading=""
@@ -1,7 +1,7 @@
1
1
  <script>import { context } from "./Accordion.svelte";
2
- import { log, useActions, createUID } from "../../internal/index.js";
2
+ import { log, useActions, createUID, classProp } from "../../internal/index.js";
3
3
  import { onMount, setContext } from "svelte";
4
- let { children, class: klass, use = [], self, disabled = false, ...props } = $props();
4
+ let { children, class: klass, use = [], self = $bindable(), disabled = false, ...props } = $props();
5
5
  const API = context();
6
6
  const { uid } = createUID("item");
7
7
  onMount(() => {
@@ -13,7 +13,6 @@ onMount(() => {
13
13
  });
14
14
  });
15
15
  const active = $derived(API.activeItems.includes(uid()));
16
- const classProp = $derived(typeof klass === "function" ? klass({ active }) : klass);
17
16
  setContext("accordionitem-id", uid());
18
17
  $effect(() => {
19
18
  API.setDisabled(uid(), disabled);
@@ -24,7 +23,7 @@ $effect(() => {
24
23
  bind:this={self}
25
24
  use:useActions={use}
26
25
  id={uid()}
27
- class={classProp}
26
+ class={classProp(klass, { active })}
28
27
  data-accordionitem=""
29
28
  data-disabled={disabled || undefined}
30
29
  data-state={active ? 'opened' : 'closed'}
@@ -1,18 +1,20 @@
1
1
  <script context="module"></script>
2
2
 
3
- <script>import { useActions } from "../../internal/index.js";
3
+ <script>import {
4
+ useActions,
5
+ classProp
6
+ } from "../../internal/index.js";
4
7
  let {
5
8
  children,
6
9
  class: klass,
7
10
  use = [],
8
- self,
9
- checked = false,
11
+ self = $bindable(),
12
+ checked = $bindable(false),
10
13
  required = false,
11
14
  disabled = false,
12
15
  onClick,
13
16
  ...props
14
17
  } = $props();
15
- const classProp = $derived(typeof klass === "function" ? klass({ checked }) : klass);
16
18
  const handleClick = (e) => {
17
19
  onClick?.(e);
18
20
  if (disabled)
@@ -25,7 +27,7 @@ const handleClick = (e) => {
25
27
  type="button"
26
28
  bind:this={self}
27
29
  use:useActions={use}
28
- class={classProp}
30
+ class={classProp(klass, { checked })}
29
31
  role="checkbox"
30
32
  aria-checked={checked}
31
33
  aria-required={required}
@@ -22,6 +22,7 @@ declare const __propDef: {
22
22
  contextmenu?: string | null | undefined;
23
23
  dir?: string | null | undefined;
24
24
  draggable?: import("svelte/elements").Booleanish | null | undefined;
25
+ elementtiming?: string | null | undefined;
25
26
  enterkeyhint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | null | undefined;
26
27
  hidden?: boolean | null | undefined;
27
28
  id?: string | null | undefined;
@@ -0,0 +1,55 @@
1
+ <script context="module">import { getContext, onMount, tick } from "svelte";
2
+ import { createContext } from "./context.svelte.js";
3
+ const contextName = "combobox-context";
4
+ export const context = () => getContext(contextName);
5
+ </script>
6
+
7
+ <script generics="ValueType">import { createUID, useActions, classProp } from "../../internal/index.js";
8
+ import { setContext } from "svelte";
9
+ let {
10
+ children,
11
+ use = [],
12
+ class: klass,
13
+ value = $bindable(),
14
+ label = $bindable(),
15
+ touched = $bindable(),
16
+ self = $bindable(),
17
+ onChange,
18
+ ...props
19
+ } = $props();
20
+ const { uid } = createUID("combobox");
21
+ const multiple = Array.isArray(value);
22
+ const API = createContext(uid, multiple, {
23
+ onChange({ newValue, newTouched, newLabel }) {
24
+ if (newValue) {
25
+ value = newValue;
26
+ onChange?.({ value: newValue });
27
+ }
28
+ if (newLabel && !multiple) {
29
+ label = newLabel;
30
+ onChange?.({ label: newLabel });
31
+ }
32
+ if (typeof newTouched === "boolean")
33
+ touched = newTouched;
34
+ }
35
+ });
36
+ setContext(contextName, API);
37
+ onMount(async () => {
38
+ await tick();
39
+ API.setInitialSelected(value);
40
+ API.close();
41
+ API.setMounted(true);
42
+ });
43
+ </script>
44
+
45
+ <div
46
+ bind:this={self}
47
+ use:useActions={use}
48
+ id={uid()}
49
+ class={classProp(klass, { visible: API.visible && API.mounted })}
50
+ data-select=""
51
+ data-state={API.visible && API.mounted ? 'opened' : 'closed'}
52
+ {...props}
53
+ >
54
+ {@render children({ visible: API.visible && API.mounted })}
55
+ </div>
@@ -0,0 +1,50 @@
1
+ import { SvelteComponent } from "svelte";
2
+ export declare const context: () => {
3
+ visible: boolean;
4
+ hoveredIndex: number;
5
+ options: HTMLElement[];
6
+ touched: HTMLElement[];
7
+ dropdown: HTMLElement | null;
8
+ mounted: boolean;
9
+ selectedOptions: HTMLElement[];
10
+ hoveredOption: HTMLElement;
11
+ trigger: HTMLInputElement | null;
12
+ multiple: boolean;
13
+ open(): void;
14
+ close(): void;
15
+ toggle(): void;
16
+ queryElements(): void;
17
+ navigateOptions(action: import("../../internal/index.js").CalcIndexAction): void;
18
+ setHoveredOption(optionId?: string | undefined): void;
19
+ setSelectedOptions(): void;
20
+ setInitialSelected(value: unknown): Promise<void>;
21
+ setTrigger(node: HTMLInputElement): void;
22
+ setDropdown(node: HTMLElement): void;
23
+ setMounted(value: boolean): void;
24
+ setTouched(value: boolean): void;
25
+ uid: import("../../internal/index.js").UID;
26
+ };
27
+ import { type BaseProps } from '../../internal/index.js';
28
+ declare class __sveltets_Render<ValueType> {
29
+ props(): BaseProps<HTMLDivElement, {
30
+ visible: boolean;
31
+ }> & {
32
+ value: ValueType;
33
+ label?: string | undefined;
34
+ touched?: boolean | undefined;
35
+ onChange?: ((payload?: {
36
+ value?: ValueType | undefined;
37
+ label?: string | undefined;
38
+ } | undefined) => void) | undefined;
39
+ };
40
+ events(): {} & {
41
+ [evt: string]: CustomEvent<any>;
42
+ };
43
+ slots(): {};
44
+ }
45
+ export type ComboboxProps<ValueType> = ReturnType<__sveltets_Render<ValueType>['props']>;
46
+ export type ComboboxEvents<ValueType> = ReturnType<__sveltets_Render<ValueType>['events']>;
47
+ export type ComboboxSlots<ValueType> = ReturnType<__sveltets_Render<ValueType>['slots']>;
48
+ export default class Combobox<ValueType> extends SvelteComponent<ComboboxProps<ValueType>, ComboboxEvents<ValueType>, ComboboxSlots<ValueType>> {
49
+ }
50
+ export {};
@@ -0,0 +1,83 @@
1
+ <script>import { context } from "./Combobox.svelte";
2
+ import {
3
+ clickOutside,
4
+ anchorElement,
5
+ portal,
6
+ useActions,
7
+ getTransition,
8
+ classProp
9
+ } from "../../internal/index.js";
10
+ import { log } from "../../internal/index.js";
11
+ import { onMount } from "svelte";
12
+ let {
13
+ children,
14
+ transition,
15
+ use = [],
16
+ portalTarget = "body",
17
+ sameWidth = false,
18
+ class: klass,
19
+ self = $bindable(),
20
+ placement = "bottom",
21
+ constrainViewport = false,
22
+ ...props
23
+ } = $props();
24
+ const API = context();
25
+ let dropdownCleanup = $state(void 0);
26
+ const _transition = getTransition(transition);
27
+ const attrs = $derived({
28
+ id: API.uid("dropdown"),
29
+ "aria-labelledby": API.uid("trigger"),
30
+ role: "listbox",
31
+ class: classProp(klass, { visible: API.visible }),
32
+ "data-comboboxdropdown": "",
33
+ hidden: !API.mounted || void 0
34
+ });
35
+ onMount(() => {
36
+ if (!API)
37
+ log.error("<ComboboxDropdown> Must be a direct child of <Combobox />");
38
+ });
39
+ $effect(() => {
40
+ if (API.visible && self)
41
+ API.setDropdown(self);
42
+ });
43
+ $effect(() => {
44
+ if (API.visible && API.trigger && API.dropdown) {
45
+ dropdownCleanup = anchorElement(API.trigger, API.dropdown, {
46
+ placement,
47
+ constrainViewport,
48
+ sameWidth
49
+ });
50
+ }
51
+ return () => {
52
+ dropdownCleanup?.();
53
+ };
54
+ });
55
+ </script>
56
+
57
+ {#if _transition}
58
+ {#if API.visible}
59
+ <div
60
+ bind:this={self}
61
+ use:clickOutside={{ exclude: [API.trigger], callback: API.close }}
62
+ use:portal={portalTarget}
63
+ use:useActions={use}
64
+ in:_transition.in.fn={_transition.in.params}
65
+ out:_transition.out.fn={_transition.out.params}
66
+ {...attrs}
67
+ {...props}
68
+ >
69
+ {@render children({ visible: API.visible })}
70
+ </div>
71
+ {/if}
72
+ {:else if API.visible}
73
+ <div
74
+ bind:this={self}
75
+ use:clickOutside={{ exclude: [API.trigger], callback: API.close }}
76
+ use:portal={portalTarget}
77
+ use:useActions={use}
78
+ {...attrs}
79
+ {...props}
80
+ >
81
+ {@render children({ visible: API.visible })}
82
+ </div>
83
+ {/if}
@@ -0,0 +1,33 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type Transition, type BaseProps } from '../../internal/index.js';
3
+ import type { Placement } from '@floating-ui/dom';
4
+ declare const __propDef: {
5
+ props: BaseProps<HTMLDivElement, {
6
+ visible: boolean;
7
+ }> & {
8
+ /**
9
+ * The `svelte/transtion` you wish to use.
10
+ *
11
+ * @see https://lithesome.dev/docs/api#transition-prop
12
+ */
13
+ transition?: Transition | undefined;
14
+ /** The element to portal the dropdown menu to. */
15
+ portalTarget?: string | HTMLElement | undefined;
16
+ /** The anchor point of the dropdown relative to the trigger. */
17
+ placement?: Placement | undefined;
18
+ /** Keeps the dropdown from ever growing outside of the viewport. */
19
+ constrainViewport?: boolean | undefined;
20
+ /** Makes the dropdown the same width as the trigger. */
21
+ sameWidth?: boolean | undefined;
22
+ };
23
+ events: {
24
+ [evt: string]: CustomEvent<any>;
25
+ };
26
+ slots: {};
27
+ };
28
+ export type ComboboxDropdownProps = typeof __propDef.props;
29
+ export type ComboboxDropdownEvents = typeof __propDef.events;
30
+ export type ComboboxDropdownSlots = typeof __propDef.slots;
31
+ export default class ComboboxDropdown extends SvelteComponent<ComboboxDropdownProps, ComboboxDropdownEvents, ComboboxDropdownSlots> {
32
+ }
33
+ export {};
@@ -0,0 +1,82 @@
1
+ <script>import { context } from "./Combobox.svelte";
2
+ import {
3
+ useActions,
4
+ classProp,
5
+ PREVENT_KEYS,
6
+ KEYS
7
+ } from "../../internal/index.js";
8
+ import { onMount } from "svelte";
9
+ let {
10
+ class: klass,
11
+ use = [],
12
+ value = $bindable(),
13
+ self = $bindable(),
14
+ disabled,
15
+ onClick,
16
+ onFocus,
17
+ onKeydown,
18
+ ...props
19
+ } = $props();
20
+ const API = context();
21
+ onMount(() => {
22
+ if (!API || !self)
23
+ return;
24
+ API.setTrigger(self);
25
+ });
26
+ const handleClick = (e) => {
27
+ onClick?.(e);
28
+ if (disabled)
29
+ return;
30
+ API.toggle();
31
+ };
32
+ const handleKeydown = (e) => {
33
+ onKeydown?.(e);
34
+ if (disabled)
35
+ return;
36
+ const { key } = e;
37
+ if (!PREVENT_KEYS.includes(key)) {
38
+ API.setTouched(true);
39
+ if (!API.visible)
40
+ API.open();
41
+ }
42
+ if (key === KEYS.arrowUp || key === KEYS.arrowDown || key === KEYS.end || key === KEYS.home) {
43
+ e.preventDefault();
44
+ if (!API.visible)
45
+ API.open();
46
+ }
47
+ if (key === KEYS.home)
48
+ API.navigateOptions("first");
49
+ if (key === KEYS.end)
50
+ API.navigateOptions("last");
51
+ if (key === KEYS.arrowUp)
52
+ API.navigateOptions("prev");
53
+ if (key === KEYS.arrowDown)
54
+ API.navigateOptions("next");
55
+ if (key === KEYS.escape)
56
+ API.close();
57
+ if (key === KEYS.enter) {
58
+ e.preventDefault();
59
+ if (API.hoveredOption && API.visible) {
60
+ document.querySelector(`#${API.hoveredOption.id}`).click();
61
+ if (!API.multiple)
62
+ API.close();
63
+ } else {
64
+ API.open();
65
+ }
66
+ }
67
+ if (key === "Tab")
68
+ API.close();
69
+ };
70
+ </script>
71
+
72
+ <input
73
+ type="text"
74
+ bind:this={self}
75
+ use:useActions={use}
76
+ id={API.uid('input')}
77
+ class={classProp(klass, { visible: API.visible })}
78
+ onclick={handleClick}
79
+ onkeydown={handleKeydown}
80
+ bind:value
81
+ {...props}
82
+ />
@@ -0,0 +1,23 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type BasePropsNoChildren, type Handler } from '../../internal/index.js';
3
+ declare const __propDef: {
4
+ props: BasePropsNoChildren<HTMLInputElement, {
5
+ visible: boolean;
6
+ }> & {
7
+ value: string;
8
+ disabled?: boolean | undefined;
9
+ onClick?: Handler<MouseEvent, HTMLInputElement> | undefined;
10
+ onFocus?: Handler<FocusEvent, HTMLInputElement> | undefined;
11
+ onKeydown?: Handler<KeyboardEvent, HTMLInputElement> | undefined;
12
+ };
13
+ events: {
14
+ [evt: string]: CustomEvent<any>;
15
+ };
16
+ slots: {};
17
+ };
18
+ export type ComboboxInputProps = typeof __propDef.props;
19
+ export type ComboboxInputEvents = typeof __propDef.events;
20
+ export type ComboboxInputSlots = typeof __propDef.slots;
21
+ export default class ComboboxInput extends SvelteComponent<ComboboxInputProps, ComboboxInputEvents, ComboboxInputSlots> {
22
+ }
23
+ export {};
@@ -0,0 +1,75 @@
1
+ <script>import { context } from "./Combobox.svelte";
2
+ import {
3
+ useActions,
4
+ classProp,
5
+ isBrowser
6
+ } from "../../internal/index.js";
7
+ import { createUID } from "../../internal/index.js";
8
+ import { onMount, tick } from "svelte";
9
+ let {
10
+ children,
11
+ class: klass,
12
+ use = [],
13
+ value,
14
+ label: labelProp,
15
+ self = $bindable(),
16
+ disabled,
17
+ onClick,
18
+ onFocus,
19
+ onMouseenter,
20
+ ...props
21
+ } = $props();
22
+ let optionEl;
23
+ const API = context();
24
+ const { uid } = createUID("item");
25
+ const hovered = $derived(API.hoveredOption?.id === uid());
26
+ const selected = $derived(!!API.selectedOptions.find((el) => el.dataset.value === value));
27
+ const label = $derived(labelProp || isBrowser && self ? self?.textContent?.trim() : "");
28
+ const handleClick = (e) => {
29
+ onClick?.(e);
30
+ if (!disabled) {
31
+ API.setSelectedOptions();
32
+ }
33
+ };
34
+ const handleFocus = (e) => {
35
+ onFocus?.(e);
36
+ };
37
+ const handleMouseover = (e) => {
38
+ onMouseenter?.(e);
39
+ if (!disabled)
40
+ API.setHoveredOption(uid());
41
+ };
42
+ onMount(() => {
43
+ API.queryElements();
44
+ return async () => {
45
+ if (!API.visible)
46
+ return;
47
+ await tick();
48
+ API.queryElements();
49
+ };
50
+ });
51
+ </script>
52
+
53
+ <button
54
+ bind:this={self}
55
+ bind:this={optionEl}
56
+ use:useActions={use}
57
+ id={uid()}
58
+ class={classProp(klass, { hovered, selected })}
59
+ type="button"
60
+ {disabled}
61
+ role="option"
62
+ tabindex="0"
63
+ aria-selected={selected}
64
+ data-hovered={hovered ? '' : undefined}
65
+ data-selected={selected ? '' : undefined}
66
+ data-comboboxoption=""
67
+ data-value={value}
68
+ data-label={label}
69
+ onmouseover={handleMouseover}
70
+ onfocus={handleFocus}
71
+ onclick={handleClick}
72
+ {...props}
73
+ >
74
+ {@render children({ hovered, selected })}
75
+ </button>
@@ -0,0 +1,25 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type BaseProps, type JsonValue, type Handler } from '../../internal/index.js';
3
+ declare const __propDef: {
4
+ props: BaseProps<HTMLButtonElement | HTMLAnchorElement, {
5
+ hovered: boolean;
6
+ selected: boolean;
7
+ }> & {
8
+ value: JsonValue;
9
+ disabled?: boolean | undefined;
10
+ label?: string | undefined;
11
+ onClick?: Handler<MouseEvent, HTMLButtonElement | HTMLAnchorElement> | undefined;
12
+ onFocus?: Handler<FocusEvent, HTMLButtonElement | HTMLAnchorElement> | undefined;
13
+ onMouseenter?: Handler<MouseEvent, HTMLButtonElement | HTMLAnchorElement> | undefined;
14
+ };
15
+ events: {
16
+ [evt: string]: CustomEvent<any>;
17
+ };
18
+ slots: {};
19
+ };
20
+ export type ComboboxOptionProps = typeof __propDef.props;
21
+ export type ComboboxOptionEvents = typeof __propDef.events;
22
+ export type ComboboxOptionSlots = typeof __propDef.slots;
23
+ export default class ComboboxOption extends SvelteComponent<ComboboxOptionProps, ComboboxOptionEvents, ComboboxOptionSlots> {
24
+ }
25
+ export {};
@@ -0,0 +1,40 @@
1
+ import { type CalcIndexAction, type UID, type JsonValue } from '../../internal/index.js';
2
+ export interface Option {
3
+ value: JsonValue;
4
+ label: string;
5
+ id: string;
6
+ disabled?: boolean;
7
+ }
8
+ interface Hooks<ValueType> {
9
+ onChange: (values: {
10
+ newValue?: ValueType;
11
+ newTouched?: boolean;
12
+ newLabel?: string;
13
+ }) => void;
14
+ }
15
+ export declare const createContext: <ValueType>(uid: UID, multiple: boolean | undefined, hooks: Hooks<ValueType>) => {
16
+ visible: boolean;
17
+ hoveredIndex: number;
18
+ options: HTMLElement[];
19
+ touched: HTMLElement[];
20
+ dropdown: HTMLElement | null;
21
+ mounted: boolean;
22
+ selectedOptions: HTMLElement[];
23
+ hoveredOption: HTMLElement;
24
+ trigger: HTMLInputElement | null;
25
+ multiple: boolean;
26
+ open(): void;
27
+ close(): void;
28
+ toggle(): void;
29
+ queryElements(): void;
30
+ navigateOptions(action: CalcIndexAction): void;
31
+ setHoveredOption(optionId?: string): void;
32
+ setSelectedOptions(): void;
33
+ setInitialSelected(value: ValueType): Promise<void>;
34
+ setTrigger(node: HTMLInputElement): void;
35
+ setDropdown(node: HTMLElement): void;
36
+ setMounted(value: boolean): void;
37
+ setTouched(value: boolean): void;
38
+ uid: UID;
39
+ };
40
+ export {};