kosui 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +3 -0
  3. package/dist/alert/alert.svelte +28 -0
  4. package/dist/alert/alert.svelte.d.ts +5 -0
  5. package/dist/alert/index.d.ts +1 -0
  6. package/dist/alert/index.js +1 -0
  7. package/dist/autocomplete/autocomplete-content.svelte +47 -0
  8. package/dist/autocomplete/autocomplete-content.svelte.d.ts +10 -0
  9. package/dist/autocomplete/autocomplete-context.svelte.d.ts +12 -0
  10. package/dist/autocomplete/autocomplete-context.svelte.js +34 -0
  11. package/dist/autocomplete/autocomplete-input.svelte +43 -0
  12. package/dist/autocomplete/autocomplete-input.svelte.d.ts +7 -0
  13. package/dist/autocomplete/autocomplete-item.svelte +68 -0
  14. package/dist/autocomplete/autocomplete-item.svelte.d.ts +11 -0
  15. package/dist/autocomplete/autocomplete.svelte +20 -0
  16. package/dist/autocomplete/autocomplete.svelte.d.ts +8 -0
  17. package/dist/autocomplete/index.d.ts +4 -0
  18. package/dist/autocomplete/index.js +4 -0
  19. package/dist/avatar/avatar.svelte +47 -0
  20. package/dist/avatar/avatar.svelte.d.ts +8 -0
  21. package/dist/avatar/index.d.ts +1 -0
  22. package/dist/avatar/index.js +1 -0
  23. package/dist/badge/badge.svelte +43 -0
  24. package/dist/badge/badge.svelte.d.ts +9 -0
  25. package/dist/badge/index.d.ts +1 -0
  26. package/dist/badge/index.js +1 -0
  27. package/dist/base.d.ts +21 -0
  28. package/dist/base.js +70 -0
  29. package/dist/bindable.svelte.d.ts +7 -0
  30. package/dist/bindable.svelte.js +25 -0
  31. package/dist/box/box.svelte +42 -0
  32. package/dist/box/box.svelte.d.ts +12 -0
  33. package/dist/box/index.d.ts +1 -0
  34. package/dist/box/index.js +1 -0
  35. package/dist/breadcrumbs/breadcrumbs.svelte +39 -0
  36. package/dist/breadcrumbs/breadcrumbs.svelte.d.ts +13 -0
  37. package/dist/breadcrumbs/index.d.ts +1 -0
  38. package/dist/breadcrumbs/index.js +1 -0
  39. package/dist/button/button.svelte +70 -0
  40. package/dist/button/button.svelte.d.ts +13 -0
  41. package/dist/button/index.d.ts +1 -0
  42. package/dist/button/index.js +1 -0
  43. package/dist/chip/chip.svelte +57 -0
  44. package/dist/chip/chip.svelte.d.ts +11 -0
  45. package/dist/chip/index.d.ts +1 -0
  46. package/dist/chip/index.js +1 -0
  47. package/dist/command/action.svelte.d.ts +35 -0
  48. package/dist/command/action.svelte.js +76 -0
  49. package/dist/command/command-content.svelte +15 -0
  50. package/dist/command/command-content.svelte.d.ts +8 -0
  51. package/dist/command/command-context.svelte.d.ts +5 -0
  52. package/dist/command/command-context.svelte.js +13 -0
  53. package/dist/command/command-input.svelte +44 -0
  54. package/dist/command/command-input.svelte.d.ts +7 -0
  55. package/dist/command/command-item.svelte +66 -0
  56. package/dist/command/command-item.svelte.d.ts +11 -0
  57. package/dist/command/command-search.svelte +29 -0
  58. package/dist/command/command-search.svelte.d.ts +5 -0
  59. package/dist/command/command.svelte +19 -0
  60. package/dist/command/command.svelte.d.ts +8 -0
  61. package/dist/command/commander.svelte +107 -0
  62. package/dist/command/commander.svelte.d.ts +9 -0
  63. package/dist/command/index.d.ts +8 -0
  64. package/dist/command/index.js +8 -0
  65. package/dist/common/divider.svelte +13 -0
  66. package/dist/common/divider.svelte.d.ts +6 -0
  67. package/dist/common/header.svelte +35 -0
  68. package/dist/common/header.svelte.d.ts +10 -0
  69. package/dist/common/index.d.ts +3 -0
  70. package/dist/common/index.js +3 -0
  71. package/dist/common/item-context.svelte.d.ts +12 -0
  72. package/dist/common/item-context.svelte.js +77 -0
  73. package/dist/dialog/dialog-button.svelte +25 -0
  74. package/dist/dialog/dialog-button.svelte.d.ts +32 -0
  75. package/dist/dialog/dialog.svelte +69 -0
  76. package/dist/dialog/dialog.svelte.d.ts +37 -0
  77. package/dist/dialog/dialoguer-context.svelte.d.ts +53 -0
  78. package/dist/dialog/dialoguer-context.svelte.js +85 -0
  79. package/dist/dialog/dialoguer.svelte +65 -0
  80. package/dist/dialog/dialoguer.svelte.d.ts +7 -0
  81. package/dist/dialog/index.d.ts +4 -0
  82. package/dist/dialog/index.js +4 -0
  83. package/dist/event-manager.d.ts +15 -0
  84. package/dist/event-manager.js +47 -0
  85. package/dist/fab/fab.svelte +28 -0
  86. package/dist/fab/fab.svelte.d.ts +6 -0
  87. package/dist/fab/index.d.ts +1 -0
  88. package/dist/fab/index.js +1 -0
  89. package/dist/index.d.ts +39 -0
  90. package/dist/index.js +39 -0
  91. package/dist/input/index.d.ts +1 -0
  92. package/dist/input/index.js +1 -0
  93. package/dist/input/input.svelte +41 -0
  94. package/dist/input/input.svelte.d.ts +7 -0
  95. package/dist/link/index.d.ts +1 -0
  96. package/dist/link/index.js +1 -0
  97. package/dist/link/link.svelte +51 -0
  98. package/dist/link/link.svelte.d.ts +10 -0
  99. package/dist/markdown/index.d.ts +25 -0
  100. package/dist/markdown/index.js +25 -0
  101. package/dist/markdown/markdown-blockquote.svelte +14 -0
  102. package/dist/markdown/markdown-blockquote.svelte.d.ts +7 -0
  103. package/dist/markdown/markdown-br.svelte +12 -0
  104. package/dist/markdown/markdown-br.svelte.d.ts +7 -0
  105. package/dist/markdown/markdown-code.svelte +14 -0
  106. package/dist/markdown/markdown-code.svelte.d.ts +7 -0
  107. package/dist/markdown/markdown-codespan.svelte +15 -0
  108. package/dist/markdown/markdown-codespan.svelte.d.ts +7 -0
  109. package/dist/markdown/markdown-context.svelte.d.ts +26 -0
  110. package/dist/markdown/markdown-context.svelte.js +30 -0
  111. package/dist/markdown/markdown-def.svelte +15 -0
  112. package/dist/markdown/markdown-def.svelte.d.ts +7 -0
  113. package/dist/markdown/markdown-del.svelte +14 -0
  114. package/dist/markdown/markdown-del.svelte.d.ts +7 -0
  115. package/dist/markdown/markdown-em.svelte +14 -0
  116. package/dist/markdown/markdown-em.svelte.d.ts +7 -0
  117. package/dist/markdown/markdown-escape.svelte +8 -0
  118. package/dist/markdown/markdown-escape.svelte.d.ts +5 -0
  119. package/dist/markdown/markdown-heading.svelte +16 -0
  120. package/dist/markdown/markdown-heading.svelte.d.ts +7 -0
  121. package/dist/markdown/markdown-hr.svelte +12 -0
  122. package/dist/markdown/markdown-hr.svelte.d.ts +7 -0
  123. package/dist/markdown/markdown-html.svelte +9 -0
  124. package/dist/markdown/markdown-html.svelte.d.ts +5 -0
  125. package/dist/markdown/markdown-image.svelte +12 -0
  126. package/dist/markdown/markdown-image.svelte.d.ts +7 -0
  127. package/dist/markdown/markdown-link.svelte +15 -0
  128. package/dist/markdown/markdown-link.svelte.d.ts +7 -0
  129. package/dist/markdown/markdown-list-item.svelte +14 -0
  130. package/dist/markdown/markdown-list-item.svelte.d.ts +7 -0
  131. package/dist/markdown/markdown-list.svelte +19 -0
  132. package/dist/markdown/markdown-list.svelte.d.ts +7 -0
  133. package/dist/markdown/markdown-paragraph.svelte +16 -0
  134. package/dist/markdown/markdown-paragraph.svelte.d.ts +7 -0
  135. package/dist/markdown/markdown-space.svelte +8 -0
  136. package/dist/markdown/markdown-space.svelte.d.ts +5 -0
  137. package/dist/markdown/markdown-strong.svelte +15 -0
  138. package/dist/markdown/markdown-strong.svelte.d.ts +7 -0
  139. package/dist/markdown/markdown-table-cell.svelte +16 -0
  140. package/dist/markdown/markdown-table-cell.svelte.d.ts +7 -0
  141. package/dist/markdown/markdown-table.svelte +34 -0
  142. package/dist/markdown/markdown-table.svelte.d.ts +7 -0
  143. package/dist/markdown/markdown-text.svelte +8 -0
  144. package/dist/markdown/markdown-text.svelte.d.ts +5 -0
  145. package/dist/markdown/markdown-token.svelte +25 -0
  146. package/dist/markdown/markdown-token.svelte.d.ts +7 -0
  147. package/dist/markdown/markdown-tokens.svelte +13 -0
  148. package/dist/markdown/markdown-tokens.svelte.d.ts +7 -0
  149. package/dist/markdown/markdown.svelte +186 -0
  150. package/dist/markdown/markdown.svelte.d.ts +31 -0
  151. package/dist/menu/index.d.ts +7 -0
  152. package/dist/menu/index.js +7 -0
  153. package/dist/menu/menu-actions.svelte +51 -0
  154. package/dist/menu/menu-actions.svelte.d.ts +7 -0
  155. package/dist/menu/menu-content.svelte +47 -0
  156. package/dist/menu/menu-content.svelte.d.ts +10 -0
  157. package/dist/menu/menu-context.svelte.d.ts +18 -0
  158. package/dist/menu/menu-context.svelte.js +118 -0
  159. package/dist/menu/menu-item.svelte +85 -0
  160. package/dist/menu/menu-item.svelte.d.ts +11 -0
  161. package/dist/menu/menu-trigger-button.svelte +31 -0
  162. package/dist/menu/menu-trigger-button.svelte.d.ts +5 -0
  163. package/dist/menu/menu-trigger.svelte +42 -0
  164. package/dist/menu/menu-trigger.svelte.d.ts +10 -0
  165. package/dist/menu/menu.svelte +29 -0
  166. package/dist/menu/menu.svelte.d.ts +9 -0
  167. package/dist/merge-props.d.ts +13 -0
  168. package/dist/merge-props.js +84 -0
  169. package/dist/modal/index.d.ts +1 -0
  170. package/dist/modal/index.js +1 -0
  171. package/dist/modal/modal.svelte +123 -0
  172. package/dist/modal/modal.svelte.d.ts +11 -0
  173. package/dist/ordered-html-elements.d.ts +7 -0
  174. package/dist/ordered-html-elements.js +29 -0
  175. package/dist/popover/index.d.ts +1 -0
  176. package/dist/popover/index.js +1 -0
  177. package/dist/popover/popover.svelte +184 -0
  178. package/dist/popover/popover.svelte.d.ts +18 -0
  179. package/dist/portal/index.d.ts +1 -0
  180. package/dist/portal/index.js +1 -0
  181. package/dist/portal/portal.svelte +12 -0
  182. package/dist/portal/portal.svelte.d.ts +8 -0
  183. package/dist/portal/proxy.svelte +10 -0
  184. package/dist/portal/proxy.svelte.d.ts +7 -0
  185. package/dist/progress/circular-progress.svelte +86 -0
  186. package/dist/progress/circular-progress.svelte.d.ts +13 -0
  187. package/dist/progress/index.d.ts +1 -0
  188. package/dist/progress/index.js +1 -0
  189. package/dist/shortcut/index.d.ts +2 -0
  190. package/dist/shortcut/index.js +2 -0
  191. package/dist/shortcut/shortcut-badge.svelte +41 -0
  192. package/dist/shortcut/shortcut-badge.svelte.d.ts +11 -0
  193. package/dist/shortcut/shortcut.d.ts +29 -0
  194. package/dist/shortcut/shortcut.js +95 -0
  195. package/dist/toggle/index.d.ts +2 -0
  196. package/dist/toggle/index.js +2 -0
  197. package/dist/toggle/toggle-button.svelte +60 -0
  198. package/dist/toggle/toggle-button.svelte.d.ts +32 -0
  199. package/dist/toggle/toggle-context.svelte.d.ts +9 -0
  200. package/dist/toggle/toggle-context.svelte.js +32 -0
  201. package/dist/toggle/toggle-group.svelte +41 -0
  202. package/dist/toggle/toggle-group.svelte.d.ts +32 -0
  203. package/dist/tooltip/index.d.ts +1 -0
  204. package/dist/tooltip/index.js +1 -0
  205. package/dist/tooltip/tooltip.svelte +94 -0
  206. package/dist/tooltip/tooltip.svelte.d.ts +25 -0
  207. package/dist/utils.d.ts +43 -0
  208. package/dist/utils.js +72 -0
  209. package/package.json +76 -0
