@reshape-biotech/design-system 2.7.5 → 2.7.6

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.
@@ -46,7 +46,7 @@
46
46
  </Story>
47
47
 
48
48
  <Story name="No toggle" asChild>
49
- <Banner type="progress" closable={false}>
49
+ <Banner type="info" closable={false}>
50
50
  {#snippet icon()}
51
51
  <Icon size={20} color="icon-blue" weight="bold">
52
52
  {#snippet children(props)}
@@ -117,7 +117,7 @@
117
117
 
118
118
  <div class="space-y-2">
119
119
  <h4>Progress</h4>
120
- <Banner type="progress">
120
+ <Banner type="info">
121
121
  {#snippet icon()}
122
122
  <Icon size={20} color="icon-blue" weight="bold">
123
123
  {#snippet children(props)}
@@ -126,7 +126,7 @@
126
126
  </Icon>
127
127
  {/snippet}
128
128
  {#snippet content()}
129
- This is a "progress" banner.
129
+ This is a "info" banner.
130
130
  {/snippet}
131
131
  </Banner>
132
132
  </div>
@@ -5,11 +5,12 @@
5
5
  import { Icon } from '../icons/';
6
6
 
7
7
  interface Props {
8
- type?: 'neutral' | 'success' | 'progress' | 'warning' | 'error';
8
+ type?: 'neutral' | 'success' | 'info' | 'warning' | 'error';
9
9
  show?: boolean;
10
10
  closable?: boolean;
11
11
  icon?: Snippet;
12
12
  content: Snippet;
13
+ compact?: boolean;
13
14
  }
14
15
 
15
16
  let {
@@ -18,22 +19,27 @@
18
19
  closable = true,
19
20
  icon,
20
21
  content,
22
+ compact = true,
21
23
  }: Props = $props();
22
24
 
23
25
  const color = {
24
26
  neutral: 'neutral',
25
27
  success: 'success',
26
- progress: 'blue',
28
+ info: 'blue',
27
29
  warning: 'warning',
28
30
  error: 'danger',
29
31
  }[type];
30
32
  </script>
31
33
 
32
34
  {#if show}
33
- <div class="rounded-lg bg-{color} flex w-full items-center justify-between p-3">
34
- <div class="inline-flex w-full items-center justify-start gap-3">
35
+ <div
36
+ class="bg-{color} flex min-h-12 w-full items-center justify-between p-2 {compact
37
+ ? 'rounded-xl'
38
+ : 'rounded-2xl'}"
39
+ >
40
+ <div class="inline-flex w-full items-center justify-start gap-2">
35
41
  {#if icon}
36
- <div class="flex size-5 items-center justify-center text-icon-{color} ">
42
+ <div class="flex items-center justify-center px-1 text-icon-{color}">
37
43
  {@render icon?.()}
38
44
  </div>
39
45
  {/if}
@@ -42,7 +48,7 @@
42
48
  </div>
43
49
  </div>
44
50
  {#if closable}
45
- <IconButton size="sm" onclick={() => (show = false)}>
51
+ <IconButton size="sm" onclick={() => (show = false)} variant="transparent" rounded={false}>
46
52
  <Icon color="icon-secondary" weight="bold" icon={X} />
47
53
  </IconButton>
48
54
  {/if}
@@ -1,10 +1,11 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  interface Props {
3
- type?: 'neutral' | 'success' | 'progress' | 'warning' | 'error';
3
+ type?: 'neutral' | 'success' | 'info' | 'warning' | 'error';
4
4
  show?: boolean;
5
5
  closable?: boolean;
6
6
  icon?: Snippet;
7
7
  content: Snippet;
8
+ compact?: boolean;
8
9
  }
9
10
  declare const Banner: import("svelte").Component<Props, {}, "show">;
10
11
  type Banner = ReturnType<typeof Banner>;
@@ -119,7 +119,7 @@
119
119
 
120
120
  .button:disabled {
121
121
 
122
- border-style: none;
122
+ border-color: transparent;
123
123
 
124
124
  background-color: #12192a0A;
125
125
 
@@ -331,7 +331,7 @@
331
331
  }
332
332
  .btn-transparent-inverse:hover {
333
333
 
334
- background-color: #FFFFFF26
334
+ background-color: #FFFFFF0D
335
335
  }
336
336
  .btn-transparent-inverse:active {
337
337
 
@@ -108,7 +108,7 @@
108
108
  <Story name="Card nested in CardWrapper" args={{ class: 'w-96' }} asChild>
109
109
  <CardWrapper class="w-96" variant="compact">
110
110
  {#snippet Header()}
111
- <h5>Overview</h5>
111
+ <h6>Overview</h6>
112
112
  <span class="text-sm text-success">Active</span>
113
113
  {/snippet}
114
114
  {#snippet children()}
@@ -124,7 +124,7 @@
124
124
  </Card>
125
125
  {/snippet}
126
126
  {#snippet Footer()}
127
- <p class="py-2 text-xs text-secondary">Last updated 2 hours ago</p>
127
+ <p class="px-3 py-2 text-xs text-secondary">Last updated 2 hours ago</p>
128
128
  {/snippet}
129
129
  </CardWrapper>
130
130
  </Story>
@@ -19,7 +19,7 @@
19
19
  </script>
20
20
 
21
21
  <div
22
- class="overflow-hidden rounded-lg border border-static bg-surface shadow-container {additionalClasses}"
22
+ class="overflow-hidden rounded-[10px] border border-static bg-surface shadow-container {additionalClasses}"
23
23
  >
24
24
  {#if Header}
25
25
  <header
@@ -45,7 +45,7 @@
45
45
  {@render children()}
46
46
  </div>
47
47
  {#if Footer}
48
- <footer class="flex min-h-8 w-full items-center px-3">
48
+ <footer class="flex min-h-8 w-full items-center">
49
49
  {@render Footer()}
50
50
  </footer>
51
51
  {/if}
@@ -60,7 +60,7 @@
60
60
 
61
61
  --tw-bg-opacity: 1;
62
62
 
63
- background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1))
63
+ background-color: rgb(249 249 250 / var(--tw-bg-opacity, 1))
64
64
  }
65
65
 
66
66
  .wrapper.default {
@@ -80,19 +80,4 @@
80
80
 
81
81
  padding: 0.125rem
82
82
  }
83
-
84
- .wrapper-footer {
85
-
86
- display: flex;
87
-
88
- min-height: 2rem;
89
-
90
- width: 100%;
91
-
92
- align-items: center;
93
-
94
- padding-left: 1rem;
95
-
96
- padding-right: 1rem
97
- }
98
83
  </style>
@@ -205,7 +205,7 @@ input::placeholder {
205
205
 
206
206
  --tw-bg-opacity: 1;
207
207
 
208
- background-color: rgb(250 250 250 / var(--tw-bg-opacity, 1))
208
+ background-color: rgb(249 249 250 / var(--tw-bg-opacity, 1))
209
209
  }
210
210
 
211
211
  .transparent {
@@ -9,9 +9,9 @@
9
9
  let { children, items }: Props = $props();
10
10
  </script>
11
11
 
12
- <div class="inline-flex w-full flex-col items-center rounded-[10px] bg-base">
12
+ <div class="inline-flex w-full flex-col items-center rounded-xl bg-base">
13
13
  <div
14
- class="flex w-full px-0.5 pt-0.5 [&>*]:rounded-lg [&>*]:border [&>*]:border-static [&>*]:p-1"
14
+ class="flex w-full px-0.5 pt-0.5 [&>*]:rounded-[10px] [&>*]:border [&>*]:border-static [&>*]:p-1"
15
15
  >
16
16
  {@render children()}
17
17
  </div>
@@ -545,41 +545,41 @@
545
545
  </script>
546
546
 
547
547
  {#snippet UndoResetControls()}
548
- <div class="flex items-center gap-1">
549
- <IconButton
550
- variant="transparent-inverse"
551
- rounded={false}
552
- onclick={undo}
553
- disabled={marks.length === 0 || disabled}
554
- aria-label="Undo last mark"
555
- >
556
- <Icon icon={ArrowUUpLeft} />
557
- </IconButton>
558
- <Divider vertical inverse class="!h-5" />
559
- <Button
560
- variant="transparent-inverse"
561
- size="sm"
562
- onClick={reset}
563
- disabled={marks.length === 0 || disabled}
564
- accessibilityLabel="Reset all marks"
565
- class="!text-primary-inverse"
566
- >
567
- Clear all
568
- </Button>
569
- </div>
548
+ {#if marks.length > 0}
549
+ <div class="flex items-center gap-2">
550
+ <IconButton
551
+ variant="transparent-inverse"
552
+ rounded={false}
553
+ onclick={undo}
554
+ disabled={marks.length === 0 || disabled}
555
+ aria-label="Undo last mark"
556
+ >
557
+ <Icon icon={ArrowUUpLeft} />
558
+ </IconButton>
559
+ <Divider vertical inverse class="!h-4" />
560
+ <Button
561
+ variant="transparent-inverse"
562
+ size="sm"
563
+ onClick={reset}
564
+ disabled={marks.length === 0 || disabled}
565
+ accessibilityLabel="Reset all marks"
566
+ class="!text-primary-inverse"
567
+ >
568
+ Clear all
569
+ </Button>
570
+ </div>
571
+ {/if}
570
572
  {/snippet}
571
573
 
572
574
  {#snippet TopLeftActions()}
573
575
  {#if activeMarkerName && !hideMarkers && !disabled}
574
- <div
575
- class="absolute left-2 top-2 z-20 flex w-full max-w-[calc(100%-1rem)] items-center justify-between rounded-lg border border-interactive-inverse bg-base-inverse px-3 py-2"
576
- >
577
- <div class="flex items-center gap-2">
576
+ <div class="flex h-10 items-center justify-between rounded-lg px-2 py-2">
577
+ <div class="flex items-center gap-3">
578
578
  <div
579
579
  class="flex !h-6 !w-6 shrink-0 items-center justify-center rounded-md"
580
580
  style="background-color: {resolvedActiveMarkerColor()}"
581
581
  >
582
- <Icon size={16} color="primary-inverse" icon={CursorClick} />
582
+ <Icon color="primary-inverse" icon={CursorClick} />
583
583
  </div>
584
584
 
585
585
  <span class="text-sm text-primary-inverse">
@@ -594,7 +594,7 @@
594
594
 
595
595
  {#snippet ZoomControls()}
596
596
  <div
597
- class="absolute bottom-2 right-2 z-20 flex flex-col items-center gap-1 rounded-md border border-interactive-inverse bg-base-inverse p-1 opacity-0 transition-opacity duration-200 group-hover:opacity-100"
597
+ class="absolute bottom-2 right-2 z-20 flex flex-col items-center gap-1 rounded-xl border border-static-inverse bg-base-inverse p-1 opacity-0 transition-opacity duration-200 group-hover:opacity-100"
598
598
  >
599
599
  <IconButton
600
600
  variant="transparent-inverse"
@@ -617,57 +617,59 @@
617
617
  </div>
618
618
  {/snippet}
619
619
 
620
- <div
621
- bind:this={container}
622
- class="group relative h-full w-full overflow-hidden rounded-lg border"
623
- data-testid="manual-cfu-counter"
624
- >
620
+ <div class="flex h-full w-full flex-col gap-1 p-1" data-testid="manual-cfu-counter">
625
621
  {#if !hideMarkers && !disabled}
626
622
  {@render TopLeftActions()}
627
- {@render ZoomControls()}
628
623
  {/if}
629
624
 
630
- <!--
631
- We need to use SVG for this interactive component.
632
- The SVG element is treated as a canvas for clicking, panning, and zooming.
633
- We add accessibility attributes to make it more accessible despite the interactive nature.
634
- -->
635
- <!-- svelte-ignore a11y_click_events_have_key_events -->
636
- <!-- svelte-ignore a11y_no_static_element_interactions -->
637
- <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
638
- <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
639
- <svg
640
- bind:this={svgElement}
641
- onclick={handleClick}
642
- onmousedown={handleMouseDown}
643
- onmousemove={handleMouseMove}
644
- onmouseup={handleMouseUp}
645
- onmouseleave={handleMouseLeave}
646
- oncontextmenu={handleContextMenu}
647
- onwheel={handleWheel}
648
- class:cursor-grabbing={panningState === 'active'}
649
- class:cursor-grab={!disabled && (panningState === 'ready' || (isShiftPressed && !panningState))}
650
- class:cursor-not-allowed={disabled}
651
- class:cursor-crosshair={!disabled && !panningState && !isShiftPressed}
652
- class="h-full w-full"
653
- role="application"
654
- aria-label={disabled
655
- ? 'CFU Counter (disabled)'
656
- : 'CFU Counter - Click to add markers, right click or shift+click to pan'}
657
- tabindex="0"
658
- >
659
- <g bind:this={viewport} id="viewport" class="h-full w-full">
660
- <image href={imageUrl} x="0" y="0" width="100%" />
661
- <g
662
- bind:this={dotsGroup}
663
- id="dots"
664
- class="pointer-events-none"
665
- aria-hidden={hideMarkers}
666
- class:hidden={hideMarkers}
667
- />
668
- </g>
669
- </svg>
670
-
671
- <!-- Debug info for marks count - useful for testing -->
672
- <span class="sr-only" data-testid="marks-count">{marks.length}</span>
625
+ <div bind:this={container} class="group relative flex-1 overflow-hidden rounded-xl bg-black">
626
+ {#if !hideMarkers && !disabled}
627
+ {@render ZoomControls()}
628
+ {/if}
629
+
630
+ <!--
631
+ We need to use SVG for this interactive component.
632
+ The SVG element is treated as a canvas for clicking, panning, and zooming.
633
+ We add accessibility attributes to make it more accessible despite the interactive nature.
634
+ -->
635
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
636
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
637
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
638
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
639
+ <svg
640
+ bind:this={svgElement}
641
+ onclick={handleClick}
642
+ onmousedown={handleMouseDown}
643
+ onmousemove={handleMouseMove}
644
+ onmouseup={handleMouseUp}
645
+ onmouseleave={handleMouseLeave}
646
+ oncontextmenu={handleContextMenu}
647
+ onwheel={handleWheel}
648
+ class:cursor-grabbing={panningState === 'active'}
649
+ class:cursor-grab={!disabled &&
650
+ (panningState === 'ready' || (isShiftPressed && !panningState))}
651
+ class:cursor-not-allowed={disabled}
652
+ class:cursor-crosshair={!disabled && !panningState && !isShiftPressed}
653
+ class="h-full w-full focus:outline-none"
654
+ role="application"
655
+ aria-label={disabled
656
+ ? 'CFU Counter (disabled)'
657
+ : 'CFU Counter - Click to add markers, right click or shift+click to pan'}
658
+ tabindex="0"
659
+ >
660
+ <g bind:this={viewport} id="viewport" class="h-full w-full">
661
+ <image href={imageUrl} x="0" y="0" width="100%" />
662
+ <g
663
+ bind:this={dotsGroup}
664
+ id="dots"
665
+ class="pointer-events-none"
666
+ aria-hidden={hideMarkers}
667
+ class:hidden={hideMarkers}
668
+ />
669
+ </g>
670
+ </svg>
671
+
672
+ <!-- Debug info for marks count - useful for testing -->
673
+ <span class="sr-only" data-testid="marks-count">{marks.length}</span>
674
+ </div>
673
675
  </div>
@@ -31,7 +31,7 @@
31
31
  };
32
32
  </script>
33
33
 
34
- <div class="w-full rounded-lg border border-static bg-surface px-5 py-2 shadow-container">
34
+ <div class="w-full rounded-xl border border-static bg-surface px-5 py-2 shadow-container">
35
35
  <table class={`w-full table-fixed sm:table-auto xl:table-${tableLayout}`}>
36
36
  {@render children?.({ THead: THead, TBody: TBody, Tr: Tr, Th: Th, Td: Td })}
37
37
  </table>
@@ -35,9 +35,9 @@
35
35
  }: Props = $props();
36
36
 
37
37
  const sizes = {
38
- xs: 'h-5 text-xs p-1',
39
- sm: 'h-6 text-xs p-1.5',
40
- md: 'h-7 text-sm p-2',
38
+ xs: 'h-5 text-xs p-1 rounded',
39
+ sm: 'h-6 text-xs p-1.5 rounded',
40
+ md: 'h-7 text-sm p-2 rounded-md',
41
41
  };
42
42
  let sizeClassName = $derived(sizes[size]);
43
43
 
@@ -115,7 +115,6 @@
115
115
  gap: 0.5rem;
116
116
  overflow: hidden;
117
117
  text-overflow: ellipsis;
118
- white-space: nowrap;
119
- border-radius: 0.25rem
118
+ white-space: nowrap
120
119
  }
121
120
  </style>
@@ -50,7 +50,7 @@
50
50
  {side}
51
51
  {align}
52
52
  sideOffset={8}
53
- class={`${className} z-50 max-w-xs text-wrap rounded bg-base-inverse px-2 py-1 text-left text-sm font-normal text-primary-inverse shadow-menu`}
53
+ class={`${className} z-50 max-w-xs text-wrap rounded-md bg-base-inverse px-2 py-1 text-left text-sm font-normal text-primary-inverse shadow-menu`}
54
54
  >
55
55
  {#if content}
56
56
  {@render content()}
@@ -1,6 +1,6 @@
1
1
  export const colors = {
2
2
  base: {
3
- mist: '#fafafa',
3
+ mist: '#f9f9fa',
4
4
  snow: '#f6f7f7',
5
5
  white: {
6
6
  default: '#FFFFFF',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reshape-biotech/design-system",
3
- "version": "2.7.5",
3
+ "version": "2.7.6",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build",