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.
Files changed (238) 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/fab/fab.svelte +30 -10
  46. package/dist/fab/fab.svelte.d.ts +3 -2
  47. package/dist/index.d.ts +0 -1
  48. package/dist/index.js +0 -1
  49. package/dist/input/field.d.ts +8 -0
  50. package/dist/input/field.js +7 -0
  51. package/dist/input/index.d.ts +2 -1
  52. package/dist/input/index.js +2 -1
  53. package/dist/input/input.svelte +21 -66
  54. package/dist/input/input.svelte.d.ts +6 -16
  55. package/dist/link/link.svelte +33 -42
  56. package/dist/link/link.svelte.d.ts +4 -3
  57. package/dist/markdown/index.d.ts +2 -25
  58. package/dist/markdown/index.js +0 -24
  59. package/dist/markdown/markdown-tokens.svelte +166 -6
  60. package/dist/markdown/markdown-tokens.svelte.d.ts +2 -0
  61. package/dist/markdown/markdown.svelte +62 -173
  62. package/dist/markdown/markdown.svelte.d.ts +7 -27
  63. package/dist/markdown/parse.d.ts +5 -0
  64. package/dist/markdown/parse.js +30 -0
  65. package/dist/markdown/types.d.ts +28 -0
  66. package/dist/markdown/types.js +1 -0
  67. package/dist/menu/index.d.ts +3 -6
  68. package/dist/menu/index.js +3 -6
  69. package/dist/menu/menu-actions.svelte +44 -38
  70. package/dist/menu/menu-context.d.ts +4 -0
  71. package/dist/menu/menu-context.js +2 -0
  72. package/dist/menu/menu-group.svelte +40 -0
  73. package/dist/menu/menu-group.svelte.d.ts +11 -0
  74. package/dist/menu/menu-item.svelte +31 -54
  75. package/dist/menu/menu-item.svelte.d.ts +7 -5
  76. package/dist/menu/menu.svelte +160 -15
  77. package/dist/menu/menu.svelte.d.ts +15 -4
  78. package/dist/merge-props.d.ts +1 -1
  79. package/dist/merge-props.js +10 -5
  80. package/dist/modal/modal.svelte +60 -83
  81. package/dist/modal/modal.svelte.d.ts +5 -4
  82. package/dist/popover/index.d.ts +1 -1
  83. package/dist/popover/index.js +1 -1
  84. package/dist/popover/popover.svelte +58 -111
  85. package/dist/popover/popover.svelte.d.ts +6 -8
  86. package/dist/progress/circular-progress.svelte +64 -30
  87. package/dist/progress/circular-progress.svelte.d.ts +7 -8
  88. package/dist/shortcut/index.d.ts +2 -2
  89. package/dist/shortcut/index.js +1 -1
  90. package/dist/shortcut/shortcut-hint.svelte +36 -0
  91. package/dist/shortcut/shortcut-hint.svelte.d.ts +9 -0
  92. package/dist/shortcut/shortcut.d.ts +19 -14
  93. package/dist/shortcut/shortcut.js +105 -52
  94. package/dist/skeleton/skeleton.svelte +13 -8
  95. package/dist/skeleton/skeleton.svelte.d.ts +2 -5
  96. package/dist/slider/index.d.ts +1 -8
  97. package/dist/slider/index.js +1 -8
  98. package/dist/slider/slider.svelte +180 -211
  99. package/dist/slider/slider.svelte.d.ts +11 -32
  100. package/dist/switch/index.d.ts +1 -2
  101. package/dist/switch/index.js +1 -2
  102. package/dist/switch/switch.svelte +36 -60
  103. package/dist/switch/switch.svelte.d.ts +6 -17
  104. package/dist/textarea/index.d.ts +1 -1
  105. package/dist/textarea/index.js +1 -1
  106. package/dist/textarea/textarea.svelte +23 -63
  107. package/dist/textarea/textarea.svelte.d.ts +8 -18
  108. package/dist/theme.css +191 -0
  109. package/dist/toggle/index.d.ts +0 -1
  110. package/dist/toggle/index.js +0 -1
  111. package/dist/toggle/toggle-button.svelte +72 -38
  112. package/dist/toggle/toggle-button.svelte.d.ts +4 -4
  113. package/dist/toggle/toggle-context.d.ts +10 -0
  114. package/dist/toggle/toggle-context.js +2 -0
  115. package/dist/toggle/toggle-group.svelte +41 -22
  116. package/dist/toggle/toggle-group.svelte.d.ts +7 -4
  117. package/dist/tooltip/tooltip.svelte +67 -26
  118. package/dist/tooltip/tooltip.svelte.d.ts +10 -4
  119. package/dist/utils.d.ts +9 -3
  120. package/dist/utils.js +10 -0
  121. package/package.json +6 -5
  122. package/dist/autocomplete/autocomplete-content.svelte +0 -47
  123. package/dist/autocomplete/autocomplete-content.svelte.d.ts +0 -10
  124. package/dist/autocomplete/autocomplete-context.svelte.d.ts +0 -12
  125. package/dist/autocomplete/autocomplete-context.svelte.js +0 -34
  126. package/dist/autocomplete/autocomplete-input.svelte +0 -36
  127. package/dist/autocomplete/autocomplete-input.svelte.d.ts +0 -5
  128. package/dist/autocomplete/autocomplete-item.svelte +0 -68
  129. package/dist/autocomplete/autocomplete-item.svelte.d.ts +0 -11
  130. package/dist/base.css +0 -71
  131. package/dist/bindable.svelte.d.ts +0 -7
  132. package/dist/bindable.svelte.js +0 -25
  133. package/dist/command/command-content.svelte +0 -15
  134. package/dist/command/command-content.svelte.d.ts +0 -8
  135. package/dist/command/command-context.svelte.d.ts +0 -5
  136. package/dist/command/command-context.svelte.js +0 -13
  137. package/dist/command/command-input.svelte +0 -44
  138. package/dist/command/command-input.svelte.d.ts +0 -7
  139. package/dist/command/command-item.svelte +0 -66
  140. package/dist/command/command-item.svelte.d.ts +0 -11
  141. package/dist/command/command-search.svelte +0 -28
  142. package/dist/command/command-search.svelte.d.ts +0 -5
  143. package/dist/command/command.svelte +0 -19
  144. package/dist/command/command.svelte.d.ts +0 -8
  145. package/dist/command/commander.svelte +0 -107
  146. package/dist/command/commander.svelte.d.ts +0 -9
  147. package/dist/common/header.svelte +0 -35
  148. package/dist/common/header.svelte.d.ts +0 -10
  149. package/dist/common/item-context.svelte.d.ts +0 -12
  150. package/dist/common/item-context.svelte.js +0 -77
  151. package/dist/dialog/dialog-button.svelte +0 -25
  152. package/dist/dialog/dialog-button.svelte.d.ts +0 -32
  153. package/dist/dialog/dialoguer-context.svelte.d.ts +0 -53
  154. package/dist/dialog/dialoguer-context.svelte.js +0 -85
  155. package/dist/dialog/dialoguer.svelte +0 -65
  156. package/dist/dialog/dialoguer.svelte.d.ts +0 -7
  157. package/dist/markdown/markdown-blockquote.svelte +0 -14
  158. package/dist/markdown/markdown-blockquote.svelte.d.ts +0 -7
  159. package/dist/markdown/markdown-br.svelte +0 -12
  160. package/dist/markdown/markdown-br.svelte.d.ts +0 -7
  161. package/dist/markdown/markdown-code.svelte +0 -14
  162. package/dist/markdown/markdown-code.svelte.d.ts +0 -7
  163. package/dist/markdown/markdown-codespan.svelte +0 -15
  164. package/dist/markdown/markdown-codespan.svelte.d.ts +0 -7
  165. package/dist/markdown/markdown-context.svelte.d.ts +0 -26
  166. package/dist/markdown/markdown-context.svelte.js +0 -31
  167. package/dist/markdown/markdown-def.svelte +0 -15
  168. package/dist/markdown/markdown-def.svelte.d.ts +0 -7
  169. package/dist/markdown/markdown-del.svelte +0 -14
  170. package/dist/markdown/markdown-del.svelte.d.ts +0 -7
  171. package/dist/markdown/markdown-em.svelte +0 -14
  172. package/dist/markdown/markdown-em.svelte.d.ts +0 -7
  173. package/dist/markdown/markdown-escape.svelte +0 -8
  174. package/dist/markdown/markdown-escape.svelte.d.ts +0 -5
  175. package/dist/markdown/markdown-heading.svelte +0 -16
  176. package/dist/markdown/markdown-heading.svelte.d.ts +0 -7
  177. package/dist/markdown/markdown-hr.svelte +0 -12
  178. package/dist/markdown/markdown-hr.svelte.d.ts +0 -7
  179. package/dist/markdown/markdown-html.svelte +0 -9
  180. package/dist/markdown/markdown-html.svelte.d.ts +0 -5
  181. package/dist/markdown/markdown-image.svelte +0 -12
  182. package/dist/markdown/markdown-image.svelte.d.ts +0 -7
  183. package/dist/markdown/markdown-link.svelte +0 -17
  184. package/dist/markdown/markdown-link.svelte.d.ts +0 -7
  185. package/dist/markdown/markdown-list-item.svelte +0 -14
  186. package/dist/markdown/markdown-list-item.svelte.d.ts +0 -7
  187. package/dist/markdown/markdown-list.svelte +0 -19
  188. package/dist/markdown/markdown-list.svelte.d.ts +0 -7
  189. package/dist/markdown/markdown-paragraph.svelte +0 -16
  190. package/dist/markdown/markdown-paragraph.svelte.d.ts +0 -7
  191. package/dist/markdown/markdown-space.svelte +0 -8
  192. package/dist/markdown/markdown-space.svelte.d.ts +0 -5
  193. package/dist/markdown/markdown-strong.svelte +0 -15
  194. package/dist/markdown/markdown-strong.svelte.d.ts +0 -7
  195. package/dist/markdown/markdown-table-cell.svelte +0 -16
  196. package/dist/markdown/markdown-table-cell.svelte.d.ts +0 -7
  197. package/dist/markdown/markdown-table.svelte +0 -36
  198. package/dist/markdown/markdown-table.svelte.d.ts +0 -7
  199. package/dist/markdown/markdown-text.svelte +0 -8
  200. package/dist/markdown/markdown-text.svelte.d.ts +0 -5
  201. package/dist/markdown/markdown-token.svelte +0 -25
  202. package/dist/markdown/markdown-token.svelte.d.ts +0 -7
  203. package/dist/menu/menu-content.svelte +0 -47
  204. package/dist/menu/menu-content.svelte.d.ts +0 -10
  205. package/dist/menu/menu-context.svelte.d.ts +0 -18
  206. package/dist/menu/menu-context.svelte.js +0 -118
  207. package/dist/menu/menu-trigger-button.svelte +0 -31
  208. package/dist/menu/menu-trigger-button.svelte.d.ts +0 -5
  209. package/dist/menu/menu-trigger.svelte +0 -42
  210. package/dist/menu/menu-trigger.svelte.d.ts +0 -10
  211. package/dist/ordered-html-elements.d.ts +0 -7
  212. package/dist/ordered-html-elements.js +0 -29
  213. package/dist/portal/index.d.ts +0 -2
  214. package/dist/portal/index.js +0 -2
  215. package/dist/portal/portal.svelte +0 -15
  216. package/dist/portal/portal.svelte.d.ts +0 -8
  217. package/dist/portal/proxy.svelte +0 -13
  218. package/dist/portal/proxy.svelte.d.ts +0 -7
  219. package/dist/shortcut/shortcut-badge.svelte +0 -41
  220. package/dist/shortcut/shortcut-badge.svelte.d.ts +0 -11
  221. package/dist/slider/slider-context.svelte.d.ts +0 -50
  222. package/dist/slider/slider-context.svelte.js +0 -216
  223. package/dist/slider/slider-handle-label-arrow.svelte +0 -18
  224. package/dist/slider/slider-handle-label-arrow.svelte.d.ts +0 -6
  225. package/dist/slider/slider-handle-label.svelte +0 -35
  226. package/dist/slider/slider-handle-label.svelte.d.ts +0 -6
  227. package/dist/slider/slider-handle.svelte +0 -54
  228. package/dist/slider/slider-handle.svelte.d.ts +0 -6
  229. package/dist/slider/slider-mark-dot.svelte +0 -25
  230. package/dist/slider/slider-mark-dot.svelte.d.ts +0 -6
  231. package/dist/slider/slider-mark-label.svelte +0 -37
  232. package/dist/slider/slider-mark-label.svelte.d.ts +0 -9
  233. package/dist/slider/slider-mark.svelte +0 -33
  234. package/dist/slider/slider-mark.svelte.d.ts +0 -9
  235. package/dist/switch/switch-thumb.svelte +0 -52
  236. package/dist/switch/switch-thumb.svelte.d.ts +0 -7
  237. package/dist/toggle/toggle-context.svelte.d.ts +0 -9
  238. package/dist/toggle/toggle-context.svelte.js +0 -32
