@syscore/ui-library 1.25.0 → 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 (30) hide show
  1. package/client/components/ui/app-bar.tsx +299 -0
  2. package/client/components/ui/banner.tsx +108 -0
  3. package/client/components/ui/bottom-navigation.tsx +223 -0
  4. package/client/components/ui/card.tsx +108 -26
  5. package/client/components/ui/date-picker.tsx +188 -0
  6. package/client/components/ui/empty-state.tsx +197 -0
  7. package/client/components/ui/file-upload.tsx +214 -0
  8. package/client/components/ui/footer.tsx +179 -0
  9. package/client/components/ui/layout.tsx +381 -0
  10. package/client/components/ui/sidebar.tsx +11 -5
  11. package/client/components/ui/stepper.tsx +148 -0
  12. package/client/components/ui/system-bar.tsx +119 -0
  13. package/client/components/ui/timeline.tsx +181 -0
  14. package/client/global.css +2304 -41
  15. package/client/ui/AppBar/app-bar.stories.tsx +280 -0
  16. package/client/ui/Banner/banner.stories.tsx +238 -0
  17. package/client/ui/BottomNavigation/bottom-navigation.stories.tsx +285 -0
  18. package/client/ui/Card.stories.tsx +285 -168
  19. package/client/ui/DatePicker/DatePicker.stories.tsx +293 -0
  20. package/client/ui/EmptyState/empty-state.stories.tsx +251 -0
  21. package/client/ui/FileUpload/FileUpload.stories.tsx +218 -0
  22. package/client/ui/Footer/footer.stories.tsx +194 -0
  23. package/client/ui/Layout.stories.tsx +1481 -0
  24. package/client/ui/Stepper/Stepper.stories.tsx +344 -0
  25. package/client/ui/SystemBar/system-bar.stories.tsx +179 -0
  26. package/client/ui/Timeline/timeline.stories.tsx +404 -0
  27. package/dist/index.cjs.js +1 -1
  28. package/dist/index.d.ts +219 -0
  29. package/dist/index.es.js +1504 -99
  30. package/package.json +1 -1
