@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
@@ -1,134 +1,132 @@
1
1
  <script lang="ts">
2
- import { onMount } from 'svelte';
3
- // import { browser } from '$app/environment';
4
- const browser = typeof window !== 'undefined';
5
- import { fade } from 'svelte/transition';
6
-
7
-
8
- export let src: string;
9
- export let alt: string = '';
10
- export let thumbhash: string;
11
- export let class_ = '';
12
- export let style = '';
13
- export let roundedCorners = 'rounded-medium';
14
- export let onLoad: (() => void) | undefined = undefined;
2
+ import { onMount } from 'svelte';
3
+ // import { browser } from '$app/environment';
4
+ const browser = typeof window !== 'undefined';
5
+ import { fade } from 'svelte/transition';
15
6
 
16
- let imageLoaded = false;
17
- let imageElement: HTMLImageElement;
18
- let base64Hash: string;
19
- let shouldShowThumbhash = true;
20
- let thumbHashVisible = false;
21
-
22
- // Debug logs
23
- let showLogs = false;
7
+ export let src: string;
8
+ export let alt: string = '';
9
+ export let thumbhash: string;
10
+ export let class_ = '';
11
+ export let style = '';
12
+ export let roundedCorners = 'rounded-card';
13
+ export let onLoad: (() => void) | undefined = undefined;
24
14
 
15
+ let imageLoaded = false;
16
+ let imageElement: HTMLImageElement;
17
+ let base64Hash: string;
18
+ let shouldShowThumbhash = true;
19
+ let thumbHashVisible = false;
25
20
 
26
- /***
27
- * METHODS
28
- **/
21
+ // Debug logs
22
+ let showLogs = false;
29
23
 