@@ -1,186 +1,75 @@
1
1
  <script module lang="ts">
2
- import {
3
- MarkdownBlockquote,
4
- MarkdownBr,
5
- MarkdownCode,
6
- MarkdownCodespan,
7
- MarkdownContext,
8
- MarkdownDef,
9
- MarkdownDel,
10
- MarkdownEm,
11
- MarkdownEscape,
12
- MarkdownHeading,
13
- MarkdownHr,
14
- MarkdownHtml,
15
- MarkdownImage,
16
- MarkdownLink,
17
- MarkdownList,
18
- MarkdownListItem,
19
- MarkdownParagraph,
20
- MarkdownSpace,
21
- MarkdownStrong,
22
- MarkdownTable,
23
- MarkdownTableCell,
24
- MarkdownText,
25
- MarkdownTokens,
26
- setMarkdownContext,
27
- type MarkdownComponentProps,
28
- } from "./index.js";
29
- import {
30
- Lexer,
31
- type MarkedOptions,
32
- type MarkedToken,
33
- type Tokens,
34
- } from "marked";
35
- import type { Snippet } from "svelte";
2
+ import { cn, type ClassName, type ElementRef } from "../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+ import MarkdownTokens from "./markdown-tokens.svelte";
5
+ import { parse } from "./parse.js";
6
+ import type { MarkdownRenderers } from "./types.js";
36
7
 
