@reshape-biotech/design-system 1.2.6 → 2.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 (187) hide show
  1. package/README.md +5 -1
  2. package/dist/app.css +97 -97
  3. package/dist/components/activity/Activity.stories.svelte +104 -104
  4. package/dist/components/activity/Activity.svelte +112 -112
  5. package/dist/components/avatar/Avatar.stories.svelte +23 -23
  6. package/dist/components/avatar/Avatar.svelte +54 -54
  7. package/dist/components/banner/Banner.stories.svelte +105 -105
  8. package/dist/components/banner/Banner.svelte +42 -42
  9. package/dist/components/button/Button.stories.svelte +61 -61
  10. package/dist/components/button/Button.svelte +95 -95
  11. package/dist/components/card/Card.stories.svelte +112 -112
  12. package/dist/components/card/Card.svelte +18 -18
  13. package/dist/components/checkbox/Checkbox.stories.svelte +8 -8
  14. package/dist/components/checkbox/Checkbox.svelte +17 -17
  15. package/dist/components/collapsible/Collapsible.stories.svelte +26 -26
  16. package/dist/components/collapsible/components/collapsible-content.svelte +20 -20
  17. package/dist/components/collapsible/components/collapsible-trigger.svelte +12 -12
  18. package/dist/components/collapsible/index.d.ts +1 -1
  19. package/dist/components/combobox/Combobox.stories.svelte +412 -412
  20. package/dist/components/combobox/components/combobox-add.svelte +8 -8
  21. package/dist/components/combobox/components/combobox-content.svelte +39 -39
  22. package/dist/components/combobox/components/combobox-indicator.svelte +1 -1
  23. package/dist/components/combobox/index.d.ts +1 -1
  24. package/dist/components/datepicker/DatePicker.stories.svelte +196 -196
  25. package/dist/components/datepicker/DatePicker.svelte +173 -173
  26. package/dist/components/divider/Divider.stories.svelte +7 -7
  27. package/dist/components/divider/Divider.svelte +9 -9
  28. package/dist/components/drawer/Drawer.stories.svelte +51 -51
  29. package/dist/components/drawer/Drawer.svelte +33 -33
  30. package/dist/components/drawer/DrawerLabel.svelte +10 -10
  31. package/dist/components/dropdown/Dropdown.stories.svelte +210 -210
  32. package/dist/components/dropdown/Dropdown.svelte +57 -57
  33. package/dist/components/dropdown/components/DropdownContent.svelte +16 -16
  34. package/dist/components/dropdown/components/DropdownMenu.svelte +10 -10
  35. package/dist/components/dropdown/components/DropdownTrigger.svelte +37 -37
  36. package/dist/components/dropdown/components/OutlinedButton.svelte +9 -9
  37. package/dist/components/empty-content/EmptyContent.stories.svelte +38 -38
  38. package/dist/components/empty-content/EmptyContent.svelte +12 -12
  39. package/dist/components/graphs/bar-chart/BarChart.stories.svelte +91 -91
  40. package/dist/components/graphs/bar-chart/BarChart.svelte +147 -147
  41. package/dist/components/graphs/bar-chart/StackedBarChart.stories.svelte +57 -57
  42. package/dist/components/graphs/bar-chart/StackedBarChart.svelte +198 -199
  43. package/dist/components/graphs/chart/Chart.stories.svelte +96 -96
  44. package/dist/components/graphs/chart/Chart.svelte +207 -207
  45. package/dist/components/graphs/line/LineChart.stories.svelte +138 -138
  46. package/dist/components/graphs/line/LineChart.svelte +140 -142
  47. package/dist/components/graphs/matrix/Matrix.stories.svelte +117 -117
  48. package/dist/components/graphs/matrix/Matrix.svelte +141 -141
  49. package/dist/components/graphs/multiline/MultiLineChart.stories.svelte +168 -168
  50. package/dist/components/graphs/multiline/MultiLineChart.svelte +236 -236
  51. package/dist/components/graphs/scatterplot/Scatterplot.stories.svelte +84 -84
  52. package/dist/components/graphs/scatterplot/Scatterplot.svelte +302 -302
  53. package/dist/components/graphs/utils/duration.d.ts +1 -0
  54. package/dist/components/graphs/utils/duration.js +33 -0
  55. package/dist/components/graphs/utils/tooltipFormatter.js +1 -1
  56. package/dist/components/icon-button/IconButton.stories.svelte +64 -64
  57. package/dist/components/icon-button/IconButton.svelte +88 -88
  58. package/dist/components/icons/AnalysisIcon.stories.svelte +18 -18
  59. package/dist/components/icons/AnalysisIcon.svelte +96 -96
  60. package/dist/components/icons/Icon.stories.svelte +111 -111
  61. package/dist/components/icons/Icon.svelte +17 -17
  62. package/dist/components/icons/PrincipalIcon.svelte +59 -59
  63. package/dist/components/icons/custom/Halo.svelte +31 -31
  64. package/dist/components/icons/custom/Well.svelte +27 -27
  65. package/dist/components/icons/index.js +1 -1
  66. package/dist/components/image/Image.svelte +42 -42
  67. package/dist/components/input/Input.stories.svelte +55 -55
  68. package/dist/components/input/Input.svelte +121 -121
  69. package/dist/components/label/Label.stories.svelte +18 -18
  70. package/dist/components/label/Label.svelte +11 -11
  71. package/dist/components/list/List.stories.svelte +84 -84
  72. package/dist/components/list/List.svelte +20 -20
  73. package/dist/components/logo/Logo.stories.svelte +15 -15
  74. package/dist/components/logo/Logo.svelte +30 -30
  75. package/dist/components/manual-cfu-counter/ManualCFUCounter.stories.svelte +102 -102
  76. package/dist/components/manual-cfu-counter/ManualCFUCounter.svelte +557 -557
  77. package/dist/components/manual-cfu-counter/test/ManualCFUCounterTestWrapper.svelte +11 -11
  78. package/dist/components/markdown/Markdown.stories.svelte +10 -10
  79. package/dist/components/markdown/Markdown.svelte +6 -6
  80. package/dist/components/modal/Modal.stories.svelte +29 -29
  81. package/dist/components/modal/Modal.svelte +71 -71
  82. package/dist/components/multi-cfu-counter/MultiCFUCounter.stories.svelte +201 -201
  83. package/dist/components/multi-cfu-counter/MultiCFUCounter.svelte +606 -606
  84. package/dist/components/multi-cfu-counter/test/MultiCFUCounterTestWrapper.svelte +17 -17
  85. package/dist/components/notification-popup/NotificationPopup.stories.svelte +18 -18
  86. package/dist/components/notification-popup/NotificationPopup.svelte +26 -26
  87. package/dist/components/notifications/Notifications.stories.svelte +101 -101
  88. package/dist/components/notifications/Notifications.svelte +9 -9
  89. package/dist/components/pill/Pill.stories.svelte +8 -8
  90. package/dist/components/pill/Pill.svelte +27 -27
  91. package/dist/components/progress-circle/ProgressCircle.stories.svelte +8 -8
  92. package/dist/components/progress-circle/ProgressCircle.svelte +54 -54
  93. package/dist/components/required-status-indicator/RequiredStatusIndicator.stories.svelte +18 -18
  94. package/dist/components/required-status-indicator/RequiredStatusIndicator.svelte +14 -14
  95. package/dist/components/segmented-control-buttons/ControlButton.svelte +36 -36
  96. package/dist/components/segmented-control-buttons/SegmentedControlButtons.stories.svelte +35 -35
  97. package/dist/components/segmented-control-buttons/SegmentedControlButtons.svelte +13 -13
  98. package/dist/components/select/Select.stories.svelte +200 -94
  99. package/dist/components/select/Select.stories.svelte.d.ts +1 -1
  100. package/dist/components/select/components/Group.svelte +24 -0
  101. package/dist/components/select/components/MultiSelectTrigger.svelte +66 -0
  102. package/dist/components/select/components/SelectContent.svelte +33 -0
  103. package/dist/components/select/components/SelectGroupHeading.svelte +19 -0
  104. package/dist/components/select/components/SelectItem.svelte +39 -0
  105. package/dist/components/select/components/SelectTrigger.svelte +48 -0
  106. package/dist/components/select/index.d.ts +10 -7
  107. package/dist/components/select/index.js +12 -1
  108. package/dist/components/sjsf-wrappers/SjsfNumberInputWrapper.svelte +102 -87
  109. package/dist/components/sjsf-wrappers/SjsfNumberInputWrapper.svelte.d.ts +1 -1
  110. package/dist/components/sjsf-wrappers/SjsfTextInputWrapper.svelte +53 -53
  111. package/dist/components/sjsf-wrappers/SjsfTextInputWrapper.svelte.d.ts +1 -1
  112. package/dist/components/sjsf-wrappers/sjsfCustomTheme.js +1 -1
  113. package/dist/components/skeleton-loader/SkeletonLoader.stories.svelte +32 -32
  114. package/dist/components/skeleton-loader/SkeletonLoader.svelte +10 -10
  115. package/dist/components/skeleton-loader/StatcardSkeleton.svelte +9 -9
  116. package/dist/components/skeleton-loader/components/Skeleton.svelte +7 -7
  117. package/dist/components/skeleton-loader/components/SkeletonImage.svelte +12 -12
  118. package/dist/components/slider/Slider.stories.svelte +23 -23
  119. package/dist/components/slider/Slider.svelte +107 -107
  120. package/dist/components/spinner/Spinner.stories.svelte +8 -8
  121. package/dist/components/spinner/Spinner.svelte +18 -18
  122. package/dist/components/stat-card/StatCard.stories.svelte +26 -26
  123. package/dist/components/stat-card/StatCard.svelte +128 -128
  124. package/dist/components/status-badge/StatusBadge.stories.svelte +365 -365
  125. package/dist/components/status-badge/StatusBadge.svelte +54 -54
  126. package/dist/components/stepper/Stepper.stories.svelte +219 -219
  127. package/dist/components/stepper/components/stepper-root.svelte +12 -12
  128. package/dist/components/stepper/components/stepper-step.svelte +83 -83
  129. package/dist/components/table/Table.stories.svelte +87 -87
  130. package/dist/components/table/Table.svelte +32 -32
  131. package/dist/components/table/components/TBody.svelte +7 -7
  132. package/dist/components/table/components/THead.svelte +7 -7
  133. package/dist/components/table/components/Td.svelte +8 -8
  134. package/dist/components/table/components/Th.svelte +8 -8
  135. package/dist/components/table/components/Tr.svelte +11 -11
  136. package/dist/components/tabs/Tabs.stories.svelte +20 -20
  137. package/dist/components/tabs/Tabs.svelte +8 -8
  138. package/dist/components/tabs/components/Content.svelte +8 -8
  139. package/dist/components/tabs/components/Tab.svelte +14 -14
  140. package/dist/components/tabs/components/Tabs.svelte +7 -7
  141. package/dist/components/tag/Tag.stories.svelte +57 -57
  142. package/dist/components/tag/Tag.svelte +95 -95
  143. package/dist/components/textarea/Textarea.stories.svelte +70 -70
  144. package/dist/components/textarea/Textarea.svelte +76 -76
  145. package/dist/components/toast/Toast.stories.svelte +204 -204
  146. package/dist/components/toast/Toast.svelte +53 -53
  147. package/dist/components/toggle/Toggle.stories.svelte +9 -9
  148. package/dist/components/toggle/Toggle.svelte +53 -53
  149. package/dist/components/toggle-icon-button/ToggleIconButton.stories.svelte +152 -152
  150. package/dist/components/toggle-icon-button/ToggleIconButton.svelte +99 -99
  151. package/dist/components/tooltip/Tooltip.stories.svelte +85 -111
  152. package/dist/components/tooltip/Tooltip.svelte +57 -46
  153. package/dist/components/tooltip/Tooltip.svelte.d.ts +1 -1
  154. package/dist/components/tooltip/TooltipTest.svelte +31 -0
  155. package/dist/components/tooltip/TooltipTest.svelte.d.ts +11 -0
  156. package/dist/fonts/index.js +1 -1
  157. package/dist/index.d.ts +0 -1
  158. package/dist/index.js +0 -1
  159. package/dist/notifications.d.ts +1 -4
  160. package/dist/notifications.js +1 -1
  161. package/dist/tailwind-safelist.js +406 -406
  162. package/dist/tailwind.preset.js +10 -10
  163. package/dist/tokens/colors.js +18 -18
  164. package/dist/tokens/typography.js +6 -6
  165. package/dist/tokens.js +19 -19
  166. package/dist/types/fonts.d.ts +2 -2
  167. package/package.json +199 -204
  168. package/dist/components/select/Select.svelte +0 -139
  169. package/dist/components/select/Select.svelte.d.ts +0 -60
  170. package/dist/components/select-new/Select.stories.svelte +0 -219
  171. package/dist/components/select-new/Select.stories.svelte.d.ts +0 -19
  172. package/dist/components/select-new/components/Group.svelte +0 -24
  173. package/dist/components/select-new/components/MultiSelectTrigger.svelte +0 -66
  174. package/dist/components/select-new/components/SelectContent.svelte +0 -33
  175. package/dist/components/select-new/components/SelectGroupHeading.svelte +0 -19
  176. package/dist/components/select-new/components/SelectItem.svelte +0 -39
  177. package/dist/components/select-new/components/SelectTrigger.svelte +0 -48
  178. package/dist/components/select-new/index.d.ts +0 -10
  179. package/dist/components/select-new/index.js +0 -12
  180. /package/dist/components/{select-new → select}/components/Group.svelte.d.ts +0 -0
  181. /package/dist/components/{select-new → select}/components/MultiSelectTrigger.svelte.d.ts +0 -0
  182. /package/dist/components/{select-new → select}/components/SelectContent.svelte.d.ts +0 -0
  183. /package/dist/components/{select-new → select}/components/SelectGroupHeading.svelte.d.ts +0 -0
  184. /package/dist/components/{select-new → select}/components/SelectItem.svelte.d.ts +0 -0
  185. /package/dist/components/{select-new → select}/components/SelectTrigger.svelte.d.ts +0 -0
  186. /package/dist/components/{select-new → select}/types.d.ts +0 -0
  187. /package/dist/components/{select-new → select}/types.js +0 -0
