@reshape-biotech/design-system 0.0.54 → 1.1.2

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 (181) hide show
  1. package/dist/components/activity/Activity.stories.svelte +21 -8
  2. package/dist/components/activity/Activity.svelte +44 -6
  3. package/dist/components/activity/Activity.svelte.d.ts +1 -1
  4. package/dist/components/avatar/Avatar.stories.svelte +7 -17
  5. package/dist/components/avatar/Avatar.svelte +2 -2
  6. package/dist/components/avatar/Avatar.svelte.d.ts +2 -2
  7. package/dist/components/banner/Banner.stories.svelte +5 -5
  8. package/dist/components/banner/Banner.svelte +1 -1
  9. package/dist/components/button/Button.stories.svelte +54 -21
  10. package/dist/components/button/Button.svelte +58 -11
  11. package/dist/components/button/Button.svelte.d.ts +4 -3
  12. package/dist/components/card/Card.stories.svelte +130 -0
  13. package/dist/components/card/Card.stories.svelte.d.ts +19 -0
  14. package/dist/components/card/Card.svelte +25 -0
  15. package/dist/components/card/Card.svelte.d.ts +10 -0
  16. package/dist/components/card/index.d.ts +1 -0
  17. package/dist/components/card/index.js +1 -0
  18. package/dist/components/checkbox/Checkbox.stories.svelte +7 -15
  19. package/dist/components/checkbox/Checkbox.svelte +7 -7
  20. package/dist/components/checkbox/Checkbox.svelte.d.ts +3 -5
  21. package/dist/components/collapsible/Collapsible.stories.svelte +5 -4
  22. package/dist/components/combobox/Combobox.stories.svelte +7 -5
  23. package/dist/components/datepicker/DatePicker.stories.svelte +13 -18
  24. package/dist/components/datepicker/DatePicker.svelte +1 -0
  25. package/dist/components/divider/Divider.stories.svelte +1 -3
  26. package/dist/components/divider/Divider.svelte +8 -2
  27. package/dist/components/divider/Divider.svelte.d.ts +2 -0
  28. package/dist/components/drawer/Drawer.stories.svelte +3 -3
  29. package/dist/components/dropdown/Dropdown.stories.svelte +8 -8
  30. package/dist/components/empty-content/EmptyContent.stories.svelte +2 -2
  31. package/dist/components/graphs/bar-chart/BarChart.stories.svelte +81 -0
  32. package/dist/components/graphs/bar-chart/BarChart.stories.svelte.d.ts +19 -0
  33. package/dist/components/graphs/bar-chart/BarChart.svelte +136 -0
  34. package/dist/components/graphs/bar-chart/BarChart.svelte.d.ts +15 -0
  35. package/dist/components/graphs/bar-chart/StackedBarChart.stories.svelte +42 -0
  36. package/dist/components/graphs/bar-chart/StackedBarChart.stories.svelte.d.ts +19 -0
  37. package/dist/components/graphs/bar-chart/StackedBarChart.svelte +177 -0
  38. package/dist/components/graphs/bar-chart/StackedBarChart.svelte.d.ts +16 -0
  39. package/dist/components/graphs/chart/Chart.stories.svelte +30 -25
  40. package/dist/components/graphs/chart/Chart.svelte +104 -32
  41. package/dist/components/graphs/chart/Chart.svelte.d.ts +15 -5
  42. package/dist/components/graphs/index.d.ts +3 -0
  43. package/dist/components/graphs/index.js +3 -0
  44. package/dist/components/graphs/line/LineChart.stories.svelte +97 -17
  45. package/dist/components/graphs/line/LineChart.svelte +90 -51
  46. package/dist/components/graphs/line/LineChart.svelte.d.ts +6 -13
  47. package/dist/components/graphs/matrix/Matrix.stories.svelte +142 -0
  48. package/dist/components/graphs/matrix/Matrix.stories.svelte.d.ts +19 -0
  49. package/dist/components/graphs/matrix/Matrix.svelte +149 -0
  50. package/dist/components/graphs/matrix/Matrix.svelte.d.ts +24 -0
  51. package/dist/components/graphs/matrix/index.d.ts +3 -0
  52. package/dist/components/graphs/matrix/index.js +3 -0
  53. package/dist/components/graphs/multiline/MultiLineChart.stories.svelte +115 -28
  54. package/dist/components/graphs/multiline/MultiLineChart.svelte +187 -50
  55. package/dist/components/graphs/multiline/MultiLineChart.svelte.d.ts +9 -12
  56. package/dist/components/graphs/scatterplot/Scatterplot.stories.svelte +68 -41
  57. package/dist/components/graphs/scatterplot/Scatterplot.svelte +312 -45
  58. package/dist/components/graphs/scatterplot/Scatterplot.svelte.d.ts +23 -13
  59. package/dist/components/graphs/utils/tooltipFormatter.d.ts +10 -0
  60. package/dist/components/graphs/utils/tooltipFormatter.js +52 -0
  61. package/dist/components/icon-button/IconButton.stories.svelte +6 -6
  62. package/dist/components/icon-button/IconButton.svelte +50 -9
  63. package/dist/components/icon-button/IconButton.svelte.d.ts +3 -5
  64. package/dist/components/icons/AnalysisIcon.stories.svelte +15 -21
  65. package/dist/components/icons/AnalysisIcon.svelte +63 -44
  66. package/dist/components/icons/AnalysisIcon.svelte.d.ts +1 -0
  67. package/dist/components/icons/Icon.stories.svelte +4 -4
  68. package/dist/components/icons/Icon.svelte +1 -1
  69. package/dist/components/icons/PrincipalIcon.svelte +96 -0
  70. package/dist/components/icons/PrincipalIcon.svelte.d.ts +10 -0
  71. package/dist/components/icons/custom/Halo.svelte +14 -8
  72. package/dist/components/icons/custom/Halo.svelte.d.ts +7 -25
  73. package/dist/components/icons/custom/Well.svelte +14 -6
  74. package/dist/components/icons/custom/Well.svelte.d.ts +7 -25
  75. package/dist/components/icons/index.d.ts +3 -2
  76. package/dist/components/icons/index.js +34 -0
  77. package/dist/components/input/Input.stories.svelte +16 -22
  78. package/dist/components/input/Input.svelte +140 -134
  79. package/dist/components/input/Input.svelte.d.ts +12 -13
  80. package/dist/components/label/Label.stories.svelte +28 -0
  81. package/dist/components/label/Label.stories.svelte.d.ts +19 -0
  82. package/dist/components/label/Label.svelte +17 -0
  83. package/dist/components/label/Label.svelte.d.ts +9 -0
  84. package/dist/components/list/List.stories.svelte +3 -3
  85. package/dist/components/logo/Logo.stories.svelte +1 -1
  86. package/dist/components/manual-cfu-counter/ManualCFUCounter.stories.svelte +125 -0
  87. package/dist/components/manual-cfu-counter/ManualCFUCounter.stories.svelte.d.ts +3 -0
  88. package/dist/components/manual-cfu-counter/ManualCFUCounter.svelte +577 -0
  89. package/dist/components/manual-cfu-counter/ManualCFUCounter.svelte.d.ts +16 -0
  90. package/dist/components/manual-cfu-counter/index.d.ts +1 -0
  91. package/dist/components/manual-cfu-counter/index.js +1 -0
  92. package/dist/components/manual-cfu-counter/test/ManualCFUCounterTestWrapper.svelte +22 -0
  93. package/dist/components/manual-cfu-counter/test/ManualCFUCounterTestWrapper.svelte.d.ts +19 -0
  94. package/dist/components/markdown/Markdown.stories.svelte +1 -1
  95. package/dist/components/markdown/Markdown.svelte +1 -1
  96. package/dist/components/modal/Modal.stories.svelte +2 -2
  97. package/dist/components/modal/Modal.svelte +27 -22
  98. package/dist/components/modal/Modal.svelte.d.ts +4 -1
  99. package/dist/components/notification-popup/NotificationPopup.stories.svelte +1 -1
  100. package/dist/components/pill/Pill.stories.svelte +13 -0
  101. package/dist/components/pill/Pill.stories.svelte.d.ts +19 -0
  102. package/dist/components/progress-circle/ProgressCircle.stories.svelte +15 -0
  103. package/dist/components/progress-circle/ProgressCircle.stories.svelte.d.ts +19 -0
  104. package/dist/components/required-status-indicator/RequiredStatusIndicator.stories.svelte +28 -0
  105. package/dist/components/required-status-indicator/RequiredStatusIndicator.stories.svelte.d.ts +19 -0
  106. package/dist/components/required-status-indicator/RequiredStatusIndicator.svelte +22 -0
  107. package/dist/components/required-status-indicator/RequiredStatusIndicator.svelte.d.ts +8 -0
  108. package/dist/components/required-status-indicator/index.d.ts +1 -0
  109. package/dist/components/required-status-indicator/index.js +1 -0
  110. package/dist/components/segmented-control-buttons/SegmentedControlButtons.stories.svelte +3 -3
  111. package/dist/components/select/Select.stories.svelte +12 -12
  112. package/dist/components/select/Select.svelte +0 -2
  113. package/dist/components/select-new/Select.stories.svelte +219 -0
  114. package/dist/components/select-new/Select.stories.svelte.d.ts +19 -0
  115. package/dist/components/select-new/components/Group.svelte +24 -0
  116. package/dist/components/select-new/components/Group.svelte.d.ts +11 -0
  117. package/dist/components/select-new/components/MultiSelectTrigger.svelte +66 -0
  118. package/dist/components/select-new/components/MultiSelectTrigger.svelte.d.ts +17 -0
  119. package/dist/components/select-new/components/SelectContent.svelte +33 -0
  120. package/dist/components/select-new/components/SelectContent.svelte.d.ts +10 -0
  121. package/dist/components/select-new/components/SelectGroupHeading.svelte +19 -0
  122. package/dist/components/select-new/components/SelectGroupHeading.svelte.d.ts +9 -0
  123. package/dist/components/select-new/components/SelectItem.svelte +41 -0
  124. package/dist/components/select-new/components/SelectItem.svelte.d.ts +9 -0
  125. package/dist/components/select-new/components/SelectTrigger.svelte +48 -0
  126. package/dist/components/select-new/components/SelectTrigger.svelte.d.ts +12 -0
  127. package/dist/components/select-new/index.d.ts +10 -0
  128. package/dist/components/select-new/index.js +12 -0
  129. package/dist/components/select-new/types.d.ts +25 -0
  130. package/dist/components/select-new/types.js +1 -0
  131. package/dist/components/sjsf-wrappers/SjsfNumberInputWrapper.svelte +92 -0
  132. package/dist/components/sjsf-wrappers/SjsfNumberInputWrapper.svelte.d.ts +3 -0
  133. package/dist/components/sjsf-wrappers/SjsfTextInputWrapper.svelte +65 -0
  134. package/dist/components/sjsf-wrappers/SjsfTextInputWrapper.svelte.d.ts +3 -0
  135. package/dist/components/sjsf-wrappers/index.d.ts +2 -0
  136. package/dist/components/sjsf-wrappers/index.js +2 -0
  137. package/dist/components/sjsf-wrappers/sjsfCustomTheme.d.ts +2 -0
  138. package/dist/components/sjsf-wrappers/sjsfCustomTheme.js +8 -0
  139. package/dist/components/skeleton-loader/SkeletonLoader.stories.svelte +4 -4
  140. package/dist/components/slider/Slider.stories.svelte +4 -4
  141. package/dist/components/spinner/Spinner.stories.svelte +13 -0
  142. package/dist/components/spinner/Spinner.stories.svelte.d.ts +19 -0
  143. package/dist/components/stat-card/StatCard.stories.svelte +27 -19
  144. package/dist/components/stat-card/StatCard.svelte +100 -6
  145. package/dist/components/stat-card/StatCard.svelte.d.ts +3 -0
  146. package/dist/components/status-badge/StatusBadge.stories.svelte +6 -6
  147. package/dist/components/status-badge/StatusBadge.svelte +5 -3
  148. package/dist/components/stepper/Stepper.stories.svelte +243 -0
  149. package/dist/components/stepper/Stepper.stories.svelte.d.ts +19 -0
  150. package/dist/components/stepper/components/stepper-root.svelte +20 -0
  151. package/dist/components/stepper/components/stepper-root.svelte.d.ts +9 -0
  152. package/dist/components/stepper/components/stepper-step.svelte +100 -0
  153. package/dist/components/stepper/components/stepper-step.svelte.d.ts +11 -0
  154. package/dist/components/stepper/index.d.ts +15 -0
  155. package/dist/components/stepper/index.js +2 -0
  156. package/dist/components/table/Table.stories.svelte +1 -1
  157. package/dist/components/table/components/Td.svelte +3 -2
  158. package/dist/components/table/components/Td.svelte.d.ts +1 -0
  159. package/dist/components/table/components/Tr.svelte +3 -2
  160. package/dist/components/table/components/Tr.svelte.d.ts +1 -0
  161. package/dist/components/tabs/Tabs.stories.svelte +1 -1
  162. package/dist/components/tag/Tag.stories.svelte +9 -9
  163. package/dist/components/tag/Tag.svelte +0 -18
  164. package/dist/components/textarea/Textarea.stories.svelte +97 -0
  165. package/dist/components/textarea/Textarea.stories.svelte.d.ts +19 -0
  166. package/dist/components/textarea/Textarea.svelte +94 -0
  167. package/dist/components/textarea/Textarea.svelte.d.ts +17 -0
  168. package/dist/components/textarea/index.d.ts +1 -0
  169. package/dist/components/textarea/index.js +1 -0
  170. package/dist/components/toggle/Toggle.stories.svelte +1 -1
  171. package/dist/components/toggle/Toggle.svelte +3 -2
  172. package/dist/components/toggle/Toggle.svelte.d.ts +1 -0
  173. package/dist/components/toggle-icon-button/ToggleIconButton.stories.svelte +6 -6
  174. package/dist/components/tooltip/Tooltip.stories.svelte +6 -6
  175. package/dist/components/tooltip/Tooltip.svelte +1 -1
  176. package/dist/index.d.ts +7 -0
  177. package/dist/index.js +7 -0
  178. package/dist/tailwind.preset.d.ts +5 -0
  179. package/dist/tokens.d.ts +10 -0
  180. package/dist/tokens.js +6 -4
  181. package/package.json +1 -2
