kosui 0.2.0 → 0.4.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/fab/fab.svelte +30 -10
- package/dist/fab/fab.svelte.d.ts +3 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -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 +60 -83
- package/dist/modal/modal.svelte.d.ts +5 -4
- 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,100 @@
|
|
|
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 { prefersReducedMotion } from "svelte/motion";
|
|
8
9
|
import { scale } from "svelte/transition";
|
|
9
|
-
import { twMerge } from "tailwind-merge";
|
|
10
10
|
|
|
11
11
|
export type ModalProps = {
|
|
12
|
-
|
|
12
|
+
el?: HTMLDialogElement;
|
|
13
13
|
onCancel?: () => void;
|
|
14
14
|
children: Snippet;
|
|
15
15
|
} & ClassName &
|
|
16
|
-
|
|
16
|
+
ShapeProp &
|
|
17
|
+
Omit<HTMLDialogAttributes, "class">;
|
|
18
|
+
|
|
19
|
+
type Layer = { el: HTMLDialogElement; opener?: HTMLElement };
|
|
20
|
+
|
|
21
|
+
const layers: Layer[] = [];
|
|
22
|
+
|
|
23
|
+
function focusedElement() {
|
|
24
|
+
const active = document.activeElement;
|
|
25
|
+
return active instanceof HTMLElement && active !== document.body
|
|
26
|
+
? active
|
|
27
|
+
: undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function closeLayer(layer: Layer) {
|
|
31
|
+
const index = layers.indexOf(layer);
|
|
32
|
+
layers.splice(index, 1);
|
|
33
|
+
const above = layers[index];
|
|
34
|
+
if (above) {
|
|
35
|
+
if (!above.opener?.isConnected || layer.el.contains(above.opener)) {
|
|
36
|
+
above.opener = layer.opener;
|
|
37
|
+
}
|
|
38
|
+
} else if (layer.opener?.isConnected) {
|
|
39
|
+
layer.opener.focus();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
17
42
|
</script>
|
|
18
43
|
|
|
19
44
|
<script lang="ts">
|
|
20
45
|
let {
|
|
21
|
-
|
|
46
|
+
el = $bindable(),
|
|
22
47
|
open = $bindable(),
|
|
23
48
|
onCancel,
|
|
24
49
|
children,
|
|
50
|
+
shape = "xl",
|
|
25
51
|
class: className,
|
|
26
52
|
...restProps
|
|
27
53
|
}: ModalProps = $props();
|
|
28
54
|
|
|
29
|
-
function
|
|
30
|
-
if (Shortcut.ESCAPE.matches(event)) {
|
|
31
|
-
open = false;
|
|
32
|
-
onCancel?.();
|
|
33
|
-
event.preventDefault();
|
|
34
|
-
}
|
|
55
|
+
function isolateKeys(event: KeyboardEvent) {
|
|
35
56
|
event.stopImmediatePropagation();
|
|
36
57
|
}
|
|
37
58
|
|
|
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
|
-
}
|
|
59
|
+
function oncancel(event: Event) {
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
open = false;
|
|
62
|
+
onCancel?.();
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
$effect(() => {
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
if (!el) return;
|
|
67
|
+
const layer: Layer = { el, opener: focusedElement() };
|
|
68
|
+
layers.push(layer);
|
|
69
|
+
if (!el.open) el.showModal();
|
|
70
|
+
events.on("keydown", isolateKeys);
|
|
60
71
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
72
|
+
return () => {
|
|
73
|
+
events.remove("keydown", isolateKeys);
|
|
74
|
+
closeLayer(layer);
|
|
75
|
+
};
|
|
66
76
|
});
|
|
67
77
|
</script>
|
|
68
78
|
|
|
69
79
|
{#if open}
|
|
70
80
|
<dialog
|
|
71
|
-
bind:this={
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
bind:this={el}
|
|
82
|
+
closedby="any"
|
|
83
|
+
class={cn(
|
|
84
|
+
"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",
|
|
85
|
+
baseClasses({ shape }),
|
|
86
|
+
className,
|
|
87
|
+
)}
|
|
88
|
+
transition:scale={{
|
|
89
|
+
duration: prefersReducedMotion.current ? 0 : 150,
|
|
90
|
+
start: 0.95,
|
|
91
|
+
}}
|
|
74
92
|
{...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
|
-
},
|
|
93
|
+
oncancel,
|
|
94
|
+
onintrostart: () => el?.removeAttribute("data-closing"),
|
|
95
|
+
onoutrostart: () => el?.setAttribute("data-closing", ""),
|
|
87
96
|
})}
|
|
88
97
|
>
|
|
89
98
|
{@render children()}
|
|
90
99
|
</dialog>
|
|
91
100
|
{/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,12 @@
|
|
|
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";
|
|
4
5
|
export type ModalProps = {
|
|
5
|
-
|
|
6
|
+
el?: HTMLDialogElement;
|
|
6
7
|
onCancel?: () => void;
|
|
7
8
|
children: Snippet;
|
|
8
|
-
} & ClassName & HTMLDialogAttributes
|
|
9
|
-
declare const Modal: import("svelte").Component<ModalProps, {}, "
|
|
9
|
+
} & ClassName & ShapeProp & Omit<HTMLDialogAttributes, "class">;
|
|
10
|
+
declare const Modal: import("svelte").Component<ModalProps, {}, "el" | "open">;
|
|
10
11
|
type Modal = ReturnType<typeof Modal>;
|
|
11
12
|
export default Modal;
|
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";
|