@@ -1,17 +1,17 @@
1
1
  <script module lang="ts">
2
- import { defineMeta } from '@storybook/addon-svelte-csf';
3
- import RequiredStatusIndicator from './RequiredStatusIndicator.svelte';
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import RequiredStatusIndicator from './RequiredStatusIndicator.svelte';
4
4
 
5
- const { Story } = defineMeta({
6
- title: 'Design System/RequiredStatusIndicator',
7
- component: RequiredStatusIndicator,
8
- tags: ['autodocs'],
9
- argTypes: {
10
- currentCount: { control: 'number', description: 'Current number of completed items' },
11
- requiredCount: { control: 'number', description: 'Total number of required items' },
12
- class: { control: 'text', description: 'Optional additional CSS classes' }
13
- }
14
- });
5
+ const { Story } = defineMeta({
6
+ title: 'Design System/RequiredStatusIndicator',
7
+ component: RequiredStatusIndicator,
8
+ tags: ['autodocs'],
9
+ argTypes: {
10
+ currentCount: { control: 'number', description: 'Current number of completed items' },
11
+ requiredCount: { control: 'number', description: 'Total number of required items' },
12
+ class: { control: 'text', description: 'Optional additional CSS classes' },
13
+ },
14
+ });
15
15
  </script>
16
16
 
