@syscore/ui-library 1.1.10 → 1.1.12
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/App.tsx +47 -0
- package/client/components/icons/ConceptIcons.tsx +667 -0
- package/client/components/icons/NavAccount.tsx +31 -0
- package/client/components/icons/NavBullet.tsx +19 -0
- package/client/components/icons/NavLogo.tsx +36 -0
- package/client/components/icons/ProviderBadges.tsx +295 -0
- package/client/components/icons/ProviderSeals.tsx +319 -0
- package/client/components/icons/SealHealthSafetyRating.tsx +65 -0
- package/client/components/icons/SealIwbiMember.tsx +86 -0
- package/client/components/icons/SealWell.tsx +84 -0
- package/client/components/icons/SealWellCertification.tsx +138 -0
- package/client/components/icons/SealWellCommunity.tsx +122 -0
- package/client/components/icons/SealWellResidence.tsx +122 -0
- package/client/components/icons/SealWorksWithWell.tsx +140 -0
- package/client/components/icons/UtilityAccordion.tsx +21 -0
- package/client/components/icons/UtilityChevronDown.tsx +36 -0
- package/client/components/icons/UtilityClassification.tsx +45 -0
- package/client/components/icons/UtilityClose.tsx +41 -0
- package/client/components/icons/UtilityDrag.tsx +69 -0
- package/client/components/icons/UtilityEdit.tsx +42 -0
- package/client/components/icons/UtilityOptions.tsx +45 -0
- package/client/components/icons/UtilityPortfolio.tsx +87 -0
- package/client/components/icons/UtilityReset.tsx +41 -0
- package/client/components/icons/UtilityScoring.tsx +43 -0
- package/client/components/icons/UtilitySearch.tsx +38 -0
- package/client/components/icons/UtilitySort.tsx +52 -0
- package/client/components/icons/UtilityText.tsx +34 -0
- package/client/components/icons/WaterMarkWWWProducts.tsx +26 -0
- package/client/components/icons/WaterMarkWellProjects.tsx +30 -0
- package/client/components/icons/WatermarkMemberOrg.tsx +59 -0
- package/client/components/icons/WellSeal.tsx +79 -0
- package/client/components/icons/X.tsx +35 -0
- package/client/hooks/UseTabs.tsx +35 -0
- package/client/hooks/use-mobile.tsx +21 -0
- package/client/hooks/use-segmented-control.ts +42 -0
- package/client/hooks/use-toast.ts +188 -0
- package/client/pages/Index.tsx +88 -0
- package/client/pages/NotFound.tsx +29 -0
- package/client/ui/Accordion/Accordion.stories.tsx +74 -0
- package/client/ui/Alert/Alert.stories.tsx +82 -0
- package/client/ui/AlertDialog/AlertDialog.stories.tsx +106 -0
- package/client/ui/AspectRatio.stories.tsx +78 -0
- package/client/ui/Avatar/Avatar.stories.tsx +94 -0
- package/client/ui/Badge/Badge.stories.tsx +60 -0
- package/client/ui/Breadcrumb/Breadcrumb.stories.tsx +97 -0
- package/client/ui/Button.stories.tsx +429 -0
- package/client/ui/Calendar/Calendar.stories.tsx +99 -0
- package/client/ui/Card.stories.tsx +84 -0
- package/client/ui/Carousel/Carousel.stories.tsx +85 -0
- package/client/ui/Chart/Chart.stories.tsx +58 -0
- package/client/ui/Checkbox/Checkbox.stories.tsx +112 -0
- package/client/ui/Collapsible/Collapsible.stories.tsx +101 -0
- package/client/ui/Colors.stories.tsx +1041 -0
- package/client/ui/Command/Command.stories.tsx +97 -0
- package/client/ui/ContextMenu/ContextMenu.stories.tsx +74 -0
- package/client/ui/Dialog.stories.tsx +69 -0
- package/client/ui/Drawer/Drawer.stories.tsx +87 -0
- package/client/ui/DropdownMenu/DropdownMenu.stories.tsx +139 -0
- package/client/ui/Form/Form.stories.tsx +74 -0
- package/client/ui/HoverCard/HoverCard.stories.tsx +94 -0
- package/client/ui/Icons.stories.tsx +328 -0
- package/client/ui/Input/Input.stories.tsx +69 -0
- package/client/ui/InputOTP/InputOTP.stories.tsx +85 -0
- package/client/ui/Label.stories.tsx +66 -0
- package/client/ui/Menubar/Menubar.stories.tsx +88 -0
- package/client/ui/Navigation.stories.tsx +57 -0
- package/client/ui/NavigationMenu/NavigationMenu.stories.tsx +106 -0
- package/client/ui/Pagination/Pagination.stories.tsx +115 -0
- package/client/ui/Popover/Popover.stories.tsx +99 -0
- package/client/ui/Progress/Progress.stories.tsx +63 -0
- package/client/ui/RadioGroup/RadioGroup.stories.tsx +110 -0
- package/client/ui/Resizable/Resizable.stories.tsx +88 -0
- package/client/ui/ScrollArea/ScrollArea.stories.tsx +64 -0
- package/client/ui/SearchField.stories.tsx +63 -0
- package/client/ui/Select/Select.stories.tsx +111 -0
- package/client/ui/Separator/Separator.stories.tsx +67 -0
- package/client/ui/Sheet/Sheet.stories.tsx +138 -0
- package/client/ui/Sidebar/Sidebar.stories.tsx +92 -0
- package/client/ui/Skeleton/Skeleton.stories.tsx +65 -0
- package/client/ui/Slider/Slider.stories.tsx +101 -0
- package/client/ui/Sonner/Sonner.stories.tsx +48 -0
- package/client/ui/StrategyTable.stories.tsx +138 -0
- package/client/ui/Switch/Switch.stories.tsx +96 -0
- package/client/ui/Table/Table.stories.tsx +135 -0
- package/client/ui/Tabs.stories.tsx +33 -0
- package/client/ui/Tag.stories.tsx +190 -0
- package/client/ui/Textarea/Textarea.stories.tsx +56 -0
- package/client/ui/Toast/Toast.stories.tsx +76 -0
- package/client/ui/Toaster/Toaster.stories.tsx +52 -0
- package/client/ui/Toggle.stories.tsx +248 -0
- package/client/ui/ToggleGroup/ToggleGroup.stories.tsx +88 -0
- package/client/ui/Tooltip.stories.tsx +72 -0
- package/client/ui/Typography.stories.tsx +421 -0
- package/client/ui/WELLDashboard/WELLDashboard.stories.tsx +115 -0
- package/client/ui/WELLDashboard/index.tsx +317 -0
- package/client/vite-env.d.ts +1 -0
- package/dist/ui/index.cjs.js +1 -1
- package/dist/ui/index.d.ts +10 -1
- package/dist/ui/index.es.js +2233 -447
- package/package.json +2 -1
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Tag } from "@/components/ui/Tag";
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Review/Tag",
|
|
6
|
+
component: Tag,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "padded",
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof Tag>;
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const DualStateInactive: Story = {
|
|
18
|
+
args: {
|
|
19
|
+
active: false,
|
|
20
|
+
children: "Tag",
|
|
21
|
+
},
|
|
22
|
+
render: () => (
|
|
23
|
+
<div className="space-y-4">
|
|
24
|
+
<div>
|
|
25
|
+
<p className="text-sm text-gray-600 mb-2">General purpose, inactive</p>
|
|
26
|
+
<Tag active={false}>Tag</Tag>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const DualStateActive: Story = {
|
|
33
|
+
args: {
|
|
34
|
+
active: true,
|
|
35
|
+
children: "Tag",
|
|
36
|
+
},
|
|
37
|
+
render: () => (
|
|
38
|
+
<div className="space-y-4">
|
|
39
|
+
<div>
|
|
40
|
+
<p className="text-sm text-gray-600 mb-2">General purpose, active</p>
|
|
41
|
+
<Tag active={true}>Tag</Tag>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const StatusTagsLight: Story = {
|
|
48
|
+
args: {
|
|
49
|
+
status: "todo",
|
|
50
|
+
variant: "light",
|
|
51
|
+
children: "Todo",
|
|
52
|
+
},
|
|
53
|
+
render: () => (
|
|
54
|
+
<div className="space-y-6">
|
|
55
|
+
<div>
|
|
56
|
+
<p className="text-sm font-semibold text-gray-600 mb-4">
|
|
57
|
+
Status, light
|
|
58
|
+
</p>
|
|
59
|
+
<div className="flex flex-col justify-center items-center gap-6">
|
|
60
|
+
<Tag status="todo" variant="light">
|
|
61
|
+
Todo
|
|
62
|
+
</Tag>
|
|
63
|
+
<Tag status="low" variant="light">
|
|
64
|
+
Low
|
|
65
|
+
</Tag>
|
|
66
|
+
<Tag status="medium" variant="light">
|
|
67
|
+
Medium
|
|
68
|
+
</Tag>
|
|
69
|
+
<Tag status="high" variant="light">
|
|
70
|
+
High
|
|
71
|
+
</Tag>
|
|
72
|
+
<Tag status="done" variant="light">
|
|
73
|
+
Done
|
|
74
|
+
</Tag>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
),
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const StatusTagsDark: Story = {
|
|
82
|
+
args: {
|
|
83
|
+
status: "todo",
|
|
84
|
+
variant: "dark",
|
|
85
|
+
children: "Todo",
|
|
86
|
+
},
|
|
87
|
+
render: () => (
|
|
88
|
+
<div className="space-y-6 bg-gray-900 p-8 rounded-lg">
|
|
89
|
+
<div>
|
|
90
|
+
<p className="text-sm font-semibold text-gray-300 mb-4">Status, dark</p>
|
|
91
|
+
<div className="flex flex-col justify-center items-center gap-6">
|
|
92
|
+
<Tag status="todo" variant="dark">
|
|
93
|
+
Todo
|
|
94
|
+
</Tag>
|
|
95
|
+
<Tag status="low" variant="dark">
|
|
96
|
+
Low
|
|
97
|
+
</Tag>
|
|
98
|
+
<Tag status="medium" variant="dark">
|
|
99
|
+
Medium
|
|
100
|
+
</Tag>
|
|
101
|
+
<Tag status="high" variant="dark">
|
|
102
|
+
High
|
|
103
|
+
</Tag>
|
|
104
|
+
<Tag status="done" variant="dark">
|
|
105
|
+
Done
|
|
106
|
+
</Tag>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
),
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const AllVariants: Story = {
|
|
114
|
+
args: {
|
|
115
|
+
active: false,
|
|
116
|
+
variant: "light",
|
|
117
|
+
children: "Tag",
|
|
118
|
+
},
|
|
119
|
+
render: (args) => (
|
|
120
|
+
<div className="space-y-12">
|
|
121
|
+
<div className="space-y-6">
|
|
122
|
+
<h3 className="text-base font-semibold text-gray-700">
|
|
123
|
+
Dual-state tags
|
|
124
|
+
</h3>
|
|
125
|
+
<div className="flex flex-col justify-center items-center gap-6">
|
|
126
|
+
<div>
|
|
127
|
+
<p className="text-sm text-gray-600 mb-2">
|
|
128
|
+
General purpose, inactive
|
|
129
|
+
</p>
|
|
130
|
+
<Tag {...args}>Tag</Tag>
|
|
131
|
+
</div>
|
|
132
|
+
<div>
|
|
133
|
+
<p className="text-sm text-gray-600 mb-2">
|
|
134
|
+
General purpose, active
|
|
135
|
+
</p>
|
|
136
|
+
<Tag {...args} active>
|
|
137
|
+
Tag
|
|
138
|
+
</Tag>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<div className="space-y-6">
|
|
144
|
+
<h3 className="text-base font-semibold text-gray-700">Status tags</h3>
|
|
145
|
+
<div className="grid grid-cols-2 gap-12">
|
|
146
|
+
<div>
|
|
147
|
+
<p className="text-sm text-gray-600 mb-4">Status, light</p>
|
|
148
|
+
<div className="flex flex-col justify-center items-center gap-6">
|
|
149
|
+
<Tag {...args} variant="light" status="todo">
|
|
150
|
+
Todo
|
|
151
|
+
</Tag>
|
|
152
|
+
<Tag {...args} variant="light" status="low">
|
|
153
|
+
Low
|
|
154
|
+
</Tag>
|
|
155
|
+
<Tag {...args} variant="light" status="medium">
|
|
156
|
+
Medium
|
|
157
|
+
</Tag>
|
|
158
|
+
<Tag {...args} variant="light" status="high">
|
|
159
|
+
High
|
|
160
|
+
</Tag>
|
|
161
|
+
<Tag {...args} variant="light" status="done">
|
|
162
|
+
Done
|
|
163
|
+
</Tag>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
<div className="bg-gray-900 p-6 rounded-lg">
|
|
167
|
+
<p className="text-sm text-gray-300 mb-4">Status, dark</p>
|
|
168
|
+
<div className="flex flex-col justify-center items-center gap-6">
|
|
169
|
+
<Tag {...args} variant="dark" status="todo">
|
|
170
|
+
Todo
|
|
171
|
+
</Tag>
|
|
172
|
+
<Tag {...args} variant="dark" status="low">
|
|
173
|
+
Low
|
|
174
|
+
</Tag>
|
|
175
|
+
<Tag {...args} variant="dark" status="medium">
|
|
176
|
+
Medium
|
|
177
|
+
</Tag>
|
|
178
|
+
<Tag {...args} variant="dark" status="high">
|
|
179
|
+
High
|
|
180
|
+
</Tag>
|
|
181
|
+
<Tag {...args} variant="dark" status="done">
|
|
182
|
+
Done
|
|
183
|
+
</Tag>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
</div>
|
|
189
|
+
),
|
|
190
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Textarea } from "../../components/ui/textarea";
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "UI/Textarea",
|
|
6
|
+
component: Textarea,
|
|
7
|
+
tags: ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
} satisfies Meta<typeof Textarea>;
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
type Story = StoryObj<typeof meta>;
|
|
16
|
+
|
|
17
|
+
export const Default: Story = {
|
|
18
|
+
args: {
|
|
19
|
+
placeholder: "Enter your message here...",
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const WithValue: Story = {
|
|
24
|
+
args: {
|
|
25
|
+
placeholder: "Enter your message here...",
|
|
26
|
+
value: "This is some pre-filled text.",
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const Disabled: Story = {
|
|
31
|
+
args: {
|
|
32
|
+
placeholder: "This textarea is disabled",
|
|
33
|
+
disabled: true,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const Rows: Story = {
|
|
38
|
+
render: () => (
|
|
39
|
+
<div className="space-y-4 w-full max-w-md">
|
|
40
|
+
<div>
|
|
41
|
+
<label className="text-sm font-medium mb-2 block">Small (3 rows)</label>
|
|
42
|
+
<Textarea placeholder="Type here..." rows={3} />
|
|
43
|
+
</div>
|
|
44
|
+
<div>
|
|
45
|
+
<label className="text-sm font-medium mb-2 block">
|
|
46
|
+
Medium (5 rows)
|
|
47
|
+
</label>
|
|
48
|
+
<Textarea placeholder="Type here..." rows={5} />
|
|
49
|
+
</div>
|
|
50
|
+
<div>
|
|
51
|
+
<label className="text-sm font-medium mb-2 block">Large (8 rows)</label>
|
|
52
|
+
<Textarea placeholder="Type here..." rows={8} />
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
),
|
|
56
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { useToast } from "../../hooks/use-toast";
|
|
3
|
+
import { Button } from "../../components/ui/button";
|
|
4
|
+
import { Toast, ToastAction } from "../../components/ui/toast";
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "UI/Toast",
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: "centered",
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
|
|
16
|
+
type Story = StoryObj;
|
|
17
|
+
|
|
18
|
+
export const Default: Story = {
|
|
19
|
+
render: () => {
|
|
20
|
+
const { toast } = useToast();
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Button
|
|
24
|
+
onClick={() =>
|
|
25
|
+
toast({
|
|
26
|
+
title: "Success",
|
|
27
|
+
description: "Your action was successful.",
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
>
|
|
31
|
+
Show Toast
|
|
32
|
+
</Button>
|
|
33
|
+
);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const WithAction: Story = {
|
|
38
|
+
render: () => {
|
|
39
|
+
const { toast } = useToast();
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Button
|
|
43
|
+
onClick={() =>
|
|
44
|
+
toast({
|
|
45
|
+
title: "Undo Action",
|
|
46
|
+
description: "You can undo this action.",
|
|
47
|
+
action: <ToastAction altText="Undo">Undo</ToastAction>,
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
>
|
|
51
|
+
Show Toast with Action
|
|
52
|
+
</Button>
|
|
53
|
+
);
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const Destructive: Story = {
|
|
58
|
+
render: () => {
|
|
59
|
+
const { toast } = useToast();
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<Button
|
|
63
|
+
variant="destructive"
|
|
64
|
+
onClick={() =>
|
|
65
|
+
toast({
|
|
66
|
+
title: "Error",
|
|
67
|
+
description: "Something went wrong.",
|
|
68
|
+
variant: "destructive",
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
>
|
|
72
|
+
Show Error Toast
|
|
73
|
+
</Button>
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Toaster } from "../../components/ui/toaster";
|
|
3
|
+
import { useToast } from "../../hooks/use-toast";
|
|
4
|
+
import { Button } from "../../components/ui/button";
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "UI/Toaster",
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: "centered",
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
|
|
16
|
+
type Story = StoryObj;
|
|
17
|
+
|
|
18
|
+
export const Default: Story = {
|
|
19
|
+
render: () => {
|
|
20
|
+
const { toast } = useToast();
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div className="space-y-4">
|
|
24
|
+
<Toaster />
|
|
25
|
+
<div className="space-y-2">
|
|
26
|
+
<Button
|
|
27
|
+
onClick={() =>
|
|
28
|
+
toast({
|
|
29
|
+
title: "Success",
|
|
30
|
+
description: "Your changes have been saved.",
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
>
|
|
34
|
+
Show Success Toast
|
|
35
|
+
</Button>
|
|
36
|
+
<Button
|
|
37
|
+
variant="destructive"
|
|
38
|
+
onClick={() =>
|
|
39
|
+
toast({
|
|
40
|
+
title: "Error",
|
|
41
|
+
description: "Something went wrong.",
|
|
42
|
+
variant: "destructive",
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
>
|
|
46
|
+
Show Error Toast
|
|
47
|
+
</Button>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { SegmentedControl } from "../components/ui/Toggle";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { cn } from "../lib/utils";
|
|
5
|
+
import { UtilityAccordion } from "@/components/icons/UtilityAccordion";
|
|
6
|
+
import { UtilityText } from "@/components/icons/UtilityText";
|
|
7
|
+
|
|
8
|
+
const meta = {
|
|
9
|
+
title: "Review/Toggle",
|
|
10
|
+
component: SegmentedControl,
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
parameters: {
|
|
13
|
+
layout: "centered",
|
|
14
|
+
},
|
|
15
|
+
} satisfies Meta<typeof SegmentedControl>;
|
|
16
|
+
|
|
17
|
+
export default meta;
|
|
18
|
+
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
|
|
21
|
+
// Complete Design System Overview
|
|
22
|
+
export const AllToggleVariants: Story = {
|
|
23
|
+
args: {
|
|
24
|
+
options: [{ label: "Placeholder", value: "placeholder" }],
|
|
25
|
+
},
|
|
26
|
+
render: () => {
|
|
27
|
+
const [segmentedValue, setSegmentedValue] = useState("active");
|
|
28
|
+
const [viewValue, setViewValue] = useState<"grid" | "list">("grid");
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div className="bg-[#FAFAFA] p-16 space-y-20">
|
|
32
|
+
{/* Utility Toggles Section */}
|
|
33
|
+
<div className="space-y-12">
|
|
34
|
+
<div>
|
|
35
|
+
<h3 className="text-lg font-semibold text-[#4E4F57] mb-8">
|
|
36
|
+
Utility toggles
|
|
37
|
+
</h3>
|
|
38
|
+
<div className="space-y-6">
|
|
39
|
+
<div className="space-y-4">
|
|
40
|
+
<p className="text-[#4E4F57]">Modal pagination</p>
|
|
41
|
+
<div className="inline-flex items-center overflow-hidden border border-gray-100 bg-white rounded-full transition-all h-8 gap-0">
|
|
42
|
+
<button
|
|
43
|
+
className={cn(
|
|
44
|
+
"inline-flex items-center justify-center w-12 h-8 rounded-full text-gray-500 hover:bg-gray-50 disabled:opacity-50 transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring bg-gray-100",
|
|
45
|
+
)}
|
|
46
|
+
onClick={() => console.log("Previous")}
|
|
47
|
+
type="button"
|
|
48
|
+
aria-label="Previous page"
|
|
49
|
+
>
|
|
50
|
+
<svg
|
|
51
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
52
|
+
width="10"
|
|
53
|
+
height="2"
|
|
54
|
+
viewBox="0 0 10 2"
|
|
55
|
+
fill="none"
|
|
56
|
+
>
|
|
57
|
+
<path
|
|
58
|
+
d="M0.75 0.75L8.75 0.75"
|
|
59
|
+
stroke="#71747D"
|
|
60
|
+
strokeWidth="1.5"
|
|
61
|
+
strokeLinecap="round"
|
|
62
|
+
strokeLinejoin="round"
|
|
63
|
+
/>
|
|
64
|
+
</svg>
|
|
65
|
+
</button>
|
|
66
|
+
<button
|
|
67
|
+
className={cn(
|
|
68
|
+
"inline-flex items-center justify-center w-12 h-8 rounded-full text-gray-500 hover:bg-gray-50 disabled:opacity-50 transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring bg-white",
|
|
69
|
+
)}
|
|
70
|
+
onClick={() => console.log("Next")}
|
|
71
|
+
type="button"
|
|
72
|
+
aria-label="Next page"
|
|
73
|
+
>
|
|
74
|
+
<svg
|
|
75
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
76
|
+
width="16"
|
|
77
|
+
height="10"
|
|
78
|
+
viewBox="0 0 16 10"
|
|
79
|
+
fill="none"
|
|
80
|
+
>
|
|
81
|
+
<path
|
|
82
|
+
d="M10.75 0.75L14.75 4.75L10.75 8.75"
|
|
83
|
+
stroke="#71747D"
|
|
84
|
+
strokeWidth="1.5"
|
|
85
|
+
strokeLinecap="round"
|
|
86
|
+
strokeLinejoin="round"
|
|
87
|
+
/>
|
|
88
|
+
<path
|
|
89
|
+
d="M14.75 4.75H0.75"
|
|
90
|
+
stroke="#71747D"
|
|
91
|
+
strokeWidth="1.5"
|
|
92
|
+
strokeLinecap="round"
|
|
93
|
+
strokeLinejoin="round"
|
|
94
|
+
/>
|
|
95
|
+
</svg>
|
|
96
|
+
</button>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
{/* State Controls Section */}
|
|
104
|
+
<div className="space-y-12">
|
|
105
|
+
<div>
|
|
106
|
+
<h3 className="text-lg font-semibold text-[#4E4F57] mb-8">
|
|
107
|
+
State controls
|
|
108
|
+
</h3>
|
|
109
|
+
<div className="space-y-8">
|
|
110
|
+
<div className="space-y-4">
|
|
111
|
+
<p className="text-[#4E4F57]">Segmented control</p>
|
|
112
|
+
<SegmentedControl
|
|
113
|
+
className="inline-flex items-center overflow-hidden border border-gray-100 bg-white rounded-full transition-all h-8 p-0 [&>button]:flex-1"
|
|
114
|
+
options={[
|
|
115
|
+
{ label: "Active", value: "active" },
|
|
116
|
+
{ label: "Inactive", value: "inactive" },
|
|
117
|
+
]}
|
|
118
|
+
value={segmentedValue}
|
|
119
|
+
onValueChange={setSegmentedValue}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
<div className="space-y-4">
|
|
123
|
+
<p className="text-[#4E4F57]">View control</p>
|
|
124
|
+
<SegmentedControl<"grid" | "list">
|
|
125
|
+
className="inline-flex items-center overflow-hidden border border-gray-100 bg-white rounded-full transition-all h-8 p-0 [&>button]:w-12 [&>button]:px-0 [&>button]:text-gray-500 [&>button[data-active='true']]:bg-cyan-700 [&>button[data-active='true']]:text-white"
|
|
126
|
+
options={[
|
|
127
|
+
{
|
|
128
|
+
label: <UtilityAccordion />,
|
|
129
|
+
value: "grid",
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
label: <UtilityText />,
|
|
133
|
+
value: "list",
|
|
134
|
+
},
|
|
135
|
+
]}
|
|
136
|
+
value={viewValue}
|
|
137
|
+
defaultValue="grid"
|
|
138
|
+
onValueChange={setViewValue}
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
);
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// Segmented Control Stories
|
|
150
|
+
export const SegmentedControlExample: Story = {
|
|
151
|
+
render: (args) => {
|
|
152
|
+
const [value, setValue] = useState("active");
|
|
153
|
+
return (
|
|
154
|
+
<SegmentedControl
|
|
155
|
+
{...args}
|
|
156
|
+
className="inline-flex items-center overflow-hidden border border-gray-100 bg-white rounded-full transition-all h-8 p-0 [&>button]:flex-1"
|
|
157
|
+
value={value}
|
|
158
|
+
onValueChange={setValue}
|
|
159
|
+
/>
|
|
160
|
+
);
|
|
161
|
+
},
|
|
162
|
+
args: {
|
|
163
|
+
options: [
|
|
164
|
+
{ label: "Active", value: "active" },
|
|
165
|
+
{ label: "Inactive", value: "inactive" },
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// Pagination Control Stories
|
|
171
|
+
export const PaginationControlExample: Story = {
|
|
172
|
+
args: {
|
|
173
|
+
options: [{ label: "Placeholder", value: "placeholder" }],
|
|
174
|
+
},
|
|
175
|
+
render: () => {
|
|
176
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
177
|
+
const totalPages = 5;
|
|
178
|
+
|
|
179
|
+
return (
|
|
180
|
+
<div className="flex items-center gap-4">
|
|
181
|
+
<div className="inline-flex items-center overflow-hidden border border-gray-100 bg-white rounded-full transition-all h-8 gap-0">
|
|
182
|
+
<button
|
|
183
|
+
className={cn(
|
|
184
|
+
"inline-flex items-center justify-center w-12 h-8 rounded-full text-gray-500 hover:bg-gray-50 disabled:opacity-50 transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring bg-gray-100",
|
|
185
|
+
)}
|
|
186
|
+
onClick={() => setCurrentPage(Math.max(1, currentPage - 1))}
|
|
187
|
+
disabled={currentPage === 1}
|
|
188
|
+
type="button"
|
|
189
|
+
aria-label="Previous page"
|
|
190
|
+
>
|
|
191
|
+
<svg
|
|
192
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
193
|
+
width="10"
|
|
194
|
+
height="2"
|
|
195
|
+
viewBox="0 0 10 2"
|
|
196
|
+
fill="none"
|
|
197
|
+
>
|
|
198
|
+
<path
|
|
199
|
+
d="M0.75 0.75L8.75 0.75"
|
|
200
|
+
stroke="#71747D"
|
|
201
|
+
strokeWidth="1.5"
|
|
202
|
+
strokeLinecap="round"
|
|
203
|
+
strokeLinejoin="round"
|
|
204
|
+
/>
|
|
205
|
+
</svg>
|
|
206
|
+
</button>
|
|
207
|
+
<button
|
|
208
|
+
className={cn(
|
|
209
|
+
"inline-flex items-center justify-center w-12 h-8 rounded-full text-gray-500 hover:bg-gray-50 disabled:opacity-50 transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring bg-white",
|
|
210
|
+
)}
|
|
211
|
+
onClick={() =>
|
|
212
|
+
setCurrentPage(Math.min(totalPages, currentPage + 1))
|
|
213
|
+
}
|
|
214
|
+
disabled={currentPage === totalPages}
|
|
215
|
+
type="button"
|
|
216
|
+
aria-label="Next page"
|
|
217
|
+
>
|
|
218
|
+
<svg
|
|
219
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
220
|
+
width="16"
|
|
221
|
+
height="10"
|
|
222
|
+
viewBox="0 0 16 10"
|
|
223
|
+
fill="none"
|
|
224
|
+
>
|
|
225
|
+
<path
|
|
226
|
+
d="M10.75 0.75L14.75 4.75L10.75 8.75"
|
|
227
|
+
stroke="#71747D"
|
|
228
|
+
strokeWidth="1.5"
|
|
229
|
+
strokeLinecap="round"
|
|
230
|
+
strokeLinejoin="round"
|
|
231
|
+
/>
|
|
232
|
+
<path
|
|
233
|
+
d="M14.75 4.75H0.75"
|
|
234
|
+
stroke="#71747D"
|
|
235
|
+
strokeWidth="1.5"
|
|
236
|
+
strokeLinecap="round"
|
|
237
|
+
strokeLinejoin="round"
|
|
238
|
+
/>
|
|
239
|
+
</svg>
|
|
240
|
+
</button>
|
|
241
|
+
</div>
|
|
242
|
+
<span className="text-sm text-gray-600">
|
|
243
|
+
Page {currentPage} of {totalPages}
|
|
244
|
+
</span>
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
},
|
|
248
|
+
};
|