@syscore/ui-library 1.17.0 → 1.19.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.
package/client/global.css CHANGED
@@ -701,7 +701,7 @@ layer(base);
701
701
  --blur-lg: 12px;
702
702
  --blur-xl: 20px;
703
703
 
704
- --radius-modal: 40px;
704
+ --radius-modal: 24px;
705
705
  --modal-color: rgba(0, 0, 0, 0.08);
706
706
 
707
707
  --shadow-xs: 0 1px 2px 0 rgba(16, 24, 40, 0.05);
@@ -2480,11 +2480,13 @@ body {
2480
2480
  inset: 0;
2481
2481
  z-index: 50;
2482
2482
  display: flex;
2483
- align-items: center;
2483
+ align-items: flex-start;
2484
2484
  justify-content: center;
2485
2485
  overflow-y: auto;
2486
- padding-block: 1.5rem;
2486
+ padding-top: 4rem;
2487
+ padding-bottom: 4rem;
2487
2488
  background-color: rgba(0, 0, 0, 0.5);
2489
+ cursor: zoom-out;
2488
2490
  }
2489
2491
 
2490
2492
  .dialog-overlay[data-state="open"] {
@@ -2496,16 +2498,17 @@ body {
2496
2498
  }
2497
2499
 
2498
2500
  .dialog-content {
2499
- position: relative;
2500
2501
  z-index: 50;
2501
2502
  display: grid;
2502
2503
  gap: 1rem;
2503
- margin: auto;
2504
- border-radius: 40px;
2505
- border: 12px solid rgba(255, 255, 255, 0.2);
2504
+ margin-inline: auto;
2506
2505
  transition: all 0.2s ease-in-out;
2507
2506
  }
2508
2507
 
2508
+ .dialog-content:focus-visible {
2509
+ outline: none;
2510
+ }
2511
+
2509
2512
  .dialog-content[data-state="open"] {
2510
2513
  animation:
2511
2514
  fade-in 0.15s ease-in-out,
@@ -2518,10 +2521,25 @@ body {
2518
2521
  zoom-out 0.15s ease-in-out;
2519
2522
  }
2520
2523
 
2524
+ .dialog-content-wrapper {
2525
+ position: relative;
2526
+ border: 12px solid rgba(255, 255, 255, 0.2);
2527
+ /* outer radius = inner radius + border width to keep curves concentric */
2528
+ border-radius: calc(var(--radius-modal) + 12px);
2529
+ }
2530
+
2521
2531
  .dialog-content-inner {
2532
+ display: flex;
2533
+ flex-direction: column;
2534
+ gap: 1.5rem;
2522
2535
  padding: 1.5rem;
2523
- border-radius: 24px;
2536
+ border-radius: var(--radius-modal);
2524
2537
  background-color: var(--color-gray-50, #f9f9fa);
2538
+ cursor: default;
2539
+ overflow: clip;
2540
+ transition-property:
2541
+ color, background-color, border-color, text-decoration-color, fill, stroke;
2542
+ transition-duration: 300ms;
2525
2543
  }
2526
2544
 
2527
2545
  .dialog-close {
@@ -2544,7 +2562,7 @@ body {
2544
2562
  }
2545
2563
 
2546
2564
  .dialog-close svg {
2547
- pointer-events: none;
2565
+ cursor: pointer;
2548
2566
  flex-shrink: 0;
2549
2567
  color: var(--color-gray-400);
2550
2568
  transition: color 0.2s ease-in-out;
@@ -2554,12 +2572,22 @@ body {
2554
2572
  color: var(--color-gray-500);
2555
2573
  }
2556
2574
 
2575
+ .dialog-close-icon {
2576
+ color: var(--color-gray-400);
2577
+ transition: color 0.2s ease-in-out;
2578
+ }
2579
+
2580
+ .dialog-close:hover .dialog-close-icon {
2581
+ color: var(--color-gray-500);
2582
+ }
2583
+
2557
2584
  .dialog-header {
2558
2585
  display: flex;
2559
2586
  flex-direction: column;
2560
2587
  gap: 0.5rem;
2561
2588
  text-align: center;
2562
2589
  align-items: center;
2590
+ justify-content: center;
2563
2591
  }
2564
2592
 
2565
2593
  @media (min-width: 640px) {
@@ -3852,21 +3880,25 @@ body {
3852
3880
 
3853
3881
  /* MobileNav Styles */
3854
3882
  .mobile-nav {
3883
+ position: fixed;
3884
+ bottom: 0;
3885
+ left: 0;
3886
+ right: 0;
3887
+ z-index: 50;
3855
3888
  display: flex;
3856
3889
  flex-direction: column;
3857
- position: relative;
3858
3890
  }
3859
3891
 
3860
3892
  .mobile-nav-overlay {
3861
- position: absolute;
3893
+ position: fixed;
3862
3894
  inset: 0;
3863
3895
  background-color: rgba(0, 0, 0, 0.08);
3864
- z-index: 10;
3896
+ z-index: 40;
3865
3897
  }
3866
3898
 
3867
3899
  .mobile-nav-panel {
3868
3900
  position: relative;
3869
- z-index: 20;
3901
+ z-index: 50;
3870
3902
  background-color: white;
3871
3903
  border-radius: 32px 32px 0 0;
3872
3904
  box-shadow:
@@ -3906,7 +3938,7 @@ body {
3906
3938
 
3907
3939
  .mobile-nav-bar {
3908
3940
  position: relative;
3909
- z-index: 20;
3941
+ z-index: 50;
3910
3942
  border-top: 1px solid var(--color-gray-100);
3911
3943
  background-color: var(--color-gray-50);
3912
3944
  flex-shrink: 0;
@@ -3920,7 +3952,7 @@ body {
3920
3952
  align-items: center;
3921
3953
  justify-content: space-around;
3922
3954
  padding-top: 0.5rem;
3923
- padding-bottom: 2rem;
3955
+ padding-bottom: 0.5rem;
3924
3956
  padding-left: 1.5rem;
3925
3957
  padding-right: 1.5rem;
3926
3958
  }
@@ -3936,6 +3968,10 @@ body {
3936
3968
  color: var(--color-gray-400);
3937
3969
  }
3938
3970
 
3971
+ .mobile-nav-trigger svg [stroke]:not([stroke="none"]) {
3972
+ stroke: currentColor;
3973
+ }
3974
+
3939
3975
  .mobile-nav-trigger:hover {
3940
3976
  color: var(--color-gray-600);
3941
3977
  }
@@ -3946,7 +3982,12 @@ body {
3946
3982
 
3947
3983
  .mobile-nav-trigger:disabled {
3948
3984
  pointer-events: none;
3949
- opacity: 0.4;
3985
+ cursor: default;
3986
+ color: var(--color-gray-200);
3987
+ }
3988
+
3989
+ .mobile-nav-trigger:disabled svg [fill]:not([fill="none"]) {
3990
+ fill: transparent;
3950
3991
  }
3951
3992
 
3952
3993
  /* Pagination Styles */
@@ -6992,6 +7033,38 @@ body {
6992
7033
  text-underline-offset: 2px;
6993
7034
  }
6994
7035
 
7036
+ /* Responsive Typography - Mobile */
7037
+ @media (max-width: 640px) {
7038
+ .heading-xlarge {
7039
+ font-size: 36px;
7040
+ line-height: 40px;
7041
+ }
7042
+ .heading-large {
7043
+ font-size: 28px;
7044
+ line-height: 32px;
7045
+ }
7046
+ .heading-medium {
7047
+ font-size: 26px;
7048
+ line-height: 30px;
7049
+ }
7050
+ .heading-small {
7051
+ font-size: 24px;
7052
+ line-height: 28px;
7053
+ }
7054
+ .heading-xsmall {
7055
+ font-size: 20px;
7056
+ line-height: 24px;
7057
+ }
7058
+ .heading-xxsmall {
7059
+ font-size: 18px;
7060
+ line-height: 22px;
7061
+ }
7062
+ .body-large {
7063
+ font-size: 16px;
7064
+ line-height: 22.4px;
7065
+ }
7066
+ }
7067
+
6995
7068
  /* Standard Table Styles */
6996
7069
  .standard-table {
6997
7070
  border: 1px solid var(--color-blue-200, #cbe0f1);
@@ -7105,6 +7178,14 @@ body {
7105
7178
  gap: 1rem;
7106
7179
  }
7107
7180
 
7181
+ @media (max-width: 640px) {
7182
+ .standard-table-row-header,
7183
+ .standard-table-list-row {
7184
+ height: auto;
7185
+ min-height: 5rem;
7186
+ }
7187
+ }
7188
+
7108
7189
  /* PageHeader Styles */
7109
7190
  .page-header {
7110
7191
  margin-bottom: 1.5rem;
@@ -7142,6 +7223,12 @@ body {
7142
7223
  padding-right: 10rem;
7143
7224
  }
7144
7225
 
7226
+ @media (max-width: 640px) {
7227
+ .page-header-description {
7228
+ padding-right: 0;
7229
+ }
7230
+ }
7231
+
7145
7232
  /* Navigation Styles */
7146
7233
  .navigation {
7147
7234
  position: absolute;
@@ -3,6 +3,7 @@ import { Button } from "../components/ui/button";
3
3
  import { Input } from "../components/ui/input";
4
4
  import { Label } from "../components/ui/label";
5
5
  import { useState } from "react";
6
+ import { AnimatePresence, motion } from "motion/react";
6
7
  import {
7
8
  Dialog,
8
9
  DialogContent,
@@ -115,6 +116,75 @@ export const WithForm: Story = {
115
116
  },
116
117
  };
117
118
 
119
+ export const ExpandableContent: Story = {
120
+ render: () => {
121
+ const [open, setOpen] = useState(false);
122
+ const [expanded, setExpanded] = useState(false);
123
+ return (
124
+ <Dialog open={open} onOpenChange={setOpen}>
125
+ <DialogTrigger asChild>
126
+ <Button variant="general-secondary" onClick={() => setOpen(true)}>
127
+ Expandable Dialog
128
+ </Button>
129
+ </DialogTrigger>
130
+ <DialogContent className="sm:min-w-[360px]" showCloseButton={false}>
131
+ <DialogHeader>
132
+ <DialogTitle className="text-gray-800">
133
+ Notification Preferences
134
+ </DialogTitle>
135
+ <DialogDescription>
136
+ Choose which notifications you'd like to receive.
137
+ </DialogDescription>
138
+ </DialogHeader>
139
+ <AnimatePresence>
140
+ {expanded && (
141
+ <motion.div
142
+ key="expanded-content"
143
+ initial={{ height: 0, opacity: 0 }}
144
+ animate={{ height: "auto", opacity: 1 }}
145
+ exit={{ height: 0, opacity: 0 }}
146
+ transition={{ duration: 0.2, ease: "easeInOut" }}
147
+ style={{ overflow: "hidden" }}
148
+ >
149
+ <div className="flex flex-col gap-3 body-base text-gray-700">
150
+ <label className="flex items-center gap-2">
151
+ <input type="checkbox" defaultChecked /> Email notifications
152
+ </label>
153
+ <label className="flex items-center gap-2">
154
+ <input type="checkbox" /> SMS notifications
155
+ </label>
156
+ <label className="flex items-center gap-2">
157
+ <input type="checkbox" defaultChecked /> Push notifications
158
+ </label>
159
+ <label className="flex items-center gap-2">
160
+ <input type="checkbox" /> Weekly digest
161
+ </label>
162
+ </div>
163
+ </motion.div>
164
+ )}
165
+ </AnimatePresence>
166
+ <div className="flex gap-4 justify-center items-center">
167
+ <Button
168
+ size="utility"
169
+ variant="general-secondary"
170
+ onClick={() => setExpanded(!expanded)}
171
+ >
172
+ {expanded ? "Show less" : "Show more"}
173
+ </Button>
174
+ <Button
175
+ size="utility"
176
+ variant="general-primary"
177
+ onClick={() => setOpen(false)}
178
+ >
179
+ Save
180
+ </Button>
181
+ </div>
182
+ </DialogContent>
183
+ </Dialog>
184
+ );
185
+ },
186
+ };
187
+
118
188
  export const LongContentScroll: Story = {
119
189
  render: () => {
120
190
  const [open, setOpen] = useState(false);
@@ -17,6 +17,7 @@ import { UtilityText } from "../components/icons/UtilityText";
17
17
  import { UtilityCompare } from "../components/icons/UtilityCompare";
18
18
  import { UtilityRevisionsShow } from "../components/icons/UtilityRevisionsShow";
19
19
  import { UtilityFeedback } from "../components/icons/UtilityFeedback";
20
+ import { Button } from "@/components/ui/button";
20
21
 
21
22
  const meta = {
22
23
  title: "Review/MobileNav",
@@ -24,6 +25,9 @@ const meta = {
24
25
  tags: ["autodocs"],
25
26
  parameters: {
26
27
  layout: "fullscreen",
28
+ viewport: {
29
+ defaultViewport: "mobile1",
30
+ },
27
31
  docs: {
28
32
  description: {
29
33
  component: `
@@ -41,33 +45,41 @@ Mobile navigation with a spring-animated slide-up panel. Built as a **compound c
41
45
  ## Basic Usage
42
46
 
43
47
  \`\`\`tsx
44
- <MobileNav className="h-screen">
45
- <MobileNavPanel>
46
- {(activeKey) => <MyContent tab={activeKey} />}
47
- </MobileNavPanel>
48
-
49
- <MobileNavBar>
50
- <MobileNavTrigger value="home" label="Home">
51
- <HomeIcon className="size-6" />
52
- </MobileNavTrigger>
53
- <MobileNavTrigger value="search" label="Search">
54
- <SearchIcon className="size-6" />
55
- </MobileNavTrigger>
56
- </MobileNavBar>
57
- </MobileNav>
48
+ <section>
49
+ {/* Your page content */}
50
+ <MyPageContent />
51
+
52
+ {/* Fixed bottom nav */}
53
+ <MobileNav>
54
+ <MobileNavPanel>
55
+ {(activeKey) => <MyContent tab={activeKey} />}
56
+ </MobileNavPanel>
57
+
58
+ <MobileNavBar>
59
+ <MobileNavTrigger value="home" label="Home">
60
+ <HomeIcon className="size-6" />
61
+ </MobileNavTrigger>
62
+ <MobileNavTrigger value="search" label="Search">
63
+ <SearchIcon className="size-6" />
64
+ </MobileNavTrigger>
65
+ </MobileNavBar>
66
+ </MobileNav>
67
+ </section>
58
68
  \`\`\`
59
69
 
60
- ## Styling Active State
70
+ ## Icon Color Handling
61
71
 
62
- \`MobileNavTrigger\` renders a \`<button>\` with the \`group\` class and a \`data-active\` attribute when selected. Use Tailwind's \`group-data-active:\` modifier on children to style based on active state:
72
+ Icon colors are controlled entirely by the trigger CSS no per-icon color classes needed. The trigger sets \`color\` for each state, and SVG strokes inherit via \`currentColor\`. Decorative fills are cleared on disabled.
63
73
 
64
74
  \`\`\`tsx
75
+ {/* Icons only need sizing — color is inherited from the trigger */}
65
76
  <MobileNavTrigger value="home" label="Home">
66
- <HomeIcon className="size-6 text-gray-400 group-data-active:text-gray-900" />
67
- <span className="text-xs hidden group-data-active:block">Home</span>
77
+ <HomeIcon className="size-6" />
68
78
  </MobileNavTrigger>
69
79
  \`\`\`
70
80
 
81
+ States: default (gray-400), hover (gray-600), active (gray-900), disabled (gray-200 + fills transparent).
82
+
71
83
  ## Custom Actions (onAction)
72
84
 
73
85
  Use \`onAction\` on a trigger to fire a custom callback instead of opening the panel:
@@ -224,35 +236,43 @@ export const Default: Story = {
224
236
  args: { children: null },
225
237
 
226
238
  render: () => (
227
- <MobileNav className="h-screen w-full bg-gray-50">
239
+ <div className="h-screen w-full bg-white">
228
240
  {/* Main content area */}
229
- <div className="flex-1 p-6 overflow-y-auto">
241
+ <div className="p-6">
230
242
  <p className="text-sm text-gray-400">
231
243
  Tap an icon below to open the panel.
232
244
  </p>
245
+ <Button
246
+ size="large"
247
+ variant="general-primary"
248
+ onClick={() => alert("Hello")}
249
+ >
250
+ Open panel
251
+ </Button>
233
252
  </div>
234
253
 
235
- {/* Panel slides up above the nav */}
236
- <MobileNavPanel>
237
- {(activeKey) => <PanelContent activeKey={activeKey} />}
238
- </MobileNavPanel>
239
-
240
- {/* Nav — always visible */}
241
- <MobileNavBar>
242
- <MobileNavTrigger value="list" label="Changes">
243
- <UtilityText className="size-6 text-gray-500 group-data-active:text-gray-900" />
244
- </MobileNavTrigger>
245
- <MobileNavTrigger value="workflow" label="Workflow">
246
- <UtilityCompare className="size-6 text-gray-500 group-data-active:text-gray-900" />
247
- </MobileNavTrigger>
248
- <MobileNavTrigger value="edit" label="Edits">
249
- <UtilityRevisionsShow className="size-6 text-gray-500 group-data-active:text-gray-900" />
250
- </MobileNavTrigger>
251
- <MobileNavTrigger value="comments" label="Comments">
252
- <UtilityFeedback className="size-6 text-gray-500 group-data-active:text-gray-900" />
253
- </MobileNavTrigger>
254
- </MobileNavBar>
255
- </MobileNav>
254
+ {/* Fixed bottom nav */}
255
+ <MobileNav>
256
+ <MobileNavPanel>
257
+ {(activeKey) => <PanelContent activeKey={activeKey} />}
258
+ </MobileNavPanel>
259
+
260
+ <MobileNavBar>
261
+ <MobileNavTrigger value="list" label="Changes">
262
+ <UtilityText className="size-6" />
263
+ </MobileNavTrigger>
264
+ <MobileNavTrigger value="workflow" label="Workflow">
265
+ <UtilityCompare className="size-6" />
266
+ </MobileNavTrigger>
267
+ <MobileNavTrigger value="edit" label="Edits">
268
+ <UtilityRevisionsShow className="size-6" />
269
+ </MobileNavTrigger>
270
+ <MobileNavTrigger value="comments" label="Comments">
271
+ <UtilityFeedback className="size-6" />
272
+ </MobileNavTrigger>
273
+ </MobileNavBar>
274
+ </MobileNav>
275
+ </div>
256
276
  ),
257
277
  };
258
278
 
@@ -260,38 +280,40 @@ const WithCustomActionRender = () => {
260
280
  const [modalOpen, setModalOpen] = useState(false);
261
281
 
262
282
  return (
263
- <MobileNav className="relative h-screen w-full bg-gray-50">
264
- <div className="flex-1 p-6 overflow-y-auto">
283
+ <div className="relative h-screen w-full bg-white">
284
+ <div className="p-6">
265
285
  <p className="text-sm text-gray-400">
266
286
  The &ldquo;Edits&rdquo; trigger opens a modal instead of the panel.
267
287
  </p>
268
288
  </div>
269
289
 
270
- <MobileNavPanel>
271
- {(activeKey) => <PanelContent activeKey={activeKey} />}
272
- </MobileNavPanel>
273
-
274
- <MobileNavBar>
275
- <MobileNavTrigger value="list" label="Changes">
276
- <UtilityText className="size-6 text-gray-500 group-data-active:text-gray-900" />
277
- </MobileNavTrigger>
278
- <MobileNavTrigger value="workflow" label="Workflow">
279
- <UtilityCompare className="size-8 text-gray-500 group-data-active:text-gray-900" />
280
- </MobileNavTrigger>
281
- <MobileNavTrigger
282
- value="edit"
283
- label="Edits"
284
- onAction={() => setModalOpen(true)}
285
- >
286
- <UtilityRevisionsShow className="size-6 text-gray-500" />
287
- </MobileNavTrigger>
288
- <MobileNavTrigger value="comments" label="Comments">
289
- <UtilityFeedback className="size-6 text-gray-500 group-data-active:text-gray-900" />
290
- </MobileNavTrigger>
291
- </MobileNavBar>
290
+ <MobileNav>
291
+ <MobileNavPanel>
292
+ {(activeKey) => <PanelContent activeKey={activeKey} />}
293
+ </MobileNavPanel>
294
+
295
+ <MobileNavBar>
296
+ <MobileNavTrigger value="list" label="Changes">
297
+ <UtilityText className="size-6" />
298
+ </MobileNavTrigger>
299
+ <MobileNavTrigger value="workflow" label="Workflow">
300
+ <UtilityCompare className="size-8" />
301
+ </MobileNavTrigger>
302
+ <MobileNavTrigger
303
+ value="edit"
304
+ label="Edits"
305
+ onAction={() => setModalOpen(true)}
306
+ >
307
+ <UtilityRevisionsShow className="size-6" />
308
+ </MobileNavTrigger>
309
+ <MobileNavTrigger value="comments" label="Comments">
310
+ <UtilityFeedback className="size-6" />
311
+ </MobileNavTrigger>
312
+ </MobileNavBar>
313
+ </MobileNav>
292
314
 
293
315
  {modalOpen && (
294
- <div className="absolute inset-0 z-50 flex items-center justify-center bg-black/20">
316
+ <div className="fixed inset-0 z-60 flex items-center justify-center bg-black/20">
295
317
  <div className="relative rounded-xl bg-white p-6 shadow-lg w-72">
296
318
  <button
297
319
  onClick={() => setModalOpen(false)}
@@ -307,7 +329,7 @@ const WithCustomActionRender = () => {
307
329
  </div>
308
330
  </div>
309
331
  )}
310
- </MobileNav>
332
+ </div>
311
333
  );
312
334
  };
313
335
 
@@ -320,32 +342,34 @@ export const WithDisabledTrigger: Story = {
320
342
  args: { children: null },
321
343
 
322
344
  render: () => (
323
- <MobileNav className="h-screen w-full bg-gray-50">
324
- <div className="flex-1 p-6 overflow-y-auto">
345
+ <div className="h-screen w-full bg-white">
346
+ <div className="p-6">
325
347
  <p className="text-sm text-gray-400">
326
348
  The &ldquo;Comments&rdquo; trigger is disabled because there are no
327
349
  comments.
328
350
  </p>
329
351
  </div>
330
352
 
331
- <MobileNavPanel>
332
- {(activeKey) => <PanelContent activeKey={activeKey} />}
333
- </MobileNavPanel>
334
-
335
- <MobileNavBar>
336
- <MobileNavTrigger value="list" label="Changes">
337
- <UtilityText className="size-6 text-gray-500 group-data-active:text-gray-900" />
338
- </MobileNavTrigger>
339
- <MobileNavTrigger value="workflow" label="Workflow">
340
- <UtilityCompare className="size-6 text-gray-500 group-data-active:text-gray-900" />
341
- </MobileNavTrigger>
342
- <MobileNavTrigger value="edit" label="Edits">
343
- <UtilityRevisionsShow className="size-6 text-gray-500 group-data-active:text-gray-900" />
344
- </MobileNavTrigger>
345
- <MobileNavTrigger value="comments" label="Comments" disabled>
346
- <UtilityFeedback className="size-6 text-gray-500 group-data-active:text-gray-900" />
347
- </MobileNavTrigger>
348
- </MobileNavBar>
349
- </MobileNav>
353
+ <MobileNav>
354
+ <MobileNavPanel>
355
+ {(activeKey) => <PanelContent activeKey={activeKey} />}
356
+ </MobileNavPanel>
357
+
358
+ <MobileNavBar>
359
+ <MobileNavTrigger value="list" label="Changes">
360
+ <UtilityText className="size-7" />
361
+ </MobileNavTrigger>
362
+ <MobileNavTrigger value="workflow" label="Workflow" disabled>
363
+ <UtilityCompare className="size-8" />
364
+ </MobileNavTrigger>
365
+ <MobileNavTrigger value="edit" label="Edits" disabled>
366
+ <UtilityRevisionsShow className="size-7" />
367
+ </MobileNavTrigger>
368
+ <MobileNavTrigger value="comments" label="Comments" disabled>
369
+ <UtilityFeedback className="size-7" />
370
+ </MobileNavTrigger>
371
+ </MobileNavBar>
372
+ </MobileNav>
373
+ </div>
350
374
  ),
351
375
  };
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
+ import { useState } from "react";
2
3
  ("use client");
3
4
 
4
5
  import {
@@ -18,6 +19,13 @@ import { AlphaIcon } from "@/components/icons/AlphaIcon";
18
19
  import * as React from "react";
19
20
  import { Globe } from "lucide-react";
20
21
  import { Button } from "@/components/ui/button";
22
+ import {
23
+ Dialog,
24
+ DialogHeader,
25
+ DialogContent,
26
+ DialogTrigger,
27
+ DialogTitle,
28
+ } from "@/components/ui/dialog";
21
29
 
22
30
  // Mock Link component for Storybook (simulates Next.js Link)
23
31
  const Link = React.forwardRef<
@@ -211,6 +219,7 @@ export const Default: Story = {
211
219
 
212
220
  export const StandardNavigation: Story = {
213
221
  render: () => {
222
+ const [open, setOpen] = useState(false);
214
223
  return (
215
224
  <div className="h-screen bg-cyan-900">
216
225
  <Navigation>
@@ -224,6 +233,43 @@ export const StandardNavigation: Story = {
224
233
  <NavigationAccount />
225
234
  </NavigationActions>
226
235
  </Navigation>
236
+
237
+ <div className="h-full w-full flex items-center justify-center">
238
+ <Dialog open={open} onOpenChange={setOpen}>
239
+ <DialogTrigger asChild>
240
+ <Button
241
+ size="large"
242
+ variant="general-primary"
243
+ onClick={() => setOpen(true)}
244
+ >
245
+ Open Dialog
246
+ </Button>
247
+ </DialogTrigger>
248
+ <DialogContent className="sm:min-w-[297px]" showCloseButton={false}>
249
+ <DialogHeader>
250
+ <DialogTitle className="text-gray-800 text-center mb-8 h-8 justify-center items-center flex">
251
+ Are you sure?
252
+ </DialogTitle>
253
+ </DialogHeader>
254
+ <div className="flex gap-4 justify-center items-center">
255
+ <Button
256
+ size="utility"
257
+ variant="general-secondary"
258
+ onClick={() => setOpen(false)}
259
+ >
260
+ Nevermind
261
+ </Button>
262
+ <Button
263
+ size="utility"
264
+ variant="general-primary"
265
+ onClick={() => setOpen(false)}
266
+ >
267
+ Yes, delete user
268
+ </Button>
269
+ </div>
270
+ </DialogContent>
271
+ </Dialog>
272
+ </div>
227
273
  </div>
228
274
  );
229
275
  },