@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/components/icons/UtilityCompare.tsx +8 -15
- package/client/components/icons/UtilityFeedback.tsx +1 -1
- package/client/components/icons/UtilityRevisionsHide.tsx +1 -1
- package/client/components/icons/UtilityRevisionsShow.tsx +9 -9
- package/client/components/icons/UtilityText.tsx +38 -29
- package/client/components/ui/dialog.tsx +21 -11
- package/client/components/ui/mobile-nav.tsx +99 -64
- package/client/global.css +103 -16
- package/client/ui/Dialog.stories.tsx +70 -0
- package/client/ui/MobileNav.stories.tsx +112 -88
- package/client/ui/Navigation.stories.tsx +46 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +164 -128
- package/package.json +1 -1
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:
|
|
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:
|
|
2483
|
+
align-items: flex-start;
|
|
2484
2484
|
justify-content: center;
|
|
2485
2485
|
overflow-y: auto;
|
|
2486
|
-
padding-
|
|
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:
|
|
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
|
-
|
|
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:
|
|
3893
|
+
position: fixed;
|
|
3862
3894
|
inset: 0;
|
|
3863
3895
|
background-color: rgba(0, 0, 0, 0.08);
|
|
3864
|
-
z-index:
|
|
3896
|
+
z-index: 40;
|
|
3865
3897
|
}
|
|
3866
3898
|
|
|
3867
3899
|
.mobile-nav-panel {
|
|
3868
3900
|
position: relative;
|
|
3869
|
-
z-index:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<
|
|
50
|
-
<
|
|
51
|
-
<
|
|
52
|
-
</
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
</
|
|
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
|
-
##
|
|
70
|
+
## Icon Color Handling
|
|
61
71
|
|
|
62
|
-
|
|
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
|
|
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
|
-
<
|
|
239
|
+
<div className="h-screen w-full bg-white">
|
|
228
240
|
{/* Main content area */}
|
|
229
|
-
<div className="
|
|
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
|
-
{/*
|
|
236
|
-
<
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
-
<
|
|
264
|
-
<div className="
|
|
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 “Edits” trigger opens a modal instead of the panel.
|
|
267
287
|
</p>
|
|
268
288
|
</div>
|
|
269
289
|
|
|
270
|
-
<
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
<
|
|
276
|
-
<
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
<
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
<
|
|
290
|
-
|
|
291
|
-
|
|
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="
|
|
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
|
-
</
|
|
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
|
-
<
|
|
324
|
-
<div className="
|
|
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 “Comments” trigger is disabled because there are no
|
|
327
349
|
comments.
|
|
328
350
|
</p>
|
|
329
351
|
</div>
|
|
330
352
|
|
|
331
|
-
<
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
<
|
|
337
|
-
<
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
<
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
<
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
<
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
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
|
},
|