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.
Files changed (248) hide show
  1. package/README.md +34 -3
  2. package/dist/alert/alert.svelte +16 -157
  3. package/dist/alert/alert.svelte.d.ts +3 -26
  4. package/dist/alert/index.d.ts +1 -1
  5. package/dist/alert/index.js +1 -1
  6. package/dist/autocomplete/autocomplete.svelte +126 -12
  7. package/dist/autocomplete/autocomplete.svelte.d.ts +30 -6
  8. package/dist/autocomplete/index.d.ts +1 -5
  9. package/dist/autocomplete/index.js +1 -5
  10. package/dist/avatar/avatar.svelte +16 -10
  11. package/dist/badge/badge.svelte +31 -20
  12. package/dist/badge/badge.svelte.d.ts +8 -4
  13. package/dist/badge/index.d.ts +1 -1
  14. package/dist/base.d.ts +4 -8
  15. package/dist/base.js +14 -28
  16. package/dist/box/box.svelte +2 -14
  17. package/dist/box/box.svelte.d.ts +0 -2
  18. package/dist/breadcrumbs/breadcrumbs.svelte +38 -19
  19. package/dist/breadcrumbs/breadcrumbs.svelte.d.ts +6 -4
  20. package/dist/breadcrumbs/index.d.ts +1 -1
  21. package/dist/breadcrumbs/index.js +1 -1
  22. package/dist/button/button.svelte +96 -31
  23. package/dist/button/button.svelte.d.ts +11 -5
  24. package/dist/button/index.d.ts +1 -1
  25. package/dist/button/index.js +1 -1
  26. package/dist/chip/chip.svelte +62 -14
  27. package/dist/chip/chip.svelte.d.ts +2 -1
  28. package/dist/command/action.svelte.js +13 -18
  29. package/dist/command/command-palette.svelte +163 -0
  30. package/dist/command/command-palette.svelte.d.ts +11 -0
  31. package/dist/command/index.d.ts +1 -8
  32. package/dist/command/index.js +1 -8
  33. package/dist/common/divider.svelte +10 -5
  34. package/dist/common/divider.svelte.d.ts +3 -3
  35. package/dist/common/index.d.ts +0 -2
  36. package/dist/common/index.js +0 -2
  37. package/dist/dialog/dialog-provider.svelte +70 -0
  38. package/dist/dialog/dialog-provider.svelte.d.ts +7 -0
  39. package/dist/dialog/dialog.svelte +33 -35
  40. package/dist/dialog/dialog.svelte.d.ts +4 -8
  41. package/dist/dialog/dialogs.svelte.d.ts +49 -0
  42. package/dist/dialog/dialogs.svelte.js +73 -0
  43. package/dist/dialog/index.d.ts +2 -3
  44. package/dist/dialog/index.js +2 -3
  45. package/dist/drawer/drawer.svelte +51 -0
  46. package/dist/drawer/drawer.svelte.d.ts +8 -0
  47. package/dist/drawer/index.d.ts +1 -0
  48. package/dist/drawer/index.js +1 -0
  49. package/dist/fab/fab.svelte +30 -10
  50. package/dist/fab/fab.svelte.d.ts +3 -2
  51. package/dist/index.d.ts +2 -1
  52. package/dist/index.js +2 -1
  53. package/dist/input/field.d.ts +8 -0
  54. package/dist/input/field.js +7 -0
  55. package/dist/input/index.d.ts +2 -1
  56. package/dist/input/index.js +2 -1
  57. package/dist/input/input.svelte +21 -66
  58. package/dist/input/input.svelte.d.ts +6 -16
  59. package/dist/link/link.svelte +33 -42
  60. package/dist/link/link.svelte.d.ts +4 -3
  61. package/dist/markdown/index.d.ts +2 -25
  62. package/dist/markdown/index.js +0 -24
  63. package/dist/markdown/markdown-tokens.svelte +166 -6
  64. package/dist/markdown/markdown-tokens.svelte.d.ts +2 -0
  65. package/dist/markdown/markdown.svelte +62 -173
  66. package/dist/markdown/markdown.svelte.d.ts +7 -27
  67. package/dist/markdown/parse.d.ts +5 -0
  68. package/dist/markdown/parse.js +30 -0
  69. package/dist/markdown/types.d.ts +28 -0
  70. package/dist/markdown/types.js +1 -0
  71. package/dist/menu/index.d.ts +3 -6
  72. package/dist/menu/index.js +3 -6
  73. package/dist/menu/menu-actions.svelte +44 -38
  74. package/dist/menu/menu-context.d.ts +4 -0
  75. package/dist/menu/menu-context.js +2 -0
  76. package/dist/menu/menu-group.svelte +40 -0
  77. package/dist/menu/menu-group.svelte.d.ts +11 -0
  78. package/dist/menu/menu-item.svelte +31 -54
  79. package/dist/menu/menu-item.svelte.d.ts +7 -5
  80. package/dist/menu/menu.svelte +160 -15
  81. package/dist/menu/menu.svelte.d.ts +15 -4
  82. package/dist/merge-props.d.ts +1 -1
  83. package/dist/merge-props.js +10 -5
  84. package/dist/modal/modal.svelte +67 -84
  85. package/dist/modal/modal.svelte.d.ts +7 -4
  86. package/dist/nav/index.d.ts +2 -0
  87. package/dist/nav/index.js +2 -0
  88. package/dist/nav/nav-group.svelte +40 -0
  89. package/dist/nav/nav-group.svelte.d.ts +10 -0
  90. package/dist/nav/nav-item.svelte +65 -0
  91. package/dist/nav/nav-item.svelte.d.ts +14 -0
  92. package/dist/popover/index.d.ts +1 -1
  93. package/dist/popover/index.js +1 -1
  94. package/dist/popover/popover.svelte +58 -111
  95. package/dist/popover/popover.svelte.d.ts +6 -8
  96. package/dist/progress/circular-progress.svelte +64 -30
  97. package/dist/progress/circular-progress.svelte.d.ts +7 -8
  98. package/dist/shortcut/index.d.ts +2 -2
  99. package/dist/shortcut/index.js +1 -1
  100. package/dist/shortcut/shortcut-hint.svelte +36 -0
  101. package/dist/shortcut/shortcut-hint.svelte.d.ts +9 -0
  102. package/dist/shortcut/shortcut.d.ts +19 -14
  103. package/dist/shortcut/shortcut.js +105 -52
  104. package/dist/skeleton/skeleton.svelte +13 -8
  105. package/dist/skeleton/skeleton.svelte.d.ts +2 -5
  106. package/dist/slider/index.d.ts +1 -8
  107. package/dist/slider/index.js +1 -8
  108. package/dist/slider/slider.svelte +180 -211
  109. package/dist/slider/slider.svelte.d.ts +11 -32
  110. package/dist/switch/index.d.ts +1 -2
  111. package/dist/switch/index.js +1 -2
  112. package/dist/switch/switch.svelte +36 -60
  113. package/dist/switch/switch.svelte.d.ts +6 -17
  114. package/dist/textarea/index.d.ts +1 -1
  115. package/dist/textarea/index.js +1 -1
  116. package/dist/textarea/textarea.svelte +23 -63
  117. package/dist/textarea/textarea.svelte.d.ts +8 -18
  118. package/dist/theme.css +191 -0
  119. package/dist/toggle/index.d.ts +0 -1
  120. package/dist/toggle/index.js +0 -1
  121. package/dist/toggle/toggle-button.svelte +72 -38
  122. package/dist/toggle/toggle-button.svelte.d.ts +4 -4
  123. package/dist/toggle/toggle-context.d.ts +10 -0
  124. package/dist/toggle/toggle-context.js +2 -0
  125. package/dist/toggle/toggle-group.svelte +41 -22
  126. package/dist/toggle/toggle-group.svelte.d.ts +7 -4
  127. package/dist/tooltip/tooltip.svelte +67 -26
  128. package/dist/tooltip/tooltip.svelte.d.ts +10 -4
  129. package/dist/utils.d.ts +9 -3
  130. package/dist/utils.js +10 -0
  131. package/package.json +6 -5
  132. package/dist/autocomplete/autocomplete-content.svelte +0 -47
  133. package/dist/autocomplete/autocomplete-content.svelte.d.ts +0 -10
  134. package/dist/autocomplete/autocomplete-context.svelte.d.ts +0 -12
  135. package/dist/autocomplete/autocomplete-context.svelte.js +0 -34
  136. package/dist/autocomplete/autocomplete-input.svelte +0 -36
  137. package/dist/autocomplete/autocomplete-input.svelte.d.ts +0 -5
  138. package/dist/autocomplete/autocomplete-item.svelte +0 -68
  139. package/dist/autocomplete/autocomplete-item.svelte.d.ts +0 -11
  140. package/dist/base.css +0 -71
  141. package/dist/bindable.svelte.d.ts +0 -7
  142. package/dist/bindable.svelte.js +0 -25
  143. package/dist/command/command-content.svelte +0 -15
  144. package/dist/command/command-content.svelte.d.ts +0 -8
  145. package/dist/command/command-context.svelte.d.ts +0 -5
  146. package/dist/command/command-context.svelte.js +0 -13
  147. package/dist/command/command-input.svelte +0 -44
  148. package/dist/command/command-input.svelte.d.ts +0 -7
  149. package/dist/command/command-item.svelte +0 -66
  150. package/dist/command/command-item.svelte.d.ts +0 -11
  151. package/dist/command/command-search.svelte +0 -28
  152. package/dist/command/command-search.svelte.d.ts +0 -5
  153. package/dist/command/command.svelte +0 -19
  154. package/dist/command/command.svelte.d.ts +0 -8
  155. package/dist/command/commander.svelte +0 -107
  156. package/dist/command/commander.svelte.d.ts +0 -9
  157. package/dist/common/header.svelte +0 -35
  158. package/dist/common/header.svelte.d.ts +0 -10
  159. package/dist/common/item-context.svelte.d.ts +0 -12
  160. package/dist/common/item-context.svelte.js +0 -77
  161. package/dist/dialog/dialog-button.svelte +0 -25
  162. package/dist/dialog/dialog-button.svelte.d.ts +0 -32
  163. package/dist/dialog/dialoguer-context.svelte.d.ts +0 -53
  164. package/dist/dialog/dialoguer-context.svelte.js +0 -85
  165. package/dist/dialog/dialoguer.svelte +0 -65
  166. package/dist/dialog/dialoguer.svelte.d.ts +0 -7
  167. package/dist/markdown/markdown-blockquote.svelte +0 -14
  168. package/dist/markdown/markdown-blockquote.svelte.d.ts +0 -7
  169. package/dist/markdown/markdown-br.svelte +0 -12
  170. package/dist/markdown/markdown-br.svelte.d.ts +0 -7
  171. package/dist/markdown/markdown-code.svelte +0 -14
  172. package/dist/markdown/markdown-code.svelte.d.ts +0 -7
  173. package/dist/markdown/markdown-codespan.svelte +0 -15
  174. package/dist/markdown/markdown-codespan.svelte.d.ts +0 -7
  175. package/dist/markdown/markdown-context.svelte.d.ts +0 -26
  176. package/dist/markdown/markdown-context.svelte.js +0 -31
  177. package/dist/markdown/markdown-def.svelte +0 -15
  178. package/dist/markdown/markdown-def.svelte.d.ts +0 -7
  179. package/dist/markdown/markdown-del.svelte +0 -14
  180. package/dist/markdown/markdown-del.svelte.d.ts +0 -7
  181. package/dist/markdown/markdown-em.svelte +0 -14
  182. package/dist/markdown/markdown-em.svelte.d.ts +0 -7
  183. package/dist/markdown/markdown-escape.svelte +0 -8
  184. package/dist/markdown/markdown-escape.svelte.d.ts +0 -5
  185. package/dist/markdown/markdown-heading.svelte +0 -16
  186. package/dist/markdown/markdown-heading.svelte.d.ts +0 -7
  187. package/dist/markdown/markdown-hr.svelte +0 -12
  188. package/dist/markdown/markdown-hr.svelte.d.ts +0 -7
  189. package/dist/markdown/markdown-html.svelte +0 -9
  190. package/dist/markdown/markdown-html.svelte.d.ts +0 -5
  191. package/dist/markdown/markdown-image.svelte +0 -12
  192. package/dist/markdown/markdown-image.svelte.d.ts +0 -7
  193. package/dist/markdown/markdown-link.svelte +0 -17
  194. package/dist/markdown/markdown-link.svelte.d.ts +0 -7
  195. package/dist/markdown/markdown-list-item.svelte +0 -14
  196. package/dist/markdown/markdown-list-item.svelte.d.ts +0 -7
  197. package/dist/markdown/markdown-list.svelte +0 -19
  198. package/dist/markdown/markdown-list.svelte.d.ts +0 -7
  199. package/dist/markdown/markdown-paragraph.svelte +0 -16
  200. package/dist/markdown/markdown-paragraph.svelte.d.ts +0 -7
  201. package/dist/markdown/markdown-space.svelte +0 -8
  202. package/dist/markdown/markdown-space.svelte.d.ts +0 -5
  203. package/dist/markdown/markdown-strong.svelte +0 -15
  204. package/dist/markdown/markdown-strong.svelte.d.ts +0 -7
  205. package/dist/markdown/markdown-table-cell.svelte +0 -16
  206. package/dist/markdown/markdown-table-cell.svelte.d.ts +0 -7
  207. package/dist/markdown/markdown-table.svelte +0 -36
  208. package/dist/markdown/markdown-table.svelte.d.ts +0 -7
  209. package/dist/markdown/markdown-text.svelte +0 -8
  210. package/dist/markdown/markdown-text.svelte.d.ts +0 -5
  211. package/dist/markdown/markdown-token.svelte +0 -25
  212. package/dist/markdown/markdown-token.svelte.d.ts +0 -7
  213. package/dist/menu/menu-content.svelte +0 -47
  214. package/dist/menu/menu-content.svelte.d.ts +0 -10
  215. package/dist/menu/menu-context.svelte.d.ts +0 -18
  216. package/dist/menu/menu-context.svelte.js +0 -118
  217. package/dist/menu/menu-trigger-button.svelte +0 -31
  218. package/dist/menu/menu-trigger-button.svelte.d.ts +0 -5
  219. package/dist/menu/menu-trigger.svelte +0 -42
  220. package/dist/menu/menu-trigger.svelte.d.ts +0 -10
  221. package/dist/ordered-html-elements.d.ts +0 -7
  222. package/dist/ordered-html-elements.js +0 -29
  223. package/dist/portal/index.d.ts +0 -2
  224. package/dist/portal/index.js +0 -2
  225. package/dist/portal/portal.svelte +0 -15
  226. package/dist/portal/portal.svelte.d.ts +0 -8
  227. package/dist/portal/proxy.svelte +0 -13
  228. package/dist/portal/proxy.svelte.d.ts +0 -7
  229. package/dist/shortcut/shortcut-badge.svelte +0 -41
  230. package/dist/shortcut/shortcut-badge.svelte.d.ts +0 -11
  231. package/dist/slider/slider-context.svelte.d.ts +0 -50
  232. package/dist/slider/slider-context.svelte.js +0 -216
  233. package/dist/slider/slider-handle-label-arrow.svelte +0 -18
  234. package/dist/slider/slider-handle-label-arrow.svelte.d.ts +0 -6
  235. package/dist/slider/slider-handle-label.svelte +0 -35
  236. package/dist/slider/slider-handle-label.svelte.d.ts +0 -6
  237. package/dist/slider/slider-handle.svelte +0 -54
  238. package/dist/slider/slider-handle.svelte.d.ts +0 -6
  239. package/dist/slider/slider-mark-dot.svelte +0 -25
  240. package/dist/slider/slider-mark-dot.svelte.d.ts +0 -6
  241. package/dist/slider/slider-mark-label.svelte +0 -37
  242. package/dist/slider/slider-mark-label.svelte.d.ts +0 -9
  243. package/dist/slider/slider-mark.svelte +0 -33
  244. package/dist/slider/slider-mark.svelte.d.ts +0 -9
  245. package/dist/switch/switch-thumb.svelte +0 -52
  246. package/dist/switch/switch-thumb.svelte.d.ts +0 -7
  247. package/dist/toggle/toggle-context.svelte.d.ts +0 -9
  248. package/dist/toggle/toggle-context.svelte.js +0 -32