@@ -0,0 +1,285 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { useState } from "react";
3
+ import {
4
+ BottomNavigation,
5
+ BottomNavigationItem,
6
+ BottomNavigationGroup,
7
+ } from "../../components/ui/bottom-navigation";
8
+ import {
9
+ History,
10
+ Heart,
11
+ MapPin,
12
+ Tv,
13
+ Music,
14
+ BookOpen,
15
+ Image,
16
+ } from "lucide-react";
17
+
18
+ const meta = {
19
+ title: "UI/BottomNavigation",
20
+ component: BottomNavigation,
21
+ tags: ["autodocs"],
22
+ parameters: {
23
+ layout: "fullscreen",
24
+ },
25
+ argTypes: {
26
+ grow: { control: "boolean" },
27
+ horizontal: { control: "boolean" },
28
+ shift: { control: "boolean" },
29
+ active: { control: "boolean" },
30
+ elevated: { control: "boolean" },
31
+ color: { control: "color" },
32
+ },
33
+ } satisfies Meta<typeof BottomNavigation>;
34
+
35
+ export default meta;
36
+
37
+ type Story = StoryObj<typeof meta>;
38
+
39
+ // ─── Wrapper helper — gives stories a realistic page height ──────────────────
40
+ function PageWrapper({ children }: { children: React.ReactNode }) {
41
+ return (
42
+ <div
43
+ style={{
44
+ position: "relative",
45
+ height: 200,
46
+ overflow: "hidden",
47
+ border: "1px solid #e5e7eb",
48
+ borderRadius: 8,
49
+ background: "#f9f9fa",
50
+ }}
51
+ >
52
+ {children}
53
+ </div>
54
+ );
55
+ }
56
+
57
+ // ─── Default ─────────────────────────────────────────────────────────────────
58
+
59
+ export const Default: Story = {
60
+ render: () => {
61
+ const [value, setValue] = useState(0);
62
+ return (
63
+ <PageWrapper>
64
+ <BottomNavigation value={value} onChange={(v) => setValue(Number(v))}>
65
+ <BottomNavigationGroup>
66
+ <BottomNavigationItem value={0}>
67
+ <History size={20} />
68
+ <span>Recent</span>
69
+ </BottomNavigationItem>
70
+ <BottomNavigationItem value={1}>
71
+ <Heart size={20} />
72
+ <span>Favorites</span>
73
+ </BottomNavigationItem>
74
+ <BottomNavigationItem value={2}>
75
+ <MapPin size={20} />
76
+ <span>Nearby</span>
77
+ </BottomNavigationItem>
78
+ </BottomNavigationGroup>
79
+ </BottomNavigation>
80
+ </PageWrapper>
81
+ );
82
+ },
83
+ };
84
+
85
+ // ─── Color ───────────────────────────────────────────────────────────────────
86
+ // The `color` prop applies the active highlight color to the selected item.
87
+
88
+ export const Color: Story = {
89
+ render: () => {
90
+ const [value, setValue] = useState(1);
91
+ return (
92
+ <PageWrapper>
93
+ <BottomNavigation
94
+ value={value}
95
+ onChange={(v) => setValue(Number(v))}
96
+ color="var(--color-cyan-800, #0f748a)"
97
+ >
98
+ <BottomNavigationGroup>
99
+ <BottomNavigationItem value={0}>
100
+ <History size={20} />
101
+ <span>Recents</span>
102
+ </BottomNavigationItem>
103
+ <BottomNavigationItem value={1}>
104
+ <Heart size={20} />
105
+ <span>Favorites</span>
106
+ </BottomNavigationItem>
107
+ <BottomNavigationItem value={2}>
108
+ <MapPin size={20} />
109
+ <span>Nearby</span>
110
+ </BottomNavigationItem>
111
+ </BottomNavigationGroup>
112
+ </BottomNavigation>
113
+ </PageWrapper>
114
+ );
115
+ },
116
+ };
117
+
118
+ // ─── Grow ─────────────────────────────────────────────────────────────────────
119
+ // Each item fills all available space (max 168px per MD spec).
120
+
121
+ export const Grow: Story = {
122
+ render: () => {
123
+ const [value, setValue] = useState(1);
124
+ return (
125
+ <PageWrapper>
126
+ <BottomNavigation
127
+ value={value}
128
+ onChange={(v) => setValue(Number(v))}
129
+ color="var(--color-cyan-800, #0f748a)"
130
+ grow
131
+ >
132
+ <BottomNavigationGroup>
133
+ <BottomNavigationItem value={0}>
134
+ <History size={20} />
135
+ <span>Recents</span>
136
+ </BottomNavigationItem>
137
+ <BottomNavigationItem value={1}>
138
+ <Heart size={20} />
139
+ <span>Favorites</span>
140
+ </BottomNavigationItem>
141
+ <BottomNavigationItem value={2}>
142
+ <MapPin size={20} />
143
+ <span>Nearby</span>
144
+ </BottomNavigationItem>
145
+ </BottomNavigationGroup>
146
+ </BottomNavigation>
147
+ </PageWrapper>
148
+ );
149
+ },
150
+ };
151
+
152
+ // ─── Horizontal ───────────────────────────────────────────────────────────────
153
+ // Icon and label sit side-by-side instead of stacked.
154
+
155
+ export const Horizontal: Story = {
156
+ render: () => {
157
+ const [value, setValue] = useState(1);
158
+ return (
159
+ <PageWrapper>
160
+ <BottomNavigation
161
+ value={value}
162
+ onChange={(v) => setValue(Number(v))}
163
+ color="var(--color-blue-600, #2e74ad)"
164
+ horizontal
165
+ >
166
+ <BottomNavigationGroup>
167
+ <BottomNavigationItem value={0}>
168
+ <History size={20} />
169
+ <span>Recents</span>
170
+ </BottomNavigationItem>
171
+ <BottomNavigationItem value={1}>
172
+ <Heart size={20} />
173
+ <span>Favorites</span>
174
+ </BottomNavigationItem>
175
+ <BottomNavigationItem value={2}>
176
+ <MapPin size={20} />
177
+ <span>Nearby</span>
178
+ </BottomNavigationItem>
179
+ </BottomNavigationGroup>
180
+ </BottomNavigation>
181
+ </PageWrapper>
182
+ );
183
+ },
184
+ };
185
+
186
+ // ─── Shift ────────────────────────────────────────────────────────────────────
187
+ // Only the active item shows its label; inactive items show icon only.
188
+ // The background color changes per active item using the color prop.
189
+
190
+ export const Shift: Story = {
191
+ render: () => {
192
+ const colors = ["#f97316", "#84cc16", "#0ea5e9", "#a855f7"];
193
+ const [value, setValue] = useState(1);
194
+ return (
195
+ <PageWrapper>
196
+ <BottomNavigation
197
+ value={value}
198
+ onChange={(v) => setValue(Number(v))}
199
+ color="#ffffff"
200
+ shift
201
+ style={{ backgroundColor: colors[value] }}
202
+ >
203
+ <BottomNavigationGroup>
204
+ <BottomNavigationItem value={0}>
205
+ <Tv size={20} />
206
+ <span>Video</span>
207
+ </BottomNavigationItem>
208
+ <BottomNavigationItem value={1}>
209
+ <Music size={20} />
210
+ <span>Music</span>
211
+ </BottomNavigationItem>
212
+ <BottomNavigationItem value={2}>
213
+ <BookOpen size={20} />
214
+ <span>Book</span>
215
+ </BottomNavigationItem>
216
+ <BottomNavigationItem value={3}>
217
+ <Image size={20} />
218
+ <span>Image</span>
219
+ </BottomNavigationItem>
220
+ </BottomNavigationGroup>
221
+ </BottomNavigation>
222
+ </PageWrapper>
223
+ );
224
+ },
225
+ };
226
+
227
+ // ─── Toggle ───────────────────────────────────────────────────────────────────
228
+ // The `active` prop controls whether the nav bar is visible.
229
+ // When false the bar slides off-screen.
230
+
231
+ export const Toggle: Story = {
232
+ render: () => {
233
+ const [value, setValue] = useState(0);
234
+ const [visible, setVisible] = useState(true);
235
+ return (
236
+ <PageWrapper>
237
+ <div
238
+ style={{
239
+ display: "flex",
240
+ justifyContent: "center",
241
+ paddingTop: "2rem",
242
+ }}
243
+ >
244
+ <button
245
+ type="button"
246
+ onClick={() => setVisible((v) => !v)}
247
+ style={{
248
+ padding: "0.5rem 1.25rem",
249
+ border: "1px solid var(--color-blue-600, #2e74ad)",
250
+ borderRadius: 9999,
251
+ color: "var(--color-blue-600, #2e74ad)",
252
+ background: "transparent",
253
+ cursor: "pointer",
254
+ fontWeight: 600,
255
+ fontSize: "0.875rem",
256
+ }}
257
+ >
258
+ Toggle Navigation
259
+ </button>
260
+ </div>
261
+ <BottomNavigation
262
+ value={value}
263
+ onChange={(v) => setValue(Number(v))}
264
+ color="var(--color-blue-600, #2e74ad)"
265
+ active={visible}
266
+ >
267
+ <BottomNavigationGroup>
268
+ <BottomNavigationItem value={0}>
269
+ <History size={20} />
270
+ <span>Recents</span>
271
+ </BottomNavigationItem>
272
+ <BottomNavigationItem value={1}>
273
+ <Heart size={20} />
274
+ <span>Favorites</span>
275
+ </BottomNavigationItem>
276
+ <BottomNavigationItem value={2}>
277
+ <MapPin size={20} />
278
+ <span>Nearby</span>
279
+ </BottomNavigationItem>
280
+ </BottomNavigationGroup>
281
+ </BottomNavigation>
282
+ </PageWrapper>
283
+ );
284
+ },
285
+ };