@svelte-thing/primitives 0.0.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.
- package/README.md +1 -0
- package/dist/button/index.d.mts +9 -0
- package/dist/button/index.mjs +6 -0
- package/dist/chunk-D7D4PA-g.mjs +13 -0
- package/dist/context-BJAwVB1S.mjs +5 -0
- package/dist/context-D77KIx26.mjs +5 -0
- package/dist/context-DwEoOJU2.mjs +5 -0
- package/dist/createInput.svelte-DTz79zNF.d.mts +9 -0
- package/dist/createInput.svelte-DzcT9u1t.mjs +92 -0
- package/dist/field/date/index.d.mts +2 -0
- package/dist/field/date/index.mjs +27 -0
- package/dist/field/error/index.d.mts +2 -0
- package/dist/field/error/index.mjs +10 -0
- package/dist/field/index.d.mts +13 -0
- package/dist/field/index.mjs +25 -0
- package/dist/field/input/index.d.mts +2 -0
- package/dist/field/input/index.mjs +2 -0
- package/dist/field/label/index.d.mts +2 -0
- package/dist/field/label/index.mjs +15 -0
- package/dist/field/password/index.d.mts +2 -0
- package/dist/field/password/index.mjs +61 -0
- package/dist/field/root/index.d.mts +2 -0
- package/dist/field/root/index.mjs +79 -0
- package/dist/index-07sbgO0w.d.mts +9 -0
- package/dist/index-B-PBb_8h.d.mts +14 -0
- package/dist/index-BLb5EVhG.d.mts +35 -0
- package/dist/index-BVVgDSdq.d.mts +1 -0
- package/dist/index-Boej-mdy.d.mts +25 -0
- package/dist/index-C-ME1Tk9.d.mts +9 -0
- package/dist/index-CA_POIj_.d.mts +9 -0
- package/dist/index-CbchmhrC.d.mts +9 -0
- package/dist/index-D2vzMU8o.d.mts +13 -0
- package/dist/index-DAHEDQQS.d.mts +9 -0
- package/dist/index-OI9KlY5x.d.mts +9 -0
- package/dist/index-j-8eH9nJ.d.mts +29 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +3 -0
- package/dist/menu/index.d.mts +5 -0
- package/dist/menu/index.mjs +6 -0
- package/dist/menu/item/index.d.mts +14 -0
- package/dist/menu/item/index.mjs +86 -0
- package/dist/menu/popup/index.d.mts +19 -0
- package/dist/menu/popup/index.mjs +121 -0
- package/dist/menu/root/index.d.mts +28 -0
- package/dist/menu/root/index.mjs +69 -0
- package/dist/menu/trigger/index.d.mts +13 -0
- package/dist/menu/trigger/index.mjs +27 -0
- package/dist/pagination/content/index.d.mts +9 -0
- package/dist/pagination/content/index.mjs +6 -0
- package/dist/pagination/ellipsis/index.d.mts +9 -0
- package/dist/pagination/ellipsis/index.mjs +6 -0
- package/dist/pagination/index.d.mts +6 -0
- package/dist/pagination/index.mjs +6 -0
- package/dist/pagination/item/index.d.mts +9 -0
- package/dist/pagination/item/index.mjs +6 -0
- package/dist/pagination/link/index.d.mts +13 -0
- package/dist/pagination/link/index.mjs +13 -0
- package/dist/pagination/root/index.d.mts +9 -0
- package/dist/pagination/root/index.mjs +9 -0
- package/dist/tab/index.d.mts +13 -0
- package/dist/tab/index.mjs +21 -0
- package/dist/tab/indicator/index.d.mts +2 -0
- package/dist/tab/indicator/index.mjs +42 -0
- package/dist/tab/list/index.d.mts +2 -0
- package/dist/tab/list/index.mjs +20 -0
- package/dist/tab/panel/index.d.mts +2 -0
- package/dist/tab/panel/index.mjs +28 -0
- package/dist/tab/root/index.d.mts +2 -0
- package/dist/tab/root/index.mjs +57 -0
- package/dist/tab/title/index.d.mts +2 -0
- package/dist/tab/title/index.mjs +18 -0
- package/dist/tab/trigger/index.d.mts +2 -0
- package/dist/tab/trigger/index.mjs +94 -0
- package/dist/table/index.d.mts +2 -0
- package/dist/table/index.mjs +2 -0
- package/dist/table/row/index.d.mts +17 -0
- package/dist/table/row/index.mjs +17 -0
- package/package.json +64 -0
- package/src/button/createButton.svelte.ts +11 -0
- package/src/button/index.ts +1 -0
- package/src/field/date/createPicker.svelte.ts +41 -0
- package/src/field/date/index.ts +1 -0
- package/src/field/error/createError.svelte.ts +21 -0
- package/src/field/error/index.ts +1 -0
- package/src/field/index.ts +6 -0
- package/src/field/input/createInput.svelte.ts +136 -0
- package/src/field/input/index.ts +1 -0
- package/src/field/label/createLabel.svelte.ts +24 -0
- package/src/field/label/index.ts +1 -0
- package/src/field/password/context.ts +5 -0
- package/src/field/password/createPassword.svelte.ts +43 -0
- package/src/field/password/createShow.svelte.ts +47 -0
- package/src/field/password/index.ts +3 -0
- package/src/field/root/context.ts +5 -0
- package/src/field/root/createRoot.svelte.ts +113 -0
- package/src/field/root/index.ts +2 -0
- package/src/index.ts +2 -0
- package/src/menu/index.ts +4 -0
- package/src/menu/item/createItem.svelte.ts +123 -0
- package/src/menu/item/index.ts +1 -0
- package/src/menu/popup/createPopup.svelte.ts +186 -0
- package/src/menu/popup/index.ts +1 -0
- package/src/menu/root/context.ts +5 -0
- package/src/menu/root/createRoot.svelte.ts +96 -0
- package/src/menu/root/index.ts +2 -0
- package/src/menu/trigger/createTrigger.svelte.ts +44 -0
- package/src/menu/trigger/index.ts +1 -0
- package/src/pagination/content/createContent.svelte.ts +11 -0
- package/src/pagination/content/index.ts +1 -0
- package/src/pagination/ellipsis/createEllipsis.svelte.ts +13 -0
- package/src/pagination/ellipsis/index.ts +1 -0
- package/src/pagination/index.ts +5 -0
- package/src/pagination/item/createItem.svelte.ts +11 -0
- package/src/pagination/item/index.ts +1 -0
- package/src/pagination/link/createLink.svelte.ts +23 -0
- package/src/pagination/link/index.ts +1 -0
- package/src/pagination/root/createRoot.svelte.ts +14 -0
- package/src/pagination/root/index.ts +1 -0
- package/src/style.css +10 -0
- package/src/tab/index.ts +6 -0
- package/src/tab/indicator/createIndicator.svelte.ts +79 -0
- package/src/tab/indicator/index.ts +1 -0
- package/src/tab/list/createList.svelte.ts +27 -0
- package/src/tab/list/index.ts +1 -0
- package/src/tab/panel/createPanel.svelte.ts +42 -0
- package/src/tab/panel/index.ts +1 -0
- package/src/tab/root/context.ts +5 -0
- package/src/tab/root/createRoot.svelte.ts +85 -0
- package/src/tab/root/index.ts +2 -0
- package/src/tab/title/createTitle.svelte.ts +27 -0
- package/src/tab/title/index.ts +1 -0
- package/src/tab/trigger/createTrigger.svelte.ts +129 -0
- package/src/tab/trigger/index.ts +1 -0
- package/src/table/index.ts +1 -0
- package/src/table/row/context.ts +5 -0
- package/src/table/row/createRow.svelte.ts +26 -0
- package/src/table/row/index.ts +2 -0
package/src/style.css
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/* Triggers VS Code Extension Intellisense for Tailwind CSS. */
|
|
2
|
+
@import 'tailwindcss';
|
|
3
|
+
|
|
4
|
+
@import '@svelte-thing/tailwind-radix-colors/base';
|
|
5
|
+
@import '@svelte-thing/tailwind-radix-colors/brand';
|
|
6
|
+
@import '@svelte-thing/tailwind-radix-colors/brand-alpha';
|
|
7
|
+
@import '@svelte-thing/tailwind-radix-colors/neutral';
|
|
8
|
+
@import '@svelte-thing/tailwind-radix-colors/neutral-alpha';
|
|
9
|
+
@import '@svelte-thing/tailwind-radix-colors/blue';
|
|
10
|
+
@import '@svelte-thing/tailwind-radix-colors/gray';
|
package/src/tab/index.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { createAttachmentKey } from 'svelte/attachments';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
|
|
4
|
+
import { getRoot } from '../root/context.js';
|
|
5
|
+
|
|
6
|
+
export interface IndicatorState {
|
|
7
|
+
props: HTMLAttributes<HTMLSpanElement>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function createIndicator(): IndicatorState {
|
|
11
|
+
const root = getRoot();
|
|
12
|
+
const tabListSelector = $derived(`[data-tabs-list][id="${root.id}-list"]`);
|
|
13
|
+
const id = $derived(`${root.id}-indicator`);
|
|
14
|
+
const indicatorSelector = $derived(`[data-tabs-indicator][id="${id}"]`);
|
|
15
|
+
|
|
16
|
+
let resizeTick = $state(0);
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
props: {
|
|
20
|
+
'data-tabs-indicator': '',
|
|
21
|
+
get id() {
|
|
22
|
+
return id;
|
|
23
|
+
},
|
|
24
|
+
[createAttachmentKey()](element) {
|
|
25
|
+
const tabList = element.closest<HTMLElement>(tabListSelector);
|
|
26
|
+
if (!tabList) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const observer = new ResizeObserver(() => {
|
|
31
|
+
resizeTick += 1;
|
|
32
|
+
});
|
|
33
|
+
observer.observe(tabList);
|
|
34
|
+
|
|
35
|
+
return () => {
|
|
36
|
+
observer.disconnect();
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
get style() {
|
|
40
|
+
if (typeof document === 'undefined') {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const { value, direction, id } = root;
|
|
45
|
+
// oxlint-disable-next-line no-unused-expressions
|
|
46
|
+
resizeTick; // re-compute on ResizeObserver notifications
|
|
47
|
+
|
|
48
|
+
const indicator = document.querySelector<HTMLElement>(indicatorSelector);
|
|
49
|
+
const tabList = indicator?.closest<HTMLElement>(tabListSelector) ?? null;
|
|
50
|
+
const selectedTab = tabList?.querySelector<HTMLElement>(
|
|
51
|
+
`[data-tabs-trigger][id="${id}-trigger-${value}"]`,
|
|
52
|
+
);
|
|
53
|
+
if (!tabList || value === null || !selectedTab) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const rect = selectedTab.getBoundingClientRect();
|
|
58
|
+
// Floor it to avoid potential overflow.
|
|
59
|
+
const width = Math.floor(rect.width);
|
|
60
|
+
const height = Math.floor(rect.height);
|
|
61
|
+
|
|
62
|
+
const right =
|
|
63
|
+
direction === 'ltr'
|
|
64
|
+
? tabList.scrollWidth - selectedTab.offsetLeft - width - tabList.clientLeft
|
|
65
|
+
: selectedTab.offsetLeft - tabList.clientLeft;
|
|
66
|
+
const bottom = tabList.scrollHeight - selectedTab.offsetTop - height - tabList.clientTop;
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
`--active-tab-left: ${selectedTab.offsetLeft - tabList.clientLeft}px;` +
|
|
70
|
+
`--active-tab-top: ${selectedTab.offsetTop - tabList.clientTop}px;` +
|
|
71
|
+
`--active-tab-width: ${width}px;` +
|
|
72
|
+
`--active-tab-height: ${height}px;` +
|
|
73
|
+
`--active-tab-right: ${right}px;` +
|
|
74
|
+
`--active-tab-bottom: ${bottom}px;`
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './createIndicator.svelte.js';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
|
|
3
|
+
import { getRoot } from '../root/context.js';
|
|
4
|
+
|
|
5
|
+
export interface ListState {
|
|
6
|
+
props: HTMLAttributes<HTMLUListElement>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function createList(): ListState {
|
|
10
|
+
const root = getRoot();
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
props: {
|
|
14
|
+
get id() {
|
|
15
|
+
return `${root.id}-list`;
|
|
16
|
+
},
|
|
17
|
+
get 'aria-labelledby'() {
|
|
18
|
+
return root.hasTitle ? `${root.id}-title` : undefined;
|
|
19
|
+
},
|
|
20
|
+
get 'data-orientation'() {
|
|
21
|
+
return root.orientation;
|
|
22
|
+
},
|
|
23
|
+
'data-tabs-list': '',
|
|
24
|
+
role: 'tablist',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './createList.svelte.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Exact } from '@svelte-thing/type-utils';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
|
|
4
|
+
import { getRoot } from '../root/context.js';
|
|
5
|
+
|
|
6
|
+
export interface CreatePanelProps {
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface PanelState {
|
|
11
|
+
props: HTMLAttributes<HTMLElement>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function createPanel<T extends CreatePanelProps>(
|
|
15
|
+
props: Exact<CreatePanelProps, T>,
|
|
16
|
+
): PanelState {
|
|
17
|
+
const root = getRoot();
|
|
18
|
+
const isSelected = $derived(root.panel === props.value);
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
props: {
|
|
22
|
+
get 'aria-labelledby'() {
|
|
23
|
+
return `${root.id}-trigger-${props.value}`;
|
|
24
|
+
},
|
|
25
|
+
get 'data-orientation'() {
|
|
26
|
+
return root.orientation;
|
|
27
|
+
},
|
|
28
|
+
get 'data-hidden'() {
|
|
29
|
+
return isSelected ? undefined : '';
|
|
30
|
+
},
|
|
31
|
+
get hidden() {
|
|
32
|
+
return isSelected ? undefined : '';
|
|
33
|
+
},
|
|
34
|
+
get id() {
|
|
35
|
+
return `${root.id}-panel-${props.value}`;
|
|
36
|
+
},
|
|
37
|
+
'data-tab-panel': '',
|
|
38
|
+
role: 'tabpanel',
|
|
39
|
+
tabindex: 0,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './createPanel.svelte.js';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { Exact } from '@svelte-thing/type-utils';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { uid } from 'uid';
|
|
4
|
+
|
|
5
|
+
import { setRoot } from '../root/context.js';
|
|
6
|
+
|
|
7
|
+
export type Direction = 'ltr' | 'rtl';
|
|
8
|
+
export type Orientation = 'horizontal' | 'vertical';
|
|
9
|
+
|
|
10
|
+
export interface CreateRootProps {
|
|
11
|
+
activateOnFocus: boolean | undefined;
|
|
12
|
+
direction: Direction | undefined;
|
|
13
|
+
orientation: Orientation | undefined;
|
|
14
|
+
value: string | undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type TValue = string | null;
|
|
18
|
+
|
|
19
|
+
export interface RootState {
|
|
20
|
+
activateOnFocus: boolean;
|
|
21
|
+
direction: Direction;
|
|
22
|
+
hasTitle: boolean;
|
|
23
|
+
id: string;
|
|
24
|
+
orientation: Orientation;
|
|
25
|
+
panel: TValue;
|
|
26
|
+
value: TValue;
|
|
27
|
+
props: HTMLAttributes<HTMLElement>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function createRoot<T extends CreateRootProps>(props: Exact<CreateRootProps, T>): RootState {
|
|
31
|
+
const activateOnFocus = $derived(props.activateOnFocus ?? true);
|
|
32
|
+
const direction = $derived(props.direction ?? 'ltr');
|
|
33
|
+
const id = $derived(uid());
|
|
34
|
+
const orientation = $derived(props.orientation ?? 'horizontal');
|
|
35
|
+
|
|
36
|
+
let hasTitle = $state(false);
|
|
37
|
+
let value = $derived(props.value ?? null);
|
|
38
|
+
let panel = $derived(props.value ?? null);
|
|
39
|
+
|
|
40
|
+
const root: RootState = {
|
|
41
|
+
get activateOnFocus() {
|
|
42
|
+
return activateOnFocus;
|
|
43
|
+
},
|
|
44
|
+
get direction() {
|
|
45
|
+
return direction;
|
|
46
|
+
},
|
|
47
|
+
get hasTitle() {
|
|
48
|
+
return hasTitle;
|
|
49
|
+
},
|
|
50
|
+
set hasTitle(h) {
|
|
51
|
+
hasTitle = h;
|
|
52
|
+
},
|
|
53
|
+
get id() {
|
|
54
|
+
return id;
|
|
55
|
+
},
|
|
56
|
+
get orientation() {
|
|
57
|
+
return orientation;
|
|
58
|
+
},
|
|
59
|
+
get panel() {
|
|
60
|
+
return panel;
|
|
61
|
+
},
|
|
62
|
+
set panel(p) {
|
|
63
|
+
panel = p;
|
|
64
|
+
},
|
|
65
|
+
get value() {
|
|
66
|
+
return value;
|
|
67
|
+
},
|
|
68
|
+
set value(v) {
|
|
69
|
+
value = v;
|
|
70
|
+
},
|
|
71
|
+
props: {
|
|
72
|
+
get 'data-orientation'() {
|
|
73
|
+
return orientation;
|
|
74
|
+
},
|
|
75
|
+
get id() {
|
|
76
|
+
return id;
|
|
77
|
+
},
|
|
78
|
+
'data-tab-root': '',
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
setRoot(root);
|
|
83
|
+
|
|
84
|
+
return root;
|
|
85
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { onDestroy } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
|
|
4
|
+
import { getRoot } from '../root/context.js';
|
|
5
|
+
|
|
6
|
+
export interface TitleState {
|
|
7
|
+
props: HTMLAttributes<HTMLHeadingElement>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function createTitle(): TitleState {
|
|
11
|
+
const root = getRoot();
|
|
12
|
+
|
|
13
|
+
root.hasTitle = true;
|
|
14
|
+
|
|
15
|
+
onDestroy(() => {
|
|
16
|
+
root.hasTitle = false;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
props: {
|
|
21
|
+
get id() {
|
|
22
|
+
return `${root.id}-title`;
|
|
23
|
+
},
|
|
24
|
+
'data-tab-title': '',
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './createTitle.svelte.js';
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { Exact } from '@svelte-thing/type-utils';
|
|
2
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
|
|
4
|
+
import { getRoot } from '../root/context.js';
|
|
5
|
+
|
|
6
|
+
export interface CreateTriggerProps {
|
|
7
|
+
value: string;
|
|
8
|
+
disabled: boolean | null | undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface TriggerState {
|
|
12
|
+
props: HTMLButtonAttributes;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function createTrigger<T extends CreateTriggerProps>(
|
|
16
|
+
props: Exact<CreateTriggerProps, T>,
|
|
17
|
+
): TriggerState {
|
|
18
|
+
const root = getRoot();
|
|
19
|
+
const isSelected = $derived(root.value === props.value);
|
|
20
|
+
|
|
21
|
+
if (root.value === null) {
|
|
22
|
+
root.value = props.value;
|
|
23
|
+
root.panel = props.value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
props: {
|
|
28
|
+
get 'aria-controls'() {
|
|
29
|
+
return `${root.id}-panel-${props.value}`;
|
|
30
|
+
},
|
|
31
|
+
get 'aria-selected'() {
|
|
32
|
+
return isSelected;
|
|
33
|
+
},
|
|
34
|
+
get 'data-disabled'() {
|
|
35
|
+
return props.disabled ? true : undefined;
|
|
36
|
+
},
|
|
37
|
+
get 'data-orientation'() {
|
|
38
|
+
return root.orientation;
|
|
39
|
+
},
|
|
40
|
+
get 'data-root-id'() {
|
|
41
|
+
return root.id;
|
|
42
|
+
},
|
|
43
|
+
get 'data-selected'() {
|
|
44
|
+
return isSelected ? '' : undefined;
|
|
45
|
+
},
|
|
46
|
+
get 'data-value'() {
|
|
47
|
+
return props.value;
|
|
48
|
+
},
|
|
49
|
+
get id() {
|
|
50
|
+
return `${root.id}-trigger-${props.value}`;
|
|
51
|
+
},
|
|
52
|
+
get tabindex() {
|
|
53
|
+
return isSelected ? undefined : -1;
|
|
54
|
+
},
|
|
55
|
+
'data-tabs-trigger': '',
|
|
56
|
+
type: 'button',
|
|
57
|
+
role: 'tab',
|
|
58
|
+
onclick(event) {
|
|
59
|
+
root.value = props.value;
|
|
60
|
+
root.panel = props.value;
|
|
61
|
+
|
|
62
|
+
event.currentTarget.focus();
|
|
63
|
+
},
|
|
64
|
+
onkeydown(event) {
|
|
65
|
+
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let preventDefault = false;
|
|
70
|
+
let pendingValue: string | null = null;
|
|
71
|
+
|
|
72
|
+
const button = event.currentTarget as HTMLButtonElement;
|
|
73
|
+
const triggers = [
|
|
74
|
+
...document.querySelectorAll<HTMLButtonElement>(
|
|
75
|
+
`[data-tabs-trigger][data-root-id="${root.id}"]:not([data-disabled])`,
|
|
76
|
+
),
|
|
77
|
+
];
|
|
78
|
+
const currentIndex = triggers.indexOf(button);
|
|
79
|
+
|
|
80
|
+
const nextKeyName = root.orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';
|
|
81
|
+
const previousKeyName = root.orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';
|
|
82
|
+
|
|
83
|
+
switch (event.key) {
|
|
84
|
+
case previousKeyName: {
|
|
85
|
+
const nextIndex = currentIndex === 0 ? triggers.length - 1 : currentIndex - 1;
|
|
86
|
+
pendingValue = triggers[nextIndex]?.dataset.value ?? null;
|
|
87
|
+
triggers[nextIndex]?.focus();
|
|
88
|
+
preventDefault = true;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case nextKeyName: {
|
|
92
|
+
const nextIndex = (currentIndex + 1) % triggers.length;
|
|
93
|
+
pendingValue = triggers[nextIndex]?.dataset.value ?? null;
|
|
94
|
+
triggers[nextIndex]?.focus();
|
|
95
|
+
preventDefault = true;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case 'Home': {
|
|
99
|
+
pendingValue = triggers[0]?.dataset.value ?? null;
|
|
100
|
+
triggers[0]?.focus();
|
|
101
|
+
preventDefault = true;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case 'End': {
|
|
105
|
+
pendingValue = triggers.at(-1)?.dataset.value ?? null;
|
|
106
|
+
triggers.at(-1)?.focus();
|
|
107
|
+
preventDefault = true;
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
default: {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (pendingValue !== null) {
|
|
116
|
+
root.value = pendingValue;
|
|
117
|
+
if (root.activateOnFocus) {
|
|
118
|
+
root.panel = pendingValue;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (preventDefault) {
|
|
123
|
+
event.stopPropagation();
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './createTrigger.svelte.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './row/index.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Exact } from '@svelte-thing/type-utils';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
|
|
4
|
+
import { setRow } from './context.js';
|
|
5
|
+
|
|
6
|
+
export interface CreateRowProps {
|
|
7
|
+
href: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface RowState {
|
|
11
|
+
href: string | undefined;
|
|
12
|
+
props: HTMLAttributes<HTMLElement>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function createRow<T extends CreateRowProps>(props: Exact<CreateRowProps, T>): RowState {
|
|
16
|
+
const row: RowState = {
|
|
17
|
+
get href() {
|
|
18
|
+
return props.href;
|
|
19
|
+
},
|
|
20
|
+
props: {},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
setRow(row);
|
|
24
|
+
|
|
25
|
+
return row;
|
|
26
|
+
}
|