@@ -9,24 +9,32 @@
9
9
  });
10
10
  </script>
11
11
 
12
- <Story name="Default">
13
- <StatCard title="Title" value="Value" unit="unit" titleTooltip="Title tooltip" />
14
- </Story>
12
+ <Story
13
+ name="Default"
14
+ args={{ title: 'Title', value: 'Value', unit: 'unit', titleTooltip: 'Title tooltip' }}
15
+ />
15
16
 
16
- <Story name="Germination Rate">
17
- <StatCard
18
- title="Germination Rate"
19
- value="2"
20
- unit="%"
21
- titleTooltip="Something that explains what this is..."
22
- showTitleTooltip={true}
23
- />
24
- </Story>
17
+ <Story
18
+ name="Germination Rate"
19
+ args={{
20
+ title: 'Germination Rate',
21
+ value: '2',
22
+ unit: '%',
23
+ titleTooltip: 'Something that explains what this is...',
24
+ showTitleTooltip: true
25
+ }}
26
+ />
25
27
 
26
- <Story name="Home Page">
27
- <div class="flex w-full gap-4">
28
- <StatCard title="Current jobs" value="3" unit="of 5" />
29
- <StatCard title="Run time" value="5.4" unit="hours" />
30
- <StatCard title="Images taken" value="1366" />
31
- </div>
32
- </Story>
28
+ <Story name="Home Page" args={{ title: 'Current jobs', value: '3', unit: 'of 5' }} />
29
+
30
+ <Story
31
+ name="Editable"
32
+ args={{
33
+ title: 'Germination Rate',
34
+ value: '2',
35
+ unit: '%',
36
+ titleTooltip: 'Something that explains what this is...',
37
+ showTitleTooltip: true,
38
+ editable: true
39
+ }}
40
+ />
@@ -1,7 +1,10 @@
1
1
  <script lang="ts">