37
8
  export type MarkdownProps = {
38
9
  value: string;
39
- options?: MarkedOptions;
40
- blockquote?: Snippet<[MarkdownComponentProps<Tokens.Blockquote>]>;
41
- br?: Snippet<[MarkdownComponentProps<Tokens.Br>]>;
42
- code?: Snippet<[MarkdownComponentProps<Tokens.Code>]>;
43
- codespan?: Snippet<[MarkdownComponentProps<Tokens.Codespan>]>;
44
- def?: Snippet<[MarkdownComponentProps<Tokens.Def>]>;
45
- del?: Snippet<[MarkdownComponentProps<Tokens.Del>]>;
46
- em?: Snippet<[MarkdownComponentProps<Tokens.Em>]>;
47
- escape?: Snippet<[MarkdownComponentProps<Tokens.Escape>]>;
48
- heading?: Snippet<[MarkdownComponentProps<Tokens.Heading>]>;
49
- hr?: Snippet<[MarkdownComponentProps<Tokens.Hr>]>;
50
- html?: Snippet<[MarkdownComponentProps<Tokens.HTML | Tokens.Tag>]>;
51
- image?: Snippet<[MarkdownComponentProps<Tokens.Image>]>;
52
- link?: Snippet<[MarkdownComponentProps<Tokens.Link>]>;
53
- listItem?: Snippet<[MarkdownComponentProps<Tokens.ListItem>]>;
54
- list?: Snippet<[MarkdownComponentProps<Tokens.List>]>;
55
- paragraph?: Snippet<[MarkdownComponentProps<Tokens.Paragraph>]>;
56
- space?: Snippet<[MarkdownComponentProps<Tokens.Space>]>;
57
- strong?: Snippet<[MarkdownComponentProps<Tokens.Strong>]>;
58
- tableCell?: Snippet<[MarkdownComponentProps<Tokens.TableCell>]>;
59
- table?: Snippet<[MarkdownComponentProps<Tokens.Table>]>;
60
- text?: Snippet<[MarkdownComponentProps<Tokens.Text>]>;
61
- };
10
+ gfm?: boolean;
11
+ breaks?: boolean;
12
+ } & MarkdownRenderers &
13
+ ElementRef &
14
+ ClassName &
15
+ Omit<HTMLAttributes<HTMLDivElement>, "children">;
62
16
  </script>
