@delightstack/components 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +136 -0
  3. package/SKILL.md +149 -0
  4. package/bin/agents.js +63 -0
  5. package/dist/actions/Alert.svelte +202 -0
  6. package/dist/actions/Alert.svelte.d.ts +36 -0
  7. package/dist/actions/Alert.svelte.d.ts.map +1 -0
  8. package/dist/actions/Button.svelte +1450 -0
  9. package/dist/actions/Button.svelte.d.ts +56 -0
  10. package/dist/actions/Button.svelte.d.ts.map +1 -0
  11. package/dist/actions/ButtonGroup.svelte +111 -0
  12. package/dist/actions/ButtonGroup.svelte.d.ts +41 -0
  13. package/dist/actions/ButtonGroup.svelte.d.ts.map +1 -0
  14. package/dist/actions/CommandPalette.svelte +939 -0
  15. package/dist/actions/CommandPalette.svelte.d.ts +37 -0
  16. package/dist/actions/CommandPalette.svelte.d.ts.map +1 -0
  17. package/dist/actions/ContextMenu.svelte +138 -0
  18. package/dist/actions/ContextMenu.svelte.d.ts +54 -0
  19. package/dist/actions/ContextMenu.svelte.d.ts.map +1 -0
  20. package/dist/actions/Modal.svelte +474 -0
  21. package/dist/actions/Modal.svelte.d.ts +28 -0
  22. package/dist/actions/Modal.svelte.d.ts.map +1 -0
  23. package/dist/actions/Popover.svelte +1214 -0
  24. package/dist/actions/Popover.svelte.d.ts +31 -0
  25. package/dist/actions/Popover.svelte.d.ts.map +1 -0
  26. package/dist/actions/Portal.svelte +80 -0
  27. package/dist/actions/Portal.svelte.d.ts +17 -0
  28. package/dist/actions/Portal.svelte.d.ts.map +1 -0
  29. package/dist/actions/ThemeToggle.svelte +345 -0
  30. package/dist/actions/ThemeToggle.svelte.d.ts +15 -0
  31. package/dist/actions/ThemeToggle.svelte.d.ts.map +1 -0
  32. package/dist/actions/index.d.ts +13 -0
  33. package/dist/actions/index.d.ts.map +1 -0
  34. package/dist/actions/index.js +10 -0
  35. package/dist/actions/scrollbar.d.ts +48 -0
  36. package/dist/actions/scrollbar.d.ts.map +1 -0
  37. package/dist/actions/scrollbar.js +404 -0
  38. package/dist/display/Accordion.svelte +586 -0
  39. package/dist/display/Accordion.svelte.d.ts +41 -0
  40. package/dist/display/Accordion.svelte.d.ts.map +1 -0
  41. package/dist/display/Avatar.svelte +527 -0
  42. package/dist/display/Avatar.svelte.d.ts +22 -0
  43. package/dist/display/Avatar.svelte.d.ts.map +1 -0
  44. package/dist/display/AvatarGroup.svelte +298 -0
  45. package/dist/display/AvatarGroup.svelte.d.ts +31 -0
  46. package/dist/display/AvatarGroup.svelte.d.ts.map +1 -0
  47. package/dist/display/Calendar.svelte +1366 -0
  48. package/dist/display/Calendar.svelte.d.ts +58 -0
  49. package/dist/display/Calendar.svelte.d.ts.map +1 -0
  50. package/dist/display/Chart.svelte +1426 -0
  51. package/dist/display/Chart.svelte.d.ts +35 -0
  52. package/dist/display/Chart.svelte.d.ts.map +1 -0
  53. package/dist/display/Code.svelte +780 -0
  54. package/dist/display/Code.svelte.d.ts +19 -0
  55. package/dist/display/Code.svelte.d.ts.map +1 -0
  56. package/dist/display/Comparison.svelte +686 -0
  57. package/dist/display/Comparison.svelte.d.ts +22 -0
  58. package/dist/display/Comparison.svelte.d.ts.map +1 -0
  59. package/dist/display/Counter.svelte +285 -0
  60. package/dist/display/Counter.svelte.d.ts +21 -0
  61. package/dist/display/Counter.svelte.d.ts.map +1 -0
  62. package/dist/display/Expand.svelte +48 -0
  63. package/dist/display/Expand.svelte.d.ts +9 -0
  64. package/dist/display/Expand.svelte.d.ts.map +1 -0
  65. package/dist/display/List.svelte +294 -0
  66. package/dist/display/List.svelte.d.ts +40 -0
  67. package/dist/display/List.svelte.d.ts.map +1 -0
  68. package/dist/display/ListContextReset.svelte +19 -0
  69. package/dist/display/ListContextReset.svelte.d.ts +7 -0
  70. package/dist/display/ListContextReset.svelte.d.ts.map +1 -0
  71. package/dist/display/ListItem.svelte +834 -0
  72. package/dist/display/ListItem.svelte.d.ts +22 -0
  73. package/dist/display/ListItem.svelte.d.ts.map +1 -0
  74. package/dist/display/QR.svelte +1193 -0
  75. package/dist/display/QR.svelte.d.ts +23 -0
  76. package/dist/display/QR.svelte.d.ts.map +1 -0
  77. package/dist/display/SplitPane.svelte +744 -0
  78. package/dist/display/SplitPane.svelte.d.ts +25 -0
  79. package/dist/display/SplitPane.svelte.d.ts.map +1 -0
  80. package/dist/display/Stat.svelte +439 -0
  81. package/dist/display/Stat.svelte.d.ts +24 -0
  82. package/dist/display/Stat.svelte.d.ts.map +1 -0
  83. package/dist/display/Table.svelte +4654 -0
  84. package/dist/display/Table.svelte.d.ts +249 -0
  85. package/dist/display/Table.svelte.d.ts.map +1 -0
  86. package/dist/display/TableCellEditor.svelte +935 -0
  87. package/dist/display/TableCellEditor.svelte.d.ts +58 -0
  88. package/dist/display/TableCellEditor.svelte.d.ts.map +1 -0
  89. package/dist/display/Timeline.svelte +1258 -0
  90. package/dist/display/Timeline.svelte.d.ts +43 -0
  91. package/dist/display/Timeline.svelte.d.ts.map +1 -0
  92. package/dist/display/Tree.svelte +1740 -0
  93. package/dist/display/Tree.svelte.d.ts +74 -0
  94. package/dist/display/Tree.svelte.d.ts.map +1 -0
  95. package/dist/display/Typewriter.svelte +338 -0
  96. package/dist/display/Typewriter.svelte.d.ts +22 -0
  97. package/dist/display/Typewriter.svelte.d.ts.map +1 -0
  98. package/dist/display/index.d.ts +24 -0
  99. package/dist/display/index.d.ts.map +1 -0
  100. package/dist/display/index.js +18 -0
  101. package/dist/feedback/Callout.svelte +529 -0
  102. package/dist/feedback/Callout.svelte.d.ts +24 -0
  103. package/dist/feedback/Callout.svelte.d.ts.map +1 -0
  104. package/dist/feedback/Confetti.svelte +631 -0
  105. package/dist/feedback/Confetti.svelte.d.ts +90 -0
  106. package/dist/feedback/Confetti.svelte.d.ts.map +1 -0
  107. package/dist/feedback/Progress.svelte +382 -0
  108. package/dist/feedback/Progress.svelte.d.ts +25 -0
  109. package/dist/feedback/Progress.svelte.d.ts.map +1 -0
  110. package/dist/feedback/Toast.svelte +967 -0
  111. package/dist/feedback/Toast.svelte.d.ts +54 -0
  112. package/dist/feedback/Toast.svelte.d.ts.map +1 -0
  113. package/dist/feedback/index.d.ts +7 -0
  114. package/dist/feedback/index.d.ts.map +1 -0
  115. package/dist/feedback/index.js +4 -0
  116. package/dist/form/Checkbox.svelte +449 -0
  117. package/dist/form/Checkbox.svelte.d.ts +27 -0
  118. package/dist/form/Checkbox.svelte.d.ts.map +1 -0
  119. package/dist/form/Fieldset.svelte +410 -0
  120. package/dist/form/Fieldset.svelte.d.ts +22 -0
  121. package/dist/form/Fieldset.svelte.d.ts.map +1 -0
  122. package/dist/form/FileUpload.svelte +934 -0
  123. package/dist/form/FileUpload.svelte.d.ts +41 -0
  124. package/dist/form/FileUpload.svelte.d.ts.map +1 -0
  125. package/dist/form/Form.svelte +530 -0
  126. package/dist/form/Form.svelte.d.ts +120 -0
  127. package/dist/form/Form.svelte.d.ts.map +1 -0
  128. package/dist/form/Input.svelte +2858 -0
  129. package/dist/form/Input.svelte.d.ts +66 -0
  130. package/dist/form/Input.svelte.d.ts.map +1 -0
  131. package/dist/form/Radio.svelte +507 -0
  132. package/dist/form/Radio.svelte.d.ts +39 -0
  133. package/dist/form/Radio.svelte.d.ts.map +1 -0
  134. package/dist/form/Range.svelte +912 -0
  135. package/dist/form/Range.svelte.d.ts +33 -0
  136. package/dist/form/Range.svelte.d.ts.map +1 -0
  137. package/dist/form/Rating.svelte +429 -0
  138. package/dist/form/Rating.svelte.d.ts +28 -0
  139. package/dist/form/Rating.svelte.d.ts.map +1 -0
  140. package/dist/form/Select.svelte +1933 -0
  141. package/dist/form/Select.svelte.d.ts +54 -0
  142. package/dist/form/Select.svelte.d.ts.map +1 -0
  143. package/dist/form/Toggle.svelte +645 -0
  144. package/dist/form/Toggle.svelte.d.ts +50 -0
  145. package/dist/form/Toggle.svelte.d.ts.map +1 -0
  146. package/dist/form/index.d.ts +15 -0
  147. package/dist/form/index.d.ts.map +1 -0
  148. package/dist/form/index.js +10 -0
  149. package/dist/index.d.ts +7 -0
  150. package/dist/index.d.ts.map +1 -0
  151. package/dist/index.js +6 -0
  152. package/dist/layout/README.md +172 -0
  153. package/dist/media/Carousel.svelte +2424 -0
  154. package/dist/media/Carousel.svelte.d.ts +47 -0
  155. package/dist/media/Carousel.svelte.d.ts.map +1 -0
  156. package/dist/media/Gallery.svelte +2881 -0
  157. package/dist/media/Gallery.svelte.d.ts +82 -0
  158. package/dist/media/Gallery.svelte.d.ts.map +1 -0
  159. package/dist/media/Image.svelte +389 -0
  160. package/dist/media/Image.svelte.d.ts +33 -0
  161. package/dist/media/Image.svelte.d.ts.map +1 -0
  162. package/dist/media/PDF.svelte +1793 -0
  163. package/dist/media/PDF.svelte.d.ts +44 -0
  164. package/dist/media/PDF.svelte.d.ts.map +1 -0
  165. package/dist/media/Panorama.svelte +1391 -0
  166. package/dist/media/Panorama.svelte.d.ts +47 -0
  167. package/dist/media/Panorama.svelte.d.ts.map +1 -0
  168. package/dist/media/Video.svelte +2501 -0
  169. package/dist/media/Video.svelte.d.ts +58 -0
  170. package/dist/media/Video.svelte.d.ts.map +1 -0
  171. package/dist/media/carousel.d.ts +211 -0
  172. package/dist/media/carousel.d.ts.map +1 -0
  173. package/dist/media/carousel.js +408 -0
  174. package/dist/media/index.d.ts +11 -0
  175. package/dist/media/index.d.ts.map +1 -0
  176. package/dist/media/index.js +5 -0
  177. package/dist/navigation/BottomSheet.svelte +636 -0
  178. package/dist/navigation/BottomSheet.svelte.d.ts +27 -0
  179. package/dist/navigation/BottomSheet.svelte.d.ts.map +1 -0
  180. package/dist/navigation/Breadcrumbs.svelte +611 -0
  181. package/dist/navigation/Breadcrumbs.svelte.d.ts +28 -0
  182. package/dist/navigation/Breadcrumbs.svelte.d.ts.map +1 -0
  183. package/dist/navigation/Pagination.svelte +641 -0
  184. package/dist/navigation/Pagination.svelte.d.ts +27 -0
  185. package/dist/navigation/Pagination.svelte.d.ts.map +1 -0
  186. package/dist/navigation/Steps.svelte +965 -0
  187. package/dist/navigation/Steps.svelte.d.ts +43 -0
  188. package/dist/navigation/Steps.svelte.d.ts.map +1 -0
  189. package/dist/navigation/Tabs.svelte +698 -0
  190. package/dist/navigation/Tabs.svelte.d.ts +41 -0
  191. package/dist/navigation/Tabs.svelte.d.ts.map +1 -0
  192. package/dist/navigation/index.d.ts +8 -0
  193. package/dist/navigation/index.d.ts.map +1 -0
  194. package/dist/navigation/index.js +5 -0
  195. package/package.json +139 -0
