lithesome 0.3.1 → 0.3.2
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.
- package/dist/components/Accordion/Accordion.svelte +16 -7
- package/dist/components/Accordion/Accordion.svelte.d.ts +4 -3
- package/dist/components/Accordion/AccordionButton.svelte +5 -5
- package/dist/components/Accordion/AccordionContent.svelte +3 -3
- package/dist/components/Accordion/AccordionItem.svelte +9 -9
- package/dist/components/Accordion/AccordionItem.svelte.d.ts +1 -0
- package/dist/components/Accordion/context.svelte.d.ts +9 -5
- package/dist/components/Accordion/context.svelte.js +10 -8
- package/dist/components/Combobox/Combobox.svelte +24 -22
- package/dist/components/Combobox/Combobox.svelte.d.ts +11 -11
- package/dist/components/Combobox/ComboboxDropdown.svelte +16 -16
- package/dist/components/Combobox/ComboboxInput.svelte +23 -23
- package/dist/components/Combobox/ComboboxOption.svelte +9 -9
- package/dist/components/Combobox/context.svelte.d.ts +17 -14
- package/dist/components/Combobox/context.svelte.js +9 -11
- package/dist/components/Menu/Menu.svelte +7 -8
- package/dist/components/Menu/Menu.svelte.d.ts +7 -7
- package/dist/components/Menu/MenuDropdown.svelte +15 -15
- package/dist/components/Menu/MenuItem.svelte +7 -7
- package/dist/components/Menu/MenuTrigger.svelte +21 -21
- package/dist/components/Menu/context.svelte.d.ts +9 -9
- package/dist/components/Menu/context.svelte.js +6 -12
- package/dist/components/Modal/Modal.svelte +3 -3
- package/dist/components/Modal/Modal.svelte.d.ts +2 -2
- package/dist/components/Modal/ModalContent.svelte +6 -6
- package/dist/components/Modal/ModalDescription.svelte +2 -2
- package/dist/components/Modal/ModalOverlay.svelte +4 -4
- package/dist/components/Modal/ModalTitle.svelte +2 -2
- package/dist/components/Modal/context.svelte.d.ts +7 -4
- package/dist/components/Modal/context.svelte.js +7 -9
- package/dist/components/Pin/Pin.svelte +13 -15
- package/dist/components/Pin/Pin.svelte.d.ts +8 -8
- package/dist/components/Pin/PinInput.svelte +20 -20
- package/dist/components/Pin/PinValue.svelte +4 -5
- package/dist/components/Pin/context.svelte.d.ts +15 -16
- package/dist/components/Pin/context.svelte.js +11 -13
- package/dist/components/Popover/Popover.svelte.d.ts +4 -4
- package/dist/components/Popover/context.svelte.d.ts +8 -6
- package/dist/components/Popover/context.svelte.js +8 -10
- package/dist/components/RadioGroup/RadioGroup.svelte +9 -6
- package/dist/components/RadioGroup/RadioGroupItem.svelte +1 -1
- package/dist/components/RadioGroup/context.svelte.d.ts +8 -5
- package/dist/components/RadioGroup/context.svelte.js +7 -9
- package/dist/components/Select/Select.svelte +15 -13
- package/dist/components/Select/Select.svelte.d.ts +10 -10
- package/dist/components/Select/SelectDropdown.svelte +16 -16
- package/dist/components/Select/SelectOption.svelte +1 -1
- package/dist/components/Select/SelectTrigger.svelte +24 -24
- package/dist/components/Select/SelectValue.svelte +4 -4
- package/dist/components/Select/context.svelte.d.ts +15 -12
- package/dist/components/Select/context.svelte.js +7 -9
- package/dist/components/Tabs/Tabs.svelte +7 -8
- package/dist/components/Tabs/Tabs.svelte.d.ts +4 -4
- package/dist/components/Tabs/TabsButton.svelte +10 -10
- package/dist/components/Tabs/TabsContent.svelte +3 -3
- package/dist/components/Tabs/TabsList.svelte +3 -3
- package/dist/components/Tabs/context.svelte.d.ts +7 -7
- package/dist/components/Tabs/context.svelte.js +8 -10
- package/package.json +1 -1
|
@@ -4,15 +4,24 @@ const contextName = "accordion-context";
|
|
|
4
4
|
export const context = () => getContext(contextName);
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
|
-
<script>import {
|
|
7
|
+
<script>import { useActions, classProp } from "../../internal/index.js";
|
|
8
8
|
import { setContext } from "svelte";
|
|
9
|
-
let { children, use = [], class: klass, self = $bindable(), single, ...props } = $props();
|
|
10
|
-
const {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
let { children, use = [], class: klass, self = $bindable(), single = $bindable(false), ...props } = $props();
|
|
10
|
+
const ctx = createContext({ single });
|
|
11
|
+
const active = $derived(ctx.activeItems.length > 0);
|
|
12
|
+
setContext(contextName, ctx);
|
|
13
|
+
$effect(() => {
|
|
14
|
+
ctx.setSingle(single);
|
|
15
|
+
});
|
|
14
16
|
</script>
|
|
15
17
|
|
|
16
|
-
<div
|
|
18
|
+
<div
|
|
19
|
+
bind:this={self}
|
|
20
|
+
use:useActions={use}
|
|
21
|
+
id={ctx.uid()}
|
|
22
|
+
class={classProp(klass, { active })}
|
|
23
|
+
data-accordion=""
|
|
24
|
+
{...props}
|
|
25
|
+
>
|
|
17
26
|
{@render children({ active })}
|
|
18
27
|
</div>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
2
|
export declare const context: () => {
|
|
3
|
-
|
|
4
|
-
activeItems: string[];
|
|
3
|
+
uid: (component?: string | undefined) => string;
|
|
5
4
|
toggle(itemId: string): void;
|
|
6
5
|
register(item: import("./context.svelte.js").Item): void;
|
|
7
6
|
setDisabled(id: string, val: boolean): void;
|
|
8
|
-
|
|
7
|
+
setSingle(val: boolean): void;
|
|
8
|
+
readonly items: import("./context.svelte.js").Item[];
|
|
9
|
+
readonly activeItems: string[];
|
|
9
10
|
};
|
|
10
11
|
import { type BaseProps } from '../../internal/index.js';
|
|
11
12
|
declare const __propDef: {
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import { useActions, classProp } from "../../internal/index.js";
|
|
3
3
|
import { getContext } from "svelte";
|
|
4
4
|
let { children, class: klass, use = [], self = $bindable(), onClick, ...props } = $props();
|
|
5
|
-
const
|
|
5
|
+
const ctx = context();
|
|
6
6
|
const itemId = getContext("accordionitem-id");
|
|
7
|
-
const active = $derived(
|
|
8
|
-
const item = $derived(
|
|
7
|
+
const active = $derived(ctx.activeItems.includes(itemId));
|
|
8
|
+
const item = $derived(ctx.items.find((el) => el.id === itemId));
|
|
9
9
|
const handleClick = (e) => {
|
|
10
10
|
onClick?.(e);
|
|
11
11
|
if (!item?.disabled)
|
|
12
|
-
|
|
12
|
+
ctx.toggle(itemId);
|
|
13
13
|
};
|
|
14
14
|
</script>
|
|
15
15
|
|
|
@@ -20,7 +20,7 @@ const handleClick = (e) => {
|
|
|
20
20
|
class={classProp(klass, { active, disabled: item?.disabled || false })}
|
|
21
21
|
aria-expanded={active}
|
|
22
22
|
aria-disabled={item?.disabled}
|
|
23
|
-
aria-controls={active ?
|
|
23
|
+
aria-controls={active ? ctx.uid('content') : undefined}
|
|
24
24
|
tabindex={item?.disabled ? -1 : 0}
|
|
25
25
|
data-accordionbutton=""
|
|
26
26
|
data-active={active || undefined}
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import { useActions, getTransition, classProp } from "../../internal/index.js";
|
|
3
3
|
import { getContext } from "svelte";
|
|
4
4
|
let { children, class: klass, use = [], self = $bindable(), transition, ...props } = $props();
|
|
5
|
-
const
|
|
5
|
+
const ctx = context();
|
|
6
6
|
const itemId = getContext("accordionitem-id");
|
|
7
|
-
const active = $derived(
|
|
7
|
+
const active = $derived(ctx.activeItems.includes(itemId));
|
|
8
8
|
const _transition = getTransition(transition);
|
|
9
9
|
const attrs = $derived({
|
|
10
|
-
id:
|
|
10
|
+
id: ctx.uid("content"),
|
|
11
11
|
"data-accordioncontent": "",
|
|
12
12
|
"data-active": active || void 0,
|
|
13
13
|
class: classProp(klass, { active })
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
<script>import { context } from "./Accordion.svelte";
|
|
2
2
|
import { log, useActions, createUID, classProp } from "../../internal/index.js";
|
|
3
3
|
import { onMount, setContext } from "svelte";
|
|
4
|
-
let { children, class: klass, use = [], self = $bindable(), disabled = false, ...props } = $props();
|
|
5
|
-
const
|
|
4
|
+
let { children, class: klass, use = [], self = $bindable(), disabled = $bindable(false), ...props } = $props();
|
|
5
|
+
const ctx = context();
|
|
6
6
|
const { uid } = createUID("item");
|
|
7
|
+
const active = $derived(ctx.activeItems.includes(uid()));
|
|
8
|
+
setContext("accordionitem-id", uid());
|
|
7
9
|
onMount(() => {
|
|
8
|
-
if (!
|
|
10
|
+
if (!ctx)
|
|
9
11
|
log.error("<AccordionItem /> must be a direct child of <Accordion />");
|
|
10
|
-
|
|
12
|
+
ctx.register({
|
|
11
13
|
id: uid(),
|
|
12
14
|
disabled
|
|
13
15
|
});
|
|
14
16
|
});
|
|
15
|
-
const active = $derived(API.activeItems.includes(uid()));
|
|
16
|
-
setContext("accordionitem-id", uid());
|
|
17
17
|
$effect(() => {
|
|
18
|
-
|
|
18
|
+
ctx.setDisabled(uid(), disabled);
|
|
19
19
|
});
|
|
20
20
|
</script>
|
|
21
21
|
|
|
@@ -23,11 +23,11 @@ $effect(() => {
|
|
|
23
23
|
bind:this={self}
|
|
24
24
|
use:useActions={use}
|
|
25
25
|
id={uid()}
|
|
26
|
-
class={classProp(klass, { active })}
|
|
26
|
+
class={classProp(klass, { active, disabled })}
|
|
27
27
|
data-accordionitem=""
|
|
28
28
|
data-disabled={disabled || undefined}
|
|
29
29
|
data-state={active ? 'opened' : 'closed'}
|
|
30
30
|
{...props}
|
|
31
31
|
>
|
|
32
|
-
{@render children({ active })}
|
|
32
|
+
{@render children({ active, disabled })}
|
|
33
33
|
</div>
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { type UID } from '../../internal/index.js';
|
|
2
1
|
export interface Item {
|
|
3
2
|
id: string;
|
|
4
3
|
disabled: boolean;
|
|
5
4
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
interface InitialValues {
|
|
6
|
+
single?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const createContext: (init: InitialValues) => {
|
|
9
|
+
uid: (component?: string | undefined) => string;
|
|
9
10
|
toggle(itemId: string): void;
|
|
10
11
|
register(item: Item): void;
|
|
11
12
|
setDisabled(id: string, val: boolean): void;
|
|
12
|
-
|
|
13
|
+
setSingle(val: boolean): void;
|
|
14
|
+
readonly items: Item[];
|
|
15
|
+
readonly activeItems: string[];
|
|
13
16
|
};
|
|
17
|
+
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {} from '../../internal/index.js';
|
|
2
|
-
export const createContext = (
|
|
1
|
+
import { createUID } from '../../internal/index.js';
|
|
2
|
+
export const createContext = (init) => {
|
|
3
|
+
const { uid } = createUID('accordion');
|
|
3
4
|
let items = $state([]);
|
|
4
5
|
let activeItems = $state([]);
|
|
5
|
-
|
|
6
|
+
let single = $state(init.single || false);
|
|
7
|
+
return {
|
|
8
|
+
uid,
|
|
6
9
|
toggle(itemId) {
|
|
7
10
|
if (single) {
|
|
8
11
|
if (activeItems[0] === itemId)
|
|
@@ -23,11 +26,10 @@ export const createContext = (uid, single = false) => {
|
|
|
23
26
|
setDisabled(id, val) {
|
|
24
27
|
const index = items.findIndex((el) => el.id === id);
|
|
25
28
|
items[index].disabled = val;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
...functions,
|
|
29
|
+
},
|
|
30
|
+
setSingle(val) {
|
|
31
|
+
single = val;
|
|
32
|
+
},
|
|
31
33
|
get items() {
|
|
32
34
|
return items;
|
|
33
35
|
},
|
|
@@ -4,7 +4,7 @@ const contextName = "combobox-context";
|
|
|
4
4
|
export const context = () => getContext(contextName);
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
|
-
<script generics="ValueType">import {
|
|
7
|
+
<script generics="ValueType">import { useActions, classProp } from "../../internal/index.js";
|
|
8
8
|
import { setContext } from "svelte";
|
|
9
9
|
let {
|
|
10
10
|
children,
|
|
@@ -17,39 +17,41 @@ let {
|
|
|
17
17
|
onChange,
|
|
18
18
|
...props
|
|
19
19
|
} = $props();
|
|
20
|
-
const { uid } = createUID("combobox");
|
|
21
20
|
const multiple = Array.isArray(value);
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
const ctx = createContext(
|
|
22
|
+
{ multiple },
|
|
23
|
+
{
|
|
24
|
+
onChange({ newValue, newTouched, newLabel }) {
|
|
25
|
+
if (newValue) {
|
|
26
|
+
value = newValue;
|
|
27
|
+
onChange?.({ value: newValue });
|
|
28
|
+
}
|
|
29
|
+
if (newLabel && !multiple) {
|
|
30
|
+
label = newLabel;
|
|
31
|
+
onChange?.({ label: newLabel });
|
|
32
|
+
}
|
|
33
|
+
if (typeof newTouched === "boolean")
|
|
34
|
+
touched = newTouched;
|
|
27
35
|
}
|
|
28
|
-
if (newLabel && !multiple) {
|
|
29
|
-
label = newLabel;
|
|
30
|
-
onChange?.({ label: newLabel });
|
|
31
|
-
}
|
|
32
|
-
if (typeof newTouched === "boolean")
|
|
33
|
-
touched = newTouched;
|
|
34
36
|
}
|
|
35
|
-
|
|
36
|
-
setContext(contextName,
|
|
37
|
+
);
|
|
38
|
+
setContext(contextName, ctx);
|
|
37
39
|
onMount(async () => {
|
|
38
40
|
await tick();
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
ctx.setInitialSelected(value);
|
|
42
|
+
ctx.close();
|
|
43
|
+
ctx.setMounted(true);
|
|
42
44
|
});
|
|
43
45
|
</script>
|
|
44
46
|
|
|
45
47
|
<div
|
|
46
48
|
bind:this={self}
|
|
47
49
|
use:useActions={use}
|
|
48
|
-
id={uid()}
|
|
49
|
-
class={classProp(klass, { visible:
|
|
50
|
+
id={ctx.uid()}
|
|
51
|
+
class={classProp(klass, { visible: ctx.visible && ctx.mounted })}
|
|
50
52
|
data-select=""
|
|
51
|
-
data-state={
|
|
53
|
+
data-state={ctx.visible && ctx.mounted ? 'opened' : 'closed'}
|
|
52
54
|
{...props}
|
|
53
55
|
>
|
|
54
|
-
{@render children({ visible:
|
|
56
|
+
{@render children({ visible: ctx.visible && ctx.mounted })}
|
|
55
57
|
</div>
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
2
|
export declare const context: () => {
|
|
3
|
-
|
|
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;
|
|
3
|
+
uid: (component?: string | undefined) => string;
|
|
13
4
|
open(): void;
|
|
14
5
|
close(): void;
|
|
15
6
|
toggle(): void;
|
|
@@ -22,7 +13,16 @@ export declare const context: () => {
|
|
|
22
13
|
setDropdown(node: HTMLElement): void;
|
|
23
14
|
setMounted(value: boolean): void;
|
|
24
15
|
setTouched(value: boolean): void;
|
|
25
|
-
|
|
16
|
+
readonly visible: boolean;
|
|
17
|
+
readonly hoveredIndex: number;
|
|
18
|
+
readonly options: HTMLElement[];
|
|
19
|
+
readonly touched: HTMLElement[];
|
|
20
|
+
readonly dropdown: HTMLElement | null;
|
|
21
|
+
readonly mounted: boolean;
|
|
22
|
+
readonly selectedOptions: HTMLElement[];
|
|
23
|
+
readonly hoveredOption: HTMLElement;
|
|
24
|
+
readonly trigger: HTMLInputElement | null;
|
|
25
|
+
multiple: boolean | undefined;
|
|
26
26
|
};
|
|
27
27
|
import { type BaseProps } from '../../internal/index.js';
|
|
28
28
|
declare class __sveltets_Render<ValueType> {
|
|
@@ -21,28 +21,28 @@ let {
|
|
|
21
21
|
constrainViewport = false,
|
|
22
22
|
...props
|
|
23
23
|
} = $props();
|
|
24
|
-
const
|
|
24
|
+
const ctx = context();
|
|
25
25
|
let dropdownCleanup = $state(void 0);
|
|
26
26
|
const _transition = getTransition(transition);
|
|
27
27
|
const attrs = $derived({
|
|
28
|
-
id:
|
|
29
|
-
"aria-labelledby":
|
|
28
|
+
id: ctx.uid("dropdown"),
|
|
29
|
+
"aria-labelledby": ctx.uid("trigger"),
|
|
30
30
|
role: "listbox",
|
|
31
|
-
class: classProp(klass, { visible:
|
|
31
|
+
class: classProp(klass, { visible: ctx.visible }),
|
|
32
32
|
"data-comboboxdropdown": "",
|
|
33
|
-
hidden: !
|
|
33
|
+
hidden: !ctx.mounted || void 0
|
|
34
34
|
});
|
|
35
35
|
onMount(() => {
|
|
36
|
-
if (!
|
|
36
|
+
if (!ctx)
|
|
37
37
|
log.error("<ComboboxDropdown> Must be a direct child of <Combobox />");
|
|
38
38
|
});
|
|
39
39
|
$effect(() => {
|
|
40
|
-
if (
|
|
41
|
-
|
|
40
|
+
if (ctx.visible && self)
|
|
41
|
+
ctx.setDropdown(self);
|
|
42
42
|
});
|
|
43
43
|
$effect(() => {
|
|
44
|
-
if (
|
|
45
|
-
dropdownCleanup = anchorElement(
|
|
44
|
+
if (ctx.visible && ctx.trigger && ctx.dropdown) {
|
|
45
|
+
dropdownCleanup = anchorElement(ctx.trigger, ctx.dropdown, {
|
|
46
46
|
placement,
|
|
47
47
|
constrainViewport,
|
|
48
48
|
sameWidth
|
|
@@ -55,10 +55,10 @@ $effect(() => {
|
|
|
55
55
|
</script>
|
|
56
56
|
|
|
57
57
|
{#if _transition}
|
|
58
|
-
{#if
|
|
58
|
+
{#if ctx.visible}
|
|
59
59
|
<div
|
|
60
60
|
bind:this={self}
|
|
61
|
-
use:clickOutside={{ exclude: [
|
|
61
|
+
use:clickOutside={{ exclude: [ctx.trigger], callback: ctx.close }}
|
|
62
62
|
use:portal={portalTarget}
|
|
63
63
|
use:useActions={use}
|
|
64
64
|
in:_transition.in.fn={_transition.in.params}
|
|
@@ -66,18 +66,18 @@ $effect(() => {
|
|
|
66
66
|
{...attrs}
|
|
67
67
|
{...props}
|
|
68
68
|
>
|
|
69
|
-
{@render children({ visible:
|
|
69
|
+
{@render children({ visible: ctx.visible })}
|
|
70
70
|
</div>
|
|
71
71
|
{/if}
|
|
72
|
-
{:else if
|
|
72
|
+
{:else if ctx.visible}
|
|
73
73
|
<div
|
|
74
74
|
bind:this={self}
|
|
75
|
-
use:clickOutside={{ exclude: [
|
|
75
|
+
use:clickOutside={{ exclude: [ctx.trigger], callback: ctx.close }}
|
|
76
76
|
use:portal={portalTarget}
|
|
77
77
|
use:useActions={use}
|
|
78
78
|
{...attrs}
|
|
79
79
|
{...props}
|
|
80
80
|
>
|
|
81
|
-
{@render children({ visible:
|
|
81
|
+
{@render children({ visible: ctx.visible })}
|
|
82
82
|
</div>
|
|
83
83
|
{/if}
|
|
@@ -11,23 +11,23 @@ let {
|
|
|
11
11
|
use = [],
|
|
12
12
|
value = $bindable(),
|
|
13
13
|
self = $bindable(),
|
|
14
|
-
disabled,
|
|
14
|
+
disabled = $bindable(false),
|
|
15
15
|
onClick,
|
|
16
16
|
onFocus,
|
|
17
17
|
onKeydown,
|
|
18
18
|
...props
|
|
19
19
|
} = $props();
|
|
20
|
-
const
|
|
20
|
+
const ctx = context();
|
|
21
21
|
onMount(() => {
|
|
22
|
-
if (!
|
|
22
|
+
if (!ctx || !self)
|
|
23
23
|
return;
|
|
24
|
-
|
|
24
|
+
ctx.setTrigger(self);
|
|
25
25
|
});
|
|
26
26
|
const handleClick = (e) => {
|
|
27
27
|
onClick?.(e);
|
|
28
28
|
if (disabled)
|
|
29
29
|
return;
|
|
30
|
-
|
|
30
|
+
ctx.toggle();
|
|
31
31
|
};
|
|
32
32
|
const handleKeydown = (e) => {
|
|
33
33
|
onKeydown?.(e);
|
|
@@ -35,37 +35,37 @@ const handleKeydown = (e) => {
|
|
|
35
35
|
return;
|
|
36
36
|
const { key } = e;
|
|
37
37
|
if (!PREVENT_KEYS.includes(key)) {
|
|
38
|
-
|
|
39
|
-
if (!
|
|
40
|
-
|
|
38
|
+
ctx.setTouched(true);
|
|
39
|
+
if (!ctx.visible)
|
|
40
|
+
ctx.open();
|
|
41
41
|
}
|
|
42
42
|
if (key === KEYS.arrowUp || key === KEYS.arrowDown || key === KEYS.end || key === KEYS.home) {
|
|
43
43
|
e.preventDefault();
|
|
44
|
-
if (!
|
|
45
|
-
|
|
44
|
+
if (!ctx.visible)
|
|
45
|
+
ctx.open();
|
|
46
46
|
}
|
|
47
47
|
if (key === KEYS.home)
|
|
48
|
-
|
|
48
|
+
ctx.navigateOptions("first");
|
|
49
49
|
if (key === KEYS.end)
|
|
50
|
-
|
|
50
|
+
ctx.navigateOptions("last");
|
|
51
51
|
if (key === KEYS.arrowUp)
|
|
52
|
-
|
|
52
|
+
ctx.navigateOptions("prev");
|
|
53
53
|
if (key === KEYS.arrowDown)
|
|
54
|
-
|
|
54
|
+
ctx.navigateOptions("next");
|
|
55
55
|
if (key === KEYS.escape)
|
|
56
|
-
|
|
56
|
+
ctx.close();
|
|
57
57
|
if (key === KEYS.enter) {
|
|
58
58
|
e.preventDefault();
|
|
59
|
-
if (
|
|
60
|
-
document.querySelector(`#${
|
|
61
|
-
if (!
|
|
62
|
-
|
|
59
|
+
if (ctx.hoveredOption && ctx.visible) {
|
|
60
|
+
document.querySelector(`#${ctx.hoveredOption.id}`).click();
|
|
61
|
+
if (!ctx.multiple)
|
|
62
|
+
ctx.close();
|
|
63
63
|
} else {
|
|
64
|
-
|
|
64
|
+
ctx.open();
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
if (key === "Tab")
|
|
68
|
-
|
|
68
|
+
ctx.close();
|
|
69
69
|
};
|
|
70
70
|
</script>
|
|
71
71
|
|
|
@@ -73,8 +73,8 @@ const handleKeydown = (e) => {
|
|
|
73
73
|
type="text"
|
|
74
74
|
bind:this={self}
|
|
75
75
|
use:useActions={use}
|
|
76
|
-
id={
|
|
77
|
-
class={classProp(klass, { visible:
|
|
76
|
+
id={ctx.uid('input')}
|
|
77
|
+
class={classProp(klass, { visible: ctx.visible })}
|
|
78
78
|
onclick={handleClick}
|
|
79
79
|
onkeydown={handleKeydown}
|
|
80
80
|
bind:value
|
|
@@ -13,22 +13,22 @@ let {
|
|
|
13
13
|
value,
|
|
14
14
|
label: labelProp,
|
|
15
15
|
self = $bindable(),
|
|
16
|
-
disabled,
|
|
16
|
+
disabled = $bindable(false),
|
|
17
17
|
onClick,
|
|
18
18
|
onFocus,
|
|
19
19
|
onMouseenter,
|
|
20
20
|
...props
|
|
21
21
|
} = $props();
|
|
22
22
|
let optionEl;
|
|
23
|
-
const
|
|
23
|
+
const ctx = context();
|
|
24
24
|
const { uid } = createUID("item");
|
|
25
|
-
const hovered = $derived(
|
|
26
|
-
const selected = $derived(!!
|
|
25
|
+
const hovered = $derived(ctx.hoveredOption?.id === uid());
|
|
26
|
+
const selected = $derived(!!ctx.selectedOptions.find((el) => el.dataset.value === value));
|
|
27
27
|
const label = $derived(labelProp || isBrowser && self ? self?.textContent?.trim() : "");
|
|
28
28
|
const handleClick = (e) => {
|
|
29
29
|
onClick?.(e);
|
|
30
30
|
if (!disabled) {
|
|
31
|
-
|
|
31
|
+
ctx.setSelectedOptions();
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
const handleFocus = (e) => {
|
|
@@ -37,15 +37,15 @@ const handleFocus = (e) => {
|
|
|
37
37
|
const handleMouseover = (e) => {
|
|
38
38
|
onMouseenter?.(e);
|
|
39
39
|
if (!disabled)
|
|
40
|
-
|
|
40
|
+
ctx.setHoveredOption(uid());
|
|
41
41
|
};
|
|
42
42
|
onMount(() => {
|
|
43
|
-
|
|
43
|
+
ctx.queryElements();
|
|
44
44
|
return async () => {
|
|
45
|
-
if (!
|
|
45
|
+
if (!ctx.visible)
|
|
46
46
|
return;
|
|
47
47
|
await tick();
|
|
48
|
-
|
|
48
|
+
ctx.queryElements();
|
|
49
49
|
};
|
|
50
50
|
});
|
|
51
51
|
</script>
|
|
@@ -1,28 +1,22 @@
|
|
|
1
|
-
import { type CalcIndexAction, type
|
|
1
|
+
import { type CalcIndexAction, type JsonValue } from '../../internal/index.js';
|
|
2
2
|
export interface Option {
|
|
3
3
|
value: JsonValue;
|
|
4
4
|
label: string;
|
|
5
5
|
id: string;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
}
|
|
8
|
+
interface InitialValues {
|
|
9
|
+
multiple?: boolean;
|
|
10
|
+
}
|
|
8
11
|
interface Hooks<ValueType> {
|
|
9
|
-
onChange
|
|
12
|
+
onChange?: (values: {
|
|
10
13
|
newValue?: ValueType;
|
|
11
14
|
newTouched?: boolean;
|
|
12
15
|
newLabel?: string;
|
|
13
16
|
}) => void;
|
|
14
17
|
}
|
|
15
|
-
export declare const createContext: <ValueType>(
|
|
16
|
-
|
|
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;
|
|
18
|
+
export declare const createContext: <ValueType>({ multiple }: InitialValues, hooks?: Hooks<ValueType>) => {
|
|
19
|
+
uid: (component?: string | undefined) => string;
|
|
26
20
|
open(): void;
|
|
27
21
|
close(): void;
|
|
28
22
|
toggle(): void;
|
|
@@ -35,6 +29,15 @@ export declare const createContext: <ValueType>(uid: UID, multiple: boolean | un
|
|
|
35
29
|
setDropdown(node: HTMLElement): void;
|
|
36
30
|
setMounted(value: boolean): void;
|
|
37
31
|
setTouched(value: boolean): void;
|
|
38
|
-
|
|
32
|
+
readonly visible: boolean;
|
|
33
|
+
readonly hoveredIndex: number;
|
|
34
|
+
readonly options: HTMLElement[];
|
|
35
|
+
readonly touched: HTMLElement[];
|
|
36
|
+
readonly dropdown: HTMLElement | null;
|
|
37
|
+
readonly mounted: boolean;
|
|
38
|
+
readonly selectedOptions: HTMLElement[];
|
|
39
|
+
readonly hoveredOption: HTMLElement;
|
|
40
|
+
readonly trigger: HTMLInputElement | null;
|
|
41
|
+
multiple: boolean | undefined;
|
|
39
42
|
};
|
|
40
43
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { calculateIndex, disableScroll, removeDisabledElements } from '../../internal/index.js';
|
|
1
|
+
import { calculateIndex, disableScroll, removeDisabledElements, createUID } from '../../internal/index.js';
|
|
2
2
|
import { tick } from 'svelte';
|
|
3
|
-
export const createContext = (
|
|
3
|
+
export const createContext = ({ multiple }, hooks) => {
|
|
4
|
+
const { uid } = createUID('combobox');
|
|
4
5
|
let visible = $state(true);
|
|
5
6
|
let hoveredIndex = $state(-1);
|
|
6
7
|
let options = $state([]);
|
|
@@ -32,9 +33,10 @@ export const createContext = (uid, multiple = false, hooks) => {
|
|
|
32
33
|
$effect(() => {
|
|
33
34
|
if (!visible)
|
|
34
35
|
return;
|
|
35
|
-
hooks
|
|
36
|
+
hooks?.onChange?.({ newTouched: touched });
|
|
36
37
|
});
|
|
37
|
-
|
|
38
|
+
return {
|
|
39
|
+
uid,
|
|
38
40
|
open() {
|
|
39
41
|
visible = true;
|
|
40
42
|
},
|
|
@@ -74,11 +76,11 @@ export const createContext = (uid, multiple = false, hooks) => {
|
|
|
74
76
|
selectedOptions[0] = hoveredOption;
|
|
75
77
|
}
|
|
76
78
|
if (!multiple) {
|
|
77
|
-
|
|
79
|
+
visible = false;
|
|
78
80
|
}
|
|
79
81
|
const value = multiple ? selectedOptions.map((el) => el.dataset.value) : selectedOptions[0].dataset.value;
|
|
80
82
|
const label = multiple ? '' : selectedOptions[0].dataset.label || '';
|
|
81
|
-
hooks
|
|
83
|
+
hooks?.onChange?.({ newValue: value, newLabel: label });
|
|
82
84
|
},
|
|
83
85
|
async setInitialSelected(value) {
|
|
84
86
|
selectedOptions = options.filter((el) => {
|
|
@@ -99,11 +101,7 @@ export const createContext = (uid, multiple = false, hooks) => {
|
|
|
99
101
|
},
|
|
100
102
|
setTouched(value) {
|
|
101
103
|
touched = value;
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
return {
|
|
105
|
-
uid,
|
|
106
|
-
...functions,
|
|
104
|
+
},
|
|
107
105
|
get visible() {
|
|
108
106
|
return visible;
|
|
109
107
|
},
|
|
@@ -4,22 +4,21 @@ const contextName = "menu-context";
|
|
|
4
4
|
export const context = () => getContext(contextName);
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
|
-
<script>import {
|
|
7
|
+
<script>import { useActions, classProp } from "../../internal/index.js";
|
|
8
8
|
import { setContext } from "svelte";
|
|
9
9
|
let { children, use = [], class: klass, self = $bindable(), ...props } = $props();
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
setContext(contextName, API);
|
|
10
|
+
const ctx = createContext();
|
|
11
|
+
setContext(contextName, ctx);
|
|
13
12
|
</script>
|
|
14
13
|
|
|
15
14
|
<div
|
|
16
15
|
bind:this={self}
|
|
17
16
|
use:useActions={use}
|
|
18
|
-
id={uid()}
|
|
19
|
-
class={classProp(klass, { visible:
|
|
17
|
+
id={ctx.uid()}
|
|
18
|
+
class={classProp(klass, { visible: ctx.visible })}
|
|
20
19
|
data-menu=""
|
|
21
|
-
data-state={
|
|
20
|
+
data-state={ctx.visible ? 'opened' : 'closed'}
|
|
22
21
|
{...props}
|
|
23
22
|
>
|
|
24
|
-
{@render children({ visible:
|
|
23
|
+
{@render children({ visible: ctx.visible })}
|
|
25
24
|
</div>
|