2
+ import IconButton from '../icon-button/IconButton.svelte';
2
3
  import { Icon } from '../icons';
3
4
  import Spinner from '../spinner/Spinner.svelte';
4
5
  import Tooltip from '../tooltip/Tooltip.svelte';
6
+ import { Input } from '../input';
7
+ import { tick } from 'svelte';
5
8
 
6
9
  interface Props {
7
10
  title: string;
@@ -9,6 +12,9 @@
9
12
  unit?: string | null;
10
13
  titleTooltip?: string;
11
14
  showTitleTooltip?: boolean;
15
+ editable?: boolean;
16
+ onsubmit?: (value: string | number) => void;
17
+ inputType?: 'text' | 'number';
12
18
  }
13
19
 
14
20
  let {
@@ -16,13 +22,82 @@
16
22
  value = null,
17
23
  unit = '',
18
24
  titleTooltip = '',
19
- showTitleTooltip = false
25
+ showTitleTooltip = false,
26
+ editable = false,
27
+ inputType = 'text',
28
+ onsubmit
20
29
  }: Props = $props();
21
30
  const formattedValue = $derived(typeof value === 'number' ? value.toLocaleString() : value);
31
+ let isEditing = $state(false);
32
+ let inputValue = $state('');
33
+ let inputComponent = $state<Input | null>(null);
34
+
35
+ function startEditing(event?: MouseEvent) {
36
+ if (event) {
37
+ event.stopPropagation();
38
+ }
39
+ isEditing = true;
40
+ inputValue = value !== null ? value.toString() : '';
41
+ }
42
+
43
+ function handleCardClick() {
44
+ if (editable && !isEditing && value !== null) {
45
+ startEditing();
46
+ }
47
+ }
48
+
49
+ function handleInputBlur(event: Event) {
50
+ const target = event.target as HTMLInputElement;
51
+ inputValue = target.value;
52
+ submitValue();
53
+ }
54
+
55
+ function handleInputKeydown(event: KeyboardEvent) {
56
+ const target = event.target as HTMLInputElement;
57
+ inputValue = target.value;
58
+ if (event.key === 'Escape') {
59
+ isEditing = false;
60
+ }
61
+ if (event.key === 'Enter') {
62
+ submitValue();
63
+ }
64
+ }
65
+
66
+ function submitValue() {
67
+ if (inputValue.trim() === '') {
68
+ isEditing = false;
69
+ return;
70
+ }
71
+
72
+ // Try to parse as number if possible
73
+ const numValue = parseFloat(inputValue);
74
+ const newValue = isNaN(numValue) ? inputValue : numValue;
75
+
76
+ if (onsubmit) {
77
+ onsubmit(newValue);
78
+ }
79
+
80
+ isEditing = false;
81
+ }
82
+
83
+ $effect(() => {
84
+ if (isEditing && inputComponent) {
85
+ tick().then(() => {
86
+ inputComponent?.focus();
87
+ });
88
+ }
89
+ });
22
90
  </script>
