@widgetic/design-system 0.5.22 → 0.5.23

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 (246) hide show
  1. package/README.md +2 -0
  2. package/dist/components/CopyableHeader.svelte +260 -448
  3. package/dist/components/CopyableHeader.svelte.d.ts +8 -5
  4. package/dist/components/EmptyState.svelte +100 -128
  5. package/dist/components/EmptyState.svelte.d.ts +16 -19
  6. package/dist/components/GenerateLoader.svelte +17 -10
  7. package/dist/components/PasswordInput.svelte +41 -44
  8. package/dist/components/PasswordInput.svelte.d.ts +2 -0
  9. package/dist/components/ThumbHashImage.svelte +117 -119
  10. package/dist/components/WScrollArea.svelte +47 -41
  11. package/dist/components/chat/ActivityRow.svelte +115 -0
  12. package/dist/components/chat/ActivityRow.svelte.d.ts +18 -0
  13. package/dist/components/chat/ChatHeader.svelte +114 -0
  14. package/dist/components/chat/ChatHeader.svelte.d.ts +26 -0
  15. package/dist/components/chat/Composer.svelte +172 -0
  16. package/dist/components/chat/Composer.svelte.d.ts +27 -0
  17. package/dist/components/chat/Message.svelte +158 -0
  18. package/dist/components/chat/Message.svelte.d.ts +28 -0
  19. package/dist/components/chat/OptionRow.svelte +59 -0
  20. package/dist/components/chat/OptionRow.svelte.d.ts +14 -0
  21. package/dist/components/chat/PlanCard.svelte +220 -0
  22. package/dist/components/chat/PlanCard.svelte.d.ts +34 -0
  23. package/dist/components/chat/QuestionCard.svelte +265 -0
  24. package/dist/components/chat/QuestionCard.svelte.d.ts +38 -0
  25. package/dist/components/chat/ScrollToBottom.svelte +51 -0
  26. package/dist/components/chat/ScrollToBottom.svelte.d.ts +11 -0
  27. package/dist/components/chat/SuggestionCard.svelte +79 -0
  28. package/dist/components/chat/SuggestionCard.svelte.d.ts +20 -0
  29. package/dist/components/chat/TaskRow.svelte +59 -0
  30. package/dist/components/chat/TaskRow.svelte.d.ts +11 -0
  31. package/dist/components/chat/composerLogic.d.ts +16 -0
  32. package/dist/components/chat/composerLogic.js +29 -0
  33. package/dist/components/chat/index.d.ts +16 -0
  34. package/dist/components/chat/index.js +16 -0
  35. package/dist/components/chat/questionCardLogic.d.ts +11 -0
  36. package/dist/components/chat/questionCardLogic.js +39 -0
  37. package/dist/components/index.d.ts +10 -1
  38. package/dist/components/index.js +10 -0
  39. package/dist/components/modals/ActionModal.svelte +186 -180
  40. package/dist/components/modals/BaseModal.svelte +402 -399
  41. package/dist/components/modals/BaseModal.svelte.d.ts +1 -0
  42. package/dist/components/modals/NewItemDialog.svelte +200 -243
  43. package/dist/components/modals/Portal.svelte +107 -105
  44. package/dist/components/modals/README.md +16 -2
  45. package/dist/components/modals/RenameDialog.svelte +234 -292
  46. package/dist/components/navigation/Breadcrumbs.svelte +415 -377
  47. package/dist/components/navigation/Breadcrumbs.svelte.d.ts +3 -2
  48. package/dist/components/navigation/types.d.ts +2 -0
  49. package/dist/components/pdf/PDFViewer.svelte +1 -1
  50. package/dist/components/search-input/SearchInput.svelte +51 -104
  51. package/dist/components/search-input/SearchInput.svelte.d.ts +9 -27
  52. package/dist/components/shad-editor/editor.css +1 -1
  53. package/dist/components/shad-editor/i18n/messages.d.ts +1 -1
  54. package/dist/components/shad-editor/i18n/messages.js +1 -1
  55. package/dist/components/shell/AppShell.svelte +52 -0
  56. package/dist/components/shell/AppShell.svelte.d.ts +13 -0
  57. package/dist/components/shell/Banner.svelte +90 -0
  58. package/dist/components/shell/Banner.svelte.d.ts +61 -0
  59. package/dist/components/shell/ErrorState.svelte +60 -0
  60. package/dist/components/shell/ErrorState.svelte.d.ts +13 -0
  61. package/dist/components/shell/Link.svelte +63 -0
  62. package/dist/components/shell/Link.svelte.d.ts +53 -0
  63. package/dist/components/shell/NavDrawer.svelte +117 -0
  64. package/dist/components/shell/NavDrawer.svelte.d.ts +10 -0
  65. package/dist/components/shell/NavRow.svelte +128 -0
  66. package/dist/components/shell/NavRow.svelte.d.ts +65 -0
  67. package/dist/components/shell/NavSectionLabel.svelte +27 -0
  68. package/dist/components/shell/NavSectionLabel.svelte.d.ts +9 -0
  69. package/dist/components/shell/NotificationRow.svelte +76 -0
  70. package/dist/components/shell/NotificationRow.svelte.d.ts +16 -0
  71. package/dist/components/shell/PageHeader.svelte +42 -0
  72. package/dist/components/shell/PageHeader.svelte.d.ts +12 -0
  73. package/dist/components/shell/ProfileRow.svelte +95 -0
  74. package/dist/components/shell/ProfileRow.svelte.d.ts +54 -0
  75. package/dist/components/shell/SettingsDialog.svelte +118 -0
  76. package/dist/components/shell/SettingsDialog.svelte.d.ts +19 -0
  77. package/dist/components/shell/SettingsNav.svelte +46 -0
  78. package/dist/components/shell/SettingsNav.svelte.d.ts +11 -0
  79. package/dist/components/shell/Sidebar.svelte +82 -0
  80. package/dist/components/shell/Sidebar.svelte.d.ts +25 -0
  81. package/dist/components/shell/Stat.svelte +63 -0
  82. package/dist/components/shell/Stat.svelte.d.ts +58 -0
  83. package/dist/components/shell/TopBar.svelte +37 -0
  84. package/dist/components/shell/TopBar.svelte.d.ts +11 -0
  85. package/dist/components/shell/WidgetRow.svelte +126 -0
  86. package/dist/components/shell/WidgetRow.svelte.d.ts +78 -0
  87. package/dist/components/shell/error-state-messages.d.ts +7 -0
  88. package/dist/components/shell/error-state-messages.js +9 -0
  89. package/dist/components/shell/index.d.ts +22 -0
  90. package/dist/components/shell/index.js +25 -0
  91. package/dist/components/shell/link-external.d.ts +2 -0
  92. package/dist/components/shell/link-external.js +7 -0
  93. package/dist/components/shell/messages.d.ts +7 -0
  94. package/dist/components/shell/messages.js +5 -0
  95. package/dist/components/shell/settings-nav-types.d.ts +12 -0
  96. package/dist/components/shell/settings-nav-types.js +3 -0
  97. package/dist/components/shell/shell-utils.d.ts +7 -0
  98. package/dist/components/shell/shell-utils.js +27 -0
  99. package/dist/components/shell/stat-tone.d.ts +3 -0
  100. package/dist/components/shell/stat-tone.js +11 -0
  101. package/dist/components/toast/ToasterModal.svelte +102 -168
  102. package/dist/components/toast/ToasterModal.svelte.d.ts +2 -12
  103. package/dist/components/ui/accordion/accordion-content.svelte +3 -2
  104. package/dist/components/ui/accordion/accordion-item.svelte +10 -1
  105. package/dist/components/ui/accordion/accordion-trigger.svelte +4 -3
  106. package/dist/components/ui/alert/alert-description.svelte +5 -1
  107. package/dist/components/ui/alert/alert-title.svelte +2 -1
  108. package/dist/components/ui/alert/index.d.ts +13 -11
  109. package/dist/components/ui/alert/index.js +4 -4
  110. package/dist/components/ui/avatar/avatar-utils.d.ts +2 -0
  111. package/dist/components/ui/avatar/avatar-utils.js +9 -0
  112. package/dist/components/ui/avatar/avatar.svelte +63 -0
  113. package/dist/components/ui/avatar/avatar.svelte.d.ts +80 -0
  114. package/dist/components/ui/avatar/index.d.ts +4 -0
  115. package/dist/components/ui/avatar/index.js +4 -0
  116. package/dist/components/ui/badge/badge.svelte +22 -10
  117. package/dist/components/ui/badge/badge.svelte.d.ts +14 -15
  118. package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +2 -2
  119. package/dist/components/ui/breadcrumb/breadcrumb-link.svelte +1 -1
  120. package/dist/components/ui/breadcrumb/breadcrumb-page.svelte +1 -1
  121. package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte +2 -2
  122. package/dist/components/ui/button/button-padding.d.ts +9 -0
  123. package/dist/components/ui/button/button-padding.js +15 -0
  124. package/dist/components/ui/button/button.svelte +81 -31
  125. package/dist/components/ui/button/button.svelte.d.ts +48 -29
  126. package/dist/components/ui/calendar/calendar-cell.svelte +1 -1
  127. package/dist/components/ui/calendar/calendar-head-cell.svelte +1 -1
  128. package/dist/components/ui/calendar/calendar-next-button.svelte +2 -2
  129. package/dist/components/ui/calendar/calendar-prev-button.svelte +2 -2
  130. package/dist/components/ui/card/card-description.svelte +1 -1
  131. package/dist/components/ui/card/card-title.svelte +1 -1
  132. package/dist/components/ui/card/card.svelte +1 -1
  133. package/dist/components/ui/checkbox/checkbox.svelte +9 -5
  134. package/dist/components/ui/chip/chip.svelte +48 -0
  135. package/dist/components/ui/chip/chip.svelte.d.ts +13 -0
  136. package/dist/components/ui/chip/index.d.ts +2 -0
  137. package/dist/components/ui/chip/index.js +2 -0
  138. package/dist/components/ui/command/command-dialog.svelte +1 -1
  139. package/dist/components/ui/command/command-input.svelte +4 -4
  140. package/dist/components/ui/command/command-item.svelte +1 -1
  141. package/dist/components/ui/command/command.svelte +1 -1
  142. package/dist/components/ui/dialog/dialog-content.svelte +4 -4
  143. package/dist/components/ui/dialog/dialog-description.svelte +1 -1
  144. package/dist/components/ui/dialog/dialog-overlay.svelte +1 -1
  145. package/dist/components/ui/dialog/dialog-title.svelte +1 -1
  146. package/dist/components/ui/drawer/drawer-content.svelte +1 -1
  147. package/dist/components/ui/drawer/drawer-overlay.svelte +1 -1
  148. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +5 -5
  149. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +1 -1
  150. package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +1 -1
  151. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +20 -2
  152. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +4 -0
  153. package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +5 -1
  154. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +3 -3
  155. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +2 -1
  156. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +1 -1
  157. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +3 -3
  158. package/dist/components/ui/field/field-ids.d.ts +7 -0
  159. package/dist/components/ui/field/field-ids.js +15 -0
  160. package/dist/components/ui/field/field.svelte +62 -0
  161. package/dist/components/ui/field/field.svelte.d.ts +21 -0
  162. package/dist/components/ui/field/index.d.ts +3 -0
  163. package/dist/components/ui/field/index.js +3 -0
  164. package/dist/components/ui/hover-card/hover-card-content.svelte +1 -1
  165. package/dist/components/ui/icon-button/icon-button.svelte +72 -0
  166. package/dist/components/ui/icon-button/icon-button.svelte.d.ts +90 -0
  167. package/dist/components/ui/icon-button/index.d.ts +2 -0
  168. package/dist/components/ui/icon-button/index.js +4 -0
  169. package/dist/components/ui/input/index.d.ts +1 -0
  170. package/dist/components/ui/input/input.svelte +11 -4
  171. package/dist/components/ui/input/input.svelte.d.ts +4 -1
  172. package/dist/components/ui/input-otp/input-otp-separator.svelte +2 -2
  173. package/dist/components/ui/input-otp/input-otp-slot.svelte +5 -4
  174. package/dist/components/ui/input-otp/input-otp-slot.svelte.d.ts +1 -1
  175. package/dist/components/ui/input-otp/input-otp.svelte +1 -1
  176. package/dist/components/ui/label/label.svelte +3 -2
  177. package/dist/components/ui/popover/popover-content.svelte +1 -1
  178. package/dist/components/ui/progress/progress.svelte +19 -5
  179. package/dist/components/ui/progress/progress.svelte.d.ts +4 -2
  180. package/dist/components/ui/radio-group/radio-group-item.svelte +4 -4
  181. package/dist/components/ui/range-calendar/range-calendar-head-cell.svelte +1 -1
  182. package/dist/components/ui/range-calendar/range-calendar-next-button.svelte +2 -2
  183. package/dist/components/ui/range-calendar/range-calendar-prev-button.svelte +2 -2
  184. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +4 -1
  185. package/dist/components/ui/scroll-area/scroll-area.svelte +1 -1
  186. package/dist/components/ui/select/select-content.svelte +1 -3
  187. package/dist/components/ui/select/select-item.svelte +5 -4
  188. package/dist/components/ui/select/select-scroll-down-button.svelte +2 -2
  189. package/dist/components/ui/select/select-scroll-up-button.svelte +2 -2
  190. package/dist/components/ui/select/select-trigger.svelte +4 -3
  191. package/dist/components/ui/skeleton/index.d.ts +2 -0
  192. package/dist/components/ui/skeleton/index.js +2 -0
  193. package/dist/components/ui/skeleton/skeleton.svelte +24 -0
  194. package/dist/components/ui/skeleton/skeleton.svelte.d.ts +8 -0
  195. package/dist/components/ui/slider/slider.svelte +5 -10
  196. package/dist/components/ui/sonner/sonner.svelte +19 -13
  197. package/dist/components/ui/stepper-button/index.d.ts +3 -0
  198. package/dist/components/ui/stepper-button/index.js +2 -0
  199. package/dist/components/ui/stepper-button/stepper-button.svelte +37 -0
  200. package/dist/components/ui/stepper-button/stepper-button.svelte.d.ts +9 -0
  201. package/dist/components/ui/switch/switch.svelte +8 -3
  202. package/dist/components/ui/table/table-cell.svelte +1 -1
  203. package/dist/components/ui/table/table-head.svelte +1 -1
  204. package/dist/components/ui/table/table-row.svelte +1 -1
  205. package/dist/components/ui/tabs/tabs-list.svelte +1 -1
  206. package/dist/components/ui/tabs/tabs-trigger.svelte +1 -1
  207. package/dist/components/ui/tag/index.d.ts +2 -0
  208. package/dist/components/ui/tag/index.js +2 -0
  209. package/dist/components/ui/tag/tag.svelte +42 -0
  210. package/dist/components/ui/tag/tag.svelte.d.ts +11 -0
  211. package/dist/components/ui/textarea/textarea.svelte +4 -3
  212. package/dist/components/ui/textarea/textarea.svelte.d.ts +2 -2
  213. package/dist/components/ui/toggle/toggle.svelte +9 -9
  214. package/dist/components/ui/toggle/toggle.svelte.d.ts +14 -21
  215. package/dist/components/ui/tooltip/tooltip-content.svelte +1 -1
  216. package/dist/fonts/Inter/Inter-Black.woff2 +0 -0
  217. package/dist/fonts/Inter/Inter-BlackItalic.woff2 +0 -0
  218. package/dist/fonts/Inter/Inter-Bold.woff2 +0 -0
  219. package/dist/fonts/Inter/Inter-BoldItalic.woff2 +0 -0
  220. package/dist/fonts/Inter/Inter-ExtraBold.woff2 +0 -0
  221. package/dist/fonts/Inter/Inter-ExtraBoldItalic.woff2 +0 -0
  222. package/dist/fonts/Inter/Inter-ExtraLight-BETA.woff2 +0 -0
  223. package/dist/fonts/Inter/Inter-ExtraLightItalic-BETA.woff2 +0 -0
  224. package/dist/fonts/Inter/Inter-Italic.woff2 +0 -0
  225. package/dist/fonts/Inter/Inter-Light-BETA.woff2 +0 -0
  226. package/dist/fonts/Inter/Inter-LightItalic-BETA.woff2 +0 -0
  227. package/dist/fonts/Inter/Inter-Medium.woff2 +0 -0
  228. package/dist/fonts/Inter/Inter-MediumItalic.woff2 +0 -0
  229. package/dist/fonts/Inter/Inter-Regular.woff2 +0 -0
  230. package/dist/fonts/Inter/Inter-SemiBold.woff2 +0 -0
  231. package/dist/fonts/Inter/Inter-SemiBoldItalic.woff2 +0 -0
  232. package/dist/fonts/Inter/Inter-Thin-BETA.woff2 +0 -0
  233. package/dist/fonts/Inter/Inter-ThinItalic-BETA.woff2 +0 -0
  234. package/dist/fonts/Inter/Inter-italic.var.woff2 +0 -0
  235. package/dist/fonts/Inter/Inter-upright.var.woff2 +0 -0
  236. package/dist/fonts/Inter/Inter.var.woff2 +0 -0
  237. package/dist/fonts/JetBrainsMono/JetBrainsMono-Regular.woff2 +0 -0
  238. package/dist/i18n/audit/designSystemWords.d.ts +1 -1
  239. package/dist/i18n/audit/designSystemWords.js +1 -1
  240. package/dist/styles/fonts.css +18 -14
  241. package/dist/styles/global.css +7 -19
  242. package/dist/styles/tokens.css +332 -0
  243. package/dist/utils.d.ts +27 -0
  244. package/dist/utils.js +33 -2
  245. package/package.json +2 -1
  246. package/tailwind.config.ts +7 -47
