@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,601 @@
1
+ <!--
2
+ @component StepIndicator
3
+
4
+ A world-class step indicator component for multi-step healthcare workflows.
5
+ Designed with full accessibility, clear visual states, and flexible layouts.
6
+
7
+ Features:
8
+ - Horizontal and vertical orientations
9
+ - Size variants (sm, md, lg)
10
+ - Step descriptions and substeps
11
+ - Custom icons per step
12
+ - Optional step indicators
13
+ - Warning and error states
14
+ - Progress summary display
15
+ - Full keyboard navigation
16
+ - Screen reader announcements
17
+
18
+ @example
19
+ <StepIndicator
20
+ steps={[
21
+ { id: 'patient', label: 'Patient Info', description: 'Enter patient details', state: 'completed' },
22
+ { id: 'insurance', label: 'Insurance', state: 'active' },
23
+ { id: 'verify', label: 'Verify', state: 'pending', optional: true }
24
+ ]}
25
+ showProgress
26
+ />
27
+ -->
28
+ <script lang="ts">
29
+ import type { Snippet } from 'svelte';
30
+ import { Check, X, AlertTriangle } from 'lucide-svelte';
31
+ import type { Step, StepState } from '../../types/index.js';
32
+
33
+ type StepIndicatorSize = 'sm' | 'md' | 'lg';
34
+ type StepIndicatorVariant = 'default' | 'compact' | 'minimal';
35
+ type StepIndicatorOrientation = 'horizontal' | 'vertical';
36
+
37
+ interface Props {
38
+ /** Array of steps */
39
+ steps: Step[];
40
+ /** Size variant */
41
+ size?: StepIndicatorSize;
42
+ /** Display variant */
43
+ variant?: StepIndicatorVariant;
44
+ /** Layout orientation */
45
+ orientation?: StepIndicatorOrientation;
46
+ /** Whether to show labels */
47
+ showLabels?: boolean;
48
+ /** Whether to show step descriptions */
49
+ showDescriptions?: boolean;
50
+ /** Whether to show progress summary (e.g., "Step 2 of 5") */
51
+ showProgress?: boolean;
52
+ /** Custom progress format function */
53
+ progressFormat?: (current: number, total: number) => string;
54
+ /** Allow clicking on future steps (not just completed/active) */
55
+ allowFutureSteps?: boolean;
56
+ /** Custom icon snippet for steps */
57
+ stepIcon?: Snippet<[{ step: Step; index: number; state: StepState }]>;
58
+ /** Accessible label for the navigation */
59
+ ariaLabel?: string;
60
+ /** Additional CSS classes */
61
+ class?: string;
62
+ /** ID for the component */
63
+ id?: string;
64
+ /** Step click handler */
65
+ onStepClick?: (step: Step, index: number) => void;
66
+ }
67
+
68
+ let {
69
+ steps,
70
+ size = 'md',
71
+ variant = 'default',
72
+ orientation = 'horizontal',
73
+ showLabels = true,
74
+ showDescriptions = false,
75
+ showProgress = false,
76
+ progressFormat,
77
+ allowFutureSteps = false,
78
+ stepIcon,
79
+ ariaLabel = 'Progress',
80
+ class: className = '',
81
+ id,
82
+ onStepClick
83
+ }: Props = $props();
84
+
85
+ // Size configurations
86
+ const sizeConfig: Record<StepIndicatorSize, {
87
+ circleSize: string;
88
+ circleWidth: string;
89
+ circleHeight: string;
90
+ fontSize: string;
91
+ descriptionSize: string;
92
+ iconSize: number;
93
+ lineThickness: string;
94
+ gap: string;
95
+ labelGap: string;
96
+ }> = {
97
+ sm: {
98
+ circleSize: '1.5rem',
99
+ circleWidth: '1.5rem',
100
+ circleHeight: '1.5rem',
101
+ fontSize: '0.75rem',
102
+ descriptionSize: '0.6875rem',
103
+ iconSize: 12,
104
+ lineThickness: '2px',
105
+ gap: '0.5rem',
106
+ labelGap: '0.25rem'
107
+ },
108
+ md: {
109
+ circleSize: '2rem',
110
+ circleWidth: '2rem',
111
+ circleHeight: '2rem',
112
+ fontSize: '0.875rem',
113
+ descriptionSize: '0.75rem',
114
+ iconSize: 16,
115
+ lineThickness: '2px',
116
+ gap: '0.75rem',
117
+ labelGap: '0.375rem'
118
+ },
119
+ lg: {
120
+ circleSize: '2.5rem',
121
+ circleWidth: '2.5rem',
122
+ circleHeight: '2.5rem',
123
+ fontSize: '1rem',
124
+ descriptionSize: '0.8125rem',
125
+ iconSize: 20,
126
+ lineThickness: '3px',
127
+ gap: '1rem',
128
+ labelGap: '0.5rem'
129
+ }
130
+ };
131
+
132
+ const config = $derived(sizeConfig[size]);
133
+
134
+ // Calculate progress
135
+ const completedCount = $derived(steps.filter(s => s.state === 'completed').length);
136
+ const activeIndex = $derived(steps.findIndex(s => s.state === 'active'));
137
+ const currentStepNumber = $derived(activeIndex >= 0 ? activeIndex + 1 : completedCount + 1);
138
+
139
+ // Progress text
140
+ const progressText = $derived(
141
+ progressFormat
142
+ ? progressFormat(currentStepNumber, steps.length)
143
+ : `Step ${currentStepNumber} of ${steps.length}`
144
+ );
145
+
146
+ // Check if step is clickable
147
+ function isClickable(step: Step, index: number): boolean {
148
+ if (!onStepClick) return false;
149
+ if (allowFutureSteps) return true;
150
+ return step.state === 'completed' || step.state === 'active' || step.state === 'error';
151
+ }
152
+
153
+ // Handle step click
154
+ function handleStepClick(step: Step, index: number) {
155
+ if (isClickable(step, index)) {
156
+ onStepClick?.(step, index);
157
+ }
158
+ }
159
+
160
+ // Handle keyboard navigation
161
+ function handleKeyDown(e: KeyboardEvent, step: Step, index: number) {
162
+ if (e.key === 'Enter' || e.key === ' ') {
163
+ e.preventDefault();
164
+ handleStepClick(step, index);
165
+ }
166
+ }
167
+
168
+ // Get line state between steps
169
+ function getLineState(index: number): 'completed' | 'active' | 'pending' {
170
+ const currentStep = steps[index];
171
+ if (currentStep?.state === 'completed') return 'completed';
172
+ if (currentStep?.state === 'active') return 'active';
173
+ return 'pending';
174
+ }
175
+ </script>
176
+
177
+ <div
178
+ {id}
179
+ class="step-indicator step-indicator-{orientation} step-indicator-{size} step-indicator-{variant} {className}"
180
+ >
181
+ <!-- Progress summary -->
182
+ {#if showProgress}
183
+ <div class="step-indicator-progress" role="status" aria-live="polite">
184
+ <span class="step-indicator-progress-text">{progressText}</span>
185
+ </div>
186
+ {/if}
187
+
188
+ <nav aria-label={ariaLabel}>
189
+ <ol class="step-indicator-list" role="list">
190
+ {#each steps as step, index (step.id)}
191
+ {@const clickable = isClickable(step, index)}
192
+ <li
193
+ class="step-indicator-item"
194
+ class:step-indicator-item-last={index === steps.length - 1}
195
+ >
196
+ <!-- Step button/indicator -->
197
+ <button
198
+ type="button"
199
+ class="step-indicator-step"
200
+ class:step-indicator-step-clickable={clickable}
201
+ class:step-indicator-step-completed={step.state === 'completed'}
202
+ class:step-indicator-step-active={step.state === 'active'}
203
+ class:step-indicator-step-error={step.state === 'error'}
204
+ class:step-indicator-step-pending={step.state === 'pending'}
205
+ onclick={() => handleStepClick(step, index)}
206
+ onkeydown={(e) => handleKeyDown(e, step, index)}
207
+ disabled={!clickable}
208
+ aria-current={step.state === 'active' ? 'step' : undefined}
209
+ aria-describedby={step.description && showDescriptions ? `${id || 'step'}-${step.id}-desc` : undefined}
210
+ >
211
+ <!-- Circle indicator -->
212
+ <span
213
+ class="step-indicator-circle"
214
+ style="width: {config.circleWidth}; height: {config.circleHeight};"
215
+ >
216
+ {#if stepIcon}
217
+ {@render stepIcon({ step, index, state: step.state })}
218
+ {:else if step.state === 'completed'}
219
+ <Check size={config.iconSize} strokeWidth={3} aria-hidden="true" />
220
+ {:else if step.state === 'error'}
221
+ <X size={config.iconSize} strokeWidth={3} aria-hidden="true" />
222
+ {:else}
223
+ <span class="step-indicator-number" style="font-size: calc({config.fontSize} * 0.9);">
224
+ {index + 1}
225
+ </span>
226
+ {/if}
227
+ </span>
228
+
229
+ <!-- Label and description -->
230
+ {#if showLabels && variant !== 'minimal'}
231
+ <span class="step-indicator-content">
232
+ <span class="step-indicator-label" style="font-size: {config.fontSize};">
233
+ {step.label}
234
+ {#if step.optional}
235
+ <span class="step-indicator-optional">(optional)</span>
236
+ {/if}
237
+ </span>
238
+ {#if showDescriptions && step.description}
239
+ <span
240
+ id="{id || 'step'}-{step.id}-desc"
241
+ class="step-indicator-description"
242
+ style="font-size: {config.descriptionSize};"
243
+ >
244
+ {step.description}
245
+ </span>
246
+ {/if}
247
+ </span>
248
+ {/if}
249
+ </button>
250
+
251
+ <!-- Connector line -->
252
+ {#if index < steps.length - 1}
253
+ <div
254
+ class="step-indicator-line step-indicator-line-{getLineState(index)}"
255
+ style="--line-thickness: {config.lineThickness};"
256
+ aria-hidden="true"
257
+ ></div>
258
+ {/if}
259
+ </li>
260
+ {/each}
261
+ </ol>
262
+ </nav>
263
+ </div>
264
+
265
+ <style>
266
+ /* ========================================
267
+ BASE STYLES
268
+ ======================================== */
269
+ .step-indicator {
270
+ display: flex;
271
+ flex-direction: column;
272
+ }
273
+
274
+ .step-indicator-list {
275
+ display: flex;
276
+ list-style: none;
277
+ padding: 0;
278
+ margin: 0;
279
+ }
280
+
281
+ /* ========================================
282
+ HORIZONTAL ORIENTATION
283
+ ======================================== */
284
+ .step-indicator-horizontal .step-indicator-list {
285
+ flex-direction: row;
286
+ align-items: flex-start;
287
+ }
288
+
289
+ .step-indicator-horizontal .step-indicator-item {
290
+ display: flex;
291
+ align-items: center;
292
+ flex: 1;
293
+ }
294
+
295
+ .step-indicator-horizontal .step-indicator-item-last {
296
+ flex: 0;
297
+ }
298
+
299
+ .step-indicator-horizontal .step-indicator-step {
300
+ display: flex;
301
+ flex-direction: column;
302
+ align-items: center;
303
+ gap: 0.5rem;
304
+ background: none;
305
+ border: none;
306
+ padding: 0;
307
+ font: inherit;
308
+ cursor: default;
309
+ min-width: 0;
310
+ }
311
+
312
+ .step-indicator-horizontal .step-indicator-line {
313
+ flex: 1;
314
+ height: var(--line-thickness);
315
+ margin: 0 0.5rem;
316
+ border-radius: 9999px;
317
+ align-self: center;
318
+ margin-top: calc(-0.5rem - (var(--line-thickness) / 2));
319
+ }
320
+
321
+ .step-indicator-horizontal.step-indicator-default .step-indicator-line {
322
+ margin-top: 0;
323
+ align-self: flex-start;
324
+ transform: translateY(calc(1rem - (var(--line-thickness) / 2)));
325
+ }
326
+
327
+ .step-indicator-horizontal.step-indicator-sm .step-indicator-line {
328
+ transform: translateY(calc(0.75rem - (var(--line-thickness) / 2)));
329
+ }
330
+
331
+ .step-indicator-horizontal.step-indicator-lg .step-indicator-line {
332
+ transform: translateY(calc(1.25rem - (var(--line-thickness) / 2)));
333
+ }
334
+
335
+ /* ========================================
336
+ VERTICAL ORIENTATION
337
+ ======================================== */
338
+ .step-indicator-vertical .step-indicator-list {
339
+ flex-direction: column;
340
+ }
341
+
342
+ .step-indicator-vertical .step-indicator-item {
343
+ display: flex;
344
+ flex-direction: column;
345
+ }
346
+
347
+ .step-indicator-vertical .step-indicator-step {
348
+ display: flex;
349
+ flex-direction: row;
350
+ align-items: flex-start;
351
+ gap: 0.75rem;
352
+ background: none;
353
+ border: none;
354
+ padding: 0;
355
+ font: inherit;
356
+ cursor: default;
357
+ text-align: left;
358
+ }
359
+
360
+ .step-indicator-vertical .step-indicator-line {
361
+ width: var(--line-thickness);
362
+ min-height: 2rem;
363
+ margin-left: calc(1rem - (var(--line-thickness) / 2));
364
+ margin-top: 0.5rem;
365
+ margin-bottom: 0.5rem;
366
+ border-radius: 9999px;
367
+ }
368
+
369
+ .step-indicator-vertical.step-indicator-sm .step-indicator-line {
370
+ margin-left: calc(0.75rem - (var(--line-thickness) / 2));
371
+ }
372
+
373
+ .step-indicator-vertical.step-indicator-lg .step-indicator-line {
374
+ margin-left: calc(1.25rem - (var(--line-thickness) / 2));
375
+ }
376
+
377
+ /* ========================================
378
+ COMPACT VARIANT
379
+ ======================================== */
380
+ .step-indicator-compact .step-indicator-step {
381
+ flex-direction: row;
382
+ gap: 0.5rem;
383
+ }
384
+
385
+ .step-indicator-compact.step-indicator-horizontal .step-indicator-line {
386
+ transform: none;
387
+ align-self: center;
388
+ }
389
+
390
+ /* ========================================
391
+ MINIMAL VARIANT
392
+ ======================================== */
393
+ .step-indicator-minimal .step-indicator-step {
394
+ flex-direction: row;
395
+ }
396
+
397
+ /* ========================================
398
+ CIRCLE INDICATOR
399
+ ======================================== */
400
+ .step-indicator-circle {
401
+ display: flex;
402
+ align-items: center;
403
+ justify-content: center;
404
+ border-radius: 9999px;
405
+ font-weight: 600;
406
+ flex-shrink: 0;
407
+ transition: all 0.2s ease;
408
+ border: 2px solid transparent;
409
+ }
410
+
411
+ /* Pending state */
412
+ .step-indicator-step-pending .step-indicator-circle {
413
+ background-color: var(--ui-bg-tertiary);
414
+ color: var(--ui-text-tertiary);
415
+ border-color: var(--ui-border-default);
416
+ }
417
+
418
+ /* Active state */
419
+ .step-indicator-step-active .step-indicator-circle {
420
+ background-color: rgb(var(--ui-color-primary));
421
+ color: white;
422
+ border-color: rgb(var(--ui-color-primary));
423
+ }
424
+
425
+ /* Completed state */
426
+ .step-indicator-step-completed .step-indicator-circle {
427
+ background-color: rgb(var(--ui-color-success));
428
+ color: white;
429
+ border-color: rgb(var(--ui-color-success));
430
+ }
431
+
432
+ /* Error state */
433
+ .step-indicator-step-error .step-indicator-circle {
434
+ background-color: rgb(var(--ui-color-error));
435
+ color: white;
436
+ border-color: rgb(var(--ui-color-error));
437
+ }
438
+
439
+ /* ========================================
440
+ STEP NUMBER
441
+ ======================================== */
442
+ .step-indicator-number {
443
+ line-height: 1;
444
+ }
445
+
446
+ /* ========================================
447
+ CLICKABLE STEPS
448
+ ======================================== */
449
+ .step-indicator-step-clickable {
450
+ cursor: pointer;
451
+ }
452
+
453
+ .step-indicator-step-clickable:hover .step-indicator-circle {
454
+ transform: scale(1.05);
455
+ }
456
+
457
+ .step-indicator-step-clickable:active .step-indicator-circle {
458
+ transform: scale(0.98);
459
+ }
460
+
461
+ .step-indicator-step-clickable:focus-visible {
462
+ outline: none;
463
+ }
464
+
465
+ .step-indicator-step-clickable:focus-visible .step-indicator-circle {
466
+ box-shadow: 0 0 0 3px rgb(var(--ui-color-primary) / 0.3);
467
+ }
468
+
469
+ /* ========================================
470
+ CONTENT (LABEL + DESCRIPTION)
471
+ ======================================== */
472
+ .step-indicator-content {
473
+ display: flex;
474
+ flex-direction: column;
475
+ gap: 0.125rem;
476
+ min-width: 0;
477
+ }
478
+
479
+ .step-indicator-horizontal .step-indicator-content {
480
+ align-items: center;
481
+ text-align: center;
482
+ }
483
+
484
+ .step-indicator-vertical .step-indicator-content {
485
+ align-items: flex-start;
486
+ text-align: left;
487
+ padding-top: 0.125rem;
488
+ }
489
+
490
+ .step-indicator-label {
491
+ font-weight: 500;
492
+ color: var(--ui-text-secondary);
493
+ transition: color 0.2s ease;
494
+ line-height: 1.3;
495
+ }
496
+
497
+ .step-indicator-step-active .step-indicator-label {
498
+ color: var(--ui-text-primary);
499
+ font-weight: 600;
500
+ }
501
+
502
+ .step-indicator-step-completed .step-indicator-label {
503
+ color: var(--ui-text-primary);
504
+ }
505
+
506
+ .step-indicator-step-error .step-indicator-label {
507
+ color: rgb(var(--ui-color-error));
508
+ }
509
+
510
+ .step-indicator-optional {
511
+ font-weight: 400;
512
+ color: var(--ui-text-tertiary);
513
+ font-size: 0.8em;
514
+ }
515
+
516
+ .step-indicator-description {
517
+ color: var(--ui-text-tertiary);
518
+ line-height: 1.4;
519
+ }
520
+
521
+ /* ========================================
522
+ CONNECTOR LINES
523
+ ======================================== */
524
+ .step-indicator-line {
525
+ background-color: var(--ui-border-default);
526
+ transition: background-color 0.3s ease;
527
+ }
528
+
529
+ .step-indicator-line-completed {
530
+ background-color: rgb(var(--ui-color-success));
531
+ }
532
+
533
+ .step-indicator-line-active {
534
+ background: linear-gradient(
535
+ to right,
536
+ rgb(var(--ui-color-primary)) 0%,
537
+ var(--ui-border-default) 100%
538
+ );
539
+ }
540
+
541
+ .step-indicator-vertical .step-indicator-line-active {
542
+ background: linear-gradient(
543
+ to bottom,
544
+ rgb(var(--ui-color-primary)) 0%,
545
+ var(--ui-border-default) 100%
546
+ );
547
+ }
548
+
549
+ /* ========================================
550
+ PROGRESS SUMMARY
551
+ ======================================== */
552
+ .step-indicator-progress {
553
+ margin-bottom: 0.5rem;
554
+ }
555
+
556
+ .step-indicator-progress-text {
557
+ font-size: 0.8125rem;
558
+ font-weight: 500;
559
+ color: var(--ui-text-secondary);
560
+ }
561
+
562
+ /* ========================================
563
+ DISABLED STATE
564
+ ======================================== */
565
+ .step-indicator-step:disabled {
566
+ cursor: default;
567
+ }
568
+
569
+ .step-indicator-step-pending {
570
+ opacity: 0.6;
571
+ }
572
+
573
+ /* ========================================
574
+ REDUCED MOTION
575
+ ======================================== */
576
+ @media (prefers-reduced-motion: reduce) {
577
+ .step-indicator-circle,
578
+ .step-indicator-label,
579
+ .step-indicator-line,
580
+ .step-indicator-progress-fill {
581
+ transition: none;
582
+ }
583
+
584
+ .step-indicator-step-clickable:hover .step-indicator-circle {
585
+ transform: none;
586
+ }
587
+ }
588
+
589
+ /* ========================================
590
+ RESPONSIVE
591
+ ======================================== */
592
+ @media (max-width: 640px) {
593
+ .step-indicator-horizontal.step-indicator-default .step-indicator-content {
594
+ display: none;
595
+ }
596
+
597
+ .step-indicator-horizontal.step-indicator-default .step-indicator-line {
598
+ transform: translateY(calc(1rem - (var(--line-thickness) / 2)));
599
+ }
600
+ }
601
+ </style>
@@ -0,0 +1,70 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { Step, StepState } from '../../types/index.js';
3
+ type StepIndicatorSize = 'sm' | 'md' | 'lg';
4
+ type StepIndicatorVariant = 'default' | 'compact' | 'minimal';
5
+ type StepIndicatorOrientation = 'horizontal' | 'vertical';
6
+ interface Props {
7
+ /** Array of steps */
8
+ steps: Step[];
9
+ /** Size variant */
10
+ size?: StepIndicatorSize;
11
+ /** Display variant */
12
+ variant?: StepIndicatorVariant;
13
+ /** Layout orientation */
14
+ orientation?: StepIndicatorOrientation;
15
+ /** Whether to show labels */
16
+ showLabels?: boolean;
17
+ /** Whether to show step descriptions */
18
+ showDescriptions?: boolean;
19
+ /** Whether to show progress summary (e.g., "Step 2 of 5") */
20
+ showProgress?: boolean;
21
+ /** Custom progress format function */
22
+ progressFormat?: (current: number, total: number) => string;
23
+ /** Allow clicking on future steps (not just completed/active) */
24
+ allowFutureSteps?: boolean;
25
+ /** Custom icon snippet for steps */
26
+ stepIcon?: Snippet<[{
27
+ step: Step;
28
+ index: number;
29
+ state: StepState;
30
+ }]>;
31
+ /** Accessible label for the navigation */
32
+ ariaLabel?: string;
33
+ /** Additional CSS classes */
34
+ class?: string;
35
+ /** ID for the component */
36
+ id?: string;
37
+ /** Step click handler */
38
+ onStepClick?: (step: Step, index: number) => void;
39
+ }
40
+ /**
41
+ * StepIndicator
42
+ *
43
+ * A world-class step indicator component for multi-step healthcare workflows.
44
+ * Designed with full accessibility, clear visual states, and flexible layouts.
45
+ *
46
+ * Features:
47
+ * - Horizontal and vertical orientations
48
+ * - Size variants (sm, md, lg)
49
+ * - Step descriptions and substeps
50
+ * - Custom icons per step
51
+ * - Optional step indicators
52
+ * - Warning and error states
53
+ * - Progress summary display
54
+ * - Full keyboard navigation
55
+ * - Screen reader announcements
56
+ *
57
+ * @example
58
+ * <StepIndicator
59
+ * steps={[
60
+ * { id: 'patient', label: 'Patient Info', description: 'Enter patient details', state: 'completed' },
61
+ * { id: 'insurance', label: 'Insurance', state: 'active' },
62
+ * { id: 'verify', label: 'Verify', state: 'pending', optional: true }
63
+ * ]}
64
+ * showProgress
65
+ * />
66
+ */
67
+ declare const StepIndicator: import("svelte").Component<Props, {}, "">;
68
+ type StepIndicator = ReturnType<typeof StepIndicator>;
69
+ export default StepIndicator;
70
+ //# sourceMappingURL=StepIndicator.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepIndicator.svelte.d.ts","sourceRoot":"","sources":["../../../src/navigation/StepIndicator/StepIndicator.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAG3D,KAAK,iBAAiB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC5C,KAAK,oBAAoB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAC9D,KAAK,wBAAwB,GAAG,YAAY,GAAG,UAAU,CAAC;AAE1D,UAAU,KAAK;IACd,qBAAqB;IACrB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,mBAAmB;IACnB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,sBAAsB;IACtB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,yBAAyB;IACzB,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,6BAA6B;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sCAAsC;IACtC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5D,iEAAiE;IACjE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC,CAAC;IACtE,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAsLF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as StepIndicator } from './StepIndicator.svelte';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/navigation/StepIndicator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1 @@
1
+ export { default as StepIndicator } from './StepIndicator.svelte';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @synthaxai/ui - Navigation Components
3
+ *
4
+ * Components for navigation and multi-step workflows.
5
+ */
6
+ export { StepIndicator } from './StepIndicator/index.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/navigation/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @synthaxai/ui - Navigation Components
3
+ *
4
+ * Components for navigation and multi-step workflows.
5
+ */
6
+ export { StepIndicator } from './StepIndicator/index.js';