23
91
 
92
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
24
93
  <div
25
- class="flex w-full flex-shrink-0 flex-grow basis-0 flex-col items-start gap-2 overflow-clip rounded-lg bg-neutral p-4"
94
+ data-testid="stat-card-body"
95
+ class="flex w-full flex-shrink-0 flex-grow basis-0 flex-col items-start gap-2 overflow-clip rounded-lg bg-neutral p-4 text-left transition-colors"
96
+ class:hover:bg-neutral-hover={editable && !isEditing && value !== null}
97
+ class:cursor-pointer={editable && !isEditing && value !== null}
98
+ onclick={editable && !isEditing && value !== null ? handleCardClick : undefined}
99
+ onkeydown={editable && !isEditing && value !== null ? handleInputKeydown : undefined}
100
+ aria-label={editable && !isEditing && value !== null ? `Edit ${title}` : undefined}
26
101
  >
27
102
  <p class="flex items-center justify-start gap-2 truncate font-medium text-secondary">
28
103
  {title}
@@ -39,11 +114,30 @@
39
114
  </Tooltip>
40
115
  {/if}
41
116
  </p>
42
- <div class="flex items-baseline gap-1">
117
+ <div class="flex h-10 w-full items-center gap-1">
43
118
  {#if value !== null}
44
- <p class="text-2xl font-medium">{formattedValue}</p>
45
- {#if unit}
46
- <p class="truncate text-2xl font-medium text-tertiary">{unit}</p>
119
+ {#if isEditing}
120
+ <div class="flex-1">
121
+ <Input
122
+ bind:this={inputComponent}
123
+ type={inputType}
124
+ value={inputValue}
125
+ onblur={handleInputBlur}
126
+ onkeydown={handleInputKeydown}
127
+ />
128
+ </div>
129
+ {:else}
130
+ <div class="flex flex-1 flex-nowrap items-baseline gap-1">
131
+ <p class="text-2xl font-medium">{formattedValue}</p>
132
+ {#if unit}
133
+ <p class="flex-1 truncate text-2xl font-medium text-tertiary">{unit}</p>
134
+ {/if}
135
+ </div>
136
+ {#if editable}
137
+ <IconButton onclick={(e) => startEditing(e)}>
138
+ <Icon iconName="PencilSimple" />
139
+ </IconButton>
140
+ {/if}
47
141
  {/if}
48
142
  {:else}
49
143
  <Spinner />
@@ -4,6 +4,9 @@ interface Props {
4
4
  unit?: string | null;
5
5
  titleTooltip?: string;
6
6
  showTitleTooltip?: boolean;
7
+ editable?: boolean;
8
+ onsubmit?: (value: string | number) => void;
9
+ inputType?: 'text' | 'number';
7
10
  }
8
11
  declare const StatCard: import("svelte").Component<Props, {}, "">;
9
12
  type StatCard = ReturnType<typeof StatCard>;
@@ -14,7 +14,7 @@
14
14
  let calculated_progress = 32;
15
15
  </script>
16
16
 
17
- <Story name="Neutral">
17
+ <Story name="Neutral" asChild>
18
18
  <p class="font-mono text-xs">Medium:</p>
19
19
  <div class="flex flex-row gap-4">
20
20
  <div class="flex flex-row gap-1">
@@ -84,7 +84,7 @@
84
84
  </div>
85
85
  </Story>
86
86
 
87
- <Story name="Success">
87
+ <Story name="Success" asChild>
88
88
  <p class="font-mono text-xs">Medium:</p>
89
89
  <div class="flex flex-row gap-4">
90
90
  <div class="flex flex-row gap-1">
@@ -198,7 +198,7 @@
198
198
  </div>
199
199
  </Story>
200
200
 
201
- <Story name="Progress">
201
+ <Story name="Progress" asChild>
202
202
  <p class="font-mono text-xs">Medium:</p>
203
203
  <div class="flex flex-row gap-1">
204
204
  <Tooltip>
@@ -268,7 +268,7 @@
268
268
  </div>
269
269
  </Story>
270
270
 
271
- <Story name="Warning">
271
+ <Story name="Warning" asChild>
272
272
  <p class="font-mono text-xs">Medium:</p>
273
273
  <div class="flex flex-row gap-1">
274
274
  <Tooltip>
@@ -326,7 +326,7 @@
326
326
  </div>
327
327
  </Story>
328
328
 
329
- <Story name="Error">
329
+ <Story name="Error" asChild>
330
330
  <p class="font-mono text-xs">Medium:</p>
331
331
  <div class="flex flex-row gap-1">
332
332
  <Tooltip>
@@ -384,7 +384,7 @@
384
384
  </div>
385
385
  </Story>
386
386
 
387
- <Story name="Icon only">
387
+ <Story name="Icon only" asChild>
388
388
  <StatusBadge type="neutral" iconOnly>
389
389
  {#snippet icon()}
390
390
  <Icon iconName="SpinnerGap" />
@@ -28,9 +28,11 @@
28
28
  class:badge-icon-only={iconOnly}
29
29
  data-testid="status-badge"
30
30
  >
31
- <div class={`icon`}>
32
- {@render icon?.()}
33
- </div>
31
+ {#if icon}
32
+ <div class={`icon`}>
33
+ {@render icon?.()}
34
+ </div>
35
+ {/if}
34
36
  <div class="gap-2">
35
37
  {@render content?.()}
36
38
  {@render progress?.()}
@@ -0,0 +1,243 @@
1
+ <script module lang="ts">
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import * as Stepper from './index';
4
+ import StepperComponent from './components/stepper-root.svelte';
5
+
6
+ const { Story } = defineMeta({
7
+ title: 'Design System/Stepper',
8
+ component: StepperComponent,
9
+ tags: ['autodocs'],
10
+ argTypes: {
11
+ class: { control: 'text', description: 'Additional CSS classes' },
12
+ currentStep: { control: 'text', description: 'The currently active step identifier' }
13
+ }
14
+ });
15
+ </script>
16
+
17
+ <Story name="Controlled by Root">
18
+ <div class="space-y-8 p-4">
19
+ <div>
20
+ <h3 class="mb-4 text-lg font-medium">Stepper controlled by currentStep prop</h3>
21
+ <div class="max-w-sm">
22
+ <Stepper.Root currentStep="2">
23
+ <Stepper.Step stepNumber="1">Configure experiment</Stepper.Step>
24
+ <Stepper.Step stepNumber="2">Set run conditions</Stepper.Step>
25
+ <Stepper.Step stepNumber="3">Approve plate maps</Stepper.Step>
26
+ <Stepper.Step stepNumber="4">Review</Stepper.Step>
27
+ </Stepper.Root>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </Story>
32
+
33
+ <Story name="Non-Numeric Steps">
34
+ <div class="space-y-8 p-4">
35
+ <div>
36
+ <h3 class="mb-4 text-lg font-medium">Stepper with Letter-based Steps</h3>
37
+ <div class="max-w-sm">
38
+ <Stepper.Root currentStep="B">
39
+ <Stepper.Step stepNumber="A">Configure</Stepper.Step>
40
+ <Stepper.Step stepNumber="B">Process</Stepper.Step>
41
+ <Stepper.Step stepNumber="C">Complete</Stepper.Step>
42
+ </Stepper.Root>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </Story>
47
+
48
+ <Story name="All States (Individually set)">
49
+ <div class="space-y-8 p-4">
50
+ <div>
51
+ <h3 class="mb-4 text-lg font-medium">Individual Step States</h3>
52
+ <div class="grid grid-cols-1 gap-6 md:grid-cols-3">
53
+ <div>
54
+ <h4 class="mb-2 text-sm font-medium text-secondary">Completed State</h4>
55
+ <div class="max-w-sm">
56
+ <Stepper.Root>
57
+ <Stepper.Step state="completed" stepNumber="1">Configure experiment</Stepper.Step>
58
+ </Stepper.Root>
59
+ </div>
60
+ </div>
61
+ <div>
62
+ <h4 class="mb-2 text-sm font-medium text-secondary">Active State</h4>
63
+ <div class="max-w-sm">
64
+ <Stepper.Root>
65
+ <Stepper.Step state="active" stepNumber="2">Set run conditions</Stepper.Step>
66
+ </Stepper.Root>
67
+ </div>
68
+ </div>
69
+ <div>
70
+ <h4 class="mb-2 text-sm font-medium text-secondary">Future State</h4>
71
+ <div class="max-w-sm">
72
+ <Stepper.Root>
73
+ <Stepper.Step state="future" stepNumber="3">Approve plate maps</Stepper.Step>
74
+ </Stepper.Root>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </Story>
81
+
82
+ <Story name="Progress Examples">
83
+ <div class="space-y-8 p-4">
84
+ <div>
85
+ <h3 class="mb-4 text-lg font-medium">Progress States</h3>
86
+ <div class="grid grid-cols-1 gap-8 lg:grid-cols-2">
87
+ <div>
88
+ <h4 class="mb-2 text-sm font-medium text-secondary">Start State</h4>
89
+ <div class="max-w-sm">
90
+ <Stepper.Root currentStep="1">
91
+ <Stepper.Step stepNumber="1">Configure experiment</Stepper.Step>
92
+ <Stepper.Step stepNumber="2">Set run conditions</Stepper.Step>
93
+ <Stepper.Step stepNumber="3">Approve plate maps</Stepper.Step>
94
+ <Stepper.Step stepNumber="4">Review</Stepper.Step>
95
+ </Stepper.Root>
96
+ </div>
97
+ </div>
98
+ <div>
99
+ <h4 class="mb-2 text-sm font-medium text-secondary">Mid Progress</h4>
100
+ <div class="max-w-sm">
101
+ <Stepper.Root currentStep="3">
102
+ <Stepper.Step stepNumber="1">Configure experiment</Stepper.Step>
103
+ <Stepper.Step stepNumber="2">Set run conditions</Stepper.Step>
104
+ <Stepper.Step stepNumber="3">Approve plate maps</Stepper.Step>
105
+ <Stepper.Step stepNumber="4">Review</Stepper.Step>
106
+ </Stepper.Root>
107
+ </div>
108
+ </div>
109
+ <div>
110
+ <h4 class="mb-2 text-sm font-medium text-secondary">Almost Complete</h4>
111
+ <div class="max-w-sm">
112
+ <Stepper.Root currentStep="4">
113
+ <Stepper.Step stepNumber="1">Configure experiment</Stepper.Step>
114
+ <Stepper.Step stepNumber="2">Set run conditions</Stepper.Step>
115
+ <Stepper.Step stepNumber="3">Approve plate maps</Stepper.Step>
116
+ <Stepper.Step stepNumber="4">Review</Stepper.Step>
117
+ </Stepper.Root>
118
+ </div>
119
+ </div>
120
+ <div>
121
+ <h4 class="mb-2 text-sm font-medium text-secondary">All Complete</h4>
122
+ <div class="max-w-sm">
123
+ <!-- To show all as complete, set currentStep to a non-existent step after the last one -->
124
+ <Stepper.Root currentStep="5">
125
+ <Stepper.Step stepNumber="1">Configure experiment</Stepper.Step>
126
+ <Stepper.Step stepNumber="2">Set run conditions</Stepper.Step>
127
+ <Stepper.Step stepNumber="3">Approve plate maps</Stepper.Step>
128
+ <Stepper.Step stepNumber="4">Review</Stepper.Step>
129
+ </Stepper.Root>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ </Story>
136
+
137
+ <Story name="Different Step Counts">
138
+ <div class="space-y-8 p-4">
139
+ <div>
140
+ <h3 class="mb-4 text-lg font-medium">Various Step Configurations</h3>
141
+ <div class="grid grid-cols-1 gap-8 lg:grid-cols-2">
142
+ <div>
143
+ <h4 class="mb-2 text-sm font-medium text-secondary">Two Steps</h4>
144
+ <div class="max-w-sm">
145
+ <Stepper.Root currentStep="1">
146
+ <Stepper.Step stepNumber="1">Setup</Stepper.Step>
147
+ <Stepper.Step stepNumber="2">Review</Stepper.Step>
148
+ </Stepper.Root>
149
+ </div>
150
+ </div>
151
+ <div>
152
+ <h4 class="mb-2 text-sm font-medium text-secondary">Three Steps</h4>
153
+ <div class="max-w-sm">
154
+ <Stepper.Root currentStep="2">
155
+ <Stepper.Step stepNumber="1">Configure</Stepper.Step>
156
+ <Stepper.Step stepNumber="2">Process</Stepper.Step>
157
+ <Stepper.Step stepNumber="3">Complete</Stepper.Step>
158
+ </Stepper.Root>
159
+ </div>
160
+ </div>
161
+ <div>
162
+ <h4 class="mb-2 text-sm font-medium text-secondary">Five Steps</h4>
163
+ <div class="max-w-sm">
164
+ <Stepper.Root currentStep="3">
165
+ <Stepper.Step stepNumber="1">Initialize</Stepper.Step>
166
+ <Stepper.Step stepNumber="2">Configure</Stepper.Step>
167
+ <Stepper.Step stepNumber="3">Process</Stepper.Step>
168
+ <Stepper.Step stepNumber="4">Validate</Stepper.Step>
169
+ <Stepper.Step stepNumber="5">Complete</Stepper.Step>
170
+ </Stepper.Root>
171
+ </div>
172
+ </div>
173
+ <div>
174
+ <h4 class="mb-2 text-sm font-medium text-secondary">Single Step</h4>
175
+ <div class="max-w-sm">
176
+ <Stepper.Root currentStep="1">
177
+ <Stepper.Step stepNumber="1">Single action step</Stepper.Step>
178
+ </Stepper.Root>
179
+ </div>
180
+ </div>
181
+ </div>
182
+ </div>
183
+ </div>
184
+ </Story>
185
+
186
+ <Story name="Custom Styling">
187
+ <div class="space-y-8 p-4">
188
+ <div>
189
+ <h3 class="mb-4 text-lg font-medium">Custom Classes</h3>
190
+ <div class="max-w-sm">
191
+ <Stepper.Root currentStep="2" class="rounded-lg border bg-surface p-4">
192
+ <Stepper.Step stepNumber="1" class="font-bold">Configure experiment</Stepper.Step>
193
+ <Stepper.Step stepNumber="2" class="font-bold">Set run conditions</Stepper.Step>
194
+ <Stepper.Step stepNumber="3" class="font-bold">Approve plate maps</Stepper.Step>
195
+ </Stepper.Root>
196
+ </div>
197
+ </div>
198
+ </div>
199
+ </Story>
200
+
201
+ <Story name="Responsive Behavior">
202
+ <div class="space-y-8 p-4">
203
+ <div>
204
+ <h3 class="mb-4 text-lg font-medium">Text Truncation</h3>
205
+ <div class="space-y-6">
206
+ <div>
207
+ <h4 class="mb-2 text-sm font-medium text-secondary">Normal Width (224px - Figma spec)</h4>
208
+ <div class="w-56">
209
+ <Stepper.Root currentStep="2">
210
+ <Stepper.Step stepNumber="1">Configure experiment</Stepper.Step>
211
+ <Stepper.Step stepNumber="2">Set run conditions</Stepper.Step>
212
+ <Stepper.Step stepNumber="3">Approve plate maps</Stepper.Step>
213
+ </Stepper.Root>
214
+ </div>
215
+ </div>
216
+ <div>
217
+ <h4 class="mb-2 text-sm font-medium text-secondary">Narrow Width (160px)</h4>
218
+ <div class="w-40">
219
+ <Stepper.Root currentStep="2">
220
+ <Stepper.Step stepNumber="1">Configure experiment parameters</Stepper.Step>
221
+ <Stepper.Step stepNumber="2">Set run conditions and parameters</Stepper.Step>
222
+ <Stepper.Step stepNumber="3">Approve all plate maps and configurations</Stepper.Step>
223
+ </Stepper.Root>
224
+ </div>
225
+ </div>
226
+ <div>
227
+ <h4 class="mb-2 text-sm font-medium text-secondary">Very Narrow Width (120px)</h4>
228
+ <div class="w-30">
229
+ <Stepper.Root currentStep="2">
230
+ <Stepper.Step stepNumber="1"
231
+ >Configure experiment parameters and settings</Stepper.Step
232
+ >
233
+ <Stepper.Step stepNumber="2">Set detailed run conditions and parameters</Stepper.Step>
234
+ <Stepper.Step stepNumber="3"
235
+ >Approve all plate maps and final configurations</Stepper.Step
236
+ >
237
+ </Stepper.Root>
238
+ </div>
239
+ </div>
240
+ </div>
241
+ </div>
242
+ </div>
243
+ </Story>
@@ -0,0 +1,19 @@
1
+ import * as Stepper from './index';
2
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
+ $$bindings?: Bindings;
5
+ } & Exports;
6
+ (internal: unknown, props: {
7
+ $$events?: Events;
8
+ $$slots?: Slots;
9
+ }): Exports & {
10
+ $set?: any;
11
+ $on?: any;
12
+ };
13
+ z_$$bindings?: Bindings;
14
+ }
15
+ declare const Stepper: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
16
+ [evt: string]: CustomEvent<any>;
17
+ }, {}, {}, string>;
18
+ type Stepper = InstanceType<typeof Stepper>;
19
+ export default Stepper;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { setContext } from 'svelte';
4
+
5
+ interface Props {
6
+ children: Snippet;
7
+ class?: string;
8
+ currentStep?: string;
9
+ }
10
+
11
+ let { children, class: className = '', currentStep }: Props = $props();
12
+
13
+ setContext('STEPPER_CONTEXT', {
14
+ currentStep
15
+ });
16
+ </script>
17
+
18
+ <div class="flex w-full flex-col gap-3 {className}" role="progressbar">
19
+ {@render children()}
20
+ </div>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ children: Snippet;
4
+ class?: string;
5
+ currentStep?: string;
6
+ }
7
+ declare const StepperRoot: import("svelte").Component<Props, {}, "">;
8
+ type StepperRoot = ReturnType<typeof StepperRoot>;
9
+ export default StepperRoot;
@@ -0,0 +1,100 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { getContext } from 'svelte';
4
+ import { Icon } from '../../icons/';
5
+ import type { StepState } from '../';
6
+
7
+ interface Props {
8
+ children: Snippet;
9
+ state?: StepState;
10
+ stepNumber: string;
11
+ class?: string;
12
+ }
13
+
14
+ let { children, state: stateProp, stepNumber, class: className = '' }: Props = $props();
15
+ const id = $props.id();
16
+
17
+ type StepperContext = {
18
+ currentStep: string;
19
+ };
20
+
21
+ const context = getContext<StepperContext | undefined>('STEPPER_CONTEXT');
22
+
23
+ const currentState = $derived.by(() => {
24
+ if (context && context.currentStep !== undefined) {
25
+ if (context.currentStep > stepNumber) {
26
+ return 'completed';
27
+ } else if (context.currentStep === stepNumber) {
28
+ return 'active';
29
+ } else {
30
+ return 'future';
31
+ }
32
+ }
33
+ return stateProp ?? 'future';
34
+ });
35
+
36
+ const stateVariants = {
37
+ completed: {
38
+ container: 'bg-transparent text-primary-inverse',
39
+ iconContainer: 'bg-primary ',
40
+ iconColor: 'text-surface',
41
+ labelColor: 'text-primary',
42
+ showIcon: true
43
+ },
44
+ active: {
45
+ container: 'bg-accent text-primary-inverse',
46
+ iconContainer: 'bg-primary ',
47
+ iconColor: 'text-surface',
48
+ labelColor: 'text-primary',
49
+ showIcon: false
50
+ },
51
+ future: {
52
+ container: 'bg-transparent',
53
+ iconContainer: 'bg-transparent border border-interactive',
54
+ iconColor: 'text-secondary',
55
+ labelColor: 'text-secondary',
56
+ showIcon: false
57
+ }
58
+ };
59
+
60
+ const variant = $derived(stateVariants[currentState]);
61
+ </script>
62
+
63
+ <div
64
+ {id}
65
+ class="relative flex items-center gap-3 rounded-lg px-2 py-3 {variant.container} {className}"
66
+ role="progressbar"
67
+ aria-valuenow={currentState === 'completed' ? 100 : currentState === 'active' ? 50 : 0}
68
+ aria-valuemin="0"
69
+ aria-valuemax="100"
70
+ aria-label="Step {stepNumber}"
71
+ >
72
+ <div
73
+ class="flex h-6 w-6 items-center justify-center rounded-md {variant.iconContainer}"
74
+ aria-hidden="true"
75
+ >
76
+ {#if variant.showIcon}
77
+ <Icon iconName="Check" class="h-3 w-3 {variant.iconColor}" />
78
+ {:else}
79
+ <span class="text-xs font-medium leading-none {variant.iconColor}">
80
+ {stepNumber}
81
+ </span>
82
+ {/if}
83
+ </div>
84
+
85
+ <span class="text-sm font-medium leading-tight {variant.labelColor} flex-1 truncate">
86
+ {@render children()}
87
+ </span>
88
+ </div>
89
+
90
+ <style>
91
+ div[role='progressbar']:not(:last-child)::after {
92
+ content: '';
93
+ position: absolute;
94
+ width: 1px;
95
+ background-color: #12192a0d;
96
+ left: calc(0.5rem + 1.5rem / 2 - 1px / 2);
97
+ top: 2.25rem;
98
+ height: 2.25rem;
99
+ }
100
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { StepState } from '../';
3
+ interface Props {
4
+ children: Snippet;
5
+ state?: StepState;
6
+ stepNumber: string;
7
+ class?: string;
8
+ }
9
+ declare const StepperStep: import("svelte").Component<Props, {}, "">;
10
+ type StepperStep = ReturnType<typeof StepperStep>;
11
+ export default StepperStep;