63
17
 
64
18
  <script lang="ts">
65
19
  let {
66
20
  value,
67
- options = {},
68
- blockquote = defaultBlockquote,
69
- br = defaultBr,
70
- code = defaultCode,
71
- codespan = defaultCodespan,
72
- def = defaultDef,
73
- del = defaultDel,
74
- em = defaultEm,
75
- escape = defaultEscape,
76
- heading = defaultHeading,
77
- hr = defaultHr,
78
- html = defaultHtml,
79
- image = defaultImage,
80
- link = defaultLink,
81
- listItem = defaultListItem,
82
- list = defaultList,
83
- paragraph = defaultParagraph,
84
- space = defaultSpace,
85
- strong = defaultStrong,
86
- tableCell = defaultTableCell,
87
- table = defaultTable,
88
- text = defaultText,
21
+ gfm = true,
22
+ breaks = false,
23
+ el = $bindable(),
24
+ class: className,
25
+ blockquote,
26
+ br,
27
+ code,
28
+ codespan,
29
+ del,
30
+ em,
31
+ heading,
32
+ hr,
33
+ html,
34
+ image,
35
+ link,
36
+ list,
37
+ listItem,
38
+ paragraph,
39
+ strong,
40
+ table,
41
+ tableCell,
42
+ text,
43
+ ...restProps
89
44
  }: MarkdownProps = $props();
90
45
 
91
- setMarkdownContext(
92
- new MarkdownContext(
93
- () => ({
94
- blockquote,
95
- br,
96
- code,
97
- codespan,
98
- def,
99
- del,
100
- em,
101
- escape,
102
- heading,
103
- hr,
104
- html,
105
- image,
106
- link,
107
- list_item: listItem,
108
- list,
109
- paragraph,
110
- space,
111
- strong,
112
- table,
113
- text,
114
- }),
115
- () => tableCell,
116
- ),
117
- );
118
-
119
- let tokens = $derived(Lexer.lex(value, options) as MarkedToken[]);
46
+ const tokens = $derived(parse(value, { gfm, breaks }));
47
+ const renderers: MarkdownRenderers = $derived({
48
+ blockquote,
49
+ br,
50
+ code,
51
+ codespan,
52
+ del,
53
+ em,
54
+ heading,
55
+ hr,
56
+ html,
57
+ image,
58
+ link,
59
+ list,
60
+ listItem,
61
+ paragraph,
62
+ strong,
63
+ table,
64
+ tableCell,
65
+ text,
66
+ });
120
67
  </script>
121
68
 