@@ -0,0 +1,107 @@
1
+ <script module lang="ts">
2
+ import { match } from "../utils";
3
+ import { Check, ChevronRight } from "@lucide/svelte";
4
+ import {
5
+ Action,
6
+ Command,
7
+ CommandContent,
8
+ CommandDivider,
9
+ CommandItem,
10
+ CommandSearch,
11
+ Registry,
12
+ } from ".";
13
+ import { events } from "..";
14
+ import { Modal } from "../modal";
15
+ import { Shortcut, ShortcutBadge } from "../shortcut";
16
+
17
+ export type CommanderProps = {
18
+ open?: boolean;
19
+ query?: string;
20
+ command: Registry;
21
+ };
22
+ </script>
23
+
24
+ <script lang="ts">
25
+ let {
26
+ open = $bindable(false),
27
+ query = $bindable(""),
28
+ command,
29
+ }: CommanderProps = $props();
30
+
31
+ let actions = $derived(
32
+ command.actions.filter(
33
+ (action) =>
34
+ action.enabled() &&
35
+ (match(action.id, query) ||
36
+ (action.category && match(action.category, query)) ||
37
+ match(action.name, query) ||
38
+ match(action.description, query)),
39
+ ),
40
+ );
41
+
42
+ let categoryHasSelected = $derived(
43
+ actions.reduce(
44
+ (acc, { category, selected }) => ({
45
+ ...acc,
46
+ [category]: acc[category] || selected !== undefined,
47
+ }),
48
+ {} as Record<string, boolean>,
49
+ ),
50
+ );
51
+
52
+ function handleSelect(action: Action) {
53
+ action.callback();
54
+ open = false;
55
+ }
56
+
57
+ function handleKeyDown(event: KeyboardEvent) {
58
+ const action = command.getByShortcut(Shortcut.fromEvent(event));
59
+ if (action && action.enabled()) {
60
+ action.callback();
61
+ event.preventDefault();
62
+ event.stopImmediatePropagation();
63
+ }
64
+ }
65
+
66
+ $effect(() => {
67
+ return events.on("keydown", handleKeyDown);
68
+ });
69
+ </script>
70
+
71
+ <Modal
72
+ bind:open
73
+ onoutroend={() => (query = "")}
74
+ class="h-[min(60%,48em)] w-[min(calc(100%-1em),36em)] rounded-lg bg-m3-surface-container p-0"
75
+ >
76
+ <Command>
77
+ <CommandSearch bind:value={query} />
78
+ <CommandDivider />
79
+ <CommandContent>
80
+ {#if actions.length > 0}
81
+ {#each actions as action (action.id)}
82
+ <CommandItem
83
+ onSelect={() => handleSelect(action)}
84
+ title={action.description}
85
+ >
86
+ <action.icon size={14} class="mr-2" />
87
+ <div>{action.category}</div>
88
+ <ChevronRight size={14} />
89
+ {#if categoryHasSelected[action.category]}
90
+ {#if action.selected?.()}
91
+ <Check size={16} class="text-m3-primary" />
92
+ {:else}
93
+ <div class="size-4"></div>
94
+ {/if}
95
+ {/if}
96
+ <div>{action.name}</div>
97
+ {#if action.shortcut}
98
+ <ShortcutBadge class="ml-auto" shortcut={action.shortcut} />
99
+ {/if}
100
+ </CommandItem>
101
+ {/each}
102
+ {:else}
103
+ <div class="text-center">No results found.</div>
104
+ {/if}
105
+ </CommandContent>
106
+ </Command>
107
+ </Modal>
@@ -0,0 +1,9 @@
1
+ import { Registry } from ".";
2
+ export type CommanderProps = {
3
+ open?: boolean;
4
+ query?: string;
5
+ command: Registry;
6
+ };
7
+ declare const Commander: import("svelte").Component<CommanderProps, {}, "open" | "query">;
8
+ type Commander = ReturnType<typeof Commander>;
9
+ export default Commander;
@@ -0,0 +1,8 @@
1
+ export { Divider as CommandDivider, Header as CommandHeader } from "../common";
2
+ export { Action, Registry } from "./action.svelte";
3
+ export { default as CommandContent } from "./command-content.svelte";
4
+ export { default as CommandInput } from "./command-input.svelte";
5
+ export { default as CommandItem } from "./command-item.svelte";
6
+ export { default as CommandSearch } from "./command-search.svelte";
7
+ export { default as Command } from "./command.svelte";
8
+ export { default as Commander } from "./commander.svelte";
@@ -0,0 +1,8 @@
1
+ export { Divider as CommandDivider, Header as CommandHeader } from "../common";
2
+ export { Action, Registry } from "./action.svelte";
3
+ export { default as CommandContent } from "./command-content.svelte";
4
+ export { default as CommandInput } from "./command-input.svelte";
5
+ export { default as CommandItem } from "./command-item.svelte";
6
+ export { default as CommandSearch } from "./command-search.svelte";
7
+ export { default as Command } from "./command.svelte";
8
+ export { default as Commander } from "./commander.svelte";
@@ -0,0 +1,13 @@
1
+ <script module lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { twMerge } from "tailwind-merge";
4
+ import type { ClassName } from "../utils";
5
+
6
+ export type DividerProps = {} & ClassName & HTMLAttributes<HTMLHRElement>;
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ let { class: className, ...restProps }: DividerProps = $props();
11
+ </script>
12
+
13
+ <hr class={twMerge("-mx-1 my-1", className)} {...restProps} />
@@ -0,0 +1,6 @@
1
+ import type { HTMLAttributes } from "svelte/elements";
2
+ import type { ClassName } from "../utils";
3
+ export type DividerProps = {} & ClassName & HTMLAttributes<HTMLHRElement>;
4
+ declare const Divider: import("svelte").Component<DividerProps, {}, "">;
5
+ type Divider = ReturnType<typeof Divider>;
6
+ export default Divider;
@@ -0,0 +1,35 @@
1
+ <script module lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+ import { twMerge } from "tailwind-merge";
5
+ import { baseClasses, type Variants } from "../base";
6
+ import type { ClassName } from "../utils";
7
+
8
+ export type HeaderProps = {
9
+ children: Snippet;
10
+ } & ClassName &
11
+ Variants &
12
+ HTMLAttributes<HTMLDivElement>;
13
+ </script>
14
+
15
+ <script lang="ts">
16
+ let {
17
+ children,
18
+ class: className,
19
+ variant = "plain",
20
+ color = "primary",
21
+ shape = "rounded",
22
+ ...restProps
23
+ }: HeaderProps = $props();
24
+ </script>
25
+
26
+ <div
27
+ class={twMerge(
28
+ baseClasses({ variant, color, shape }),
29
+ "px-2 py-1 text-xs uppercase",
30
+ className,
31
+ )}
32
+ {...restProps}
33
+ >
34
+ {@render children()}
35
+ </div>
@@ -0,0 +1,10 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { type Variants } from "../base";
4
+ import type { ClassName } from "../utils";
5
+ export type HeaderProps = {
6
+ children: Snippet;
7
+ } & ClassName & Variants & HTMLAttributes<HTMLDivElement>;
8
+ declare const Header: import("svelte").Component<HeaderProps, {}, "">;
9
+ type Header = ReturnType<typeof Header>;
10
+ export default Header;
@@ -0,0 +1,3 @@
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";
@@ -0,0 +1,3 @@
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,12 @@
1
+ export declare class ItemContext {
2
+ #private;
3
+ get input(): string;
4
+ set input(value: string);
5
+ bindInput(getInput: () => string, setInput: (val: string) => void): void;
6
+ get items(): HTMLElement[];
7
+ add(item: HTMLElement): () => void;
8
+ delete(item: HTMLElement): void;
9
+ get focused(): HTMLElement | undefined;
10
+ set focused(value: HTMLElement | undefined);
11
+ handleKeyDown(event: KeyboardEvent): void;
12
+ }
@@ -0,0 +1,77 @@
1
+ import { Bindable } from "../bindable.svelte";
2
+ import { OrderedHTMLElements } from "../ordered-html-elements";
3
+ import { Shortcut } from "../shortcut";
4
+ export class ItemContext {
5
+ #input = new Bindable("");
6
+ #items = new OrderedHTMLElements();
7
+ #focused = $state();
8
+ get input() {
9
+ return this.#input.value;
10
+ }
11
+ set input(value) {
12
+ this.#input.value = value;
13
+ }
14
+ bindInput(getInput, setInput) {
15
+ this.#input.bind(getInput, setInput);
16
+ }
17
+ get items() {
18
+ return this.#items.items;
19
+ }
20
+ add(item) {
21
+ this.#items.add(item);
22
+ this.focused = this.#input.value === "" ? undefined : this.items[0];
23
+ return () => this.delete(item);
24
+ }
25
+ delete(item) {
26
+ this.#items.delete(item);
27
+ this.focused = this.#input.value === "" ? undefined : this.items[0];
28
+ }
29
+ get focused() {
30
+ return this.#focused;
31
+ }
32
+ set focused(value) {
33
+ this.#focused = value;
34
+ }
35
+ handleKeyDown(event) {
36
+ if (!this.items)
37
+ return;
38
+ if (Shortcut.ARROW_UP.matches(event)) {
39
+ if (this.items.length !== 0) {
40
+ if (!this.focused) {
41
+ this.focused = this.items[this.items.length - 1];
42
+ this.focused.scrollIntoView(false);
43
+ }
44
+ else {
45
+ const index = this.items.indexOf(this.focused);
46
+ this.focused =
47
+ this.items[(index - 1 + this.items.length) % this.items.length];
48
+ this.focused.scrollIntoView(false);
49
+ }
50
+ }
51
+ event.preventDefault();
52
+ event.stopImmediatePropagation();
53
+ }
54
+ else if (Shortcut.ARROW_DOWN.matches(event)) {
55
+ if (this.items.length !== 0) {
56
+ if (!this.focused) {
57
+ this.focused = this.items[0];
58
+ this.focused.scrollIntoView(false);
59
+ }
60
+ else {
61
+ const index = this.items.indexOf(this.focused);
62
+ this.focused = this.items[(index + 1) % this.items.length];
63
+ this.focused.scrollIntoView(false);
64
+ }
65
+ }
66
+ event.preventDefault();
67
+ event.stopImmediatePropagation();
68
+ }
69
+ else if (Shortcut.ENTER.matches(event)) {
70
+ if (this.focused) {
71
+ this.focused.click();
72
+ event.preventDefault();
73
+ event.stopImmediatePropagation();
74
+ }
75
+ }
76
+ }
77
+ }
@@ -0,0 +1,25 @@
1
+ <script module lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import { Button, type ButtonProps } from "../button";
4
+
5
+ export type DialogButtonProps<T> = {
6
+ value: T | undefined;
7
+ autofocus?: boolean;
8
+ onSelect: (value: T | undefined) => void;
9
+ children: Snippet;
10
+ } & Omit<ButtonProps, "value">;
11
+ </script>
12
+
13
+ <script lang="ts" generics="T">
14
+ let {
15
+ value,
16
+ onSelect,
17
+ autofocus = false,
18
+ children,
19
+ ...restProps
20
+ }: DialogButtonProps<T> = $props();
21
+ </script>
22
+
23
+ <Button onclick={() => onSelect(value)} {autofocus} {...restProps}>
24
+ {@render children()}
25
+ </Button>
@@ -0,0 +1,32 @@
1
+ import type { Snippet } from "svelte";
2
+ import { type ButtonProps } from "../button";
3
+ export type DialogButtonProps<T> = {
4
+ value: T | undefined;
5
+ autofocus?: boolean;
6
+ onSelect: (value: T | undefined) => void;
7
+ children: Snippet;
8
+ } & Omit<ButtonProps, "value">;
9
+ declare function $$render<T>(): {
10
+ props: DialogButtonProps<T>;
11
+ exports: {};
12
+ bindings: "";
13
+ slots: {};
14
+ events: {};
15
+ };
16
+ declare class __sveltets_Render<T> {
17
+ props(): ReturnType<typeof $$render<T>>['props'];
18
+ events(): ReturnType<typeof $$render<T>>['events'];
19
+ slots(): ReturnType<typeof $$render<T>>['slots'];
20
+ bindings(): "";
21
+ exports(): {};
22
+ }
23
+ interface $$IsomorphicComponent {
24
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
25
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
26
+ } & ReturnType<__sveltets_Render<T>['exports']>;
27
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
28
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
29
+ }
30
+ declare const DialogButton: $$IsomorphicComponent;
31
+ type DialogButton<T> = InstanceType<typeof DialogButton<T>>;
32
+ export default DialogButton;
@@ -0,0 +1,69 @@
1
+ <script module lang="ts">
2
+ import type { Icon } from "@lucide/svelte";
3
+ import type { Snippet } from "svelte";
4
+ import { twMerge } from "tailwind-merge";
5
+ import { mergeComponentProps } from "../merge-props";
6
+ import { Modal, type ModalProps } from "../modal";
7
+
8
+ export type DialogProps<T> = {
9
+ ref?: HTMLDialogElement;
10
+ onSelect?: (value: T | undefined) => void;
11
+ icon?: typeof Icon;
12
+ title?: string;
13
+ children: Snippet;
14
+ actions?: Snippet<[{ onSelect: (value: T | undefined) => void }]>;
15
+ } & ModalProps;
16
+ </script>
17
+
18
+ <script lang="ts" generics="T">
19
+ let {
20
+ ref = $bindable(),
21
+ open = $bindable(),
22
+ onSelect,
23
+ class: className,
24
+ icon: IconComponent,
25
+ title,
26
+ children,
27
+ actions,
28
+ ...restProps
29
+ }: DialogProps<T> = $props();
30
+
31
+ function handleSelect(value: T | undefined) {
32
+ onSelect?.(value);
33
+ open = false;
34
+ }
35
+
36
+ function handleCancel() {
37
+ onSelect?.(undefined);
38
+ }
39
+ </script>
40
+
41
+ <Modal
42
+ bind:ref
43
+ bind:open
44
+ class={twMerge("w-[min(calc(100%-1em),36em)]", className)}
45
+ {...mergeComponentProps(
46
+ Modal,
47
+ { role: "dialog", "aria-modal": "true", onCancel: handleCancel },
48
+ restProps,
49
+ )}
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}
68
+ </div>
69
+ </Modal>
@@ -0,0 +1,37 @@
1
+ import type { Icon } from "@lucide/svelte";
2
+ import type { Snippet } from "svelte";
3
+ import { type ModalProps } from "../modal";
4
+ export type DialogProps<T> = {
5
+ ref?: HTMLDialogElement;
6
+ onSelect?: (value: T | undefined) => void;
7
+ icon?: typeof Icon;
8
+ title?: string;
9
+ children: Snippet;
10
+ actions?: Snippet<[{
11
+ onSelect: (value: T | undefined) => void;
12
+ }]>;
13
+ } & ModalProps;
14
+ declare function $$render<T>(): {
15
+ props: DialogProps<T>;
16
+ exports: {};
17
+ bindings: "open" | "ref";
18
+ slots: {};
19
+ events: {};
20
+ };
21
+ declare class __sveltets_Render<T> {
22
+ props(): ReturnType<typeof $$render<T>>['props'];
23
+ events(): ReturnType<typeof $$render<T>>['events'];
24
+ slots(): ReturnType<typeof $$render<T>>['slots'];
25
+ bindings(): "open" | "ref";
26
+ exports(): {};
27
+ }
28
+ interface $$IsomorphicComponent {
29
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
30
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
31
+ } & ReturnType<__sveltets_Render<T>['exports']>;
32
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
33
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
34
+ }
35
+ declare const Dialog: $$IsomorphicComponent;
36
+ type Dialog<T> = InstanceType<typeof Dialog<T>>;
37
+ export default Dialog;
@@ -0,0 +1,53 @@
1
+ import type { Icon } from "@lucide/svelte";
2
+ import { type Snippet } from "svelte";
3
+ import type { Variants } from "../base";
4
+ import type { InputProps } from "../input";
5
+ export type ButtonProps<T> = {
6
+ text: string;
7
+ value: T;
8
+ default?: boolean;
9
+ } & Variants;
10
+ type ShowDialogProps<T> = {
11
+ icon?: typeof Icon;
12
+ title?: string;
13
+ inputProps?: InputProps;
14
+ message: Snippet<[]> | string;
15
+ buttons: ButtonProps<T>[];
16
+ };
17
+ type NoticeDialogProps = {
18
+ icon?: typeof Icon;
19
+ title?: string;
20
+ message: Snippet<[]> | string;
21
+ acceptText?: string;
22
+ };
23
+ type ConfirmDialogProps = {
24
+ icon?: typeof Icon;
25
+ title?: string;
26
+ message: Snippet<[]> | string;
27
+ cancelText?: string;
28
+ acceptText?: string;
29
+ };
30
+ type InputDialogProps = {
31
+ icon?: typeof Icon;
32
+ title?: string;
33
+ props: InputProps;
34
+ message: Snippet<[]> | string;
35
+ cancelText?: string;
36
+ acceptText?: string;
37
+ };
38
+ export declare class DialoguerContext {
39
+ message: Snippet<[]> | string;
40
+ icon: typeof Icon | undefined;
41
+ title: string | undefined;
42
+ inputProps: InputProps | undefined;
43
+ buttons: ButtonProps<unknown>[];
44
+ resolve: (value: unknown) => void;
45
+ open: boolean;
46
+ show<T>(dialog: ShowDialogProps<T>): Promise<T>;
47
+ notice(dialog: NoticeDialogProps): Promise<void>;
48
+ confirm(dialog: ConfirmDialogProps): Promise<boolean>;
49
+ input(dialog: InputDialogProps): Promise<string | undefined>;
50
+ }
51
+ export declare function setDialoguerContext(state: DialoguerContext): DialoguerContext;
52
+ export declare function getDialoguerContext(): DialoguerContext;
53
+ export {};
@@ -0,0 +1,85 @@
1
+ import { getContext, setContext } from "svelte";
2
+ export class DialoguerContext {
3
+ message = $state("");
4
+ icon = $state();
5
+ title = $state();
6
+ inputProps = $state();
7
+ buttons = $state.raw([]);
8
+ resolve = $state(() => { });
9
+ open = $state(false);
10
+ show(dialog) {
11
+ ({
12
+ icon: this.icon,
13
+ title: this.title,
14
+ inputProps: this.inputProps,
15
+ message: this.message,
16
+ buttons: this.buttons,
17
+ } = dialog);
18
+ this.open = true;
19
+ return new Promise((newResolve) => (this.resolve = newResolve));
20
+ }
21
+ async notice(dialog) {
22
+ await this.show({
23
+ icon: dialog.icon,
24
+ title: dialog.title,
25
+ inputProps: undefined,
26
+ message: dialog.message,
27
+ buttons: [
28
+ {
29
+ text: dialog.acceptText ?? "OK",
30
+ value: null,
31
+ default: true,
32
+ },
33
+ ],
34
+ });
35
+ }
36
+ async confirm(dialog) {
37
+ return await this.show({
38
+ icon: dialog.icon,
39
+ title: dialog.title,
40
+ inputProps: undefined,
41
+ message: dialog.message,
42
+ buttons: [
43
+ {
44
+ text: dialog.cancelText ?? "Cancel",
45
+ value: false,
46
+ default: false,
47
+ },
48
+ {
49
+ text: dialog.acceptText ?? "Accept",
50
+ value: true,
51
+ variant: "filled",
52
+ default: true,
53
+ },
54
+ ],
55
+ });
56
+ }
57
+ async input(dialog) {
58
+ return await this.show({
59
+ icon: dialog.icon,
60
+ title: dialog.title,
61
+ inputProps: dialog.props,
62
+ message: dialog.message,
63
+ buttons: [
64
+ {
65
+ text: dialog.cancelText ?? "Cancel",
66
+ value: "cancel",
67
+ },
68
+ {
69
+ text: dialog.acceptText ?? "Accept",
70
+ value: "accept",
71
+ variant: "filled",
72
+ },
73
+ ],
74
+ });
75
+ }
76
+ }
77
+ export function setDialoguerContext(state) {
78
+ return setContext(DialoguerContext, state);
79
+ }
80
+ export function getDialoguerContext() {
81
+ const ctx = getContext(DialoguerContext);
82
+ if (!ctx)
83
+ throw new Error("DialoguerContext is undefined");
84
+ return ctx;
85
+ }
@@ -0,0 +1,65 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import { Input } from "../input";
4
+ import DialogButton from "./dialog-button.svelte";
5
+ import Dialog from "./dialog.svelte";
6
+ import {
7
+ DialoguerContext,
8
+ setDialoguerContext,
9
+ type ButtonProps,
10
+ } from "./dialoguer-context.svelte";
11
+
12
+ const dialog = setDialoguerContext(new DialoguerContext());
13
+
14
+ type Props = {
15
+ children: Snippet;
16
+ };
17
+ let { children }: Props = $props();
18
+
19
+ let value: string = $derived(dialog.inputProps?.value ?? "");
20
+
21
+ function getValue(button: ButtonProps<unknown>) {
22
+ if (dialog.inputProps === undefined) {
23
+ return button.value;
24
+ }
25
+ if (button.value === "cancel") {
26
+ return undefined;
27
+ }
28
+ if (button.value === "accept") {
29
+ return value;
30
+ }
31
+ throw new Error("Invalid state");
32
+ }
33
+ </script>
34
+
35
+ <Dialog
36
+ bind:open={dialog.open}
37
+ icon={dialog.icon}
38
+ title={dialog.title}
39
+ onSelect={dialog.resolve}
40
+ >
41
+ {#if typeof dialog.message === "function"}
42
+ {@render dialog.message()}
43
+ {:else}
44
+ {dialog.message}
45
+ {/if}
46
+
47
+ {#if dialog.inputProps !== undefined}
48
+ <Input class="mt-2 w-full" bind:value autofocus {...dialog.inputProps} />
49
+ {/if}
50
+
51
+ {#snippet actions(props)}
52
+ {#each dialog.buttons as button (button)}
53
+ <DialogButton
54
+ variant={button.variant}
55
+ value={getValue(button)}
56
+ autofocus={button.default}
57
+ {...props}
58
+ >
59
+ {button.text}
60
+ </DialogButton>
61
+ {/each}
62
+ {/snippet}
63
+ </Dialog>
64
+
65
+ {@render children()}