30
- // Convert hex string to base64
31
- function hexToBase64(hexstring: string | null | undefined): string {
32
- if (!hexstring || typeof hexstring !== 'string') return '';
24
+ /***
25
+ * METHODS
26
+ **/
33
27
 
34
- // if (showLogs) console.log('ThumbHashImage: Converting hash to base64', {
35
- // input: hexstring,
36
- // src,
37
- // alt
38
- // });
39
-
40
- try {
41
- const hex = hexstring.replace(/\s+/g, '');
42
- if (hex.length === 0 || hex.length % 2 !== 0) return '';
43
- const bytes = new Uint8Array(hex.length / 2);
44
- for (let i = 0; i < hex.length; i += 2) {
45
- bytes[i/2] = parseInt(hex.substring(i, i + 2), 16);
46
- }
47
- const result = btoa(String.fromCharCode.apply(null, Array.from(bytes)));
48
- // if (showLogs) console.log('ThumbHashImage: Base64 conversion result', { result });
49
- return result;
50
- } catch (error) {
51
- console.error('ThumbHashImage: Error converting hex to base64:', error);
52
- return '';
53
- }
54
- }
28
+ // Convert hex string to base64
29
+ function hexToBase64(hexstring: string | null | undefined): string {
30
+ if (!hexstring || typeof hexstring !== 'string') return '';
55
31
 
56
- $: {
57
- // if (showLogs) console.log('ThumbHashImage: Props updated', {
58
- // src,
59
- // alt,
60
- // thumbhash,
61
- // shouldShowThumbhash,
62
- // browser,
63
- // imageLoaded,
64
- // 'customElements.get("thumb-hash")': browser ? customElements.get('thumb-hash') : undefined
65
- // });
66
- base64Hash = hexToBase64(thumbhash);
67
- }
32
+ // if (showLogs) console.log('ThumbHashImage: Converting hash to base64', {
33
+ // input: hexstring,
34
+ // src,
35
+ // alt
36
+ // });
68
37
 
69
- onMount(async () => {
70
- // if (showLogs) console.log('ThumbHashImage: Component mounted', {
71
- // browser,
72
- // 'customElements.get("thumb-hash")': browser ? customElements.get('thumb-hash') : undefined
73
- // });
38
+ try {
39
+ const hex = hexstring.replace(/\s+/g, '');
40
+ if (hex.length === 0 || hex.length % 2 !== 0) return '';
41
+ const bytes = new Uint8Array(hex.length / 2);
42
+ for (let i = 0; i < hex.length; i += 2) {
43
+ bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
44
+ }
45
+ const result = btoa(String.fromCharCode.apply(null, Array.from(bytes)));
46
+ // if (showLogs) console.log('ThumbHashImage: Base64 conversion result', { result });
47
+ return result;
48
+ } catch (error) {
49
+ console.error('ThumbHashImage: Error converting hex to base64:', error);
50
+ return '';
51
+ }
52
+ }
74
53
 
75
- if (browser && !customElements.get('thumb-hash')) {
76
- // if (showLogs) console.log('ThumbHashImage: Initializing ThumbHashElement');
77
- try {
78
- const { ThumbHashElement } = await import('@hirasso/thumbhash-custom-element');
79
- ThumbHashElement.init();
80
- // if (showLogs) console.log('ThumbHashImage: ThumbHashElement initialized successfully');
81
- } catch (error) {
82
- if (showLogs) console.error('ThumbHashImage: Failed to initialize ThumbHashElement', error);
83
- }
84
- }
54
+ $: {
55
+ // if (showLogs) console.log('ThumbHashImage: Props updated', {
56
+ // src,
57
+ // alt,
58
+ // thumbhash,
59
+ // shouldShowThumbhash,
60
+ // browser,
61
+ // imageLoaded,
62
+ // 'customElements.get("thumb-hash")': browser ? customElements.get('thumb-hash') : undefined
63
+ // });
64
+ base64Hash = hexToBase64(thumbhash);
65
+ }
85
66
 
86
- // Check if image is already cached
87
- if (imageElement?.complete) {
88
- // if (showLogs) console.log('ThumbHashImage: Image already cached');
89
- imageLoaded = true;
90
- shouldShowThumbhash = false;
91
- if (onLoad) onLoad();
92
- } else {
93
- // Trigger thumbhash fade in
94
- setTimeout(() => {
95
- thumbHashVisible = true;
96
- }, 50);
97
- }
98
- });
67
+ onMount(async () => {
68
+ // if (showLogs) console.log('ThumbHashImage: Component mounted', {
69
+ // browser,
70
+ // 'customElements.get("thumb-hash")': browser ? customElements.get('thumb-hash') : undefined
71
+ // });
99
72
 
100
- function handleImageLoad() {
101
- // if (showLogs) console.log('ThumbHashImage: Image loaded', { src });
102
- imageLoaded = true;
103
- // Delay removal of thumbhash so that the image fades in over it
104
- setTimeout(() => {
105
- shouldShowThumbhash = false;
106
- }, 600);
107
- if (onLoad) onLoad();
108
- }
73
+ if (browser && !customElements.get('thumb-hash')) {
74
+ // if (showLogs) console.log('ThumbHashImage: Initializing ThumbHashElement');
75
+ try {
76
+ const { ThumbHashElement } = await import('@hirasso/thumbhash-custom-element');
77
+ ThumbHashElement.init();
78
+ // if (showLogs) console.log('ThumbHashImage: ThumbHashElement initialized successfully');
79
+ } catch (error) {
80
+ if (showLogs) console.error('ThumbHashImage: Failed to initialize ThumbHashElement', error);
81
+ }
82
+ }
83
+
84
+ // Check if image is already cached
85
+ if (imageElement?.complete) {
86
+ // if (showLogs) console.log('ThumbHashImage: Image already cached');
87
+ imageLoaded = true;
88
+ shouldShowThumbhash = false;
89
+ if (onLoad) onLoad();
90
+ } else {
91
+ // Trigger thumbhash fade in
92
+ setTimeout(() => {
93
+ thumbHashVisible = true;
94
+ }, 50);
95
+ }
96
+ });
97
+
98
+ function handleImageLoad() {
99
+ // if (showLogs) console.log('ThumbHashImage: Image loaded', { src });
100
+ imageLoaded = true;
101
+ // Delay removal of thumbhash so that the image fades in over it
102
+ setTimeout(() => {
103
+ shouldShowThumbhash = false;
104
+ }, 600);
105
+ if (onLoad) onLoad();
106
+ }
109
107
  </script>
110
108
 
111
109
  <div class="relative overflow-hidden {roundedCorners} {class_}" {style}>
