kosui 0.2.0 → 0.5.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 +34 -3
- package/dist/alert/alert.svelte +16 -157
- package/dist/alert/alert.svelte.d.ts +3 -26
- package/dist/alert/index.d.ts +1 -1
- package/dist/alert/index.js +1 -1
- package/dist/autocomplete/autocomplete.svelte +126 -12
- package/dist/autocomplete/autocomplete.svelte.d.ts +30 -6
- package/dist/autocomplete/index.d.ts +1 -5
- package/dist/autocomplete/index.js +1 -5
- package/dist/avatar/avatar.svelte +16 -10
- package/dist/badge/badge.svelte +31 -20
- package/dist/badge/badge.svelte.d.ts +8 -4
- package/dist/badge/index.d.ts +1 -1
- package/dist/base.d.ts +4 -8
- package/dist/base.js +14 -28
- package/dist/box/box.svelte +2 -14
- package/dist/box/box.svelte.d.ts +0 -2
- package/dist/breadcrumbs/breadcrumbs.svelte +38 -19
- package/dist/breadcrumbs/breadcrumbs.svelte.d.ts +6 -4
- package/dist/breadcrumbs/index.d.ts +1 -1
- package/dist/breadcrumbs/index.js +1 -1
- package/dist/button/button.svelte +96 -31
- package/dist/button/button.svelte.d.ts +11 -5
- package/dist/button/index.d.ts +1 -1
- package/dist/button/index.js +1 -1
- package/dist/chip/chip.svelte +62 -14
- package/dist/chip/chip.svelte.d.ts +2 -1
- package/dist/command/action.svelte.js +13 -18
- package/dist/command/command-palette.svelte +163 -0
- package/dist/command/command-palette.svelte.d.ts +11 -0
- package/dist/command/index.d.ts +1 -8
- package/dist/command/index.js +1 -8
- package/dist/common/divider.svelte +10 -5
- package/dist/common/divider.svelte.d.ts +3 -3
- package/dist/common/index.d.ts +0 -2
- package/dist/common/index.js +0 -2
- package/dist/dialog/dialog-provider.svelte +70 -0
- package/dist/dialog/dialog-provider.svelte.d.ts +7 -0
- package/dist/dialog/dialog.svelte +33 -35
- package/dist/dialog/dialog.svelte.d.ts +4 -8
- package/dist/dialog/dialogs.svelte.d.ts +49 -0
- package/dist/dialog/dialogs.svelte.js +73 -0
- package/dist/dialog/index.d.ts +2 -3
- package/dist/dialog/index.js +2 -3
- package/dist/drawer/drawer.svelte +51 -0
- package/dist/drawer/drawer.svelte.d.ts +8 -0
- package/dist/drawer/index.d.ts +1 -0
- package/dist/drawer/index.js +1 -0
- package/dist/fab/fab.svelte +30 -10
- package/dist/fab/fab.svelte.d.ts +3 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/input/field.d.ts +8 -0
- package/dist/input/field.js +7 -0
- package/dist/input/index.d.ts +2 -1
- package/dist/input/index.js +2 -1
- package/dist/input/input.svelte +21 -66
- package/dist/input/input.svelte.d.ts +6 -16
- package/dist/link/link.svelte +33 -42
- package/dist/link/link.svelte.d.ts +4 -3
- package/dist/markdown/index.d.ts +2 -25
- package/dist/markdown/index.js +0 -24
- package/dist/markdown/markdown-tokens.svelte +166 -6
- package/dist/markdown/markdown-tokens.svelte.d.ts +2 -0
- package/dist/markdown/markdown.svelte +62 -173
- package/dist/markdown/markdown.svelte.d.ts +7 -27
- package/dist/markdown/parse.d.ts +5 -0
- package/dist/markdown/parse.js +30 -0
- package/dist/markdown/types.d.ts +28 -0
- package/dist/markdown/types.js +1 -0
- package/dist/menu/index.d.ts +3 -6
- package/dist/menu/index.js +3 -6
- package/dist/menu/menu-actions.svelte +44 -38
- package/dist/menu/menu-context.d.ts +4 -0
- package/dist/menu/menu-context.js +2 -0
- package/dist/menu/menu-group.svelte +40 -0
- package/dist/menu/menu-group.svelte.d.ts +11 -0
- package/dist/menu/menu-item.svelte +31 -54
- package/dist/menu/menu-item.svelte.d.ts +7 -5
- package/dist/menu/menu.svelte +160 -15
- package/dist/menu/menu.svelte.d.ts +15 -4
- package/dist/merge-props.d.ts +1 -1
- package/dist/merge-props.js +10 -5
- package/dist/modal/modal.svelte +67 -84
- package/dist/modal/modal.svelte.d.ts +7 -4
- package/dist/nav/index.d.ts +2 -0
- package/dist/nav/index.js +2 -0
- package/dist/nav/nav-group.svelte +40 -0
- package/dist/nav/nav-group.svelte.d.ts +10 -0
- package/dist/nav/nav-item.svelte +65 -0
- package/dist/nav/nav-item.svelte.d.ts +14 -0
- package/dist/popover/index.d.ts +1 -1
- package/dist/popover/index.js +1 -1
- package/dist/popover/popover.svelte +58 -111
- package/dist/popover/popover.svelte.d.ts +6 -8
- package/dist/progress/circular-progress.svelte +64 -30
- package/dist/progress/circular-progress.svelte.d.ts +7 -8
- package/dist/shortcut/index.d.ts +2 -2
- package/dist/shortcut/index.js +1 -1
- package/dist/shortcut/shortcut-hint.svelte +36 -0
- package/dist/shortcut/shortcut-hint.svelte.d.ts +9 -0
- package/dist/shortcut/shortcut.d.ts +19 -14
- package/dist/shortcut/shortcut.js +105 -52
- package/dist/skeleton/skeleton.svelte +13 -8
- package/dist/skeleton/skeleton.svelte.d.ts +2 -5
- package/dist/slider/index.d.ts +1 -8
- package/dist/slider/index.js +1 -8
- package/dist/slider/slider.svelte +180 -211
- package/dist/slider/slider.svelte.d.ts +11 -32
- package/dist/switch/index.d.ts +1 -2
- package/dist/switch/index.js +1 -2
- package/dist/switch/switch.svelte +36 -60
- package/dist/switch/switch.svelte.d.ts +6 -17
- package/dist/textarea/index.d.ts +1 -1
- package/dist/textarea/index.js +1 -1
- package/dist/textarea/textarea.svelte +23 -63
- package/dist/textarea/textarea.svelte.d.ts +8 -18
- package/dist/theme.css +191 -0
- package/dist/toggle/index.d.ts +0 -1
- package/dist/toggle/index.js +0 -1
- package/dist/toggle/toggle-button.svelte +72 -38
- package/dist/toggle/toggle-button.svelte.d.ts +4 -4
- package/dist/toggle/toggle-context.d.ts +10 -0
- package/dist/toggle/toggle-context.js +2 -0
- package/dist/toggle/toggle-group.svelte +41 -22
- package/dist/toggle/toggle-group.svelte.d.ts +7 -4
- package/dist/tooltip/tooltip.svelte +67 -26
- package/dist/tooltip/tooltip.svelte.d.ts +10 -4
- package/dist/utils.d.ts +9 -3
- package/dist/utils.js +10 -0
- package/package.json +6 -5
- package/dist/autocomplete/autocomplete-content.svelte +0 -47
- package/dist/autocomplete/autocomplete-content.svelte.d.ts +0 -10
- package/dist/autocomplete/autocomplete-context.svelte.d.ts +0 -12
- package/dist/autocomplete/autocomplete-context.svelte.js +0 -34
- package/dist/autocomplete/autocomplete-input.svelte +0 -36
- package/dist/autocomplete/autocomplete-input.svelte.d.ts +0 -5
- package/dist/autocomplete/autocomplete-item.svelte +0 -68
- package/dist/autocomplete/autocomplete-item.svelte.d.ts +0 -11
- package/dist/base.css +0 -71
- package/dist/bindable.svelte.d.ts +0 -7
- package/dist/bindable.svelte.js +0 -25
- package/dist/command/command-content.svelte +0 -15
- package/dist/command/command-content.svelte.d.ts +0 -8
- package/dist/command/command-context.svelte.d.ts +0 -5
- package/dist/command/command-context.svelte.js +0 -13
- package/dist/command/command-input.svelte +0 -44
- package/dist/command/command-input.svelte.d.ts +0 -7
- package/dist/command/command-item.svelte +0 -66
- package/dist/command/command-item.svelte.d.ts +0 -11
- package/dist/command/command-search.svelte +0 -28
- package/dist/command/command-search.svelte.d.ts +0 -5
- package/dist/command/command.svelte +0 -19
- package/dist/command/command.svelte.d.ts +0 -8
- package/dist/command/commander.svelte +0 -107
- package/dist/command/commander.svelte.d.ts +0 -9
- package/dist/common/header.svelte +0 -35
- package/dist/common/header.svelte.d.ts +0 -10
- package/dist/common/item-context.svelte.d.ts +0 -12
- package/dist/common/item-context.svelte.js +0 -77
- package/dist/dialog/dialog-button.svelte +0 -25
- package/dist/dialog/dialog-button.svelte.d.ts +0 -32
- package/dist/dialog/dialoguer-context.svelte.d.ts +0 -53
- package/dist/dialog/dialoguer-context.svelte.js +0 -85
- package/dist/dialog/dialoguer.svelte +0 -65
- package/dist/dialog/dialoguer.svelte.d.ts +0 -7
- package/dist/markdown/markdown-blockquote.svelte +0 -14
- package/dist/markdown/markdown-blockquote.svelte.d.ts +0 -7
- package/dist/markdown/markdown-br.svelte +0 -12
- package/dist/markdown/markdown-br.svelte.d.ts +0 -7
- package/dist/markdown/markdown-code.svelte +0 -14
- package/dist/markdown/markdown-code.svelte.d.ts +0 -7
- package/dist/markdown/markdown-codespan.svelte +0 -15
- package/dist/markdown/markdown-codespan.svelte.d.ts +0 -7
- package/dist/markdown/markdown-context.svelte.d.ts +0 -26
- package/dist/markdown/markdown-context.svelte.js +0 -31
- package/dist/markdown/markdown-def.svelte +0 -15
- package/dist/markdown/markdown-def.svelte.d.ts +0 -7
- package/dist/markdown/markdown-del.svelte +0 -14
- package/dist/markdown/markdown-del.svelte.d.ts +0 -7
- package/dist/markdown/markdown-em.svelte +0 -14
- package/dist/markdown/markdown-em.svelte.d.ts +0 -7
- package/dist/markdown/markdown-escape.svelte +0 -8
- package/dist/markdown/markdown-escape.svelte.d.ts +0 -5
- package/dist/markdown/markdown-heading.svelte +0 -16
- package/dist/markdown/markdown-heading.svelte.d.ts +0 -7
- package/dist/markdown/markdown-hr.svelte +0 -12
- package/dist/markdown/markdown-hr.svelte.d.ts +0 -7
- package/dist/markdown/markdown-html.svelte +0 -9
- package/dist/markdown/markdown-html.svelte.d.ts +0 -5
- package/dist/markdown/markdown-image.svelte +0 -12
- package/dist/markdown/markdown-image.svelte.d.ts +0 -7
- package/dist/markdown/markdown-link.svelte +0 -17
- package/dist/markdown/markdown-link.svelte.d.ts +0 -7
- package/dist/markdown/markdown-list-item.svelte +0 -14
- package/dist/markdown/markdown-list-item.svelte.d.ts +0 -7
- package/dist/markdown/markdown-list.svelte +0 -19
- package/dist/markdown/markdown-list.svelte.d.ts +0 -7
- package/dist/markdown/markdown-paragraph.svelte +0 -16
- package/dist/markdown/markdown-paragraph.svelte.d.ts +0 -7
- package/dist/markdown/markdown-space.svelte +0 -8
- package/dist/markdown/markdown-space.svelte.d.ts +0 -5
- package/dist/markdown/markdown-strong.svelte +0 -15
- package/dist/markdown/markdown-strong.svelte.d.ts +0 -7
- package/dist/markdown/markdown-table-cell.svelte +0 -16
- package/dist/markdown/markdown-table-cell.svelte.d.ts +0 -7
- package/dist/markdown/markdown-table.svelte +0 -36
- package/dist/markdown/markdown-table.svelte.d.ts +0 -7
- package/dist/markdown/markdown-text.svelte +0 -8
- package/dist/markdown/markdown-text.svelte.d.ts +0 -5
- package/dist/markdown/markdown-token.svelte +0 -25
- package/dist/markdown/markdown-token.svelte.d.ts +0 -7
- package/dist/menu/menu-content.svelte +0 -47
- package/dist/menu/menu-content.svelte.d.ts +0 -10
- package/dist/menu/menu-context.svelte.d.ts +0 -18
- package/dist/menu/menu-context.svelte.js +0 -118
- package/dist/menu/menu-trigger-button.svelte +0 -31
- package/dist/menu/menu-trigger-button.svelte.d.ts +0 -5
- package/dist/menu/menu-trigger.svelte +0 -42
- package/dist/menu/menu-trigger.svelte.d.ts +0 -10
- package/dist/ordered-html-elements.d.ts +0 -7
- package/dist/ordered-html-elements.js +0 -29
- package/dist/portal/index.d.ts +0 -2
- package/dist/portal/index.js +0 -2
- package/dist/portal/portal.svelte +0 -15
- package/dist/portal/portal.svelte.d.ts +0 -8
- package/dist/portal/proxy.svelte +0 -13
- package/dist/portal/proxy.svelte.d.ts +0 -7
- package/dist/shortcut/shortcut-badge.svelte +0 -41
- package/dist/shortcut/shortcut-badge.svelte.d.ts +0 -11
- package/dist/slider/slider-context.svelte.d.ts +0 -50
- package/dist/slider/slider-context.svelte.js +0 -216
- package/dist/slider/slider-handle-label-arrow.svelte +0 -18
- package/dist/slider/slider-handle-label-arrow.svelte.d.ts +0 -6
- package/dist/slider/slider-handle-label.svelte +0 -35
- package/dist/slider/slider-handle-label.svelte.d.ts +0 -6
- package/dist/slider/slider-handle.svelte +0 -54
- package/dist/slider/slider-handle.svelte.d.ts +0 -6
- package/dist/slider/slider-mark-dot.svelte +0 -25
- package/dist/slider/slider-mark-dot.svelte.d.ts +0 -6
- package/dist/slider/slider-mark-label.svelte +0 -37
- package/dist/slider/slider-mark-label.svelte.d.ts +0 -9
- package/dist/slider/slider-mark.svelte +0 -33
- package/dist/slider/slider-mark.svelte.d.ts +0 -9
- package/dist/switch/switch-thumb.svelte +0 -52
- package/dist/switch/switch-thumb.svelte.d.ts +0 -7
- package/dist/toggle/toggle-context.svelte.d.ts +0 -9
- package/dist/toggle/toggle-context.svelte.js +0 -32
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type
|
|
1
|
+
import { type ColorProp } from "../base.js";
|
|
2
|
+
import { type ClassName } from "../utils.js";
|
|
3
3
|
import type { Snippet } from "svelte";
|
|
4
4
|
import type { HTMLButtonAttributes } from "svelte/elements";
|
|
5
5
|
export type MenuItemProps = {
|
|
6
|
-
onSelect?: (
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
onSelect?: () => void;
|
|
7
|
+
checked?: boolean;
|
|
8
|
+
el?: HTMLButtonElement;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
} & ClassName & ColorProp & Omit<HTMLButtonAttributes, "type" | "value" | "role" | "class">;
|
|
9
11
|
declare const MenuItem: import("svelte").Component<MenuItemProps, {}, "el">;
|
|
10
12
|
type MenuItem = ReturnType<typeof MenuItem>;
|
|
11
13
|
export default MenuItem;
|
package/dist/menu/menu.svelte
CHANGED
|
@@ -1,29 +1,174 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import type { ShapeProp } from "../base.js";
|
|
3
|
+
import { baseClasses } from "../base.js";
|
|
4
|
+
import { mergeProps } from "../merge-props.js";
|
|
5
|
+
import {
|
|
6
|
+
Popover,
|
|
7
|
+
type PopoverPlacement,
|
|
8
|
+
type PopoverProps,
|
|
9
|
+
} from "../popover/index.js";
|
|
10
|
+
import { Shortcut } from "../shortcut/index.js";
|
|
11
|
+
import { cn, TypingBuffer } from "../utils.js";
|
|
4
12
|
import type { Snippet } from "svelte";
|
|
13
|
+
import { createAttachmentKey, type Attachment } from "svelte/attachments";
|
|
14
|
+
import { setMenuContext } from "./menu-context.js";
|
|
15
|
+
|
|
16
|
+
export type MenuTriggerProps = {
|
|
17
|
+
[attachment: symbol]: Attachment<HTMLElement>;
|
|
18
|
+
id: string;
|
|
19
|
+
"aria-haspopup": "menu";
|
|
20
|
+
"aria-expanded": boolean;
|
|
21
|
+
"aria-controls"?: string;
|
|
22
|
+
onclick: (event: MouseEvent) => void;
|
|
23
|
+
onkeydown: (event: KeyboardEvent) => void;
|
|
24
|
+
};
|
|
5
25
|
|
|
6
26
|
export type MenuProps = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} &
|
|
27
|
+
trigger: Snippet<[MenuTriggerProps]>;
|
|
28
|
+
placement?: PopoverPlacement;
|
|
29
|
+
} & ShapeProp &
|
|
30
|
+
Omit<PopoverProps, "placement" | "anchorEl" | "onKeydownWhileOpen">;
|
|
31
|
+
|
|
32
|
+
type Start = "first" | "last" | "menu";
|
|
10
33
|
</script>
|
|
11
34
|
|
|
12
35
|
<script lang="ts">
|
|
13
36
|
let {
|
|
14
37
|
open = $bindable(false),
|
|
15
|
-
children,
|
|
16
38
|
el = $bindable(),
|
|
39
|
+
trigger,
|
|
40
|
+
placement = "bottom-start",
|
|
41
|
+
shape = "xs",
|
|
42
|
+
class: className,
|
|
43
|
+
children,
|
|
44
|
+
...restProps
|
|
17
45
|
}: MenuProps = $props();
|
|
18
46
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
47
|
+
const id = $props.id();
|
|
48
|
+
const anchor = createAttachmentKey();
|
|
49
|
+
const buffer = new TypingBuffer();
|
|
50
|
+
let anchorEl: HTMLElement | undefined = $state();
|
|
51
|
+
let start: Start = "menu";
|
|
52
|
+
|
|
53
|
+
function show(from: Start) {
|
|
54
|
+
start = from;
|
|
55
|
+
open = true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function close() {
|
|
59
|
+
open = false;
|
|
60
|
+
anchorEl?.focus();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
setMenuContext({ close });
|
|
64
|
+
|
|
65
|
+
$effect(() => {
|
|
66
|
+
if (open && el) queueMicrotask(focusStart);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
function items(): HTMLElement[] {
|
|
70
|
+
return el
|
|
71
|
+
? [
|
|
72
|
+
...el.querySelectorAll<HTMLElement>(
|
|
73
|
+
'[role^="menuitem"]:not(:disabled)',
|
|
74
|
+
),
|
|
75
|
+
]
|
|
76
|
+
: [];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function focusStart() {
|
|
80
|
+
const list = items();
|
|
81
|
+
const target =
|
|
82
|
+
start === "first" ? list[0] : start === "last" ? list.at(-1) : el;
|
|
83
|
+
(target ?? el)?.focus();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function typeahead(char: string, list: HTMLElement[], index: number) {
|
|
87
|
+
const typed = buffer.append(char).toLowerCase();
|
|
88
|
+
const prefix = [...typed].every((c) => c === typed[0]) ? typed[0] : typed;
|
|
89
|
+
const ordered = [...list.slice(index + 1), ...list.slice(0, index + 1)];
|
|
90
|
+
return ordered.find((item) =>
|
|
91
|
+
item.textContent?.trim().toLowerCase().startsWith(prefix),
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function onkeydown(event: KeyboardEvent) {
|
|
96
|
+
if (
|
|
97
|
+
Shortcut.TAB_FORWARD.matches(event) ||
|
|
98
|
+
Shortcut.TAB_BACKWARD.matches(event)
|
|
99
|
+
) {
|
|
100
|
+
open = false;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const list = items();
|
|
104
|
+
const index = list.indexOf(document.activeElement as HTMLElement);
|
|
105
|
+
let target: HTMLElement | undefined;
|
|
106
|
+
if (Shortcut.ARROW_DOWN.matches(event)) {
|
|
107
|
+
target = list[(index + 1) % list.length];
|
|
108
|
+
} else if (Shortcut.ARROW_UP.matches(event)) {
|
|
109
|
+
target = index <= 0 ? list.at(-1) : list[index - 1];
|
|
110
|
+
} else if (Shortcut.HOME.matches(event)) {
|
|
111
|
+
target = list[0];
|
|
112
|
+
} else if (Shortcut.END.matches(event)) {
|
|
113
|
+
target = list.at(-1);
|
|
114
|
+
} else if (Shortcut.isChar(event) && event.key !== " ") {
|
|
115
|
+
target = typeahead(event.key, list, index);
|
|
116
|
+
} else if (
|
|
117
|
+
!Shortcut.ENTER.matches(event) &&
|
|
118
|
+
!Shortcut.SPACE.matches(event)
|
|
119
|
+
) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
target?.focus();
|
|
123
|
+
if (target) event.preventDefault();
|
|
124
|
+
event.stopPropagation();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function onpointerleave() {
|
|
128
|
+
if (el?.contains(document.activeElement)) el.focus();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const triggerProps: MenuTriggerProps = $derived({
|
|
132
|
+
[anchor]: (node) => {
|
|
133
|
+
anchorEl = node;
|
|
134
|
+
},
|
|
135
|
+
id: `${id}-trigger`,
|
|
136
|
+
"aria-haspopup": "menu",
|
|
137
|
+
"aria-expanded": open,
|
|
138
|
+
"aria-controls": open ? `${id}-menu` : undefined,
|
|
139
|
+
onclick: (event) => {
|
|
140
|
+
if (open) open = false;
|
|
141
|
+
else show(event.detail === 0 ? "first" : "menu");
|
|
142
|
+
},
|
|
143
|
+
onkeydown: (event) => {
|
|
144
|
+
if (Shortcut.ARROW_DOWN.matches(event)) show("first");
|
|
145
|
+
else if (Shortcut.ARROW_UP.matches(event)) show("last");
|
|
146
|
+
else return;
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
},
|
|
149
|
+
});
|
|
27
150
|
</script>
|
|
28
151
|
|
|
29
|
-
{@render
|
|
152
|
+
{@render trigger(triggerProps)}
|
|
153
|
+
|
|
154
|
+
<Popover
|
|
155
|
+
bind:open
|
|
156
|
+
bind:el
|
|
157
|
+
{anchorEl}
|
|
158
|
+
{placement}
|
|
159
|
+
id="{id}-menu"
|
|
160
|
+
role="menu"
|
|
161
|
+
aria-labelledby="{id}-trigger"
|
|
162
|
+
tabindex={-1}
|
|
163
|
+
class={cn(
|
|
164
|
+
baseClasses({ shape }),
|
|
165
|
+
"max-h-[min(60vh,32rem)] min-w-40 overflow-y-auto bg-m3-surface-container p-1 text-m3-on-surface shadow-md shadow-m3-shadow/20 outline-none",
|
|
166
|
+
className,
|
|
167
|
+
)}
|
|
168
|
+
{...mergeProps(restProps, {
|
|
169
|
+
onkeydown,
|
|
170
|
+
onpointerleave,
|
|
171
|
+
})}
|
|
172
|
+
>
|
|
173
|
+
{@render children()}
|
|
174
|
+
</Popover>
|
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShapeProp } from "../base.js";
|
|
2
|
+
import { type PopoverPlacement, type PopoverProps } from "../popover/index.js";
|
|
2
3
|
import type { Snippet } from "svelte";
|
|
4
|
+
import { type Attachment } from "svelte/attachments";
|
|
5
|
+
export type MenuTriggerProps = {
|
|
6
|
+
[attachment: symbol]: Attachment<HTMLElement>;
|
|
7
|
+
id: string;
|
|
8
|
+
"aria-haspopup": "menu";
|
|
9
|
+
"aria-expanded": boolean;
|
|
10
|
+
"aria-controls"?: string;
|
|
11
|
+
onclick: (event: MouseEvent) => void;
|
|
12
|
+
onkeydown: (event: KeyboardEvent) => void;
|
|
13
|
+
};
|
|
3
14
|
export type MenuProps = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} &
|
|
15
|
+
trigger: Snippet<[MenuTriggerProps]>;
|
|
16
|
+
placement?: PopoverPlacement;
|
|
17
|
+
} & ShapeProp & Omit<PopoverProps, "placement" | "anchorEl" | "onKeydownWhileOpen">;
|
|
7
18
|
declare const Menu: import("svelte").Component<MenuProps, {}, "el" | "open">;
|
|
8
19
|
type Menu = ReturnType<typeof Menu>;
|
|
9
20
|
export default Menu;
|
package/dist/merge-props.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare function interceptStopImmediatePropagation(event: Event, callback
|
|
|
4
4
|
export declare function runEventHandlers(target: EventTarget, event: Event & {
|
|
5
5
|
currentTarget: EventTarget & Element;
|
|
6
6
|
}, ...handlers: EventHandler[]): void;
|
|
7
|
-
type Props = Record<
|
|
7
|
+
type Props = Record<PropertyKey, unknown>;
|
|
8
8
|
type PropsUnion<T extends Props[]> = (T extends (infer U)[] ? U extends Props ? (k: {
|
|
9
9
|
[K in keyof U]: U[K];
|
|
10
10
|
}) => void : never : never) extends (k: infer I) => void ? I : never;
|
package/dist/merge-props.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cn } from "./utils.js";
|
|
2
2
|
function isClass(value) {
|
|
3
3
|
if (value === null || value === undefined) {
|
|
4
4
|
return true;
|
|
@@ -9,10 +9,12 @@ function isClass(value) {
|
|
|
9
9
|
if (Array.isArray(value)) {
|
|
10
10
|
return value.every((item) => isClass(item));
|
|
11
11
|
}
|
|
12
|
-
return
|
|
12
|
+
return Object.getPrototypeOf(value) === Object.prototype;
|
|
13
13
|
}
|
|
14
14
|
function isHandlerKey(key) {
|
|
15
|
-
return
|
|
15
|
+
return (typeof key === "string" &&
|
|
16
|
+
key.startsWith("on") &&
|
|
17
|
+
key[2].toLowerCase() === key[2]);
|
|
16
18
|
}
|
|
17
19
|
function isHandler(value) {
|
|
18
20
|
return typeof value === "function";
|
|
@@ -48,10 +50,13 @@ function chainCallbacks(...callbacks) {
|
|
|
48
50
|
}
|
|
49
51
|
};
|
|
50
52
|
}
|
|
53
|
+
function ownKeys(props) {
|
|
54
|
+
return [...Object.keys(props), ...Object.getOwnPropertySymbols(props)];
|
|
55
|
+
}
|
|
51
56
|
export function mergeProps(...args) {
|
|
52
57
|
const result = {};
|
|
53
58
|
for (const props of args) {
|
|
54
|
-
for (const key
|
|
59
|
+
for (const key of ownKeys(props)) {
|
|
55
60
|
const prevVal = result[key];
|
|
56
61
|
const currVal = props[key];
|
|
57
62
|
if (currVal === undefined) {
|
|
@@ -70,7 +75,7 @@ export function mergeProps(...args) {
|
|
|
70
75
|
continue;
|
|
71
76
|
}
|
|
72
77
|
if (key === "class" && isClass(prevVal) && isClass(currVal)) {
|
|
73
|
-
result[key] =
|
|
78
|
+
result[key] = cn(prevVal, currVal);
|
|
74
79
|
continue;
|
|
75
80
|
}
|
|
76
81
|
result[key] = currVal;
|
package/dist/modal/modal.svelte
CHANGED
|
@@ -1,123 +1,106 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { events } from "../index.js";
|
|
3
|
+
import { baseClasses, type ShapeProp } from "../base.js";
|
|
3
4
|
import { mergeProps } from "../merge-props.js";
|
|
4
|
-
import {
|
|
5
|
-
import type { ClassName } from "../utils.js";
|
|
5
|
+
import { cn, type ClassName } from "../utils.js";
|
|
6
6
|
import type { Snippet } from "svelte";
|
|
7
7
|
import type { HTMLDialogAttributes } from "svelte/elements";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { prefersReducedMotion } from "svelte/motion";
|
|
9
|
+
import { scale, type TransitionConfig } from "svelte/transition";
|
|
10
10
|
|
|
11
11
|
export type ModalProps = {
|
|
12
|
-
|
|
12
|
+
el?: HTMLDialogElement;
|
|
13
13
|
onCancel?: () => void;
|
|
14
|
+
transition?: (node: Element) => TransitionConfig;
|
|
14
15
|
children: Snippet;
|
|
15
16
|
} & ClassName &
|
|
16
|
-
|
|
17
|
+
ShapeProp &
|
|
18
|
+
Omit<HTMLDialogAttributes, "class">;
|
|
19
|
+
|
|
20
|
+
type Layer = { el: HTMLDialogElement; opener?: HTMLElement };
|
|
21
|
+
|
|
22
|
+
const layers: Layer[] = [];
|
|
23
|
+
|
|
24
|
+
function zoom(node: Element) {
|
|
25
|
+
return scale(node, {
|
|
26
|
+
duration: prefersReducedMotion.current ? 0 : 150,
|
|
27
|
+
start: 0.95,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function focusedElement() {
|
|
32
|
+
const active = document.activeElement;
|
|
33
|
+
return active instanceof HTMLElement && active !== document.body
|
|
34
|
+
? active
|
|
35
|
+
: undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function closeLayer(layer: Layer) {
|
|
39
|
+
const index = layers.indexOf(layer);
|
|
40
|
+
layers.splice(index, 1);
|
|
41
|
+
const above = layers[index];
|
|
42
|
+
if (above) {
|
|
43
|
+
if (!above.opener?.isConnected || layer.el.contains(above.opener)) {
|
|
44
|
+
above.opener = layer.opener;
|
|
45
|
+
}
|
|
46
|
+
} else if (layer.opener?.isConnected) {
|
|
47
|
+
layer.opener.focus();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
17
50
|
</script>
|
|
18
51
|
|
|
19
52
|
<script lang="ts">
|
|
20
53
|
let {
|
|
21
|
-
|
|
54
|
+
el = $bindable(),
|
|
22
55
|
open = $bindable(),
|
|
23
56
|
onCancel,
|
|
57
|
+
transition = zoom,
|
|
24
58
|
children,
|
|
59
|
+
shape = "xl",
|
|
25
60
|
class: className,
|
|
26
61
|
...restProps
|
|
27
62
|
}: ModalProps = $props();
|
|
28
63
|
|
|
29
|
-
function
|
|
30
|
-
if (Shortcut.ESCAPE.matches(event)) {
|
|
31
|
-
open = false;
|
|
32
|
-
onCancel?.();
|
|
33
|
-
event.preventDefault();
|
|
34
|
-
}
|
|
64
|
+
function isolateKeys(event: KeyboardEvent) {
|
|
35
65
|
event.stopImmediatePropagation();
|
|
36
66
|
}
|
|
37
67
|
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
event.clientY < rect.top ||
|
|
43
|
-
event.clientY > rect.top + rect.height ||
|
|
44
|
-
event.clientX < rect.left ||
|
|
45
|
-
event.clientX > rect.left + rect.width
|
|
46
|
-
) {
|
|
47
|
-
open = false;
|
|
48
|
-
onCancel?.();
|
|
49
|
-
event.preventDefault();
|
|
50
|
-
event.stopImmediatePropagation();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
68
|
+
function oncancel(event: Event) {
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
open = false;
|
|
71
|
+
onCancel?.();
|
|
53
72
|
}
|
|
54
73
|
|
|
55
74
|
$effect(() => {
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
if (!el) return;
|
|
76
|
+
const layer: Layer = { el, opener: focusedElement() };
|
|
77
|
+
layers.push(layer);
|
|
78
|
+
if (!el.open) el.showModal();
|
|
79
|
+
events.on("keydown", isolateKeys);
|
|
60
80
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
81
|
+
return () => {
|
|
82
|
+
events.remove("keydown", isolateKeys);
|
|
83
|
+
closeLayer(layer);
|
|
84
|
+
};
|
|
66
85
|
});
|
|
67
86
|
</script>
|
|
68
87
|
|
|
69
88
|
{#if open}
|
|
70
89
|
<dialog
|
|
71
|
-
bind:this={
|
|
72
|
-
|
|
73
|
-
|
|
90
|
+
bind:this={el}
|
|
91
|
+
closedby="any"
|
|
92
|
+
class={cn(
|
|
93
|
+
"m-auto bg-m3-surface-container-high p-6 text-m3-on-surface shadow-lg backdrop:bg-black/50 backdrop:backdrop-blur-[2px] data-closing:backdrop:bg-transparent motion-safe:backdrop:transition-colors starting:backdrop:bg-transparent",
|
|
94
|
+
baseClasses({ shape }),
|
|
95
|
+
className,
|
|
96
|
+
)}
|
|
97
|
+
transition:transition
|
|
74
98
|
{...mergeProps(restProps, {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
ref.classList.add("backdrop-in");
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
onoutrostart: () => {
|
|
82
|
-
if (ref) {
|
|
83
|
-
ref.classList.remove("backdrop-in");
|
|
84
|
-
ref.classList.add("backdrop-out");
|
|
85
|
-
}
|
|
86
|
-
},
|
|
99
|
+
oncancel,
|
|
100
|
+
onintrostart: () => el?.removeAttribute("data-closing"),
|
|
101
|
+
onoutrostart: () => el?.setAttribute("data-closing", ""),
|
|
87
102
|
})}
|
|
88
103
|
>
|
|
89
104
|
{@render children()}
|
|
90
105
|
</dialog>
|
|
91
106
|
{/if}
|
|
92
|
-
|
|
93
|
-
<style>@layer components {
|
|
94
|
-
.backdrop-in::backdrop {
|
|
95
|
-
animation: backdrop-in 150ms forwards;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.backdrop-out::backdrop {
|
|
99
|
-
animation: backdrop-out 150ms forwards;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
@keyframes backdrop-in {
|
|
103
|
-
from {
|
|
104
|
-
background: rgba(0, 0, 0, 0);
|
|
105
|
-
backdrop-filter: blur(0px);
|
|
106
|
-
}
|
|
107
|
-
to {
|
|
108
|
-
background: rgba(0, 0, 0, 0.5);
|
|
109
|
-
backdrop-filter: blur(2px);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
@keyframes backdrop-out {
|
|
114
|
-
from {
|
|
115
|
-
background: rgba(0, 0, 0, 0.5);
|
|
116
|
-
backdrop-filter: blur(2px);
|
|
117
|
-
}
|
|
118
|
-
to {
|
|
119
|
-
background: rgba(0, 0, 0, 0);
|
|
120
|
-
backdrop-filter: blur(0px);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}</style>
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ShapeProp } from "../base.js";
|
|
2
|
+
import { type ClassName } from "../utils.js";
|
|
2
3
|
import type { Snippet } from "svelte";
|
|
3
4
|
import type { HTMLDialogAttributes } from "svelte/elements";
|
|
5
|
+
import { type TransitionConfig } from "svelte/transition";
|
|
4
6
|
export type ModalProps = {
|
|
5
|
-
|
|
7
|
+
el?: HTMLDialogElement;
|
|
6
8
|
onCancel?: () => void;
|
|
9
|
+
transition?: (node: Element) => TransitionConfig;
|
|
7
10
|
children: Snippet;
|
|
8
|
-
} & ClassName & HTMLDialogAttributes
|
|
9
|
-
declare const Modal: import("svelte").Component<ModalProps, {}, "
|
|
11
|
+
} & ClassName & ShapeProp & Omit<HTMLDialogAttributes, "class">;
|
|
12
|
+
declare const Modal: import("svelte").Component<ModalProps, {}, "el" | "open">;
|
|
10
13
|
type Modal = ReturnType<typeof Modal>;
|
|
11
14
|
export default Modal;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { cn, type ClassName, type ElementRef } from "../utils.js";
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
4
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
5
|
+
|
|
6
|
+
export type NavGroupProps = {
|
|
7
|
+
label: string;
|
|
8
|
+
children: Snippet;
|
|
9
|
+
} & ElementRef &
|
|
10
|
+
ClassName &
|
|
11
|
+
Omit<HTMLAttributes<HTMLDivElement>, "class">;
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<script lang="ts">
|
|
15
|
+
let {
|
|
16
|
+
label,
|
|
17
|
+
children,
|
|
18
|
+
el = $bindable(),
|
|
19
|
+
class: className,
|
|
20
|
+
...restProps
|
|
21
|
+
}: NavGroupProps = $props();
|
|
22
|
+
|
|
23
|
+
const id = $props.id();
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
bind:this={el}
|
|
28
|
+
role="group"
|
|
29
|
+
aria-labelledby="{id}-label"
|
|
30
|
+
class={cn("flex flex-col gap-0.5", className)}
|
|
31
|
+
{...restProps}
|
|
32
|
+
>
|
|
33
|
+
<div
|
|
34
|
+
id="{id}-label"
|
|
35
|
+
class="px-4 pt-4 pb-1 text-xs font-medium tracking-wide text-m3-on-surface-variant uppercase"
|
|
36
|
+
>
|
|
37
|
+
{label}
|
|
38
|
+
</div>
|
|
39
|
+
{@render children()}
|
|
40
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ClassName, type ElementRef } from "../utils.js";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
4
|
+
export type NavGroupProps = {
|
|
5
|
+
label: string;
|
|
6
|
+
children: Snippet;
|
|
7
|
+
} & ElementRef & ClassName & Omit<HTMLAttributes<HTMLDivElement>, "class">;
|
|
8
|
+
declare const NavGroup: import("svelte").Component<NavGroupProps, {}, "el">;
|
|
9
|
+
type NavGroup = ReturnType<typeof NavGroup>;
|
|
10
|
+
export default NavGroup;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
baseClasses,
|
|
4
|
+
type ShapeProp,
|
|
5
|
+
type Size,
|
|
6
|
+
type SizeProp,
|
|
7
|
+
} from "../base.js";
|
|
8
|
+
import { cn, type ClassName, type ElementRef } from "../utils.js";
|
|
9
|
+
import type { LucideIcon } from "@lucide/svelte";
|
|
10
|
+
import type { Snippet } from "svelte";
|
|
11
|
+
import type { HTMLAnchorAttributes } from "svelte/elements";
|
|
12
|
+
|
|
13
|
+
export type NavItemProps = {
|
|
14
|
+
href: string;
|
|
15
|
+
current?: boolean;
|
|
16
|
+
icon?: LucideIcon;
|
|
17
|
+
children: Snippet;
|
|
18
|
+
} & ElementRef &
|
|
19
|
+
ClassName &
|
|
20
|
+
ShapeProp &
|
|
21
|
+
SizeProp &
|
|
22
|
+
Omit<HTMLAnchorAttributes, "href">;
|
|
23
|
+
|
|
24
|
+
const SIZES: Record<Size, string> = {
|
|
25
|
+
xs: "h-7 gap-2 px-3 text-xs",
|
|
26
|
+
sm: "h-9 gap-3 px-4 text-sm",
|
|
27
|
+
md: "h-11 gap-3 px-4 text-sm",
|
|
28
|
+
lg: "h-13 gap-3 px-4 text-base",
|
|
29
|
+
xl: "h-15 gap-4 px-5 text-base",
|
|
30
|
+
};
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<script lang="ts">
|
|
34
|
+
let {
|
|
35
|
+
href,
|
|
36
|
+
current = false,
|
|
37
|
+
icon: Icon,
|
|
38
|
+
children,
|
|
39
|
+
el = $bindable(),
|
|
40
|
+
class: className,
|
|
41
|
+
shape = "full",
|
|
42
|
+
size = "md",
|
|
43
|
+
...restProps
|
|
44
|
+
}: NavItemProps = $props();
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<!-- eslint-disable svelte/no-navigation-without-resolve -->
|
|
48
|
+
<a
|
|
49
|
+
bind:this={el}
|
|
50
|
+
{href}
|
|
51
|
+
aria-current={current ? "page" : undefined}
|
|
52
|
+
class={cn(
|
|
53
|
+
baseClasses({ shape }),
|
|
54
|
+
SIZES[size],
|
|
55
|
+
"flex shrink-0 items-center text-m3-on-surface-variant hover:bg-m3-on-surface/8 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-m3-secondary aria-[current=page]:bg-m3-secondary-container aria-[current=page]:font-medium aria-[current=page]:text-m3-on-secondary-container",
|
|
56
|
+
className,
|
|
57
|
+
)}
|
|
58
|
+
{...restProps}
|
|
59
|
+
>
|
|
60
|
+
{#if Icon}
|
|
61
|
+
<Icon class="size-[1.25em] shrink-0" />
|
|
62
|
+
{/if}
|
|
63
|
+
{@render children()}
|
|
64
|
+
</a>
|
|
65
|
+
<!-- eslint-enable svelte/no-navigation-without-resolve -->
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ShapeProp, type SizeProp } from "../base.js";
|
|
2
|
+
import { type ClassName, type ElementRef } from "../utils.js";
|
|
3
|
+
import type { LucideIcon } from "@lucide/svelte";
|
|
4
|
+
import type { Snippet } from "svelte";
|
|
5
|
+
import type { HTMLAnchorAttributes } from "svelte/elements";
|
|
6
|
+
export type NavItemProps = {
|
|
7
|
+
href: string;
|
|
8
|
+
current?: boolean;
|
|
9
|
+
icon?: LucideIcon;
|
|
10
|
+
children: Snippet;
|
|
11
|
+
} & ElementRef & ClassName & ShapeProp & SizeProp & Omit<HTMLAnchorAttributes, "href">;
|
|
12
|
+
declare const NavItem: import("svelte").Component<NavItemProps, {}, "el">;
|
|
13
|
+
type NavItem = ReturnType<typeof NavItem>;
|
|
14
|
+
export default NavItem;
|
package/dist/popover/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as Popover, type PopoverProps } from "./popover.svelte";
|
|
1
|
+
export { default as Popover, type PopoverPlacement, type PopoverProps, } from "./popover.svelte";
|
package/dist/popover/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as Popover } from "./popover.svelte";
|
|
1
|
+
export { default as Popover, } from "./popover.svelte";
|