17
17
  <Story name="Incomplete" args={{ currentCount: 1, requiredCount: 3 }} />
@@ -19,10 +19,10 @@
19
19
  <Story name="Complete" args={{ currentCount: 3, requiredCount: 3 }} />
20
20
 
21
21
  <Story
22
- name="CustomClass"
23
- args={{
24
- currentCount: 2,
25
- requiredCount: 4,
26
- class: 'text-lg text-warning'
27
- }}
22
+ name="CustomClass"
23
+ args={{
24
+ currentCount: 2,
25
+ requiredCount: 4,
26
+ class: 'text-lg text-warning',
27
+ }}
28
28
  />
@@ -1,22 +1,22 @@
1
1
  <script lang="ts">
2
- import { Icon } from '../icons';
2
+ import { Icon } from '../icons';
3
3
 
4
- type Props = {
5
- currentCount: number;
6
- requiredCount: number;
7
- class?: string;
8
- };
4
+ type Props = {
5
+ currentCount: number;
6
+ requiredCount: number;
7
+ class?: string;
8
+ };
9
9
 
10
- let { currentCount, requiredCount, class: className = '' }: Props = $props();
10
+ let { currentCount, requiredCount, class: className = '' }: Props = $props();
11
11
 
12
- const isComplete = $derived(currentCount >= requiredCount);
12
+ const isComplete = $derived(currentCount >= requiredCount);
13
13
  </script>