112
- {#if shouldShowThumbhash && browser}
113
- <div class="absolute inset-0">
114
- <thumb-hash
115
- value={base64Hash}
116
- class="block w-full h-full transition-opacity duration-300"
117
- style="object-fit: cover; opacity: {thumbHashVisible ? 1 : 0}"
118
- class:opacity-0={imageLoaded}
119
- ></thumb-hash>
120
- </div>
121
- {/if}
110
+ {#if shouldShowThumbhash && browser}
111
+ <div class="absolute inset-0">
112
+ <thumb-hash
113
+ value={base64Hash}
114
+ class="block h-full w-full transition-opacity duration-300"
115
+ style="object-fit: cover; opacity: {thumbHashVisible ? 1 : 0}"
116
+ class:opacity-0={imageLoaded}
117
+ ></thumb-hash>
118
+ </div>
119
+ {/if}
122
120
 
123
- <img
124
- bind:this={imageElement}
125
- {src}
126
- {alt}
127
- loading="lazy"
128
- decoding="async"
129
- class="w-full h-full object-cover transition-opacity duration-300"
130
- class:opacity-0={!imageLoaded}
131
- class:opacity-100={imageLoaded}
132
- on:load={handleImageLoad}
133
- />
134
- </div>
121
+ <img
122
+ bind:this={imageElement}
123
+ {src}
124
+ {alt}
125
+ loading="lazy"
126
+ decoding="async"
127
+ class="h-full w-full object-cover transition-opacity duration-300"
128
+ class:opacity-0={!imageLoaded}
129
+ class:opacity-100={imageLoaded}
130
+ on:load={handleImageLoad}
131
+ />
132
+ </div>
@@ -1,47 +1,53 @@
1
1
  <script lang="ts">
2
- import { ScrollArea } from './ui/scroll-area';
3
-
4
- // COMPONENT PROPS
5
- let className = '';
6
- export { className as class };
7
- export let style: string = '';
8
- // Viewport Class
9
- export let viewPortClass: string = '';
10
- // Content Padding
11
- // export let contentPadding: number = 0;
12
- // Orientation
13
- export let orientation: 'horizontal' | 'vertical' = 'vertical';
14
- // Scrollbar Y Classes
15
- export let scrollOutside: boolean = false;
16
- export let scrollbarWidth = 16; // Default width of the scrollbar in pixels
17
- export let scrollbarYClasses = '';
18
- export let scrollHideDelay = 0;
19
- export let type : any = 'hover';
20
- //
21
- export let element: HTMLElement | null = null;
2
+ import { ScrollArea } from './ui/scroll-area';
22
3
 
4
+ // COMPONENT PROPS
5
+ let className = '';
6
+ export { className as class };
7
+ export let style: string = '';
8
+ // Viewport Class
9
+ export let viewPortClass: string = '';
10
+ // Content Padding
11
+ // export let contentPadding: number = 0;
12
+ // Orientation
13
+ export let orientation: 'horizontal' | 'vertical' = 'vertical';
14
+ // Scrollbar Y Classes
15
+ export let scrollOutside: boolean = false;
16
+ export let scrollbarWidth = 16; // Default width of the scrollbar in pixels
17
+ export let scrollbarYClasses = '';
18
+ export let scrollHideDelay = 0;
19
+ export let type: any = 'hover';
20
+ //
21
+ export let element: HTMLElement | null = null;
23
22
  </script>
24
23
 
25
24
  <!-- HTML Template -->
26
- <ScrollArea bind:ref={element}
27
- class={(className ? className + ' ' : '') + "scroll-area-container w-full h-full " +
28
- "widgetic-radius widgetic-colors select-text " +
29
- "**:!data-scroll-area-viewport:pe-(--scrollbar-width)"}
30
- style="{style} {scrollOutside ? `width: calc(100% + ${scrollbarWidth}px) !important;` : ''}
31
- --scrollbar-width: {scrollbarWidth}px; --scrollbar-padding: {scrollbarWidth/4}px; "
32
- {orientation}
33
- {type}
34
- {scrollHideDelay}
35
- scrollbarYClasses={scrollbarYClasses + "flex w-[var(--scrollbar-width)] !p-(--scrollbar-padding) " +
36
- "!bg-transparent border-none select-none touch-none " +
37
- "[&>div]:rounded-[var(--radius-pill)] [&>div]:cursor-pointer " +
38
- "[&>div]:bg-[hsl(var(--grey1))] hover:[&>div]:bg-[hsl(var(--grey2))] " +
39
- "[&>div]:transition-colors [&>div]:duration-250"}
40
- >
41
- <div class="actual-viewport {viewPortClass ? viewPortClass + ' ' : ''} absolute inset-0 z-[-1]" style="margin-inline-end: {scrollbarWidth}px;">
42
- <!-- <div class="viewport-inner absolute border border-red-500" style="inset: {contentPadding}px;"></div> -->
43
- </div>
44
- <slot/>
25
+ <ScrollArea
26
+ bind:ref={element}
27
+ class={'scroll-area-container h-full w-full ' +
28
+ 'widgetic-radius widgetic-colors select-text ' +
29
+ '**:!data-scroll-area-viewport:pe-(--scrollbar-width)' +
30
+ // The caller's classes come last: the class merge keeps the last of two that set the same thing (a caller's own
31
+ // height or width replaces the h-full and w-full above)
32
+ (className ? ' ' + className : '')}
33
+ style="{style} {scrollOutside ? `width: calc(100% + ${scrollbarWidth}px) !important;` : ''}
34
+ --scrollbar-width: {scrollbarWidth}px; --scrollbar-padding: {scrollbarWidth /
35
+ 4}px; "
36
+ {orientation}
37
+ {type}
38
+ {scrollHideDelay}
39
+ scrollbarYClasses={scrollbarYClasses +
40
+ 'flex w-[var(--scrollbar-width)] !p-(--scrollbar-padding) ' +
41
+ '!bg-transparent border-none select-none touch-none ' +
42
+ '[&>div]:rounded-full [&>div]:cursor-pointer ' +
43
+ '[&>div]:bg-muted-foreground/30 hover:[&>div]:bg-muted-foreground/50 ' +
44
+ '[&>div]:transition-colors [&>div]:duration-fast'}
45
+ >
46
+ <div
47
+ class="actual-viewport {viewPortClass ? viewPortClass + ' ' : ''} absolute inset-0 z-[-1]"
48
+ style="margin-inline-end: {scrollbarWidth}px;"
49
+ >
50
+ <!-- <div class="viewport-inner absolute border border-red-500" style="inset: {contentPadding}px;"></div> -->
51
+ </div>
52
+ <slot />
45
53
  </ScrollArea>
46
-
47
-
@@ -0,0 +1,115 @@
1
+ <!--
2
+ Figma: Activity Row (component set 67:87, node 67:87)
3
+ -->
4
+ <script lang="ts" module>
5
+ import type { Snippet } from 'svelte';
6
+ import type { HTMLAttributes } from 'svelte/elements';
7
+
8
+ export type ActivityRowStatus = 'pending' | 'running' | 'done' | 'failed';
9
+
10
+ export type ActivityRowProps = HTMLAttributes<HTMLDivElement> & {
11
+ ref?: HTMLDivElement | null;
12
+ class?: string;
13
+ label: string;
14
+ status?: ActivityRowStatus;
15
+ detail?: string;
16
+ expanded?: boolean;
17
+ expandLabel?: string;
18
+ collapseLabel?: string;
19
+ onToggle?: () => void;
20
+ detailContent?: Snippet;
21
+ };
22
+ </script>
23
+
24
+ <script lang="ts">
25
+ import IconChevronDown from '@tabler/icons-svelte/icons/chevron-down';
26
+ import IconChevronRight from '@tabler/icons-svelte/icons/chevron-right';
27
+ import IconCircle from '@tabler/icons-svelte/icons/circle';
28
+ import IconCircleCheck from '@tabler/icons-svelte/icons/circle-check';
29
+ import IconCircleX from '@tabler/icons-svelte/icons/circle-x';
30
+ import IconLoader2 from '@tabler/icons-svelte/icons/loader-2';
31
+ import { cn } from '../../utils.js';
32
+
33
+ let {
34
+ ref = $bindable(null),
35
+ class: className,
36
+ label,
37
+ status = 'pending',
38
+ detail,
39
+ expanded = false,
40
+ expandLabel = 'Show details',
41
+ collapseLabel = 'Hide details',
42
+ onToggle,
43
+ detailContent,
44
+ ...restProps
45
+ }: ActivityRowProps = $props();
46
+
47
+ const hasDetail = $derived(Boolean(detail || detailContent));
48
+ const toggleLabel = $derived(expanded ? collapseLabel : expandLabel);
49
+ </script>
50
+
51
+ <div
52
+ bind:this={ref}
53
+ class={cn('flex w-full max-w-[25.5rem] flex-col gap-1', className)}
54
+ {...restProps}
55
+ >
56
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
57
+ <svelte:element
58
+ this={hasDetail ? 'button' : 'div'}
59
+ type={hasDetail ? 'button' : undefined}
60
+ class={cn(
61
+ 'duration-fast focus-visible:ring-ring focus-visible:ring-offset-background flex w-full items-center gap-2 rounded-lg px-2 py-1 text-start transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',
62
+ hasDetail && 'hover:bg-accent'
63
+ )}
64
+ aria-expanded={hasDetail ? expanded : undefined}
65
+ aria-label={hasDetail ? toggleLabel : undefined}
66
+ onclick={() => {
67
+ if (hasDetail) onToggle?.();
68
+ }}
69
+ >
70
+ <span class="text-muted-foreground flex size-4 shrink-0 items-center justify-center">
71
+ {#if status === 'running'}
72
+ <IconLoader2
73
+ class="size-4 animate-spin stroke-[1.333] motion-reduce:animate-none"
74
+ aria-hidden="true"
75
+ />
76
+ {:else if status === 'done'}
77
+ <IconCircleCheck class="text-brand size-4 stroke-[1.333]" aria-hidden="true" />
78
+ {:else if status === 'failed'}
79
+ <IconCircleX class="text-destructive size-4 stroke-[1.333]" aria-hidden="true" />
80
+ {:else}
81
+ <IconCircle class="size-4 stroke-[1.333]" aria-hidden="true" />
82
+ {/if}
83
+ </span>
84
+ <span
85
+ class={cn(
86
+ 'text-body min-w-0 flex-1 truncate',
87
+ status === 'running' || status === 'done' ? 'text-foreground' : 'text-muted-foreground'
88
+ )}
89
+ >
90
+ {label}
91
+ </span>
92
+ {#if hasDetail}
93
+ {#if expanded}
94
+ <IconChevronDown
95
+ class="text-muted-foreground size-4 shrink-0 stroke-[1.333]"
96
+ aria-hidden="true"
97
+ />
98
+ {:else}
99
+ <IconChevronRight
100
+ class="text-muted-foreground size-4 shrink-0 stroke-[1.333] rtl:-scale-x-100"
101
+ aria-hidden="true"
102
+ />
103
+ {/if}
104
+ {/if}
105
+ </svelte:element>
106
+ {#if expanded && (detail || detailContent)}
107
+ <div class="text-caption text-muted-foreground ps-6 pe-2">
108
+ {#if detailContent}
109
+ {@render detailContent()}
110
+ {:else if detail}
111
+ {detail}
112
+ {/if}
113
+ </div>
114
+ {/if}
115
+ </div>
@@ -0,0 +1,18 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ export type ActivityRowStatus = 'pending' | 'running' | 'done' | 'failed';
4
+ export type ActivityRowProps = HTMLAttributes<HTMLDivElement> & {
5
+ ref?: HTMLDivElement | null;
6
+ class?: string;
7
+ label: string;
8
+ status?: ActivityRowStatus;
9
+ detail?: string;
10
+ expanded?: boolean;
11
+ expandLabel?: string;
12
+ collapseLabel?: string;
13
+ onToggle?: () => void;
14
+ detailContent?: Snippet;
15
+ };
16
+ declare const ActivityRow: import("svelte").Component<ActivityRowProps, {}, "ref">;
17
+ type ActivityRow = ReturnType<typeof ActivityRow>;
18
+ export default ActivityRow;
@@ -0,0 +1,114 @@
1
+ <!--
2
+ Figma: Chat Header (component set 69:26, page Chat Header)
3
+ -->
4
+ <script lang="ts">
5
+ import type { HTMLAttributes } from 'svelte/elements';
6
+ import IconChevronDown from '@tabler/icons-svelte/icons/chevron-down';
7
+ import IconMessagePlus from '@tabler/icons-svelte/icons/message-plus';
8
+ import IconMessages from '@tabler/icons-svelte/icons/messages';
9
+ import IconPin from '@tabler/icons-svelte/icons/pin';
10
+ import IconX from '@tabler/icons-svelte/icons/x';
11
+ import { Button } from '../ui/button';
12
+ import { IconButton } from '../ui/icon-button';
13
+ import { cn } from '../../utils.js';
14
+
15
+ export type ChatHeaderLayout = 'panel' | 'fullscreen';
16
+
17
+ export type ChatHeaderMessages = {
18
+ newChat: string;
19
+ history: string;
20
+ pin: string;
21
+ close: string;
22
+ openHistory: string;
23
+ };
24
+
25
+ const defaultMessages: ChatHeaderMessages = {
26
+ newChat: 'New chat',
27
+ history: 'Chat history',
28
+ pin: 'Pin chat',
29
+ close: 'Close chat',
30
+ openHistory: 'Open chat history'
31
+ };
32
+
33
+ type Props = HTMLAttributes<HTMLElement> & {
34
+ ref?: HTMLElement | null;
35
+ class?: string;
36
+ layout?: ChatHeaderLayout;
37
+ title?: string;
38
+ status?: string;
39
+ showClose?: boolean;
40
+ messages?: Partial<ChatHeaderMessages>;
41
+ onTitleClick?: () => void;
42
+ onNewChat?: () => void;
43
+ onHistory?: () => void;
44
+ onPin?: () => void;
45
+ onClose?: () => void;
46
+ };
47
+
48
+ let {
49
+ ref = $bindable(null),
50
+ class: className,
51
+ layout = 'panel',
52
+ title,
53
+ status,
54
+ showClose = false,
55
+ messages: messagesProp,
56
+ onTitleClick,
57
+ onNewChat,
58
+ onHistory,
59
+ onPin,
60
+ onClose,
61
+ ...restProps
62
+ }: Props = $props();
63
+
64
+ const messages = $derived({ ...defaultMessages, ...messagesProp });
65
+ const displayTitle = $derived(title?.trim() || messages.newChat);
66
+ </script>
67
+
68
+ <header
69
+ bind:this={ref}
70
+ class={cn(
71
+ 'flex h-14 shrink-0 items-center gap-1 px-3',
72
+ layout === 'panel' && 'w-chat-panel max-w-full',
73
+ layout === 'fullscreen' && 'max-w-content w-full',
74
+ className
75
+ )}
76
+ {...restProps}
77
+ >
78
+ <Button
79
+ variant="ghost"
80
+ size="sm"
81
+ class="max-w-[min(100%,14rem)] shrink-0 gap-1 px-2"
82
+ onclick={onTitleClick}
83
+ aria-label={messages.openHistory}
84
+ >
85
+ <span class="truncate">{displayTitle}</span>
86
+ <IconChevronDown class="size-4 shrink-0 stroke-[1.333]" aria-hidden="true" />
87
+ </Button>
88
+
89
+ {#if status}
90
+ <span class="text-caption text-muted-foreground hidden shrink-0 sm:inline">{status}</span>
91
+ {/if}
92
+
93
+ <span class="min-w-0 flex-1" aria-hidden="true"></span>
94
+
95
+ <IconButton variant="ghost" label={messages.pin} onclick={onPin}>
96
+ <IconPin class="stroke-[1.333]" />
97
+ </IconButton>
98
+
99
+ <IconButton variant="ghost" label={messages.newChat} onclick={onNewChat}>
100
+ <IconMessagePlus class="stroke-[1.333]" />
101
+ </IconButton>
102
+
103
+ {#if onHistory}
104
+ <IconButton variant="ghost" label={messages.history} onclick={onHistory}>
105
+ <IconMessages class="stroke-[1.333]" />
106
+ </IconButton>
107
+ {/if}
108
+
109
+ {#if showClose}
110
+ <IconButton variant="ghost" label={messages.close} onclick={onClose}>
111
+ <IconX class="stroke-[1.333]" />
112
+ </IconButton>
113
+ {/if}
114
+ </header>
@@ -0,0 +1,26 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ export type ChatHeaderLayout = 'panel' | 'fullscreen';
3
+ export type ChatHeaderMessages = {
4
+ newChat: string;
5
+ history: string;
6
+ pin: string;
7
+ close: string;
8
+ openHistory: string;
9
+ };
10
+ type Props = HTMLAttributes<HTMLElement> & {
11
+ ref?: HTMLElement | null;
12
+ class?: string;
13
+ layout?: ChatHeaderLayout;
14
+ title?: string;
15
+ status?: string;
16
+ showClose?: boolean;
17
+ messages?: Partial<ChatHeaderMessages>;
18
+ onTitleClick?: () => void;
19
+ onNewChat?: () => void;
20
+ onHistory?: () => void;
21
+ onPin?: () => void;
22
+ onClose?: () => void;
23
+ };
24
+ declare const ChatHeader: import("svelte").Component<Props, {}, "ref">;
25
+ type ChatHeader = ReturnType<typeof ChatHeader>;
26
+ export default ChatHeader;