@@ -0,0 +1,25 @@
1
+ import { type Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ vertical?: boolean;
4
+ size?: number;
5
+ min_size?: number;
6
+ max_size?: number;
7
+ snap?: number[];
8
+ snap_threshold?: number;
9
+ collapsible?: boolean;
10
+ collapsed?: 'first' | 'second' | null;
11
+ id?: string;
12
+ class?: string;
13
+ first?: Snippet;
14
+ second?: Snippet;
15
+ onresize?: (detail: {
16
+ size: number;
17
+ }) => void;
18
+ oncollapse?: (detail: {
19
+ pane: 'first' | 'second' | null;
20
+ }) => void;
21
+ };
22
+ declare const SplitPane: import("svelte").Component<$$ComponentProps, {}, "size" | "collapsed">;
23
+ type SplitPane = ReturnType<typeof SplitPane>;
24
+ export default SplitPane;
25
+ //# sourceMappingURL=SplitPane.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SplitPane.svelte.d.ts","sourceRoot":"","sources":["../../src/display/SplitPane.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGrC,KAAK,gBAAgB,GAAI;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IACtC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;CACnE,CAAC;AAwdH,QAAA,MAAM,SAAS,wEAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -0,0 +1,439 @@
1
+ <script lang="ts">
2
+ import type { Component } from 'svelte';
3
+ import Counter from './Counter.svelte';
4
+
5
+ const propId = $props.id();
6
+ let {
7
+ /** Main statistic value to display */
8
+ value,
9
+
10
+ /** Descriptive label */
11
+ label = undefined as string | undefined,
12
+
13
+ /** Leading icon component */
14
+ icon: Icon = undefined as Component<Record<string, never>> | undefined,
15
+
16
+ /** Percentage change from previous period */
17
+ change = undefined as number | undefined,
18
+
19
+ /** Description for the change (e.g., "vs last month") */
20
+ change_label = undefined as string | undefined,
21
+
22
+ /** Override trend direction (auto-detected from change by default) */
23
+ trend = undefined as 'up' | 'down' | 'neutral' | undefined,
24
+
25
+ /** Component size */
26
+ size = '1' as '0' | '1' | '2' | '3',
27
+
28
+ /** Horizontal layout */
29
+ horizontal = false,
30
+
31
+ /** Animate value via Counter */
32
+ animated = true,
33
+
34
+ /** Prefix shown smaller and top-aligned alongside the value (e.g. "$") */
35
+ prefix = undefined as string | undefined,
36
+
37
+ /** Suffix shown smaller and top-aligned alongside the value (e.g. "%") */
38
+ suffix = undefined as string | undefined,
39
+
40
+ /** Number of decimal places for numeric values */
41
+ decimals = 0,
42
+
43
+ /** Show loading skeleton */
44
+ skeleton = false,
45
+
46
+ /** Element ID */
47
+ id = propId,
48
+
49
+ /** Additional CSS classes */
50
+ class: class_name = '',
51
+ }: {
52
+ value: string | number;
53
+ label?: string;
54
+ icon?: Component<Record<string, never>>;
55
+ change?: number;
56
+ change_label?: string;
57
+ trend?: 'up' | 'down' | 'neutral';
58
+ size?: '0' | '1' | '2' | '3';
59
+ horizontal?: boolean;
60
+ animated?: boolean;
61
+ prefix?: string;
62
+ suffix?: string;
63
+ decimals?: number;
64
+ skeleton?: boolean;
65
+ id?: string;
66
+ class?: string;
67
+ } = $props();
68
+
69
+ let counter_ref = $state<{ restart: () => void } | undefined>(undefined);
70
+
71
+ export function restart() {
72
+ counter_ref?.restart();
73
+ }
74
+
75
+ const is_numeric = $derived(typeof value === 'number');
76
+
77
+ const resolved_trend = $derived.by<'up' | 'down' | 'neutral'>(() => {
78
+ if (trend) return trend;
79
+ if (change === undefined || change === 0) return 'neutral';
80
+ return change > 0 ? 'up' : 'down';
81
+ });
82
+
83
+ const trend_color = $derived.by<'success' | 'error' | 'neutral'>(() => {
84
+ if (resolved_trend === 'up') return 'success';
85
+ if (resolved_trend === 'down') return 'error';
86
+ return 'neutral';
87
+ });
88
+
89
+ function formatChange(val: number): string {
90
+ const sign = val > 0 ? '+' : '';
91
+ const formatted =
92
+ Math.abs(val) === Math.round(Math.abs(val)) ? val.toFixed(0) : val.toFixed(1);
93
+ return `${sign}${formatted}%`;
94
+ }
95
+
96
+ const change_text = $derived(change !== undefined ? formatChange(change) : '');
97
+
98
+ const change_aria_label = $derived.by(() => {
99
+ if (change === undefined) return '';
100
+ const direction =
101
+ resolved_trend === 'up'
102
+ ? 'increased'
103
+ : resolved_trend === 'down'
104
+ ? 'decreased'
105
+ : 'unchanged';
106
+ const amount = Math.abs(change).toFixed(1);
107
+ const suffix = change_label ? `, ${change_label}` : '';
108
+ return `${direction} by ${amount} percent${suffix}`;
109
+ });
110
+ </script>
111
+
112
+ <div
113
+ {id}
114
+ class={['stat', `size-${size}`, class_name].filter(Boolean).join(' ')}
115
+ class:horizontal
116
+ class:skeleton>
117
+ {#if skeleton}
118
+ <div class="skeleton-wrap">
119
+ {#if Icon}
120
+ <div class="skeleton-icon"></div>
121
+ {/if}
122
+ <div class="skeleton-body">
123
+ <div class="skeleton-value"></div>
124
+ {#if label}
125
+ <div class="skeleton-label"></div>
126
+ {/if}
127
+ {#if change !== undefined}
128
+ <div class="skeleton-change"></div>
129
+ {/if}
130
+ </div>
131
+ </div>
132
+ {:else}
133
+ {#if Icon}
134
+ <div class="icon">
135
+ <Icon />
136
+ </div>
137
+ {/if}
138
+
139
+ <div class="body">
140
+ <div class="value" aria-live="polite">
141
+ {#if is_numeric && animated}
142
+ <Counter
143
+ bind:this={counter_ref}
144
+ value={value as number}
145
+ {prefix}
146
+ {suffix}
147
+ {decimals} />
148
+ {:else}
149
+ {#if prefix}<span class="affix prefix">{prefix}</span>{/if}
150
+ {value}
151
+ {#if suffix}<span class="affix suffix">{suffix}</span>{/if}
152
+ {/if}
153
+ </div>
154
+
155
+ {#if label}
156
+ <div class="label">{label}</div>
157
+ {/if}
158
+
159
+ {#if change !== undefined}
160
+ <div class="change {trend_color}" aria-label={change_aria_label}>
161
+ <svg
162
+ class="arrow"
163
+ width="14"
164
+ height="14"
165
+ viewBox="0 0 14 14"
166
+ fill="none"
167
+ aria-hidden="true">
168
+ {#if resolved_trend === 'up'}
169
+ <path
170
+ d="M3 10L10 3M10 3H5M10 3V8"
171
+ stroke="currentColor"
172
+ stroke-width="1.5"
173
+ stroke-linecap="round"
174
+ stroke-linejoin="round" />
175
+ {:else if resolved_trend === 'down'}
176
+ <path
177
+ d="M3 4L10 11M10 11H5M10 11V6"
178
+ stroke="currentColor"
179
+ stroke-width="1.5"
180
+ stroke-linecap="round"
181
+ stroke-linejoin="round" />
182
+ {:else}
183
+ <path
184
+ d="M3 7H11M11 7L8 4M11 7L8 10"
185
+ stroke="currentColor"
186
+ stroke-width="1.5"
187
+ stroke-linecap="round"
188
+ stroke-linejoin="round" />
189
+ {/if}
190
+ </svg>
191
+ <span class="text">
192
+ {change_text}{#if change_label}{' '}{change_label}{/if}
193
+ </span>
194
+ </div>
195
+ {/if}
196
+ </div>
197
+ {/if}
198
+ </div>
199
+
200
+ <style>
201
+ .stat {
202
+ --stat-value-font: 28px;
203
+ --stat-label-font: 13px;
204
+ --stat-icon-size: 28px;
205
+
206
+ display: flex;
207
+ flex-direction: column;
208
+ align-items: flex-start;
209
+ gap: 0.5rem;
210
+
211
+ &.size-0 {
212
+ --stat-value-font: 20px;
213
+ --stat-label-font: 11px;
214
+ --stat-icon-size: 20px;
215
+ }
216
+ &.size-1 {
217
+ --stat-value-font: 28px;
218
+ --stat-label-font: 13px;
219
+ --stat-icon-size: 28px;
220
+ }
221
+ &.size-2 {
222
+ --stat-value-font: 40px;
223
+ --stat-label-font: 15px;
224
+ --stat-icon-size: 36px;
225
+ }
226
+ &.size-3 {
227
+ --stat-value-font: 56px;
228
+ --stat-label-font: 17px;
229
+ --stat-icon-size: 48px;
230
+ }
231
+
232
+ &.horizontal {
233
+ flex-direction: row;
234
+ align-items: center;
235
+ gap: 0.75rem;
236
+ }
237
+
238
+ .icon {
239
+ display: flex;
240
+ align-items: center;
241
+ justify-content: center;
242
+ width: var(--stat-icon-size);
243
+ height: var(--stat-icon-size);
244
+ color: var(--color-action, light-dark(#3b82f6, #60a5fa));
245
+ flex-shrink: 0;
246
+
247
+ :global(svg) {
248
+ width: 100%;
249
+ height: 100%;
250
+ }
251
+ }
252
+
253
+ .body {
254
+ display: flex;
255
+ flex-direction: column;
256
+ gap: 0.125rem;
257
+ min-width: 0;
258
+ }
259
+
260
+ .value {
261
+ font-size: var(--stat-value-font);
262
+ font-weight: 600;
263
+ line-height: 1.15;
264
+ color: var(--color-text, light-dark(#111827, #f9fafb));
265
+ font-variant-numeric: tabular-nums;
266
+ white-space: nowrap;
267
+ display: inline-flex;
268
+ align-items: flex-start;
269
+
270
+ /* Counter resets line-height to 1 on itself; inherit ours so the
271
+ animated value occupies the same 1.15 line box as static values and
272
+ the skeleton (no height jump between skeleton ↔ loaded or
273
+ animated ↔ static). */
274
+ > :global(.counter) {
275
+ line-height: inherit;
276
+ }
277
+ }
278
+
279
+ .affix {
280
+ font-size: 0.5em;
281
+ line-height: 1;
282
+ font-weight: 500;
283
+ opacity: 0.85;
284
+ padding-top: 0.15em;
285
+ }
286
+ .prefix {
287
+ margin-right: 0.1em;
288
+ }
289
+ .suffix {
290
+ margin-left: 0.1em;
291
+ }
292
+
293
+ .label {
294
+ font-size: var(--stat-label-font);
295
+ line-height: 1.3;
296
+ color: var(--color-text-muted, light-dark(#6b7280, #9ca3af));
297
+ white-space: nowrap;
298
+ }
299
+
300
+ .change {
301
+ display: inline-flex;
302
+ align-items: center;
303
+ gap: 0.2rem;
304
+ font-size: var(--stat-label-font);
305
+ line-height: 1.3;
306
+ margin-top: 0.25rem;
307
+ white-space: nowrap;
308
+
309
+ &.success {
310
+ color: var(--color-success, light-dark(#16a34a, #4ade80));
311
+ }
312
+ &.error {
313
+ color: var(--color-error, light-dark(#dc2626, #f87171));
314
+ }
315
+ &.neutral {
316
+ color: var(--color-text-muted, light-dark(#6b7280, #9ca3af));
317
+ }
318
+
319
+ .arrow {
320
+ flex-shrink: 0;
321
+ }
322
+
323
+ .text {
324
+ display: inline;
325
+ }
326
+ }
327
+ }
328
+
329
+ /* ── Skeleton ───────────────────────────────────────────────── */
330
+
331
+ .stat.skeleton {
332
+ pointer-events: none;
333
+ }
334
+
335
+ .skeleton-wrap {
336
+ display: flex;
337
+ flex-direction: column;
338
+ gap: 0.5rem;
339
+ width: 100%;
340
+
341
+ .stat.horizontal & {
342
+ flex-direction: row;
343
+ align-items: center;
344
+ gap: 0.75rem;
345
+ }
346
+ }
347
+
348
+ .skeleton-icon,
349
+ .skeleton-value,
350
+ .skeleton-label,
351
+ .skeleton-change {
352
+ position: relative;
353
+ overflow: hidden;
354
+ background: var(--skeleton-bg, rgb(from var(--color-text, #888) r g b / 0.1));
355
+
356
+ &::after {
357
+ content: '';
358
+ position: absolute;
359
+ inset: 0;
360
+ transform: translateX(-100%);
361
+ background-image: linear-gradient(
362
+ 105deg,
363
+ transparent 25%,
364
+ var(--skeleton-sheen, rgb(from var(--color-text, #888) r g b / 0.12)) 50%,
365
+ transparent 75%
366
+ );
367
+ animation: delight-skeleton-shimmer var(--skeleton-duration, 2.4s) ease-in-out
368
+ infinite;
369
+ animation-delay: var(--shimmer-delay, 0s);
370
+ }
371
+ }
372
+
373
+ .skeleton-icon {
374
+ --shimmer-delay: 0ms;
375
+ width: var(--stat-icon-size);
376
+ height: var(--stat-icon-size);
377
+ border-radius: var(--radius-md, 0.25rem);
378
+ @supports (corner-shape: squircle) {
379
+ corner-shape: squircle;
380
+ border-radius: calc(var(--radius-md, 0.25rem) * var(--squircle-ratio, 2));
381
+ }
382
+ flex-shrink: 0;
383
+ }
384
+
385
+ /* Mirrors .body (gap 0.125rem); each bar pads itself out to the real
386
+ text line's height so the loaded stat lands without a shift. */
387
+ .skeleton-body {
388
+ display: flex;
389
+ flex-direction: column;
390
+ gap: 0.125rem;
391
+ }
392
+
393
+ /* Value line: real font is --stat-value-font at line-height 1.15. */
394
+ .skeleton-value {
395
+ --shimmer-delay: 120ms;
396
+ width: 6em;
397
+ height: calc(var(--stat-value-font) * 0.7);
398
+ margin-block: calc(var(--stat-value-font) * 0.225);
399
+ border-radius: var(--radius-full, 1e5px);
400
+ }
401
+
402
+ /* Label / change lines: real font is --stat-label-font at line-height 1.3. */
403
+ .skeleton-label,
404
+ .skeleton-change {
405
+ height: calc(var(--stat-label-font) * 0.7);
406
+ margin-block: calc(var(--stat-label-font) * 0.3);
407
+ border-radius: var(--radius-full, 1e5px);
408
+ }
409
+
410
+ .skeleton-label {
411
+ --shimmer-delay: 240ms;
412
+ width: 8em;
413
+ }
414
+
415
+ .skeleton-change {
416
+ --shimmer-delay: 360ms;
417
+ width: 10em;
418
+ margin-top: calc(0.25rem + var(--stat-label-font) * 0.3);
419
+ }
420
+
421
+ @keyframes -global-delight-skeleton-shimmer {
422
+ 0% {
423
+ transform: translateX(-100%);
424
+ }
425
+ 55%,
426
+ 100% {
427
+ transform: translateX(100%);
428
+ }
429
+ }
430
+
431
+ @media (prefers-reduced-motion: reduce) {
432
+ .skeleton-icon::after,
433
+ .skeleton-value::after,
434
+ .skeleton-label::after,
435
+ .skeleton-change::after {
436
+ animation: none;
437
+ }
438
+ }
439
+ </style>
@@ -0,0 +1,24 @@
1
+ import type { Component } from 'svelte';
2
+ type $$ComponentProps = {
3
+ value: string | number;
4
+ label?: string;
5
+ icon?: Component<Record<string, never>>;
6
+ change?: number;
7
+ change_label?: string;
8
+ trend?: 'up' | 'down' | 'neutral';
9
+ size?: '0' | '1' | '2' | '3';
10
+ horizontal?: boolean;
11
+ animated?: boolean;
12
+ prefix?: string;
13
+ suffix?: string;
14
+ decimals?: number;
15
+ skeleton?: boolean;
16
+ id?: string;
17
+ class?: string;
18
+ };
19
+ declare const Stat: Component<$$ComponentProps, {
20
+ restart: () => void;
21
+ }, "">;
22
+ type Stat = ReturnType<typeof Stat>;
23
+ export default Stat;
24
+ //# sourceMappingURL=Stat.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Stat.svelte.d.ts","sourceRoot":"","sources":["../../src/display/Stat.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGvC,KAAK,gBAAgB,GAAI;IACxB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IAClC,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AA8JH,QAAA,MAAM,IAAI;;MAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}