@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
@@ -0,0 +1,66 @@
1
+ <script lang="ts">
2
+ import * as Select from '../index';
3
+ import { Icon, type IconName } from '../../icons';
4
+ import IconButton from '../../icon-button/IconButton.svelte';
5
+
6
+ type ItemType = {
7
+ value: string;
8
+ label: string;
9
+ iconName?: IconName | string;
10
+ };
11
+
12
+ interface Props {
13
+ selectedValues: string[];
14
+ items: ItemType[];
15
+ onRemoveItem: (itemValue: string) => void;
16
+ placeholder?: string;
17
+ class?: string;
18
+ [key: string]: any;
19
+ }
20
+
21
+ let {
22
+ selectedValues,
23
+ items,
24
+ onRemoveItem,
25
+ placeholder = 'Select items...',
26
+ class: className,
27
+ ...restProps
28
+ }: Props = $props();
29
+ </script>
30
+
31
+ <Select.Trigger
32
+ class={'bg-background ring-offset-background placeholder:text-muted-foreground focus:ring-ring flex h-10 w-full items-center justify-between rounded-md border border-input px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50' +
33
+ (className || '')}
34
+ {...restProps}
35
+ >
36
+ {#if selectedValues.length === 0}
37
+ <span class="flex-grow px-2 text-tertiary">{placeholder}</span>
38
+ {:else}
39
+ <div class="flex flex-grow flex-wrap items-center gap-1">
40
+ {#each selectedValues as selectedVal (selectedVal)}
41
+ {@const item = items.find((i) => i.value === selectedVal)}
42
+ {#if item}
43
+ <div
44
+ class="flex w-fit items-center gap-1 rounded-sm bg-neutral px-1 py-0.5 text-sm"
45
+ aria-label={`Selected item ${item.label}`}
46
+ >
47
+ {#if item.iconName}
48
+ <Icon iconName={item.iconName as IconName} />
49
+ {/if}
50
+ <span>{item.label}</span>
51
+ <IconButton
52
+ type="button"
53
+ aria-label={`Remove ${item.label}`}
54
+ onclick={() => onRemoveItem(item.value)}
55
+ size="xs"
56
+ variant="transparent"
57
+ class="text-primary focus:outline-none"
58
+ >
59
+ <Icon iconName="X" />
60
+ </IconButton>
61
+ </div>
62
+ {/if}
63
+ {/each}
64
+ </div>
65
+ {/if}
66
+ </Select.Trigger>
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from 'bits-ui';
3
+ import type { ContentProps } from '../types';
4
+
5
+ import type { Snippet } from 'svelte';
6
+ import Icon from '../../icons/Icon.svelte';
7
+
8
+ interface Props extends ContentProps {
9
+ children: Snippet;
10
+ class?: string;
11
+ sideOffset?: number;
12
+ }
13
+
14
+ let { class: className = '', sideOffset = 4, children, ...restProps }: Props = $props();
15
+
16
+ const baseClasses = `
17
+ w-[var(--bits-select-anchor-width)] relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-surface text-surface-foreground shadow-md
18
+ `;
19
+ </script>
20
+
21
+ <SelectPrimitive.Portal>
22
+ <SelectPrimitive.Content {...restProps} {sideOffset} class={baseClasses + ' ' + className}>
23
+ <SelectPrimitive.ScrollUpButton class="flex justify-center">
24
+ <Icon iconName="CaretUp" />
25
+ </SelectPrimitive.ScrollUpButton>
26
+ <SelectPrimitive.Viewport class="p-1 ">
27
+ {@render children()}
28
+ </SelectPrimitive.Viewport>
29
+ <SelectPrimitive.ScrollDownButton class="flex justify-center">
30
+ <Icon iconName="CaretDown" />
31
+ </SelectPrimitive.ScrollDownButton>
32
+ </SelectPrimitive.Content>
33
+ </SelectPrimitive.Portal>
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from 'bits-ui';
3
+ import type { GroupHeadingProps } from '../types';
4
+
5
+ import type { Snippet } from 'svelte';
6
+
7
+ interface Props extends GroupHeadingProps {
8
+ children: Snippet;
9
+ class?: string;
10
+ }
11
+
12
+ let { class: className = '', children, ...restProps }: Props = $props();
13
+
14
+ const baseClasses = 'py-1.5 pl-2 pr-2 text-sm font-semibold text-muted-foreground';
15
+ </script>
16
+
17
+ <SelectPrimitive.GroupHeading {...restProps} class="{baseClasses} {className}">
18
+ {@render children()}
19
+ </SelectPrimitive.GroupHeading>
@@ -0,0 +1,39 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from 'bits-ui';
3
+ import type { ItemProps, ItemSlotProps } from '../types';
4
+
5
+ import type { Snippet } from 'svelte';
6
+ import Icon from '../../icons/Icon.svelte';
7
+
8
+ interface Props extends ItemProps {
9
+ children?: Snippet<[ItemSlotProps]>;
10
+ class?: string;
11
+ }
12
+
13
+ let { class: className = '', children, ...restProps }: Props = $props();
14
+
15
+ const baseClasses = `
16
+ relative flex w-full h-auto gap-2 cursor-default select-none items-center justify-between rounded-lg p-3 text-sm outline-none
17
+ focus:bg-neutral focus:text-accent-foreground
18
+ data-[disabled]:pointer-events-none data-[disabled]:opacity-50
19
+ data-[highlighted]:bg-neutral data-[highlighted]:text-accent-foreground
20
+ `;
21
+ </script>
22
+
23
+ <SelectPrimitive.Item {...restProps} class={baseClasses + ' ' + className}>
24
+ {#snippet children(params: ItemSlotProps)}
25
+ {#if children}
26
+ {@render children(params)}
27
+ {:else}
28
+ <span>
29
+ {restProps.label ??
30
+ (typeof restProps.value === 'string' || typeof restProps.value === 'number'
31
+ ? restProps.value
32
+ : 'Item')}</span
33
+ >
34
+ {/if}
35
+ {#if params.selected}
36
+ <Icon iconName="Check" color="accent" />
37
+ {/if}
38
+ {/snippet}
39
+ </SelectPrimitive.Item>
@@ -0,0 +1,48 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from 'bits-ui';
3
+ import type { TriggerProps, IconSnippet } from '../types';
4
+
5
+ import type { Snippet } from 'svelte';
6
+ import { Icon } from '../../icons';
7
+
8
+ interface Props extends TriggerProps {
9
+ TriggerIcon?: IconSnippet;
10
+ children?: Snippet;
11
+ class?: string;
12
+ placeholder?: string;
13
+ displayValue?: string;
14
+ }
15
+
16
+ let {
17
+ class: className = '',
18
+ TriggerIcon = undefined,
19
+ children,
20
+ placeholder = 'Select an option',
21
+ displayValue = undefined,
22
+ ...restProps
23
+ }: Props = $props();
24
+
25
+ const baseClasses =
26
+ 'flex h-10 w-full items-center justify-between rounded-lg border border-input bg-surface p-2 text-sm placeholder:text-tertiary focus:outline-none hover:border-hover focus:border-accent disabled:cursor-not-allowed disabled:opacity-50 transition-colors shadow-input';
27
+ </script>
28
+
29
+ <SelectPrimitive.Trigger
30
+ {...restProps}
31
+ class={baseClasses + ' ' + className}
32
+ aria-label={placeholder}
33
+ >
34
+ <div class="flex-1 truncate text-left">
35
+ {#if children}
36
+ {@render children()}
37
+ {:else if displayValue !== undefined}
38
+ {displayValue}
39
+ {:else}
40
+ <span class="text-tertiary">{placeholder}</span>
41
+ {/if}
42
+ </div>
43
+ {#if TriggerIcon}
44
+ {@render TriggerIcon()}
45
+ {:else}
46
+ <Icon iconName="CaretDown" color="secondary" class="mx-1 shrink-0" />
47
+ {/if}
48
+ </SelectPrimitive.Trigger>
@@ -1,7 +1,10 @@
1
- export type SelectItemProps = {
2
- value: string;
3
- label: string;
4
- description?: string;
5
- group?: string;
6
- };
7
- export { default as Select } from './Select.svelte';
1
+ import Content from './components/SelectContent.svelte';
2
+ import Item from './components/SelectItem.svelte';
3
+ import GroupHeading from './components/SelectGroupHeading.svelte';
4
+ import Trigger from './components/SelectTrigger.svelte';
5
+ import MultiSelectTrigger from './components/MultiSelectTrigger.svelte';
6
+ import Group from './components/Group.svelte';
7
+ export declare const Root: import("svelte").Component<import("bits-ui").ComboboxRootPropsWithoutHTML, {}, "value" | "open">;
8
+ export declare const Portal: import("svelte").Component<import("bits-ui").PortalProps, {}, "">;
9
+ export { Content, Item, Group, GroupHeading, Trigger, MultiSelectTrigger };
10
+ export * from './types';
@@ -1 +1,12 @@
1
- export { default as Select } from './Select.svelte';
1
+ import { Select as SelectPrimitive } from 'bits-ui';
2
+ // Custom Svelte components
3
+ import Content from './components/SelectContent.svelte';
4
+ import Item from './components/SelectItem.svelte';
5
+ import GroupHeading from './components/SelectGroupHeading.svelte';
6
+ import Trigger from './components/SelectTrigger.svelte';
7
+ import MultiSelectTrigger from './components/MultiSelectTrigger.svelte';
8
+ import Group from './components/Group.svelte';
9
+ export const Root = SelectPrimitive.Root;
10
+ export const Portal = SelectPrimitive.Portal;
11
+ export { Content, Item, Group, GroupHeading, Trigger, MultiSelectTrigger };
12
+ export * from './types';
@@ -1,92 +1,107 @@
1
1
  <script lang="ts">
2
- import type { ComponentProps } from '@sjsf/form';
3
- import { getFormContext, inputAttributes } from '@sjsf/form';
4
- import Input from '../input/Input.svelte';
5
- import type { FocusEventHandler } from 'svelte/elements';
6
-
7
- type Props = ComponentProps['numberWidget'];
8
-
9
- let { value = $bindable(), config, handlers, errors }: Props = $props();
10
-
11
- const ctx = getFormContext();
12
-
13
- const derivedAttrs = $derived(
14
- inputAttributes(ctx, config, 'number', handlers, {
15
- type: 'number'
16
- })
17
- );
18
- const placeholder = $derived(
19
- config?.uiSchema?.['ui:placeholder'] ||
20
- config?.schema?.description ||
21
- (Array.isArray(config?.schema?.examples) && config.schema.examples.length > 0
22
- ? String(config.schema.examples[0]) // Ensure the example is also a string
23
- : '') ||
24
- ''
25
- );
26
-
27
- const readonly = $derived(config?.schema?.readOnly ?? false);
28
- const currentClass = $derived(derivedAttrs?.class ?? 'w-full');
29
-
30
- const onBlurHandler = $derived(
31
- derivedAttrs.onblur
32
- ? (event: FocusEvent) =>
33
- (derivedAttrs.onblur as FocusEventHandler<HTMLInputElement>)(event as any)
34
- : undefined
35
- );
36
-
37
- const onChangeHandler = $derived(
38
- derivedAttrs.onchange
39
- ? (event: Event) =>
40
- (derivedAttrs.onchange as FocusEventHandler<HTMLInputElement>)(event as any)
41
- : undefined
42
- );
43
-
44
- const onInputHandler = $derived(
45
- derivedAttrs.oninput
46
- ? (event: Event) =>
47
- (derivedAttrs.oninput as FocusEventHandler<HTMLInputElement>)(event as any)
48
- : undefined
49
- );
50
-
51
- const getStringValue = () => {
52
- if (value === undefined || value === null || isNaN(value)) {
53
- return '';
54
- }
55
- return String(value);
56
- };
57
-
58
- const setNumericValue = (newValueFromInput: unknown) => {
59
- const stringifiedInput =
60
- newValueFromInput === null || newValueFromInput === undefined
61
- ? ''
62
- : String(newValueFromInput);
63
-
64
- if (stringifiedInput.trim() === '') {
65
- value = undefined;
66
- } else {
67
- const num = parseFloat(stringifiedInput);
68
- value = isNaN(num) ? undefined : num;
69
- }
70
- };
2
+ import type { ComponentProps } from '@sjsf/form';
3
+ import { getFormContext, inputAttributes } from '@sjsf/form';
4
+ import Input from '../input/Input.svelte';
5
+ import type { FocusEventHandler } from 'svelte/elements';
6
+
7
+ type Props = ComponentProps['numberWidget'];
8
+
9
+ let { value = $bindable(), config, handlers, errors }: Props = $props();
10
+
11
+ const ctx = getFormContext();
12
+
13
+ const derivedAttrs = $derived(
14
+ inputAttributes(ctx, config, 'number', handlers, {
15
+ type: 'number',
16
+ })
17
+ );
18
+ const placeholder = $derived(
19
+ config?.uiSchema?.['ui:placeholder'] ||
20
+ config?.schema?.description ||
21
+ (Array.isArray(config?.schema?.examples) && config.schema.examples.length > 0
22
+ ? String(config.schema.examples[0]) // Ensure the example is also a string
23
+ : '') ||
24
+ ''
25
+ );
26
+
27
+ const readonly = $derived(config?.schema?.readOnly ?? false);
28
+ const currentClass = $derived(derivedAttrs?.class ?? 'w-full');
29
+
30
+ const onBlurHandler = $derived(
31
+ derivedAttrs.onblur
32
+ ? (event: FocusEvent) =>
33
+ (derivedAttrs.onblur as FocusEventHandler<HTMLInputElement>)(event as any)
34
+ : undefined
35
+ );
36
+
37
+ const onChangeHandler = $derived(
38
+ derivedAttrs.onchange
39
+ ? (event: Event) =>
40
+ (derivedAttrs.onchange as FocusEventHandler<HTMLInputElement>)(event as any)
41
+ : undefined
42
+ );
43
+
44
+ const onInputHandler = $derived(
45
+ derivedAttrs.oninput
46
+ ? (event: Event) =>
47
+ (derivedAttrs.oninput as FocusEventHandler<HTMLInputElement>)(event as any)
48
+ : undefined
49
+ );
50
+
51
+ let displayValue = $state('');
52
+
53
+ const getStringValue = () => {
54
+ if (displayValue !== '') {
55
+ return displayValue;
56
+ }
57
+
58
+ if (value === undefined || value === null || isNaN(value)) {
59
+ return '';
60
+ }
61
+ return String(value);
62
+ };
63
+
64
+ const setNumericValue = (newValueFromInput: unknown) => {
65
+ const stringifiedInput =
66
+ newValueFromInput === null || newValueFromInput === undefined
67
+ ? ''
68
+ : String(newValueFromInput);
69
+
70
+ const validNumberPattern = /^-?\d*\.?\d*$/;
71
+ if (stringifiedInput !== '' && !validNumberPattern.test(stringifiedInput)) {
72
+ return;
73
+ }
74
+
75
+ displayValue = stringifiedInput;
76
+
77
+ if (stringifiedInput.trim() === '') {
78
+ value = undefined;
79
+ } else {
80
+ const num = parseFloat(stringifiedInput);
81
+ value = isNaN(num) ? undefined : num;
82
+ }
83
+ };
71
84
  </script>
72
85
 
73
86
  <Input
74
- bind:value={() => getStringValue(), (v) => setNumericValue(v)}
75
- placeholder={String(placeholder)}
76
- type={'number'}
77
- {readonly}
78
- id={String(derivedAttrs.id)}
79
- name={String(derivedAttrs.name)}
80
- disabled={derivedAttrs.disabled}
81
- required={derivedAttrs.required}
82
- step={config?.schema?.multipleOf ?? (config?.schema?.type === 'integer' ? 1 : 'any')}
83
- min={config?.schema?.minimum ?? config?.schema?.exclusiveMinimum}
84
- max={config?.schema?.maximum ?? config?.schema?.exclusiveMaximum}
85
- aria-invalid={errors && errors.length > 0 ? true : undefined}
86
- aria-describedby={errors && errors.length > 0 ? `${String(derivedAttrs.id)}-errors` : undefined}
87
- class={String(currentClass)}
88
- autocomplete="off"
89
- oninput={onInputHandler}
90
- onchange={onChangeHandler}
91
- onblur={onBlurHandler}
87
+ bind:value={() => getStringValue(), (v) => setNumericValue(v)}
88
+ placeholder={String(placeholder)}
89
+ type={'text'}
90
+ inputmode={'decimal'}
91
+ pattern={config?.schema?.type === 'integer' ? '-?\\d*' : '-?\\d*\\.?\\d*'}
92
+ {readonly}
93
+ id={String(derivedAttrs.id)}
94
+ name={String(derivedAttrs.name)}
95
+ disabled={derivedAttrs.disabled}
96
+ required={derivedAttrs.required}
97
+ step={config?.schema?.multipleOf ?? (config?.schema?.type === 'integer' ? 1 : 'any')}
98
+ min={config?.schema?.minimum ?? config?.schema?.exclusiveMinimum}
99
+ max={config?.schema?.maximum ?? config?.schema?.exclusiveMaximum}
100
+ aria-invalid={errors && errors.length > 0 ? true : undefined}
101
+ aria-describedby={errors && errors.length > 0 ? `${String(derivedAttrs.id)}-errors` : undefined}
102
+ class={String(currentClass)}
103
+ autocomplete="off"
104
+ oninput={onInputHandler}
105
+ onchange={onChangeHandler}
106
+ onblur={onBlurHandler}
92
107
  />
@@ -1,3 +1,3 @@
1
- declare const SjsfNumberInputWrapper: import("svelte").Component<any, {}, "value">;
1
+ declare const SjsfNumberInputWrapper: import("svelte").Component<ComponentProps, {}, "value">;
2
2
  type SjsfNumberInputWrapper = ReturnType<typeof SjsfNumberInputWrapper>;
3
3
  export default SjsfNumberInputWrapper;
@@ -1,65 +1,65 @@
1
1
  <script lang="ts">
2
- import type { ComponentProps } from '@sjsf/form';
3
- import { getFormContext, inputAttributes } from '@sjsf/form';
4
- import Input from '../input/Input.svelte';
5
- import type { FormEventHandler, FocusEventHandler } from 'svelte/elements';
2
+ import type { ComponentProps } from '@sjsf/form';
3
+ import { getFormContext, inputAttributes } from '@sjsf/form';
4
+ import Input from '../input/Input.svelte';
5
+ import type { FormEventHandler, FocusEventHandler } from 'svelte/elements';
6
6
 
7
- type Props = ComponentProps['textWidget'];
7
+ type Props = ComponentProps['textWidget'];
8
8
 
9
- let { value = $bindable(), config, handlers, errors }: Props = $props();
9
+ let { value = $bindable(), config, handlers, errors }: Props = $props();
10
10
 
11
- const ctx = getFormContext();
11
+ const ctx = getFormContext();
12
12
 
13
- const derivedAttrs = $derived(
14
- inputAttributes(ctx, config, 'text', handlers, {
15
- type: 'text'
16
- })
17
- );
13
+ const derivedAttrs = $derived(
14
+ inputAttributes(ctx, config, 'text', handlers, {
15
+ type: 'text',
16
+ })
17
+ );
18
18
 
19
- const placeholder = $derived(
20
- config?.uiSchema?.['ui:placeholder'] ||
21
- config?.schema?.description ||
22
- (Array.isArray(config?.schema?.examples) && config.schema.examples.length > 0
23
- ? String(config.schema.examples[0])
24
- : '') ||
25
- ''
26
- );
19
+ const placeholder = $derived(
20
+ config?.uiSchema?.['ui:placeholder'] ||
21
+ config?.schema?.description ||
22
+ (Array.isArray(config?.schema?.examples) && config.schema.examples.length > 0
23
+ ? String(config.schema.examples[0])
24
+ : '') ||
25
+ ''
26
+ );
27
27
 
28
- const readonly = $derived(config?.schema?.readOnly ?? false);
29
- const currentClass = $derived(derivedAttrs?.class ?? 'w-full');
28
+ const readonly = $derived(config?.schema?.readOnly ?? false);
29
+ const currentClass = $derived(derivedAttrs?.class ?? 'w-full');
30
30
 
31
- const onInput = $derived(
32
- derivedAttrs.oninput
33
- ? (event: Event) => (derivedAttrs.oninput as FormEventHandler<HTMLInputElement>)(event as any)
34
- : undefined
35
- );
36
- const onChange = $derived(
37
- derivedAttrs.onchange
38
- ? (event: Event) =>
39
- (derivedAttrs.onchange as FormEventHandler<HTMLInputElement>)(event as any)
40
- : undefined
41
- );
42
- const onBlur = $derived(
43
- derivedAttrs.onblur
44
- ? (event: FocusEvent) =>
45
- (derivedAttrs.onblur as FocusEventHandler<HTMLInputElement>)(event as any)
46
- : undefined
47
- );
31
+ const onInput = $derived(
32
+ derivedAttrs.oninput
33
+ ? (event: Event) => (derivedAttrs.oninput as FormEventHandler<HTMLInputElement>)(event as any)
34
+ : undefined
35
+ );
36
+ const onChange = $derived(
37
+ derivedAttrs.onchange
38
+ ? (event: Event) =>
39
+ (derivedAttrs.onchange as FormEventHandler<HTMLInputElement>)(event as any)
40
+ : undefined
41
+ );
42
+ const onBlur = $derived(
43
+ derivedAttrs.onblur
44
+ ? (event: FocusEvent) =>
45
+ (derivedAttrs.onblur as FocusEventHandler<HTMLInputElement>)(event as any)
46
+ : undefined
47
+ );
48
48
  </script>
49
49
 
50
50
  <Input
51
- bind:value
52
- placeholder={String(placeholder)}
53
- type="text"
54
- {readonly}
55
- id={String(derivedAttrs.id)}
56
- name={String(derivedAttrs.name)}
57
- disabled={derivedAttrs.disabled}
58
- required={derivedAttrs.required}
59
- oninput={onInput}
60
- onchange={onChange}
61
- onblur={onBlur}
62
- aria-invalid={errors && errors.length > 0 ? true : undefined}
63
- aria-describedby={errors && errors.length > 0 ? `${String(derivedAttrs.id)}-errors` : undefined}
64
- class={String(currentClass)}
51
+ bind:value
52
+ placeholder={String(placeholder)}
53
+ type="text"
54
+ {readonly}
55
+ id={String(derivedAttrs.id)}
56
+ name={String(derivedAttrs.name)}
57
+ disabled={derivedAttrs.disabled}
58
+ required={derivedAttrs.required}
59
+ oninput={onInput}
60
+ onchange={onChange}
61
+ onblur={onBlur}
62
+ aria-invalid={errors && errors.length > 0 ? true : undefined}
63
+ aria-describedby={errors && errors.length > 0 ? `${String(derivedAttrs.id)}-errors` : undefined}
64
+ class={String(currentClass)}
65
65
  />
@@ -1,3 +1,3 @@
1
- declare const SjsfTextInputWrapper: import("svelte").Component<any, {}, "value">;
1
+ declare const SjsfTextInputWrapper: import("svelte").Component<ComponentProps, {}, "value">;
2
2
  type SjsfTextInputWrapper = ReturnType<typeof SjsfTextInputWrapper>;
3
3
  export default SjsfTextInputWrapper;
@@ -4,5 +4,5 @@ import SjsfNumberInputWrapper from './SjsfNumberInputWrapper.svelte';
4
4
  import SjsfTextInputWrapper from './SjsfTextInputWrapper.svelte';
5
5
  export const sjsfCustomTheme = overrideByRecord(BasicTheme, {
6
6
  numberWidget: SjsfNumberInputWrapper,
7
- textWidget: SjsfTextInputWrapper
7
+ textWidget: SjsfTextInputWrapper,
8
8
  });
@@ -1,45 +1,45 @@
1
1
  <script module>
2
- import SkeletonLoader from './SkeletonLoader.svelte';
3
- import StatcardSkeleton from './StatcardSkeleton.svelte';
2
+ import SkeletonLoader from './SkeletonLoader.svelte';
3
+ import StatcardSkeleton from './StatcardSkeleton.svelte';
4
4
 
5
- import { defineMeta } from '@storybook/addon-svelte-csf';
5
+ import { defineMeta } from '@storybook/addon-svelte-csf';
6
6
 
7
- const { Story } = defineMeta({
8
- component: SkeletonLoader,
9
- title: 'Design System/SkeletonLoader'
10
- });
7
+ const { Story } = defineMeta({
8
+ component: SkeletonLoader,
9
+ title: 'Design System/SkeletonLoader',
10
+ });
11
11
  </script>
12
12
 
13
13
  <Story name="Primary" asChild>
14
- <SkeletonLoader class="h-[50px] w-[200px]">
15
- {#snippet children({ Skeleton })}
16
- <Skeleton class="h-full w-full" />
17
- {/snippet}
18
- </SkeletonLoader>
14
+ <SkeletonLoader class="h-[50px] w-[200px]">
15
+ {#snippet children({ Skeleton })}
16
+ <Skeleton class="h-full w-full" />
17
+ {/snippet}
18
+ </SkeletonLoader>
19
19
  </Story>
20
20
 
21
21
  <Story name="ImagePlaceholder" asChild>
22
- <SkeletonLoader class="h-[100px] w-[500px]">
23
- {#snippet children({ Skeleton, SkeletonImage })}
24
- <div class="flex h-full gap-2">
25
- <Skeleton class="flex h-full w-[160px] items-center justify-center">
26
- <SkeletonImage />
27
- </Skeleton>
28
- <div class="flex flex-1 flex-col gap-2">
29
- <Skeleton class="flex h-[20px] w-full" />
30
- <Skeleton class="flex h-[20px] w-full" />
31
- <Skeleton class="flex h-[20px] w-full" />
32
- <Skeleton class="flex h-[20px] w-full" />
33
- </div>
34
- </div>
35
- {/snippet}
36
- </SkeletonLoader>
22
+ <SkeletonLoader class="h-[100px] w-[500px]">
23
+ {#snippet children({ Skeleton, SkeletonImage })}
24
+ <div class="flex h-full gap-2">
25
+ <Skeleton class="flex h-full w-[160px] items-center justify-center">
26
+ <SkeletonImage />
27
+ </Skeleton>
28
+ <div class="flex flex-1 flex-col gap-2">
29
+ <Skeleton class="flex h-[20px] w-full" />
30
+ <Skeleton class="flex h-[20px] w-full" />
31
+ <Skeleton class="flex h-[20px] w-full" />
32
+ <Skeleton class="flex h-[20px] w-full" />
33
+ </div>
34
+ </div>
35
+ {/snippet}
36
+ </SkeletonLoader>
37
37
  </Story>
38
38
 
39
39
  <Story name="StatCard" asChild>
40
- <div class="flex w-[900px] gap-4">
41
- <StatcardSkeleton />
42
- <StatcardSkeleton />
43
- <StatcardSkeleton />
44
- </div>
40
+ <div class="flex w-[900px] gap-4">
41
+ <StatcardSkeleton />
42
+ <StatcardSkeleton />
43
+ <StatcardSkeleton />
44
+ </div>
45
45
  </Story>