@syscore/ui-library 1.18.0 → 1.19.1
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 +6 -2
- package/client/global.css +47 -10
- package/client/ui/Dialog.stories.tsx +70 -0
- package/client/ui/MobileNav.stories.tsx +20 -18
- package/client/ui/Navigation.stories.tsx +46 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.es.js +256 -133
- package/package.json +1 -1
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import React from "react";
|
|
2
1
|
import { cn } from "../../lib/utils";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
className?: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export const UtilityCompare: React.FC<UtilityCompareProps> = ({
|
|
9
|
-
className,
|
|
10
|
-
}) => {
|
|
3
|
+
export function UtilityCompare({ className }: { className?: string }) {
|
|
11
4
|
return (
|
|
12
5
|
<div
|
|
13
6
|
className={cn(
|
|
@@ -26,21 +19,21 @@ export const UtilityCompare: React.FC<UtilityCompareProps> = ({
|
|
|
26
19
|
<path
|
|
27
20
|
d="M10.6002 5.79905C10.6002 8.44949 8.45114 10.5981 5.80011 10.5981C3.14908 10.5981 1 8.44949 1 5.79905C1 3.14861 3.14908 1 5.80011 1C8.45114 1 10.6002 3.14861 10.6002 5.79905Z"
|
|
28
21
|
fill="#E0FBF5"
|
|
29
|
-
stroke="
|
|
22
|
+
stroke="currentColor"
|
|
30
23
|
stroke-width="2"
|
|
31
24
|
stroke-linecap="round"
|
|
32
25
|
stroke-linejoin="round"
|
|
33
26
|
/>
|
|
34
27
|
<path
|
|
35
28
|
d="M5.80078 16.998L5.80078 24.9965C5.80078 25.845 6.13793 26.6588 6.73806 27.2587C7.33819 27.8587 8.15214 28.1958 9.00086 28.1958L20.2011 28.1958"
|
|
36
|
-
stroke="
|
|
29
|
+
stroke="currentColor"
|
|
37
30
|
stroke-width="2"
|
|
38
31
|
stroke-linecap="round"
|
|
39
32
|
stroke-linejoin="round"
|
|
40
33
|
/>
|
|
41
34
|
<path
|
|
42
35
|
d="M10.6002 21.7971L5.80011 16.998L1 21.7971"
|
|
43
|
-
stroke="
|
|
36
|
+
stroke="currentColor"
|
|
44
37
|
stroke-width="2"
|
|
45
38
|
stroke-linecap="round"
|
|
46
39
|
stroke-linejoin="round"
|
|
@@ -48,21 +41,21 @@ export const UtilityCompare: React.FC<UtilityCompareProps> = ({
|
|
|
48
41
|
<path
|
|
49
42
|
d="M29.8001 28.2014C29.8001 30.8518 27.651 33.0004 24.9999 33.0004C22.3489 33.0004 20.1998 30.8518 20.1998 28.2014C20.1998 25.551 22.3489 23.4023 24.9999 23.4023C27.651 23.4023 29.8001 25.5509 29.8001 28.2014Z"
|
|
50
43
|
fill="#EFF5FB"
|
|
51
|
-
stroke="
|
|
44
|
+
stroke="currentColor"
|
|
52
45
|
stroke-width="2"
|
|
53
46
|
stroke-linecap="round"
|
|
54
47
|
stroke-linejoin="round"
|
|
55
48
|
/>
|
|
56
49
|
<path
|
|
57
50
|
d="M25.0002 16.9946V8.99624C25.0002 8.14771 24.663 7.33394 24.0629 6.73395C23.4628 6.13395 22.6488 5.79687 21.8001 5.79687L10.5999 5.79688"
|
|
58
|
-
stroke="
|
|
51
|
+
stroke="currentColor"
|
|
59
52
|
stroke-width="2"
|
|
60
53
|
stroke-linecap="round"
|
|
61
54
|
stroke-linejoin="round"
|
|
62
55
|
/>
|
|
63
56
|
<path
|
|
64
57
|
d="M20.1998 12.2012L24.9999 17.0002L29.8001 12.2012"
|
|
65
|
-
stroke="
|
|
58
|
+
stroke="currentColor"
|
|
66
59
|
stroke-width="2"
|
|
67
60
|
stroke-linecap="round"
|
|
68
61
|
stroke-linejoin="round"
|
|
@@ -70,4 +63,4 @@ export const UtilityCompare: React.FC<UtilityCompareProps> = ({
|
|
|
70
63
|
</svg>
|
|
71
64
|
</div>
|
|
72
65
|
);
|
|
73
|
-
}
|
|
66
|
+
}
|
|
@@ -14,7 +14,7 @@ export function UtilityFeedback({ className }: { className?: string }) {
|
|
|
14
14
|
height="28"
|
|
15
15
|
viewBox="0 0 30 28"
|
|
16
16
|
fill="none"
|
|
17
|
-
className={cn("text-inherit")}
|
|
17
|
+
className={cn("text-inherit w-full h-full")}
|
|
18
18
|
>
|
|
19
19
|
<path
|
|
20
20
|
d="M29 20.162C29 20.888 28.705 21.5843 28.1799 22.0977C27.6548 22.611 26.9426 22.8995 26.2 22.8995H7.7592C7.01665 22.8996 6.30458 23.1881 5.7796 23.7015L2.6968 26.7154C2.55779 26.8513 2.38068 26.9438 2.18788 26.9813C1.99508 27.0188 1.79524 26.9996 1.61363 26.926C1.43202 26.8525 1.27678 26.728 1.16756 26.5682C1.05834 26.4084 1.00003 26.2205 1 26.0283V3.73743C1 3.01142 1.295 2.31514 1.8201 1.80178C2.3452 1.28841 3.05739 1 3.8 1H26.2C26.9426 1 27.6548 1.28841 28.1799 1.80178C28.705 2.31514 29 3.01142 29 3.73743V20.162Z"
|
|
@@ -14,7 +14,7 @@ export function UtilityRevisionsHide({ className }: { className?: string }) {
|
|
|
14
14
|
height="15"
|
|
15
15
|
viewBox="0 0 17 15"
|
|
16
16
|
fill="none"
|
|
17
|
-
className={cn("text-inherit")}
|
|
17
|
+
className={cn("text-inherit w-full h-full")}
|
|
18
18
|
>
|
|
19
19
|
<path
|
|
20
20
|
d="M5.48682 6.27734L0.75 11.0142V13.3826H7.85523L10.2236 11.0142"
|
|
@@ -14,7 +14,7 @@ export function UtilityRevisionsShow({ className }: { className?: string }) {
|
|
|
14
14
|
height="26"
|
|
15
15
|
viewBox="0 0 30 26"
|
|
16
16
|
fill="none"
|
|
17
|
-
className={cn("text-inherit")}
|
|
17
|
+
className={cn("text-inherit w-full h-full")}
|
|
18
18
|
>
|
|
19
19
|
<path
|
|
20
20
|
d="M9.84194 11.5L1 20.5006V25.0009H14.2629L18.6839 20.5006"
|
|
@@ -22,17 +22,17 @@ export function UtilityRevisionsShow({ className }: { className?: string }) {
|
|
|
22
22
|
/>
|
|
23
23
|
<path
|
|
24
24
|
d="M9.84194 11.5L1 20.5006V25.0009H14.2629L18.6839 20.5006"
|
|
25
|
-
stroke="
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
stroke="currentColor"
|
|
26
|
+
strokeWidth="2"
|
|
27
|
+
strokeLinecap="round"
|
|
28
|
+
strokeLinejoin="round"
|
|
29
29
|
/>
|
|
30
30
|
<path
|
|
31
31
|
d="M28.9999 13.0008L22.2211 19.9013C21.6702 20.451 20.9295 20.7589 20.158 20.7589C19.3865 20.7589 18.6458 20.451 18.0949 19.9013L10.4319 12.1008C9.89184 11.5399 9.58936 10.7859 9.58936 10.0006C9.58936 9.21531 9.89184 8.4613 10.4319 7.90048L17.2107 1"
|
|
32
|
-
stroke="
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
stroke="currentColor"
|
|
33
|
+
strokeWidth="2"
|
|
34
|
+
strokeLinecap="round"
|
|
35
|
+
strokeLinejoin="round"
|
|
36
36
|
/>
|
|
37
37
|
</svg>
|
|
38
38
|
</div>
|
|
@@ -1,34 +1,43 @@
|
|
|
1
|
+
import { cn } from "@/lib/utils";
|
|
2
|
+
|
|
1
3
|
export function UtilityText({ className }: { className?: string }) {
|
|
2
4
|
return (
|
|
3
|
-
<
|
|
4
|
-
className={
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
viewBox="0 0 16 14"
|
|
9
|
-
fill="none"
|
|
5
|
+
<div
|
|
6
|
+
className={cn(
|
|
7
|
+
"size-4 flex items-center justify-center text-gray-500",
|
|
8
|
+
className,
|
|
9
|
+
)}
|
|
10
10
|
>
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
11
|
+
<svg
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
width="16"
|
|
14
|
+
height="14"
|
|
15
|
+
viewBox="0 0 16 14"
|
|
16
|
+
fill="none"
|
|
17
|
+
className={cn("text-inherit w-full h-full")}
|
|
18
|
+
>
|
|
19
|
+
<path
|
|
20
|
+
d="M8.75 12.75H0.75"
|
|
21
|
+
stroke="currentColor"
|
|
22
|
+
strokeWidth="1.5"
|
|
23
|
+
strokeLinecap="round"
|
|
24
|
+
stroke-linejoin="round"
|
|
25
|
+
/>
|
|
26
|
+
<path
|
|
27
|
+
d="M10.75 0.75H0.75"
|
|
28
|
+
stroke="currentColor"
|
|
29
|
+
strokeWidth="1.5"
|
|
30
|
+
strokeLinecap="round"
|
|
31
|
+
strokeLinejoin="round"
|
|
32
|
+
/>
|
|
33
|
+
<path
|
|
34
|
+
d="M14.75 6.75H0.75"
|
|
35
|
+
stroke="currentColor"
|
|
36
|
+
strokeWidth="1.5"
|
|
37
|
+
strokeLinecap="round"
|
|
38
|
+
strokeLinejoin="round"
|
|
39
|
+
/>
|
|
40
|
+
</svg>
|
|
41
|
+
</div>
|
|
33
42
|
);
|
|
34
43
|
}
|
|
@@ -4,6 +4,7 @@ import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
|
4
4
|
import { cn } from "@/lib/utils";
|
|
5
5
|
import { UtilityClose } from "../icons/UtilityClose";
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
function Dialog({
|
|
8
9
|
...props
|
|
9
10
|
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
|
|
@@ -46,30 +47,39 @@ function DialogOverlay({
|
|
|
46
47
|
|
|
47
48
|
function DialogContent({
|
|
48
49
|
className,
|
|
50
|
+
innerClassName,
|
|
51
|
+
closeClassName,
|
|
49
52
|
children,
|
|
50
53
|
showCloseButton = true,
|
|
51
54
|
...props
|
|
52
55
|
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
|
53
56
|
showCloseButton?: boolean;
|
|
57
|
+
innerClassName?: string;
|
|
58
|
+
closeClassName?: string;
|
|
54
59
|
}) {
|
|
55
60
|
return (
|
|
56
61
|
<DialogPortal data-slot="dialog-portal">
|
|
57
|
-
<DialogOverlay>
|
|
62
|
+
<DialogOverlay className="overflow-y-auto">
|
|
58
63
|
<DialogPrimitive.Content
|
|
59
64
|
data-slot="dialog-content"
|
|
60
65
|
className={cn("dialog-content", className)}
|
|
61
66
|
{...props}
|
|
62
67
|
>
|
|
63
|
-
<div className="dialog-content-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
<div className="dialog-content-wrapper">
|
|
69
|
+
<div className={cn("dialog-content-inner", innerClassName)}>
|
|
70
|
+
{children}
|
|
71
|
+
</div>
|
|
72
|
+
{showCloseButton && (
|
|
73
|
+
<div className="dialog-close">
|
|
74
|
+
<DialogPrimitive.Close data-slot="dialog-close">
|
|
75
|
+
<UtilityClose
|
|
76
|
+
className={cn("dialog-close-icon", closeClassName)}
|
|
77
|
+
/>
|
|
78
|
+
<span className="sr-only">Close</span>
|
|
79
|
+
</DialogPrimitive.Close>
|
|
80
|
+
</div>
|
|
81
|
+
)}
|
|
82
|
+
</div>
|
|
73
83
|
</DialogPrimitive.Content>
|
|
74
84
|
</DialogOverlay>
|
|
75
85
|
</DialogPortal>
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "react";
|
|
12
12
|
import { motion, useMotionValue, animate } from "motion/react";
|
|
13
13
|
import { cn } from "@/lib/utils";
|
|
14
|
+
import { Button } from "./button";
|
|
14
15
|
|
|
15
16
|
interface MobileNavContextValue {
|
|
16
17
|
activeKey: string | null;
|
|
@@ -295,7 +296,10 @@ const MobileNavTrigger = ({
|
|
|
295
296
|
};
|
|
296
297
|
|
|
297
298
|
return (
|
|
298
|
-
<
|
|
299
|
+
<Button
|
|
300
|
+
variant="clear"
|
|
301
|
+
size="icon"
|
|
302
|
+
type="button"
|
|
299
303
|
onClick={handleClick}
|
|
300
304
|
disabled={disabled}
|
|
301
305
|
data-active={activeKey === value || undefined}
|
|
@@ -304,7 +308,7 @@ const MobileNavTrigger = ({
|
|
|
304
308
|
aria-label={label}
|
|
305
309
|
>
|
|
306
310
|
{children}
|
|
307
|
-
</
|
|
311
|
+
</Button>
|
|
308
312
|
);
|
|
309
313
|
};
|
|
310
314
|
|
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) {
|
|
@@ -3940,6 +3968,10 @@ body {
|
|
|
3940
3968
|
color: var(--color-gray-400);
|
|
3941
3969
|
}
|
|
3942
3970
|
|
|
3971
|
+
.mobile-nav-trigger svg [stroke]:not([stroke="none"]) {
|
|
3972
|
+
stroke: currentColor;
|
|
3973
|
+
}
|
|
3974
|
+
|
|
3943
3975
|
.mobile-nav-trigger:hover {
|
|
3944
3976
|
color: var(--color-gray-600);
|
|
3945
3977
|
}
|
|
@@ -3950,7 +3982,12 @@ body {
|
|
|
3950
3982
|
|
|
3951
3983
|
.mobile-nav-trigger:disabled {
|
|
3952
3984
|
pointer-events: none;
|
|
3953
|
-
|
|
3985
|
+
cursor: default;
|
|
3986
|
+
color: var(--color-gray-200);
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3989
|
+
.mobile-nav-trigger:disabled svg [fill]:not([fill="none"]) {
|
|
3990
|
+
fill: transparent;
|
|
3954
3991
|
}
|
|
3955
3992
|
|
|
3956
3993
|
/* Pagination Styles */
|
|
@@ -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);
|
|
@@ -67,17 +67,19 @@ Mobile navigation with a spring-animated slide-up panel. Built as a **compound c
|
|
|
67
67
|
</section>
|
|
68
68
|
\`\`\`
|
|
69
69
|
|
|
70
|
-
##
|
|
70
|
+
## Icon Color Handling
|
|
71
71
|
|
|
72
|
-
|
|
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.
|
|
73
73
|
|
|
74
74
|
\`\`\`tsx
|
|
75
|
+
{/* Icons only need sizing — color is inherited from the trigger */}
|
|
75
76
|
<MobileNavTrigger value="home" label="Home">
|
|
76
|
-
<HomeIcon className="size-6
|
|
77
|
-
<span className="text-xs hidden group-data-active:block">Home</span>
|
|
77
|
+
<HomeIcon className="size-6" />
|
|
78
78
|
</MobileNavTrigger>
|
|
79
79
|
\`\`\`
|
|
80
80
|
|
|
81
|
+
States: default (gray-400), hover (gray-600), active (gray-900), disabled (gray-200 + fills transparent).
|
|
82
|
+
|
|
81
83
|
## Custom Actions (onAction)
|
|
82
84
|
|
|
83
85
|
Use \`onAction\` on a trigger to fire a custom callback instead of opening the panel:
|
|
@@ -257,16 +259,16 @@ export const Default: Story = {
|
|
|
257
259
|
|
|
258
260
|
<MobileNavBar>
|
|
259
261
|
<MobileNavTrigger value="list" label="Changes">
|
|
260
|
-
<UtilityText className="size-6
|
|
262
|
+
<UtilityText className="size-6" />
|
|
261
263
|
</MobileNavTrigger>
|
|
262
264
|
<MobileNavTrigger value="workflow" label="Workflow">
|
|
263
|
-
<UtilityCompare className="size-6
|
|
265
|
+
<UtilityCompare className="size-6" />
|
|
264
266
|
</MobileNavTrigger>
|
|
265
267
|
<MobileNavTrigger value="edit" label="Edits">
|
|
266
|
-
<UtilityRevisionsShow className="size-6
|
|
268
|
+
<UtilityRevisionsShow className="size-6" />
|
|
267
269
|
</MobileNavTrigger>
|
|
268
270
|
<MobileNavTrigger value="comments" label="Comments">
|
|
269
|
-
<UtilityFeedback className="size-6
|
|
271
|
+
<UtilityFeedback className="size-6" />
|
|
270
272
|
</MobileNavTrigger>
|
|
271
273
|
</MobileNavBar>
|
|
272
274
|
</MobileNav>
|
|
@@ -292,20 +294,20 @@ const WithCustomActionRender = () => {
|
|
|
292
294
|
|
|
293
295
|
<MobileNavBar>
|
|
294
296
|
<MobileNavTrigger value="list" label="Changes">
|
|
295
|
-
<UtilityText className="size-6
|
|
297
|
+
<UtilityText className="size-6" />
|
|
296
298
|
</MobileNavTrigger>
|
|
297
299
|
<MobileNavTrigger value="workflow" label="Workflow">
|
|
298
|
-
<UtilityCompare className="size-8
|
|
300
|
+
<UtilityCompare className="size-8" />
|
|
299
301
|
</MobileNavTrigger>
|
|
300
302
|
<MobileNavTrigger
|
|
301
303
|
value="edit"
|
|
302
304
|
label="Edits"
|
|
303
305
|
onAction={() => setModalOpen(true)}
|
|
304
306
|
>
|
|
305
|
-
<UtilityRevisionsShow className="size-6
|
|
307
|
+
<UtilityRevisionsShow className="size-6" />
|
|
306
308
|
</MobileNavTrigger>
|
|
307
309
|
<MobileNavTrigger value="comments" label="Comments">
|
|
308
|
-
<UtilityFeedback className="size-6
|
|
310
|
+
<UtilityFeedback className="size-6" />
|
|
309
311
|
</MobileNavTrigger>
|
|
310
312
|
</MobileNavBar>
|
|
311
313
|
</MobileNav>
|
|
@@ -355,16 +357,16 @@ export const WithDisabledTrigger: Story = {
|
|
|
355
357
|
|
|
356
358
|
<MobileNavBar>
|
|
357
359
|
<MobileNavTrigger value="list" label="Changes">
|
|
358
|
-
<UtilityText className="size-
|
|
360
|
+
<UtilityText className="size-7" />
|
|
359
361
|
</MobileNavTrigger>
|
|
360
|
-
<MobileNavTrigger value="workflow" label="Workflow">
|
|
361
|
-
<UtilityCompare className="size-
|
|
362
|
+
<MobileNavTrigger value="workflow" label="Workflow" disabled>
|
|
363
|
+
<UtilityCompare className="size-8" />
|
|
362
364
|
</MobileNavTrigger>
|
|
363
|
-
<MobileNavTrigger value="edit" label="Edits">
|
|
364
|
-
<UtilityRevisionsShow className="size-
|
|
365
|
+
<MobileNavTrigger value="edit" label="Edits" disabled>
|
|
366
|
+
<UtilityRevisionsShow className="size-7" />
|
|
365
367
|
</MobileNavTrigger>
|
|
366
368
|
<MobileNavTrigger value="comments" label="Comments" disabled>
|
|
367
|
-
<UtilityFeedback className="size-
|
|
369
|
+
<UtilityFeedback className="size-7" />
|
|
368
370
|
</MobileNavTrigger>
|
|
369
371
|
</MobileNavBar>
|
|
370
372
|
</MobileNav>
|
|
@@ -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
|
},
|