122
- {#snippet defaultBlockquote(props: MarkdownComponentProps<Tokens.Blockquote>)}
123
- <MarkdownBlockquote {...props} />
124
- {/snippet}
125
- {#snippet defaultBr(props: MarkdownComponentProps<Tokens.Br>)}
126
- <MarkdownBr {...props} />
127
- {/snippet}
128
- {#snippet defaultCode(props: MarkdownComponentProps<Tokens.Code>)}
129
- <MarkdownCode {...props} />
130
- {/snippet}
131
- {#snippet defaultCodespan(props: MarkdownComponentProps<Tokens.Codespan>)}
132
- <MarkdownCodespan {...props} />
133
- {/snippet}
134
- {#snippet defaultDef(props: MarkdownComponentProps<Tokens.Def>)}
135
- <MarkdownDef {...props} />
136
- {/snippet}
137
- {#snippet defaultDel(props: MarkdownComponentProps<Tokens.Del>)}
138
- <MarkdownDel {...props} />
139
- {/snippet}
140
- {#snippet defaultEm(props: MarkdownComponentProps<Tokens.Em>)}
141
- <MarkdownEm {...props} />
142
- {/snippet}
143
- {#snippet defaultEscape(props: MarkdownComponentProps<Tokens.Escape>)}
144
- <MarkdownEscape {...props} />
145
- {/snippet}
146
- {#snippet defaultHeading(props: MarkdownComponentProps<Tokens.Heading>)}
147
- <MarkdownHeading {...props} />
148
- {/snippet}
149
- {#snippet defaultHr(props: MarkdownComponentProps<Tokens.Hr>)}
150
- <MarkdownHr {...props} />
151
- {/snippet}
152
- {#snippet defaultHtml(props: MarkdownComponentProps<Tokens.HTML | Tokens.Tag>)}
153
- <MarkdownHtml {...props} />
154
- {/snippet}
155
- {#snippet defaultImage(props: MarkdownComponentProps<Tokens.Image>)}
156
- <MarkdownImage {...props} />
157
- {/snippet}
158
- {#snippet defaultLink(props: MarkdownComponentProps<Tokens.Link>)}
159
- <MarkdownLink {...props} />
160
- {/snippet}
161
- {#snippet defaultListItem(props: MarkdownComponentProps<Tokens.ListItem>)}
162
- <MarkdownListItem {...props} />
163
- {/snippet}
164
- {#snippet defaultList(props: MarkdownComponentProps<Tokens.List>)}
165
- <MarkdownList {...props} />
166
- {/snippet}
167
- {#snippet defaultParagraph(props: MarkdownComponentProps<Tokens.Paragraph>)}
168
- <MarkdownParagraph {...props} />
169
- {/snippet}
170
- {#snippet defaultSpace(props: MarkdownComponentProps<Tokens.Space>)}
171
- <MarkdownSpace {...props} />
172
- {/snippet}
173
- {#snippet defaultStrong(props: MarkdownComponentProps<Tokens.Strong>)}
174
- <MarkdownStrong {...props} />
175
- {/snippet}
176
- {#snippet defaultTable(props: MarkdownComponentProps<Tokens.Table>)}
177
- <MarkdownTable {...props} />
178
- {/snippet}
179
- {#snippet defaultTableCell(props: MarkdownComponentProps<Tokens.TableCell>)}
180
- <MarkdownTableCell {...props} />
181
- {/snippet}
182
- {#snippet defaultText(props: MarkdownComponentProps<Tokens.Text>)}
183
- <MarkdownText {...props} />
184
- {/snippet}
185
-
186
- <MarkdownTokens {tokens} />
69
+ <div
70
+ bind:this={el}
71
+ class={cn("flex flex-col gap-3 wrap-break-word", className)}
72
+ {...restProps}
73
+ >
74
+ <MarkdownTokens {tokens} {renderers} />
75
+ </div>
@@ -1,31 +1,11 @@
1
- import { type MarkdownComponentProps } from "./index.js";
2
- import { type MarkedOptions, type Tokens } from "marked";
3
- import type { Snippet } from "svelte";
1
+ import { type ClassName, type ElementRef } from "../utils.js";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import type { MarkdownRenderers } from "./types.js";
4
4
  export type MarkdownProps = {
5
5
  value: string;
6
- options?: MarkedOptions;
7
- blockquote?: Snippet<[MarkdownComponentProps<Tokens.Blockquote>]>;
8
- br?: Snippet<[MarkdownComponentProps<Tokens.Br>]>;
9
- code?: Snippet<[MarkdownComponentProps<Tokens.Code>]>;
10
- codespan?: Snippet<[MarkdownComponentProps<Tokens.Codespan>]>;
11
- def?: Snippet<[MarkdownComponentProps<Tokens.Def>]>;
12
- del?: Snippet<[MarkdownComponentProps<Tokens.Del>]>;
13
- em?: Snippet<[MarkdownComponentProps<Tokens.Em>]>;
14
- escape?: Snippet<[MarkdownComponentProps<Tokens.Escape>]>;
15
- heading?: Snippet<[MarkdownComponentProps<Tokens.Heading>]>;
16
- hr?: Snippet<[MarkdownComponentProps<Tokens.Hr>]>;
17
- html?: Snippet<[MarkdownComponentProps<Tokens.HTML | Tokens.Tag>]>;
18
- image?: Snippet<[MarkdownComponentProps<Tokens.Image>]>;
19
- link?: Snippet<[MarkdownComponentProps<Tokens.Link>]>;
20
- listItem?: Snippet<[MarkdownComponentProps<Tokens.ListItem>]>;
21
- list?: Snippet<[MarkdownComponentProps<Tokens.List>]>;
22
- paragraph?: Snippet<[MarkdownComponentProps<Tokens.Paragraph>]>;
23
- space?: Snippet<[MarkdownComponentProps<Tokens.Space>]>;
24
- strong?: Snippet<[MarkdownComponentProps<Tokens.Strong>]>;
25
- tableCell?: Snippet<[MarkdownComponentProps<Tokens.TableCell>]>;
26
- table?: Snippet<[MarkdownComponentProps<Tokens.Table>]>;
27
- text?: Snippet<[MarkdownComponentProps<Tokens.Text>]>;
28
- };
29
- declare const Markdown: import("svelte").Component<MarkdownProps, {}, "">;
6
+ gfm?: boolean;
7
+ breaks?: boolean;
8
+ } & MarkdownRenderers & ElementRef & ClassName & Omit<HTMLAttributes<HTMLDivElement>, "children">;
9
+ declare const Markdown: import("svelte").Component<MarkdownProps, {}, "el">;
30
10
  type Markdown = ReturnType<typeof Markdown>;
31
11
  export default Markdown;
@@ -0,0 +1,5 @@
1
+ import { type MarkedToken } from "marked";
2
+ export declare function parse(value: string, options: {
3
+ gfm: boolean;
4
+ breaks: boolean;
5
+ }): MarkedToken[];
@@ -0,0 +1,30 @@
1
+ import { Lexer } from "marked";
2
+ const SCHEME = /^[a-z][a-z\d+.-]*:/i;
3
+ const SAFE_SCHEME = /^(?:https?|mailto|tel):/i;
4
+ function isSafe(url) {
5
+ const normalized = url.replace(/[\p{Cc}\s]/gu, "");
6
+ return !SCHEME.test(normalized) || SAFE_SCHEME.test(normalized);
7
+ }
8
+ function sanitize(tokens) {
9
+ for (const token of tokens) {
10
+ if (token.type === "link" || token.type === "image") {
11
+ token.href = isSafe(token.href) ? token.href : "";
12
+ }
13
+ if ("tokens" in token && token.tokens) {
14
+ sanitize(token.tokens);
15
+ }
16
+ if (token.type === "list") {
17
+ sanitize(token.items);
18
+ }
19
+ if (token.type === "table") {
20
+ for (const cell of [...token.header, ...token.rows.flat()]) {
21
+ sanitize(cell.tokens);
22
+ }
23
+ }
24
+ }
25
+ }
26
+ export function parse(value, options) {
27
+ const tokens = new Lexer(options).lex(value);
28
+ sanitize(tokens);
29
+ return tokens;
30
+ }
@@ -0,0 +1,28 @@
1
+ import type { Tokens } from "marked";
2
+ import type { Snippet } from "svelte";
3
+ export type MarkdownSnippetProps<T> = {
4
+ token: T;
5
+ children: Snippet;
6
+ };
7
+ type Renderer<T> = Snippet<[MarkdownSnippetProps<T>]>;
8
+ export type MarkdownRenderers = {
9
+ blockquote?: Renderer<Tokens.Blockquote>;
10
+ br?: Renderer<Tokens.Br>;
11
+ code?: Renderer<Tokens.Code>;
12
+ codespan?: Renderer<Tokens.Codespan>;
13
+ del?: Renderer<Tokens.Del>;
14
+ em?: Renderer<Tokens.Em>;
15
+ heading?: Renderer<Tokens.Heading>;
16
+ hr?: Renderer<Tokens.Hr>;
17
+ html?: Renderer<Tokens.HTML | Tokens.Tag>;
18
+ image?: Renderer<Tokens.Image>;
19
+ link?: Renderer<Tokens.Link>;
20
+ list?: Renderer<Tokens.List>;
21
+ listItem?: Renderer<Tokens.ListItem>;
22
+ paragraph?: Renderer<Tokens.Paragraph>;
23
+ strong?: Renderer<Tokens.Strong>;
24
+ table?: Renderer<Tokens.Table>;
25
+ tableCell?: Renderer<Tokens.TableCell>;
26
+ text?: Renderer<Tokens.Text>;
27
+ };
28
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,8 +1,5 @@
1
- export { Divider as MenuDivider, Header as MenuHeader, } from "../common/index.js";
1
+ export { Divider as MenuDivider } from "../common/index.js";
2
2
  export { default as MenuActions, type MenuActionsProps, } from "./menu-actions.svelte";
3
- export { default as MenuContent, type MenuContentProps, } from "./menu-content.svelte";
4
- export { getMenuContext, MenuContext, setMenuContext, } from "./menu-context.svelte.js";
3
+ export { default as MenuGroup, type MenuGroupProps } from "./menu-group.svelte";
5
4
  export { default as MenuItem, type MenuItemProps } from "./menu-item.svelte";
6
- export { default as MenuTriggerButton, type MenuTriggerButtonProps, } from "./menu-trigger-button.svelte";
7
- export { default as MenuTrigger, type MenuTriggerProps, } from "./menu-trigger.svelte";
8
- export { default as Menu, type MenuProps } from "./menu.svelte";
5
+ export { default as Menu, type MenuProps, type MenuTriggerProps, } from "./menu.svelte";
@@ -1,8 +1,5 @@
1
- export { Divider as MenuDivider, Header as MenuHeader, } from "../common/index.js";
1
+ export { Divider as MenuDivider } from "../common/index.js";
2
2
  export { default as MenuActions, } from "./menu-actions.svelte";
3
- export { default as MenuContent, } from "./menu-content.svelte";
4
- export { getMenuContext, MenuContext, setMenuContext, } from "./menu-context.svelte.js";
3
+ export { default as MenuGroup } from "./menu-group.svelte";
5
4
  export { default as MenuItem } from "./menu-item.svelte";
6
- export { default as MenuTriggerButton, } from "./menu-trigger-button.svelte";
7
- export { default as MenuTrigger, } from "./menu-trigger.svelte";
8
- export { default as Menu } from "./menu.svelte";
5
+ export { default as Menu, } from "./menu.svelte";
@@ -1,51 +1,57 @@
1
1
  <script lang="ts">
2
2
  import type { Action } from "../command/index.js";
3
- import { MenuDivider, MenuHeader, MenuItem } from "./index.js";
4
- import { Check } from "@lucide/svelte";
3
+ import { Divider as MenuDivider } from "../common/index.js";
4
+ import { ShortcutHint } from "../shortcut/index.js";
5
+ import MenuGroup from "./menu-group.svelte";
6
+ import MenuItem from "./menu-item.svelte";
5
7
 
6
8
  export type MenuActionsProps = {
7
9
  actions: Action[];
8
10
  };
9
11
  let { actions }: MenuActionsProps = $props();
10
12
 
11
- let categoryHasSelected = $derived(
12
- actions.reduce(
13
- (acc, { category, selected }) => ({
14
- ...acc,
15
- [category]: acc[category] || selected !== undefined,
16
- }),
17
- {} as Record<string, boolean>,
18
- ),
13
+ type Group = { category: string; actions: Action[]; checkable: boolean };
14
+
15
+ const groups = $derived(
16
+ actions.reduce<Group[]>((groups, action) => {
17
+ let last = groups.at(-1);
18
+ if (last?.category !== action.category) {
19
+ last = { category: action.category, actions: [], checkable: false };
20
+ groups.push(last);
21
+ }
22
+ last.actions.push(action);
23
+ last.checkable ||= action.selected !== undefined;
24
+ return groups;
25
+ }, []),
19
26
  );
20
27
  </script>
21
28
 
22
- {#each actions as action, index (action)}
23
- {@const Icon = action.icon}
24
- {#if index === 0 || actions[index - 1].category !== action.category}
25
- {#if index !== 0}
26
- <MenuDivider />
27
- {/if}
28
- <MenuHeader>{action.category}</MenuHeader>
29
- {/if}
30
- <MenuItem
31
- class="gap-2"
32
- onSelect={action.callback}
33
- title={action.description}
34
- disabled={!action.enabled()}
35
- >
36
- {#if categoryHasSelected[action.category]}
37
- {#if action.selected?.()}
38
- <Check class="text-m3-primary" size={16} />
39
- {:else}
40
- <div class="size-4"></div>
29
+ {#snippet items({ actions, checkable }: Group)}
30
+ {#each actions as action (action)}
31
+ <MenuItem
32
+ onSelect={action.callback}
33
+ title={action.description}
34
+ disabled={!action.enabled()}
35
+ checked={checkable ? (action.selected?.() ?? false) : undefined}
36
+ >
37
+ <action.icon size={16} class="shrink-0" />
38
+ {action.name}
39
+ {#if action.shortcut}
40
+ <ShortcutHint shortcut={action.shortcut} class="ml-auto pl-4" />
41
41
  {/if}
42
- {/if}
43
- <Icon size={16} />
44
- {action.name}
45
- {#if action.shortcut}
46
- <div class="ml-auto pl-2 text-xs">
47
- {action.shortcut.toString()}
48
- </div>
49
- {/if}
50
- </MenuItem>
42
+ </MenuItem>
43
+ {/each}
44
+ {/snippet}
45
+
46
+ {#each groups as group, index (index)}
47
+ {#if index > 0}
48
+ <MenuDivider />
49
+ {/if}
50
+ {#if group.category}
51
+ <MenuGroup label={group.category}>
52
+ {@render items(group)}
53
+ </MenuGroup>
54
+ {:else}
55
+ {@render items(group)}
56
+ {/if}
51
57
  {/each}
@@ -0,0 +1,4 @@
1
+ export type MenuContext = {
2
+ close(): void;
3
+ };
4
+ export declare const getMenuContext: () => MenuContext, setMenuContext: (context: MenuContext) => MenuContext;
@@ -0,0 +1,2 @@
1
+ import { createContext } from "svelte";
2
+ export const [getMenuContext, setMenuContext] = createContext();
@@ -0,0 +1,40 @@
1
+ <script module lang="ts">
2
+ import { cn, type ClassName } from "../utils.js";
3
+ import type { Snippet } from "svelte";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+
6
+ export type MenuGroupProps = {
7
+ label: string;
8
+ el?: HTMLDivElement;
9
+ children: Snippet;
10
+ } & ClassName &
11
+ Omit<HTMLAttributes<HTMLDivElement>, "class">;
12
+ </script>
13
+
14
+ <script lang="ts">
15
+ let {
16
+ label,
17
+ children,
18
+ el = $bindable(),
19
+ class: className,
20
+ ...restProps
21
+ }: MenuGroupProps = $props();
22
+
23
+ const id = $props.id();
24
+ </script>
25
+
26
+ <div
27
+ bind:this={el}
28
+ role="group"
29
+ aria-labelledby="{id}-label"
30
+ class={cn(className)}
31
+ {...restProps}
32
+ >
33
+ <div
34
+ id="{id}-label"
35
+ class="px-3 pt-2 pb-1 text-xs font-medium text-m3-on-surface-variant"
36
+ >
37
+ {label}
38
+ </div>
39
+ {@render children()}
40
+ </div>
@@ -0,0 +1,11 @@
1
+ import { type ClassName } from "../utils.js";
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+ export type MenuGroupProps = {
5
+ label: string;
6
+ el?: HTMLDivElement;
7
+ children: Snippet;
8
+ } & ClassName & Omit<HTMLAttributes<HTMLDivElement>, "class">;
9
+ declare const MenuGroup: import("svelte").Component<MenuGroupProps, {}, "el">;
10
+ type MenuGroup = ReturnType<typeof MenuGroup>;
11
+ export default MenuGroup;
@@ -1,85 +1,62 @@
1
1
  <script module lang="ts">
2
- import { baseClasses, type Variants } from "../base.js";
3
- import { getMenuContext } from "./index.js";
2
+ import { baseClasses, type ColorProp } from "../base.js";
4
3
  import { mergeProps } from "../merge-props.js";
5
- import { Shortcut } from "../shortcut/index.js";
6
- import type { ClassName, ElementRef } from "../utils.js";
4
+ import { cn, type ClassName } from "../utils.js";
5
+ import { Check } from "@lucide/svelte";
7
6
  import type { Snippet } from "svelte";
8
7
  import type { HTMLButtonAttributes } from "svelte/elements";
9
- import { twMerge } from "tailwind-merge";
8
+ import { getMenuContext } from "./menu-context.js";
10
9
 
11
10
  export type MenuItemProps = {
12
- onSelect?: (el: HTMLElement) => void;
13
- children: Snippet<[]>;
14
- } & ElementRef &
15
- ClassName &
16
- Variants &
17
- Omit<HTMLButtonAttributes, "type" | "value">;
11
+ onSelect?: () => void;
12
+ checked?: boolean;
13
+ el?: HTMLButtonElement;
14
+ children: Snippet;
15
+ } & ClassName &
16
+ ColorProp &
17
+ Omit<HTMLButtonAttributes, "type" | "value" | "role" | "class">;
18
18
  </script>
19
19
 
20
20
  <script lang="ts">
21
21
  let {
22
22
  onSelect,
23
+ checked,
23
24
  children,
24
25
  el = $bindable(),
26
+ color = "plain",
25
27
  class: className,
26
- variant = "plain",
27
- color = "secondary",
28
- shape = "rounded",
29
28
  ...restProps
30
29
  }: MenuItemProps = $props();
31
30
 
32
- const ctx = getMenuContext();
33
-
34
- function handleClick() {
35
- if (el) {
36
- onSelect?.(el);
37
- }
38
- ctx.close();
39
- }
40
-
41
- function handleMouseEnter(event: MouseEvent) {
42
- if (event.target instanceof HTMLElement) {
43
- ctx.focus(event.target);
44
- }
45
- }
46
-
47
- function handleFocus(event: FocusEvent) {
48
- if (event.target instanceof HTMLElement) {
49
- ctx.focus(event.target);
50
- }
51
- }
52
-
53
- function handleKeyDown(event: KeyboardEvent) {
54
- if (Shortcut.ENTER.matches(event) || Shortcut.SPACE.matches(event)) {
55
- event.stopImmediatePropagation();
56
- }
57
- }
58
-
59
- $effect(() => {
60
- if (el) {
61
- return ctx.add(el);
62
- }
63
- });
31
+ const menu = getMenuContext();
64
32
  </script>
65
33
 
66
34
  <button
67
35
  bind:this={el}
68
- role="menuitem"
69
- class={twMerge(
70
- baseClasses({ variant, color, shape, focus: true }),
71
- "flex w-full items-center gap-1 px-2 py-1 text-left text-sm focus:ring-0",
36
+ type="button"
37
+ role={checked === undefined ? "menuitem" : "menuitemcheckbox"}
38
+ aria-checked={checked}
39
+ tabindex={-1}
40
+ class={cn(
41
+ baseClasses({ color }),
42
+ "flex h-8 w-full items-center gap-2 rounded-sm px-3 text-left text-sm outline-none focus:bg-current/10 disabled:text-m3-on-surface/38",
72
43
  className,
73
44
  )}
74
45
  {...mergeProps(
75
46
  {
76
- onclick: handleClick,
77
- onmouseenter: handleMouseEnter,
78
- onfocus: handleFocus,
79
- onkeydown: handleKeyDown,
47
+ onclick: () => {
48
+ menu.close();
49
+ onSelect?.();
50
+ },
51
+ onpointermove: () => {
52
+ if (el && !el.disabled && document.activeElement !== el) el.focus();
53
+ },
80
54
  },
81
55
  restProps,
82
56
  )}
83
57
  >
58
+ {#if checked !== undefined}
59
+ <Check size={16} class={cn("shrink-0", !checked && "invisible")} />
60
+ {/if}
84
61
  {@render children()}
85
62
  </button>