@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
@@ -0,0 +1,54 @@
1
+ export declare const profileRowVariants: import("tailwind-variants").TVReturnType<{
2
+ interactive: {
3
+ true: string;
4
+ false: string;
5
+ };
6
+ }, undefined, "flex h-12 w-full min-w-0 items-center gap-2 rounded-lg p-2 text-start transition-colors duration-fast focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-sidebar-ring focus-visible:ring-offset-2 focus-visible:ring-offset-sidebar", {
7
+ responsiveVariants?: boolean | (string | number | symbol)[] | {
8
+ interactive?: boolean | (string | number | symbol)[] | undefined;
9
+ } | undefined;
10
+ } & import("tailwind-variants/dist/config.js").TWMConfig & {
11
+ twMergeConfig: {
12
+ classGroups: {
13
+ "font-size": {
14
+ text: ("display-hero" | "heading-page" | "heading-section" | "body" | "body-medium" | "body-large" | "caption" | "caption-medium" | "label" | "label-small" | "code")[];
15
+ }[];
16
+ };
17
+ };
18
+ }, {
19
+ interactive: {
20
+ true: string;
21
+ false: string;
22
+ };
23
+ }, undefined, import("tailwind-variants").TVReturnType<{
24
+ interactive: {
25
+ true: string;
26
+ false: string;
27
+ };
28
+ }, undefined, "flex h-12 w-full min-w-0 items-center gap-2 rounded-lg p-2 text-start transition-colors duration-fast focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-sidebar-ring focus-visible:ring-offset-2 focus-visible:ring-offset-sidebar", import("tailwind-variants/dist/config.js").TVConfig<{
29
+ interactive: {
30
+ true: string;
31
+ false: string;
32
+ };
33
+ }, {
34
+ interactive: {
35
+ true: string;
36
+ false: string;
37
+ };
38
+ }>, unknown, unknown, undefined>>;
39
+ export type ProfileRowVisualState = 'default' | 'hover' | 'focus';
40
+ import type { HTMLAttributes } from 'svelte/elements';
41
+ import type { Snippet } from 'svelte';
42
+ type $$ComponentProps = HTMLAttributes<HTMLElement> & {
43
+ title: string;
44
+ subtitle?: string;
45
+ showSubtitle?: boolean;
46
+ showTrailingIcon?: boolean;
47
+ name?: string;
48
+ src?: string;
49
+ visualState?: ProfileRowVisualState;
50
+ menu?: Snippet;
51
+ };
52
+ declare const ProfileRow: import("svelte").Component<$$ComponentProps, {}, "">;
53
+ type ProfileRow = ReturnType<typeof ProfileRow>;
54
+ export default ProfileRow;
@@ -0,0 +1,118 @@
1
+ <!--
2
+ Figma: Settings Dialog (component set 107:618, page Settings Dialog)
3
+ -->
4
+ <script lang="ts" module>
5
+ export type SettingsDialogProps = {
6
+ open?: boolean;
7
+ class?: string;
8
+ title: string;
9
+ description?: string;
10
+ activeId: string;
11
+ groups: import('./settings-nav-types.js').SettingsNavGroup[];
12
+ onSelect?: (id: string) => void;
13
+ closeLabel?: string;
14
+ messages?: import('./messages.js').SettingsDialogMessages;
15
+ privacyHref?: string;
16
+ termsHref?: string;
17
+ cookieHref?: string;
18
+ children: import('svelte').Snippet;
19
+ descriptionSlot?: import('svelte').Snippet;
20
+ };
21
+ </script>
22
+
23
+ <script lang="ts">
24
+ import { Dialog as DialogPrimitive } from 'bits-ui';
25
+ import IconX from '@tabler/icons-svelte/icons/x';
26
+ import type { Snippet } from 'svelte';
27
+ import * as Dialog from '../ui/dialog/index.js';
28
+ import { cn } from '../../utils.js';
29
+ import SettingsNav from './SettingsNav.svelte';
30
+ import { defaultSettingsDialogMessages, type SettingsDialogMessages } from './messages.js';
31
+ import type { SettingsNavGroup } from './settings-nav-types.js';
32
+
33
+ let {
34
+ open = $bindable(false),
35
+ class: className,
36
+ title,
37
+ description = undefined,
38
+ activeId,
39
+ groups,
40
+ onSelect,
41
+ closeLabel = 'Close',
42
+ messages = defaultSettingsDialogMessages,
43
+ privacyHref = '#',
44
+ termsHref = '#',
45
+ cookieHref = '#',
46
+ children,
47
+ descriptionSlot
48
+ }: SettingsDialogProps = $props();
49
+ </script>
50
+
51
+ <Dialog.Root bind:open>
52
+ <Dialog.Portal>
53
+ <Dialog.Overlay class="bg-foreground/50 backdrop-blur-sm" />
54
+ <DialogPrimitive.Content
55
+ class={cn(
56
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 border-border bg-background duration-base fixed z-50 flex overflow-hidden border',
57
+ 'inset-0 h-full max-h-none w-full rounded-none',
58
+ 'lg:h-settings-modal lg:w-settings-modal lg:rounded-panel lg:start-1/2 lg:top-1/2 lg:max-h-[calc(100vh-2rem)] lg:max-w-[calc(100vw-2rem)] lg:-translate-x-1/2 lg:-translate-y-1/2',
59
+ className
60
+ )}
61
+ aria-describedby={description || descriptionSlot ? 'settings-dialog-description' : undefined}
62
+ >
63
+ <div class="flex min-h-0 min-w-0 flex-1 flex-col lg:flex-row">
64
+ <aside
65
+ class="border-border bg-sidebar flex w-full shrink-0 flex-col border-b p-3 lg:w-64 lg:border-e lg:border-b-0"
66
+ >
67
+ <SettingsNav {groups} {activeId} {onSelect} class="flex-1" />
68
+ <div class="mt-auto flex flex-col gap-1 px-2 pt-4 pb-1">
69
+ <a
70
+ href={privacyHref}
71
+ class="text-caption text-muted-foreground duration-fast hover:text-foreground w-fit transition-colors"
72
+ >{messages.privacyPolicy}</a
73
+ >
74
+ <a
75
+ href={termsHref}
76
+ class="text-caption text-muted-foreground duration-fast hover:text-foreground w-fit transition-colors"
77
+ >{messages.termsOfService}</a
78
+ >
79
+ <a
80
+ href={cookieHref}
81
+ class="text-caption text-muted-foreground duration-fast hover:text-foreground w-fit transition-colors"
82
+ >{messages.cookieSettings}</a
83
+ >
84
+ </div>
85
+ </aside>
86
+ <div class="flex min-h-0 min-w-0 flex-1 flex-col gap-6 overflow-y-auto p-8">
87
+ <header class="flex flex-col gap-1 pe-10">
88
+ <DialogPrimitive.Title class="text-heading-page text-foreground"
89
+ >{title}</DialogPrimitive.Title
90
+ >
91
+ {#if descriptionSlot}
92
+ <DialogPrimitive.Description
93
+ id="settings-dialog-description"
94
+ class="text-body text-muted-foreground"
95
+ >
96
+ {@render descriptionSlot()}
97
+ </DialogPrimitive.Description>
98
+ {:else if description}
99
+ <DialogPrimitive.Description
100
+ id="settings-dialog-description"
101
+ class="text-body text-muted-foreground"
102
+ >
103
+ {description}
104
+ </DialogPrimitive.Description>
105
+ {/if}
106
+ </header>
107
+ <div class="flex min-h-0 flex-1 flex-col gap-6">{@render children()}</div>
108
+ </div>
109
+ </div>
110
+ <DialogPrimitive.Close
111
+ class="text-foreground hover:bg-accent duration-fast focus-visible:ring-ring focus-visible:ring-offset-background absolute end-4 top-4 inline-flex size-8 items-center justify-center rounded-lg transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden"
112
+ >
113
+ <IconX class="size-4 stroke-[1.333]" aria-hidden="true" />
114
+ <span class="sr-only">{closeLabel}</span>
115
+ </DialogPrimitive.Close>
116
+ </DialogPrimitive.Content>
117
+ </Dialog.Portal>
118
+ </Dialog.Root>
@@ -0,0 +1,19 @@
1
+ export type SettingsDialogProps = {
2
+ open?: boolean;
3
+ class?: string;
4
+ title: string;
5
+ description?: string;
6
+ activeId: string;
7
+ groups: import('./settings-nav-types.js').SettingsNavGroup[];
8
+ onSelect?: (id: string) => void;
9
+ closeLabel?: string;
10
+ messages?: import('./messages.js').SettingsDialogMessages;
11
+ privacyHref?: string;
12
+ termsHref?: string;
13
+ cookieHref?: string;
14
+ children: import('svelte').Snippet;
15
+ descriptionSlot?: import('svelte').Snippet;
16
+ };
17
+ declare const SettingsDialog: import("svelte").Component<SettingsDialogProps, {}, "open">;
18
+ type SettingsDialog = ReturnType<typeof SettingsDialog>;
19
+ export default SettingsDialog;
@@ -0,0 +1,46 @@
1
+ <!--
2
+ Figma: Settings Nav (component set 106:467, page Settings Dialog)
3
+ -->
4
+ <script lang="ts" module>
5
+ import type { HTMLAttributes } from 'svelte/elements';
6
+ import type { SettingsNavGroup } from './settings-nav-types.js';
7
+
8
+ export type SettingsNavProps = HTMLAttributes<HTMLElement> & {
9
+ class?: string;
10
+ groups: SettingsNavGroup[];
11
+ activeId: string;
12
+ onSelect?: (id: string) => void;
13
+ };
14
+ </script>
15
+
16
+ <script lang="ts">
17
+ import { cn } from '../../utils.js';
18
+ import NavRow from './NavRow.svelte';
19
+ import NavSectionLabel from './NavSectionLabel.svelte';
20
+ import { settingsNavItemIsActive } from './settings-nav-types.js';
21
+
22
+ let { class: className, groups, activeId, onSelect, ...restProps }: SettingsNavProps = $props();
23
+ </script>
24
+
25
+ <nav class={cn('flex w-full flex-col gap-0.5', className)} aria-label="Settings" {...restProps}>
26
+ {#each groups as group (group.id)}
27
+ <div class="flex flex-col gap-0.5">
28
+ <NavSectionLabel label={group.label} />
29
+ {#each group.items as item (item.id)}
30
+ {@const active = settingsNavItemIsActive(activeId, item.id)}
31
+ <NavRow
32
+ label={item.label}
33
+ {active}
34
+ showIcon={Boolean(item.icon)}
35
+ onclick={() => onSelect?.(item.id)}
36
+ >
37
+ {#snippet icon()}
38
+ {#if item.icon}
39
+ {@render item.icon()}
40
+ {/if}
41
+ {/snippet}
42
+ </NavRow>
43
+ {/each}
44
+ </div>
45
+ {/each}
46
+ </nav>
@@ -0,0 +1,11 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import type { SettingsNavGroup } from './settings-nav-types.js';
3
+ export type SettingsNavProps = HTMLAttributes<HTMLElement> & {
4
+ class?: string;
5
+ groups: SettingsNavGroup[];
6
+ activeId: string;
7
+ onSelect?: (id: string) => void;
8
+ };
9
+ declare const SettingsNav: import("svelte").Component<SettingsNavProps, {}, "">;
10
+ type SettingsNav = ReturnType<typeof SettingsNav>;
11
+ export default SettingsNav;
@@ -0,0 +1,82 @@
1
+ <!-- Figma: Sidebar (component set 53:33, node 53:33). -->
2
+ <script lang="ts">
3
+ import type { Icon } from '@tabler/icons-svelte';
4
+ import type { HTMLAttributes } from 'svelte/elements';
5
+ import type { Snippet } from 'svelte';
6
+ import { cn } from '../../utils.js';
7
+ import NavRow from './NavRow.svelte';
8
+
9
+ export type SidebarNavItem = {
10
+ id: string;
11
+ label: string;
12
+ /** Custom icon markup (advanced). */
13
+ icon?: Snippet;
14
+ /** Tabler icon component (preferred for standard nav icons). */
15
+ iconComponent?: Icon;
16
+ href?: string;
17
+ count?: string | number;
18
+ disabled?: boolean;
19
+ };
20
+
21
+ let {
22
+ class: className,
23
+ activeId = undefined,
24
+ items = undefined,
25
+ onNavigate,
26
+ header,
27
+ nav,
28
+ footer,
29
+ ...restProps
30
+ }: HTMLAttributes<HTMLElement> & {
31
+ activeId?: string;
32
+ items?: SidebarNavItem[];
33
+ onNavigate?: (id: string) => void;
34
+ header?: Snippet;
35
+ nav?: Snippet;
36
+ footer?: Snippet;
37
+ } = $props();
38
+
39
+ function handleItemClick(id: string, href?: string) {
40
+ if (href) return;
41
+ onNavigate?.(id);
42
+ }
43
+ </script>
44
+
45
+ <aside
46
+ class={cn(
47
+ 'w-sidebar bg-sidebar text-sidebar-foreground flex h-full shrink-0 flex-col gap-0.5 p-3',
48
+ className
49
+ )}
50
+ {...restProps}
51
+ >
52
+ {#if header}
53
+ <div class="mb-0 shrink-0">{@render header()}</div>
54
+ {/if}
55
+
56
+ {#if items?.length}
57
+ <nav class="flex min-h-0 flex-1 flex-col gap-0.5" aria-label="Main">
58
+ {#each items as item (item.id)}
59
+ <NavRow
60
+ label={item.label}
61
+ href={item.href}
62
+ active={activeId === item.id}
63
+ disabled={item.disabled}
64
+ showIcon={Boolean(item.icon) || Boolean(item.iconComponent)}
65
+ showTrailing={item.count !== undefined && item.count !== null && item.count !== ''}
66
+ trailing={item.count != null ? String(item.count) : ''}
67
+ icon={item.icon}
68
+ iconComponent={item.iconComponent}
69
+ onclick={item.href ? undefined : () => handleItemClick(item.id, item.href)}
70
+ />
71
+ {/each}
72
+ </nav>
73
+ {:else if nav}
74
+ <nav class="flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto" aria-label="Main">
75
+ {@render nav()}
76
+ </nav>
77
+ {/if}
78
+
79
+ {#if footer}
80
+ <div class="mt-auto shrink-0 pt-2">{@render footer()}</div>
81
+ {/if}
82
+ </aside>
@@ -0,0 +1,25 @@
1
+ import type { Icon } from '@tabler/icons-svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { Snippet } from 'svelte';
4
+ export type SidebarNavItem = {
5
+ id: string;
6
+ label: string;
7
+ /** Custom icon markup (advanced). */
8
+ icon?: Snippet;
9
+ /** Tabler icon component (preferred for standard nav icons). */
10
+ iconComponent?: Icon;
11
+ href?: string;
12
+ count?: string | number;
13
+ disabled?: boolean;
14
+ };
15
+ type $$ComponentProps = HTMLAttributes<HTMLElement> & {
16
+ activeId?: string;
17
+ items?: SidebarNavItem[];
18
+ onNavigate?: (id: string) => void;
19
+ header?: Snippet;
20
+ nav?: Snippet;
21
+ footer?: Snippet;
22
+ };
23
+ declare const Sidebar: import("svelte").Component<$$ComponentProps, {}, "">;
24
+ type Sidebar = ReturnType<typeof Sidebar>;
25
+ export default Sidebar;
@@ -0,0 +1,63 @@
1
+ <!--
2
+ Figma: Stat (component set 327:243, page Experiments)
3
+ -->
4
+ <script lang="ts" module>
5
+ import type { HTMLAttributes } from 'svelte/elements';
6
+ import type { Snippet } from 'svelte';
7
+ import { type StatTone, statHintClass } from './stat-tone.js';
8
+
9
+ export const statVariants = tv({
10
+ base: 'flex flex-col gap-0.5 rounded-xl border border-border bg-background p-4',
11
+ variants: {
12
+ tone: {
13
+ default: '',
14
+ positive: '',
15
+ negative: ''
16
+ }
17
+ },
18
+ defaultVariants: {
19
+ tone: 'default'
20
+ }
21
+ });
22
+
23
+ export type StatProps = HTMLAttributes<HTMLDivElement> & {
24
+ class?: string;
25
+ label: string;
26
+ value: string;
27
+ hint?: string;
28
+ delta?: string;
29
+ tone?: StatTone;
30
+ trendIcon?: Snippet;
31
+ };
32
+ </script>
33
+
34
+ <script lang="ts">
35
+ import { cn, tv } from '../../utils.js';
36
+
37
+ let {
38
+ class: className,
39
+ label,
40
+ value,
41
+ hint = undefined,
42
+ delta = undefined,
43
+ tone = 'default',
44
+ trendIcon,
45
+ ...restProps
46
+ }: StatProps = $props();
47
+
48
+ const hintLine = $derived(delta ?? hint);
49
+ const hintClass = $derived(statHintClass(tone));
50
+ </script>
51
+
52
+ <div class={cn(statVariants({ tone }), className)} {...restProps}>
53
+ <p class="text-caption-medium text-muted-foreground">{label}</p>
54
+ <p class="text-heading-page text-foreground">{value}</p>
55
+ {#if hintLine}
56
+ <p class={cn('text-caption flex items-center gap-1', hintClass)}>
57
+ {#if trendIcon}
58
+ <span class="inline-flex shrink-0 items-center">{@render trendIcon()}</span>
59
+ {/if}
60
+ <span>{hintLine}</span>
61
+ </p>
62
+ {/if}
63
+ </div>
@@ -0,0 +1,58 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import type { Snippet } from 'svelte';
3
+ import { type StatTone } from './stat-tone.js';
4
+ export declare const statVariants: import("tailwind-variants").TVReturnType<{
5
+ tone: {
6
+ default: string;
7
+ positive: string;
8
+ negative: string;
9
+ };
10
+ }, undefined, "flex flex-col gap-0.5 rounded-xl border border-border bg-background p-4", {
11
+ responsiveVariants?: boolean | (string | number | symbol)[] | {
12
+ tone?: 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
+ };
21
+ };
22
+ }, {
23
+ tone: {
24
+ default: string;
25
+ positive: string;
26
+ negative: string;
27
+ };
28
+ }, undefined, import("tailwind-variants").TVReturnType<{
29
+ tone: {
30
+ default: string;
31
+ positive: string;
32
+ negative: string;
33
+ };
34
+ }, undefined, "flex flex-col gap-0.5 rounded-xl border border-border bg-background p-4", import("tailwind-variants/dist/config.js").TVConfig<{
35
+ tone: {
36
+ default: string;
37
+ positive: string;
38
+ negative: string;
39
+ };
40
+ }, {
41
+ tone: {
42
+ default: string;
43
+ positive: string;
44
+ negative: string;
45
+ };
46
+ }>, unknown, unknown, undefined>>;
47
+ export type StatProps = HTMLAttributes<HTMLDivElement> & {
48
+ class?: string;
49
+ label: string;
50
+ value: string;
51
+ hint?: string;
52
+ delta?: string;
53
+ tone?: StatTone;
54
+ trendIcon?: Snippet;
55
+ };
56
+ declare const Stat: import("svelte").Component<StatProps, {}, "">;
57
+ type Stat = ReturnType<typeof Stat>;
58
+ export default Stat;
@@ -0,0 +1,37 @@
1
+ <!-- Figma: Top Bar (component set 142:2, node 142:2). -->
2
+ <script lang="ts">
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { Snippet } from 'svelte';
5
+ import IconMenu2 from '@tabler/icons-svelte/icons/menu-2';
6
+ import { cn } from '../../utils.js';
7
+ import { IconButton } from '../ui/icon-button/index.js';
8
+
9
+ let {
10
+ class: className,
11
+ title,
12
+ menuLabel = 'Open navigation',
13
+ onMenuClick,
14
+ action,
15
+ ...restProps
16
+ }: HTMLAttributes<HTMLElement> & {
17
+ title: string;
18
+ menuLabel?: string;
19
+ onMenuClick?: () => void;
20
+ action?: Snippet;
21
+ } = $props();
22
+ </script>
23
+
24
+ <header
25
+ class={cn('bg-sidebar flex h-14 w-full shrink-0 items-center gap-2 px-3 lg:hidden', className)}
26
+ {...restProps}
27
+ >
28
+ <IconButton variant="ghost" label={menuLabel} onclick={onMenuClick}>
29
+ <IconMenu2 />
30
+ </IconButton>
31
+ <h1 class="text-heading-section text-foreground min-w-0 flex-1 truncate">{title}</h1>
32
+ {#if action}
33
+ <div class="shrink-0">{@render action()}</div>
34
+ {:else}
35
+ <span class="size-8 shrink-0" aria-hidden="true"></span>
36
+ {/if}
37
+ </header>
@@ -0,0 +1,11 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import type { Snippet } from 'svelte';
3
+ type $$ComponentProps = HTMLAttributes<HTMLElement> & {
4
+ title: string;
5
+ menuLabel?: string;
6
+ onMenuClick?: () => void;
7
+ action?: Snippet;
8
+ };
9
+ declare const TopBar: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type TopBar = ReturnType<typeof TopBar>;
11
+ export default TopBar;
@@ -0,0 +1,126 @@
1
+ <!-- Figma: Widget Row (component set 54:5, node 54:5). -->
2
+ <script lang="ts" module>
3
+ import type { VariantProps } from 'tailwind-variants';
4
+
5
+ export const widgetRowVariants = tv({
6
+ base: 'group/widget-row flex min-h-16 w-full max-w-content items-center gap-4 rounded-xl py-3 ps-4 pe-4 transition-colors duration-fast focus-within:outline-hidden',
7
+ variants: {
8
+ selected: {
9
+ true: 'bg-brand-subtle ring-2 ring-brand',
10
+ false:
11
+ 'hover:bg-accent focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background'
12
+ },
13
+ loading: {
14
+ true: 'pointer-events-none',
15
+ false: ''
16
+ }
17
+ },
18
+ defaultVariants: {
19
+ selected: false,
20
+ loading: false
21
+ }
22
+ });
23
+
24
+ export type WidgetRowVisualState = 'default' | 'hover' | 'focus' | 'selected' | 'loading';
25
+ </script>
26
+
27
+ <script lang="ts">
28
+ import type { HTMLAttributes } from 'svelte/elements';
29
+ import type { Snippet } from 'svelte';
30
+ import { cn, tv } from '../../utils.js';
31
+ import { Badge } from '../ui/badge/index.js';
32
+ import { Skeleton } from '../ui/skeleton/index.js';
33
+
34
+ let {
35
+ class: className,
36
+ title,
37
+ meta = '',
38
+ showBadge = true,
39
+ badgeLabel = 'Published',
40
+ selected = false,
41
+ loading = false,
42
+ visualState = undefined,
43
+ actionsAlwaysVisible = false,
44
+ thumbnail,
45
+ actions,
46
+ ...restProps
47
+ }: HTMLAttributes<HTMLDivElement> & {
48
+ title: string;
49
+ meta?: string;
50
+ showBadge?: boolean;
51
+ badgeLabel?: string;
52
+ selected?: boolean;
53
+ loading?: boolean;
54
+ visualState?: WidgetRowVisualState;
55
+ /** Touch / mobile: keep row actions visible without hover. */
56
+ actionsAlwaysVisible?: boolean;
57
+ thumbnail?: Snippet;
58
+ actions?: Snippet;
59
+ } = $props();
60
+
61
+ const isLoading = $derived(loading || visualState === 'loading');
62
+ const isSelected = $derived(selected || visualState === 'selected');
63
+ const forceHover = $derived(visualState === 'hover');
64
+ const forceFocus = $derived(visualState === 'focus');
65
+ </script>
66
+
67
+ {#if isLoading}
68
+ <div
69
+ class={cn(
70
+ 'max-w-content flex min-h-16 w-full items-center gap-4 rounded-xl py-3 ps-4 pe-4',
71
+ className
72
+ )}
73
+ role="status"
74
+ aria-busy="true"
75
+ >
76
+ <Skeleton class="size-10 shrink-0 rounded-lg" />
77
+ <div class="flex min-w-0 flex-1 flex-col gap-2">
78
+ <Skeleton class="h-5 w-3/5 max-w-xs" />
79
+ <Skeleton class="h-4 w-2/5 max-w-[12rem]" />
80
+ </div>
81
+ <Skeleton class="h-5 w-20 rounded-full" />
82
+ </div>
83
+ {:else}
84
+ <div
85
+ class={cn(
86
+ widgetRowVariants({ selected: isSelected }),
87
+ forceHover && !isSelected && 'bg-accent',
88
+ forceFocus && !isSelected && 'ring-ring ring-offset-background ring-2 ring-offset-2',
89
+ className
90
+ )}
91
+ {...restProps}
92
+ >
93
+ <div
94
+ class={cn(
95
+ 'bg-muted duration-fast group-hover/widget-row:bg-background flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-lg transition-colors',
96
+ forceHover && 'bg-background'
97
+ )}
98
+ >
99
+ {#if thumbnail}
100
+ {@render thumbnail()}
101
+ {/if}
102
+ </div>
103
+
104
+ <div class="min-w-0 flex-1 flex-col gap-0 overflow-hidden">
105
+ <span class="text-body-medium text-foreground block truncate">{title}</span>
106
+ {#if meta}
107
+ <span class="text-caption text-muted-foreground block truncate">{meta}</span>
108
+ {/if}
109
+ </div>
110
+
111
+ {#if showBadge}
112
+ <Badge variant="secondary" showDot class="shrink-0 max-sm:hidden">{badgeLabel}</Badge>
113
+ {/if}
114
+
115
+ {#if actions}
116
+ <div
117
+ class={cn(
118
+ 'duration-fast shrink-0 opacity-0 transition-opacity group-focus-within/widget-row:opacity-100 group-hover/widget-row:opacity-100',
119
+ (actionsAlwaysVisible || forceHover || forceFocus) && 'opacity-100'
120
+ )}
121
+ >
122
+ {@render actions()}
123
+ </div>
124
+ {/if}
125
+ </div>
126
+ {/if}