lithesome 0.0.7
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/LICENSE.md +21 -0
- package/README.md +44 -0
- package/dist/components/Accordion/Accordion.svelte +19 -0
- package/dist/components/Accordion/Accordion.svelte.d.ts +26 -0
- package/dist/components/Accordion/AccordionContent.svelte +35 -0
- package/dist/components/Accordion/AccordionContent.svelte.d.ts +24 -0
- package/dist/components/Accordion/AccordionHeading.svelte +16 -0
- package/dist/components/Accordion/AccordionHeading.svelte.d.ts +17 -0
- package/dist/components/Accordion/AccordionItem.svelte +32 -0
- package/dist/components/Accordion/AccordionItem.svelte.d.ts +19 -0
- package/dist/components/Accordion/AccordionTrigger.svelte +26 -0
- package/dist/components/Accordion/AccordionTrigger.svelte.d.ts +17 -0
- package/dist/components/Accordion/context.svelte.d.ts +12 -0
- package/dist/components/Accordion/context.svelte.js +34 -0
- package/dist/components/Menu/Menu.svelte +26 -0
- package/dist/components/Menu/Menu.svelte.d.ts +33 -0
- package/dist/components/Menu/MenuDropdown.svelte +78 -0
- package/dist/components/Menu/MenuDropdown.svelte.d.ts +28 -0
- package/dist/components/Menu/MenuItem.svelte +43 -0
- package/dist/components/Menu/MenuItem.svelte.d.ts +21 -0
- package/dist/components/Menu/MenuTrigger.svelte +78 -0
- package/dist/components/Menu/MenuTrigger.svelte.d.ts +17 -0
- package/dist/components/Menu/context.svelte.d.ts +17 -0
- package/dist/components/Menu/context.svelte.js +64 -0
- package/dist/components/Modal/Modal.svelte +43 -0
- package/dist/components/Modal/Modal.svelte.d.ts +23 -0
- package/dist/components/Modal/ModalContent.svelte +38 -0
- package/dist/components/Modal/ModalContent.svelte.d.ts +22 -0
- package/dist/components/Modal/ModalDescription.svelte +17 -0
- package/dist/components/Modal/ModalDescription.svelte.d.ts +15 -0
- package/dist/components/Modal/ModalOverlay.svelte +28 -0
- package/dist/components/Modal/ModalOverlay.svelte.d.ts +22 -0
- package/dist/components/Modal/ModalTitle.svelte +10 -0
- package/dist/components/Modal/ModalTitle.svelte.d.ts +15 -0
- package/dist/components/Modal/context.svelte.d.ts +6 -0
- package/dist/components/Modal/context.svelte.js +19 -0
- package/dist/components/Pin/Pin.svelte +51 -0
- package/dist/components/Pin/Pin.svelte.d.ts +37 -0
- package/dist/components/Pin/PinInput.svelte +96 -0
- package/dist/components/Pin/PinInput.svelte.d.ts +21 -0
- package/dist/components/Pin/PinValue.svelte +27 -0
- package/dist/components/Pin/PinValue.svelte.d.ts +18 -0
- package/dist/components/Pin/context.svelte.d.ts +25 -0
- package/dist/components/Pin/context.svelte.js +52 -0
- package/dist/components/RadioGroup/RadioGroup.svelte +30 -0
- package/dist/components/RadioGroup/RadioGroupItem.svelte +61 -0
- package/dist/components/RadioGroup/RadioGroupItem.svelte.d.ts +21 -0
- package/dist/components/RadioGroup/context.svelte.d.ts +18 -0
- package/dist/components/RadioGroup/context.svelte.js +30 -0
- package/dist/components/Select/Select.svelte +38 -0
- package/dist/components/Select/Select.svelte.d.ts +43 -0
- package/dist/components/Select/SelectDropdown.svelte +79 -0
- package/dist/components/Select/SelectDropdown.svelte.d.ts +28 -0
- package/dist/components/Select/SelectOption.svelte +51 -0
- package/dist/components/Select/SelectOption.svelte.d.ts +23 -0
- package/dist/components/Select/SelectTrigger.svelte +85 -0
- package/dist/components/Select/SelectTrigger.svelte.d.ts +17 -0
- package/dist/components/Select/SelectValue.svelte +19 -0
- package/dist/components/Select/SelectValue.svelte.d.ts +19 -0
- package/dist/components/Select/context.svelte.d.ts +34 -0
- package/dist/components/Select/context.svelte.js +114 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +24 -0
- package/dist/internal/actions/action.d.ts +15 -0
- package/dist/internal/actions/action.js +47 -0
- package/dist/internal/actions/clickOutside.d.ts +13 -0
- package/dist/internal/actions/clickOutside.js +21 -0
- package/dist/internal/actions/focusTrap.d.ts +7 -0
- package/dist/internal/actions/focusTrap.js +17 -0
- package/dist/internal/actions/portal.d.ts +8 -0
- package/dist/internal/actions/portal.js +19 -0
- package/dist/internal/helpers/element.d.ts +10 -0
- package/dist/internal/helpers/element.js +42 -0
- package/dist/internal/helpers/is.d.ts +1 -0
- package/dist/internal/helpers/is.js +1 -0
- package/dist/internal/helpers/keyboard.d.ts +21 -0
- package/dist/internal/helpers/keyboard.js +31 -0
- package/dist/internal/helpers/transition.d.ts +17 -0
- package/dist/internal/helpers/transition.js +15 -0
- package/dist/internal/helpers/utils.d.ts +14 -0
- package/dist/internal/helpers/utils.js +52 -0
- package/dist/internal/index.d.ts +10 -0
- package/dist/internal/index.js +10 -0
- package/dist/internal/types.d.ts +14 -0
- package/dist/internal/types.js +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type BaseProps } from '../../internal/index.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: BaseProps<HTMLDivElement, {
|
|
5
|
+
visible: boolean;
|
|
6
|
+
}>;
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {};
|
|
11
|
+
};
|
|
12
|
+
export type MenuTriggerProps = typeof __propDef.props;
|
|
13
|
+
export type MenuTriggerEvents = typeof __propDef.events;
|
|
14
|
+
export type MenuTriggerSlots = typeof __propDef.slots;
|
|
15
|
+
export default class MenuTrigger extends SvelteComponent<MenuTriggerProps, MenuTriggerEvents, MenuTriggerSlots> {
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type CalcIndexAction, type UID } from '../../internal/index.js';
|
|
2
|
+
export declare const createContext: (uid: UID) => {
|
|
3
|
+
uid: UID;
|
|
4
|
+
visible: boolean;
|
|
5
|
+
hoveredIndex: number;
|
|
6
|
+
trigger: HTMLElement | null;
|
|
7
|
+
items: string[];
|
|
8
|
+
hoveredItem: string;
|
|
9
|
+
open(): void;
|
|
10
|
+
close(): void;
|
|
11
|
+
toggle(): void;
|
|
12
|
+
navigateItems(action: CalcIndexAction): void;
|
|
13
|
+
register(item: string): void;
|
|
14
|
+
unregister(item: string): void;
|
|
15
|
+
setHoveredItem(itemId: string): void;
|
|
16
|
+
setTrigger(node: HTMLElement): void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { calculateIndex, disableScroll } from '../../internal/index.js';
|
|
2
|
+
export const createContext = (uid) => {
|
|
3
|
+
// Internal state
|
|
4
|
+
let visible = $state(false);
|
|
5
|
+
let hoveredIndex = $state(-1);
|
|
6
|
+
let trigger = $state(null);
|
|
7
|
+
let items = $state([]);
|
|
8
|
+
// Derived state
|
|
9
|
+
const hoveredItem = $derived(items[hoveredIndex]);
|
|
10
|
+
// Effects
|
|
11
|
+
$effect(() => {
|
|
12
|
+
disableScroll(visible && !document.body.style.overflow);
|
|
13
|
+
});
|
|
14
|
+
$effect(() => {
|
|
15
|
+
if (!visible)
|
|
16
|
+
hoveredIndex = -1;
|
|
17
|
+
});
|
|
18
|
+
// Functions
|
|
19
|
+
const functions = {
|
|
20
|
+
open() {
|
|
21
|
+
visible = true;
|
|
22
|
+
},
|
|
23
|
+
close() {
|
|
24
|
+
visible = false;
|
|
25
|
+
},
|
|
26
|
+
toggle() {
|
|
27
|
+
visible = !visible;
|
|
28
|
+
},
|
|
29
|
+
navigateItems(action) {
|
|
30
|
+
hoveredIndex = calculateIndex(action, items, hoveredIndex);
|
|
31
|
+
},
|
|
32
|
+
register(item) {
|
|
33
|
+
items = [...items, item];
|
|
34
|
+
},
|
|
35
|
+
unregister(item) {
|
|
36
|
+
items = items.filter((el) => el === item);
|
|
37
|
+
},
|
|
38
|
+
setHoveredItem(itemId) {
|
|
39
|
+
hoveredIndex = items.findIndex((el) => el === itemId);
|
|
40
|
+
},
|
|
41
|
+
setTrigger(node) {
|
|
42
|
+
trigger = node;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
...functions,
|
|
47
|
+
uid,
|
|
48
|
+
get visible() {
|
|
49
|
+
return visible;
|
|
50
|
+
},
|
|
51
|
+
get hoveredIndex() {
|
|
52
|
+
return hoveredIndex;
|
|
53
|
+
},
|
|
54
|
+
get trigger() {
|
|
55
|
+
return trigger;
|
|
56
|
+
},
|
|
57
|
+
get items() {
|
|
58
|
+
return items;
|
|
59
|
+
},
|
|
60
|
+
get hoveredItem() {
|
|
61
|
+
return hoveredItem;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script context="module">import { getContext } from "svelte";
|
|
2
|
+
import { createContext } from "./context.svelte.js";
|
|
3
|
+
const contextName = "modal-context";
|
|
4
|
+
export const context = () => getContext(contextName);
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script>import { createUID, useActions, portal, KEYS, isBrowser } from "../../internal/index.js";
|
|
8
|
+
import { setContext } from "svelte";
|
|
9
|
+
let { children, use = [], class: klass, self, visible, portalTarget = "body", ...props } = $props();
|
|
10
|
+
const { uid } = createUID("modal");
|
|
11
|
+
const API = createContext(uid, visible);
|
|
12
|
+
setContext(contextName, API);
|
|
13
|
+
const classProp = $derived(typeof klass === "function" ? klass({}) : klass);
|
|
14
|
+
const handleKeys = (e) => {
|
|
15
|
+
const { key } = e;
|
|
16
|
+
if (key === KEYS.escape)
|
|
17
|
+
visible = false;
|
|
18
|
+
};
|
|
19
|
+
$effect(() => {
|
|
20
|
+
API.updateVisible(visible);
|
|
21
|
+
if (isBrowser) {
|
|
22
|
+
if (visible) {
|
|
23
|
+
window.addEventListener("keydown", handleKeys);
|
|
24
|
+
} else {
|
|
25
|
+
window.removeEventListener("keydown", handleKeys);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
{#if visible}
|
|
32
|
+
<div
|
|
33
|
+
bind:this={self}
|
|
34
|
+
use:portal={portalTarget}
|
|
35
|
+
use:useActions={use}
|
|
36
|
+
id={uid()}
|
|
37
|
+
class={classProp}
|
|
38
|
+
data-modal=""
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
{@render children({})}
|
|
42
|
+
</div>
|
|
43
|
+
{/if}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
export declare const context: () => {
|
|
3
|
+
visible: boolean;
|
|
4
|
+
updateVisible(value: boolean): void;
|
|
5
|
+
uid: import("../../internal/index.js").UID;
|
|
6
|
+
};
|
|
7
|
+
import { type BaseProps } from '../../internal/index.js';
|
|
8
|
+
declare const __propDef: {
|
|
9
|
+
props: BaseProps<HTMLDivElement, any> & {
|
|
10
|
+
visible: boolean;
|
|
11
|
+
portalTarget?: string | HTMLElement | undefined;
|
|
12
|
+
};
|
|
13
|
+
events: {
|
|
14
|
+
[evt: string]: CustomEvent<any>;
|
|
15
|
+
};
|
|
16
|
+
slots: {};
|
|
17
|
+
};
|
|
18
|
+
export type ModalProps = typeof __propDef.props;
|
|
19
|
+
export type ModalEvents = typeof __propDef.events;
|
|
20
|
+
export type ModalSlots = typeof __propDef.slots;
|
|
21
|
+
export default class Modal extends SvelteComponent<ModalProps, ModalEvents, ModalSlots> {
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script>import { useActions, trap, getTransition } from "../../internal/index.js";
|
|
2
|
+
import { onMount } from "svelte";
|
|
3
|
+
import { context } from "./Modal.svelte";
|
|
4
|
+
let { children, class: klass, use = [], self, transition, ...props } = $props();
|
|
5
|
+
const API = context();
|
|
6
|
+
const classProp = $derived(typeof klass === "function" ? klass({}) : klass);
|
|
7
|
+
const _transition = getTransition(transition);
|
|
8
|
+
const attrs = $derived({
|
|
9
|
+
id: API.uid("content"),
|
|
10
|
+
class: classProp,
|
|
11
|
+
role: "dialog",
|
|
12
|
+
"aria-modal": "true",
|
|
13
|
+
tabindex: -1,
|
|
14
|
+
"aria-describedby": API.uid("description"),
|
|
15
|
+
"aria-labelledby": API.uid("title"),
|
|
16
|
+
"data-modalcontent": ""
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
{#if _transition}
|
|
21
|
+
{#if API.visible}
|
|
22
|
+
<div
|
|
23
|
+
bind:this={self}
|
|
24
|
+
use:trap={{ allowOutsideClick: true }}
|
|
25
|
+
use:useActions={use}
|
|
26
|
+
in:_transition.in.fn|global={_transition.in.params}
|
|
27
|
+
out:_transition.out.fn|global={_transition.out.params}
|
|
28
|
+
{...props}
|
|
29
|
+
{...attrs}
|
|
30
|
+
>
|
|
31
|
+
{@render children({})}
|
|
32
|
+
</div>
|
|
33
|
+
{/if}
|
|
34
|
+
{:else if API.visible}
|
|
35
|
+
<div bind:this={self} use:trap={{ allowOutsideClick: true }} use:useActions={use} {...props} {...attrs}>
|
|
36
|
+
{@render children({})}
|
|
37
|
+
</div>
|
|
38
|
+
{/if}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type BaseProps, type Transition } from '../../internal/index.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: BaseProps<HTMLDivElement, any> & {
|
|
5
|
+
/**
|
|
6
|
+
* The `svelte/transtion` you wish to use.
|
|
7
|
+
*
|
|
8
|
+
* @see https://lithesome.dev/docs/api#transition-prop
|
|
9
|
+
*/
|
|
10
|
+
transition?: Transition | undefined;
|
|
11
|
+
};
|
|
12
|
+
events: {
|
|
13
|
+
[evt: string]: CustomEvent<any>;
|
|
14
|
+
};
|
|
15
|
+
slots: {};
|
|
16
|
+
};
|
|
17
|
+
export type ModalContentProps = typeof __propDef.props;
|
|
18
|
+
export type ModalContentEvents = typeof __propDef.events;
|
|
19
|
+
export type ModalContentSlots = typeof __propDef.slots;
|
|
20
|
+
export default class ModalContent extends SvelteComponent<ModalContentProps, ModalContentEvents, ModalContentSlots> {
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script>import { useActions } from "../../internal/index.js";
|
|
2
|
+
import { context } from "./Modal.svelte";
|
|
3
|
+
let { children, class: klass, use = [], self, ...props } = $props();
|
|
4
|
+
const API = context();
|
|
5
|
+
const classProp = $derived(typeof klass === "function" ? klass({}) : klass);
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<p
|
|
9
|
+
id={API.uid('description')}
|
|
10
|
+
bind:this={self}
|
|
11
|
+
data-modaldescription=""
|
|
12
|
+
use:useActions={use}
|
|
13
|
+
class={classProp}
|
|
14
|
+
{...props}
|
|
15
|
+
>
|
|
16
|
+
{@render children({})}
|
|
17
|
+
</p>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type BaseProps } from '../../internal/index.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: BaseProps<HTMLParagraphElement, any>;
|
|
5
|
+
events: {
|
|
6
|
+
[evt: string]: CustomEvent<any>;
|
|
7
|
+
};
|
|
8
|
+
slots: {};
|
|
9
|
+
};
|
|
10
|
+
export type ModalDescriptionProps = typeof __propDef.props;
|
|
11
|
+
export type ModalDescriptionEvents = typeof __propDef.events;
|
|
12
|
+
export type ModalDescriptionSlots = typeof __propDef.slots;
|
|
13
|
+
export default class ModalDescription extends SvelteComponent<ModalDescriptionProps, ModalDescriptionEvents, ModalDescriptionSlots> {
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script>import { useActions, getTransition } from "../../internal/index.js";
|
|
2
|
+
import { context } from "./Modal.svelte";
|
|
3
|
+
let { class: klass, use = [], self, transition, ...props } = $props();
|
|
4
|
+
const API = context();
|
|
5
|
+
const _transition = getTransition(transition);
|
|
6
|
+
const classProp = $derived(typeof klass === "function" ? klass({}) : klass);
|
|
7
|
+
const attrs = $derived({
|
|
8
|
+
id: API.uid("overlay"),
|
|
9
|
+
"aria-hidden": "true",
|
|
10
|
+
"data-modaloverlay": "",
|
|
11
|
+
class: classProp
|
|
12
|
+
});
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
{#if _transition}
|
|
16
|
+
{#if API.visible}
|
|
17
|
+
<div
|
|
18
|
+
in:_transition.in.fn={_transition.in.params}
|
|
19
|
+
out:_transition.out.fn={_transition.out.params}
|
|
20
|
+
bind:this={self}
|
|
21
|
+
use:useActions={use}
|
|
22
|
+
{...props}
|
|
23
|
+
{...attrs}
|
|
24
|
+
/>
|
|
25
|
+
{/if}
|
|
26
|
+
{:else if API.visible}
|
|
27
|
+
<div bind:this={self} use:useActions={use} {...props} {...attrs} />
|
|
28
|
+
{/if}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type BaseProps, type Transition } from '../../internal/index.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: Omit<BaseProps<HTMLDivElement, any>, "children"> & {
|
|
5
|
+
/**
|
|
6
|
+
* The `svelte/transtion` you wish to use.
|
|
7
|
+
*
|
|
8
|
+
* @see https://lithesome.dev/docs/api#transition-prop
|
|
9
|
+
*/
|
|
10
|
+
transition?: Transition | undefined;
|
|
11
|
+
};
|
|
12
|
+
events: {
|
|
13
|
+
[evt: string]: CustomEvent<any>;
|
|
14
|
+
};
|
|
15
|
+
slots: {};
|
|
16
|
+
};
|
|
17
|
+
export type ModalOverlayProps = typeof __propDef.props;
|
|
18
|
+
export type ModalOverlayEvents = typeof __propDef.events;
|
|
19
|
+
export type ModalOverlaySlots = typeof __propDef.slots;
|
|
20
|
+
export default class ModalOverlay extends SvelteComponent<ModalOverlayProps, ModalOverlayEvents, ModalOverlaySlots> {
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<script>import { useActions } from "../../internal/index.js";
|
|
2
|
+
import { context } from "./Modal.svelte";
|
|
3
|
+
let { children, class: klass, use = [], self, ...props } = $props();
|
|
4
|
+
const API = context();
|
|
5
|
+
const classProp = $derived(typeof klass === "function" ? klass({}) : klass);
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<h2 id={API.uid('title')} bind:this={self} data-modaltitle="" use:useActions={use} class={classProp} {...props}>
|
|
9
|
+
{@render children({})}
|
|
10
|
+
</h2>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type BaseProps } from '../../internal/index.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: BaseProps<HTMLHeadElement, any>;
|
|
5
|
+
events: {
|
|
6
|
+
[evt: string]: CustomEvent<any>;
|
|
7
|
+
};
|
|
8
|
+
slots: {};
|
|
9
|
+
};
|
|
10
|
+
export type ModalTitleProps = typeof __propDef.props;
|
|
11
|
+
export type ModalTitleEvents = typeof __propDef.events;
|
|
12
|
+
export type ModalTitleSlots = typeof __propDef.slots;
|
|
13
|
+
export default class ModalTitle extends SvelteComponent<ModalTitleProps, ModalTitleEvents, ModalTitleSlots> {
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { disableScroll } from '../../internal/index.js';
|
|
2
|
+
export const createContext = (uid, visibleInitial) => {
|
|
3
|
+
let visible = $state(visibleInitial);
|
|
4
|
+
$effect(() => {
|
|
5
|
+
disableScroll(visible && !document.body.style.overflow);
|
|
6
|
+
});
|
|
7
|
+
const functions = {
|
|
8
|
+
updateVisible(value) {
|
|
9
|
+
visible = value;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
uid,
|
|
14
|
+
...functions,
|
|
15
|
+
get visible() {
|
|
16
|
+
return visible;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script context="module">import { getContext } from "svelte";
|
|
2
|
+
import { createContext } from "./context.svelte.js";
|
|
3
|
+
const contextName = "pin-context";
|
|
4
|
+
export const context = () => getContext(contextName);
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<script>import { createUID, useActions } from "../../internal/index.js";
|
|
8
|
+
import { setContext } from "svelte";
|
|
9
|
+
let {
|
|
10
|
+
children,
|
|
11
|
+
use = [],
|
|
12
|
+
class: klass,
|
|
13
|
+
self,
|
|
14
|
+
value,
|
|
15
|
+
disabled = false,
|
|
16
|
+
type = "text",
|
|
17
|
+
placeholder = "\u25CB",
|
|
18
|
+
onChange,
|
|
19
|
+
...props
|
|
20
|
+
} = $props();
|
|
21
|
+
const { uid } = createUID("pin");
|
|
22
|
+
const API = createContext(
|
|
23
|
+
uid,
|
|
24
|
+
{ value, disabled, type, placeholder },
|
|
25
|
+
{
|
|
26
|
+
onChange(val) {
|
|
27
|
+
onChange?.(val);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
setContext(contextName, API);
|
|
32
|
+
const classProp = $derived(typeof klass === "function" ? klass({ filled: API.filled }) : klass);
|
|
33
|
+
$effect(() => {
|
|
34
|
+
API.setType(type);
|
|
35
|
+
API.setDisabled(disabled);
|
|
36
|
+
});
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div
|
|
40
|
+
bind:this={self}
|
|
41
|
+
id={uid()}
|
|
42
|
+
use:useActions={use}
|
|
43
|
+
class={classProp}
|
|
44
|
+
data-disabled={disabled || undefined}
|
|
45
|
+
aria-disabled={disabled || undefined}
|
|
46
|
+
data-pin=""
|
|
47
|
+
data-filled={API.filled || undefined}
|
|
48
|
+
{...props}
|
|
49
|
+
>
|
|
50
|
+
{@render children({ filled: API.filled })}
|
|
51
|
+
</div>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
export declare const context: () => {
|
|
3
|
+
inputs: string[];
|
|
4
|
+
value: string[];
|
|
5
|
+
disabled: boolean;
|
|
6
|
+
transformedValue: string;
|
|
7
|
+
type: "text" | "password";
|
|
8
|
+
filled: boolean;
|
|
9
|
+
placeholder: string;
|
|
10
|
+
register(inputId: string): void;
|
|
11
|
+
setValue(index: number, newVal: string): void;
|
|
12
|
+
setType(newVal: "text" | "password"): void;
|
|
13
|
+
setDisabled(newVal: boolean): void;
|
|
14
|
+
uid: import("../../internal/index.js").UID;
|
|
15
|
+
};
|
|
16
|
+
import { type BaseProps } from '../../internal/index.js';
|
|
17
|
+
declare const __propDef: {
|
|
18
|
+
props: BaseProps<HTMLDivElement, {
|
|
19
|
+
filled: boolean;
|
|
20
|
+
}> & {
|
|
21
|
+
value: string[];
|
|
22
|
+
disabled?: boolean | undefined;
|
|
23
|
+
type?: "text" | "password" | undefined;
|
|
24
|
+
placeholder?: string | undefined;
|
|
25
|
+
onChange?: ((value: string) => void) | undefined;
|
|
26
|
+
};
|
|
27
|
+
events: {
|
|
28
|
+
[evt: string]: CustomEvent<any>;
|
|
29
|
+
};
|
|
30
|
+
slots: {};
|
|
31
|
+
};
|
|
32
|
+
export type PinProps = typeof __propDef.props;
|
|
33
|
+
export type PinEvents = typeof __propDef.events;
|
|
34
|
+
export type PinSlots = typeof __propDef.slots;
|
|
35
|
+
export default class Pin extends SvelteComponent<PinProps, PinEvents, PinSlots> {
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script>import { context } from "./Pin.svelte";
|
|
2
|
+
import { log, useActions, createUID, KEYS } from "../../internal/index.js";
|
|
3
|
+
import { onMount, tick } from "svelte";
|
|
4
|
+
let { class: klass, use = [], self, name, ...props } = $props();
|
|
5
|
+
let value = $state("");
|
|
6
|
+
const API = context();
|
|
7
|
+
const { uid } = createUID("input");
|
|
8
|
+
const classProp = $derived(
|
|
9
|
+
typeof klass === "function" ? klass({ filled: API.filled, disabled: API.disabled }) : klass
|
|
10
|
+
);
|
|
11
|
+
const index = $derived(API.inputs.indexOf(uid()));
|
|
12
|
+
let focused = $state(false);
|
|
13
|
+
onMount(() => {
|
|
14
|
+
if (!API)
|
|
15
|
+
log.error("<PinInput /> must be a direct child of <Pin />");
|
|
16
|
+
API.register(uid());
|
|
17
|
+
});
|
|
18
|
+
$effect(() => {
|
|
19
|
+
API.setValue(index, value);
|
|
20
|
+
});
|
|
21
|
+
const handleInput = async (event) => {
|
|
22
|
+
if (API.disabled)
|
|
23
|
+
return;
|
|
24
|
+
const e = event;
|
|
25
|
+
if (e.inputType !== "insertText")
|
|
26
|
+
return;
|
|
27
|
+
await tick();
|
|
28
|
+
if (value.length > 1) {
|
|
29
|
+
value = e.data;
|
|
30
|
+
}
|
|
31
|
+
if (value.length === 1) {
|
|
32
|
+
moveFocus("next");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const handleKeyDown = (e) => {
|
|
37
|
+
if (API.disabled)
|
|
38
|
+
return;
|
|
39
|
+
const { key } = e;
|
|
40
|
+
if (key === KEYS.arrowLeft) {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
moveFocus("prev");
|
|
43
|
+
}
|
|
44
|
+
if (key === KEYS.arrowRight) {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
moveFocus("next");
|
|
47
|
+
}
|
|
48
|
+
if (index === API.inputs.length - 1 && value.length === 0 && key === KEYS.backspace) {
|
|
49
|
+
moveFocus("prev");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (key === KEYS.backspace && value.length === 0) {
|
|
53
|
+
moveFocus("prev");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const handleFocus = () => {
|
|
58
|
+
if (API.disabled)
|
|
59
|
+
return;
|
|
60
|
+
focused = true;
|
|
61
|
+
};
|
|
62
|
+
const handleBlur = () => {
|
|
63
|
+
if (API.disabled)
|
|
64
|
+
return;
|
|
65
|
+
focused = false;
|
|
66
|
+
};
|
|
67
|
+
const moveFocus = (direction) => {
|
|
68
|
+
const dir = {
|
|
69
|
+
next: index + 1,
|
|
70
|
+
prev: index - 1,
|
|
71
|
+
first: 0,
|
|
72
|
+
last: API.inputs.length - 1
|
|
73
|
+
};
|
|
74
|
+
const target = API.inputs[dir[direction]];
|
|
75
|
+
if (target)
|
|
76
|
+
document.querySelector(`#${target}`)?.focus();
|
|
77
|
+
};
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<input
|
|
81
|
+
bind:this={self}
|
|
82
|
+
bind:value
|
|
83
|
+
id={uid()}
|
|
84
|
+
use:useActions={use}
|
|
85
|
+
class={classProp}
|
|
86
|
+
{name}
|
|
87
|
+
disabled={API.disabled}
|
|
88
|
+
data-pininput=""
|
|
89
|
+
data-filled={API.filled || undefined}
|
|
90
|
+
placeholder={focused ? '' : API.placeholder}
|
|
91
|
+
oninput={handleInput}
|
|
92
|
+
onkeydown={handleKeyDown}
|
|
93
|
+
onfocus={handleFocus}
|
|
94
|
+
onblur={handleBlur}
|
|
95
|
+
{...props}
|
|
96
|
+
/>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type BaseProps } from '../../internal/index.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: Omit<BaseProps<HTMLInputElement, {
|
|
5
|
+
filled: boolean;
|
|
6
|
+
disabled: boolean;
|
|
7
|
+
}>, "children"> & {
|
|
8
|
+
/** The HTML Input element name attribute. */
|
|
9
|
+
name?: string | undefined;
|
|
10
|
+
};
|
|
11
|
+
events: {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
};
|
|
14
|
+
slots: {};
|
|
15
|
+
};
|
|
16
|
+
export type PinInputProps = typeof __propDef.props;
|
|
17
|
+
export type PinInputEvents = typeof __propDef.events;
|
|
18
|
+
export type PinInputSlots = typeof __propDef.slots;
|
|
19
|
+
export default class PinInput extends SvelteComponent<PinInputProps, PinInputEvents, PinInputSlots> {
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script>import { context } from "./Pin.svelte";
|
|
2
|
+
import { log, useActions, createUID, KEYS } from "../../internal/index.js";
|
|
3
|
+
import { onMount } from "svelte";
|
|
4
|
+
let { class: klass, use = [], self, name, ...props } = $props();
|
|
5
|
+
const API = context();
|
|
6
|
+
const { uid } = createUID("input");
|
|
7
|
+
const classProp = $derived(typeof klass === "function" ? klass({}) : klass);
|
|
8
|
+
onMount(() => {
|
|
9
|
+
if (!API)
|
|
10
|
+
log.error("<AccordionItem /> must be a direct child of <Accordion />");
|
|
11
|
+
});
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<input
|
|
15
|
+
bind:this={self}
|
|
16
|
+
bind:value={API.transformedValue}
|
|
17
|
+
id={uid()}
|
|
18
|
+
use:useActions={use}
|
|
19
|
+
aria-hidden="true"
|
|
20
|
+
tabindex="-1"
|
|
21
|
+
hidden
|
|
22
|
+
class={classProp}
|
|
23
|
+
data-pininput=""
|
|
24
|
+
{name}
|
|
25
|
+
{...props}
|
|
26
|
+
style="opacity: 0; pointer-events: none; user-select: none; scale: 0;"
|
|
27
|
+
/>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import { type BaseProps } from '../../internal/index.js';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: Omit<BaseProps<HTMLInputElement, any>, "children"> & {
|
|
5
|
+
/** The HTML Input element name attribute. */
|
|
6
|
+
name?: string | undefined;
|
|
7
|
+
};
|
|
8
|
+
events: {
|
|
9
|
+
[evt: string]: CustomEvent<any>;
|
|
10
|
+
};
|
|
11
|
+
slots: {};
|
|
12
|
+
};
|
|
13
|
+
export type PinValueProps = typeof __propDef.props;
|
|
14
|
+
export type PinValueEvents = typeof __propDef.events;
|
|
15
|
+
export type PinValueSlots = typeof __propDef.slots;
|
|
16
|
+
export default class PinValue extends SvelteComponent<PinValueProps, PinValueEvents, PinValueSlots> {
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type UID } from '../../internal/index.js';
|
|
2
|
+
interface Defaults {
|
|
3
|
+
value: string[];
|
|
4
|
+
disabled: boolean;
|
|
5
|
+
type: 'text' | 'password';
|
|
6
|
+
placeholder: string;
|
|
7
|
+
}
|
|
8
|
+
interface Hooks {
|
|
9
|
+
onChange: (value: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare const createContext: (uid: UID, defaults: Defaults, hooks: Hooks) => {
|
|
12
|
+
inputs: string[];
|
|
13
|
+
value: string[];
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
transformedValue: string;
|
|
16
|
+
type: "text" | "password";
|
|
17
|
+
filled: boolean;
|
|
18
|
+
placeholder: string;
|
|
19
|
+
register(inputId: string): void;
|
|
20
|
+
setValue(index: number, newVal: string): void;
|
|
21
|
+
setType(newVal: 'text' | 'password'): void;
|
|
22
|
+
setDisabled(newVal: boolean): void;
|
|
23
|
+
uid: UID;
|
|
24
|
+
};
|
|
25
|
+
export {};
|