@@ -14,7 +14,8 @@
14
14
 
15
15
  <svelte:element
16
16
  this={level}
17
- class={cn("mb-1 font-medium leading-none tracking-tight", className)}
17
+ data-slot="alert-title"
18
+ class={cn("text-body-medium", className)}
18
19
  {...$$restProps}
19
20
  >
20
21
  <slot />
@@ -1,4 +1,4 @@
1
- import { type VariantProps } from "tailwind-variants";
1
+ import type { VariantProps } from "tailwind-variants";
2
2
  import Root from "./alert.svelte";
3
3
  import Description from "./alert-description.svelte";
4
4
  import Title from "./alert-title.svelte";
@@ -7,27 +7,29 @@ export declare const alertVariants: import("tailwind-variants").TVReturnType<{
7
7
  default: string;
8
8
  destructive: string;
9
9
  };
10
- }, undefined, "[&>svg]:text-foreground relative w-full rounded-lg border p-4 [&:has(svg)]:ps-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:start-4 [&>svg]:top-4", import("tailwind-variants/dist/config.js").TVConfig<{
11
- variant: {
12
- default: string;
13
- destructive: string;
10
+ }, undefined, "relative grid w-full grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 rounded-xl border border-border bg-background p-3 pe-4 ps-4 text-foreground [&>svg]:col-start-1 [&>svg]:row-start-1 [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:stroke-[1.333] [&_[data-slot=alert-title]]:col-start-2 [&_[data-slot=alert-title]]:row-start-1 [&_[data-slot=alert-description]]:col-start-2 [&_[data-slot=alert-description]]:row-start-2", {
11
+ responsiveVariants?: boolean | (string | number | symbol)[] | {
12
+ variant?: boolean | (string | number | symbol)[] | undefined;
13
+ } | undefined;
14
+ } & import("tailwind-variants/dist/config.js").TWMConfig & {
15
+ twMergeConfig: {
16
+ classGroups: {
17
+ "font-size": {
18
+ text: ("display-hero" | "heading-page" | "heading-section" | "body" | "body-medium" | "body-large" | "caption" | "caption-medium" | "label" | "label-small" | "code")[];
19
+ }[];
20
+ };
14
21
  };
15
22
  }, {
16
23
  variant: {
17
24
  default: string;
18
25
  destructive: string;
19
26
  };
20
- }>, {
21
- variant: {
22
- default: string;
23
- destructive: string;
24
- };
25
27
  }, undefined, import("tailwind-variants").TVReturnType<{
26
28
  variant: {
27
29
  default: string;
28
30
  destructive: string;
29
31
  };
30
- }, undefined, "[&>svg]:text-foreground relative w-full rounded-lg border p-4 [&:has(svg)]:ps-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:start-4 [&>svg]:top-4", import("tailwind-variants/dist/config.js").TVConfig<{
32
+ }, undefined, "relative grid w-full grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 rounded-xl border border-border bg-background p-3 pe-4 ps-4 text-foreground [&>svg]:col-start-1 [&>svg]:row-start-1 [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:stroke-[1.333] [&_[data-slot=alert-title]]:col-start-2 [&_[data-slot=alert-title]]:row-start-1 [&_[data-slot=alert-description]]:col-start-2 [&_[data-slot=alert-description]]:row-start-2", import("tailwind-variants/dist/config.js").TVConfig<{
31
33
  variant: {
32
34
  default: string;
33
35
  destructive: string;
@@ -1,13 +1,13 @@
1
- import { tv } from "tailwind-variants";
1
+ import { tv } from "../../../utils.js";
2
2
  import Root from "./alert.svelte";
3
3
  import Description from "./alert-description.svelte";
4
4
  import Title from "./alert-title.svelte";
5
5
  export const alertVariants = tv({
6
- base: "[&>svg]:text-foreground relative w-full rounded-lg border p-4 [&:has(svg)]:ps-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:start-4 [&>svg]:top-4",
6
+ base: "relative grid w-full grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 rounded-xl border border-border bg-background p-3 pe-4 ps-4 text-foreground [&>svg]:col-start-1 [&>svg]:row-start-1 [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:stroke-[1.333] [&_[data-slot=alert-title]]:col-start-2 [&_[data-slot=alert-title]]:row-start-1 [&_[data-slot=alert-description]]:col-start-2 [&_[data-slot=alert-description]]:row-start-2",
7
7
  variants: {
8
8
  variant: {
9
- default: "bg-background text-foreground",
10
- destructive: "border-destructive/50 text-destructive text-destructive dark:border-destructive [&>svg]:text-destructive",
9
+ default: "text-foreground [&>svg]:text-foreground",
10
+ destructive: "[&>svg]:text-destructive [&_[data-slot=alert-title]]:text-destructive [&_[data-slot=alert-description]]:text-destructive/90",
11
11
  },
12
12
  },
13
13
  defaultVariants: {
@@ -0,0 +1,2 @@
1
+ /** Derive one or two letter initials from a display name (Figma Avatar / Type=Initials). */
2
+ export declare function avatarInitials(name: string): string;
@@ -0,0 +1,9 @@
1
+ /** Derive one or two letter initials from a display name (Figma Avatar / Type=Initials). */
2
+ export function avatarInitials(name) {
3
+ const parts = name.trim().split(/\s+/).filter(Boolean);
4
+ if (parts.length === 0)
5
+ return "?";
6
+ if (parts.length === 1)
7
+ return parts[0].slice(0, 2).toUpperCase();
8
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
9
+ }
@@ -0,0 +1,63 @@
1
+ <!-- Figma: Avatar (component set 50:17, node 50:3). -->
2
+ <script lang="ts" module>
3
+ import type { VariantProps } from "tailwind-variants";
4
+
5
+ export const avatarVariants = tv({
6
+ base: "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-brand-subtle text-brand-foreground",
7
+ variants: {
8
+ size: {
9
+ sm: "size-6 text-caption-medium",
10
+ default: "size-8 text-caption-medium",
11
+ lg: "size-10 text-label-small",
12
+ },
13
+ type: {
14
+ initials: "bg-brand-subtle text-brand-foreground",
15
+ icon: "bg-muted text-foreground",
16
+ },
17
+ },
18
+ defaultVariants: {
19
+ size: "sm",
20
+ type: "initials",
21
+ },
22
+ });
23
+
24
+ export type AvatarSize = VariantProps<typeof avatarVariants>["size"];
25
+ export type AvatarType = VariantProps<typeof avatarVariants>["type"];
26
+ </script>
27
+
28
+ <script lang="ts">
29
+ import type { HTMLAttributes } from "svelte/elements";
30
+ import type { Snippet } from "svelte";
31
+ import { cn, tv } from "../../../utils.js";
32
+ import { avatarInitials } from "./avatar-utils.js";
33
+
34
+ let {
35
+ class: className,
36
+ size = "sm",
37
+ type = "initials",
38
+ src = undefined,
39
+ alt = "",
40
+ name = "",
41
+ icon,
42
+ ...restProps
43
+ }: HTMLAttributes<HTMLSpanElement> & {
44
+ size?: AvatarSize;
45
+ type?: AvatarType;
46
+ src?: string;
47
+ alt?: string;
48
+ name?: string;
49
+ icon?: Snippet;
50
+ } = $props();
51
+
52
+ const initials = $derived(avatarInitials(name || alt));
53
+ </script>
54
+
55
+ <span class={cn(avatarVariants({ size, type }), className)} {...restProps}>
56
+ {#if src}
57
+ <img {src} {alt} class="size-full object-cover" />
58
+ {:else if type === "icon" && icon}
59
+ <span class="flex items-center justify-center">{@render icon()}</span>
60
+ {:else}
61
+ <span aria-hidden="true">{initials}</span>
62
+ {/if}
63
+ </span>
@@ -0,0 +1,80 @@
1
+ import type { VariantProps } from "tailwind-variants";
2
+ export declare const avatarVariants: import("tailwind-variants").TVReturnType<{
3
+ size: {
4
+ sm: string;
5
+ default: string;
6
+ lg: string;
7
+ };
8
+ type: {
9
+ initials: string;
10
+ icon: string;
11
+ };
12
+ }, undefined, "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-brand-subtle text-brand-foreground", {
13
+ responsiveVariants?: boolean | (string | number | symbol)[] | {
14
+ size?: boolean | (string | number | symbol)[] | undefined;
15
+ type?: boolean | (string | number | symbol)[] | undefined;
16
+ } | undefined;
17
+ } & import("tailwind-variants/dist/config.js").TWMConfig & {
18
+ twMergeConfig: {
19
+ classGroups: {
20
+ "font-size": {
21
+ text: ("display-hero" | "heading-page" | "heading-section" | "body" | "body-medium" | "body-large" | "caption" | "caption-medium" | "label" | "label-small" | "code")[];
22
+ }[];
23
+ };
24
+ };
25
+ }, {
26
+ size: {
27
+ sm: string;
28
+ default: string;
29
+ lg: string;
30
+ };
31
+ type: {
32
+ initials: string;
33
+ icon: string;
34
+ };
35
+ }, undefined, import("tailwind-variants").TVReturnType<{
36
+ size: {
37
+ sm: string;
38
+ default: string;
39
+ lg: string;
40
+ };
41
+ type: {
42
+ initials: string;
43
+ icon: string;
44
+ };
45
+ }, undefined, "relative inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full bg-brand-subtle text-brand-foreground", import("tailwind-variants/dist/config.js").TVConfig<{
46
+ size: {
47
+ sm: string;
48
+ default: string;
49
+ lg: string;
50
+ };
51
+ type: {
52
+ initials: string;
53
+ icon: string;
54
+ };
55
+ }, {
56
+ size: {
57
+ sm: string;
58
+ default: string;
59
+ lg: string;
60
+ };
61
+ type: {
62
+ initials: string;
63
+ icon: string;
64
+ };
65
+ }>, unknown, unknown, undefined>>;
66
+ export type AvatarSize = VariantProps<typeof avatarVariants>["size"];
67
+ export type AvatarType = VariantProps<typeof avatarVariants>["type"];
68
+ import type { HTMLAttributes } from "svelte/elements";
69
+ import type { Snippet } from "svelte";
70
+ type $$ComponentProps = HTMLAttributes<HTMLSpanElement> & {
71
+ size?: AvatarSize;
72
+ type?: AvatarType;
73
+ src?: string;
74
+ alt?: string;
75
+ name?: string;
76
+ icon?: Snippet;
77
+ };
78
+ declare const Avatar: import("svelte").Component<$$ComponentProps, {}, "">;
79
+ type Avatar = ReturnType<typeof Avatar>;
80
+ export default Avatar;
@@ -0,0 +1,4 @@
1
+ import Root from "./avatar.svelte";
2
+ export { avatarInitials } from "./avatar-utils.js";
3
+ export { avatarVariants, type AvatarSize } from "./avatar.svelte";
4
+ export { Root, Root as Avatar };
@@ -0,0 +1,4 @@
1
+ import Root from "./avatar.svelte";
2
+ export { avatarInitials } from "./avatar-utils.js";
3
+ export { avatarVariants } from "./avatar.svelte";
4
+ export { Root, Root as Avatar };
@@ -1,17 +1,15 @@
1
+ <!-- Figma: Badge (component set 50:4, node 50:2). -->
1
2
  <script lang="ts" module>
2
- import { type VariantProps, tv } from "tailwind-variants";
3
+ import type { VariantProps } from "tailwind-variants";
3
4
 
4
5
  export const badgeVariants = tv({
5
- base: "focus:ring-ring inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-offset-2",
6
+ base: "inline-flex h-5 max-w-full items-center gap-1.5 rounded-full border border-transparent px-2 text-label-small focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
6
7
  variants: {
7
8
  variant: {
8
- default:
9
- "bg-primary text-primary-foreground hover:bg-primary/80 border-transparent",
10
- secondary:
11
- "bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent",
12
- destructive:
13
- "bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent",
14
- outline: "text-foreground",
9
+ default: "bg-secondary text-secondary-foreground",
10
+ secondary: "bg-brand-subtle text-brand-foreground",
11
+ destructive: "bg-destructive text-destructive-foreground",
12
+ outline: "border-border bg-transparent text-foreground",
15
13
  },
16
14
  },
17
15
  defaultVariants: {
@@ -25,17 +23,19 @@
25
23
  <script lang="ts">
26
24
  import type { WithElementRef } from "bits-ui";
27
25
  import type { HTMLAnchorAttributes } from "svelte/elements";
28
- import { cn } from "../../../utils.js";
26
+ import { cn, tv } from "../../../utils.js";
29
27
 
30
28
  let {
31
29
  ref = $bindable(null),
32
30
  href,
33
31
  class: className,
34
32
  variant = "default",
33
+ showDot = false,
35
34
  children,
36
35
  ...restProps
37
36
  }: WithElementRef<HTMLAnchorAttributes> & {
38
37
  variant?: BadgeVariant;
38
+ showDot?: boolean;
39
39
  } = $props();
40
40
  </script>
41
41
 
@@ -46,5 +46,17 @@
46
46
  class={cn(badgeVariants({ variant }), className)}
47
47
  {...restProps}
48
48
  >
49
+ {#if showDot}
50
+ <span
51
+ class={cn(
52
+ "size-1.5 shrink-0 rounded-full bg-current",
53
+ variant === "default" && "bg-secondary-foreground",
54
+ variant === "secondary" && "bg-brand-foreground",
55
+ variant === "destructive" && "bg-destructive-foreground",
56
+ variant === "outline" && "bg-foreground"
57
+ )}
58
+ aria-hidden="true"
59
+ ></span>
60
+ {/if}
49
61
  {@render children?.()}
50
62
  </svelte:element>
@@ -1,4 +1,4 @@
1
- import { type VariantProps } from "tailwind-variants";
1
+ import type { VariantProps } from "tailwind-variants";
2
2
  export declare const badgeVariants: import("tailwind-variants").TVReturnType<{
3
3
  variant: {
4
4
  default: string;
@@ -6,12 +6,17 @@ export declare const badgeVariants: import("tailwind-variants").TVReturnType<{
6
6
  destructive: string;
7
7
  outline: string;
8
8
  };
9
- }, undefined, "focus:ring-ring inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-offset-2", import("tailwind-variants/dist/config.js").TVConfig<{
10
- variant: {
11
- default: string;
12
- secondary: string;
13
- destructive: string;
14
- outline: string;
9
+ }, undefined, "inline-flex h-5 max-w-full items-center gap-1.5 rounded-full border border-transparent px-2 text-label-small focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", {
10
+ responsiveVariants?: boolean | (string | number | symbol)[] | {
11
+ variant?: boolean | (string | number | symbol)[] | undefined;
12
+ } | undefined;
13
+ } & import("tailwind-variants/dist/config.js").TWMConfig & {
14
+ twMergeConfig: {
15
+ classGroups: {
16
+ "font-size": {
17
+ text: ("display-hero" | "heading-page" | "heading-section" | "body" | "body-medium" | "body-large" | "caption" | "caption-medium" | "label" | "label-small" | "code")[];
18
+ }[];
19
+ };
15
20
  };
16
21
  }, {
17
22
  variant: {
@@ -20,13 +25,6 @@ export declare const badgeVariants: import("tailwind-variants").TVReturnType<{
20
25
  destructive: string;
21
26
  outline: string;
22
27
  };
23
- }>, {
24
- variant: {
25
- default: string;
26
- secondary: string;
27
- destructive: string;
28
- outline: string;
29
- };
30
28
  }, undefined, import("tailwind-variants").TVReturnType<{
31
29
  variant: {
32
30
  default: string;
@@ -34,7 +32,7 @@ export declare const badgeVariants: import("tailwind-variants").TVReturnType<{
34
32
  destructive: string;
35
33
  outline: string;
36
34
  };
37
- }, undefined, "focus:ring-ring inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-offset-2", import("tailwind-variants/dist/config.js").TVConfig<{
35
+ }, undefined, "inline-flex h-5 max-w-full items-center gap-1.5 rounded-full border border-transparent px-2 text-label-small focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", import("tailwind-variants/dist/config.js").TVConfig<{
38
36
  variant: {
39
37
  default: string;
40
38
  secondary: string;
@@ -54,6 +52,7 @@ import type { WithElementRef } from "bits-ui";
54
52
  import type { HTMLAnchorAttributes } from "svelte/elements";
55
53
  type $$ComponentProps = WithElementRef<HTMLAnchorAttributes> & {
56
54
  variant?: BadgeVariant;
55
+ showDot?: boolean;
57
56
  };
58
57
  declare const Badge: import("svelte").Component<$$ComponentProps, {}, "ref">;
59
58
  type Badge = ReturnType<typeof Badge>;
@@ -4,7 +4,7 @@
4
4
  </script>
5
5
 
6
6
  <script lang="ts">
7
- import Ellipsis from "lucide-svelte/icons/ellipsis";
7
+ import IconDots from "@tabler/icons-svelte/icons/dots";
8
8
  import type { WithElementRef, WithoutChildren } from "bits-ui";
9
9
  import type { HTMLAttributes } from "svelte/elements";
10
10
  import { cn } from "../../../utils.js";
@@ -23,6 +23,6 @@
23
23
  class={cn("flex size-9 items-center justify-center", className)}
24
24
  {...restProps}
25
25
  >
26
- <Ellipsis class="size-4" />
26
+ <IconDots class="size-4 stroke-[1.333]" />
27
27
  <span class="sr-only">More</span>
28
28
  </span>
@@ -16,7 +16,7 @@
16
16
  } = $props();
17
17
 
18
18
  const attrs = $derived({
19
- class: cn("hover:text-foreground transition-colors", className),
19
+ class: cn("text-caption-medium text-muted-foreground hover:text-foreground transition-colors duration-fast", className),
20
20
  href,
21
21
  ...restProps,
22
22
  });
@@ -21,7 +21,7 @@
21
21
  role="link"
22
22
  aria-disabled="true"
23
23
  aria-current="page"
24
- class={cn("text-foreground font-normal", className)}
24
+ class={cn("text-caption-medium text-foreground", className)}
25
25
  {...restProps}
26
26
  >
27
27
  {@render children?.()}
@@ -4,7 +4,7 @@
4
4
  </script>
5
5
 
6
6
  <script lang="ts">
7
- import ChevronRight from "lucide-svelte/icons/chevron-right";
7
+ import IconChevronRight from "@tabler/icons-svelte/icons/chevron-right";
8
8
  import type { WithElementRef } from "bits-ui";
9
9
  import type { HTMLLiAttributes } from "svelte/elements";
10
10
  import { cn } from "../../../utils.js";
@@ -27,6 +27,6 @@
27
27
  {#if children}
28
28
  {@render children?.()}
29
29
  {:else}
30
- <ChevronRight class="rtl:-scale-x-100" />
30
+ <IconChevronRight class="stroke-[1.333] rtl:-scale-x-100" />
31
31
  {/if}
32
32
  </li>
@@ -0,0 +1,9 @@
1
+ /**
2
+ * True when a `class` string sets the padding of a side: `p-0`, `px-2`, `ps-4`, `pr-1`, also with a modifier in front
3
+ * (`!px-3`, `md:px-2`, `[&_svg]:p-0`) or behind it (`px-3!`).
4
+ *
5
+ * The Button reads this to leave its icon rule out (Figma pads the icon side by 12 and the label side by 16, see the note
6
+ * at the top of `button.svelte`): a caller that has chosen the sides itself, like an icon-only button with `p-0`, would
7
+ * otherwise get one of them changed by a rule it knows nothing about.
8
+ */
9
+ export declare function classNameSetsPadding(className: string | null | undefined): boolean;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * True when a `class` string sets the padding of a side: `p-0`, `px-2`, `ps-4`, `pr-1`, also with a modifier in front
3
+ * (`!px-3`, `md:px-2`, `[&_svg]:p-0`) or behind it (`px-3!`).
4
+ *
5
+ * The Button reads this to leave its icon rule out (Figma pads the icon side by 12 and the label side by 16, see the note
6
+ * at the top of `button.svelte`): a caller that has chosen the sides itself, like an icon-only button with `p-0`, would
7
+ * otherwise get one of them changed by a rule it knows nothing about.
8
+ */
9
+ export function classNameSetsPadding(className) {
10
+ if (!className)
11
+ return false;
12
+ // The utility has to start a class name (`px-` in `placeholder-x` or `peer-x` is not a padding): at the start, after a
13
+ // space or after the `:` of a modifier. The hyphen after the letters is what tells `pl-` from `placeholder`.
14
+ return /(^|[\s:])!?-?(?:p|px|ps|pe|pl|pr)-/.test(className);
15
+ }
@@ -1,48 +1,102 @@
1
+ <!--
2
+ Figma: Button (component set 33:4, page Button); Button Small (33:215) maps to size `sm`.
3
+ Width: the button pads its sides by 12 (small: 8) and the label sits in a box with 4 more on each side, so a button with
4
+ only a label is the text + 32 wide (small: + 24). With an icon first it is the text + 48 (small: + 40): the icon touches
5
+ the 12 and the label keeps its 4 + 12 on the other side; with an icon at each end both sides are 12 (text + 64).
6
+ The 1px stroke of Outline and Stroke sits inside that padding and takes no room in Figma.
7
+ With bits-ui triggers (Dialog, DropdownMenu, Tooltip, …), use `{#snippet child({ props })}` and spread
8
+ `props` onto `<Button {...props}>` — do not wrap `<Button>` inside a default trigger (nested buttons).
9
+ -->
1
10
  <script lang="ts" module>
2
11
  import type { WithElementRef } from "bits-ui";
3
12
  import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
4
- import { type VariantProps, tv } from "tailwind-variants";
13
+ import type { VariantProps } from "tailwind-variants";
5
14
 
6
15
  export const buttonVariants = tv({
7
- base: "ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
16
+ base: "inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-lg text-label transition-colors duration-fast press-feedback focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:stroke-[1.333]",
8
17
  variants: {
9
18
  variant: {
10
19
  default: "bg-primary text-primary-foreground hover:bg-primary/90",
11
- destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
20
+ destructive:
21
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
12
22
  outline:
13
- "border-input bg-background hover:bg-accent hover:text-accent-foreground border",
14
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
15
- ghost: "hover:bg-accent hover:text-accent-foreground",
23
+ "border border-input bg-background text-foreground hover:bg-accent hover:text-foreground",
24
+ secondary:
25
+ "bg-secondary text-secondary-foreground hover:bg-accent hover:text-foreground",
26
+ ghost: "text-foreground hover:bg-accent hover:text-foreground",
27
+ accent: "bg-brand text-brand-foreground hover:bg-brand/90",
28
+ stroke:
29
+ "border border-border-strong/30 bg-transparent text-foreground hover:bg-accent hover:text-foreground",
16
30
  link: "text-primary underline-offset-4 hover:underline",
17
31
  },
18
32
  size: {
19
- default: "h-10 px-4 py-2",
20
- sm: "h-9 rounded-md px-3",
21
- lg: "h-11 rounded-md px-8",
22
- icon: "h-10 w-10",
33
+ // The 12 of the side (small: 8) and the 4 of the label box (see the note at the top), as Figma
34
+ default: "h-9 px-4",
35
+ sm: "h-8 px-3",
36
+ lg: "h-10 px-6",
37
+ icon: "h-9 w-9",
38
+ "icon-sm": "h-8 w-8",
39
+ },
40
+ // Switched on by the Button below and not by every caller of `buttonVariants` (a calendar cell or a menu trigger
41
+ // sets its own padding): an icon sits at the side with no label box, so that side is 12 (small: 8)
42
+ iconPadding: {
43
+ true: "",
44
+ false: "",
23
45
  },
24
46
  },
47
+ compoundVariants: [
48
+ // The first icon is taken as the leading one (CSS cannot tell a leading icon from a trailing one, text is no
49
+ // element); a second icon makes the other side 12 as well. Either way the width is the one Figma draws.
50
+ {
51
+ size: "default",
52
+ iconPadding: true,
53
+ class: "has-[>svg]:ps-3 has-[>svg:nth-of-type(2)]:pe-3",
54
+ },
55
+ {
56
+ size: "sm",
57
+ iconPadding: true,
58
+ class: "has-[>svg]:ps-2 has-[>svg:nth-of-type(2)]:pe-2",
59
+ },
60
+ // Figma draws the 1px stroke of Outline and Stroke inside the padding, a CSS border sits outside it: those two take
61
+ // 1px off every side, so that they are as wide as the other styles
62
+ { variant: ["outline", "stroke"], size: "default", class: "px-[15px]" },
63
+ { variant: ["outline", "stroke"], size: "sm", class: "px-[11px]" },
64
+ {
65
+ variant: ["outline", "stroke"],
66
+ size: "default",
67
+ iconPadding: true,
68
+ class: "has-[>svg]:ps-[11px] has-[>svg:nth-of-type(2)]:pe-[11px]",
69
+ },
70
+ {
71
+ variant: ["outline", "stroke"],
72
+ size: "sm",
73
+ iconPadding: true,
74
+ class: "has-[>svg]:ps-[7px] has-[>svg:nth-of-type(2)]:pe-[7px]",
75
+ },
76
+ ],
25
77
  defaultVariants: {
26
78
  variant: "default",
27
79
  size: "default",
80
+ iconPadding: false,
28
81
  },
29
82
  });
30
83
 
31
84
  export type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
32
85
  export type ButtonSize = VariantProps<typeof buttonVariants>["size"];
33
86
 
34
- export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
35
- WithElementRef<HTMLAnchorAttributes> & {
36
- ref?: any;
37
- href?: string;
38
- class?: string;
39
- variant?: ButtonVariant;
40
- size?: ButtonSize;
41
- };
87
+ export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
88
+ WithElementRef<HTMLAnchorAttributes> & {
89
+ ref?: any;
90
+ href?: string;
91
+ class?: string;
92
+ variant?: ButtonVariant;
93
+ size?: ButtonSize;
94
+ };
42
95
  </script>
43
96
 
44
97
  <script lang="ts">
45
- import { cn } from "../../../utils.js";
98
+ import { cn, tv } from "../../../utils.js";
99
+ import { classNameSetsPadding } from "./button-padding.js";
46
100
 
47
101
  let {
48
102
  class: className,
@@ -54,24 +108,20 @@
54
108
  children,
55
109
  ...restProps
56
110
  }: ButtonProps = $props();
111
+
112
+ // A caller that sets the padding itself (`p-0` on an icon-only button, `px-2`, `!px-3`, …) has chosen the sides: the rule
113
+ // for an icon would change one of them, so it stays off then
114
+ const classes = $derived(
115
+ cn(buttonVariants({ variant, size, iconPadding: !classNameSetsPadding(className), className })),
116
+ );
57
117
  </script>
58
118
 
59
119
  {#if href}
60
- <a
61
- bind:this={ref}
62
- class={cn(buttonVariants({ variant, size, className }))}
63
- {href}
64
- {...restProps}
65
- >
120
+ <a bind:this={ref} class={classes} {href} {...restProps}>
66
121
  {@render children?.()}
67
122
  </a>
68
123
  {:else}
69
- <button
70
- bind:this={ref}
71
- class={cn(buttonVariants({ variant, size, className }))}
72
- {type}
73
- {...restProps}
74
- >
124
+ <button bind:this={ref} class={classes} {type} {...restProps}>
75
125
  {@render children?.()}
76
126
  </button>
77
127
  {/if}