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
package/dist/base.js CHANGED
@@ -1,4 +1,4 @@
1
- import { twMerge } from "tailwind-merge";
1
+ import { cn } from "./utils.js";
2
2
  export const VARIANTS = [
3
3
  "elevated",
4
4
  "filled",
@@ -15,22 +15,10 @@ export const COLORS = [
15
15
  "plain",
16
16
  "inherit",
17
17
  ];
18
- export const SHAPES = ["square", "rounded", "circle"];
18
+ export const SHAPES = ["none", "xs", "sm", "md", "lg", "xl", "full"];
19
19
  export const SIZES = ["xs", "sm", "md", "lg", "xl"];
20
- export const RADII = [
21
- "none",
22
- "xs",
23
- "sm",
24
- "md",
25
- "lg",
26
- "xl",
27
- "2xl",
28
- "3xl",
29
- "4xl",
30
- "full",
31
- ];
32
20
  export const UNDERLINES = ["always", "hover", "none"];
33
- const hoverBaseClasses = ({ variant, color }) => twMerge("disabled:text-m3-on-surface/38 disabled:bg-m3-on-surface/12 disabled:cursor-not-allowed", variant === "filled" && "hover:opacity-90", variant === "tonal" && "hover:opacity-80", variant === "text" && "hover:opacity-80", variant === "elevated" &&
21
+ const hoverBaseClasses = ({ variant, color }) => cn("disabled:text-m3-on-surface/38 disabled:bg-m3-on-surface/12 disabled:cursor-not-allowed", variant === "filled" && "hover:opacity-90", variant === "tonal" && "hover:opacity-80", variant === "text" && "hover:opacity-80", variant === "elevated" &&
34
22
  color === "primary" &&
35
23
  "hover:bg-m3-primary-container/30", variant === "elevated" &&
36
24
  color === "secondary" &&
@@ -47,27 +35,25 @@ const hoverBaseClasses = ({ variant, color }) => twMerge("disabled:text-m3-on-su
47
35
  "hover:bg-m3-tertiary/15", (variant === "outlined" || variant === "plain") &&
48
36
  color === "error" &&
49
37
  "hover:bg-m3-error/15");
50
- const focusBaseClasses = ({ variant, color }) => twMerge("disabled:text-m3-on-surface/38 disabled:bg-m3-on-surface/12 disabled:cursor-not-allowed", "focus:ring-1 focus-visible:outline-hidden", variant === "filled" && "focus:opacity-90", variant === "tonal" && "focus:opacity-80", variant === "text" && "focus:opacity-80", color === "primary" && "focus:ring-m3-primary", color === "secondary" && "focus:ring-m3-secondary", color === "tertiary" && "focus:ring-m3-tertiary", color === "error" && "focus:ring-m3-error", variant === "filled" && color === "primary" && "focus:ring-m3-on-primary", variant === "filled" &&
51
- color === "secondary" &&
52
- "focus:ring-m3-on-secondary", variant === "filled" && color === "tertiary" && "focus:ring-m3-on-tertiary", variant === "filled" && color === "error" && "focus:ring-m3-on-error", variant === "elevated" &&
38
+ const focusBaseClasses = ({ variant, color }) => cn("disabled:text-m3-on-surface/38 disabled:bg-m3-on-surface/12 disabled:cursor-not-allowed", "focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-m3-secondary", variant === "filled" && "focus-visible:opacity-90", variant === "tonal" && "focus-visible:opacity-80", variant === "text" && "focus-visible:opacity-80", variant === "elevated" &&
53
39
  color === "primary" &&
54
- "focus:bg-m3-primary-container/30", variant === "elevated" &&
40
+ "focus-visible:bg-m3-primary-container/30", variant === "elevated" &&
55
41
  color === "secondary" &&
56
- "focus:bg-m3-secondary-container/30", variant === "elevated" &&
42
+ "focus-visible:bg-m3-secondary-container/30", variant === "elevated" &&
57
43
  color === "tertiary" &&
58
- "focus:bg-m3-tertiary-container/30", variant === "elevated" &&
44
+ "focus-visible:bg-m3-tertiary-container/30", variant === "elevated" &&
59
45
  color === "error" &&
60
- "focus:bg-m3-error-container/30", (variant === "outlined" || variant === "plain") &&
46
+ "focus-visible:bg-m3-error-container/30", (variant === "outlined" || variant === "plain") &&
61
47
  color === "primary" &&
62
- "focus:bg-m3-primary/15", (variant === "outlined" || variant === "plain") &&
48
+ "focus-visible:bg-m3-primary/15", (variant === "outlined" || variant === "plain") &&
63
49
  color === "secondary" &&
64
- "focus:bg-m3-secondary/15", (variant === "outlined" || variant === "plain") &&
50
+ "focus-visible:bg-m3-secondary/15", (variant === "outlined" || variant === "plain") &&
65
51
  color === "tertiary" &&
66
- "focus:bg-m3-tertiary/15", (variant === "outlined" || variant === "plain") &&
52
+ "focus-visible:bg-m3-tertiary/15", (variant === "outlined" || variant === "plain") &&
67
53
  color === "error" &&
68
- "focus:bg-m3-error/15");
69
- export const baseClasses = ({ variant, color, shape, underline, hover = false, focus = false, }) => twMerge(variant === "elevated" &&
70
- "bg-m3-surface-container-low shadow shadow-m3-shadow/20", variant === "outlined" && "ring-1", variant === "plain" && "", variant === "text" && "underline-offset-4", color === "primary" && "text-m3-primary", color === "secondary" && "text-m3-secondary", color === "tertiary" && "text-m3-tertiary", color === "error" && "text-m3-error", shape === "square" && "", shape === "rounded" && "rounded-md", shape === "circle" && "rounded-full", underline === "always" && "underline", underline === "hover" && "hover:underline", underline === "none" && "", variant === "filled" &&
54
+ "focus-visible:bg-m3-error/15");
55
+ export const baseClasses = ({ variant, color, shape, underline, hover = false, focus = false, }) => cn(variant === "elevated" &&
56
+ "bg-m3-surface-container-low shadow shadow-m3-shadow/20", variant === "outlined" && "ring-1", variant === "plain" && "", variant === "text" && "underline-offset-4", color === "primary" && "text-m3-primary", color === "secondary" && "text-m3-secondary", color === "tertiary" && "text-m3-tertiary", color === "error" && "text-m3-error", shape === "none" && "rounded-none", shape === "xs" && "rounded-sm", shape === "sm" && "rounded-lg", shape === "md" && "rounded-xl", shape === "lg" && "rounded-2xl", shape === "xl" && "rounded-[1.75rem]", shape === "full" && "rounded-full", underline === "always" && "underline", underline === "hover" && "hover:underline", underline === "none" && "", variant === "filled" &&
71
57
  color === "primary" &&
72
58
  "bg-m3-primary text-m3-on-primary", variant === "filled" &&
73
59
  color === "secondary" &&
@@ -1,24 +1,18 @@
1
1
  <script lang="ts">
2
2
  import { baseClasses, type Variants } from "../base.js";
3
- import { noop, type ClassName, type ElementRef } from "../utils.js";
3
+ import { cn, type ClassName, type ElementRef } from "../utils.js";
4
4
  import type { Snippet } from "svelte";
5
5
  import type { HTMLAttributes } from "svelte/elements";
6
- import { twMerge } from "tailwind-merge";
7
6
 
8
7
  export type BoxProps = {
9
- centered?: boolean;
10
- backdrop?: boolean;
11
8
  children?: Snippet;
12
9
  } & ElementRef &
13
10
  ClassName &
14
11
  Variants &
15
12
  HTMLAttributes<HTMLDivElement>;
16
13
  let {
17
- backdrop = false,
18
- centered = false,
19
14
  children,
20
15
  el = $bindable(),
21
- ref = noop,
22
16
  class: className,
23
17
  variant,
24
18
  color,
@@ -29,13 +23,7 @@
29
23
 
30
24
  <div
31
25
  bind:this={el}
32
- use:ref
33
- class={twMerge(
34
- backdrop && "bg-m3-surface-container",
35
- baseClasses({ variant, color, shape }),
36
- centered && "flex items-center justify-center",
37
- className,
38
- )}
26
+ class={cn(baseClasses({ variant, color, shape }), className)}
39
27
  {...restProps}
40
28
  >
41
29
  {@render children?.()}
@@ -3,8 +3,6 @@ import { type ClassName, type ElementRef } from "../utils.js";
3
3
  import type { Snippet } from "svelte";
4
4
  import type { HTMLAttributes } from "svelte/elements";
5
5
  export type BoxProps = {
6
- centered?: boolean;
7
- backdrop?: boolean;
8
6
  children?: Snippet;
9
7
  } & ElementRef & ClassName & Variants & HTMLAttributes<HTMLDivElement>;
10
8
  declare const Box: import("svelte").Component<BoxProps, {}, "el">;
@@ -1,9 +1,11 @@
1
1
  <script module lang="ts">
2
- import { Link, type LinkProps } from "../link/index.js";
2
+ import type { ColorProp } from "../base.js";
3
+ import { Link } from "../link/index.js";
4
+ import { type ClassName, type ElementRef } from "../utils.js";
3
5
  import type { Snippet } from "svelte";
4
- import { twMerge } from "tailwind-merge";
6
+ import type { HTMLAttributes } from "svelte/elements";
5
7
 
6
- type Crumb = {
8
+ export type Crumb = {
7
9
  title: string;
8
10
  href: string;
9
11
  };
@@ -11,29 +13,46 @@
11
13
  export type BreadcrumbsProps = {
12
14
  path: Crumb[];
13
15
  separator?: Snippet | string;
14
- } & Omit<LinkProps, "children">;
16
+ } & ColorProp &
17
+ ElementRef &
18
+ ClassName &
19
+ HTMLAttributes<HTMLElement>;
15
20
  </script>
16
21
 
17
22
  <script lang="ts">
18
- const {
23
+ let {
19
24
  path,
20
25
  separator = "›",
21
- class: className,
26
+ color = "primary",
27
+ el = $bindable(),
28
+ "aria-label": ariaLabel = "Breadcrumb",
22
29
  ...restProps
23
30
  }: BreadcrumbsProps = $props();
24
31
  </script>
25
32
 
26
- <div class={twMerge("flex gap-2", className)}>
27
- {#each path as { title, href }, index (title)}
28
- {#if index !== 0}
29
- <div>
30
- {#if typeof separator === "function"}
31
- {@render separator()}
32
- {:else}
33
- {separator}
33
+ <nav bind:this={el} aria-label={ariaLabel} {...restProps}>
34
+ <ol class="flex flex-wrap items-center gap-x-2 gap-y-1">
35
+ {#each path as { title, href }, index (index)}
36
+ {@const current = index === path.length - 1}
37
+ <li class="flex items-center gap-2">
38
+ {#if index !== 0}
39
+ <span aria-hidden="true">
40
+ {#if typeof separator === "function"}
41
+ {@render separator()}
42
+ {:else}
43
+ {separator}
44
+ {/if}
45
+ </span>
34
46
  {/if}
35
- </div>
36
- {/if}
37
- <Link {href} {...restProps}>{title}</Link>
38
- {/each}
39
- </div>
47
+ <Link
48
+ {href}
49
+ underline="hover"
50
+ color={current ? "inherit" : color}
51
+ aria-current={current ? "page" : undefined}
52
+ >
53
+ {title}
54
+ </Link>
55
+ </li>
56
+ {/each}
57
+ </ol>
58
+ </nav>
@@ -1,13 +1,15 @@
1
- import { type LinkProps } from "../link/index.js";
1
+ import type { ColorProp } from "../base.js";
2
+ import { type ClassName, type ElementRef } from "../utils.js";
2
3
  import type { Snippet } from "svelte";
3
- type Crumb = {
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+ export type Crumb = {
4
6
  title: string;
5
7
  href: string;
6
8
  };
7
9
  export type BreadcrumbsProps = {
8
10
  path: Crumb[];
9
11
  separator?: Snippet | string;
10
- } & Omit<LinkProps, "children">;
11
- declare const Breadcrumbs: import("svelte").Component<BreadcrumbsProps, {}, "">;
12
+ } & ColorProp & ElementRef & ClassName & HTMLAttributes<HTMLElement>;
13
+ declare const Breadcrumbs: import("svelte").Component<BreadcrumbsProps, {}, "el">;
12
14
  type Breadcrumbs = ReturnType<typeof Breadcrumbs>;
13
15
  export default Breadcrumbs;
@@ -1 +1 @@
1
- export { default as Breadcrumbs } from "./breadcrumbs.svelte";
1
+ export { default as Breadcrumbs, type BreadcrumbsProps, type Crumb, } from "./breadcrumbs.svelte";
@@ -1 +1 @@
1
- export { default as Breadcrumbs } from "./breadcrumbs.svelte";
1
+ export { default as Breadcrumbs, } from "./breadcrumbs.svelte";
@@ -1,63 +1,128 @@
1
1
  <script lang="ts" module>
2
- import { baseClasses, type Variants } from "../base.js";
2
+ import {
3
+ baseClasses,
4
+ type Size,
5
+ type SizeProp,
6
+ type Variants,
7
+ } from "../base.js";
3
8
  import { mergeProps } from "../merge-props.js";
4
9
  import { Tooltip, type TooltipTriggerProps } from "../tooltip/index.js";
5
- import { noop, type ClassName, type ElementRef } from "../utils.js";
10
+ import { cn, type ClassName, type ElementRef } from "../utils.js";
6
11
  import type { LucideIcon } from "@lucide/svelte";
7
12
  import type { Snippet } from "svelte";
8
- import type { HTMLButtonAttributes } from "svelte/elements";
9
- import { twMerge } from "tailwind-merge";
13
+ import type {
14
+ HTMLAnchorAttributes,
15
+ HTMLButtonAttributes,
16
+ } from "svelte/elements";
10
17
 
11
- export type ButtonProps = {
18
+ type ButtonOwnProps = {
12
19
  icon?: LucideIcon;
13
- size?: number;
14
20
  tooltip?: Snippet | string;
15
21
  } & ElementRef &
16
22
  ClassName &
17
23
  Variants &
18
- HTMLButtonAttributes;
24
+ SizeProp;
25
+
26
+ export type ButtonActionProps = ButtonOwnProps & {
27
+ href?: undefined;
28
+ } & HTMLButtonAttributes;
29
+
30
+ export type ButtonLinkProps = ButtonOwnProps & {
31
+ href: string;
32
+ } & Omit<HTMLAnchorAttributes, "href">;
33
+
34
+ export type ButtonProps = ButtonActionProps | ButtonLinkProps;
35
+
36
+ const LABEL_SIZES: Record<Size, string> = {
37
+ xs: "gap-1.5 px-3 py-1.5 text-xs",
38
+ sm: "gap-2 px-4 py-2 text-sm",
39
+ md: "gap-2 px-5 py-2.5 text-base",
40
+ lg: "gap-2.5 px-6 py-3 text-lg",
41
+ xl: "gap-3 px-7 py-4 text-xl",
42
+ };
43
+ const ICON_ONLY_SIZES: Record<Size, string> = {
44
+ xs: "size-7",
45
+ sm: "size-9",
46
+ md: "size-11",
47
+ lg: "size-13",
48
+ xl: "size-15",
49
+ };
50
+ const ICON_SIZES: Record<Size, number> = {
51
+ xs: 14,
52
+ sm: 16,
53
+ md: 20,
54
+ lg: 22,
55
+ xl: 24,
56
+ };
19
57
  </script>
20
58
 
21
59
  <script lang="ts">
22
60
  let {
23
61
  icon: IconComponent,
24
- size = 16,
25
62
  tooltip,
26
63
  children,
27
64
  el = $bindable(),
28
- ref = noop,
29
65
  class: className,
30
66
  variant = "outlined",
31
67
  color = "primary",
32
- shape = "rounded",
33
- type = "button",
68
+ shape = "full",
69
+ size = "sm",
34
70
  ...restProps
35
71
  }: ButtonProps = $props();
36
- </script>
37
72
 
38
- {#snippet button({ ref: anchorRef, ...triggerProps }: TooltipTriggerProps)}
39
- <button
40
- bind:this={el}
41
- use:ref
42
- use:anchorRef
43
- class={twMerge(
73
+ let tooltipLabel = $derived(
74
+ !children && typeof tooltip === "string" ? tooltip : undefined,
75
+ );
76
+
77
+ let classes = $derived(
78
+ cn(
44
79
  baseClasses({ variant, color, shape, hover: true, focus: true }),
45
- "flex items-center justify-center gap-2 text-sm text-nowrap transition-all select-none enabled:active:scale-95",
46
- children ? "px-4 py-2" : "p-2",
80
+ "inline-flex shrink-0 items-center justify-center text-nowrap transition-all select-none not-disabled:active:scale-95",
81
+ children ? LABEL_SIZES[size] : ICON_ONLY_SIZES[size],
47
82
  className,
48
- )}
49
- {type}
50
- {...mergeProps(restProps, triggerProps)}
51
- >
52
- {#if IconComponent}
53
- <IconComponent {size} />
54
- {/if}
55
- {@render children?.()}
56
- </button>
83
+ ),
84
+ );
85
+ </script>
86
+
87
+ {#snippet content()}
88
+ {#if IconComponent}
89
+ <IconComponent size={ICON_SIZES[size]} />
90
+ {/if}
91
+ {@render children?.()}
92
+ {/snippet}
93
+
94
+ {#snippet button({
95
+ "aria-describedby": describedBy,
96
+ ...triggerProps
97
+ }: TooltipTriggerProps)}
98
+ {#if restProps.href === undefined}
99
+ <button
100
+ bind:this={el}
101
+ aria-label={tooltipLabel}
102
+ aria-describedby={tooltipLabel ? undefined : describedBy}
103
+ class={classes}
104
+ type="button"
105
+ {...mergeProps(restProps, triggerProps)}
106
+ >
107
+ {@render content()}
108
+ </button>
109
+ {:else}
110
+ <!-- eslint-disable svelte/no-navigation-without-resolve -->
111
+ <a
112
+ bind:this={el}
113
+ aria-label={tooltipLabel}
114
+ aria-describedby={tooltipLabel ? undefined : describedBy}
115
+ class={classes}
116
+ {...mergeProps(restProps, triggerProps)}
117
+ >
118
+ {@render content()}
119
+ </a>
120
+ <!-- eslint-enable svelte/no-navigation-without-resolve -->
121
+ {/if}
57
122
  {/snippet}
58
123
 
59
124
  {#if tooltip}
60
- <Tooltip arrow>
125
+ <Tooltip>
61
126
  {#snippet trigger(props)}
62
127
  {@render button(props)}
63
128
  {/snippet}
@@ -68,5 +133,5 @@
68
133
  {/if}
69
134
  </Tooltip>
70
135
  {:else}
71
- {@render button({ ref: noop })}
136
+ {@render button({})}
72
137
  {/if}
@@ -1,13 +1,19 @@
1
- import { type Variants } from "../base.js";
1
+ import { type SizeProp, type Variants } from "../base.js";
2
2
  import { type ClassName, type ElementRef } from "../utils.js";
3
3
  import type { LucideIcon } from "@lucide/svelte";
4
4
  import type { Snippet } from "svelte";
5
- import type { HTMLButtonAttributes } from "svelte/elements";
6
- export type ButtonProps = {
5
+ import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
6
+ type ButtonOwnProps = {
7
7
  icon?: LucideIcon;
8
- size?: number;
9
8
  tooltip?: Snippet | string;
10
- } & ElementRef & ClassName & Variants & HTMLButtonAttributes;
9
+ } & ElementRef & ClassName & Variants & SizeProp;
10
+ export type ButtonActionProps = ButtonOwnProps & {
11
+ href?: undefined;
12
+ } & HTMLButtonAttributes;
13
+ export type ButtonLinkProps = ButtonOwnProps & {
14
+ href: string;
15
+ } & Omit<HTMLAnchorAttributes, "href">;
16
+ export type ButtonProps = ButtonActionProps | ButtonLinkProps;
11
17
  declare const Button: import("svelte").Component<ButtonProps, {}, "el">;
12
18
  type Button = ReturnType<typeof Button>;
13
19
  export default Button;
@@ -1 +1 @@
1
- export { default as Button, type ButtonProps } from "./button.svelte";
1
+ export { default as Button, type ButtonActionProps, type ButtonLinkProps, type ButtonProps, } from "./button.svelte";
@@ -1 +1 @@
1
- export { default as Button } from "./button.svelte";
1
+ export { default as Button, } from "./button.svelte";
@@ -1,15 +1,32 @@
1
1
  <script lang="ts" module>
2
+ import type { Size, SizeProp } from "../base.js";
2
3
  import { Box, type BoxProps } from "../box/index.js";
4
+ import { cn } from "../utils.js";
3
5
  import { X } from "@lucide/svelte";
4
6
  import type { Snippet } from "svelte";
5
- import { twMerge } from "tailwind-merge";
6
7
 
7
8
  export type ChipProps = {
8
9
  title?: string;
9
10
  onClick?: (event: MouseEvent | KeyboardEvent) => void;
10
11
  onDelete?: (event: MouseEvent | KeyboardEvent) => void;
11
12
  children: Snippet;
12
- } & BoxProps;
13
+ } & SizeProp &
14
+ BoxProps;
15
+
16
+ const LABEL_SIZES: Record<Size, string> = {
17
+ xs: "px-2 py-0.5 text-xs",
18
+ sm: "px-3 py-1 text-sm",
19
+ md: "px-3.5 py-1.5 text-base",
20
+ lg: "px-4 py-2 text-lg",
21
+ xl: "px-5 py-2.5 text-xl",
22
+ };
23
+ const REMOVE_SIZES: Record<Size, [string, number]> = {
24
+ xs: ["size-5", 12],
25
+ sm: ["size-6", 14],
26
+ md: ["size-7", 16],
27
+ lg: ["size-8", 18],
28
+ xl: ["size-9", 20],
29
+ };
13
30
  </script>
14
31
 
15
32
  <script lang="ts">
@@ -22,35 +39,66 @@
22
39
  class: className,
23
40
  variant = "filled",
24
41
  color = "primary",
25
- shape = "rounded",
42
+ shape = "sm",
43
+ size = "sm",
26
44
  ...restProps
27
45
  }: ChipProps = $props();
46
+
47
+ const id = $props.id();
48
+ let labelClasses = $derived(cn(LABEL_SIZES[size], onDelete && "pr-1"));
49
+ let [removeSize, iconSize] = $derived(REMOVE_SIZES[size]);
50
+ const focusRing =
51
+ "rounded-[inherit] focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-m3-secondary";
52
+
53
+ function deleteOnKey(event: KeyboardEvent) {
54
+ if (onDelete && (event.key === "Backspace" || event.key === "Delete")) {
55
+ event.preventDefault();
56
+ onDelete(event);
57
+ }
58
+ }
28
59
  </script>
29
60
 
30
61
  <Box
31
62
  bind:el
32
- role="option"
33
63
  {variant}
34
64
  {color}
35
65
  {shape}
36
- class={twMerge("inline-flex gap-1 px-1 py-0 text-xs", className)}
66
+ class={cn("inline-flex items-center", className)}
37
67
  {...restProps}
38
68
  >
39
- <button onclick={onClick} {title}>
40
- {@render children()}
41
- </button>
69
+ {#if onClick}
70
+ <button
71
+ type="button"
72
+ id="{id}-label"
73
+ class={cn(labelClasses, focusRing)}
74
+ {title}
75
+ onclick={onClick}
76
+ onkeydown={deleteOnKey}
77
+ >
78
+ {@render children()}
79
+ </button>
80
+ {:else}
81
+ <span id="{id}-label" class={labelClasses} {title}>
82
+ {@render children()}
83
+ </span>
84
+ {/if}
42
85
 
43
86
  {#if onDelete}
44
87
  <button
45
- aria-label="Delete chip"
46
- class={twMerge(
47
- "transition-all hover:ring-1 active:scale-95",
48
- shape === "rounded" && "rounded",
49
- shape === "circle" && "rounded-full",
88
+ type="button"
89
+ id="{id}-delete"
90
+ aria-label="Remove"
91
+ aria-labelledby="{id}-delete {id}-label"
92
+ class={cn(
93
+ "mr-0.5 inline-flex shrink-0 items-center justify-center rounded-full transition hover:bg-current/10",
94
+ removeSize,
95
+ focusRing,
96
+ "rounded-full",
50
97
  )}
51
98
  onclick={onDelete}
99
+ onkeydown={deleteOnKey}
52
100
  >
53
- <X size={12} />
101
+ <X size={iconSize} />
54
102
  </button>
55
103
  {/if}
56
104
  </Box>
@@ -1,3 +1,4 @@
1
+ import type { SizeProp } from "../base.js";
1
2
  import { type BoxProps } from "../box/index.js";
2
3
  import type { Snippet } from "svelte";
3
4
  export type ChipProps = {
@@ -5,7 +6,7 @@ export type ChipProps = {
5
6
  onClick?: (event: MouseEvent | KeyboardEvent) => void;
6
7
  onDelete?: (event: MouseEvent | KeyboardEvent) => void;
7
8
  children: Snippet;
8
- } & BoxProps;
9
+ } & SizeProp & BoxProps;
9
10
  declare const Chip: import("svelte").Component<ChipProps, {}, "el">;
10
11
  type Chip = ReturnType<typeof Chip>;
11
12
  export default Chip;
@@ -24,7 +24,6 @@ export class Action {
24
24
  }
25
25
  export class Registry {
26
26
  #actions = $state([]);
27
- #shortcuts = {};
28
27
  get actions() {
29
28
  return this.#actions;
30
29
  }
@@ -36,7 +35,7 @@ export class Registry {
36
35
  }
37
36
  }
38
37
  getByShortcut(shortcut) {
39
- return this.#shortcuts[shortcut.toString()];
38
+ return this.#actions.find((action) => action.shortcut?.equals(shortcut));
40
39
  }
41
40
  call(id) {
42
41
  const action = this.get(id);
@@ -46,31 +45,27 @@ export class Registry {
46
45
  action.callback();
47
46
  }
48
47
  register(...actions) {
49
- for (const action of actions) {
50
- untrack(() => {
51
- if (this.#actions.find((existing) => existing.id === action.id)) {
48
+ untrack(() => {
49
+ for (const action of actions) {
50
+ if (this.#actions.some((existing) => existing.id === action.id)) {
52
51
  throw new Error(`${action.id} is already registered`);
53
52
  }
54
- });
55
- if (action.shortcut) {
56
- if (action.shortcut.toString() in this.#shortcuts) {
53
+ if (action.shortcut && this.getByShortcut(action.shortcut)) {
57
54
  throw new Error(`${action.shortcut} is already registered`);
58
55
  }
59
- this.#shortcuts[action.shortcut.toString()] = action;
60
56
  }
61
- }
62
- this.#actions.unshift(...actions);
57
+ this.#actions.unshift(...actions);
58
+ });
63
59
  return () => this.unregister(...actions);
64
60
  }
65
61
  unregister(...actions) {
66
- for (const action of actions) {
67
- const index = this.#actions.indexOf(action);
68
- if (index !== -1) {
69
- this.#actions.splice(index, 1);
70
- if (action.shortcut) {
71
- delete this.#shortcuts[action.shortcut.toString()];
62
+ untrack(() => {
63
+ for (const action of actions) {
64
+ const index = this.#actions.indexOf(action);
65
+ if (index !== -1) {
66
+ this.#actions.splice(index, 1);
72
67
  }
73
68
  }
74
- }
69
+ });
75
70
  }
76
71
  }