14
14
 
15
15
  <span class={`flex items-center gap-1 text-sm text-tertiary ${className}`}>
16
- {currentCount} of {requiredCount} required
17
- {#if isComplete}
18
- <Icon iconName="CheckCircle" weight="fill" color="accent" size={16} />
19
- {:else}
20
- <Icon iconName="CheckCircle" size={16} />
21
- {/if}
16
+ {currentCount} of {requiredCount} required
17
+ {#if isComplete}
18
+ <Icon iconName="CheckCircle" weight="fill" color="accent" size={16} />
19
+ {:else}
20
+ <Icon iconName="CheckCircle" size={16} />
21
+ {/if}
22
22
  </span>
@@ -1,54 +1,54 @@
1
1
  <script lang="ts">
2
- import type { Snippet } from 'svelte';
2
+ import type { Snippet } from 'svelte';
3
3
 
4
- type Color = 'primary' | 'secondary';
4
+ type Color = 'primary' | 'secondary';
5
5
 
6
- interface Props {
7
- class?: string;
8
- color?: Color;
9
- disabled?: boolean;
10
- active?: boolean;
11
- dataTestId?: string;
12
- onclick?: () => void;
13
- children?: Snippet;
14
- }
6
+ interface Props {
7
+ class?: string;
8
+ color?: Color;
9
+ disabled?: boolean;
10
+ active?: boolean;
11
+ dataTestId?: string;
12
+ onclick?: () => void;
13
+ children?: Snippet;
14
+ }
15
15
 
16
- let {
17
- class: className = '',
18
- color = 'primary',
19
- disabled = false,
20
- active = false,
21
- dataTestId,
22
- onclick,
23
- children
24
- }: Props = $props();
25
- const colors: Record<Color, string> = {
26
- primary: 'bg-transparent text-primary hover:bg-neutral disabled:text-tertiary',
27
- secondary: 'bg-transparent text-primary hover:bg-neutral disabled:text-tertiary'
28
- };
16
+ let {
17
+ class: className = '',
18
+ color = 'primary',
19
+ disabled = false,
20
+ active = false,
21
+ dataTestId,
22
+ onclick,
23
+ children,
24
+ }: Props = $props();
25
+ const colors: Record<Color, string> = {
26
+ primary: 'bg-transparent text-primary hover:bg-neutral disabled:text-tertiary',
27
+ secondary: 'bg-transparent text-primary hover:bg-neutral disabled:text-tertiary',
28
+ };
29
29
  </script>
30
30
 
31
31
  <div class="join-item flex h-full flex-1">
32
- <button
33
- {onclick}
34
- class={`control-button flex flex-1 items-center justify-center gap-2 rounded-md text-sm leading-4 ${colors[color]} ${className} ${color}`}
35
- class:active
36
- type="button"
37
- {disabled}
38
- data-testid={dataTestId}
39
- >
40
- {@render children?.()}
41
- </button>
32
+ <button
33
+ {onclick}
34
+ class={`control-button flex flex-1 items-center justify-center gap-2 rounded-md text-sm leading-4 ${colors[color]} ${className} ${color}`}
35
+ class:active
36
+ type="button"
37
+ {disabled}
38
+ data-testid={dataTestId}
39
+ >
40
+ {@render children?.()}
41
+ </button>
42
42
  </div>
43
43
 
44
44
  <style>
45
- .primary.active {
45
+ .primary.active {
46
46
  --tw-bg-opacity: 1;
47
47
  background-color: rgb(87 80 238 / var(--tw-bg-opacity, 1));
48
48
  --tw-text-opacity: 1;
49
49
  color: rgb(255 255 255 / var(--tw-text-opacity, 1))
50
50
  }
51
- .secondary.active {
51
+ .secondary.active {
52
52
  --tw-bg-opacity: 1;
53
53
  background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1));
54
54
  --tw-text-opacity: 1;
@@ -1,45 +1,45 @@
1
1
  <script module lang="ts">
2
- import { Icon } from '../icons';
3
- import SegmentedControlButtons from './SegmentedControlButtons.svelte';
4
- import { defineMeta } from '@storybook/addon-svelte-csf';
2
+ import { Icon } from '../icons';
3
+ import SegmentedControlButtons from './SegmentedControlButtons.svelte';
4
+ import { defineMeta } from '@storybook/addon-svelte-csf';
5
5
 
6
- const { Story } = defineMeta({
7
- component: SegmentedControlButtons,
8
- title: 'Design System/SegmentedControlButtons',
9
- tags: ['autodocs']
10
- });
6
+ const { Story } = defineMeta({
7
+ component: SegmentedControlButtons,
8
+ title: 'Design System/SegmentedControlButtons',
9
+ tags: ['autodocs'],
10
+ });
11
11
  </script>
12
12
 
13
13
  <Story name="Primary" asChild>
14
- <SegmentedControlButtons class="w-[350px]">
15
- {#snippet children({ ControlButton })}
16
- <ControlButton active><Icon iconName="Star" /> Low</ControlButton>
17
- <ControlButton><Icon iconName="Star" /> Medium</ControlButton>
18
- <ControlButton disabled><Icon iconName="Star" /> High</ControlButton>
19
- {/snippet}
20
- </SegmentedControlButtons>
14
+ <SegmentedControlButtons class="w-[350px]">
15
+ {#snippet children({ ControlButton })}
16
+ <ControlButton active><Icon iconName="Star" /> Low</ControlButton>
17
+ <ControlButton><Icon iconName="Star" /> Medium</ControlButton>
18
+ <ControlButton disabled><Icon iconName="Star" /> High</ControlButton>
19
+ {/snippet}
20
+ </SegmentedControlButtons>
21
21
  </Story>
22
22
  <Story name="Large" asChild>
23
- <SegmentedControlButtons size="lg" class="w-[350px]">
24
- {#snippet children({ ControlButton })}
25
- <ControlButton active><Icon iconName="Star" /> Low</ControlButton>
26
- <ControlButton><Icon iconName="Star" /> Medium</ControlButton>
27
- <ControlButton disabled><Icon iconName="Star" /> High</ControlButton>
28
- {/snippet}
29
- </SegmentedControlButtons>
23
+ <SegmentedControlButtons size="lg" class="w-[350px]">
24
+ {#snippet children({ ControlButton })}
25
+ <ControlButton active><Icon iconName="Star" /> Low</ControlButton>
26
+ <ControlButton><Icon iconName="Star" /> Medium</ControlButton>
27
+ <ControlButton disabled><Icon iconName="Star" /> High</ControlButton>
28
+ {/snippet}
29
+ </SegmentedControlButtons>
30
30
  </Story>
31
31
  <Story name="Secondary" asChild>
32
- <SegmentedControlButtons class="w-[350px]">
33
- {#snippet children({ ControlButton })}
34
- <ControlButton active color="secondary">
35
- <Icon iconName="Star" /> Low
36
- </ControlButton>
37
- <ControlButton color="secondary">
38
- <Icon iconName="Star" /> Medium
39
- </ControlButton>
40
- <ControlButton color="secondary">
41
- <Icon iconName="Star" /> High
42
- </ControlButton>
43
- {/snippet}
44
- </SegmentedControlButtons>
32
+ <SegmentedControlButtons class="w-[350px]">
33
+ {#snippet children({ ControlButton })}
34
+ <ControlButton active color="secondary">
35
+ <Icon iconName="Star" /> Low
36
+ </ControlButton>
37
+ <ControlButton color="secondary">
38
+ <Icon iconName="Star" /> Medium
39
+ </ControlButton>
40
+ <ControlButton color="secondary">
41
+ <Icon iconName="Star" /> High
42
+ </ControlButton>
43
+ {/snippet}
44
+ </SegmentedControlButtons>
45
45
  </Story>
@@ -1,21 +1,21 @@
1
1
  <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
- import ControlButton from './ControlButton.svelte';
2
+ import type { Snippet } from 'svelte';
3
+ import ControlButton from './ControlButton.svelte';
4
4
 
5
- interface Props {
6
- class?: string;
7
- size?: 'md' | 'lg';
8
- children?: Snippet<[{ ControlButton: typeof ControlButton }]>;
9
- }
5
+ interface Props {
6
+ class?: string;
7
+ size?: 'md' | 'lg';
8
+ children?: Snippet<[{ ControlButton: typeof ControlButton }]>;
9
+ }
10
10
 
11
- let { class: className = '', size = 'md', children }: Props = $props();
11
+ let { class: className = '', size = 'md', children }: Props = $props();
12
12
 
13
- const sizes = {
14
- md: 'h-10 ',
15
- lg: 'h-16 [&>*>.control-button]:flex-col'
16
- };
13
+ const sizes = {
14
+ md: 'h-10 ',
15
+ lg: 'h-16 [&>*>.control-button]:flex-col',
16
+ };
17
17
  </script>
18
18
 
19
19
  <div class={`join flex gap-1 rounded-lg bg-neutral p-1 ${sizes[size]} ${size} ${className}`}>
20
- {@render children?.({ ControlButton })}
20
+ {@render children?.({ ControlButton })}
21
21
  </div>
@@ -1,113 +1,219 @@
1
1
  <script module lang="ts">
2
- import Select from './Select.svelte';
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import * as Select from './index';
4
+ import { Icon, type IconName } from '../icons';
3
5
 
4
- import { defineMeta } from '@storybook/addon-svelte-csf';
6
+ const { Story } = defineMeta({
7
+ title: 'Design System/Select(New)',
5
8
 
6
- const { Story } = defineMeta({
7
- component: Select,
8
- title: 'Design System/Select',
9
- tags: ['autodocs']
10
- });
9
+ argTypes: {
10
+ placeholder: { control: 'text', defaultValue: 'Select an option...' },
11
+ disabled: { control: 'boolean', defaultValue: false },
12
+ multiple: { control: 'boolean', defaultValue: false },
13
+ },
14
+ });
11
15
 
12
- const items = [
13
- { value: '1', label: 'One', group: 'Group 1', description: 'Description 1' },
14
- { value: '2', label: 'Two', group: 'Group 1', description: 'Description 2' },
15
- { value: '3', label: 'Three', group: 'Group 2' },
16
- { value: '4', label: 'Four', group: 'Group 2' }
17
- ];
18
- let value: any = $state();
19
- let thisChanged = $state(false);
16
+ const foodGroups = [
17
+ { value: 'fruits', label: 'Fruits' },
18
+ { value: 'vegetables', label: 'Vegetables' },
19
+ { value: 'grains', label: 'Grains' },
20
+ { value: 'protein', label: 'Protein Foods' },
21
+ { value: 'dairy', label: 'Dairy' },
22
+ ];
20
23
 
21
- function handleInput(e: Event) {
22
- thisChanged = true;
23
- }
24
+ const moreFruits = [
25
+ { value: 'apple', label: 'Apple' },
26
+ { value: 'banana', label: 'Banana' },
27
+ { value: 'blueberry', label: 'Blueberry' },
28
+ { value: 'grapes', label: 'Grapes' },
29
+ { value: 'mango', label: 'Mango' },
30
+ ];
31
+
32
+ let selectedValueSingle = $state<string | undefined>(undefined);
33
+ let selectedValueMultiple = $state<string[]>([]);
34
+ let selectedValueSinglePreselected = $state<string | undefined>('vegetables');
35
+ let selectedValueMultiplePreselected = $state<string[]>(['fruits', 'grains']);
36
+
37
+ const customIconItems = [
38
+ { value: 'insect_count', label: 'Insect count', iconName: 'Hash' },
39
+ { value: 'insect_health', label: 'Insect health', iconName: 'Hash' },
40
+ { value: 'leaf_area', label: 'Leaf area', iconName: 'Ruler' },
41
+ { value: 'time_spent', label: 'Time spent on leaf', iconName: 'Timer' },
42
+ ];
43
+ let selectedCustomItems = $state<string[]>(['insect_count', 'leaf_area']);
44
+
45
+ const handleRemoveCustomItem = (itemValue: string) => {
46
+ selectedCustomItems = selectedCustomItems.filter((v) => v !== itemValue);
47
+ };
48
+ const handleRemoveValueMultiple = (itemValue: string) => {
49
+ selectedValueMultiple = selectedValueMultiple.filter((v) => v !== itemValue);
50
+ };
51
+ const handleRemoveValueMultiplePreselected = (itemValue: string) => {
52
+ selectedValueMultiplePreselected = selectedValueMultiplePreselected.filter(
53
+ (v) => v !== itemValue
54
+ );
55
+ };
24
56
  </script>
25
57
 
26
- <Story name="Default" asChild>
27
- <div class="py-12">
28
- <Select listOpen {items} />
29
- </div>
30
- </Story>
31
- <Story name="Grouped" asChild>
32
- <div class="py-12">
33
- <Select listOpen {items} withGroup />
34
- </div>
35
- </Story>
58
+ <Story name="Default (Single Select)" asChild>
59
+ <div class="p-4">
60
+ <Select.Root bind:value={selectedValueSingle} items={foodGroups} type="single" open>
61
+ <Select.Trigger
62
+ class="w-[250px]"
63
+ placeholder={'Select a food group'}
64
+ displayValue={foodGroups.find((f) => f.value === selectedValueSingle)?.label}
65
+ />
36
66
 
37
- <Story name="DefaultValue" asChild>
38
- <div class="py-12">
39
- <Select listOpen {items} withGroup value={{ value: '1', label: 'One', group: 'Group 1' }} />
40
- </div>
67
+ <Select.Content>
68
+ {#each foodGroups as item (item.value)}
69
+ <Select.Item value={item.value} label={item.label} />
70
+ {/each}
71
+ </Select.Content>
72
+ </Select.Root>
73
+ <div class="mt-2 rounded bg-gray-100 p-2 text-sm">
74
+ Selected: {selectedValueSingle ?? 'Nothing'}
75
+ </div>
76
+ </div>
41
77
  </Story>
42
78
 
43
- <Story name="Disabled" asChild>
44
- <div class="py-12">
45
- <Select listOpen {items} disabled />
46
- </div>
79
+ <Story name="With Groups (Single Select)" asChild>
80
+ <div class="p-4">
81
+ <Select.Root bind:value={selectedValueSingle} items={moreFruits} type="single">
82
+ <Select.Trigger
83
+ class="w-[250px]"
84
+ placeholder={'Select a fruit'}
85
+ displayValue={moreFruits.find((f) => f.value === selectedValueSingle)?.label}
86
+ />
87
+ <Select.Portal>
88
+ <Select.Content>
89
+ <Select.Group label="Fruits">
90
+ {#each moreFruits.slice(0, 2) as item (item.value)}
91
+ <Select.Item value={item.value} label={item.label} />
92
+ {/each}
93
+ </Select.Group>
94
+ <Select.Group label="More Fruits">
95
+ {#each moreFruits.slice(2) as item (item.value)}
96
+ <Select.Item value={item.value} label={item.label} />
97
+ {/each}
98
+ </Select.Group>
99
+ </Select.Content>
100
+ </Select.Portal>
101
+ </Select.Root>
102
+ <div class="mt-2 rounded bg-gray-100 p-2 text-sm">
103
+ Selected: {selectedValueSingle ?? 'Nothing'}
104
+ </div>
105
+ </div>
47
106
  </Story>
48
- <Story name="Searchable" asChild>
49
- <div class="py-12">
50
- <Select listOpen {items} searchable />
51
- </div>
52
- </Story>
53
- <Story name="Open" asChild>
54
- <div class="py-12">
55
- <Select listOpen {items} />
56
- </div>
57
- </Story>
58
- <Story name="Error" asChild>
59
- <div class="py-12">
60
- <Select listOpen {items} hasError />
61
- </div>
62
- </Story>
63
- <Story name="Placeholder" asChild>
64
- <div class="py-12">
65
- <Select listOpen {items} placeholder="Select a value" />
66
- </div>
107
+
108
+ <Story name="Multiple Select Example" asChild>
109
+ <div class="p-4">
110
+ <Select.Root bind:value={selectedValueMultiple} items={foodGroups} type="multiple">
111
+ <Select.MultiSelectTrigger
112
+ selectedValues={selectedValueMultiple}
113
+ items={foodGroups}
114
+ onRemoveItem={handleRemoveValueMultiple}
115
+ />
116
+ <Select.Portal>
117
+ <Select.Content>
118
+ {#each foodGroups as item (item.value)}
119
+ <Select.Item value={item.value} label={item.label} />
120
+ {/each}
121
+ </Select.Content>
122
+ </Select.Portal>
123
+ </Select.Root>
124
+ <div class="mt-2 rounded bg-gray-100 p-2 text-sm">
125
+ Selected: {selectedValueMultiple.join(', ') || 'Nothing'}
126
+ </div>
127
+ </div>
67
128
  </Story>
68
- <Story name="Multiple" asChild>
69
- <div class="py-12">
70
- <Select listOpen {items} multiple bind:value />
71
- </div>
129
+
130
+ <Story name="Disabled Select" asChild>
131
+ <div class="p-4">
132
+ <Select.Root items={foodGroups} type="single" disabled={true}>
133
+ <Select.Trigger class="w-[250px]" placeholder={'Cannot select (disabled)'} disabled={true} />
134
+ <Select.Portal>
135
+ <Select.Content>
136
+ {#each foodGroups as item (item.value)}
137
+ <Select.Item value={item.value} label={item.label} disabled={true} />
138
+ {/each}
139
+ </Select.Content>
140
+ </Select.Portal>
141
+ </Select.Root>
142
+ <div class="mt-2 rounded bg-gray-100 p-2 text-sm">Selected: Nothing (disabled)</div>
143
+ </div>
72
144
  </Story>
73
145
 
74
- <Story name="Bind value input changed" asChild>
75
- <div class="py-12">
76
- <Select listOpen {items} bind:value on:input={handleInput} />
77
- {#if thisChanged}
78
- <p class="text-secondary">Wow you picked something from the dropdown 💪</p>{/if}
79
- </div>
146
+ <Story name="Pre-selected (Single Select)" asChild>
147
+ <div class="p-4">
148
+ <Select.Root bind:value={selectedValueSinglePreselected} items={foodGroups} type="single">
149
+ <Select.Trigger
150
+ class="w-[250px]"
151
+ placeholder={'Select a food group'}
152
+ displayValue={foodGroups.find((f) => f.value === selectedValueSinglePreselected)?.label}
153
+ />
154
+ <Select.Portal>
155
+ <Select.Content>
156
+ {#each foodGroups as item (item.value)}
157
+ <Select.Item value={item.value} label={item.label} />
158
+ {/each}
159
+ </Select.Content>
160
+ </Select.Portal>
161
+ </Select.Root>
162
+ <div class="mt-2 rounded bg-gray-100 p-2 text-sm">
163
+ Selected: {selectedValueSinglePreselected ?? 'Nothing'}
164
+ </div>
165
+ </div>
80
166
  </Story>
81
167
 
82
- <Story name="Custom Item" asChild>
83
- <div class="py-12">
84
- <Select listOpen {items} value={{ value: '1', label: 'One', group: 'Group 1' }}>
85
- <!-- @migration-task: migrate this slot by hand, `custom-item` is an invalid identifier -->
86
- <div
87
- slot="custom-item"
88
- class="flex h-14 w-full items-center overflow-hidden whitespace-nowrap"
89
- let:item
90
- >
91
- <div class="flex flex-col">
92
- <p class="text-sm">
93
- {item.label}
94
- </p>
95
- <p class="max-w-20 text-xs text-secondary">
96
- {item.description} very very long long loooooong long description
97
- </p>
98
- </div>
99
- </div>
100
- </Select>
101
- </div>
168
+ <Story name="Pre-selected (Multiple Select)" asChild>
169
+ <div class="p-4">
170
+ <Select.Root bind:value={selectedValueMultiplePreselected} items={foodGroups} type="multiple">
171
+ <Select.MultiSelectTrigger
172
+ selectedValues={selectedValueMultiplePreselected}
173
+ items={foodGroups}
174
+ onRemoveItem={handleRemoveValueMultiplePreselected}
175
+ />
176
+ <Select.Portal>
177
+ <Select.Content>
178
+ {#each foodGroups as item (item.value)}
179
+ <Select.Item value={item.value} label={item.label} />
180
+ {/each}
181
+ </Select.Content>
182
+ </Select.Portal>
183
+ </Select.Root>
184
+ <div class="mt-2 rounded bg-gray-100 p-2 text-sm">
185
+ Selected: {selectedValueMultiplePreselected.join(', ') || 'Nothing'}
186
+ </div>
187
+ </div>
102
188
  </Story>
103
189
 
104
- <Story name="Custom selection label" asChild>
105
- <div class="py-12">
106
- <Select {items} value={{ value: '1', label: 'One', group: 'Group 1' }}>
107
- <!-- @migration-task: migrate this slot by hand, `custom-selection` is an invalid identifier -->
108
- <div slot="custom-selection" let:selection>
109
- <p>💩{selection.label} poopoo💩</p>
110
- </div>
111
- </Select>
112
- </div>
190
+ <Story name="Multiple Select with Custom Icons and Dismissible Tags" asChild>
191
+ <div class="p-4">
192
+ <Select.Root bind:value={selectedCustomItems} items={customIconItems} type="multiple">
193
+ <Select.MultiSelectTrigger
194
+ class="w-[350px]"
195
+ selectedValues={selectedCustomItems}
196
+ items={customIconItems}
197
+ placeholder="Select metrics..."
198
+ onRemoveItem={handleRemoveCustomItem}
199
+ />
200
+ <Select.Portal>
201
+ <Select.Content>
202
+ {#each customIconItems as item (item.value)}
203
+ <Select.Item value={item.value} label={item.label}>
204
+ {#snippet children()}
205
+ <div class="flex items-center gap-2">
206
+ <Icon iconName={item.iconName as IconName} class="h-4 w-4" />
207
+ <span>{item.label}</span>
208
+ </div>
209
+ {/snippet}
210
+ </Select.Item>
211
+ {/each}
212
+ </Select.Content>
213
+ </Select.Portal>
214
+ </Select.Root>
215
+ <div class="mt-2 rounded bg-neutral p-2 text-sm">
216
+ Selected Values: {selectedCustomItems.join(', ') || 'Nothing'}
217
+ </div>
218
+ </div>
113
219
  </Story>
@@ -1,4 +1,4 @@
1
- import Select from './Select.svelte';
1
+ import * as Select from './index';
2
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
3
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
4
  $$bindings?: Bindings;
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from 'bits-ui';
3
+ import type { Snippet } from 'svelte';
4
+ import type { GroupProps as PrimitiveGroupProps } from '../types';
5
+ import GroupHeading from './SelectGroupHeading.svelte';
6
+
7
+ interface Props extends PrimitiveGroupProps {
8
+ label?: string;
9
+ children: Snippet;
10
+ class?: string;
11
+ contentClass?: string;
12
+ }
13
+
14
+ let { label, children, class: className, contentClass, ...restProps }: Props = $props();
15
+ </script>
16
+
17
+ <SelectPrimitive.Group class={className} {...restProps}>
18
+ {#if label}
19
+ <GroupHeading>{label}</GroupHeading>
20
+ {/if}
21
+ <div class={contentClass}>
22
+ {@render children()}
23
+ </div>
24
+ </SelectPrimitive.Group>