uibee 1.4.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +2 -10
- package/dist/globals.css +430 -0
- package/dist/src/components/index.d.ts +3 -0
- package/dist/src/components/index.js +4 -0
- package/dist/src/components/inputs/erase.d.ts +3 -0
- package/dist/src/components/inputs/erase.js +5 -0
- package/dist/src/components/inputs/input.d.ts +14 -0
- package/dist/src/components/inputs/input.js +11 -0
- package/dist/src/components/inputs/label.d.ts +10 -0
- package/dist/src/components/inputs/label.js +13 -0
- package/dist/src/components/inputs/switch.d.ts +10 -0
- package/dist/src/components/inputs/switch.js +7 -0
- package/dist/src/components/inputs/tag.d.ts +11 -0
- package/dist/src/components/inputs/tag.js +44 -0
- package/dist/src/components/inputs/tooltip.d.ts +4 -0
- package/dist/src/components/inputs/tooltip.js +4 -0
- package/package.json +1 -1
- package/src/components/index.ts +6 -1
- package/src/components/inputs/erase.tsx +13 -0
- package/src/components/inputs/input.tsx +52 -0
- package/src/components/inputs/label.tsx +31 -0
- package/src/components/inputs/switch.tsx +39 -0
- package/src/components/inputs/tag.tsx +137 -0
- package/src/components/inputs/tooltip.tsx +12 -0
package/Readme.md
CHANGED
|
@@ -3,21 +3,13 @@
|
|
|
3
3
|
|
|
4
4
|
This package includes shared components, functions and hooks for reuse across Login projects.
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## Getting Started
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
|
-
# Clone the repository
|
|
10
|
-
git clone git@github.com:Login-Linjeforening-for-IT/uibee.git
|
|
11
|
-
cd uibee
|
|
12
|
-
|
|
13
9
|
# Install dependencies
|
|
14
10
|
npm install
|
|
15
|
-
```
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
# Start the development server
|
|
12
|
+
# Build the project
|
|
21
13
|
npm run build
|
|
22
14
|
```
|
|
23
15
|
|
package/dist/globals.css
CHANGED
|
@@ -8,10 +8,14 @@
|
|
|
8
8
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
9
9
|
"Courier New", monospace;
|
|
10
10
|
--color-red-300: oklch(80.8% 0.114 19.571);
|
|
11
|
+
--color-red-500: oklch(63.7% 0.237 25.331);
|
|
12
|
+
--color-red-700: oklch(50.5% 0.213 27.518);
|
|
13
|
+
--color-red-800: oklch(44.4% 0.177 26.899);
|
|
11
14
|
--color-yellow-300: oklch(90.5% 0.182 98.111);
|
|
12
15
|
--color-green-300: oklch(87.1% 0.15 154.449);
|
|
13
16
|
--color-blue-300: oklch(80.9% 0.105 251.813);
|
|
14
17
|
--spacing: 0.25rem;
|
|
18
|
+
--container-3xs: 16rem;
|
|
15
19
|
--container-xs: 20rem;
|
|
16
20
|
--container-sm: 24rem;
|
|
17
21
|
--container-md: 28rem;
|
|
@@ -25,6 +29,8 @@
|
|
|
25
29
|
--font-weight-bold: 700;
|
|
26
30
|
--font-weight-extrabold: 800;
|
|
27
31
|
--tracking-tight: -0.025em;
|
|
32
|
+
--radius-sm: 0.25rem;
|
|
33
|
+
--radius-md: 0.375rem;
|
|
28
34
|
--radius-lg: 0.5rem;
|
|
29
35
|
--radius-xl: 0.75rem;
|
|
30
36
|
--default-transition-duration: 150ms;
|
|
@@ -36,6 +42,7 @@
|
|
|
36
42
|
--color-login-800: #181818;
|
|
37
43
|
--color-login-700: #1a1a1a;
|
|
38
44
|
--color-login-600: #212121;
|
|
45
|
+
--color-login-200: #727272;
|
|
39
46
|
--color-login-100: #b0b0b0;
|
|
40
47
|
--color-login-50: #ededed;
|
|
41
48
|
}
|
|
@@ -189,18 +196,65 @@
|
|
|
189
196
|
}
|
|
190
197
|
}
|
|
191
198
|
@layer utilities {
|
|
199
|
+
.pointer-events-none {
|
|
200
|
+
pointer-events: none;
|
|
201
|
+
}
|
|
202
|
+
.sr-only {
|
|
203
|
+
position: absolute;
|
|
204
|
+
width: 1px;
|
|
205
|
+
height: 1px;
|
|
206
|
+
padding: 0;
|
|
207
|
+
margin: -1px;
|
|
208
|
+
overflow: hidden;
|
|
209
|
+
clip-path: inset(50%);
|
|
210
|
+
white-space: nowrap;
|
|
211
|
+
border-width: 0;
|
|
212
|
+
}
|
|
213
|
+
.absolute {
|
|
214
|
+
position: absolute;
|
|
215
|
+
}
|
|
192
216
|
.fixed {
|
|
193
217
|
position: fixed;
|
|
194
218
|
}
|
|
195
219
|
.relative {
|
|
196
220
|
position: relative;
|
|
197
221
|
}
|
|
222
|
+
.start-2 {
|
|
223
|
+
inset-inline-start: calc(var(--spacing) * 2);
|
|
224
|
+
}
|
|
225
|
+
.top-1\/2 {
|
|
226
|
+
top: calc(1/2 * 100%);
|
|
227
|
+
}
|
|
228
|
+
.top-2 {
|
|
229
|
+
top: calc(var(--spacing) * 2);
|
|
230
|
+
}
|
|
231
|
+
.right-0 {
|
|
232
|
+
right: calc(var(--spacing) * 0);
|
|
233
|
+
}
|
|
234
|
+
.right-1 {
|
|
235
|
+
right: calc(var(--spacing) * 1);
|
|
236
|
+
}
|
|
198
237
|
.right-4 {
|
|
199
238
|
right: calc(var(--spacing) * 4);
|
|
200
239
|
}
|
|
201
240
|
.bottom-4 {
|
|
202
241
|
bottom: calc(var(--spacing) * 4);
|
|
203
242
|
}
|
|
243
|
+
.left-2 {
|
|
244
|
+
left: calc(var(--spacing) * 2);
|
|
245
|
+
}
|
|
246
|
+
.left-12 {
|
|
247
|
+
left: calc(var(--spacing) * 12);
|
|
248
|
+
}
|
|
249
|
+
.z-10 {
|
|
250
|
+
z-index: 10;
|
|
251
|
+
}
|
|
252
|
+
.z-19 {
|
|
253
|
+
z-index: 19;
|
|
254
|
+
}
|
|
255
|
+
.z-20 {
|
|
256
|
+
z-index: 20;
|
|
257
|
+
}
|
|
204
258
|
.z-50 {
|
|
205
259
|
z-index: 50;
|
|
206
260
|
}
|
|
@@ -210,21 +264,36 @@
|
|
|
210
264
|
.mb-2 {
|
|
211
265
|
margin-bottom: calc(var(--spacing) * 2);
|
|
212
266
|
}
|
|
267
|
+
.ml-1 {
|
|
268
|
+
margin-left: calc(var(--spacing) * 1);
|
|
269
|
+
}
|
|
270
|
+
.ml-3 {
|
|
271
|
+
margin-left: calc(var(--spacing) * 3);
|
|
272
|
+
}
|
|
213
273
|
.line-clamp-3 {
|
|
214
274
|
overflow: hidden;
|
|
215
275
|
display: -webkit-box;
|
|
216
276
|
-webkit-box-orient: vertical;
|
|
217
277
|
-webkit-line-clamp: 3;
|
|
218
278
|
}
|
|
279
|
+
.block {
|
|
280
|
+
display: block;
|
|
281
|
+
}
|
|
219
282
|
.flex {
|
|
220
283
|
display: flex;
|
|
221
284
|
}
|
|
285
|
+
.hidden {
|
|
286
|
+
display: none;
|
|
287
|
+
}
|
|
222
288
|
.inline {
|
|
223
289
|
display: inline;
|
|
224
290
|
}
|
|
225
291
|
.aspect-\[3\/1\] {
|
|
226
292
|
aspect-ratio: 3/1;
|
|
227
293
|
}
|
|
294
|
+
.h-4 {
|
|
295
|
+
height: calc(var(--spacing) * 4);
|
|
296
|
+
}
|
|
228
297
|
.h-6 {
|
|
229
298
|
height: calc(var(--spacing) * 6);
|
|
230
299
|
}
|
|
@@ -234,36 +303,96 @@
|
|
|
234
303
|
.min-h-screen {
|
|
235
304
|
min-height: 100vh;
|
|
236
305
|
}
|
|
306
|
+
.w-4 {
|
|
307
|
+
width: calc(var(--spacing) * 4);
|
|
308
|
+
}
|
|
309
|
+
.w-5 {
|
|
310
|
+
width: calc(var(--spacing) * 5);
|
|
311
|
+
}
|
|
237
312
|
.w-6 {
|
|
238
313
|
width: calc(var(--spacing) * 6);
|
|
239
314
|
}
|
|
240
315
|
.w-10 {
|
|
241
316
|
width: calc(var(--spacing) * 10);
|
|
242
317
|
}
|
|
318
|
+
.w-\[calc\(100\%-10px\)\] {
|
|
319
|
+
width: calc(100% - 10px);
|
|
320
|
+
}
|
|
321
|
+
.w-fit {
|
|
322
|
+
width: fit-content;
|
|
323
|
+
}
|
|
243
324
|
.w-full {
|
|
244
325
|
width: 100%;
|
|
245
326
|
}
|
|
327
|
+
.w-max {
|
|
328
|
+
width: max-content;
|
|
329
|
+
}
|
|
246
330
|
.w-sm {
|
|
247
331
|
width: var(--container-sm);
|
|
248
332
|
}
|
|
333
|
+
.max-w-3xs {
|
|
334
|
+
max-width: var(--container-3xs);
|
|
335
|
+
}
|
|
249
336
|
.max-w-md {
|
|
250
337
|
max-width: var(--container-md);
|
|
251
338
|
}
|
|
252
339
|
.max-w-xs {
|
|
253
340
|
max-width: var(--container-xs);
|
|
254
341
|
}
|
|
342
|
+
.min-w-\[6ch\] {
|
|
343
|
+
min-width: 6ch;
|
|
344
|
+
}
|
|
345
|
+
.flex-1 {
|
|
346
|
+
flex: 1;
|
|
347
|
+
}
|
|
255
348
|
.flex-shrink-0 {
|
|
256
349
|
flex-shrink: 0;
|
|
257
350
|
}
|
|
351
|
+
.origin-\[0\] {
|
|
352
|
+
transform-origin: 0;
|
|
353
|
+
}
|
|
354
|
+
.translate-x-4 {
|
|
355
|
+
--tw-translate-x: calc(var(--spacing) * 4);
|
|
356
|
+
translate: var(--tw-translate-x) var(--tw-translate-y);
|
|
357
|
+
}
|
|
358
|
+
.-translate-y-1\/2 {
|
|
359
|
+
--tw-translate-y: calc(calc(1/2 * 100%) * -1);
|
|
360
|
+
translate: var(--tw-translate-x) var(--tw-translate-y);
|
|
361
|
+
}
|
|
362
|
+
.-translate-y-5 {
|
|
363
|
+
--tw-translate-y: calc(var(--spacing) * -5);
|
|
364
|
+
translate: var(--tw-translate-x) var(--tw-translate-y);
|
|
365
|
+
}
|
|
366
|
+
.scale-75 {
|
|
367
|
+
--tw-scale-x: 75%;
|
|
368
|
+
--tw-scale-y: 75%;
|
|
369
|
+
--tw-scale-z: 75%;
|
|
370
|
+
scale: var(--tw-scale-x) var(--tw-scale-y);
|
|
371
|
+
}
|
|
372
|
+
.scale-100 {
|
|
373
|
+
--tw-scale-x: 100%;
|
|
374
|
+
--tw-scale-y: 100%;
|
|
375
|
+
--tw-scale-z: 100%;
|
|
376
|
+
scale: var(--tw-scale-x) var(--tw-scale-y);
|
|
377
|
+
}
|
|
258
378
|
.transform {
|
|
259
379
|
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
|
|
260
380
|
}
|
|
381
|
+
.cursor-pointer {
|
|
382
|
+
cursor: pointer;
|
|
383
|
+
}
|
|
384
|
+
.appearance-none {
|
|
385
|
+
appearance: none;
|
|
386
|
+
}
|
|
261
387
|
.flex-col {
|
|
262
388
|
flex-direction: column;
|
|
263
389
|
}
|
|
264
390
|
.flex-col-reverse {
|
|
265
391
|
flex-direction: column-reverse;
|
|
266
392
|
}
|
|
393
|
+
.flex-wrap {
|
|
394
|
+
flex-wrap: wrap;
|
|
395
|
+
}
|
|
267
396
|
.items-center {
|
|
268
397
|
align-items: center;
|
|
269
398
|
}
|
|
@@ -273,6 +402,12 @@
|
|
|
273
402
|
.justify-center {
|
|
274
403
|
justify-content: center;
|
|
275
404
|
}
|
|
405
|
+
.gap-0\.5 {
|
|
406
|
+
gap: calc(var(--spacing) * 0.5);
|
|
407
|
+
}
|
|
408
|
+
.gap-1 {
|
|
409
|
+
gap: calc(var(--spacing) * 1);
|
|
410
|
+
}
|
|
276
411
|
.gap-2 {
|
|
277
412
|
gap: calc(var(--spacing) * 2);
|
|
278
413
|
}
|
|
@@ -282,18 +417,49 @@
|
|
|
282
417
|
.gap-4 {
|
|
283
418
|
gap: calc(var(--spacing) * 4);
|
|
284
419
|
}
|
|
420
|
+
.truncate {
|
|
421
|
+
overflow: hidden;
|
|
422
|
+
text-overflow: ellipsis;
|
|
423
|
+
white-space: nowrap;
|
|
424
|
+
}
|
|
285
425
|
.rounded {
|
|
286
426
|
border-radius: 0.25rem;
|
|
287
427
|
}
|
|
428
|
+
.rounded-full {
|
|
429
|
+
border-radius: calc(infinity * 1px);
|
|
430
|
+
}
|
|
288
431
|
.rounded-lg {
|
|
289
432
|
border-radius: var(--radius-lg);
|
|
290
433
|
}
|
|
434
|
+
.rounded-md {
|
|
435
|
+
border-radius: var(--radius-md);
|
|
436
|
+
}
|
|
437
|
+
.rounded-sm {
|
|
438
|
+
border-radius: var(--radius-sm);
|
|
439
|
+
}
|
|
291
440
|
.rounded-xl {
|
|
292
441
|
border-radius: var(--radius-xl);
|
|
293
442
|
}
|
|
443
|
+
.border {
|
|
444
|
+
border-style: var(--tw-border-style);
|
|
445
|
+
border-width: 1px;
|
|
446
|
+
}
|
|
447
|
+
.border-\[0\.10rem\] {
|
|
448
|
+
border-style: var(--tw-border-style);
|
|
449
|
+
border-width: 0.10rem;
|
|
450
|
+
}
|
|
451
|
+
.border-login-200 {
|
|
452
|
+
border-color: var(--color-login-200);
|
|
453
|
+
}
|
|
294
454
|
.bg-login {
|
|
295
455
|
background-color: var(--color-login);
|
|
296
456
|
}
|
|
457
|
+
.bg-login-50 {
|
|
458
|
+
background-color: var(--color-login-50);
|
|
459
|
+
}
|
|
460
|
+
.bg-login-200 {
|
|
461
|
+
background-color: var(--color-login-200);
|
|
462
|
+
}
|
|
297
463
|
.bg-login-600 {
|
|
298
464
|
background-color: var(--color-login-600);
|
|
299
465
|
}
|
|
@@ -306,15 +472,33 @@
|
|
|
306
472
|
.bg-login-900 {
|
|
307
473
|
background-color: var(--color-login-900);
|
|
308
474
|
}
|
|
475
|
+
.bg-transparent {
|
|
476
|
+
background-color: transparent;
|
|
477
|
+
}
|
|
478
|
+
.stroke-3 {
|
|
479
|
+
stroke-width: 3;
|
|
480
|
+
}
|
|
309
481
|
.object-contain {
|
|
310
482
|
object-fit: contain;
|
|
311
483
|
}
|
|
484
|
+
.p-1 {
|
|
485
|
+
padding: calc(var(--spacing) * 1);
|
|
486
|
+
}
|
|
312
487
|
.p-2 {
|
|
313
488
|
padding: calc(var(--spacing) * 2);
|
|
314
489
|
}
|
|
315
490
|
.p-8 {
|
|
316
491
|
padding: calc(var(--spacing) * 8);
|
|
317
492
|
}
|
|
493
|
+
.px-1 {
|
|
494
|
+
padding-inline: calc(var(--spacing) * 1);
|
|
495
|
+
}
|
|
496
|
+
.px-2 {
|
|
497
|
+
padding-inline: calc(var(--spacing) * 2);
|
|
498
|
+
}
|
|
499
|
+
.px-2\.5 {
|
|
500
|
+
padding-inline: calc(var(--spacing) * 2.5);
|
|
501
|
+
}
|
|
318
502
|
.px-3 {
|
|
319
503
|
padding-inline: calc(var(--spacing) * 3);
|
|
320
504
|
}
|
|
@@ -324,6 +508,12 @@
|
|
|
324
508
|
.px-6 {
|
|
325
509
|
padding-inline: calc(var(--spacing) * 6);
|
|
326
510
|
}
|
|
511
|
+
.py-0\.5 {
|
|
512
|
+
padding-block: calc(var(--spacing) * 0.5);
|
|
513
|
+
}
|
|
514
|
+
.py-1 {
|
|
515
|
+
padding-block: calc(var(--spacing) * 1);
|
|
516
|
+
}
|
|
327
517
|
.py-2 {
|
|
328
518
|
padding-block: calc(var(--spacing) * 2);
|
|
329
519
|
}
|
|
@@ -333,12 +523,24 @@
|
|
|
333
523
|
.py-12 {
|
|
334
524
|
padding-block: calc(var(--spacing) * 12);
|
|
335
525
|
}
|
|
526
|
+
.pt-1 {
|
|
527
|
+
padding-top: calc(var(--spacing) * 1);
|
|
528
|
+
}
|
|
529
|
+
.pt-3 {
|
|
530
|
+
padding-top: calc(var(--spacing) * 3);
|
|
531
|
+
}
|
|
532
|
+
.pt-4 {
|
|
533
|
+
padding-top: calc(var(--spacing) * 4);
|
|
534
|
+
}
|
|
336
535
|
.pr-1 {
|
|
337
536
|
padding-right: calc(var(--spacing) * 1);
|
|
338
537
|
}
|
|
339
538
|
.pb-1 {
|
|
340
539
|
padding-bottom: calc(var(--spacing) * 1);
|
|
341
540
|
}
|
|
541
|
+
.pb-2\.5 {
|
|
542
|
+
padding-bottom: calc(var(--spacing) * 2.5);
|
|
543
|
+
}
|
|
342
544
|
.text-center {
|
|
343
545
|
text-align: center;
|
|
344
546
|
}
|
|
@@ -397,12 +599,30 @@
|
|
|
397
599
|
color: color-mix(in oklab, var(--color-red-300) 70%, transparent);
|
|
398
600
|
}
|
|
399
601
|
}
|
|
602
|
+
.text-red-500\/50 {
|
|
603
|
+
color: color-mix(in srgb, oklch(63.7% 0.237 25.331) 50%, transparent);
|
|
604
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
605
|
+
color: color-mix(in oklab, var(--color-red-500) 50%, transparent);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
.text-red-700 {
|
|
609
|
+
color: var(--color-red-700);
|
|
610
|
+
}
|
|
400
611
|
.text-yellow-300\/70 {
|
|
401
612
|
color: color-mix(in srgb, oklch(90.5% 0.182 98.111) 70%, transparent);
|
|
402
613
|
@supports (color: color-mix(in lab, red, red)) {
|
|
403
614
|
color: color-mix(in oklab, var(--color-yellow-300) 70%, transparent);
|
|
404
615
|
}
|
|
405
616
|
}
|
|
617
|
+
.shadow-md {
|
|
618
|
+
--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
619
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
620
|
+
}
|
|
621
|
+
.transition {
|
|
622
|
+
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
|
|
623
|
+
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
624
|
+
transition-duration: var(--tw-duration, var(--default-transition-duration));
|
|
625
|
+
}
|
|
406
626
|
.transition-all {
|
|
407
627
|
transition-property: all;
|
|
408
628
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
|
@@ -412,6 +632,71 @@
|
|
|
412
632
|
--tw-duration: 200ms;
|
|
413
633
|
transition-duration: 200ms;
|
|
414
634
|
}
|
|
635
|
+
.duration-300 {
|
|
636
|
+
--tw-duration: 300ms;
|
|
637
|
+
transition-duration: 300ms;
|
|
638
|
+
}
|
|
639
|
+
.outline-none {
|
|
640
|
+
--tw-outline-style: none;
|
|
641
|
+
outline-style: none;
|
|
642
|
+
}
|
|
643
|
+
.group-\[\.submitPressed\]\:text-red-500\/50 {
|
|
644
|
+
&:is(:where(.group):is(.submitPressed) *) {
|
|
645
|
+
color: color-mix(in srgb, oklch(63.7% 0.237 25.331) 50%, transparent);
|
|
646
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
647
|
+
color: color-mix(in oklab, var(--color-red-500) 50%, transparent);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
.peer-hover\:block {
|
|
652
|
+
&:is(:where(.peer):hover ~ *) {
|
|
653
|
+
@media (hover: hover) {
|
|
654
|
+
display: block;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
.peer-focus\:top-2 {
|
|
659
|
+
&:is(:where(.peer):focus ~ *) {
|
|
660
|
+
top: calc(var(--spacing) * 2);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
.peer-focus\:w-fit {
|
|
664
|
+
&:is(:where(.peer):focus ~ *) {
|
|
665
|
+
width: fit-content;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
.peer-focus\:-translate-y-5 {
|
|
669
|
+
&:is(:where(.peer):focus ~ *) {
|
|
670
|
+
--tw-translate-y: calc(var(--spacing) * -5);
|
|
671
|
+
translate: var(--tw-translate-x) var(--tw-translate-y);
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
.peer-focus\:scale-75 {
|
|
675
|
+
&:is(:where(.peer):focus ~ *) {
|
|
676
|
+
--tw-scale-x: 75%;
|
|
677
|
+
--tw-scale-y: 75%;
|
|
678
|
+
--tw-scale-z: 75%;
|
|
679
|
+
scale: var(--tw-scale-x) var(--tw-scale-y);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
.peer-focus\:px-2 {
|
|
683
|
+
&:is(:where(.peer):focus ~ *) {
|
|
684
|
+
padding-inline: calc(var(--spacing) * 2);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
.after\:content-\[\"_\*\"\] {
|
|
688
|
+
&::after {
|
|
689
|
+
--tw-content: " *";
|
|
690
|
+
content: var(--tw-content);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
.hover\:bg-login-600 {
|
|
694
|
+
&:hover {
|
|
695
|
+
@media (hover: hover) {
|
|
696
|
+
background-color: var(--color-login-600);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
415
700
|
.hover\:bg-login\/80 {
|
|
416
701
|
&:hover {
|
|
417
702
|
@media (hover: hover) {
|
|
@@ -422,6 +707,24 @@
|
|
|
422
707
|
}
|
|
423
708
|
}
|
|
424
709
|
}
|
|
710
|
+
.hover\:text-red-800 {
|
|
711
|
+
&:hover {
|
|
712
|
+
@media (hover: hover) {
|
|
713
|
+
color: var(--color-red-800);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
.focus\:border-login-50 {
|
|
718
|
+
&:focus {
|
|
719
|
+
border-color: var(--color-login-50);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
.focus\:ring-0 {
|
|
723
|
+
&:focus {
|
|
724
|
+
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
725
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
425
728
|
.focus\:outline-none {
|
|
426
729
|
&:focus {
|
|
427
730
|
--tw-outline-style: none;
|
|
@@ -480,6 +783,36 @@ body {
|
|
|
480
783
|
background: var(--background);
|
|
481
784
|
font-family: Arial, Helvetica, sans-serif;
|
|
482
785
|
}
|
|
786
|
+
@property --tw-translate-x {
|
|
787
|
+
syntax: "*";
|
|
788
|
+
inherits: false;
|
|
789
|
+
initial-value: 0;
|
|
790
|
+
}
|
|
791
|
+
@property --tw-translate-y {
|
|
792
|
+
syntax: "*";
|
|
793
|
+
inherits: false;
|
|
794
|
+
initial-value: 0;
|
|
795
|
+
}
|
|
796
|
+
@property --tw-translate-z {
|
|
797
|
+
syntax: "*";
|
|
798
|
+
inherits: false;
|
|
799
|
+
initial-value: 0;
|
|
800
|
+
}
|
|
801
|
+
@property --tw-scale-x {
|
|
802
|
+
syntax: "*";
|
|
803
|
+
inherits: false;
|
|
804
|
+
initial-value: 1;
|
|
805
|
+
}
|
|
806
|
+
@property --tw-scale-y {
|
|
807
|
+
syntax: "*";
|
|
808
|
+
inherits: false;
|
|
809
|
+
initial-value: 1;
|
|
810
|
+
}
|
|
811
|
+
@property --tw-scale-z {
|
|
812
|
+
syntax: "*";
|
|
813
|
+
inherits: false;
|
|
814
|
+
initial-value: 1;
|
|
815
|
+
}
|
|
483
816
|
@property --tw-rotate-x {
|
|
484
817
|
syntax: "*";
|
|
485
818
|
inherits: false;
|
|
@@ -500,6 +833,11 @@ body {
|
|
|
500
833
|
syntax: "*";
|
|
501
834
|
inherits: false;
|
|
502
835
|
}
|
|
836
|
+
@property --tw-border-style {
|
|
837
|
+
syntax: "*";
|
|
838
|
+
inherits: false;
|
|
839
|
+
initial-value: solid;
|
|
840
|
+
}
|
|
503
841
|
@property --tw-font-weight {
|
|
504
842
|
syntax: "*";
|
|
505
843
|
inherits: false;
|
|
@@ -508,21 +846,113 @@ body {
|
|
|
508
846
|
syntax: "*";
|
|
509
847
|
inherits: false;
|
|
510
848
|
}
|
|
849
|
+
@property --tw-shadow {
|
|
850
|
+
syntax: "*";
|
|
851
|
+
inherits: false;
|
|
852
|
+
initial-value: 0 0 #0000;
|
|
853
|
+
}
|
|
854
|
+
@property --tw-shadow-color {
|
|
855
|
+
syntax: "*";
|
|
856
|
+
inherits: false;
|
|
857
|
+
}
|
|
858
|
+
@property --tw-shadow-alpha {
|
|
859
|
+
syntax: "<percentage>";
|
|
860
|
+
inherits: false;
|
|
861
|
+
initial-value: 100%;
|
|
862
|
+
}
|
|
863
|
+
@property --tw-inset-shadow {
|
|
864
|
+
syntax: "*";
|
|
865
|
+
inherits: false;
|
|
866
|
+
initial-value: 0 0 #0000;
|
|
867
|
+
}
|
|
868
|
+
@property --tw-inset-shadow-color {
|
|
869
|
+
syntax: "*";
|
|
870
|
+
inherits: false;
|
|
871
|
+
}
|
|
872
|
+
@property --tw-inset-shadow-alpha {
|
|
873
|
+
syntax: "<percentage>";
|
|
874
|
+
inherits: false;
|
|
875
|
+
initial-value: 100%;
|
|
876
|
+
}
|
|
877
|
+
@property --tw-ring-color {
|
|
878
|
+
syntax: "*";
|
|
879
|
+
inherits: false;
|
|
880
|
+
}
|
|
881
|
+
@property --tw-ring-shadow {
|
|
882
|
+
syntax: "*";
|
|
883
|
+
inherits: false;
|
|
884
|
+
initial-value: 0 0 #0000;
|
|
885
|
+
}
|
|
886
|
+
@property --tw-inset-ring-color {
|
|
887
|
+
syntax: "*";
|
|
888
|
+
inherits: false;
|
|
889
|
+
}
|
|
890
|
+
@property --tw-inset-ring-shadow {
|
|
891
|
+
syntax: "*";
|
|
892
|
+
inherits: false;
|
|
893
|
+
initial-value: 0 0 #0000;
|
|
894
|
+
}
|
|
895
|
+
@property --tw-ring-inset {
|
|
896
|
+
syntax: "*";
|
|
897
|
+
inherits: false;
|
|
898
|
+
}
|
|
899
|
+
@property --tw-ring-offset-width {
|
|
900
|
+
syntax: "<length>";
|
|
901
|
+
inherits: false;
|
|
902
|
+
initial-value: 0px;
|
|
903
|
+
}
|
|
904
|
+
@property --tw-ring-offset-color {
|
|
905
|
+
syntax: "*";
|
|
906
|
+
inherits: false;
|
|
907
|
+
initial-value: #fff;
|
|
908
|
+
}
|
|
909
|
+
@property --tw-ring-offset-shadow {
|
|
910
|
+
syntax: "*";
|
|
911
|
+
inherits: false;
|
|
912
|
+
initial-value: 0 0 #0000;
|
|
913
|
+
}
|
|
511
914
|
@property --tw-duration {
|
|
512
915
|
syntax: "*";
|
|
513
916
|
inherits: false;
|
|
514
917
|
}
|
|
918
|
+
@property --tw-content {
|
|
919
|
+
syntax: "*";
|
|
920
|
+
initial-value: "";
|
|
921
|
+
inherits: false;
|
|
922
|
+
}
|
|
515
923
|
@layer properties {
|
|
516
924
|
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
|
517
925
|
*, ::before, ::after, ::backdrop {
|
|
926
|
+
--tw-translate-x: 0;
|
|
927
|
+
--tw-translate-y: 0;
|
|
928
|
+
--tw-translate-z: 0;
|
|
929
|
+
--tw-scale-x: 1;
|
|
930
|
+
--tw-scale-y: 1;
|
|
931
|
+
--tw-scale-z: 1;
|
|
518
932
|
--tw-rotate-x: initial;
|
|
519
933
|
--tw-rotate-y: initial;
|
|
520
934
|
--tw-rotate-z: initial;
|
|
521
935
|
--tw-skew-x: initial;
|
|
522
936
|
--tw-skew-y: initial;
|
|
937
|
+
--tw-border-style: solid;
|
|
523
938
|
--tw-font-weight: initial;
|
|
524
939
|
--tw-tracking: initial;
|
|
940
|
+
--tw-shadow: 0 0 #0000;
|
|
941
|
+
--tw-shadow-color: initial;
|
|
942
|
+
--tw-shadow-alpha: 100%;
|
|
943
|
+
--tw-inset-shadow: 0 0 #0000;
|
|
944
|
+
--tw-inset-shadow-color: initial;
|
|
945
|
+
--tw-inset-shadow-alpha: 100%;
|
|
946
|
+
--tw-ring-color: initial;
|
|
947
|
+
--tw-ring-shadow: 0 0 #0000;
|
|
948
|
+
--tw-inset-ring-color: initial;
|
|
949
|
+
--tw-inset-ring-shadow: 0 0 #0000;
|
|
950
|
+
--tw-ring-inset: initial;
|
|
951
|
+
--tw-ring-offset-width: 0px;
|
|
952
|
+
--tw-ring-offset-color: #fff;
|
|
953
|
+
--tw-ring-offset-shadow: 0 0 #0000;
|
|
525
954
|
--tw-duration: initial;
|
|
955
|
+
--tw-content: "";
|
|
526
956
|
}
|
|
527
957
|
}
|
|
528
958
|
}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
export { default as LoginPage } from './login/loginPage';
|
|
2
2
|
export { default as Toaster, addToast } from './toast/toaster';
|
|
3
|
+
export { default as Input } from './inputs/input';
|
|
4
|
+
export { default as SwitchInput } from './inputs/switch';
|
|
5
|
+
export { default as TagInput } from './inputs/tag';
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export { default as LoginPage } from './login/loginPage';
|
|
2
2
|
export { default as Toaster, addToast } from './toast/toaster';
|
|
3
|
+
// Input components
|
|
4
|
+
export { default as Input } from './inputs/input';
|
|
5
|
+
export { default as SwitchInput } from './inputs/switch';
|
|
6
|
+
export { default as TagInput } from './inputs/tag';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Eraser } from 'lucide-react';
|
|
3
|
+
export default function EraseButton({ setData }) {
|
|
4
|
+
return (_jsx("button", { type: 'button', onClick: () => setData(''), className: 'absolute right-1 cursor-pointer px-2 py-1 bg-login-800 hover:bg-login-600 rounded-md', children: _jsx(Eraser, { className: 'w-5' }) }));
|
|
5
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HTMLInputTypeAttribute } from 'react';
|
|
2
|
+
type InputProps = {
|
|
3
|
+
name: string;
|
|
4
|
+
type: HTMLInputTypeAttribute;
|
|
5
|
+
label: string;
|
|
6
|
+
value?: string | number;
|
|
7
|
+
setValue: (value: string | number) => void;
|
|
8
|
+
className?: string;
|
|
9
|
+
tooltip?: string;
|
|
10
|
+
required?: boolean;
|
|
11
|
+
color?: string;
|
|
12
|
+
};
|
|
13
|
+
export default function Input({ name, type, label, className, tooltip, required, value, setValue, color }: InputProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import ToolTip from './tooltip';
|
|
5
|
+
import Label from './label';
|
|
6
|
+
import EraseButton from './erase';
|
|
7
|
+
export default function Input({ name, type, label, className, tooltip, required, value, setValue, color }) {
|
|
8
|
+
const [hasBlured, setHasBlured] = useState(false);
|
|
9
|
+
return (_jsx("div", { className: `w-full ${className}`, children: _jsxs("div", { className: 'relative flex items-center', children: [_jsx("input", { name: name, type: type, className: 'block bg-login-800 px-2.5 pb-2.5 pt-4 w-full text-sm rounded-lg border-[0.10rem] appearance-none ' +
|
|
10
|
+
'border-login-200 focus:outline-none focus:ring-0 focus:border-login-50 peer', value: value || '', onChange: (e) => setValue(e.target.value), onFocus: (e) => e.target.showPicker(), onBlur: () => setHasBlured(true), placeholder: '', required: required }), _jsx(Label, { label: label, value: value, required: required, color: color, showRequired: required && !value && hasBlured }), value && _jsx(EraseButton, { setData: setValue }), !value && tooltip && _jsx(ToolTip, { info: tooltip })] }) }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type labelProps = {
|
|
2
|
+
label: string;
|
|
3
|
+
value: any;
|
|
4
|
+
required?: boolean;
|
|
5
|
+
showRequired?: boolean;
|
|
6
|
+
className?: string;
|
|
7
|
+
color?: string;
|
|
8
|
+
};
|
|
9
|
+
export default function Label({ label, value, required, showRequired, className, color }: labelProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export default function Label({ label, value, required, showRequired, className, color }) {
|
|
3
|
+
return (_jsx("label", { className: 'w-[calc(100%-10px)] truncate pointer-events-none absolute text-sm duration-300 transform z-10 ' +
|
|
4
|
+
'peer-focus:px-2 peer-focus:top-2 origin-[0] px-2 pt-1 peer-focus:scale-75 peer-focus:-translate-y-5 start-2 ' +
|
|
5
|
+
`${color ? color : 'bg-login-800'} ` +
|
|
6
|
+
`${value ? '-translate-y-5 scale-75 top-2 w-fit '
|
|
7
|
+
: '-translate-y-1/2 scale-100 top-1/2 '
|
|
8
|
+
+ 'peer-focus:w-fit '} ${showRequired ? 'text-red-500/50 ' : ''}
|
|
9
|
+
${!value &&
|
|
10
|
+
required ? 'group-[.submitPressed]:text-red-500/50 ' : ''}
|
|
11
|
+
${required ? 'after:content-["_*"] ' : ''}
|
|
12
|
+
${className}`, children: label }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type SwitchProps = {
|
|
2
|
+
name: string;
|
|
3
|
+
label: string;
|
|
4
|
+
value?: boolean;
|
|
5
|
+
setValue: (_: boolean) => void;
|
|
6
|
+
className?: string;
|
|
7
|
+
tooltip?: string;
|
|
8
|
+
};
|
|
9
|
+
export default function Switch({ name, label, value, className, tooltip, setValue }: SwitchProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import ToolTip from './tooltip';
|
|
4
|
+
export default function Switch({ name, label, value, className, tooltip, setValue }) {
|
|
5
|
+
return (_jsxs("div", { className: `relative w-full flex items-center px-2.5 pb-2.5 pt-3 border-login-200 rounded-lg border-[0.10rem]
|
|
6
|
+
bg-login-800 ${className}`, children: [_jsxs("label", { className: 'flex items-center cursor-pointer', children: [_jsx("input", { type: 'checkbox', name: name, className: 'sr-only', checked: value, onChange: (e) => setValue(e.target.checked) }), _jsx("div", { className: `w-10 h-6 rounded-full p-1 transition ${value ? 'bg-login-50' : 'bg-login-200'}`, children: _jsx("div", { className: `w-4 h-4 bg-login-800 rounded-full shadow-md transform transition ${value ? 'translate-x-4' : ''}` }) })] }), _jsx("span", { className: 'ml-3 text-sm', children: label }), tooltip && _jsx(ToolTip, { info: tooltip })] }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type TagInputProps = {
|
|
2
|
+
name: string;
|
|
3
|
+
label: string;
|
|
4
|
+
value?: string[];
|
|
5
|
+
setValue: (_: string[]) => void;
|
|
6
|
+
className?: string;
|
|
7
|
+
tooltip?: string;
|
|
8
|
+
required?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export default function TagInput({ name, label, value, className, tooltip, required, setValue, }: TagInputProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import ToolTip from './tooltip';
|
|
5
|
+
import Label from './label';
|
|
6
|
+
import EraseButton from './erase';
|
|
7
|
+
import { X } from 'lucide-react';
|
|
8
|
+
export default function TagInput({ name, label, value = [], className, tooltip, required, setValue, }) {
|
|
9
|
+
const original = value;
|
|
10
|
+
const [input, setInput] = useState('');
|
|
11
|
+
const [hasBlured, setHasBlured] = useState(false);
|
|
12
|
+
function addTag(value) {
|
|
13
|
+
const trimmed = value.trim();
|
|
14
|
+
if (trimmed && !value.includes(trimmed)) {
|
|
15
|
+
setValue([...value, trimmed]);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function removeTag(idx) {
|
|
19
|
+
setValue(value.filter((_, i) => i !== idx));
|
|
20
|
+
}
|
|
21
|
+
function handleKeyDown(e) {
|
|
22
|
+
if ((e.key === 'Enter' || e.key === ',' || e.key === 'Tab') &&
|
|
23
|
+
input.trim()) {
|
|
24
|
+
e.preventDefault();
|
|
25
|
+
addTag(input);
|
|
26
|
+
setInput('');
|
|
27
|
+
}
|
|
28
|
+
if (e.key === 'Backspace' && !input && value.length) {
|
|
29
|
+
setValue(value.slice(0, -1));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function handleErase() {
|
|
33
|
+
setValue([]);
|
|
34
|
+
setInput('');
|
|
35
|
+
}
|
|
36
|
+
const toRemove = original.filter((tag) => !value.includes(tag));
|
|
37
|
+
const toAdd = value.filter((tag) => !original.includes(tag));
|
|
38
|
+
return (_jsx("div", { className: `w-full ${className}`, children: _jsxs("div", { className: 'relative flex items-center flex-wrap gap-1 ' +
|
|
39
|
+
'border-[0.10rem] border-login-200 ' +
|
|
40
|
+
'rounded-lg ' +
|
|
41
|
+
'px-2.5 pt-3 pb-2.5 bg-login-800', children: [_jsxs("div", { className: 'flex flex-wrap gap-1 items-center w-full', children: [value.map((tag, idx) => (_jsxs("span", { className: 'bg-login-600 text-sm rounded px-2 ' +
|
|
42
|
+
'py-0.5 flex items-center gap-0.5', children: [tag, _jsx("button", { type: 'button', className: 'ml-1 text-red-700 hover:text-red-800', onClick: () => removeTag(idx), children: _jsx(X, { className: 'h-4 stroke-3' }) })] }, tag + idx))), _jsx("input", { value: input, onChange: (e) => setInput(e.target.value), onKeyDown: handleKeyDown, onBlur: () => setHasBlured(true), className: 'peer flex-1 min-w-[6ch] bg-transparent ' +
|
|
43
|
+
'outline-none text-sm', autoComplete: 'off', required: required && value.length === 0 }), toRemove.map((tag) => (_jsx("input", { type: 'hidden', name: name + '_remove', value: tag }, tag))), toAdd.map((tag) => (_jsx("input", { type: 'hidden', name: name + '_add', value: tag }, tag))), _jsx(Label, { label: label, value: value.length ? value.join(', ') : '', required: required, showRequired: required && value.length === 0 && hasBlured, className: 'pointer-events-none left-2' })] }), value.length > 0 && _jsx(EraseButton, { setData: handleErase }), value.length === 0 && tooltip && _jsx(ToolTip, { info: tooltip })] }) }));
|
|
44
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export default function ToolTip({ info, className }) {
|
|
3
|
+
return (_jsxs("div", { className: `absolute z-19 right-0 px-1 flex justify-center ${className}`, children: [_jsx("span", { className: 'peer cursor-pointer rounded-sm px-3 py-1 bg-login-800 hover:bg-login-600', children: "?" }), _jsx("div", { className: 'absolute hidden peer-hover:block p-2 rounded z-20 bg-login-700 border left-12 w-max max-w-3xs', children: info })] }));
|
|
4
|
+
}
|
package/package.json
CHANGED
package/src/components/index.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
export { default as LoginPage } from './login/loginPage'
|
|
2
|
-
export { default as Toaster, addToast } from './toast/toaster'
|
|
2
|
+
export { default as Toaster, addToast } from './toast/toaster'
|
|
3
|
+
|
|
4
|
+
// Input components
|
|
5
|
+
export { default as Input } from './inputs/input'
|
|
6
|
+
export { default as SwitchInput } from './inputs/switch'
|
|
7
|
+
export { default as TagInput } from './inputs/tag'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Eraser } from 'lucide-react'
|
|
2
|
+
|
|
3
|
+
export default function EraseButton({ setData }: { setData: (data: string) => void }) {
|
|
4
|
+
return (
|
|
5
|
+
<button
|
|
6
|
+
type='button'
|
|
7
|
+
onClick={() => setData('')}
|
|
8
|
+
className={'absolute right-1 cursor-pointer px-2 py-1 bg-login-800 hover:bg-login-600 rounded-md'}
|
|
9
|
+
>
|
|
10
|
+
<Eraser className='w-5' />
|
|
11
|
+
</button>
|
|
12
|
+
)
|
|
13
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { HTMLInputTypeAttribute, useState } from 'react'
|
|
4
|
+
import ToolTip from './tooltip'
|
|
5
|
+
import Label from './label'
|
|
6
|
+
import EraseButton from './erase'
|
|
7
|
+
|
|
8
|
+
type InputProps = {
|
|
9
|
+
name: string
|
|
10
|
+
type: HTMLInputTypeAttribute
|
|
11
|
+
label: string
|
|
12
|
+
value?: string | number
|
|
13
|
+
setValue: (value: string | number) => void
|
|
14
|
+
className?: string
|
|
15
|
+
tooltip?: string
|
|
16
|
+
required?: boolean
|
|
17
|
+
color?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default function Input({ name, type, label, className, tooltip, required, value, setValue, color }: InputProps) {
|
|
21
|
+
const [hasBlured, setHasBlured] = useState(false)
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div className={`w-full ${className}`}>
|
|
25
|
+
<div className='relative flex items-center'>
|
|
26
|
+
<input
|
|
27
|
+
name={name}
|
|
28
|
+
type={type}
|
|
29
|
+
className={
|
|
30
|
+
'block bg-login-800 px-2.5 pb-2.5 pt-4 w-full text-sm rounded-lg border-[0.10rem] appearance-none ' +
|
|
31
|
+
'border-login-200 focus:outline-none focus:ring-0 focus:border-login-50 peer'
|
|
32
|
+
}
|
|
33
|
+
value={value || ''}
|
|
34
|
+
onChange={(e) => setValue(e.target.value)}
|
|
35
|
+
onFocus={(e) => e.target.showPicker()}
|
|
36
|
+
onBlur={() => setHasBlured(true)}
|
|
37
|
+
placeholder=''
|
|
38
|
+
required={required}
|
|
39
|
+
/>
|
|
40
|
+
<Label
|
|
41
|
+
label={label}
|
|
42
|
+
value={value}
|
|
43
|
+
required={required}
|
|
44
|
+
color={color}
|
|
45
|
+
showRequired={required && !value && hasBlured}
|
|
46
|
+
/>
|
|
47
|
+
{value && <EraseButton setData={setValue} />}
|
|
48
|
+
{!value && tooltip && <ToolTip info={tooltip} />}
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type labelProps = {
|
|
2
|
+
label: string
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
value: any
|
|
5
|
+
required?: boolean
|
|
6
|
+
showRequired?: boolean
|
|
7
|
+
className?: string
|
|
8
|
+
color?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function Label({ label, value, required, showRequired, className, color }: labelProps) {
|
|
12
|
+
return (
|
|
13
|
+
<label
|
|
14
|
+
className={
|
|
15
|
+
'w-[calc(100%-10px)] truncate pointer-events-none absolute text-sm duration-300 transform z-10 ' +
|
|
16
|
+
'peer-focus:px-2 peer-focus:top-2 origin-[0] px-2 pt-1 peer-focus:scale-75 peer-focus:-translate-y-5 start-2 ' +
|
|
17
|
+
`${color ? color : 'bg-login-800'} ` +
|
|
18
|
+
`${value ? '-translate-y-5 scale-75 top-2 w-fit '
|
|
19
|
+
: '-translate-y-1/2 scale-100 top-1/2 '
|
|
20
|
+
+ 'peer-focus:w-fit '
|
|
21
|
+
} ${showRequired ? 'text-red-500/50 ' : ''}
|
|
22
|
+
${!value &&
|
|
23
|
+
required ? 'group-[.submitPressed]:text-red-500/50 ' : ''}
|
|
24
|
+
${required ? 'after:content-["_*"] ' : ''}
|
|
25
|
+
${className}`
|
|
26
|
+
}
|
|
27
|
+
>
|
|
28
|
+
{label}
|
|
29
|
+
</label>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import ToolTip from './tooltip'
|
|
4
|
+
|
|
5
|
+
type SwitchProps = {
|
|
6
|
+
name: string
|
|
7
|
+
label: string
|
|
8
|
+
value?: boolean
|
|
9
|
+
setValue: (_: boolean) => void
|
|
10
|
+
className?: string
|
|
11
|
+
tooltip?: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function Switch({ name, label, value, className, tooltip, setValue }: SwitchProps) {
|
|
15
|
+
return (
|
|
16
|
+
<div className={`relative w-full flex items-center px-2.5 pb-2.5 pt-3 border-login-200 rounded-lg border-[0.10rem]
|
|
17
|
+
bg-login-800 ${className}`}
|
|
18
|
+
>
|
|
19
|
+
<label className='flex items-center cursor-pointer'>
|
|
20
|
+
<input
|
|
21
|
+
type='checkbox'
|
|
22
|
+
name={name}
|
|
23
|
+
className='sr-only'
|
|
24
|
+
checked={value}
|
|
25
|
+
onChange={(e) => setValue(e.target.checked)}
|
|
26
|
+
/>
|
|
27
|
+
<div className={`w-10 h-6 rounded-full p-1 transition ${value ? 'bg-login-50' : 'bg-login-200'}`}>
|
|
28
|
+
<div
|
|
29
|
+
className={`w-4 h-4 bg-login-800 rounded-full shadow-md transform transition ${value ? 'translate-x-4' : ''}`}
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
32
|
+
</label>
|
|
33
|
+
<span className='ml-3 text-sm'>
|
|
34
|
+
{label}
|
|
35
|
+
</span>
|
|
36
|
+
{tooltip && <ToolTip info={tooltip} />}
|
|
37
|
+
</div>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useState, KeyboardEvent } from 'react'
|
|
4
|
+
import ToolTip from './tooltip'
|
|
5
|
+
import Label from './label'
|
|
6
|
+
import EraseButton from './erase'
|
|
7
|
+
import { X } from 'lucide-react'
|
|
8
|
+
|
|
9
|
+
type TagInputProps = {
|
|
10
|
+
name: string
|
|
11
|
+
label: string
|
|
12
|
+
value?: string[]
|
|
13
|
+
setValue: (_: string[]) => void
|
|
14
|
+
className?: string
|
|
15
|
+
tooltip?: string
|
|
16
|
+
required?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default function TagInput({
|
|
20
|
+
name,
|
|
21
|
+
label,
|
|
22
|
+
value = [],
|
|
23
|
+
className,
|
|
24
|
+
tooltip,
|
|
25
|
+
required,
|
|
26
|
+
setValue,
|
|
27
|
+
}: TagInputProps) {
|
|
28
|
+
const original = value
|
|
29
|
+
const [input, setInput] = useState('')
|
|
30
|
+
const [hasBlured, setHasBlured] = useState(false)
|
|
31
|
+
|
|
32
|
+
function addTag(value: string) {
|
|
33
|
+
const trimmed = value.trim()
|
|
34
|
+
if (trimmed && !value.includes(trimmed)) {
|
|
35
|
+
setValue([...value, trimmed])
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function removeTag(idx: number) {
|
|
40
|
+
setValue(value.filter((_, i) => i !== idx))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function handleKeyDown(e: KeyboardEvent<HTMLInputElement>) {
|
|
44
|
+
if (
|
|
45
|
+
(e.key === 'Enter' || e.key === ',' || e.key === 'Tab') &&
|
|
46
|
+
input.trim()
|
|
47
|
+
) {
|
|
48
|
+
e.preventDefault()
|
|
49
|
+
addTag(input)
|
|
50
|
+
setInput('')
|
|
51
|
+
}
|
|
52
|
+
if (e.key === 'Backspace' && !input && value.length) {
|
|
53
|
+
setValue(value.slice(0, -1))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function handleErase() {
|
|
58
|
+
setValue([])
|
|
59
|
+
setInput('')
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const toRemove = original.filter((tag: string) => !value.includes(tag))
|
|
63
|
+
const toAdd = value.filter((tag: string) => !original.includes(tag))
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<div className={`w-full ${className}`}>
|
|
67
|
+
<div
|
|
68
|
+
className={
|
|
69
|
+
'relative flex items-center flex-wrap gap-1 ' +
|
|
70
|
+
'border-[0.10rem] border-login-200 ' +
|
|
71
|
+
'rounded-lg ' +
|
|
72
|
+
'px-2.5 pt-3 pb-2.5 bg-login-800'
|
|
73
|
+
}
|
|
74
|
+
>
|
|
75
|
+
<div className='flex flex-wrap gap-1 items-center w-full'>
|
|
76
|
+
{value.map((tag, idx) => (
|
|
77
|
+
<span
|
|
78
|
+
key={tag + idx}
|
|
79
|
+
className={
|
|
80
|
+
'bg-login-600 text-sm rounded px-2 ' +
|
|
81
|
+
'py-0.5 flex items-center gap-0.5'
|
|
82
|
+
}
|
|
83
|
+
>
|
|
84
|
+
{tag}
|
|
85
|
+
<button
|
|
86
|
+
type='button'
|
|
87
|
+
className='ml-1 text-red-700 hover:text-red-800'
|
|
88
|
+
onClick={() => removeTag(idx)}
|
|
89
|
+
>
|
|
90
|
+
<X className='h-4 stroke-3' />
|
|
91
|
+
</button>
|
|
92
|
+
</span>
|
|
93
|
+
))}
|
|
94
|
+
<input
|
|
95
|
+
value={input}
|
|
96
|
+
onChange={(e) => setInput(e.target.value)}
|
|
97
|
+
onKeyDown={handleKeyDown}
|
|
98
|
+
onBlur={() => setHasBlured(true)}
|
|
99
|
+
className={
|
|
100
|
+
'peer flex-1 min-w-[6ch] bg-transparent ' +
|
|
101
|
+
'outline-none text-sm'
|
|
102
|
+
}
|
|
103
|
+
autoComplete='off'
|
|
104
|
+
required={required && value.length === 0}
|
|
105
|
+
/>
|
|
106
|
+
{toRemove.map((tag) => (
|
|
107
|
+
<input
|
|
108
|
+
key={tag}
|
|
109
|
+
type='hidden'
|
|
110
|
+
name={name + '_remove'}
|
|
111
|
+
value={tag}
|
|
112
|
+
/>
|
|
113
|
+
))}
|
|
114
|
+
{toAdd.map((tag) => (
|
|
115
|
+
<input
|
|
116
|
+
key={tag}
|
|
117
|
+
type='hidden'
|
|
118
|
+
name={name + '_add'}
|
|
119
|
+
value={tag}
|
|
120
|
+
/>
|
|
121
|
+
))}
|
|
122
|
+
<Label
|
|
123
|
+
label={label}
|
|
124
|
+
value={value.length ? value.join(', ') : ''}
|
|
125
|
+
required={required}
|
|
126
|
+
showRequired={
|
|
127
|
+
required && value.length === 0 && hasBlured
|
|
128
|
+
}
|
|
129
|
+
className='pointer-events-none left-2'
|
|
130
|
+
/>
|
|
131
|
+
</div>
|
|
132
|
+
{value.length > 0 && <EraseButton setData={handleErase} />}
|
|
133
|
+
{value.length === 0 && tooltip && <ToolTip info={tooltip} />}
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
)
|
|
137
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default function ToolTip({ info, className }: { info: string; className?: string }) {
|
|
2
|
+
return (
|
|
3
|
+
<div className={`absolute z-19 right-0 px-1 flex justify-center ${className}`}>
|
|
4
|
+
<span className={'peer cursor-pointer rounded-sm px-3 py-1 bg-login-800 hover:bg-login-600'}>
|
|
5
|
+
?
|
|
6
|
+
</span>
|
|
7
|
+
<div className={'absolute hidden peer-hover:block p-2 rounded z-20 bg-login-700 border left-12 w-max max-w-3xs'}>
|
|
8
|
+
{info}
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
)
|
|
12
|
+
}
|