@ponti-studios/ui 1.6.0 → 1.8.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 (79) hide show
  1. package/README.md +7 -11
  2. package/package.json +6 -31
  3. package/src/components/feedback/alert.tsx +8 -4
  4. package/src/components/feedback/index.ts +0 -4
  5. package/src/components/feedback/progress.stories.tsx +15 -0
  6. package/src/components/feedback/progress.tsx +14 -3
  7. package/src/components/feedback/update-guard.stories.tsx +4 -8
  8. package/src/components/feedback/update-guard.tsx +41 -272
  9. package/src/components/filters/filter-select.tsx +3 -5
  10. package/src/components/forms/date-picker.stories.tsx +158 -18
  11. package/src/components/forms/date-picker.tsx +286 -64
  12. package/src/components/forms/date-utils.ts +7 -2
  13. package/src/components/forms/drop-zone.tsx +11 -12
  14. package/src/components/forms/index.ts +2 -6
  15. package/src/components/forms/passkey-management.stories.tsx +8 -4
  16. package/src/components/forms/passkey-management.tsx +78 -42
  17. package/src/components/forms/radio-group.stories.tsx +3 -5
  18. package/src/components/forms/radio-group.tsx +2 -2
  19. package/src/components/forms/select.stories.tsx +16 -13
  20. package/src/components/forms/textarea.stories.tsx +1 -1
  21. package/src/components/layout/index.ts +2 -0
  22. package/src/components/layout/particle-background.stories.tsx +38 -0
  23. package/src/components/layout/particle-background.tsx +378 -0
  24. package/src/components/layout/scroll-area.stories.tsx +12 -4
  25. package/src/components/layout/scroll-area.tsx +41 -4
  26. package/src/components/navigation/tabs.stories.tsx +0 -21
  27. package/src/components/overlays/dialog.stories.tsx +38 -1
  28. package/src/components/overlays/dialog.tsx +53 -12
  29. package/src/components/overlays/index.ts +0 -11
  30. package/src/components/primitives/avatar-placeholder.svg +13 -0
  31. package/src/components/primitives/avatar.stories.tsx +2 -1
  32. package/src/components/primitives/badge.stories.tsx +13 -3
  33. package/src/components/primitives/badge.tsx +1 -1
  34. package/src/components/primitives/button.tsx +1 -1
  35. package/src/components/primitives/card.tsx +6 -2
  36. package/src/components/primitives/index.ts +0 -3
  37. package/src/index.ts +1 -3
  38. package/src/lib/index.ts +2 -3
  39. package/src/styles/animations.css +62 -0
  40. package/src/styles/index.css +31 -4
  41. package/src/styles/tokens/color-systems.stories.tsx +173 -25
  42. package/src/styles/tokens/generated/dark.colors.generated.ts +20 -12
  43. package/src/styles/tokens/generated/dark.css +20 -12
  44. package/src/styles/tokens/generated/light.colors.generated.ts +19 -11
  45. package/src/styles/tokens/generated/light.css +19 -11
  46. package/src/styles/tokens/index.ts +0 -3
  47. package/src/styles/tokens/scripts/check-source.mjs +7 -0
  48. package/src/styles/tokens/source/dark.tokens.json +44 -12
  49. package/src/styles/tokens/source/light.tokens.json +43 -11
  50. package/src/styles/tokens/typography.stories.tsx +157 -0
  51. package/src/components/feedback/file-upload-status.stories.tsx +0 -57
  52. package/src/components/feedback/file-upload-status.tsx +0 -160
  53. package/src/components/feedback/progress-bar.stories.tsx +0 -39
  54. package/src/components/feedback/progress-bar.tsx +0 -22
  55. package/src/components/forms/calendar.stories.tsx +0 -30
  56. package/src/components/forms/calendar.tsx +0 -75
  57. package/src/components/forms/date-field.stories.tsx +0 -202
  58. package/src/components/forms/date-field.tsx +0 -179
  59. package/src/components/overlays/alert-dialog.stories.tsx +0 -45
  60. package/src/components/overlays/alert-dialog.tsx +0 -116
  61. package/src/components/primitives/label.stories.tsx +0 -29
  62. package/src/components/primitives/label.tsx +0 -20
  63. package/src/components/primitives/status-badge.stories.tsx +0 -52
  64. package/src/components/primitives/status-badge.tsx +0 -33
  65. package/src/lib/create-memory-storage.ts +0 -24
  66. package/src/native/card.tsx +0 -36
  67. package/src/native/icon-button.tsx +0 -41
  68. package/src/native/index.ts +0 -38
  69. package/src/native/list-row.tsx +0 -67
  70. package/src/native/make-styles.ts +0 -32
  71. package/src/native/shadows.ts +0 -38
  72. package/src/native/text-field.tsx +0 -34
  73. package/src/native/uniwind.d.ts +0 -1
  74. package/src/native/use-theme-colors.ts +0 -19
  75. package/src/styles/tokens/foundations.stories.tsx +0 -109
  76. package/src/styles/tokens/generated/native.generated.ts +0 -266
  77. package/src/styles/tokens/normalize-native.ts +0 -88
  78. package/src/styles/tokens/source/native.tokens.json +0 -204
  79. package/src/styles/tokens/style-dictionary.native.mjs +0 -26
