@synthaxai/ui 1.0.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 (185) hide show
  1. package/README.md +262 -0
  2. package/dist/app.css +2 -0
  3. package/dist/app.html +12 -0
  4. package/dist/data-display/DataTable/DataTable.svelte +773 -0
  5. package/dist/data-display/DataTable/DataTable.svelte.d.ts +120 -0
  6. package/dist/data-display/DataTable/DataTable.svelte.d.ts.map +1 -0
  7. package/dist/data-display/DataTable/index.d.ts +2 -0
  8. package/dist/data-display/DataTable/index.d.ts.map +1 -0
  9. package/dist/data-display/DataTable/index.js +1 -0
  10. package/dist/data-display/StatCard/StatCard.svelte +409 -0
  11. package/dist/data-display/StatCard/StatCard.svelte.d.ts +63 -0
  12. package/dist/data-display/StatCard/StatCard.svelte.d.ts.map +1 -0
  13. package/dist/data-display/StatCard/index.d.ts +2 -0
  14. package/dist/data-display/StatCard/index.d.ts.map +1 -0
  15. package/dist/data-display/StatCard/index.js +1 -0
  16. package/dist/data-display/index.d.ts +8 -0
  17. package/dist/data-display/index.d.ts.map +1 -0
  18. package/dist/data-display/index.js +7 -0
  19. package/dist/dialogs/ConfirmDialog/ConfirmDialog.svelte +693 -0
  20. package/dist/dialogs/ConfirmDialog/ConfirmDialog.svelte.d.ts +66 -0
  21. package/dist/dialogs/ConfirmDialog/ConfirmDialog.svelte.d.ts.map +1 -0
  22. package/dist/dialogs/ConfirmDialog/index.d.ts +2 -0
  23. package/dist/dialogs/ConfirmDialog/index.d.ts.map +1 -0
  24. package/dist/dialogs/ConfirmDialog/index.js +1 -0
  25. package/dist/dialogs/Modal/Modal.svelte +441 -0
  26. package/dist/dialogs/Modal/Modal.svelte.d.ts +69 -0
  27. package/dist/dialogs/Modal/Modal.svelte.d.ts.map +1 -0
  28. package/dist/dialogs/Modal/index.d.ts +2 -0
  29. package/dist/dialogs/Modal/index.d.ts.map +1 -0
  30. package/dist/dialogs/Modal/index.js +1 -0
  31. package/dist/dialogs/index.d.ts +8 -0
  32. package/dist/dialogs/index.d.ts.map +1 -0
  33. package/dist/dialogs/index.js +7 -0
  34. package/dist/feedback/Alert/Alert.svelte +565 -0
  35. package/dist/feedback/Alert/Alert.svelte.d.ts +60 -0
  36. package/dist/feedback/Alert/Alert.svelte.d.ts.map +1 -0
  37. package/dist/feedback/Alert/index.d.ts +2 -0
  38. package/dist/feedback/Alert/index.d.ts.map +1 -0
  39. package/dist/feedback/Alert/index.js +1 -0
  40. package/dist/feedback/EmptyState/EmptyState.svelte +377 -0
  41. package/dist/feedback/EmptyState/EmptyState.svelte.d.ts +63 -0
  42. package/dist/feedback/EmptyState/EmptyState.svelte.d.ts.map +1 -0
  43. package/dist/feedback/EmptyState/index.d.ts +2 -0
  44. package/dist/feedback/EmptyState/index.d.ts.map +1 -0
  45. package/dist/feedback/EmptyState/index.js +1 -0
  46. package/dist/feedback/ProgressBar/ProgressBar.svelte +585 -0
  47. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts +68 -0
  48. package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts.map +1 -0
  49. package/dist/feedback/ProgressBar/index.d.ts +2 -0
  50. package/dist/feedback/ProgressBar/index.d.ts.map +1 -0
  51. package/dist/feedback/ProgressBar/index.js +1 -0
  52. package/dist/feedback/Skeleton/Skeleton.svelte +568 -0
  53. package/dist/feedback/Skeleton/Skeleton.svelte.d.ts +54 -0
  54. package/dist/feedback/Skeleton/Skeleton.svelte.d.ts.map +1 -0
  55. package/dist/feedback/Skeleton/index.d.ts +2 -0
  56. package/dist/feedback/Skeleton/index.d.ts.map +1 -0
  57. package/dist/feedback/Skeleton/index.js +1 -0
  58. package/dist/feedback/Spinner/Spinner.svelte +434 -0
  59. package/dist/feedback/Spinner/Spinner.svelte.d.ts +49 -0
  60. package/dist/feedback/Spinner/Spinner.svelte.d.ts.map +1 -0
  61. package/dist/feedback/Spinner/index.d.ts +2 -0
  62. package/dist/feedback/Spinner/index.d.ts.map +1 -0
  63. package/dist/feedback/Spinner/index.js +1 -0
  64. package/dist/feedback/Toast/Toast.svelte +587 -0
  65. package/dist/feedback/Toast/Toast.svelte.d.ts +55 -0
  66. package/dist/feedback/Toast/Toast.svelte.d.ts.map +1 -0
  67. package/dist/feedback/Toast/ToastContainer.svelte +168 -0
  68. package/dist/feedback/Toast/ToastContainer.svelte.d.ts +28 -0
  69. package/dist/feedback/Toast/ToastContainer.svelte.d.ts.map +1 -0
  70. package/dist/feedback/Toast/index.d.ts +4 -0
  71. package/dist/feedback/Toast/index.d.ts.map +1 -0
  72. package/dist/feedback/Toast/index.js +3 -0
  73. package/dist/feedback/Toast/toast-store.d.ts +72 -0
  74. package/dist/feedback/Toast/toast-store.d.ts.map +1 -0
  75. package/dist/feedback/Toast/toast-store.js +157 -0
  76. package/dist/feedback/index.d.ts +13 -0
  77. package/dist/feedback/index.d.ts.map +1 -0
  78. package/dist/feedback/index.js +12 -0
  79. package/dist/forms/Checkbox/Checkbox.svelte +404 -0
  80. package/dist/forms/Checkbox/Checkbox.svelte.d.ts +62 -0
  81. package/dist/forms/Checkbox/Checkbox.svelte.d.ts.map +1 -0
  82. package/dist/forms/Checkbox/index.d.ts +2 -0
  83. package/dist/forms/Checkbox/index.d.ts.map +1 -0
  84. package/dist/forms/Checkbox/index.js +1 -0
  85. package/dist/forms/FormField/FormField.svelte +299 -0
  86. package/dist/forms/FormField/FormField.svelte.d.ts +43 -0
  87. package/dist/forms/FormField/FormField.svelte.d.ts.map +1 -0
  88. package/dist/forms/FormField/index.d.ts +2 -0
  89. package/dist/forms/FormField/index.d.ts.map +1 -0
  90. package/dist/forms/FormField/index.js +1 -0
  91. package/dist/forms/RadioGroup/RadioGroup.svelte +418 -0
  92. package/dist/forms/RadioGroup/RadioGroup.svelte.d.ts +70 -0
  93. package/dist/forms/RadioGroup/RadioGroup.svelte.d.ts.map +1 -0
  94. package/dist/forms/RadioGroup/index.d.ts +2 -0
  95. package/dist/forms/RadioGroup/index.d.ts.map +1 -0
  96. package/dist/forms/RadioGroup/index.js +1 -0
  97. package/dist/forms/Select/Select.svelte +548 -0
  98. package/dist/forms/Select/Select.svelte.d.ts +74 -0
  99. package/dist/forms/Select/Select.svelte.d.ts.map +1 -0
  100. package/dist/forms/Select/index.d.ts +2 -0
  101. package/dist/forms/Select/index.d.ts.map +1 -0
  102. package/dist/forms/Select/index.js +1 -0
  103. package/dist/forms/TextInput/TextInput.svelte +628 -0
  104. package/dist/forms/TextInput/TextInput.svelte.d.ts +97 -0
  105. package/dist/forms/TextInput/TextInput.svelte.d.ts.map +1 -0
  106. package/dist/forms/TextInput/index.d.ts +2 -0
  107. package/dist/forms/TextInput/index.d.ts.map +1 -0
  108. package/dist/forms/TextInput/index.js +1 -0
  109. package/dist/forms/Textarea/Textarea.svelte +587 -0
  110. package/dist/forms/Textarea/Textarea.svelte.d.ts +71 -0
  111. package/dist/forms/Textarea/Textarea.svelte.d.ts.map +1 -0
  112. package/dist/forms/Textarea/index.d.ts +2 -0
  113. package/dist/forms/Textarea/index.d.ts.map +1 -0
  114. package/dist/forms/Textarea/index.js +1 -0
  115. package/dist/forms/index.d.ts +13 -0
  116. package/dist/forms/index.d.ts.map +1 -0
  117. package/dist/forms/index.js +12 -0
  118. package/dist/index.d.ts +37 -0
  119. package/dist/index.d.ts.map +1 -0
  120. package/dist/index.js +65 -0
  121. package/dist/layout/Card/Card.svelte +316 -0
  122. package/dist/layout/Card/Card.svelte.d.ts +63 -0
  123. package/dist/layout/Card/Card.svelte.d.ts.map +1 -0
  124. package/dist/layout/Card/index.d.ts +2 -0
  125. package/dist/layout/Card/index.d.ts.map +1 -0
  126. package/dist/layout/Card/index.js +1 -0
  127. package/dist/layout/Container/Container.svelte +252 -0
  128. package/dist/layout/Container/Container.svelte.d.ts +50 -0
  129. package/dist/layout/Container/Container.svelte.d.ts.map +1 -0
  130. package/dist/layout/Container/index.d.ts +2 -0
  131. package/dist/layout/Container/index.d.ts.map +1 -0
  132. package/dist/layout/Container/index.js +1 -0
  133. package/dist/layout/index.d.ts +8 -0
  134. package/dist/layout/index.d.ts.map +1 -0
  135. package/dist/layout/index.js +7 -0
  136. package/dist/navigation/StepIndicator/StepIndicator.svelte +601 -0
  137. package/dist/navigation/StepIndicator/StepIndicator.svelte.d.ts +70 -0
  138. package/dist/navigation/StepIndicator/StepIndicator.svelte.d.ts.map +1 -0
  139. package/dist/navigation/StepIndicator/index.d.ts +2 -0
  140. package/dist/navigation/StepIndicator/index.d.ts.map +1 -0
  141. package/dist/navigation/StepIndicator/index.js +1 -0
  142. package/dist/navigation/index.d.ts +7 -0
  143. package/dist/navigation/index.d.ts.map +1 -0
  144. package/dist/navigation/index.js +6 -0
  145. package/dist/primitives/Badge/Badge.svelte +365 -0
  146. package/dist/primitives/Badge/Badge.svelte.d.ts +39 -0
  147. package/dist/primitives/Badge/Badge.svelte.d.ts.map +1 -0
  148. package/dist/primitives/Badge/index.d.ts +2 -0
  149. package/dist/primitives/Badge/index.d.ts.map +1 -0
  150. package/dist/primitives/Badge/index.js +1 -0
  151. package/dist/primitives/Button/Button.svelte +430 -0
  152. package/dist/primitives/Button/Button.svelte.d.ts +50 -0
  153. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -0
  154. package/dist/primitives/Button/index.d.ts +2 -0
  155. package/dist/primitives/Button/index.d.ts.map +1 -0
  156. package/dist/primitives/Button/index.js +1 -0
  157. package/dist/primitives/index.d.ts +9 -0
  158. package/dist/primitives/index.d.ts.map +1 -0
  159. package/dist/primitives/index.js +8 -0
  160. package/dist/routes/+layout.svelte +12 -0
  161. package/dist/routes/+layout.svelte.d.ts +12 -0
  162. package/dist/routes/+layout.svelte.d.ts.map +1 -0
  163. package/dist/routes/+page.svelte +53 -0
  164. package/dist/routes/+page.svelte.d.ts +27 -0
  165. package/dist/routes/+page.svelte.d.ts.map +1 -0
  166. package/dist/styles/tokens.css +399 -0
  167. package/dist/types/index.d.ts +175 -0
  168. package/dist/types/index.d.ts.map +1 -0
  169. package/dist/types/index.js +7 -0
  170. package/dist/utils/accessibility.d.ts +103 -0
  171. package/dist/utils/accessibility.d.ts.map +1 -0
  172. package/dist/utils/accessibility.js +202 -0
  173. package/dist/utils/cn.d.ts +71 -0
  174. package/dist/utils/cn.d.ts.map +1 -0
  175. package/dist/utils/cn.js +61 -0
  176. package/dist/utils/form-styles.d.ts +76 -0
  177. package/dist/utils/form-styles.d.ts.map +1 -0
  178. package/dist/utils/form-styles.js +95 -0
  179. package/dist/utils/index.d.ts +10 -0
  180. package/dist/utils/index.d.ts.map +1 -0
  181. package/dist/utils/index.js +13 -0
  182. package/dist/utils/keyboard.d.ts +94 -0
  183. package/dist/utils/keyboard.d.ts.map +1 -0
  184. package/dist/utils/keyboard.js +179 -0
  185. package/package.json +119 -0