@@ -0,0 +1,163 @@
1
+ <script module lang="ts">
2
+ import { events } from "../index.js";
3
+ import { Modal } from "../modal/index.js";
4
+ import { Shortcut, ShortcutHint } from "../shortcut/index.js";
5
+ import { match } from "../utils.js";
6
+ import { Check, Search } from "@lucide/svelte";
7
+ import type { Action, Registry } from "./action.svelte";
8
+
9
+ export type CommandPaletteProps = {
10
+ registry: Registry;
11
+ open?: boolean;
12
+ query?: string;
13
+ label?: string;
14
+ placeholder?: string;
15
+ };
16
+
17
+ function isTyping(event: KeyboardEvent) {
18
+ return (
19
+ event.target instanceof HTMLElement &&
20
+ (event.target.isContentEditable ||
21
+ event.target.matches("input, textarea, select"))
22
+ );
23
+ }
24
+ </script>
25
+
26
+ <script lang="ts">
27
+ let {
28
+ registry,
29
+ open = $bindable(false),
30
+ query = $bindable(""),
31
+ label = "Command palette",
32
+ placeholder = "Search commands",
33
+ }: CommandPaletteProps = $props();
34
+
35
+ const id = $props.id();
36
+ let active = $state(0);
37
+
38
+ const actions = $derived(
39
+ registry.actions.filter(
40
+ (action) =>
41
+ action.enabled() &&
42
+ (match(action.id, query) ||
43
+ (action.category && match(action.category, query)) ||
44
+ match(action.name, query) ||
45
+ match(action.description, query)),
46
+ ),
47
+ );
48
+ const current = $derived(Math.min(active, actions.length - 1));
49
+
50
+ function run(action: Action) {
51
+ open = false;
52
+ action.callback();
53
+ }
54
+
55
+ function onkeydown(event: KeyboardEvent) {
56
+ const count = actions.length;
57
+ if (Shortcut.ARROW_DOWN.matches(event)) {
58
+ active = (current + 1) % count;
59
+ } else if (Shortcut.ARROW_UP.matches(event)) {
60
+ active = (current - 1 + count) % count;
61
+ } else if (Shortcut.ENTER.matches(event) && current !== -1) {
62
+ run(actions[current]);
63
+ } else {
64
+ return;
65
+ }
66
+ event.preventDefault();
67
+ }
68
+
69
+ function runShortcut(event: KeyboardEvent) {
70
+ const shortcut = Shortcut.fromEvent(event);
71
+ if (isTyping(event) && !shortcut.ctrl && !shortcut.meta && !shortcut.alt) {
72
+ return;
73
+ }
74
+ const action = registry.getByShortcut(shortcut);
75
+ if (action?.enabled()) {
76
+ action.callback();
77
+ event.preventDefault();
78
+ event.stopImmediatePropagation();
79
+ }
80
+ }
81
+
82
+ $effect(() => events.on("keydown", runShortcut));
83
+
84
+ $effect(() => {
85
+ if (current !== -1) {
86
+ document
87
+ .getElementById(`${id}-${current}`)
88
+ ?.scrollIntoView({ block: "nearest" });
89
+ }
90
+ });
91
+ </script>
92
+
93
+ <Modal
94
+ bind:open
95
+ aria-label={label}
96
+ class="flex h-[min(60vh,32rem)] w-[min(calc(100%-1em),36rem)] flex-col p-0"
97
+ onoutroend={() => {
98
+ query = "";
99
+ active = 0;
100
+ }}
101
+ >
102
+ <div class="flex items-center gap-2 border-b border-m3-outline-variant px-4">
103
+ <Search size={16} class="shrink-0 text-m3-on-surface-variant" />
104
+ <!-- svelte-ignore a11y_autofocus -->
105
+ <input
106
+ bind:value={query}
107
+ role="combobox"
108
+ aria-label={placeholder}
109
+ aria-autocomplete="list"
110
+ aria-expanded="true"
111
+ aria-controls="{id}-listbox"
112
+ aria-activedescendant={current === -1 ? undefined : `${id}-${current}`}
113
+ autocomplete="off"
114
+ autofocus
115
+ {placeholder}
116
+ class="h-12 w-full bg-transparent outline-none placeholder:text-m3-on-surface-variant"
117
+ oninput={() => (active = 0)}
118
+ {onkeydown}
119
+ />
120
+ </div>
121
+ <div
122
+ id="{id}-listbox"
123
+ role="listbox"
124
+ aria-label={label}
125
+ class="grow overflow-y-auto p-2"
126
+ >
127
+ {#each actions as action, index (action.id)}
128
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
129
+ <div
130
+ id="{id}-{index}"
131
+ role="option"
132
+ tabindex="-1"
133
+ aria-selected={index === current}
134
+ aria-checked={action.selected?.()}
135
+ title={action.description}
136
+ class="flex min-h-9 cursor-pointer items-center gap-3 rounded-sm px-3 text-sm aria-selected:bg-m3-on-surface/10"
137
+ onmousedown={(event) => event.preventDefault()}
138
+ onpointermove={() => (active = index)}
139
+ onclick={() => run(action)}
140
+ >
141
+ <action.icon size={16} class="shrink-0 text-m3-on-surface-variant" />
142
+ <span class="grow">
143
+ {#if action.category}
144
+ <span class="text-m3-on-surface-variant">{action.category}:</span>
145
+ {/if}
146
+ {action.name}
147
+ </span>
148
+ {#if action.selected?.()}
149
+ <Check size={16} class="shrink-0 text-m3-primary" />
150
+ {/if}
151
+ {#if action.shortcut}
152
+ <ShortcutHint shortcut={action.shortcut} />
153
+ {/if}
154
+ </div>
155
+ {/each}
156
+ </div>
157
+ <p
158
+ role="status"
159
+ class="absolute inset-x-0 top-1/2 text-center text-sm text-m3-on-surface-variant empty:hidden"
160
+ >
161
+ {actions.length === 0 ? "No matching commands" : ""}
162
+ </p>
163
+ </Modal>
@@ -0,0 +1,11 @@
1
+ import type { Registry } from "./action.svelte";
2
+ export type CommandPaletteProps = {
3
+ registry: Registry;
4
+ open?: boolean;
5
+ query?: string;
6
+ label?: string;
7
+ placeholder?: string;
8
+ };
9
+ declare const CommandPalette: import("svelte").Component<CommandPaletteProps, {}, "open" | "query">;
10
+ type CommandPalette = ReturnType<typeof CommandPalette>;
11
+ export default CommandPalette;
@@ -1,9 +1,2 @@
1
- export { Divider as CommandDivider, Header as CommandHeader, } from "../common/index.js";
2
1
  export { Action, Registry } from "./action.svelte";
3
- export { default as CommandContent } from "./command-content.svelte";
4
- export { CommandContext, getCommandContext, setCommandContext, } from "./command-context.svelte.js";
5
- export { default as CommandInput, type CommandInputProps, } from "./command-input.svelte";
6
- export { default as CommandItem, type CommandItemProps, } from "./command-item.svelte";
7
- export { default as CommandSearch, type CommandSearchProps, } from "./command-search.svelte";
8
- export { default as Command, type CommandProps } from "./command.svelte";
9
- export { default as Commander, type CommanderProps } from "./commander.svelte";
2
+ export { default as CommandPalette, type CommandPaletteProps, } from "./command-palette.svelte";
@@ -1,9 +1,2 @@
1
- export { Divider as CommandDivider, Header as CommandHeader, } from "../common/index.js";
2
1
  export { Action, Registry } from "./action.svelte";
3
- export { default as CommandContent } from "./command-content.svelte";
4
- export { CommandContext, getCommandContext, setCommandContext, } from "./command-context.svelte.js";
5
- export { default as CommandInput, } from "./command-input.svelte";
6
- export { default as CommandItem, } from "./command-item.svelte";
7
- export { default as CommandSearch, } from "./command-search.svelte";
8
- export { default as Command } from "./command.svelte";
9
- export { default as Commander } from "./commander.svelte";
2
+ export { default as CommandPalette, } from "./command-palette.svelte";
@@ -1,13 +1,18 @@
1
1
  <script module lang="ts">
2
- import type { ClassName } from "../utils.js";
2
+ import { cn, type ClassName, type ElementRef } from "../utils.js";
3
3
  import type { HTMLAttributes } from "svelte/elements";
4
- import { twMerge } from "tailwind-merge";
5
4
 
6
- export type DividerProps = {} & ClassName & HTMLAttributes<HTMLHRElement>;
5
+ export type DividerProps = ElementRef &
6
+ ClassName &
7
+ HTMLAttributes<HTMLHRElement>;
7
8
  </script>
8
9
 
9
10
  <script lang="ts">
10
- let { class: className, ...restProps }: DividerProps = $props();
11
+ let {
12
+ el = $bindable(),
13
+ class: className,
14
+ ...restProps
15
+ }: DividerProps = $props();
11
16
  </script>
12
17
 
13
- <hr class={twMerge("-mx-1 my-1", className)} {...restProps} />
18
+ <hr bind:this={el} class={cn("my-1", className)} {...restProps} />
@@ -1,6 +1,6 @@
1
- import type { ClassName } from "../utils.js";
1
+ import { type ClassName, type ElementRef } from "../utils.js";
2
2
  import type { HTMLAttributes } from "svelte/elements";
3
- export type DividerProps = {} & ClassName & HTMLAttributes<HTMLHRElement>;
4
- declare const Divider: import("svelte").Component<DividerProps, {}, "">;
3
+ export type DividerProps = ElementRef & ClassName & HTMLAttributes<HTMLHRElement>;
4
+ declare const Divider: import("svelte").Component<DividerProps, {}, "el">;
5
5
  type Divider = ReturnType<typeof Divider>;
6
6
  export default Divider;
@@ -1,3 +1 @@
1
1
  export { default as Divider, type DividerProps } from "./divider.svelte";
2
- export { default as Header, type HeaderProps } from "./header.svelte";
3
- export { ItemContext } from "./item-context.svelte";
@@ -1,3 +1 @@
1
1
  export { default as Divider } from "./divider.svelte";
2
- export { default as Header } from "./header.svelte";
3
- export { ItemContext } from "./item-context.svelte";
@@ -0,0 +1,70 @@
1
+ <script lang="ts">
2
+ import { Button } from "../button/index.js";
3
+ import { Input } from "../input/index.js";
4
+ import type { Snippet } from "svelte";
5
+ import Dialog from "./dialog.svelte";
6
+ import { Dialogs, setDialogs } from "./dialogs.svelte.js";
7
+
8
+ let { children }: { children: Snippet } = $props();
9
+
10
+ const id = $props.id();
11
+ const dialogs = setDialogs(new Dialogs());
12
+ const request = $derived(dialogs.current);
13
+ let value = $derived(request?.value ?? "");
14
+ </script>
15
+
16
+ <Dialog
17
+ bind:open={dialogs.open}
18
+ icon={request?.icon}
19
+ title={request?.title}
20
+ aria-describedby="{id}-message"
21
+ onSelect={(selected) => dialogs.settle(selected)}
22
+ >
23
+ {#key request}
24
+ <div id="{id}-message">
25
+ {#if typeof request?.message === "function"}
26
+ {@render request.message()}
27
+ {:else}
28
+ {request?.message}
29
+ {/if}
30
+ </div>
31
+ {#if request?.input}
32
+ <form
33
+ id="{id}-form"
34
+ class="mt-4"
35
+ onsubmit={(event) => {
36
+ event.preventDefault();
37
+ dialogs.settle(value);
38
+ }}
39
+ >
40
+ <Input
41
+ bind:value
42
+ aria-labelledby="{id}-message"
43
+ autofocus
44
+ {...request.input}
45
+ class={["w-full", request.input.class]}
46
+ />
47
+ </form>
48
+ {/if}
49
+ {/key}
50
+
51
+ {#snippet actions(select)}
52
+ {#key request}
53
+ {#each request?.actions ?? [] as action, i (i)}
54
+ <Button
55
+ variant={action.variant}
56
+ color={action.color}
57
+ shape={action.shape}
58
+ autofocus={action.default}
59
+ {...action.submit
60
+ ? { type: "submit", form: `${id}-form` }
61
+ : { onclick: () => select(action.value) }}
62
+ >
63
+ {action.text}
64
+ </Button>
65
+ {/each}
66
+ {/key}
67
+ {/snippet}
68
+ </Dialog>
69
+
70
+ {@render children()}
@@ -0,0 +1,7 @@
1
+ import type { Snippet } from "svelte";
2
+ type $$ComponentProps = {
3
+ children: Snippet;
4
+ };
5
+ declare const DialogProvider: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type DialogProvider = ReturnType<typeof DialogProvider>;
7
+ export default DialogProvider;
@@ -1,69 +1,67 @@
1
1
  <script module lang="ts">
2
2
  import { mergeComponentProps } from "../merge-props.js";
3
3
  import { Modal, type ModalProps } from "../modal/index.js";
4
+ import { cn } from "../utils.js";
4
5
  import type { LucideIcon } from "@lucide/svelte";
5
6
  import type { Snippet } from "svelte";
6
- import { twMerge } from "tailwind-merge";
7
7
 
8
8
  export type DialogProps<T> = {
9
- ref?: HTMLDialogElement;
10
- onSelect?: (value: T | undefined) => void;
11
9
  icon?: LucideIcon;
12
10
  title?: string;
13
- children: Snippet;
14
- actions?: Snippet<[{ onSelect: (value: T | undefined) => void }]>;
11
+ onSelect?: (value: T | undefined) => void;
12
+ actions?: Snippet<[select: (value: T | undefined) => void]>;
15
13
  } & ModalProps;
16
14
  </script>
17
15
 
18
16
  <script lang="ts" generics="T">
19
17
  let {
20
- ref = $bindable(),
18
+ el = $bindable(),
21
19
  open = $bindable(),
22
- onSelect,
23
- class: className,
24
- icon: IconComponent,
20
+ icon: Icon,
25
21
  title,
22
+ onSelect,
26
23
  children,
27
24
  actions,
25
+ class: className,
28
26
  ...restProps
29
27
  }: DialogProps<T> = $props();
30
28
 
31
- function handleSelect(value: T | undefined) {
32
- onSelect?.(value);
33
- open = false;
34
- }
29
+ const id = $props.id();
35
30
 
36
- function handleCancel() {
37
- onSelect?.(undefined);
31
+ function select(value: T | undefined) {
32
+ open = false;
33
+ onSelect?.(value);
38
34
  }
39
35
  </script>
40
36
 
41
37
  <Modal
42
- bind:ref
38
+ bind:el
43
39
  bind:open
44
- class={twMerge("w-[min(calc(100%-1em),36em)]", className)}
40
+ class={cn("flex w-[min(calc(100%-1em),36em)] flex-col gap-4", className)}
45
41
  {...mergeComponentProps(
46
42
  Modal,
47
- { role: "dialog", "aria-modal": "true", onCancel: handleCancel },
43
+ {
44
+ "aria-labelledby":
45
+ title && !restProps["aria-label"] ? `${id}-title` : undefined,
46
+ onCancel: () => onSelect?.(undefined),
47
+ },
48
48
  restProps,
49
49
  )}
50
50
  >
51
- <div class={twMerge("flex flex-col gap-4")}>
52
- {#if IconComponent}
53
- <IconComponent class="mx-auto" />
54
- {/if}
55
- {#if title}
56
- <div class={twMerge("text-xl", IconComponent ? "text-center" : "")}>
57
- {title}
58
- </div>
59
- {/if}
60
- <div>
61
- {@render children()}
62
- </div>
63
- {#if actions}
64
- <div class="mt-2 flex place-content-end gap-2">
65
- {@render actions({ onSelect: handleSelect })}
66
- </div>
67
- {/if}
51
+ {#if Icon}
52
+ <Icon class="mx-auto text-m3-secondary" />
53
+ {/if}
54
+ {#if title}
55
+ <h2 id="{id}-title" class={cn("text-2xl", Icon && "text-center")}>
56
+ {title}
57
+ </h2>
58
+ {/if}
59
+ <div class="text-sm text-m3-on-surface-variant">
60
+ {@render children()}
68
61
  </div>
62
+ {#if actions}
63
+ <div class="mt-2 flex flex-wrap justify-end gap-2">
64
+ {@render actions(select)}
65
+ </div>
66
+ {/if}
69
67
  </Modal>
@@ -2,19 +2,15 @@ import { type ModalProps } from "../modal/index.js";
2
2
  import type { LucideIcon } from "@lucide/svelte";
3
3
  import type { Snippet } from "svelte";
4
4
  export type DialogProps<T> = {
5
- ref?: HTMLDialogElement;
6
- onSelect?: (value: T | undefined) => void;
7
5
  icon?: LucideIcon;
8
6
  title?: string;
9
- children: Snippet;
10
- actions?: Snippet<[{
11
- onSelect: (value: T | undefined) => void;
12
- }]>;
7
+ onSelect?: (value: T | undefined) => void;
8
+ actions?: Snippet<[select: (value: T | undefined) => void]>;
13
9
  } & ModalProps;
14
10
  declare function $$render<T>(): {
15
11
  props: DialogProps<T>;
16
12
  exports: {};
17
- bindings: "open" | "ref";
13
+ bindings: "el" | "open";
18
14
  slots: {};
19
15
  events: {};
20
16
  };
@@ -22,7 +18,7 @@ declare class __sveltets_Render<T> {
22
18
  props(): ReturnType<typeof $$render<T>>['props'];
23
19
  events(): ReturnType<typeof $$render<T>>['events'];
24
20
  slots(): ReturnType<typeof $$render<T>>['slots'];
25
- bindings(): "open" | "ref";
21
+ bindings(): "el" | "open";
26
22
  exports(): {};
27
23
  }
28
24
  interface $$IsomorphicComponent {
@@ -0,0 +1,49 @@
1
+ import type { Variants } from "../base.js";
2
+ import type { InputProps } from "../input/index.js";
3
+ import type { LucideIcon } from "@lucide/svelte";
4
+ import { type Snippet } from "svelte";
5
+ export type DialogAction<T> = {
6
+ text: string;
7
+ value: T;
8
+ default?: boolean;
9
+ } & Variants;
10
+ type DialogContent = {
11
+ icon?: LucideIcon;
12
+ title?: string;
13
+ message: Snippet | string;
14
+ };
15
+ export type AlertOptions = DialogContent & {
16
+ acceptText?: string;
17
+ };
18
+ export type ConfirmOptions = DialogContent & {
19
+ cancelText?: string;
20
+ acceptText?: string;
21
+ };
22
+ export type PromptOptions = DialogContent & {
23
+ input?: InputProps;
24
+ cancelText?: string;
25
+ acceptText?: string;
26
+ };
27
+ export type ShowOptions<T> = DialogContent & {
28
+ actions: DialogAction<T>[];
29
+ };
30
+ export type DialogRequest = DialogContent & {
31
+ actions: (DialogAction<unknown> & {
32
+ submit?: boolean;
33
+ })[];
34
+ input?: Omit<InputProps, "value">;
35
+ value?: string;
36
+ resolve: (value: unknown) => void;
37
+ };
38
+ export declare class Dialogs {
39
+ #private;
40
+ current: DialogRequest | undefined;
41
+ open: boolean;
42
+ show<T>(options: ShowOptions<T>): Promise<T | undefined>;
43
+ alert({ acceptText, ...content }: AlertOptions): Promise<void>;
44
+ confirm({ cancelText, acceptText, ...content }: ConfirmOptions): Promise<boolean>;
45
+ prompt({ input: { value, ...input }, cancelText, acceptText, ...content }: PromptOptions): Promise<string | undefined>;
46
+ settle(value: unknown): void;
47
+ }
48
+ export declare const getDialogs: () => Dialogs, setDialogs: (context: Dialogs) => Dialogs;
49
+ export {};
@@ -0,0 +1,73 @@
1
+ import { createContext } from "svelte";
2
+ export class Dialogs {
3
+ current = $state.raw();
4
+ open = $state(false);
5
+ #active;
6
+ #queue = [];
7
+ show(options) {
8
+ return this.#request(options);
9
+ }
10
+ async alert({ acceptText, ...content }) {
11
+ await this.#request({
12
+ ...content,
13
+ actions: [
14
+ {
15
+ text: acceptText ?? "OK",
16
+ value: undefined,
17
+ variant: "filled",
18
+ default: true,
19
+ },
20
+ ],
21
+ });
22
+ }
23
+ async confirm({ cancelText, acceptText, ...content }) {
24
+ const accepted = await this.#request({
25
+ ...content,
26
+ actions: [
27
+ { text: cancelText ?? "Cancel", value: false, variant: "plain" },
28
+ {
29
+ text: acceptText ?? "OK",
30
+ value: true,
31
+ variant: "filled",
32
+ default: true,
33
+ },
34
+ ],
35
+ });
36
+ return accepted === true;
37
+ }
38
+ async prompt({ input: { value, ...input } = {}, cancelText, acceptText, ...content }) {
39
+ const text = await this.#request({
40
+ ...content,
41
+ input,
42
+ value: value == null ? "" : String(value),
43
+ actions: [
44
+ { text: cancelText ?? "Cancel", value: undefined, variant: "plain" },
45
+ {
46
+ text: acceptText ?? "OK",
47
+ value: undefined,
48
+ variant: "filled",
49
+ submit: true,
50
+ },
51
+ ],
52
+ });
53
+ return typeof text === "string" ? text : undefined;
54
+ }
55
+ settle(value) {
56
+ this.#active?.resolve(value);
57
+ this.#next();
58
+ }
59
+ #request(request) {
60
+ return new Promise((resolve) => {
61
+ this.#queue.push({ ...request, resolve });
62
+ if (!this.#active)
63
+ this.#next();
64
+ });
65
+ }
66
+ #next() {
67
+ this.#active = this.#queue.shift();
68
+ if (this.#active)
69
+ this.current = this.#active;
70
+ this.open = this.#active !== undefined;
71
+ }
72
+ }
73
+ export const [getDialogs, setDialogs] = createContext();
@@ -1,4 +1,3 @@
1
- export { default as DialogButton, type DialogButtonProps, } from "./dialog-button.svelte";
2
1
  export { default as Dialog, type DialogProps } from "./dialog.svelte";
3
- export { DialoguerContext, getDialoguerContext, setDialoguerContext, type DialoguerButtonProps, } from "./dialoguer-context.svelte";
4
- export { default as Dialoguer } from "./dialoguer.svelte";
2
+ export { default as DialogProvider } from "./dialog-provider.svelte";
3
+ export { Dialogs, getDialogs, type AlertOptions, type ConfirmOptions, type DialogAction, type PromptOptions, type ShowOptions, } from "./dialogs.svelte";
@@ -1,4 +1,3 @@
1
- export { default as DialogButton, } from "./dialog-button.svelte";
2
1
  export { default as Dialog } from "./dialog.svelte";
3
- export { DialoguerContext, getDialoguerContext, setDialoguerContext, } from "./dialoguer-context.svelte";
4
- export { default as Dialoguer } from "./dialoguer.svelte";
2
+ export { default as DialogProvider } from "./dialog-provider.svelte";
3
+ export { Dialogs, getDialogs, } from "./dialogs.svelte";
@@ -0,0 +1,51 @@
1
+ <script module lang="ts">
2
+ import { Modal, type ModalProps } from "../modal/index.js";
3
+ import { cn } from "../utils.js";
4
+ import { prefersReducedMotion } from "svelte/motion";
5
+ import { fly } from "svelte/transition";
6
+
7
+ export type DrawerSide = "start" | "end";
8
+
9
+ export type DrawerProps = {
10
+ side?: DrawerSide;
11
+ } & Omit<ModalProps, "transition">;
12
+ </script>
13
+
14
+ <script lang="ts">
15
+ let {
16
+ el = $bindable(),
17
+ open = $bindable(),
18
+ side = "start",
19
+ shape = "lg",
20
+ class: className,
21
+ children,
22
+ ...restProps
23
+ }: DrawerProps = $props();
24
+
25
+ function slide(node: Element) {
26
+ const rtl = getComputedStyle(node).direction === "rtl";
27
+ const fromLeft = (side === "start") !== rtl;
28
+ return fly(node, {
29
+ x: fromLeft ? "-100%" : "100%",
30
+ opacity: 1,
31
+ duration: prefersReducedMotion.current ? 0 : 200,
32
+ });
33
+ }
34
+ </script>
35
+
36
+ <Modal
37
+ bind:el
38
+ bind:open
39
+ {shape}
40
+ transition={slide}
41
+ class={cn(
42
+ "my-0 h-full max-h-none w-80 max-w-[calc(100%-3.5rem)] overflow-y-auto bg-m3-surface-container-low p-3",
43
+ side === "start"
44
+ ? "ms-0 me-auto rounded-s-none"
45
+ : "ms-auto me-0 rounded-e-none",
46
+ className,
47
+ )}
48
+ {...restProps}
49
+ >
50
+ {@render children()}
51
+ </Modal>
@@ -0,0 +1,8 @@
1
+ import { type ModalProps } from "../modal/index.js";
2
+ export type DrawerSide = "start" | "end";
3
+ export type DrawerProps = {
4
+ side?: DrawerSide;
5
+ } & Omit<ModalProps, "transition">;
6
+ declare const Drawer: import("svelte").Component<DrawerProps, {}, "el" | "open">;
7
+ type Drawer = ReturnType<typeof Drawer>;
8
+ export default Drawer;
@@ -0,0 +1 @@
1
+ export { default as Drawer, type DrawerProps, type DrawerSide, } from "./drawer.svelte";
@@ -0,0 +1 @@
1
+ export { default as Drawer, } from "./drawer.svelte";