ekm-ui 0.0.4 → 0.0.6
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/.turbo/turbo-build.log +47 -14
- package/CHANGELOG.md +12 -0
- package/dist/button.d.ts +9 -0
- package/dist/button.mjs +4 -0
- package/dist/chunk-3SV266EG.mjs +8 -0
- package/dist/chunk-3SV266EG.mjs.map +1 -0
- package/dist/chunk-5PBKUEAL.mjs +9 -0
- package/dist/chunk-5PBKUEAL.mjs.map +1 -0
- package/dist/chunk-7LHL2LAJ.mjs +7 -0
- package/dist/chunk-7LHL2LAJ.mjs.map +1 -0
- package/dist/chunk-FRIXS4BL.mjs +7 -0
- package/dist/chunk-FRIXS4BL.mjs.map +1 -0
- package/dist/chunk-G676EBCC.mjs +10 -0
- package/dist/chunk-G676EBCC.mjs.map +1 -0
- package/dist/chunk-PLYG34XT.mjs +8 -0
- package/dist/chunk-PLYG34XT.mjs.map +1 -0
- package/dist/chunk-Q6W42FIC.mjs +11 -0
- package/dist/chunk-Q6W42FIC.mjs.map +1 -0
- package/dist/chunk-RUPJ2ZHA.mjs +5 -0
- package/dist/chunk-RUPJ2ZHA.mjs.map +1 -0
- package/dist/chunk-ZIAMSFEI.mjs +18 -0
- package/dist/chunk-ZIAMSFEI.mjs.map +1 -0
- package/dist/ekm-logo.d.ts +5 -0
- package/dist/ekm-logo.mjs +4 -0
- package/dist/ekm-logo.mjs.map +1 -0
- package/dist/footer-heart-icon.d.ts +3 -0
- package/dist/footer-heart-icon.mjs +4 -0
- package/dist/footer-heart-icon.mjs.map +1 -0
- package/dist/form-row.d.ts +10 -0
- package/dist/form-row.mjs +4 -0
- package/dist/form-row.mjs.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.mjs +9 -1
- package/dist/love-footer.d.ts +3 -0
- package/dist/love-footer.mjs +5 -0
- package/dist/love-footer.mjs.map +1 -0
- package/dist/navbar/navbar.d.ts +9 -0
- package/dist/navbar/navbar.mjs +6 -0
- package/dist/navbar/navbar.mjs.map +1 -0
- package/dist/sidebar/sidebar.d.ts +7 -0
- package/dist/sidebar/sidebar.mjs +5 -0
- package/dist/sidebar/sidebar.mjs.map +1 -0
- package/images/ekm-logo.svg +12 -0
- package/images/run_workflow.jpg +0 -0
- package/package.json +8 -1
- package/readme.md +31 -0
- package/src/button.tsx +38 -0
- package/src/ekm-logo.tsx +37 -0
- package/src/footer-heart-icon.tsx +13 -0
- package/src/form-row.tsx +30 -0
- package/src/helpers/is-browser.ts +5 -0
- package/src/helpers/is-small-screen.ts +7 -0
- package/src/index.tsx +5 -2
- package/src/love-footer.tsx +11 -0
- package/src/navbar/navbar.tsx +526 -0
- package/src/sidebar/sidebar.tsx +48 -0
- package/tsconfig.json +3 -0
- package/dist/Button.d.ts +0 -22
- package/dist/Button.mjs +0 -3
- package/dist/chunk-57QDDOX4.mjs +0 -8
- package/dist/chunk-57QDDOX4.mjs.map +0 -1
- package/src/Button.tsx +0 -131
- /package/dist/{Button.mjs.map → button.mjs.map} +0 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Avatar,
|
|
3
|
+
Button,
|
|
4
|
+
Dropdown,
|
|
5
|
+
Navbar as FlowbiteNavbar,
|
|
6
|
+
Label,
|
|
7
|
+
TextInput,
|
|
8
|
+
} from "flowbite-react";
|
|
9
|
+
import { FC, useEffect } from "react";
|
|
10
|
+
import {
|
|
11
|
+
HiArchive,
|
|
12
|
+
HiBell,
|
|
13
|
+
HiCog,
|
|
14
|
+
HiCurrencyDollar,
|
|
15
|
+
HiEye,
|
|
16
|
+
HiInbox,
|
|
17
|
+
HiLogout,
|
|
18
|
+
HiMenuAlt1,
|
|
19
|
+
HiOutlineTicket,
|
|
20
|
+
HiSearch,
|
|
21
|
+
HiShoppingBag,
|
|
22
|
+
HiUserCircle,
|
|
23
|
+
HiUsers,
|
|
24
|
+
HiViewGrid,
|
|
25
|
+
HiPlusSm,
|
|
26
|
+
HiX,
|
|
27
|
+
} from "react-icons/hi";
|
|
28
|
+
import { EkmLogo } from "../ekm-logo";
|
|
29
|
+
|
|
30
|
+
type Props = {
|
|
31
|
+
onMenuButtonClick: () => void;
|
|
32
|
+
showCloseButton?: boolean;
|
|
33
|
+
avatarImg?: string;
|
|
34
|
+
avatarPlaceholderInitials?: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export function Navbar({
|
|
38
|
+
onMenuButtonClick,
|
|
39
|
+
showCloseButton,
|
|
40
|
+
avatarImg,
|
|
41
|
+
avatarPlaceholderInitials,
|
|
42
|
+
}: Props) {
|
|
43
|
+
// Close Sidebar on page change on mobile
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (showCloseButton) {
|
|
46
|
+
onMenuButtonClick();
|
|
47
|
+
}
|
|
48
|
+
}, [location]);
|
|
49
|
+
|
|
50
|
+
// Close Sidebar on mobile tap inside main content
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
function handleMobileTapInsideMain(event: MouseEvent) {
|
|
53
|
+
const main = document.querySelector("main");
|
|
54
|
+
const isClickInsideMain = main?.contains(event.target as Node);
|
|
55
|
+
|
|
56
|
+
if (showCloseButton && isClickInsideMain) {
|
|
57
|
+
onMenuButtonClick();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
document.addEventListener("mousedown", handleMobileTapInsideMain);
|
|
62
|
+
return () => {
|
|
63
|
+
document.removeEventListener("mousedown", handleMobileTapInsideMain);
|
|
64
|
+
};
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<FlowbiteNavbar fluid className="border-b border-gray-200">
|
|
69
|
+
<div className="w-full lg:px-5 lg:pl-0">
|
|
70
|
+
<div className="flex items-center justify-between">
|
|
71
|
+
<div className="flex items-center">
|
|
72
|
+
<FlowbiteNavbar.Brand href="https://ekm.com" target="_blank">
|
|
73
|
+
<EkmLogo className="mr-3" />
|
|
74
|
+
</FlowbiteNavbar.Brand>
|
|
75
|
+
<button
|
|
76
|
+
onClick={() => onMenuButtonClick()}
|
|
77
|
+
className="mr-3 cursor-pointer rounded p-2 text-gray-600 hover:bg-gray-100 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white lg:inline"
|
|
78
|
+
>
|
|
79
|
+
<span className="sr-only">Toggle sidebar</span>
|
|
80
|
+
{showCloseButton ? (
|
|
81
|
+
<HiX className="h-6 w-6" />
|
|
82
|
+
) : (
|
|
83
|
+
<HiMenuAlt1 className="h-6 w-6" />
|
|
84
|
+
)}
|
|
85
|
+
</button>
|
|
86
|
+
<form className="hidden md:block">
|
|
87
|
+
<Label htmlFor="search" className="sr-only">
|
|
88
|
+
Search
|
|
89
|
+
</Label>
|
|
90
|
+
<TextInput
|
|
91
|
+
icon={HiSearch}
|
|
92
|
+
id="search"
|
|
93
|
+
name="search"
|
|
94
|
+
placeholder="Search"
|
|
95
|
+
required
|
|
96
|
+
size={32}
|
|
97
|
+
type="search"
|
|
98
|
+
/>
|
|
99
|
+
</form>
|
|
100
|
+
</div>
|
|
101
|
+
<div className="flex items-center lg:gap-3">
|
|
102
|
+
<div className="flex items-center">
|
|
103
|
+
<button className="cursor-pointer rounded p-2 text-gray-600 hover:bg-gray-100 hover:text-gray-900 focus:bg-gray-100 focus:ring-2 focus:ring-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:bg-gray-700 dark:focus:ring-gray-700 lg:hidden">
|
|
104
|
+
<span className="sr-only">Search</span>
|
|
105
|
+
<HiSearch className="h-6 w-6" />
|
|
106
|
+
</button>
|
|
107
|
+
<div>
|
|
108
|
+
<Button type="button" className="mr-3" size="xs">
|
|
109
|
+
<HiPlusSm className="-ml-1 mr-1 h-5 w-5" /> Upgrade
|
|
110
|
+
</Button>
|
|
111
|
+
</div>
|
|
112
|
+
<NotificationBellDropdown />
|
|
113
|
+
<Dropdown
|
|
114
|
+
arrowIcon={false}
|
|
115
|
+
inline
|
|
116
|
+
label={
|
|
117
|
+
<span className="mr-1 rounded-lg p-2 hover:bg-gray-100 dark:hover:bg-gray-700">
|
|
118
|
+
<span className="sr-only">Notifications</span>
|
|
119
|
+
<HiCog className="text-2xl text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white " />
|
|
120
|
+
</span>
|
|
121
|
+
}
|
|
122
|
+
/>
|
|
123
|
+
</div>
|
|
124
|
+
<div className="hidden lg:block">
|
|
125
|
+
<UserDropdown
|
|
126
|
+
img={avatarImg}
|
|
127
|
+
placeholderInitials={avatarPlaceholderInitials}
|
|
128
|
+
/>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</FlowbiteNavbar>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const NotificationBellDropdown: FC = function () {
|
|
138
|
+
return (
|
|
139
|
+
<Dropdown
|
|
140
|
+
arrowIcon={false}
|
|
141
|
+
inline
|
|
142
|
+
label={
|
|
143
|
+
<span className="mr-2 rounded-lg p-2 hover:bg-gray-100 dark:hover:bg-gray-700">
|
|
144
|
+
<span className="sr-only">Notifications</span>
|
|
145
|
+
<HiBell className="text-2xl text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white " />
|
|
146
|
+
</span>
|
|
147
|
+
}
|
|
148
|
+
>
|
|
149
|
+
<div className="max-w-[24rem]">
|
|
150
|
+
<div className="block rounded-t-xl bg-gray-50 px-4 py-2 text-center text-base font-medium text-gray-700 dark:bg-gray-700 dark:text-gray-400">
|
|
151
|
+
Notifications
|
|
152
|
+
</div>
|
|
153
|
+
<div>
|
|
154
|
+
<a
|
|
155
|
+
href="#"
|
|
156
|
+
className="flex border-y px-4 py-3 hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-600"
|
|
157
|
+
>
|
|
158
|
+
<div className="shrink-0">
|
|
159
|
+
<img
|
|
160
|
+
alt=""
|
|
161
|
+
src="../images/users/bonnie-green.png"
|
|
162
|
+
className="h-11 w-11 rounded-full"
|
|
163
|
+
/>
|
|
164
|
+
<div className="absolute -mt-5 ml-6 flex h-5 w-5 items-center justify-center rounded-full border border-white bg-primary-700 dark:border-gray-700">
|
|
165
|
+
<NewMessageIcon />
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
<div className="w-full pl-3">
|
|
169
|
+
<div className="mb-1.5 text-sm font-normal text-gray-500 dark:text-gray-400">
|
|
170
|
+
New message from
|
|
171
|
+
<span className="font-semibold text-gray-900 dark:text-white">
|
|
172
|
+
Bonnie Green
|
|
173
|
+
</span>
|
|
174
|
+
: "Hey, what's up? All set for the presentation?"
|
|
175
|
+
</div>
|
|
176
|
+
<div className="text-xs font-medium text-primary-700 dark:text-primary-400">
|
|
177
|
+
a few moments ago
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</a>
|
|
181
|
+
<a
|
|
182
|
+
href="#"
|
|
183
|
+
className="flex border-b px-4 py-3 hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-600"
|
|
184
|
+
>
|
|
185
|
+
<div className="shrink-0">
|
|
186
|
+
<img
|
|
187
|
+
alt=""
|
|
188
|
+
src="../images/users/jese-leos.png"
|
|
189
|
+
className="h-11 w-11 rounded-full"
|
|
190
|
+
/>
|
|
191
|
+
<div className="absolute -mt-5 ml-6 flex h-5 w-5 items-center justify-center rounded-full border border-white bg-gray-900 dark:border-gray-700">
|
|
192
|
+
<NewFollowIcon />
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
<div className="w-full pl-3">
|
|
196
|
+
<div className="mb-1.5 text-sm font-normal text-gray-500 dark:text-gray-400">
|
|
197
|
+
<span className="font-semibold text-gray-900 dark:text-white">
|
|
198
|
+
Jese Leos
|
|
199
|
+
</span>
|
|
200
|
+
and
|
|
201
|
+
<span className="font-medium text-gray-900 dark:text-white">
|
|
202
|
+
5 others
|
|
203
|
+
</span>
|
|
204
|
+
started following you.
|
|
205
|
+
</div>
|
|
206
|
+
<div className="text-xs font-medium text-primary-700 dark:text-primary-400">
|
|
207
|
+
10 minutes ago
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
</a>
|
|
211
|
+
<a
|
|
212
|
+
href="#"
|
|
213
|
+
className="flex border-b px-4 py-3 hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-600"
|
|
214
|
+
>
|
|
215
|
+
<div className="shrink-0">
|
|
216
|
+
<img
|
|
217
|
+
alt=""
|
|
218
|
+
src="../images/users/joseph-mcfall.png"
|
|
219
|
+
className="h-11 w-11 rounded-full"
|
|
220
|
+
/>
|
|
221
|
+
<div className="absolute -mt-5 ml-6 flex h-5 w-5 items-center justify-center rounded-full border border-white bg-red-600 dark:border-gray-700">
|
|
222
|
+
<NewLoveIcon />
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
<div className="w-full pl-3">
|
|
226
|
+
<div className="mb-1.5 text-sm font-normal text-gray-500 dark:text-gray-400">
|
|
227
|
+
<span className="font-semibold text-gray-900 dark:text-white">
|
|
228
|
+
Joseph Mcfall
|
|
229
|
+
</span>
|
|
230
|
+
and
|
|
231
|
+
<span className="font-medium text-gray-900 dark:text-white">
|
|
232
|
+
141 others
|
|
233
|
+
</span>
|
|
234
|
+
love your story. See it and view more stories.
|
|
235
|
+
</div>
|
|
236
|
+
<div className="text-xs font-medium text-primary-700 dark:text-primary-400">
|
|
237
|
+
44 minutes ago
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
</a>
|
|
241
|
+
<a
|
|
242
|
+
href="#"
|
|
243
|
+
className="flex border-b px-4 py-3 hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-600"
|
|
244
|
+
>
|
|
245
|
+
<div className="shrink-0">
|
|
246
|
+
<img
|
|
247
|
+
alt=""
|
|
248
|
+
src="../images/users/leslie-livingston.png"
|
|
249
|
+
className="h-11 w-11 rounded-full"
|
|
250
|
+
/>
|
|
251
|
+
<div className="absolute -mt-5 ml-6 flex h-5 w-5 items-center justify-center rounded-full border border-white bg-green-400 dark:border-gray-700">
|
|
252
|
+
<NewMentionIcon />
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
<div className="w-full pl-3">
|
|
256
|
+
<div className="mb-1.5 text-sm font-normal text-gray-500 dark:text-gray-400">
|
|
257
|
+
<span className="font-semibold text-gray-900 dark:text-white">
|
|
258
|
+
Leslie Livingston
|
|
259
|
+
</span>
|
|
260
|
+
mentioned you in a comment:
|
|
261
|
+
<span className="font-medium text-primary-700 dark:text-primary-500">
|
|
262
|
+
@bonnie.green
|
|
263
|
+
</span>
|
|
264
|
+
what do you say?
|
|
265
|
+
</div>
|
|
266
|
+
<div className="text-xs font-medium text-primary-700 dark:text-primary-400">
|
|
267
|
+
1 hour ago
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
</a>
|
|
271
|
+
<a
|
|
272
|
+
href="#"
|
|
273
|
+
className="flex px-4 py-3 hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
274
|
+
>
|
|
275
|
+
<div className="shrink-0">
|
|
276
|
+
<img
|
|
277
|
+
alt=""
|
|
278
|
+
src="../images/users/robert-brown.png"
|
|
279
|
+
className="h-11 w-11 rounded-full"
|
|
280
|
+
/>
|
|
281
|
+
<div className="absolute -mt-5 ml-6 flex h-5 w-5 items-center justify-center rounded-full border border-white bg-purple-500 dark:border-gray-700">
|
|
282
|
+
<NewVideoIcon />
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
<div className="w-full pl-3">
|
|
286
|
+
<div className="mb-1.5 text-sm font-normal text-gray-500 dark:text-gray-400">
|
|
287
|
+
<span className="font-semibold text-gray-900 dark:text-white">
|
|
288
|
+
Robert Brown
|
|
289
|
+
</span>
|
|
290
|
+
posted a new video: Glassmorphism - learn how to implement
|
|
291
|
+
the new design trend.
|
|
292
|
+
</div>
|
|
293
|
+
<div className="text-xs font-medium text-primary-700 dark:text-primary-400">
|
|
294
|
+
3 hours ago
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
297
|
+
</a>
|
|
298
|
+
</div>
|
|
299
|
+
<a
|
|
300
|
+
href="#"
|
|
301
|
+
className="block rounded-b-xl bg-gray-50 py-2 text-center text-base font-normal text-gray-900 hover:bg-gray-100 dark:bg-gray-700 dark:text-white dark:hover:underline"
|
|
302
|
+
>
|
|
303
|
+
<div className="inline-flex items-center gap-x-2">
|
|
304
|
+
<HiEye className="h-6 w-6" />
|
|
305
|
+
<span>View all</span>
|
|
306
|
+
</div>
|
|
307
|
+
</a>
|
|
308
|
+
</div>
|
|
309
|
+
</Dropdown>
|
|
310
|
+
);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
const NewMessageIcon: FC = function () {
|
|
314
|
+
return (
|
|
315
|
+
<svg
|
|
316
|
+
className="h-3 w-3 text-white"
|
|
317
|
+
fill="currentColor"
|
|
318
|
+
viewBox="0 0 20 20"
|
|
319
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
320
|
+
>
|
|
321
|
+
<path d="M8.707 7.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l2-2a1 1 0 00-1.414-1.414L11 7.586V3a1 1 0 10-2 0v4.586l-.293-.293z"></path>
|
|
322
|
+
<path d="M3 5a2 2 0 012-2h1a1 1 0 010 2H5v7h2l1 2h4l1-2h2V5h-1a1 1 0 110-2h1a2 2 0 012 2v10a2 2 0 01-2 2H5a2 2 0 01-2-2V5z"></path>
|
|
323
|
+
</svg>
|
|
324
|
+
);
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
const NewFollowIcon: FC = function () {
|
|
328
|
+
return (
|
|
329
|
+
<svg
|
|
330
|
+
className="h-3 w-3 text-white"
|
|
331
|
+
fill="currentColor"
|
|
332
|
+
viewBox="0 0 20 20"
|
|
333
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
334
|
+
>
|
|
335
|
+
<path d="M8 9a3 3 0 100-6 3 3 0 000 6zM8 11a6 6 0 016 6H2a6 6 0 016-6zM16 7a1 1 0 10-2 0v1h-1a1 1 0 100 2h1v1a1 1 0 102 0v-1h1a1 1 0 100-2h-1V7z"></path>
|
|
336
|
+
</svg>
|
|
337
|
+
);
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
const NewLoveIcon: FC = function () {
|
|
341
|
+
return (
|
|
342
|
+
<svg
|
|
343
|
+
className="h-3 w-3 text-white"
|
|
344
|
+
fill="currentColor"
|
|
345
|
+
viewBox="0 0 20 20"
|
|
346
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
347
|
+
>
|
|
348
|
+
<path
|
|
349
|
+
fillRule="evenodd"
|
|
350
|
+
d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z"
|
|
351
|
+
clipRule="evenodd"
|
|
352
|
+
></path>
|
|
353
|
+
</svg>
|
|
354
|
+
);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const NewMentionIcon: FC = function () {
|
|
358
|
+
return (
|
|
359
|
+
<svg
|
|
360
|
+
className="h-3 w-3 text-white"
|
|
361
|
+
fill="currentColor"
|
|
362
|
+
viewBox="0 0 20 20"
|
|
363
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
364
|
+
>
|
|
365
|
+
<path
|
|
366
|
+
fillRule="evenodd"
|
|
367
|
+
d="M18 13V5a2 2 0 00-2-2H4a2 2 0 00-2 2v8a2 2 0 002 2h3l3 3 3-3h3a2 2 0 002-2zM5 7a1 1 0 011-1h8a1 1 0 110 2H6a1 1 0 01-1-1zm1 3a1 1 0 100 2h3a1 1 0 100-2H6z"
|
|
368
|
+
clipRule="evenodd"
|
|
369
|
+
></path>
|
|
370
|
+
</svg>
|
|
371
|
+
);
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
const NewVideoIcon: FC = function () {
|
|
375
|
+
return (
|
|
376
|
+
<svg
|
|
377
|
+
className="h-3 w-3 text-white"
|
|
378
|
+
fill="currentColor"
|
|
379
|
+
viewBox="0 0 20 20"
|
|
380
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
381
|
+
>
|
|
382
|
+
<path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z"></path>
|
|
383
|
+
</svg>
|
|
384
|
+
);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const AppDrawerDropdown: FC = function () {
|
|
388
|
+
return (
|
|
389
|
+
<Dropdown
|
|
390
|
+
arrowIcon={false}
|
|
391
|
+
inline
|
|
392
|
+
label={
|
|
393
|
+
<span className="rounded-lg p-2 hover:bg-gray-100 dark:hover:bg-gray-700">
|
|
394
|
+
<span className="sr-only">Apps</span>
|
|
395
|
+
<HiViewGrid className="text-2xl text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white" />
|
|
396
|
+
</span>
|
|
397
|
+
}
|
|
398
|
+
>
|
|
399
|
+
<div className="block rounded-t-lg border-b bg-gray-50 px-4 py-2 text-center text-base font-medium text-gray-700 dark:border-b-gray-600 dark:bg-gray-700 dark:text-white">
|
|
400
|
+
Apps
|
|
401
|
+
</div>
|
|
402
|
+
<div className="grid grid-cols-3 gap-4 p-4">
|
|
403
|
+
<a
|
|
404
|
+
href="#"
|
|
405
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
406
|
+
>
|
|
407
|
+
<HiShoppingBag className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
408
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
409
|
+
Sales
|
|
410
|
+
</div>
|
|
411
|
+
</a>
|
|
412
|
+
<a
|
|
413
|
+
href="#"
|
|
414
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
415
|
+
>
|
|
416
|
+
<HiUsers className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
417
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
418
|
+
Users
|
|
419
|
+
</div>
|
|
420
|
+
</a>
|
|
421
|
+
<a
|
|
422
|
+
href="#"
|
|
423
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
424
|
+
>
|
|
425
|
+
<HiInbox className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
426
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
427
|
+
Inbox
|
|
428
|
+
</div>
|
|
429
|
+
</a>
|
|
430
|
+
<a
|
|
431
|
+
href="#"
|
|
432
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
433
|
+
>
|
|
434
|
+
<HiUserCircle className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
435
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
436
|
+
Profile
|
|
437
|
+
</div>
|
|
438
|
+
</a>
|
|
439
|
+
<a
|
|
440
|
+
href="#"
|
|
441
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
442
|
+
>
|
|
443
|
+
<HiCog className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
444
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
445
|
+
Settings
|
|
446
|
+
</div>
|
|
447
|
+
</a>
|
|
448
|
+
<a
|
|
449
|
+
href="#"
|
|
450
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
451
|
+
>
|
|
452
|
+
<HiArchive className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
453
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
454
|
+
Products
|
|
455
|
+
</div>
|
|
456
|
+
</a>
|
|
457
|
+
<a
|
|
458
|
+
href="#"
|
|
459
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
460
|
+
>
|
|
461
|
+
<HiCurrencyDollar className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
462
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
463
|
+
Pricing
|
|
464
|
+
</div>
|
|
465
|
+
</a>
|
|
466
|
+
<a
|
|
467
|
+
href="#"
|
|
468
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
469
|
+
>
|
|
470
|
+
<HiOutlineTicket className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
471
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
472
|
+
Billing
|
|
473
|
+
</div>
|
|
474
|
+
</a>
|
|
475
|
+
<a
|
|
476
|
+
href="#"
|
|
477
|
+
className="block rounded-lg p-4 text-center hover:bg-gray-100 dark:hover:bg-gray-600"
|
|
478
|
+
>
|
|
479
|
+
<HiLogout className="mx-auto mb-1 h-7 w-7 text-gray-500 dark:text-white" />
|
|
480
|
+
<div className="text-sm font-medium text-gray-900 dark:text-white">
|
|
481
|
+
Logout
|
|
482
|
+
</div>
|
|
483
|
+
</a>
|
|
484
|
+
</div>
|
|
485
|
+
</Dropdown>
|
|
486
|
+
);
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
function UserDropdown({
|
|
490
|
+
img,
|
|
491
|
+
placeholderInitials,
|
|
492
|
+
}: {
|
|
493
|
+
img?: string;
|
|
494
|
+
placeholderInitials?: string;
|
|
495
|
+
}) {
|
|
496
|
+
return (
|
|
497
|
+
<Dropdown
|
|
498
|
+
arrowIcon={false}
|
|
499
|
+
inline
|
|
500
|
+
label={
|
|
501
|
+
<span>
|
|
502
|
+
<span className="sr-only">User menu</span>
|
|
503
|
+
<Avatar
|
|
504
|
+
alt=""
|
|
505
|
+
img={img}
|
|
506
|
+
placeholderInitials={placeholderInitials}
|
|
507
|
+
rounded
|
|
508
|
+
size="sm"
|
|
509
|
+
/>
|
|
510
|
+
</span>
|
|
511
|
+
}
|
|
512
|
+
>
|
|
513
|
+
<Dropdown.Header>
|
|
514
|
+
<span className="block text-sm">Neil Sims</span>
|
|
515
|
+
<span className="block truncate text-sm font-medium">
|
|
516
|
+
neil.sims@flowbite.com
|
|
517
|
+
</span>
|
|
518
|
+
</Dropdown.Header>
|
|
519
|
+
<Dropdown.Item>Dashboard</Dropdown.Item>
|
|
520
|
+
<Dropdown.Item>Settings</Dropdown.Item>
|
|
521
|
+
<Dropdown.Item>Earnings</Dropdown.Item>
|
|
522
|
+
<Dropdown.Divider />
|
|
523
|
+
<Dropdown.Item>Sign out</Dropdown.Item>
|
|
524
|
+
</Dropdown>
|
|
525
|
+
);
|
|
526
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import classNames from "classnames";
|
|
2
|
+
import { Sidebar as FlowbiteSidebar, TextInput } from "flowbite-react";
|
|
3
|
+
import { HiSearch } from "react-icons/hi";
|
|
4
|
+
|
|
5
|
+
import isSmallScreen from "../helpers/is-small-screen";
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
collapsed?: boolean;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function Sidebar({ children, collapsed }: Props) {
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
className={classNames("bg-gray-50 px-2.5 lg:!block", {
|
|
16
|
+
hidden: !collapsed,
|
|
17
|
+
})}
|
|
18
|
+
>
|
|
19
|
+
<FlowbiteSidebar
|
|
20
|
+
aria-label="EKM application sidebar"
|
|
21
|
+
collapsed={collapsed && !isSmallScreen()}
|
|
22
|
+
theme={{
|
|
23
|
+
root: {
|
|
24
|
+
collapsed: {
|
|
25
|
+
on: "w-10",
|
|
26
|
+
},
|
|
27
|
+
inner: "bg-gray-50",
|
|
28
|
+
},
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
<div className="flex h-full flex-col justify-between bg-gray-50 py-4">
|
|
32
|
+
<div>
|
|
33
|
+
<form className="pb-3 md:hidden">
|
|
34
|
+
<TextInput
|
|
35
|
+
icon={HiSearch}
|
|
36
|
+
type="search"
|
|
37
|
+
placeholder="Search"
|
|
38
|
+
required
|
|
39
|
+
size={32}
|
|
40
|
+
/>
|
|
41
|
+
</form>
|
|
42
|
+
{children}
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</FlowbiteSidebar>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
package/tsconfig.json
CHANGED
package/dist/Button.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility type to infer the first argument of a variantProps function.
|
|
3
|
-
*/
|
|
4
|
-
type VariantPropsOf<T> = T extends (props: infer P) => any ? P : never;
|
|
5
|
-
|
|
6
|
-
declare const buttonProps: <P extends {} & {
|
|
7
|
-
color?: "default" | "primary" | "warning" | "danger" | undefined;
|
|
8
|
-
size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
|
|
9
|
-
disabled?: boolean | undefined;
|
|
10
|
-
type?: "outline" | "solid" | "link" | undefined;
|
|
11
|
-
} & {
|
|
12
|
-
className?: string | undefined;
|
|
13
|
-
}>(props: P) => {
|
|
14
|
-
className: string;
|
|
15
|
-
} & Omit<P, "color" | "size" | "disabled" | "type">;
|
|
16
|
-
type Props = JSX.IntrinsicElements["button"] & VariantPropsOf<typeof buttonProps>;
|
|
17
|
-
declare function Button(props: Props): JSX.Element;
|
|
18
|
-
declare namespace Button {
|
|
19
|
-
var displayName: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export { Button };
|
package/dist/Button.mjs
DELETED
package/dist/chunk-57QDDOX4.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import 'react';
|
|
2
|
-
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
|
|
4
|
-
var x=Object.defineProperty;var m=Object.getOwnPropertySymbols;var v=Object.prototype.hasOwnProperty,C=Object.prototype.propertyIsEnumerable;var c=(t,n,e)=>n in t?x(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e,d=(t,n)=>{for(var e in n||(n={}))v.call(n,e)&&c(t,e,n[e]);if(m)for(var e of m(n))C.call(n,e)&&c(t,e,n[e]);return t};function b(t){let{base:n,variants:e,compoundVariants:s,defaultVariants:i}=t,u=p=>{let r=e==null?void 0:e[p];return r&&("false"in r||"true"in r)};return p=>{var f;let r=[n],V=a=>{var o,l;return (l=(o=p[a])!=null?o:i==null?void 0:i[a])!=null?l:u(a)?!1:void 0};for(let a in e){let o=V(a);o!==void 0&&r.push((f=e[a])==null?void 0:f[o]);}for(let{variants:a,className:o}of s!=null?s:[]){let l=y=>V(y)===a[y];Object.keys(a).every(l)&&r.push(o);}return r.filter(Boolean).join(" ")}}function g(t){let n=b(t);return e=>{let s={};for(let i in e)t.variants&&!(i in t.variants)&&(s[i]=e[i]);return s.className=[e.className,n(e)].filter(Boolean).join(" "),s}}var O=g({base:"rounded-full font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2",variants:{color:{default:"focus-visible:outline-indigo-600",primary:"focus-visible:outline-green-600",warning:"focus-visible:outline-orange-600",danger:"focus-visible:outline-red-600"},size:{xs:"px-2.5 py-1 text-xs",sm:"px-2.5 py-1 text-sm",md:"px-3 py-1.5 text-sm",lg:"px-3.5 py-2 text-sm",xl:"px-4 py-2.5 text-sm"},disabled:{true:"cursor-not-allowed opacity-50"},type:{outline:"ring-1 ring-inset bg-white shadow-sm",solid:"text-white shadow-sm",link:"hover:underline bg-white"}},compoundVariants:[{variants:{color:"default",type:"solid"},className:"bg-indigo-600 hover:bg-indigo-500"},{variants:{color:"primary",type:"solid"},className:"bg-green-600 hover:bg-green-500"},{variants:{color:"warning",type:"solid"},className:"bg-orange-600 hover:bg-orange-500"},{variants:{color:"danger",type:"solid"},className:"bg-red-600 hover:bg-red-500"},{variants:{color:"default",type:"outline"},className:"text-indigo-600 ring-indigo-600 hover:bg-indigo-50"},{variants:{color:"primary",type:"outline"},className:"ring-green-600 hover:bg-green-50"},{variants:{color:"warning",type:"outline"},className:"ring-orange-600 hover:bg-orange-50"},{variants:{color:"danger",type:"outline"},className:"ring-red-600 hover:bg-red-50"},{variants:{color:"default",type:"link"},className:"text-indigo-600"},{variants:{color:"primary",type:"link"},className:"ring-green-600"},{variants:{color:"warning",type:"link"},className:"ring-orange-600"},{variants:{color:"danger",type:"link"},className:"ring-red-600"}],defaultVariants:{color:"default",size:"md",disabled:!1,type:"solid"}});function P(t){return jsx("button",d({},O(t)))}P.displayName="Button";
|
|
5
|
-
|
|
6
|
-
export { P as a };
|
|
7
|
-
//# sourceMappingURL=out.js.map
|
|
8
|
-
//# sourceMappingURL=chunk-57QDDOX4.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/variants.ts","../src/Button.tsx"],"names":["createElement","forwardRef","variants","config","base","compoundVariants","defaultVariants","isBooleanVariant","name","v","props","_a","res","getSelected","_b","selected","className","isSelected","variantProps","variantClassName","result","prop","jsx","buttonProps","Button","__spreadValues"],"mappings":"yVACA,OAAS,iBAAAA,EAAe,cAAAC,MAAkB,QAuInC,SAASC,EAGdC,EAAqB,CACrB,GAAM,CAAE,KAAAC,EAAM,SAAAF,EAAU,iBAAAG,EAAkB,gBAAAC,CAAgB,EAAIH,EAExDI,EAAoBC,GAAkB,CAC1C,IAAMC,EAAIP,GAAA,YAAAA,EAAWM,GACrB,OAAOC,IAAM,UAAWA,GAAK,SAAUA,EACzC,EAEA,OAAQC,GAA6B,CAnJvC,IAAAC,EAoJI,IAAMC,EAAM,CAACR,CAAI,EAEXS,EAAeL,GAAe,CAtJxC,IAAAG,EAAAG,EAuJO,OAAAA,GAAAH,EAAAD,EAAcF,CAAI,IAAlB,KAAAG,EACDL,GAAA,YAAAA,EAAkBE,KADjB,KAAAM,EAEAP,EAAiBC,CAAI,EAAI,GAAQ,QAEpC,QAASA,KAAQN,EAAU,CACzB,IAAMa,EAAWF,EAAYL,CAAI,EAC7BO,IAAa,QAAWH,EAAI,MAAKD,EAAAT,EAASM,CAAI,IAAb,YAAAG,EAAiBI,EAAS,EAGjE,OAAS,CAAE,SAAAb,EAAU,UAAAc,CAAU,IAAKX,GAAA,KAAAA,EAAoB,CAAC,EAAG,CAC1D,IAAMY,EAAcT,GAAiBK,EAAYL,CAAI,IAAMN,EAASM,CAAI,EACpE,OAAO,KAAKN,CAAQ,EAAE,MAAMe,CAAU,GACxCL,EAAI,KAAKI,CAAS,EAGtB,OAAOJ,EAAI,OAAO,OAAO,EAAE,KAAK,GAAG,CACrC,CACF,CAeO,SAASM,EAGdf,EAAqB,CACrB,IAAMgB,EAAmBjB,EAAYC,CAAM,EAC3C,OAAmCO,GAAa,CAC9C,IAAMU,EAAc,CAAC,EAGrB,QAASC,KAAQX,EACXP,EAAO,UAAY,EAAEkB,KAAQlB,EAAO,YACtCiB,EAAOC,CAAI,EAAIX,EAAMW,CAAI,GAK7B,OAAAD,EAAO,UAAY,CAACV,EAAM,UAAWS,EAAiBT,CAAK,CAAC,EACzD,OAAO,OAAO,EACd,KAAK,GAAG,EAEJU,CACT,CACF,CC/ES,cAAAE,MAAA,oBA3HT,IAAMC,EAAcL,EAAa,CAC/B,KAAM,0GACN,SAAU,CACR,MAAO,CACL,QAAS,mCACT,QAAS,kCACT,QAAS,mCACT,OAAQ,+BACV,EACA,KAAM,CACJ,GAAI,sBACJ,GAAI,sBACJ,GAAI,sBACJ,GAAI,sBACJ,GAAI,qBACN,EACA,SAAU,CACR,KAAM,+BACR,EACA,KAAM,CACJ,QAAS,uCACT,MAAO,uBACP,KAAM,0BACR,CACF,EACA,iBAAkB,CAChB,CACE,SAAU,CACR,MAAO,UACP,KAAM,OACR,EACA,UAAW,mCACb,EACA,CACE,SAAU,CACR,MAAO,UACP,KAAM,OACR,EACA,UAAW,iCACb,EACA,CACE,SAAU,CACR,MAAO,UACP,KAAM,OACR,EACA,UAAW,mCACb,EACA,CACE,SAAU,CACR,MAAO,SACP,KAAM,OACR,EACA,UAAW,6BACb,EACA,CACE,SAAU,CACR,MAAO,UACP,KAAM,SACR,EACA,UAAW,oDACb,EACA,CACE,SAAU,CACR,MAAO,UACP,KAAM,SACR,EACA,UAAW,kCACb,EACA,CACE,SAAU,CACR,MAAO,UACP,KAAM,SACR,EACA,UAAW,oCACb,EACA,CACE,SAAU,CACR,MAAO,SACP,KAAM,SACR,EACA,UAAW,8BACb,EACA,CACE,SAAU,CACR,MAAO,UACP,KAAM,MACR,EACA,UAAW,iBACb,EACA,CACE,SAAU,CACR,MAAO,UACP,KAAM,MACR,EACA,UAAW,gBACb,EACA,CACE,SAAU,CACR,MAAO,UACP,KAAM,MACR,EACA,UAAW,iBACb,EACA,CACE,SAAU,CACR,MAAO,SACP,KAAM,MACR,EACA,UAAW,cACb,CACF,EACA,gBAAiB,CACf,MAAO,UACP,KAAM,KACN,SAAU,GACV,KAAM,OACR,CACF,CAAC,EAKM,SAASM,EAAOd,EAAc,CACnC,OAAOY,EAAC,SAAAG,EAAA,GAAWF,EAAYb,CAAK,EAAG,CACzC,CAGAc,EAAO,YAAc","sourcesContent":["import type { ComponentProps, ElementType, ReactElement, Ref } from \"react\";\nimport { createElement, forwardRef } from \"react\";\n\n/**\n * Definition of the available variants and their options.\n * @example\n * {\n * color: {\n * white: \"bg-white\"\n * green: \"bg-green-500\",\n * },\n * size: {\n * small: \"text-xs\",\n * large: \"text-lg\"\n * }\n * }\n */\nexport type Variants = Record<string, Record<string, string>>;\n\n/**\n * Configuration including defaults and compound variants.\n */\nexport interface VariantsConfig<V extends Variants> {\n base?: string;\n variants: V;\n compoundVariants?: CompoundVariant<V>[];\n defaultVariants?: Partial<OptionsOf<V>>;\n}\n\n/**\n * Rules for class names that are applied for certain variant combinations.\n */\nexport interface CompoundVariant<V extends Variants> {\n variants: Partial<OptionsOf<V>>;\n className: string;\n}\n\n/**\n * Only the boolean variants, i.e. ones that have \"true\" or \"false\" as options.\n */\ntype BooleanVariants<V extends Variants> = {\n [K in keyof V as V[K] extends { true: any } | { false: any }\n ? K\n : never]: V[K];\n};\n\n/**\n * Only the variants for which a default options is set.\n */\ntype DefaultVariants<\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n> = {\n [K in keyof V as K extends keyof C[\"defaultVariants\"]\n ? K\n : never]: C[\"variants\"][K];\n};\n\n/**\n * Names of all optional variants, i.e. booleans or ones with default options.\n */\ntype OptionalVariantNames<\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n> = keyof BooleanVariants<V> | keyof DefaultVariants<C>;\n\n/**\n * Possible options for all the optional variants.\n *\n * @example\n * {\n * color?: \"white\" | \"green\",\n * rounded?: boolean | undefined\n * }\n */\ntype OptionalOptions<\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n> = {\n [K in keyof V as K extends OptionalVariantNames<C>\n ? K\n : never]?: OptionsOf<V>[K];\n};\n\n/**\n * Possible options for all required variants.\n *\n * @example {\n * size: \"small\" | \"large\"\n * }\n */\ntype RequiredOptions<\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n> = {\n [K in keyof V as K extends OptionalVariantNames<C>\n ? never\n : K]: OptionsOf<V>[K];\n};\n\n/**\n * Utility type to extract the possible options.\n * Converts \"true\" | \"false\" options into booleans.\n *\n * @example\n * OptionsOf<{\n * size: { small: \"text-xs\"; large: \"text-lg\" };\n * rounded: { true: \"rounded-full\" }\n * }>\n * ==>\n * {\n * size: \"text-xs\" | \"text-lg\";\n * rounded: boolean;\n * }\n */\ntype OptionsOf<V extends Variants> = {\n [K in keyof V]: keyof V[K] extends \"true\" | \"false\" ? boolean : keyof V[K];\n};\n\n/**\n * Extracts the possible options.\n */\nexport type VariantOptions<\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n> = RequiredOptions<C> & OptionalOptions<C>;\n\n/**\n * Without this conversion step, defaultVariants and compoundVariants will\n * allow extra keys, i.e. non-existent variants.\n * See https://github.com/sindresorhus/type-fest/blob/main/source/simplify.d.ts\n */\nexport type Simplify<T> = {\n [K in keyof T]: T[K];\n};\n\nexport function variants<\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n>(config: Simplify<C>) {\n const { base, variants, compoundVariants, defaultVariants } = config;\n\n const isBooleanVariant = (name: keyof V) => {\n const v = variants?.[name];\n return v && (\"false\" in v || \"true\" in v);\n };\n\n return (props: VariantOptions<C>) => {\n const res = [base];\n\n const getSelected = (name: keyof V) =>\n (props as any)[name] ??\n defaultVariants?.[name] ??\n (isBooleanVariant(name) ? false : undefined);\n\n for (let name in variants) {\n const selected = getSelected(name);\n if (selected !== undefined) res.push(variants[name]?.[selected]);\n }\n\n for (let { variants, className } of compoundVariants ?? []) {\n const isSelected = (name: string) => getSelected(name) === variants[name];\n if (Object.keys(variants).every(isSelected)) {\n res.push(className);\n }\n }\n return res.filter(Boolean).join(\" \");\n };\n}\n\n/**\n * Utility type to infer the first argument of a variantProps function.\n */\nexport type VariantPropsOf<T> = T extends (props: infer P) => any ? P : never;\n\n/**\n * Type for the variantProps() argument – consists of the VariantOptions and an optional className for chaining.\n */\ntype VariantProps<\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n> = VariantOptions<C> & { className?: string };\n\nexport function variantProps<\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n>(config: Simplify<C>) {\n const variantClassName = variants<C>(config);\n return <P extends VariantProps<C>>(props: P) => {\n const result: any = {};\n\n // Pass-through all unrelated props\n for (let prop in props) {\n if (config.variants && !(prop in config.variants)) {\n result[prop] = props[prop];\n }\n }\n\n // Add the optionally passed className prop for chaining\n result.className = [props.className, variantClassName(props)]\n .filter(Boolean)\n .join(\" \");\n\n return result as { className: string } & Omit<P, keyof C[\"variants\"]>;\n };\n}\n\ntype AsProps<T extends ElementType = ElementType> = {\n as?: T;\n};\n\ntype PolymorphicComponentProps<T extends ElementType> = AsProps<T> &\n Omit<ComponentProps<T>, \"as\">;\n\nexport function styled<\n T extends ElementType,\n C extends VariantsConfig<V>,\n V extends Variants = C[\"variants\"]\n>(type: T, config: string | Simplify<C>) {\n const styledProps =\n typeof config === \"string\"\n ? variantProps({ base: config, variants: {} })\n : variantProps(config);\n\n const Component: <As extends ElementType = T>(\n props: PolymorphicComponentProps<As> & VariantOptions<C>\n // eslint-disable-next-line react/display-name\n ) => ReactElement | null = forwardRef(\n ({ as, ...props }: AsProps, ref: Ref<Element>) => {\n return createElement(as ?? type, { ...styledProps(props), ref });\n }\n );\n return Component;\n}\n","import * as React from \"react\";\nimport { VariantPropsOf, variantProps } from \"./variants\";\n\nconst buttonProps = variantProps({\n base: \"rounded-full font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2\",\n variants: {\n color: {\n default: \"focus-visible:outline-indigo-600\",\n primary: \"focus-visible:outline-green-600\",\n warning: \"focus-visible:outline-orange-600\",\n danger: \"focus-visible:outline-red-600\",\n },\n size: {\n xs: \"px-2.5 py-1 text-xs\",\n sm: \"px-2.5 py-1 text-sm\",\n md: \"px-3 py-1.5 text-sm\",\n lg: \"px-3.5 py-2 text-sm\",\n xl: \"px-4 py-2.5 text-sm\",\n },\n disabled: {\n true: \"cursor-not-allowed opacity-50\",\n },\n type: {\n outline: \"ring-1 ring-inset bg-white shadow-sm\",\n solid: \"text-white shadow-sm\",\n link: \"hover:underline bg-white\",\n },\n },\n compoundVariants: [\n {\n variants: {\n color: \"default\",\n type: \"solid\",\n },\n className: \"bg-indigo-600 hover:bg-indigo-500\",\n },\n {\n variants: {\n color: \"primary\",\n type: \"solid\",\n },\n className: \"bg-green-600 hover:bg-green-500\",\n },\n {\n variants: {\n color: \"warning\",\n type: \"solid\",\n },\n className: \"bg-orange-600 hover:bg-orange-500\",\n },\n {\n variants: {\n color: \"danger\",\n type: \"solid\",\n },\n className: \"bg-red-600 hover:bg-red-500\",\n },\n {\n variants: {\n color: \"default\",\n type: \"outline\",\n },\n className: \"text-indigo-600 ring-indigo-600 hover:bg-indigo-50\",\n },\n {\n variants: {\n color: \"primary\",\n type: \"outline\",\n },\n className: \"ring-green-600 hover:bg-green-50\",\n },\n {\n variants: {\n color: \"warning\",\n type: \"outline\",\n },\n className: \"ring-orange-600 hover:bg-orange-50\",\n },\n {\n variants: {\n color: \"danger\",\n type: \"outline\",\n },\n className: \"ring-red-600 hover:bg-red-50\",\n },\n {\n variants: {\n color: \"default\",\n type: \"link\",\n },\n className: \"text-indigo-600\",\n },\n {\n variants: {\n color: \"primary\",\n type: \"link\",\n },\n className: \"ring-green-600\",\n },\n {\n variants: {\n color: \"warning\",\n type: \"link\",\n },\n className: \"ring-orange-600\",\n },\n {\n variants: {\n color: \"danger\",\n type: \"link\",\n },\n className: \"ring-red-600\",\n },\n ],\n defaultVariants: {\n color: \"default\",\n size: \"md\",\n disabled: false,\n type: \"solid\",\n },\n});\n\ntype Props = JSX.IntrinsicElements[\"button\"] &\n VariantPropsOf<typeof buttonProps>;\n\nexport function Button(props: Props) {\n return <button {...buttonProps(props)} />;\n}\n\n// Set display name so that correct component name shows up in DevTools / Storybook.\nButton.displayName = \"Button\";\n"]}
|