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.
Files changed (65) hide show
  1. package/.turbo/turbo-build.log +47 -14
  2. package/CHANGELOG.md +12 -0
  3. package/dist/button.d.ts +9 -0
  4. package/dist/button.mjs +4 -0
  5. package/dist/chunk-3SV266EG.mjs +8 -0
  6. package/dist/chunk-3SV266EG.mjs.map +1 -0
  7. package/dist/chunk-5PBKUEAL.mjs +9 -0
  8. package/dist/chunk-5PBKUEAL.mjs.map +1 -0
  9. package/dist/chunk-7LHL2LAJ.mjs +7 -0
  10. package/dist/chunk-7LHL2LAJ.mjs.map +1 -0
  11. package/dist/chunk-FRIXS4BL.mjs +7 -0
  12. package/dist/chunk-FRIXS4BL.mjs.map +1 -0
  13. package/dist/chunk-G676EBCC.mjs +10 -0
  14. package/dist/chunk-G676EBCC.mjs.map +1 -0
  15. package/dist/chunk-PLYG34XT.mjs +8 -0
  16. package/dist/chunk-PLYG34XT.mjs.map +1 -0
  17. package/dist/chunk-Q6W42FIC.mjs +11 -0
  18. package/dist/chunk-Q6W42FIC.mjs.map +1 -0
  19. package/dist/chunk-RUPJ2ZHA.mjs +5 -0
  20. package/dist/chunk-RUPJ2ZHA.mjs.map +1 -0
  21. package/dist/chunk-ZIAMSFEI.mjs +18 -0
  22. package/dist/chunk-ZIAMSFEI.mjs.map +1 -0
  23. package/dist/ekm-logo.d.ts +5 -0
  24. package/dist/ekm-logo.mjs +4 -0
  25. package/dist/ekm-logo.mjs.map +1 -0
  26. package/dist/footer-heart-icon.d.ts +3 -0
  27. package/dist/footer-heart-icon.mjs +4 -0
  28. package/dist/footer-heart-icon.mjs.map +1 -0
  29. package/dist/form-row.d.ts +10 -0
  30. package/dist/form-row.mjs +4 -0
  31. package/dist/form-row.mjs.map +1 -0
  32. package/dist/index.css +1 -1
  33. package/dist/index.css.map +1 -1
  34. package/dist/index.d.ts +7 -1
  35. package/dist/index.mjs +9 -1
  36. package/dist/love-footer.d.ts +3 -0
  37. package/dist/love-footer.mjs +5 -0
  38. package/dist/love-footer.mjs.map +1 -0
  39. package/dist/navbar/navbar.d.ts +9 -0
  40. package/dist/navbar/navbar.mjs +6 -0
  41. package/dist/navbar/navbar.mjs.map +1 -0
  42. package/dist/sidebar/sidebar.d.ts +7 -0
  43. package/dist/sidebar/sidebar.mjs +5 -0
  44. package/dist/sidebar/sidebar.mjs.map +1 -0
  45. package/images/ekm-logo.svg +12 -0
  46. package/images/run_workflow.jpg +0 -0
  47. package/package.json +8 -1
  48. package/readme.md +31 -0
  49. package/src/button.tsx +38 -0
  50. package/src/ekm-logo.tsx +37 -0
  51. package/src/footer-heart-icon.tsx +13 -0
  52. package/src/form-row.tsx +30 -0
  53. package/src/helpers/is-browser.ts +5 -0
  54. package/src/helpers/is-small-screen.ts +7 -0
  55. package/src/index.tsx +5 -2
  56. package/src/love-footer.tsx +11 -0
  57. package/src/navbar/navbar.tsx +526 -0
  58. package/src/sidebar/sidebar.tsx +48 -0
  59. package/tsconfig.json +3 -0
  60. package/dist/Button.d.ts +0 -22
  61. package/dist/Button.mjs +0 -3
  62. package/dist/chunk-57QDDOX4.mjs +0 -8
  63. package/dist/chunk-57QDDOX4.mjs.map +0 -1
  64. package/src/Button.tsx +0 -131
  65. /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&nbsp;
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
+ &nbsp;and&nbsp;
201
+ <span className="font-medium text-gray-900 dark:text-white">
202
+ 5 others
203
+ </span>
204
+ &nbsp;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
+ &nbsp;and&nbsp;
231
+ <span className="font-medium text-gray-900 dark:text-white">
232
+ 141 others
233
+ </span>
234
+ &nbsp;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
+ &nbsp;mentioned you in a comment:&nbsp;
261
+ <span className="font-medium text-primary-700 dark:text-primary-500">
262
+ @bonnie.green
263
+ </span>
264
+ &nbsp;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
+ &nbsp;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
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "extends": "tsconfig/react-library.json",
3
3
  "include": ["."],
4
+ "compilerOptions": {
5
+ "lib": ["dom"]
6
+ },
4
7
  "exclude": ["dist", "build", "node_modules"]
5
8
  }
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
@@ -1,3 +0,0 @@
1
- export { a as Button } from './chunk-57QDDOX4.mjs';
2
- //# sourceMappingURL=out.js.map
3
- //# sourceMappingURL=Button.mjs.map
@@ -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"]}