@@ -0,0 +1,434 @@
1
+ <!--
2
+ @component Spinner
3
+
4
+ A world-class loading spinner component with multiple styles, sizes, and accessibility features.
5
+ Designed for healthcare applications where clear feedback during data operations is critical.
6
+
7
+ Features:
8
+ - Multiple animation styles (ring, dots, pulse)
9
+ - Proper ARIA announcements
10
+ - Reduced motion support
11
+ - Optional delay to prevent flash on fast operations
12
+ - Overlay mode for blocking interactions
13
+
14
+ @example
15
+ <Spinner />
16
+
17
+ @example
18
+ <Spinner size="lg" label="Loading patient data..." showLabel />
19
+
20
+ @example
21
+ <Spinner style="dots" variant="primary" />
22
+ -->
23
+ <script lang="ts">
24
+ type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
25
+ type SpinnerVariant = 'primary' | 'secondary' | 'white' | 'success' | 'error';
26
+ type SpinnerStyle = 'ring' | 'dots' | 'pulse';
27
+
28
+ interface Props {
29
+ /** Size of the spinner */
30
+ size?: SpinnerSize;
31
+ /** Color variant */
32
+ variant?: SpinnerVariant;
33
+ /** Animation style */
34
+ style?: SpinnerStyle;
35
+ /** Accessible label for screen readers */
36
+ label?: string;
37
+ /** Whether to show the label visually */
38
+ showLabel?: boolean;
39
+ /** Delay before showing spinner (prevents flash on fast loads) */
40
+ delay?: number;
41
+ /** Show as overlay covering parent container */
42
+ overlay?: boolean;
43
+ /** Additional CSS classes */
44
+ class?: string;
45
+ /** ID for the spinner element */
46
+ id?: string;
47
+ }
48
+
49
+ let {
50
+ size = 'md',
51
+ variant = 'primary',
52
+ style = 'ring',
53
+ label = 'Loading...',
54
+ showLabel = false,
55
+ delay = 0,
56
+ overlay = false,
57
+ class: className = '',
58
+ id
59
+ }: Props = $props();
60
+
61
+ // Delay visibility to prevent flash on fast operations
62
+ let isVisible = $state(false);
63
+
64
+ // Use $effect to handle delay reactively
65
+ $effect(() => {
66
+ if (delay === 0) {
67
+ isVisible = true;
68
+ return;
69
+ }
70
+
71
+ isVisible = false;
72
+ const timer = setTimeout(() => {
73
+ isVisible = true;
74
+ }, delay);
75
+
76
+ return () => clearTimeout(timer);
77
+ });
78
+
79
+ // Size configurations
80
+ const sizeConfig: Record<SpinnerSize, { dimension: number; stroke: number; fontSize: string; dotSize: number }> = {
81
+ xs: { dimension: 16, stroke: 2, fontSize: 'text-xs', dotSize: 4 },
82
+ sm: { dimension: 20, stroke: 2.5, fontSize: 'text-sm', dotSize: 5 },
83
+ md: { dimension: 28, stroke: 3, fontSize: 'text-sm', dotSize: 6 },
84
+ lg: { dimension: 40, stroke: 3.5, fontSize: 'text-base', dotSize: 8 },
85
+ xl: { dimension: 56, stroke: 4, fontSize: 'text-lg', dotSize: 10 }
86
+ };
87
+
88
+ const config = $derived(sizeConfig[size]);
89
+ </script>
90
+
91
+ {#if isVisible}
92
+ <div
93
+ {id}
94
+ class="spinner spinner-{size} spinner-{variant} {className}"
95
+ class:spinner-overlay={overlay}
96
+ role="status"
97
+ aria-live="polite"
98
+ aria-busy="true"
99
+ aria-label={label}
100
+ >
101
+ <div class="spinner-content">
102
+ <!-- Ring Spinner (Default) -->
103
+ {#if style === 'ring'}
104
+ <svg
105
+ class="spinner-ring"
106
+ width={config.dimension}
107
+ height={config.dimension}
108
+ viewBox="0 0 24 24"
109
+ fill="none"
110
+ aria-hidden="true"
111
+ >
112
+ <!-- Background track -->
113
+ <circle
114
+ class="spinner-track"
115
+ cx="12"
116
+ cy="12"
117
+ r="10"
118
+ stroke="currentColor"
119
+ stroke-width={config.stroke}
120
+ opacity="0.2"
121
+ />
122
+ <!-- Spinning arc -->
123
+ <circle
124
+ class="spinner-arc"
125
+ cx="12"
126
+ cy="12"
127
+ r="10"
128
+ stroke="currentColor"
129
+ stroke-width={config.stroke}
130
+ stroke-linecap="round"
131
+ stroke-dasharray="32 32"
132
+ stroke-dashoffset="0"
133
+ />
134
+ </svg>
135
+ {/if}
136
+
137
+ <!-- Dots Spinner -->
138
+ {#if style === 'dots'}
139
+ <div
140
+ class="spinner-dots"
141
+ style="--dot-size: {config.dotSize}px; --spinner-dimension: {config.dimension}px;"
142
+ aria-hidden="true"
143
+ >
144
+ <span class="dot dot-1"></span>
145
+ <span class="dot dot-2"></span>
146
+ <span class="dot dot-3"></span>
147
+ </div>
148
+ {/if}
149
+
150
+ <!-- Pulse Spinner -->
151
+ {#if style === 'pulse'}
152
+ <div
153
+ class="spinner-pulse"
154
+ style="width: {config.dimension}px; height: {config.dimension}px;"
155
+ aria-hidden="true"
156
+ >
157
+ <span class="pulse-ring pulse-ring-1"></span>
158
+ <span class="pulse-ring pulse-ring-2"></span>
159
+ <span class="pulse-dot"></span>
160
+ </div>
161
+ {/if}
162
+
163
+ <!-- Label -->
164
+ {#if showLabel}
165
+ <span class="spinner-label {config.fontSize}">
166
+ {label}
167
+ </span>
168
+ {:else}
169
+ <span class="sr-only">{label}</span>
170
+ {/if}
171
+ </div>
172
+ </div>
173
+ {/if}
174
+
175
+ <style>
176
+ /* ========================================
177
+ BASE SPINNER STYLES
178
+ ======================================== */
179
+ .spinner {
180
+ display: inline-flex;
181
+ align-items: center;
182
+ justify-content: center;
183
+ }
184
+
185
+ .spinner-content {
186
+ display: inline-flex;
187
+ align-items: center;
188
+ gap: 0.5rem;
189
+ }
190
+
191
+ .spinner-label {
192
+ color: var(--ui-text-secondary);
193
+ }
194
+
195
+ /* Screen reader only class */
196
+ .sr-only {
197
+ position: absolute;
198
+ width: 1px;
199
+ height: 1px;
200
+ padding: 0;
201
+ margin: -1px;
202
+ overflow: hidden;
203
+ clip: rect(0, 0, 0, 0);
204
+ white-space: nowrap;
205
+ border: 0;
206
+ }
207
+
208
+ /* ========================================
209
+ OVERLAY MODE
210
+ ======================================== */
211
+ .spinner-overlay {
212
+ position: absolute;
213
+ inset: 0;
214
+ display: flex;
215
+ align-items: center;
216
+ justify-content: center;
217
+ background: rgb(var(--ui-bg-primary-rgb, 255 255 255) / 0.8);
218
+ backdrop-filter: blur(2px);
219
+ z-index: 10;
220
+ border-radius: inherit;
221
+ }
222
+
223
+ :global([data-theme='dark']) .spinner-overlay {
224
+ background: rgb(10 10 10 / 0.8);
225
+ }
226
+
227
+ @media (prefers-color-scheme: dark) {
228
+ :global(:root:not([data-theme='light'])) .spinner-overlay {
229
+ background: rgb(10 10 10 / 0.8);
230
+ }
231
+ }
232
+
233
+ /* ========================================
234
+ VARIANT COLORS
235
+ ======================================== */
236
+ .spinner-primary {
237
+ color: rgb(var(--ui-color-primary));
238
+ }
239
+
240
+ .spinner-secondary {
241
+ color: var(--ui-text-tertiary);
242
+ }
243
+
244
+ .spinner-white {
245
+ color: white;
246
+ }
247
+
248
+ .spinner-success {
249
+ color: rgb(var(--ui-color-success));
250
+ }
251
+
252
+ .spinner-error {
253
+ color: rgb(var(--ui-color-error));
254
+ }
255
+
256
+ /* Dark mode adjustments */
257
+ :global([data-theme='dark']) .spinner-primary {
258
+ color: rgb(var(--ui-color-primary-light));
259
+ }
260
+
261
+ @media (prefers-color-scheme: dark) {
262
+ :global(:root:not([data-theme='light'])) .spinner-primary {
263
+ color: rgb(var(--ui-color-primary-light));
264
+ }
265
+ }
266
+
267
+ /* ========================================
268
+ RING SPINNER (Default)
269
+ ======================================== */
270
+ .spinner-ring {
271
+ animation: spin 1s linear infinite;
272
+ }
273
+
274
+ .spinner-track {
275
+ opacity: 0.15;
276
+ }
277
+
278
+ .spinner-arc {
279
+ transform-origin: center;
280
+ }
281
+
282
+ @keyframes spin {
283
+ from {
284
+ transform: rotate(0deg);
285
+ }
286
+ to {
287
+ transform: rotate(360deg);
288
+ }
289
+ }
290
+
291
+ /* ========================================
292
+ DOTS SPINNER
293
+ ======================================== */
294
+ .spinner-dots {
295
+ display: flex;
296
+ align-items: center;
297
+ justify-content: center;
298
+ gap: calc(var(--dot-size) * 0.6);
299
+ height: var(--spinner-dimension);
300
+ }
301
+
302
+ .dot {
303
+ width: var(--dot-size);
304
+ height: var(--dot-size);
305
+ border-radius: 50%;
306
+ background-color: currentColor;
307
+ animation: dot-bounce 1.4s ease-in-out infinite both;
308
+ }
309
+
310
+ .dot-1 {
311
+ animation-delay: -0.32s;
312
+ }
313
+
314
+ .dot-2 {
315
+ animation-delay: -0.16s;
316
+ }
317
+
318
+ .dot-3 {
319
+ animation-delay: 0s;
320
+ }
321
+
322
+ @keyframes dot-bounce {
323
+ 0%, 80%, 100% {
324
+ transform: scale(0.6);
325
+ opacity: 0.5;
326
+ }
327
+ 40% {
328
+ transform: scale(1);
329
+ opacity: 1;
330
+ }
331
+ }
332
+
333
+ /* ========================================
334
+ PULSE SPINNER
335
+ ======================================== */
336
+ .spinner-pulse {
337
+ position: relative;
338
+ display: flex;
339
+ align-items: center;
340
+ justify-content: center;
341
+ }
342
+
343
+ .pulse-ring {
344
+ position: absolute;
345
+ inset: 0;
346
+ border-radius: 50%;
347
+ border: 2px solid currentColor;
348
+ opacity: 0;
349
+ animation: pulse-ring 2s ease-out infinite;
350
+ }
351
+
352
+ .pulse-ring-2 {
353
+ animation-delay: 1s;
354
+ }
355
+
356
+ .pulse-dot {
357
+ width: 30%;
358
+ height: 30%;
359
+ border-radius: 50%;
360
+ background-color: currentColor;
361
+ animation: pulse-dot 2s ease-in-out infinite;
362
+ }
363
+
364
+ @keyframes pulse-ring {
365
+ 0% {
366
+ transform: scale(0.5);
367
+ opacity: 0.8;
368
+ }
369
+ 100% {
370
+ transform: scale(1.2);
371
+ opacity: 0;
372
+ }
373
+ }
374
+
375
+ @keyframes pulse-dot {
376
+ 0%, 100% {
377
+ transform: scale(0.8);
378
+ opacity: 0.8;
379
+ }
380
+ 50% {
381
+ transform: scale(1);
382
+ opacity: 1;
383
+ }
384
+ }
385
+
386
+ /* ========================================
387
+ REDUCED MOTION
388
+ ======================================== */
389
+ @media (prefers-reduced-motion: reduce) {
390
+ .spinner-ring {
391
+ animation: none;
392
+ }
393
+
394
+ .spinner-arc {
395
+ stroke-dasharray: 16 48;
396
+ opacity: 0.8;
397
+ }
398
+
399
+ .dot {
400
+ animation: none;
401
+ opacity: 0.7;
402
+ }
403
+
404
+ .dot-1 {
405
+ opacity: 0.4;
406
+ }
407
+
408
+ .dot-2 {
409
+ opacity: 0.7;
410
+ }
411
+
412
+ .dot-3 {
413
+ opacity: 1;
414
+ }
415
+
416
+ .pulse-ring,
417
+ .pulse-dot {
418
+ animation: none;
419
+ }
420
+
421
+ .pulse-ring {
422
+ opacity: 0.3;
423
+ transform: scale(1);
424
+ }
425
+
426
+ .pulse-ring-2 {
427
+ display: none;
428
+ }
429
+
430
+ .pulse-dot {
431
+ opacity: 1;
432
+ }
433
+ }
434
+ </style>
@@ -0,0 +1,49 @@
1
+ type SpinnerSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
2
+ type SpinnerVariant = 'primary' | 'secondary' | 'white' | 'success' | 'error';
3
+ type SpinnerStyle = 'ring' | 'dots' | 'pulse';
4
+ interface Props {
5
+ /** Size of the spinner */
6
+ size?: SpinnerSize;
7
+ /** Color variant */
8
+ variant?: SpinnerVariant;
9
+ /** Animation style */
10
+ style?: SpinnerStyle;
11
+ /** Accessible label for screen readers */
12
+ label?: string;
13
+ /** Whether to show the label visually */
14
+ showLabel?: boolean;
15
+ /** Delay before showing spinner (prevents flash on fast loads) */
16
+ delay?: number;
17
+ /** Show as overlay covering parent container */
18
+ overlay?: boolean;
19
+ /** Additional CSS classes */
20
+ class?: string;
21
+ /** ID for the spinner element */
22
+ id?: string;
23
+ }
24
+ /**
25
+ * Spinner
26
+ *
27
+ * A world-class loading spinner component with multiple styles, sizes, and accessibility features.
28
+ * Designed for healthcare applications where clear feedback during data operations is critical.
29
+ *
30
+ * Features:
31
+ * - Multiple animation styles (ring, dots, pulse)
32
+ * - Proper ARIA announcements
33
+ * - Reduced motion support
34
+ * - Optional delay to prevent flash on fast operations
35
+ * - Overlay mode for blocking interactions
36
+ *
37
+ * @example
38
+ * <Spinner />
39
+ *
40
+ * @example
41
+ * <Spinner size="lg" label="Loading patient data..." showLabel />
42
+ *
43
+ * @example
44
+ * <Spinner style="dots" variant="primary" />
45
+ */
46
+ declare const Spinner: import("svelte").Component<Props, {}, "">;
47
+ type Spinner = ReturnType<typeof Spinner>;
48
+ export default Spinner;
49
+ //# sourceMappingURL=Spinner.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinner.svelte.d.ts","sourceRoot":"","sources":["../../../src/feedback/Spinner/Spinner.svelte.ts"],"names":[],"mappings":"AAGC,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACpD,KAAK,cAAc,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAC9E,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9C,UAAU,KAAK;IACd,0BAA0B;IAC1B,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,oBAAoB;IACpB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,sBAAsB;IACtB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;CACZ;AAiGF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,QAAA,MAAM,OAAO,2CAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as Spinner } from './Spinner.svelte';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/feedback/Spinner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ export { default as Spinner } from './Spinner.svelte';