@@ -3,25 +3,33 @@
3
3
  */
4
4
 
5
5
  :root {
6
- --background: #fcfcfd;
7
- --card: #f9f9fb;
8
- --popover: #f0f0f3;
9
- --muted: #f9f9fb;
10
- --text-primary: #1c2024;
11
- --text-secondary: #60646c;
12
- --tertiary: #80838d;
13
- --primary: #3e63dd;
6
+ --background: #f4f0e8;
7
+ --card: #fbf8f2;
8
+ --secondary: #e8e4da;
9
+ --popover: #f6f2ea;
10
+ --muted: #efe9dc;
11
+ --text-primary: #11110f;
12
+ --text-secondary: #6a6352;
13
+ --tertiary: #6d6659;
14
+ --primary: #107066;
15
+ --accent: #d7efeb;
14
16
  --destructive: #ce2c31;
15
17
  --success: #30a46c;
16
18
  --warning: #ffc53d;
19
+ --text-success: #1f7a50;
20
+ --text-warning: #8a5a00;
21
+ --success-foreground: #15110f;
22
+ --warning-foreground: #15110f;
17
23
  --primary-foreground: #ffffff;
24
+ --accent-foreground: #11110f;
18
25
  --destructive-foreground: #ffffff;
19
26
  --text-destructive: #c82c31;
20
- --border-default: #cdced6;
21
- --focus-ring: #3e63dd;
27
+ --text-accent: #107066;
28
+ --border-default: #8f8576;
29
+ --focus-ring: #107066;
22
30
  --chart-1: #3e63dd;
23
31
  --chart-2: #6e56cf;
24
- --chart-3: #12a594;
32
+ --chart-3: #c73178;
25
33
  --chart-4: #f76b15;
26
34
  --chart-5: #8b8d98;
27
35
  --chart-positive: #1f7a50;
@@ -1,7 +1,6 @@
1
1
  import darkTokens from "./generated/dark.colors.generated";
2
2
  import foundations from "./generated/foundations.generated";
3
3
  import lightTokens from "./generated/light.colors.generated";
4
- import nativeTokens from "./generated/native.generated";
5
4
 
6
5
  const toPixels = (value: string) => {
7
6
  if (value.endsWith("rem")) return Number.parseFloat(value) * 16;
@@ -39,7 +38,6 @@ export const fontFamilies = Object.fromEntries(
39
38
  Object.entries(foundations.font).map(([key, value]) => [key, value.join(", ")]),
40
39
  ) as Record<keyof typeof foundations.font, string>;
41
40
 
42
- export const fontFamiliesNative = { sans: "System", serif: "serif", mono: "monospace" } as const;
43
41
  export const textSizes = Object.fromEntries(
44
42
  Object.entries(foundations.text).map(([key, value]) => [key, toPixels(value)]),
45
43
  ) as Record<keyof typeof foundations.text, number>;
@@ -63,7 +61,6 @@ export const transitionDurations = Object.fromEntries(
63
61
  Object.entries(foundations.duration).map(([key, value]) => [key, toMilliseconds(value)]),
64
62
  ) as Record<keyof typeof foundations.duration, number>;
65
63
  export const animations = foundations.animate;
66
- export const motion = nativeTokens.motion;
67
64
 
68
65
  export type RadiusToken = keyof typeof radii;
69
66
  export type TextSizeToken = keyof typeof textSizes;
@@ -30,6 +30,13 @@ for (const file of sourceFiles) {
30
30
  const source = readFileSync(file, "utf8");
31
31
  for (const check of checks) {
32
32
  if (check.name === "legacy semantic utility classes" && file.endsWith(".css")) continue;
33
+ // The Colors foundation story intentionally lists token names as data;
34
+ // those strings are not Tailwind utility classes consumed by components.
35
+ if (
36
+ check.name === "legacy semantic utility classes" &&
37
+ file.endsWith("color-systems.stories.tsx")
38
+ )
39
+ continue;
33
40
  if (check.pattern.test(source))
34
41
  failures.push(`${check.name}: ${relative(sourceDirectory, file)}`);
35
42
  }
@@ -4,35 +4,43 @@
4
4
  },
5
5
  "background": {
6
6
  "$type": "color",
7
- "$value": "rgb(17, 17, 19)"
7
+ "$value": "rgb(23, 23, 20)"
8
8
  },
9
9
  "card": {
10
10
  "$type": "color",
11
- "$value": "rgb(24, 25, 27)"
11
+ "$value": "rgb(29, 29, 25)"
12
+ },
13
+ "secondary": {
14
+ "$type": "color",
15
+ "$value": "rgb(43, 43, 37)"
12
16
  },
13
17
  "popover": {
14
18
  "$type": "color",
15
- "$value": "rgb(33, 34, 37)"
19
+ "$value": "rgb(34, 34, 30)"
16
20
  },
17
21
  "muted": {
18
22
  "$type": "color",
19
- "$value": "rgb(24, 25, 27)"
23
+ "$value": "rgb(29, 29, 25)"
20
24
  },
21
25
  "text-primary": {
22
26
  "$type": "color",
23
- "$value": "rgb(237, 238, 240)"
27
+ "$value": "rgb(255, 255, 255)"
24
28
  },
25
29
  "text-secondary": {
26
30
  "$type": "color",
27
- "$value": "rgb(176, 180, 186)"
31
+ "$value": "rgb(170, 167, 159)"
28
32
  },
29
33
  "tertiary": {
30
34
  "$type": "color",
31
- "$value": "rgb(119, 123, 132)"
35
+ "$value": "rgb(208, 204, 194)"
32
36
  },
33
37
  "primary": {
34
38
  "$type": "color",
35
- "$value": "rgb(62, 99, 221)"
39
+ "$value": "rgb(23, 130, 119)"
40
+ },
41
+ "accent": {
42
+ "$type": "color",
43
+ "$value": "rgb(33, 67, 63)"
36
44
  },
37
45
  "destructive": {
38
46
  "$type": "color",
@@ -46,10 +54,30 @@
46
54
  "$type": "color",
47
55
  "$value": "rgb(255, 197, 61)"
48
56
  },
57
+ "text-success": {
58
+ "$type": "color",
59
+ "$value": "rgb(85, 216, 154)"
60
+ },
61
+ "text-warning": {
62
+ "$type": "color",
63
+ "$value": "rgb(255, 216, 106)"
64
+ },
65
+ "success-foreground": {
66
+ "$type": "color",
67
+ "$value": "rgb(21, 17, 15)"
68
+ },
69
+ "warning-foreground": {
70
+ "$type": "color",
71
+ "$value": "rgb(21, 17, 15)"
72
+ },
49
73
  "primary-foreground": {
50
74
  "$type": "color",
51
75
  "$value": "rgb(255, 255, 255)"
52
76
  },
77
+ "accent-foreground": {
78
+ "$type": "color",
79
+ "$value": "rgb(255, 255, 255)"
80
+ },
53
81
  "destructive-foreground": {
54
82
  "$type": "color",
55
83
  "$value": "rgb(255, 255, 255)"
@@ -58,13 +86,17 @@
58
86
  "$type": "color",
59
87
  "$value": "rgb(255, 149, 146)"
60
88
  },
89
+ "text-accent": {
90
+ "$type": "color",
91
+ "$value": "rgb(27, 152, 139)"
92
+ },
61
93
  "border-default": {
62
94
  "$type": "color",
63
- "$value": "rgb(67, 72, 78)"
95
+ "$value": "rgb(107, 107, 102)"
64
96
  },
65
97
  "focus-ring": {
66
98
  "$type": "color",
67
- "$value": "rgb(62, 99, 221)"
99
+ "$value": "rgb(27, 152, 139)"
68
100
  },
69
101
  "chart-1": {
70
102
  "$type": "color",
@@ -76,7 +108,7 @@
76
108
  },
77
109
  "chart-3": {
78
110
  "$type": "color",
79
- "$value": "rgb(18, 165, 148)"
111
+ "$value": "rgb(199, 49, 120)"
80
112
  },
81
113
  "chart-4": {
82
114
  "$type": "color",
@@ -96,7 +128,7 @@
96
128
  },
97
129
  "chart-neutral": {
98
130
  "$type": "color",
99
- "$value": "rgb(90, 97, 105)"
131
+ "$value": "rgb(135, 141, 148)"
100
132
  },
101
133
  "overlay-scrim": {
102
134
  "$type": "color",
@@ -4,35 +4,43 @@
4
4
  },
5
5
  "background": {
6
6
  "$type": "color",
7
- "$value": "rgb(252, 252, 253)"
7
+ "$value": "rgb(244, 240, 232)"
8
8
  },
9
9
  "card": {
10
10
  "$type": "color",
11
- "$value": "rgb(249, 249, 251)"
11
+ "$value": "rgb(251, 248, 242)"
12
+ },
13
+ "secondary": {
14
+ "$type": "color",
15
+ "$value": "rgb(232, 228, 218)"
12
16
  },
13
17
  "popover": {
14
18
  "$type": "color",
15
- "$value": "rgb(240, 240, 243)"
19
+ "$value": "rgb(246, 242, 234)"
16
20
  },
17
21
  "muted": {
18
22
  "$type": "color",
19
- "$value": "rgb(249, 249, 251)"
23
+ "$value": "rgb(239, 233, 220)"
20
24
  },
21
25
  "text-primary": {
22
26
  "$type": "color",
23
- "$value": "rgb(28, 32, 36)"
27
+ "$value": "rgb(17, 17, 15)"
24
28
  },
25
29
  "text-secondary": {
26
30
  "$type": "color",
27
- "$value": "rgb(96, 100, 108)"
31
+ "$value": "rgb(106, 99, 82)"
28
32
  },
29
33
  "tertiary": {
30
34
  "$type": "color",
31
- "$value": "rgb(128, 131, 141)"
35
+ "$value": "rgb(109, 102, 89)"
32
36
  },
33
37
  "primary": {
34
38
  "$type": "color",
35
- "$value": "rgb(62, 99, 221)"
39
+ "$value": "rgb(16, 112, 102)"
40
+ },
41
+ "accent": {
42
+ "$type": "color",
43
+ "$value": "rgb(215, 239, 235)"
36
44
  },
37
45
  "destructive": {
38
46
  "$type": "color",
@@ -46,10 +54,30 @@
46
54
  "$type": "color",
47
55
  "$value": "rgb(255, 197, 61)"
48
56
  },
57
+ "text-success": {
58
+ "$type": "color",
59
+ "$value": "rgb(31, 122, 80)"
60
+ },
61
+ "text-warning": {
62
+ "$type": "color",
63
+ "$value": "rgb(138, 90, 0)"
64
+ },
65
+ "success-foreground": {
66
+ "$type": "color",
67
+ "$value": "rgb(21, 17, 15)"
68
+ },
69
+ "warning-foreground": {
70
+ "$type": "color",
71
+ "$value": "rgb(21, 17, 15)"
72
+ },
49
73
  "primary-foreground": {
50
74
  "$type": "color",
51
75
  "$value": "rgb(255, 255, 255)"
52
76
  },
77
+ "accent-foreground": {
78
+ "$type": "color",
79
+ "$value": "rgb(17, 17, 15)"
80
+ },
53
81
  "destructive-foreground": {
54
82
  "$type": "color",
55
83
  "$value": "rgb(255, 255, 255)"
@@ -58,13 +86,17 @@
58
86
  "$type": "color",
59
87
  "$value": "rgb(200, 44, 49)"
60
88
  },
89
+ "text-accent": {
90
+ "$type": "color",
91
+ "$value": "rgb(16, 112, 102)"
92
+ },
61
93
  "border-default": {
62
94
  "$type": "color",
63
- "$value": "rgb(205, 206, 214)"
95
+ "$value": "rgb(143, 133, 118)"
64
96
  },
65
97
  "focus-ring": {
66
98
  "$type": "color",
67
- "$value": "rgb(62, 99, 221)"
99
+ "$value": "rgb(16, 112, 102)"
68
100
  },
69
101
  "chart-1": {
70
102
  "$type": "color",
@@ -76,7 +108,7 @@
76
108
  },
77
109
  "chart-3": {
78
110
  "$type": "color",
79
- "$value": "rgb(18, 165, 148)"
111
+ "$value": "rgb(199, 49, 120)"
80
112
  },
81
113
  "chart-4": {
82
114
  "$type": "color",
@@ -0,0 +1,157 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+
3
+ import { fontFamilies, fontWeights, textLineHeights, textSizes, tracking } from "./index";
4
+
5
+ const meta: Meta = { title: "Foundations/Typography", parameters: { layout: "fullscreen" } };
6
+ export default meta;
7
+ type Story = StoryObj<typeof meta>;
8
+
9
+ const sizeTokens = Object.keys(textSizes) as Array<keyof typeof textSizes>;
10
+ const weightTokens = Object.keys(fontWeights) as Array<keyof typeof fontWeights>;
11
+ const trackingTokens = Object.keys(tracking) as Array<keyof typeof tracking>;
12
+ const familyTokens = Object.keys(fontFamilies) as Array<keyof typeof fontFamilies>;
13
+
14
+ export const TypeScale: Story = {
15
+ render: () => (
16
+ <main className="bg-background text-foreground grid min-h-screen gap-10 p-6 md:p-10">
17
+ <header className="grid gap-2">
18
+ <h1 className="text-2xl font-semibold">Typography</h1>
19
+ <p className="text-muted-foreground max-w-prose text-sm">
20
+ Font sizes, weights, tracking, and families as defined by the shared design tokens (
21
+ <code className="font-mono">src/styles/tokens</code>).
22
+ </p>
23
+ </header>
24
+
25
+ <section className="grid gap-4">
26
+ <h2 className="text-muted-foreground text-xs font-medium tracking-wider uppercase">
27
+ Type scale
28
+ </h2>
29
+ <div className="border-border divide-border grid divide-y rounded-md border">
30
+ {sizeTokens.map((token) => (
31
+ <div key={token} className="grid grid-cols-[6rem_5rem_1fr] items-baseline gap-4 p-4">
32
+ <span className="text-muted-foreground font-mono text-xs">text-{token}</span>
33
+ <span className="text-muted-foreground font-mono text-xs tabular-nums">
34
+ {textSizes[token]}px / {textLineHeights[token]?.toFixed(2)}
35
+ </span>
36
+ <span
37
+ className="truncate"
38
+ style={{ fontSize: textSizes[token], lineHeight: textLineHeights[token] }}
39
+ >
40
+ The quick brown fox jumps
41
+ </span>
42
+ </div>
43
+ ))}
44
+ </div>
45
+ </section>
46
+
47
+ <section className="grid gap-4">
48
+ <h2 className="text-muted-foreground text-xs font-medium tracking-wider uppercase">
49
+ Font weights
50
+ </h2>
51
+ <div className="border-border divide-border grid divide-y rounded-md border">
52
+ {weightTokens.map((token) => (
53
+ <div key={token} className="grid grid-cols-[8rem_1fr] items-baseline gap-4 p-4">
54
+ <span className="text-muted-foreground font-mono text-xs">
55
+ {token} / {fontWeights[token]}
56
+ </span>
57
+ <span className="text-lg" style={{ fontWeight: fontWeights[token] }}>
58
+ The quick brown fox jumps over the lazy dog
59
+ </span>
60
+ </div>
61
+ ))}
62
+ </div>
63
+ </section>
64
+
65
+ <section className="grid gap-4">
66
+ <h2 className="text-muted-foreground text-xs font-medium tracking-wider uppercase">
67
+ Tracking
68
+ </h2>
69
+ <div className="border-border divide-border grid divide-y rounded-md border">
70
+ {trackingTokens.map((token) => (
71
+ <div key={token} className="grid grid-cols-[8rem_1fr] items-baseline gap-4 p-4">
72
+ <span className="text-muted-foreground font-mono text-xs">
73
+ {token} / {tracking[token]}
74
+ </span>
75
+ <span className="text-lg" style={{ letterSpacing: tracking[token] }}>
76
+ The quick brown fox jumps over the lazy dog
77
+ </span>
78
+ </div>
79
+ ))}
80
+ </div>
81
+ </section>
82
+
83
+ <section className="grid gap-4">
84
+ <h2 className="text-muted-foreground text-xs font-medium tracking-wider uppercase">
85
+ Font families
86
+ </h2>
87
+ <div className="border-border divide-border grid divide-y rounded-md border">
88
+ {familyTokens.map((token) => (
89
+ <div key={token} className="grid gap-2 p-4">
90
+ <span className="text-muted-foreground font-mono text-xs">--font-{token}</span>
91
+ <span className="text-2xl" style={{ fontFamily: fontFamilies[token] }}>
92
+ The quick brown fox jumps over the lazy dog. 0123456789
93
+ </span>
94
+ </div>
95
+ ))}
96
+ </div>
97
+ </section>
98
+ </main>
99
+ ),
100
+ };
101
+
102
+ const headingSpecimens = [
103
+ { tag: "h1" as const, className: "text-4xl" },
104
+ { tag: "h2" as const, className: "text-3xl" },
105
+ { tag: "h3" as const, className: "text-2xl" },
106
+ { tag: "h4" as const, className: "text-xl" },
107
+ { tag: "h5" as const, className: "text-lg" },
108
+ { tag: "h6" as const, className: "text-base" },
109
+ ];
110
+
111
+ export const Headings: Story = {
112
+ render: () => (
113
+ <main className="bg-background text-foreground grid min-h-screen gap-10 p-6 md:p-10">
114
+ <header className="grid gap-2">
115
+ <h1 className="text-2xl font-semibold">Headings</h1>
116
+ <p className="text-muted-foreground max-w-prose text-sm">
117
+ `h1`–`h6` only carry font-family, weight, and tracking from the base layer — size is unset
118
+ by tag, so components pair a heading element with an explicit{" "}
119
+ <code className="font-mono">text-*</code> utility. The sizes below match this
120
+ codebase&apos;s own usage, not an enforced per-level scale.
121
+ </p>
122
+ </header>
123
+
124
+ <section className="grid gap-4">
125
+ <h2 className="text-muted-foreground text-xs font-medium tracking-wider uppercase">
126
+ Display utilities
127
+ </h2>
128
+ <div className="border-border divide-border grid divide-y rounded-md border">
129
+ <div className="grid gap-2 p-4">
130
+ <span className="text-muted-foreground font-mono text-xs">display-1</span>
131
+ <p className="display-1">Display one</p>
132
+ </div>
133
+ <div className="grid gap-2 p-4">
134
+ <span className="text-muted-foreground font-mono text-xs">display-2</span>
135
+ <p className="display-2">Display two</p>
136
+ </div>
137
+ </div>
138
+ </section>
139
+
140
+ <section className="grid gap-4">
141
+ <h2 className="text-muted-foreground text-xs font-medium tracking-wider uppercase">
142
+ Semantic headings
143
+ </h2>
144
+ <div className="border-border divide-border grid divide-y rounded-md border">
145
+ {headingSpecimens.map(({ tag: Tag, className }) => (
146
+ <div key={Tag} className="grid grid-cols-[6rem_1fr] items-baseline gap-4 p-4">
147
+ <span className="text-muted-foreground font-mono text-xs">
148
+ {Tag} / {className}
149
+ </span>
150
+ <Tag className={className}>The quick brown fox jumps over the lazy dog</Tag>
151
+ </div>
152
+ ))}
153
+ </div>
154
+ </section>
155
+ </main>
156
+ ),
157
+ };
@@ -1,57 +0,0 @@
1
- import type { Meta, StoryObj } from "@storybook/react-vite";
2
-
3
- import { FileUploadStatus } from "./file-upload-status";
4
-
5
- const meta = {
6
- title: "Feedback/FileUploadStatus",
7
- component: FileUploadStatus,
8
- tags: ["autodocs"],
9
- } satisfies Meta<typeof FileUploadStatus>;
10
-
11
- export default meta;
12
- type Story = StoryObj<typeof meta>;
13
-
14
- export const Uploading: Story = {
15
- render: () => (
16
- <div className="w-80">
17
- <FileUploadStatus uploadStatus={{ status: "uploading", stats: { progress: 42 } }} />
18
- </div>
19
- ),
20
- };
21
-
22
- export const Queued: Story = {
23
- render: () => (
24
- <div className="w-80">
25
- <FileUploadStatus uploadStatus={{ status: "queued" }} />
26
- </div>
27
- ),
28
- };
29
-
30
- export const Done: Story = {
31
- render: () => (
32
- <div className="w-80">
33
- <FileUploadStatus
34
- uploadStatus={{
35
- status: "done",
36
- stats: {
37
- processingTime: 4200,
38
- total: 128,
39
- created: 90,
40
- updated: 30,
41
- skipped: 8,
42
- },
43
- }}
44
- />
45
- </div>
46
- ),
47
- };
48
-
49
- export const Error: Story = {
50
- render: () => (
51
- <div className="w-80">
52
- <FileUploadStatus
53
- uploadStatus={{ status: "error", error: "Could not parse the CSV file." }}
54
- />
55
- </div>
56
- ),
57
- };