funuicss 3.6.16 → 3.6.18
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/cors.json +8 -0
- package/css/fun.css +253 -160
- package/gsutil +0 -0
- package/package.json +1 -1
- package/ui/button/Button.js +27 -16
- package/ui/input/Input.d.ts +2 -0
- package/ui/input/Input.js +113 -21
- package/ui/theme/theme.js +94 -83
package/cors.json
ADDED
package/css/fun.css
CHANGED
|
@@ -220,126 +220,167 @@
|
|
|
220
220
|
|
|
221
221
|
|
|
222
222
|
|
|
223
|
+
/* fonts scalling */
|
|
223
224
|
:root {
|
|
224
|
-
/*
|
|
225
|
-
--
|
|
226
|
-
--
|
|
227
|
-
--
|
|
228
|
-
--
|
|
229
|
-
--
|
|
230
|
-
--
|
|
231
|
-
--
|
|
232
|
-
--
|
|
225
|
+
/* ===== Font Scale - Perfect Fourth (1.333 ratio) ===== */
|
|
226
|
+
--font-size-smaller: 0.75rem; /* 12px */
|
|
227
|
+
--font-size-small: 0.875rem; /* 14px */
|
|
228
|
+
--font-size-base: 1rem; /* 16px - Base */
|
|
229
|
+
--font-size-big: 1.25rem; /* 20px */
|
|
230
|
+
--font-size-bigger: 1.5rem; /* 24px */
|
|
231
|
+
--font-size-h6: 1rem; /* 16px */
|
|
232
|
+
--font-size-h5: 1.25rem; /* 20px */
|
|
233
|
+
--font-size-h4: 1.5rem; /* 24px */
|
|
234
|
+
--font-size-h3: 1.75rem; /* 28px */
|
|
235
|
+
--font-size-h2: 2rem; /* 32px */
|
|
236
|
+
--font-size-h1: 2.5rem; /* 40px */
|
|
237
|
+
--font-size-jumbo: 3rem; /* 48px */
|
|
238
|
+
|
|
239
|
+
/* ===== Line Height Scale ===== */
|
|
240
|
+
--line-height-tight: 1.2;
|
|
241
|
+
--line-height-normal: 1.5;
|
|
242
|
+
--line-height-relaxed: 1.75;
|
|
243
|
+
--line-height-loose: 2;
|
|
244
|
+
|
|
245
|
+
/* Element-specific line heights */
|
|
246
|
+
--line-height-smaller: var(--line-height-normal);
|
|
247
|
+
--line-height-small: var(--line-height-normal);
|
|
248
|
+
--line-height-body: var(--line-height-normal);
|
|
249
|
+
--line-height-big: var(--line-height-normal);
|
|
250
|
+
--line-height-bigger: var(--line-height-normal);
|
|
251
|
+
--line-height-h6: var(--line-height-normal);
|
|
252
|
+
--line-height-h5: var(--line-height-normal);
|
|
253
|
+
--line-height-h4: var(--line-height-normal);
|
|
254
|
+
--line-height-h3: var(--line-height-normal);
|
|
255
|
+
--line-height-h2: var(--line-height-tight);
|
|
256
|
+
--line-height-h1: var(--line-height-tight);
|
|
257
|
+
--line-height-jumbo: var(--line-height-tight);
|
|
258
|
+
|
|
259
|
+
/* ===== Font Weights ===== */
|
|
260
|
+
--font-weight-thin: 100;
|
|
261
|
+
--font-weight-extra-light: 200;
|
|
262
|
+
--font-weight-light: 300;
|
|
263
|
+
--font-weight-normal: 400;
|
|
264
|
+
--font-weight-medium: 500;
|
|
265
|
+
--font-weight-semibold: 600;
|
|
266
|
+
--font-weight-bold: 700;
|
|
267
|
+
--font-weight-extra-bold: 800;
|
|
268
|
+
--font-weight-black: 900;
|
|
269
|
+
|
|
270
|
+
/* Element-specific font weights */
|
|
271
|
+
--font-weight-smaller: var(--font-weight-normal);
|
|
272
|
+
--font-weight-small: var(--font-weight-normal);
|
|
273
|
+
--font-weight-body: var(--font-weight-normal);
|
|
274
|
+
--font-weight-big: var(--font-weight-normal);
|
|
275
|
+
--font-weight-bigger: var(--font-weight-normal);
|
|
276
|
+
--font-weight-h6: var(--font-weight-medium);
|
|
277
|
+
--font-weight-h5: var(--font-weight-medium);
|
|
278
|
+
--font-weight-h4: var(--font-weight-medium);
|
|
279
|
+
--font-weight-h3: var(--font-weight-semibold);
|
|
280
|
+
--font-weight-h2: var(--font-weight-semibold);
|
|
281
|
+
--font-weight-h1: var(--font-weight-bold);
|
|
282
|
+
--font-weight-jumbo: var(--font-weight-bold);
|
|
283
|
+
|
|
284
|
+
/* ===== Text Decoration ===== */
|
|
285
|
+
--text-decoration-none: none;
|
|
286
|
+
--text-decoration-underline: underline;
|
|
287
|
+
--text-decoration-overline: overline;
|
|
288
|
+
--text-decoration-line-through: line-through;
|
|
289
|
+
|
|
290
|
+
/* Element-specific text decoration */
|
|
291
|
+
--text-decoration-smaller: var(--text-decoration-none);
|
|
292
|
+
--text-decoration-small: var(--text-decoration-none);
|
|
293
|
+
--text-decoration-body: var(--text-decoration-none);
|
|
294
|
+
--text-decoration-big: var(--text-decoration-none);
|
|
295
|
+
--text-decoration-bigger: var(--text-decoration-none);
|
|
296
|
+
--text-decoration-h6: var(--text-decoration-none);
|
|
297
|
+
--text-decoration-h5: var(--text-decoration-none);
|
|
298
|
+
--text-decoration-h4: var(--text-decoration-none);
|
|
299
|
+
--text-decoration-h3: var(--text-decoration-none);
|
|
300
|
+
--text-decoration-h2: var(--text-decoration-none);
|
|
301
|
+
--text-decoration-h1: var(--text-decoration-none);
|
|
302
|
+
--text-decoration-jumbo: var(--text-decoration-none);
|
|
303
|
+
|
|
304
|
+
/* ===== Font Style ===== */
|
|
305
|
+
--font-style-normal: normal;
|
|
306
|
+
--font-style-italic: italic;
|
|
307
|
+
--font-style-oblique: oblique;
|
|
308
|
+
|
|
309
|
+
/* Element-specific font styles */
|
|
310
|
+
--font-style-smaller: var(--font-style-normal);
|
|
311
|
+
--font-style-small: var(--font-style-normal);
|
|
312
|
+
--font-style-body: var(--font-style-normal);
|
|
313
|
+
--font-style-big: var(--font-style-normal);
|
|
314
|
+
--font-style-bigger: var(--font-style-normal);
|
|
315
|
+
--font-style-h6: var(--font-style-normal);
|
|
316
|
+
--font-style-h5: var(--font-style-normal);
|
|
317
|
+
--font-style-h4: var(--font-style-normal);
|
|
318
|
+
--font-style-h3: var(--font-style-normal);
|
|
319
|
+
--font-style-h2: var(--font-style-normal);
|
|
320
|
+
--font-style-h1: var(--font-style-normal);
|
|
321
|
+
--font-style-jumbo: var(--font-style-normal);
|
|
322
|
+
|
|
323
|
+
/* ===== Text Transform ===== */
|
|
324
|
+
--text-transform-none: none;
|
|
325
|
+
--text-transform-uppercase: uppercase;
|
|
326
|
+
--text-transform-lowercase: lowercase;
|
|
327
|
+
--text-transform-capitalize: capitalize;
|
|
328
|
+
|
|
329
|
+
/* Element-specific text transforms */
|
|
330
|
+
--text-transform-smaller: var(--text-transform-none);
|
|
331
|
+
--text-transform-small: var(--text-transform-none);
|
|
332
|
+
--text-transform-body: var(--text-transform-none);
|
|
333
|
+
--text-transform-big: var(--text-transform-none);
|
|
334
|
+
--text-transform-bigger: var(--text-transform-none);
|
|
335
|
+
--text-transform-h6: var(--text-transform-none);
|
|
336
|
+
--text-transform-h5: var(--text-transform-none);
|
|
337
|
+
--text-transform-h4: var(--text-transform-none);
|
|
338
|
+
--text-transform-h3: var(--text-transform-none);
|
|
339
|
+
--text-transform-h2: var(--text-transform-none);
|
|
340
|
+
--text-transform-h1: var(--text-transform-none);
|
|
341
|
+
--text-transform-jumbo: var(--text-transform-none);
|
|
342
|
+
|
|
343
|
+
/* ===== Letter Spacing ===== */
|
|
344
|
+
--letter-spacing-tighter: -0.05em;
|
|
345
|
+
--letter-spacing-tight: -0.025em;
|
|
346
|
+
--letter-spacing-normal: 0em;
|
|
347
|
+
--letter-spacing-wide: 0.025em;
|
|
348
|
+
--letter-spacing-wider: 0.05em;
|
|
349
|
+
--letter-spacing-widest: 0.1em;
|
|
350
|
+
|
|
351
|
+
/* Element-specific letter spacing */
|
|
352
|
+
--letter-spacing-smaller: var(--letter-spacing-normal);
|
|
353
|
+
--letter-spacing-small: var(--letter-spacing-normal);
|
|
354
|
+
--letter-spacing-body: var(--letter-spacing-normal);
|
|
355
|
+
--letter-spacing-big: var(--letter-spacing-normal);
|
|
356
|
+
--letter-spacing-bigger: var(--letter-spacing-normal);
|
|
357
|
+
--letter-spacing-h6: var(--letter-spacing-normal);
|
|
358
|
+
--letter-spacing-h5: var(--letter-spacing-normal);
|
|
359
|
+
--letter-spacing-h4: var(--letter-spacing-normal);
|
|
360
|
+
--letter-spacing-h3: var(--letter-spacing-normal);
|
|
361
|
+
--letter-spacing-h2: var(--letter-spacing-tight);
|
|
362
|
+
--letter-spacing-h1: var(--letter-spacing-tight);
|
|
363
|
+
--letter-spacing-jumbo: var(--letter-spacing-tight);
|
|
364
|
+
|
|
365
|
+
/* ===== Word Spacing ===== */
|
|
366
|
+
--word-spacing-tight: -0.05em;
|
|
367
|
+
--word-spacing-normal: 0em;
|
|
368
|
+
--word-spacing-wide: 0.05em;
|
|
369
|
+
--word-spacing-wider: 0.1em;
|
|
370
|
+
|
|
371
|
+
/* ===== Responsive Typography Scales ===== */
|
|
372
|
+
/* Mobile-first scale (base) */
|
|
373
|
+
--scale-mobile: 1.2;
|
|
233
374
|
|
|
234
|
-
/*
|
|
235
|
-
--
|
|
236
|
-
--btn-active-scale: 0.98;
|
|
237
|
-
--btn-disabled-opacity: 0.5;
|
|
375
|
+
/* Tablet scale */
|
|
376
|
+
--scale-tablet: 1.25;
|
|
238
377
|
|
|
239
|
-
/*
|
|
240
|
-
--
|
|
241
|
-
--btn-primary-text: var(--white);
|
|
242
|
-
--btn-primary-hover: var(--primary600);
|
|
243
|
-
|
|
244
|
-
--btn-secondary-bg: var(--secondary);
|
|
245
|
-
--btn-secondary-text: var(--white);
|
|
246
|
-
--btn-secondary-hover: var(--secondary600);
|
|
247
|
-
|
|
248
|
-
--btn-outlined-border: var(--primary);
|
|
249
|
-
--btn-outlined-text: var(--primary);
|
|
250
|
-
--btn-outlined-hover-bg: var(--primary50);
|
|
251
|
-
|
|
252
|
-
/* INPUT VARIABLES */
|
|
253
|
-
--input-font-size: var(--text-base);
|
|
254
|
-
--input-padding-x: var(--space-4);
|
|
255
|
-
--input-padding-y: var(--space-3);
|
|
256
|
-
--input-border-radius: var(--radius-lg);
|
|
257
|
-
--input-border-width: var(--inputBorder);
|
|
258
|
-
--input-border-color: var(--borderColor);
|
|
259
|
-
--input-bg: var(--white);
|
|
260
|
-
--input-text-color: var(--text-color);
|
|
261
|
-
--input-placeholder-color: var(--muted);
|
|
262
|
-
--input-min-height: var(--inputButtonHeight);
|
|
263
|
-
|
|
264
|
-
/* Input States */
|
|
265
|
-
--input-focus-border: var(--primary);
|
|
266
|
-
--input-focus-ring: 0 0 0 3px var(--primary200);
|
|
267
|
-
--input-error-border: var(--error);
|
|
268
|
-
--input-error-ring: 0 0 0 3px var(--error200);
|
|
269
|
-
--input-disabled-bg: var(--lighter);
|
|
270
|
-
--input-disabled-opacity: 0.6;
|
|
271
|
-
|
|
272
|
-
/* CARD VARIABLES */
|
|
273
|
-
--card-bg: var(--cardBg);
|
|
274
|
-
--card-border: var(--border);
|
|
275
|
-
--card-border-radius: var(--borderRadius);
|
|
276
|
-
--card-padding: var(--space-6);
|
|
277
|
-
--card-shadow: var(--card);
|
|
278
|
-
--card-hover-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
|
|
279
|
-
|
|
280
|
-
/* LINK VARIABLES */
|
|
281
|
-
--link-color: var(--linkColor);
|
|
282
|
-
--link-hover-color: var(--primary);
|
|
283
|
-
--link-underline: none;
|
|
284
|
-
--link-hover-underline: underline;
|
|
285
|
-
--link-font-weight: 400;
|
|
286
|
-
|
|
287
|
-
/* BADGE/TAG VARIABLES */
|
|
288
|
-
--badge-font-size: var(--text-xs);
|
|
289
|
-
--badge-padding-x: var(--space-2);
|
|
290
|
-
--badge-padding-y: var(--space-1);
|
|
291
|
-
--badge-border-radius: var(--radius-full);
|
|
292
|
-
--badge-font-weight: 500;
|
|
293
|
-
|
|
294
|
-
/* MODAL/DIALOG VARIABLES */
|
|
295
|
-
--modal-backdrop: rgba(0, 0, 0, 0.5);
|
|
296
|
-
--modal-bg: var(--white);
|
|
297
|
-
--modal-border-radius: var(--radius-2xl);
|
|
298
|
-
--modal-padding: var(--space-8);
|
|
299
|
-
--modal-max-width: 32rem;
|
|
300
|
-
--modal-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
|
|
301
|
-
|
|
302
|
-
/* DROPDOWN/SELECT VARIABLES */
|
|
303
|
-
--dropdown-bg: var(--white);
|
|
304
|
-
--dropdown-border: var(--border);
|
|
305
|
-
--dropdown-border-radius: var(--radius-lg);
|
|
306
|
-
--dropdown-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
|
307
|
-
--dropdown-item-padding: var(--space-3) var(--space-4);
|
|
308
|
-
--dropdown-item-hover-bg: var(--lighter);
|
|
309
|
-
|
|
310
|
-
/* SWITCH/TOGGLE VARIABLES */
|
|
311
|
-
--switch-width: 2.75rem;
|
|
312
|
-
--switch-height: 1.5rem;
|
|
313
|
-
--switch-bg: var(--borderColor);
|
|
314
|
-
--switch-active-bg: var(--primary);
|
|
315
|
-
--switch-thumb-size: 1.25rem;
|
|
316
|
-
|
|
317
|
-
/* CHECKBOX/RADIO VARIABLES */
|
|
318
|
-
--checkbox-size: 1.25rem;
|
|
319
|
-
--checkbox-border: var(--borderColor);
|
|
320
|
-
--checkbox-checked-bg: var(--primary);
|
|
321
|
-
--checkbox-checked-border: var(--primary);
|
|
322
|
-
--checkbox-border-radius: var(--radius);
|
|
323
|
-
|
|
324
|
-
/* TOOLTIP VARIABLES */
|
|
325
|
-
--tooltip-bg: var(--dark);
|
|
326
|
-
--tooltip-text: var(--white);
|
|
327
|
-
--tooltip-padding: var(--space-2) var(--space-3);
|
|
328
|
-
--tooltip-border-radius: var(--radius);
|
|
329
|
-
--tooltip-font-size: var(--text-sm);
|
|
330
|
-
|
|
331
|
-
/* AVATAR VARIABLES */
|
|
332
|
-
--avatar-size: 2.5rem;
|
|
333
|
-
--avatar-border-radius: var(--radius-full);
|
|
334
|
-
--avatar-border: 2px solid var(--white);
|
|
335
|
-
|
|
336
|
-
/* DIVIDER VARIABLES */
|
|
337
|
-
--divider-color: var(--borderColor);
|
|
338
|
-
--divider-width: 1px;
|
|
339
|
-
--divider-margin: var(--space-4) 0;
|
|
378
|
+
/* Desktop scale */
|
|
379
|
+
--scale-desktop: 1.333;
|
|
340
380
|
}
|
|
341
381
|
|
|
342
382
|
|
|
383
|
+
|
|
343
384
|
/* For WebKit browsers (Chrome, Edge, Brave, Safari) */
|
|
344
385
|
::-webkit-scrollbar {
|
|
345
386
|
width: 10px;
|
|
@@ -580,23 +621,34 @@ body {
|
|
|
580
621
|
font-weight: 900;
|
|
581
622
|
}
|
|
582
623
|
|
|
583
|
-
/* Additional responsive/animated sizes */
|
|
584
624
|
.text-big {
|
|
585
|
-
font-size:
|
|
586
|
-
line-height:
|
|
587
|
-
|
|
625
|
+
font-size: var(--font-size-big);
|
|
626
|
+
line-height: var(--line-height-big);
|
|
627
|
+
font-weight: var(--font-weight-big);
|
|
628
|
+
font-style: var(--font-style-big);
|
|
629
|
+
text-decoration: var(--text-decoration-big);
|
|
630
|
+
text-transform: var(--text-transform-big);
|
|
631
|
+
letter-spacing: var(--letter-spacing-big);
|
|
588
632
|
}
|
|
589
633
|
|
|
590
634
|
.text-bigger {
|
|
591
|
-
font-size:
|
|
592
|
-
line-height:
|
|
593
|
-
|
|
635
|
+
font-size: var(--font-size-bigger);
|
|
636
|
+
line-height: var(--line-height-bigger);
|
|
637
|
+
font-weight: var(--font-weight-bigger);
|
|
638
|
+
font-style: var(--font-style-bigger);
|
|
639
|
+
text-decoration: var(--text-decoration-bigger);
|
|
640
|
+
text-transform: var(--text-transform-bigger);
|
|
641
|
+
letter-spacing: var(--letter-spacing-bigger);
|
|
594
642
|
}
|
|
595
643
|
|
|
596
644
|
.text-jumbo {
|
|
597
|
-
font-size:
|
|
598
|
-
line-height:
|
|
599
|
-
font-weight:
|
|
645
|
+
font-size: var(--font-size-jumbo);
|
|
646
|
+
line-height: var(--line-height-jumbo);
|
|
647
|
+
font-weight: var(--font-weight-jumbo);
|
|
648
|
+
font-style: var(--font-style-jumbo);
|
|
649
|
+
text-decoration: var(--text-decoration-jumbo);
|
|
650
|
+
text-transform: var(--text-transform-jumbo);
|
|
651
|
+
letter-spacing: var(--letter-spacing-jumbo);
|
|
600
652
|
}
|
|
601
653
|
.important{
|
|
602
654
|
font-weight: 700;
|
|
@@ -604,13 +656,23 @@ body {
|
|
|
604
656
|
}
|
|
605
657
|
/* Mini sizes */
|
|
606
658
|
.text-small {
|
|
607
|
-
|
|
608
|
-
line-height:
|
|
659
|
+
font-size: var(--font-size-small);
|
|
660
|
+
line-height: var(--line-height-small);
|
|
661
|
+
font-weight: var(--font-weight-small);
|
|
662
|
+
font-style: var(--font-style-small);
|
|
663
|
+
text-decoration: var(--text-decoration-small);
|
|
664
|
+
text-transform: var(--text-transform-small);
|
|
665
|
+
letter-spacing: var(--letter-spacing-small);
|
|
609
666
|
}
|
|
610
667
|
|
|
611
668
|
.text-smaller {
|
|
612
|
-
font-size: var(--
|
|
613
|
-
line-height:
|
|
669
|
+
font-size: var(--font-size-smaller);
|
|
670
|
+
line-height: var(--line-height-smaller);
|
|
671
|
+
font-weight: var(--font-weight-smaller);
|
|
672
|
+
font-style: var(--font-style-smaller);
|
|
673
|
+
text-decoration: var(--text-decoration-smaller);
|
|
674
|
+
text-transform: var(--text-transform-smaller);
|
|
675
|
+
letter-spacing: var(--letter-spacing-smaller);
|
|
614
676
|
}
|
|
615
677
|
|
|
616
678
|
.text-minified , .text-md{
|
|
@@ -646,39 +708,82 @@ h1,
|
|
|
646
708
|
}
|
|
647
709
|
|
|
648
710
|
h1, .h1 {
|
|
649
|
-
font-size: var(--
|
|
650
|
-
line-height: var(--
|
|
651
|
-
|
|
711
|
+
font-size: var(--font-size-h1);
|
|
712
|
+
line-height: var(--line-height-h1);
|
|
713
|
+
font-weight: var(--font-weight-h1);
|
|
714
|
+
font-style: var(--font-style-h1);
|
|
715
|
+
text-decoration: var(--text-decoration-h1);
|
|
716
|
+
text-transform: var(--text-transform-h1);
|
|
717
|
+
letter-spacing: var(--letter-spacing-h1);
|
|
652
718
|
}
|
|
653
719
|
|
|
654
720
|
h2, .h2 {
|
|
655
|
-
font-size: var(--
|
|
656
|
-
line-height: var(--
|
|
657
|
-
font-weight:
|
|
721
|
+
font-size: var(--font-size-h2);
|
|
722
|
+
line-height: var(--line-height-h2);
|
|
723
|
+
font-weight: var(--font-weight-h2);
|
|
724
|
+
font-style: var(--font-style-h2);
|
|
725
|
+
text-decoration: var(--text-decoration-h2);
|
|
726
|
+
text-transform: var(--text-transform-h2);
|
|
727
|
+
letter-spacing: var(--letter-spacing-h2);
|
|
658
728
|
}
|
|
659
729
|
|
|
660
730
|
h3, .h3 {
|
|
661
|
-
font-size: var(--
|
|
662
|
-
line-height: var(--
|
|
663
|
-
|
|
731
|
+
font-size: var(--font-size-h3);
|
|
732
|
+
line-height: var(--line-height-h3);
|
|
733
|
+
font-weight: var(--font-weight-h3);
|
|
734
|
+
font-style: var(--font-style-h3);
|
|
735
|
+
text-decoration: var(--text-decoration-h3);
|
|
736
|
+
text-transform: var(--text-transform-h3);
|
|
737
|
+
letter-spacing: var(--letter-spacing-h3);
|
|
664
738
|
}
|
|
665
739
|
|
|
666
740
|
h4, .h4 {
|
|
667
|
-
font-size: var(--
|
|
668
|
-
line-height: var(--
|
|
669
|
-
|
|
741
|
+
font-size: var(--font-size-h4);
|
|
742
|
+
line-height: var(--line-height-h4);
|
|
743
|
+
font-weight: var(--font-weight-h4);
|
|
744
|
+
font-style: var(--font-style-h4);
|
|
745
|
+
text-decoration: var(--text-decoration-h4);
|
|
746
|
+
text-transform: var(--text-transform-h4);
|
|
747
|
+
letter-spacing: var(--letter-spacing-h4);
|
|
670
748
|
}
|
|
671
749
|
|
|
672
750
|
h5, .h5 {
|
|
673
|
-
font-size: var(--
|
|
674
|
-
line-height: var(--
|
|
675
|
-
|
|
751
|
+
font-size: var(--font-size-h5);
|
|
752
|
+
line-height: var(--line-height-h5);
|
|
753
|
+
font-weight: var(--font-weight-h5);
|
|
754
|
+
font-style: var(--font-style-h5);
|
|
755
|
+
text-decoration: var(--text-decoration-h5);
|
|
756
|
+
text-transform: var(--text-transform-h5);
|
|
757
|
+
letter-spacing: var(--letter-spacing-h5);
|
|
676
758
|
}
|
|
677
759
|
|
|
678
760
|
h6, .h6 {
|
|
679
|
-
font-size: var(--
|
|
680
|
-
line-height: var(--
|
|
681
|
-
|
|
761
|
+
font-size: var(--font-size-h6);
|
|
762
|
+
line-height: var(--line-height-h6);
|
|
763
|
+
font-weight: var(--font-weight-h6);
|
|
764
|
+
font-style: var(--font-style-h6);
|
|
765
|
+
text-decoration: var(--text-decoration-h6);
|
|
766
|
+
text-transform: var(--text-transform-h6);
|
|
767
|
+
letter-spacing: var(--letter-spacing-h6);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/* ===== Responsive Typography ===== */
|
|
771
|
+
@media (min-width: 768px) {
|
|
772
|
+
:root {
|
|
773
|
+
--font-size-h1: calc(2.5rem * var(--scale-tablet));
|
|
774
|
+
--font-size-h2: calc(2rem * var(--scale-tablet));
|
|
775
|
+
--font-size-h3: calc(1.75rem * var(--scale-tablet));
|
|
776
|
+
--font-size-jumbo: calc(3rem * var(--scale-tablet));
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
@media (min-width: 1024px) {
|
|
781
|
+
:root {
|
|
782
|
+
--font-size-h1: calc(2.5rem * var(--scale-desktop));
|
|
783
|
+
--font-size-h2: calc(2rem * var(--scale-desktop));
|
|
784
|
+
--font-size-h3: calc(1.75rem * var(--scale-desktop));
|
|
785
|
+
--font-size-jumbo: calc(3rem * var(--scale-desktop));
|
|
786
|
+
}
|
|
682
787
|
}
|
|
683
788
|
|
|
684
789
|
|
|
@@ -1969,8 +2074,6 @@ border-radius: var(--borderRadius);
|
|
|
1969
2074
|
|
|
1970
2075
|
|
|
1971
2076
|
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
2077
|
.dropup:hover .drop-menu {
|
|
1975
2078
|
display: block;
|
|
1976
2079
|
z-index: 1;
|
|
@@ -2050,7 +2153,6 @@ border-radius: var(--borderRadius);
|
|
|
2050
2153
|
pointer-events: none;
|
|
2051
2154
|
transition: all 0.2s ease;
|
|
2052
2155
|
background-color: transparent;
|
|
2053
|
-
padding: 0 0.25rem;
|
|
2054
2156
|
z-index: 1;
|
|
2055
2157
|
font-weight: 500;
|
|
2056
2158
|
}
|
|
@@ -2066,7 +2168,7 @@ border-radius: var(--borderRadius);
|
|
|
2066
2168
|
transform: translateY(0);
|
|
2067
2169
|
line-height: 1;
|
|
2068
2170
|
}
|
|
2069
|
-
.floating-label.label-left{left:
|
|
2171
|
+
.floating-label.label-left{left: 2rem ;}
|
|
2070
2172
|
/* Label status colors */
|
|
2071
2173
|
.floating-label.label-success.active {
|
|
2072
2174
|
color: var(--success);
|
|
@@ -2097,14 +2199,6 @@ border-radius: var(--borderRadius);
|
|
|
2097
2199
|
background-color: transparent;
|
|
2098
2200
|
}
|
|
2099
2201
|
|
|
2100
|
-
/* For textarea */
|
|
2101
|
-
textarea ~ .floating-label {
|
|
2102
|
-
top: 1.2rem;
|
|
2103
|
-
}
|
|
2104
|
-
|
|
2105
|
-
textarea ~ .floating-label.active {
|
|
2106
|
-
top: 0.35rem;
|
|
2107
|
-
}
|
|
2108
2202
|
|
|
2109
2203
|
/* Status Input Styles */
|
|
2110
2204
|
.input.success-input,
|
|
@@ -2157,8 +2251,7 @@ textarea {
|
|
|
2157
2251
|
border-radius: var(--radius) !important;
|
|
2158
2252
|
height: fit-content !important;
|
|
2159
2253
|
min-height: 4rem;
|
|
2160
|
-
padding-top:
|
|
2161
|
-
padding-bottom: 0.6rem;
|
|
2254
|
+
padding-top: 0.8rem !important;
|
|
2162
2255
|
}
|
|
2163
2256
|
|
|
2164
2257
|
/* Reset padding when there's no label for textarea */
|
package/gsutil
ADDED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.6.
|
|
2
|
+
"version": "3.6.18",
|
|
3
3
|
"name": "funuicss",
|
|
4
4
|
"description": "React and Next.js component UI Library for creating Easy and good looking websites with fewer lines of code. Elevate your web development experience with our cutting-edge React/Next.js component UI Library. Craft stunning websites effortlessly, boasting both seamless functionality and aesthetic appeal—all achieved with minimal lines of code. Unleash the power of simplicity and style in your projects!",
|
|
5
5
|
"main": "index.js",
|
package/ui/button/Button.js
CHANGED
|
@@ -62,8 +62,7 @@ var pi_1 = require("react-icons/pi");
|
|
|
62
62
|
var componentUtils_1 = require("../../utils/componentUtils");
|
|
63
63
|
var getDynamicIcon_1 = require("../../utils/getDynamicIcon");
|
|
64
64
|
function Button(_a) {
|
|
65
|
-
var _b;
|
|
66
|
-
var _c = _a.variant, variant = _c === void 0 ? '' : _c, color = _a.color, bg = _a.bg, funcss = _a.funcss, startIcon = _a.startIcon, endIcon = _a.endIcon, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, prefix = _a.prefix, suffix = _a.suffix, iconSize = _a.iconSize, _d = _a.iconLineHeight, iconLineHeight = _d === void 0 ? 0 : _d, text = _a.text, rounded = _a.rounded, raised = _a.raised, height = _a.height, width = _a.width, float = _a.float, hoverUp = _a.hoverUp, fullWidth = _a.fullWidth, outlined = _a.outlined, small = _a.small, hoverless = _a.hoverless, smaller = _a.smaller, big = _a.big, bigger = _a.bigger, jumbo = _a.jumbo, flat = _a.flat, hoverNone = _a.hoverNone, fillAnimation = _a.fillAnimation, fillDirection = _a.fillDirection, fillTextColor = _a.fillTextColor, outlineSize = _a.outlineSize, isLoading = _a.isLoading, status = _a.status, bold = _a.bold, children = _a.children, style = _a.style, url = _a.url, onClick = _a.onClick, rest = __rest(_a, ["variant", "color", "bg", "funcss", "startIcon", "endIcon", "stringPrefix", "stringSuffix", "prefix", "suffix", "iconSize", "iconLineHeight", "text", "rounded", "raised", "height", "width", "float", "hoverUp", "fullWidth", "outlined", "small", "hoverless", "smaller", "big", "bigger", "jumbo", "flat", "hoverNone", "fillAnimation", "fillDirection", "fillTextColor", "outlineSize", "isLoading", "status", "bold", "children", "style", "url", "onClick"]);
|
|
65
|
+
var _b = _a.variant, variant = _b === void 0 ? '' : _b, color = _a.color, bg = _a.bg, funcss = _a.funcss, startIcon = _a.startIcon, endIcon = _a.endIcon, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, prefix = _a.prefix, suffix = _a.suffix, iconSize = _a.iconSize, _c = _a.iconLineHeight, iconLineHeight = _c === void 0 ? 0 : _c, text = _a.text, rounded = _a.rounded, raised = _a.raised, height = _a.height, width = _a.width, float = _a.float, hoverUp = _a.hoverUp, fullWidth = _a.fullWidth, outlined = _a.outlined, small = _a.small, hoverless = _a.hoverless, smaller = _a.smaller, big = _a.big, bigger = _a.bigger, jumbo = _a.jumbo, flat = _a.flat, hoverNone = _a.hoverNone, fillAnimation = _a.fillAnimation, fillDirection = _a.fillDirection, fillTextColor = _a.fillTextColor, outlineSize = _a.outlineSize, isLoading = _a.isLoading, status = _a.status, bold = _a.bold, children = _a.children, style = _a.style, url = _a.url, onClick = _a.onClick, rest = __rest(_a, ["variant", "color", "bg", "funcss", "startIcon", "endIcon", "stringPrefix", "stringSuffix", "prefix", "suffix", "iconSize", "iconLineHeight", "text", "rounded", "raised", "height", "width", "float", "hoverUp", "fullWidth", "outlined", "small", "hoverless", "smaller", "big", "bigger", "jumbo", "flat", "hoverNone", "fillAnimation", "fillDirection", "fillTextColor", "outlineSize", "isLoading", "status", "bold", "children", "style", "url", "onClick"]);
|
|
67
66
|
var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Button', variant).mergeWithLocal;
|
|
68
67
|
var mergedProps = mergeWithLocal(__assign({ color: color, bg: bg, funcss: funcss, text: text, rounded: rounded, raised: raised, height: height, width: width, float: float, hoverUp: hoverUp, fullWidth: fullWidth, outlined: outlined, small: small, hoverless: hoverless, smaller: smaller, big: big, bigger: bigger, jumbo: jumbo, flat: flat, hoverNone: hoverNone, fillAnimation: fillAnimation, fillDirection: fillDirection, fillTextColor: fillTextColor, outlineSize: outlineSize, isLoading: isLoading, status: status, bold: bold }, rest)).props;
|
|
69
68
|
var final = {
|
|
@@ -91,17 +90,28 @@ function Button(_a) {
|
|
|
91
90
|
fillTextColor: mergedProps.fillTextColor,
|
|
92
91
|
funcss: mergedProps.funcss,
|
|
93
92
|
};
|
|
94
|
-
var
|
|
95
|
-
var
|
|
93
|
+
var _d = (0, react_1.useState)(null), prefixNode = _d[0], setPrefixNode = _d[1];
|
|
94
|
+
var _e = (0, react_1.useState)(null), suffixNode = _e[0], setSuffixNode = _e[1];
|
|
96
95
|
function isReactElement(node) {
|
|
97
96
|
return react_1.default.isValidElement(node);
|
|
98
97
|
}
|
|
98
|
+
// FIX: Clear icons when stringPrefix/stringSuffix are empty or undefined
|
|
99
99
|
(0, react_1.useEffect)(function () {
|
|
100
|
-
if (stringPrefix)
|
|
100
|
+
if (stringPrefix) {
|
|
101
101
|
(0, getDynamicIcon_1.getDynamicIcon)(stringPrefix).then(function (node) { return setPrefixNode(node); });
|
|
102
|
-
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
setPrefixNode(null); // Clear when empty
|
|
105
|
+
}
|
|
106
|
+
}, [stringPrefix]);
|
|
107
|
+
(0, react_1.useEffect)(function () {
|
|
108
|
+
if (stringSuffix) {
|
|
103
109
|
(0, getDynamicIcon_1.getDynamicIcon)(stringSuffix).then(function (node) { return setSuffixNode(node); });
|
|
104
|
-
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
setSuffixNode(null); // Clear when empty
|
|
113
|
+
}
|
|
114
|
+
}, [stringSuffix]);
|
|
105
115
|
var textColorClass = final.bg
|
|
106
116
|
? final.color
|
|
107
117
|
? final.color
|
|
@@ -111,6 +121,8 @@ function Button(_a) {
|
|
|
111
121
|
? 'white'
|
|
112
122
|
: final.bg.replace(/[0-9]/g, '')
|
|
113
123
|
: final.color;
|
|
124
|
+
// Determine background: status takes priority over bg prop
|
|
125
|
+
var effectiveBg = final.status ? final.status : final.bg;
|
|
114
126
|
var classNames = [
|
|
115
127
|
'button',
|
|
116
128
|
"text-".concat(textColorClass),
|
|
@@ -128,8 +140,8 @@ function Button(_a) {
|
|
|
128
140
|
final.bigger ? 'biggerBtn' : '',
|
|
129
141
|
final.jumbo ? 'jumboBtn' : '',
|
|
130
142
|
final.outlined
|
|
131
|
-
? "outlined outline-".concat(
|
|
132
|
-
:
|
|
143
|
+
? "outlined outline-".concat(effectiveBg || '', " text-").concat(final.color ? final.color : effectiveBg === null || effectiveBg === void 0 ? void 0 : effectiveBg.replace(/[0-9]/g, ''))
|
|
144
|
+
: effectiveBg || '',
|
|
133
145
|
"".concat(final.fillAnimation ? "".concat(final.fillTextColor ? "hover-text-".concat(final.fillTextColor) : '', " button-fill fill-").concat(final.fillDirection || 'left') : ''),
|
|
134
146
|
].join(' ');
|
|
135
147
|
var iconWrapperStyle = {
|
|
@@ -140,19 +152,18 @@ function Button(_a) {
|
|
|
140
152
|
};
|
|
141
153
|
return (react_1.default.createElement("span", null,
|
|
142
154
|
react_1.default.createElement("button", __assign({ className: "".concat(classNames, " ").concat((startIcon || endIcon || prefix || suffix || prefixNode || suffixNode || final.status || final.isLoading) ? 'iconic' : ''), style: __assign({ height: mergedProps.height || '', width: mergedProps.fullWidth ? '100%' : mergedProps.width || '', borderRadius: final.flat ? '0rem' : '' }, style), onClick: onClick || (url ? function () { return (window.location.href = url); } : undefined) }, mergedProps),
|
|
143
|
-
final.isLoading
|
|
144
|
-
react_1.default.createElement(pi_1.PiSpinner, { size: iconSize }))),
|
|
145
|
-
final.status && (react_1.default.createElement("span", { className: "btn_left_icon", style: iconWrapperStyle },
|
|
155
|
+
final.isLoading ? (react_1.default.createElement("span", { className: "btn_left_icon rotate", style: iconWrapperStyle },
|
|
156
|
+
react_1.default.createElement(pi_1.PiSpinner, { size: iconSize }))) : (react_1.default.createElement(react_1.default.Fragment, null, final.status ? (react_1.default.createElement("span", { className: "btn_left_icon", style: iconWrapperStyle },
|
|
146
157
|
final.status === 'success' && react_1.default.createElement(pi_1.PiCheck, { size: iconSize }),
|
|
147
158
|
final.status === 'info' && react_1.default.createElement(pi_1.PiInfo, { size: iconSize }),
|
|
148
159
|
final.status === 'warning' && react_1.default.createElement(pi_1.PiWarning, { size: iconSize }),
|
|
149
|
-
final.status === 'danger' && react_1.default.createElement(pi_1.PiX, { size: iconSize })))
|
|
150
|
-
|
|
160
|
+
final.status === 'danger' && react_1.default.createElement(pi_1.PiX, { size: iconSize }))) : (
|
|
161
|
+
/* Otherwise show regular start icons */
|
|
151
162
|
(prefix || startIcon || prefixNode) && (react_1.default.createElement("span", { className: "btn_left_icon", style: iconWrapperStyle }, isReactElement(startIcon) ? react_1.default.cloneElement(startIcon, { size: iconSize })
|
|
152
163
|
: isReactElement(prefix) ? react_1.default.cloneElement(prefix, { size: iconSize })
|
|
153
164
|
: isReactElement(prefixNode) ? react_1.default.cloneElement(prefixNode, { size: iconSize })
|
|
154
|
-
: prefix || startIcon || prefixNode
|
|
155
|
-
)),
|
|
165
|
+
: prefix || startIcon || prefixNode))))),
|
|
166
|
+
final.fillAnimation && react_1.default.createElement("span", { className: "button_fill_span ".concat(effectiveBg) }),
|
|
156
167
|
final.text ? final.text : children,
|
|
157
168
|
(suffix || endIcon || suffixNode) && (react_1.default.createElement("span", { className: "btn_right_icon", style: iconWrapperStyle }, isReactElement(endIcon) ? react_1.default.cloneElement(endIcon, { size: iconSize })
|
|
158
169
|
: isReactElement(suffix) ? react_1.default.cloneElement(suffix, { size: iconSize })
|
package/ui/input/Input.d.ts
CHANGED
package/ui/input/Input.js
CHANGED
|
@@ -65,6 +65,7 @@ var pi_1 = require("react-icons/pi");
|
|
|
65
65
|
var Button_1 = __importDefault(require("../button/Button"));
|
|
66
66
|
var theme_1 = require("../theme/theme");
|
|
67
67
|
var componentUtils_1 = require("../../utils/componentUtils");
|
|
68
|
+
var getDynamicIcon_1 = require("../../utils/getDynamicIcon");
|
|
68
69
|
// Status icons mapping
|
|
69
70
|
var statusIcons = {
|
|
70
71
|
success: react_1.default.createElement(pi_1.PiCheckCircle, null),
|
|
@@ -83,10 +84,9 @@ var generateInputClasses = function (_a) {
|
|
|
83
84
|
var borderClass = bordered ? 'borderedInput' : borderless ? 'borderless' : (!bordered && !borderless ? 'borderedInput' : '');
|
|
84
85
|
return "\n ".concat(statusClass, "\n ").concat(roundedClass, "\n ").concat(bgClass, "\n ").concat(funcss || '', "\n ").concat(flatClass, "\n ").concat(cornerClass, "\n ").concat(borderClass, "\n ").concat(additionalClasses, "\n input\n ").trim().replace(/\s+/g, ' ');
|
|
85
86
|
};
|
|
86
|
-
// Iconic Input Wrapper Component
|
|
87
|
+
// Iconic Input Wrapper Component
|
|
87
88
|
var IconicInputWrapper = function (_a) {
|
|
88
89
|
var startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, iconicBg = _a.iconicBg, funcss = _a.funcss, children = _a.children;
|
|
89
|
-
// Use prefix/suffix if provided, otherwise fall back to startIcon/endIcon
|
|
90
90
|
var effectiveStartIcon = prefix !== undefined ? prefix : startIcon;
|
|
91
91
|
var effectiveEndIcon = suffix !== undefined ? suffix : endIcon;
|
|
92
92
|
if (!effectiveStartIcon && !effectiveEndIcon) {
|
|
@@ -114,15 +114,35 @@ var InputContainer = function (_a) {
|
|
|
114
114
|
};
|
|
115
115
|
// Text Input Component
|
|
116
116
|
var TextInput = function (_a) {
|
|
117
|
-
var id = _a.id, name = _a.name, value = _a.value, defaultValue = _a.defaultValue, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, _b = _a.fullWidth, fullWidth = _b === void 0 ? true : _b, flat = _a.flat, bordered = _a.bordered, borderless = _a.borderless, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, iconicBg = _a.iconicBg, _c = _a.type, type = _c === void 0 ? 'text' : _c, label = _a.label, helperText = _a.helperText, _d = _a.variant, variant = _d === void 0 ? '' : _d, rest = __rest(_a, ["id", "name", "value", "defaultValue", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "bordered", "borderless", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "iconicBg", "type", "label", "helperText", "variant"]);
|
|
117
|
+
var id = _a.id, name = _a.name, value = _a.value, defaultValue = _a.defaultValue, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, _b = _a.fullWidth, fullWidth = _b === void 0 ? true : _b, flat = _a.flat, bordered = _a.bordered, borderless = _a.borderless, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, iconicBg = _a.iconicBg, _c = _a.type, type = _c === void 0 ? 'text' : _c, label = _a.label, helperText = _a.helperText, _d = _a.variant, variant = _d === void 0 ? '' : _d, placeholder = _a.placeholder, rest = __rest(_a, ["id", "name", "value", "defaultValue", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "bordered", "borderless", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "stringPrefix", "stringSuffix", "iconicBg", "type", "label", "helperText", "variant", "placeholder"]);
|
|
118
118
|
var _e = (0, react_1.useState)(false), isFocused = _e[0], setIsFocused = _e[1];
|
|
119
119
|
var _f = (0, react_1.useState)(value || defaultValue || ''), inputValue = _f[0], setInputValue = _f[1];
|
|
120
|
+
var _g = (0, react_1.useState)(null), prefixNode = _g[0], setPrefixNode = _g[1];
|
|
121
|
+
var _h = (0, react_1.useState)(null), suffixNode = _h[0], setSuffixNode = _h[1];
|
|
120
122
|
var inputRef = (0, react_1.useRef)(null);
|
|
121
123
|
(0, react_1.useEffect)(function () {
|
|
122
124
|
if (value !== undefined) {
|
|
123
125
|
setInputValue(value);
|
|
124
126
|
}
|
|
125
127
|
}, [value]);
|
|
128
|
+
// Handle stringPrefix
|
|
129
|
+
(0, react_1.useEffect)(function () {
|
|
130
|
+
if (stringPrefix) {
|
|
131
|
+
(0, getDynamicIcon_1.getDynamicIcon)(stringPrefix).then(function (node) { return setPrefixNode(node); });
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
setPrefixNode(null);
|
|
135
|
+
}
|
|
136
|
+
}, [stringPrefix]);
|
|
137
|
+
// Handle stringSuffix
|
|
138
|
+
(0, react_1.useEffect)(function () {
|
|
139
|
+
if (stringSuffix) {
|
|
140
|
+
(0, getDynamicIcon_1.getDynamicIcon)(stringSuffix).then(function (node) { return setSuffixNode(node); });
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
setSuffixNode(null);
|
|
144
|
+
}
|
|
145
|
+
}, [stringSuffix]);
|
|
126
146
|
var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
|
|
127
147
|
var mergedProps = mergeWithLocal({
|
|
128
148
|
status: status,
|
|
@@ -169,23 +189,47 @@ var TextInput = function (_a) {
|
|
|
169
189
|
if (rest.onBlur)
|
|
170
190
|
rest.onBlur(e);
|
|
171
191
|
};
|
|
172
|
-
|
|
173
|
-
var
|
|
174
|
-
|
|
192
|
+
// Determine effective icons: stringPrefix/stringSuffix take priority
|
|
193
|
+
var effectivePrefix = prefixNode || mergedProps.prefix || mergedProps.startIcon;
|
|
194
|
+
var effectiveSuffix = suffixNode || mergedProps.suffix || mergedProps.endIcon;
|
|
195
|
+
// Show placeholder only when label is active (focused or has value)
|
|
196
|
+
var showPlaceholder = placeholder && label && (isFocused || !!inputValue);
|
|
197
|
+
var inputElement = (react_1.default.createElement("input", __assign({ ref: inputRef, id: id, name: name, className: className, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, defaultValue: defaultValue, type: type, placeholder: showPlaceholder ? placeholder : (!label ? placeholder : ''), style: style, value: value }, rest)));
|
|
198
|
+
var wrappedInput = (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: mergedProps.iconicBg, funcss: mergedProps.funcss }, inputElement));
|
|
199
|
+
return (react_1.default.createElement(InputContainer, { startIcon: effectivePrefix, label: label, status: mergedProps.status, helperText: helperText, isFocused: isFocused, hasValue: !!inputValue, fullWidth: mergedProps.fullWidth, id: id }, wrappedInput));
|
|
175
200
|
};
|
|
176
201
|
exports.TextInput = TextInput;
|
|
177
202
|
// Select Component
|
|
178
203
|
var SelectInput = function (_a) {
|
|
179
|
-
var id = _a.id, name = _a.name, value = _a.value, defaultValue = _a.defaultValue, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, fullWidth = _a.fullWidth, flat = _a.flat, bordered = _a.bordered, borderless = _a.borderless, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, iconicBg = _a.iconicBg, _b = _a.options, options = _b === void 0 ? [] : _b, label = _a.label, helperText = _a.helperText, _c = _a.variant, variant = _c === void 0 ? '' : _c, rest = __rest(_a, ["id", "name", "value", "defaultValue", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "bordered", "borderless", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "iconicBg", "options", "label", "helperText", "variant"]);
|
|
204
|
+
var id = _a.id, name = _a.name, value = _a.value, defaultValue = _a.defaultValue, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, fullWidth = _a.fullWidth, flat = _a.flat, bordered = _a.bordered, borderless = _a.borderless, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, iconicBg = _a.iconicBg, _b = _a.options, options = _b === void 0 ? [] : _b, label = _a.label, helperText = _a.helperText, _c = _a.variant, variant = _c === void 0 ? '' : _c, rest = __rest(_a, ["id", "name", "value", "defaultValue", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "bordered", "borderless", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "stringPrefix", "stringSuffix", "iconicBg", "options", "label", "helperText", "variant"]);
|
|
180
205
|
var _d = (0, react_1.useState)(false), isFocused = _d[0], setIsFocused = _d[1];
|
|
181
206
|
var _e = (0, react_1.useState)(value || defaultValue || ''), selectValue = _e[0], setSelectValue = _e[1];
|
|
207
|
+
var _f = (0, react_1.useState)(null), prefixNode = _f[0], setPrefixNode = _f[1];
|
|
208
|
+
var _g = (0, react_1.useState)(null), suffixNode = _g[0], setSuffixNode = _g[1];
|
|
182
209
|
(0, react_1.useEffect)(function () {
|
|
183
210
|
if (value !== undefined) {
|
|
184
211
|
setSelectValue(value);
|
|
185
212
|
}
|
|
186
213
|
}, [value]);
|
|
187
|
-
//
|
|
188
|
-
|
|
214
|
+
// Handle stringPrefix
|
|
215
|
+
(0, react_1.useEffect)(function () {
|
|
216
|
+
if (stringPrefix) {
|
|
217
|
+
(0, getDynamicIcon_1.getDynamicIcon)(stringPrefix).then(function (node) { return setPrefixNode(node); });
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
setPrefixNode(null);
|
|
221
|
+
}
|
|
222
|
+
}, [stringPrefix]);
|
|
223
|
+
// Handle stringSuffix
|
|
224
|
+
(0, react_1.useEffect)(function () {
|
|
225
|
+
if (stringSuffix) {
|
|
226
|
+
(0, getDynamicIcon_1.getDynamicIcon)(stringSuffix).then(function (node) { return setSuffixNode(node); });
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
setSuffixNode(null);
|
|
230
|
+
}
|
|
231
|
+
}, [stringSuffix]);
|
|
232
|
+
var selectHasValue = true;
|
|
189
233
|
var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
|
|
190
234
|
var mergedProps = mergeWithLocal({
|
|
191
235
|
status: status,
|
|
@@ -232,21 +276,43 @@ var SelectInput = function (_a) {
|
|
|
232
276
|
if (rest.onBlur)
|
|
233
277
|
rest.onBlur(e);
|
|
234
278
|
};
|
|
279
|
+
var effectivePrefix = prefixNode || mergedProps.prefix || mergedProps.startIcon;
|
|
280
|
+
var effectiveSuffix = suffixNode || mergedProps.suffix || mergedProps.endIcon;
|
|
235
281
|
var selectElement = (react_1.default.createElement("select", __assign({ id: id, name: name, className: className, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, defaultValue: defaultValue, value: value, style: style }, rest), options.map(function (option) { return (react_1.default.createElement("option", { key: option.value, value: option.value }, option.text)); })));
|
|
236
|
-
var wrappedSelect = (react_1.default.createElement(IconicInputWrapper, { startIcon:
|
|
237
|
-
return (react_1.default.createElement(InputContainer, { startIcon:
|
|
282
|
+
var wrappedSelect = (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: mergedProps.iconicBg, funcss: mergedProps.funcss }, selectElement));
|
|
283
|
+
return (react_1.default.createElement(InputContainer, { startIcon: effectivePrefix, label: label, status: mergedProps.status, helperText: helperText, isFocused: isFocused, hasValue: selectHasValue, fullWidth: mergedProps.fullWidth, id: id }, wrappedSelect));
|
|
238
284
|
};
|
|
239
285
|
exports.SelectInput = SelectInput;
|
|
240
286
|
// Textarea Component
|
|
241
287
|
var TextareaInput = function (_a) {
|
|
242
|
-
var id = _a.id, name = _a.name, value = _a.value, defaultValue = _a.defaultValue, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, fullWidth = _a.fullWidth, flat = _a.flat, bordered = _a.bordered, borderless = _a.borderless, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, iconicBg = _a.iconicBg, label = _a.label, helperText = _a.helperText, _b = _a.rows, rows = _b === void 0 ? 2 : _b, _c = _a.variant, variant = _c === void 0 ? '' : _c, rest = __rest(_a, ["id", "name", "value", "defaultValue", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "bordered", "borderless", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "iconicBg", "label", "helperText", "rows", "variant"]);
|
|
288
|
+
var id = _a.id, name = _a.name, value = _a.value, defaultValue = _a.defaultValue, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, fullWidth = _a.fullWidth, flat = _a.flat, bordered = _a.bordered, borderless = _a.borderless, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, iconicBg = _a.iconicBg, label = _a.label, helperText = _a.helperText, _b = _a.rows, rows = _b === void 0 ? 2 : _b, _c = _a.variant, variant = _c === void 0 ? '' : _c, placeholder = _a.placeholder, rest = __rest(_a, ["id", "name", "value", "defaultValue", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "bordered", "borderless", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "stringPrefix", "stringSuffix", "iconicBg", "label", "helperText", "rows", "variant", "placeholder"]);
|
|
243
289
|
var _d = (0, react_1.useState)(false), isFocused = _d[0], setIsFocused = _d[1];
|
|
244
290
|
var _e = (0, react_1.useState)(value || defaultValue || ''), textValue = _e[0], setTextValue = _e[1];
|
|
291
|
+
var _f = (0, react_1.useState)(null), prefixNode = _f[0], setPrefixNode = _f[1];
|
|
292
|
+
var _g = (0, react_1.useState)(null), suffixNode = _g[0], setSuffixNode = _g[1];
|
|
245
293
|
(0, react_1.useEffect)(function () {
|
|
246
294
|
if (value !== undefined) {
|
|
247
295
|
setTextValue(value);
|
|
248
296
|
}
|
|
249
297
|
}, [value]);
|
|
298
|
+
// Handle stringPrefix
|
|
299
|
+
(0, react_1.useEffect)(function () {
|
|
300
|
+
if (stringPrefix) {
|
|
301
|
+
(0, getDynamicIcon_1.getDynamicIcon)(stringPrefix).then(function (node) { return setPrefixNode(node); });
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
setPrefixNode(null);
|
|
305
|
+
}
|
|
306
|
+
}, [stringPrefix]);
|
|
307
|
+
// Handle stringSuffix
|
|
308
|
+
(0, react_1.useEffect)(function () {
|
|
309
|
+
if (stringSuffix) {
|
|
310
|
+
(0, getDynamicIcon_1.getDynamicIcon)(stringSuffix).then(function (node) { return setSuffixNode(node); });
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
setSuffixNode(null);
|
|
314
|
+
}
|
|
315
|
+
}, [stringSuffix]);
|
|
250
316
|
var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
|
|
251
317
|
var mergedProps = mergeWithLocal({
|
|
252
318
|
status: status,
|
|
@@ -293,15 +359,39 @@ var TextareaInput = function (_a) {
|
|
|
293
359
|
if (rest.onBlur)
|
|
294
360
|
rest.onBlur(e);
|
|
295
361
|
};
|
|
296
|
-
var
|
|
297
|
-
var
|
|
298
|
-
|
|
362
|
+
var effectivePrefix = prefixNode || mergedProps.prefix || mergedProps.startIcon;
|
|
363
|
+
var effectiveSuffix = suffixNode || mergedProps.suffix || mergedProps.endIcon;
|
|
364
|
+
// Show placeholder only when label is active (focused or has value)
|
|
365
|
+
var showPlaceholder = placeholder && label && (isFocused || !!textValue);
|
|
366
|
+
var textareaElement = (react_1.default.createElement("textarea", __assign({ id: id, name: name, className: className, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, defaultValue: defaultValue, placeholder: showPlaceholder ? placeholder : (!label ? placeholder : ''), style: style, value: value, rows: rows }, rest)));
|
|
367
|
+
var wrappedTextarea = (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: mergedProps.iconicBg, funcss: mergedProps.funcss }, textareaElement));
|
|
368
|
+
return (react_1.default.createElement(InputContainer, { startIcon: effectivePrefix, label: label, status: mergedProps.status, helperText: helperText, isFocused: isFocused, hasValue: !!textValue, fullWidth: mergedProps.fullWidth, id: id }, wrappedTextarea));
|
|
299
369
|
};
|
|
300
370
|
exports.TextareaInput = TextareaInput;
|
|
301
371
|
// File Input Component
|
|
302
372
|
var FileInput = function (_a) {
|
|
303
|
-
var _b = _a.id, id = _b === void 0 ? 'fileInput' : _b, name = _a.name, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, fullWidth = _a.fullWidth, flat = _a.flat, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, iconicBg = _a.iconicBg, _c = _a.label, label = _c === void 0 ? 'Upload File' : _c, helperText = _a.helperText, icon = _a.icon, extra = _a.extra, button = _a.button, btn = _a.btn, value = _a.value, _d = _a.variant, variant = _d === void 0 ? '' : _d, rest = __rest(_a, ["id", "name", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "iconicBg", "label", "helperText", "icon", "extra", "button", "btn", "value", "variant"]);
|
|
373
|
+
var _b = _a.id, id = _b === void 0 ? 'fileInput' : _b, name = _a.name, onChange = _a.onChange, status = _a.status, funcss = _a.funcss, bg = _a.bg, fullWidth = _a.fullWidth, flat = _a.flat, rounded = _a.rounded, leftRounded = _a.leftRounded, rightRounded = _a.rightRounded, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, iconicBg = _a.iconicBg, _c = _a.label, label = _c === void 0 ? 'Upload File' : _c, helperText = _a.helperText, icon = _a.icon, extra = _a.extra, button = _a.button, btn = _a.btn, value = _a.value, _d = _a.variant, variant = _d === void 0 ? '' : _d, rest = __rest(_a, ["id", "name", "onChange", "status", "funcss", "bg", "fullWidth", "flat", "rounded", "leftRounded", "rightRounded", "startIcon", "endIcon", "prefix", "suffix", "stringPrefix", "stringSuffix", "iconicBg", "label", "helperText", "icon", "extra", "button", "btn", "value", "variant"]);
|
|
304
374
|
var _e = (0, react_1.useState)(''), fileName = _e[0], setFileName = _e[1];
|
|
375
|
+
var _f = (0, react_1.useState)(null), prefixNode = _f[0], setPrefixNode = _f[1];
|
|
376
|
+
var _g = (0, react_1.useState)(null), suffixNode = _g[0], setSuffixNode = _g[1];
|
|
377
|
+
// Handle stringPrefix
|
|
378
|
+
(0, react_1.useEffect)(function () {
|
|
379
|
+
if (stringPrefix) {
|
|
380
|
+
(0, getDynamicIcon_1.getDynamicIcon)(stringPrefix).then(function (node) { return setPrefixNode(node); });
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
setPrefixNode(null);
|
|
384
|
+
}
|
|
385
|
+
}, [stringPrefix]);
|
|
386
|
+
// Handle stringSuffix
|
|
387
|
+
(0, react_1.useEffect)(function () {
|
|
388
|
+
if (stringSuffix) {
|
|
389
|
+
(0, getDynamicIcon_1.getDynamicIcon)(stringSuffix).then(function (node) { return setSuffixNode(node); });
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
setSuffixNode(null);
|
|
393
|
+
}
|
|
394
|
+
}, [stringSuffix]);
|
|
305
395
|
var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
|
|
306
396
|
var mergedProps = mergeWithLocal({
|
|
307
397
|
status: status,
|
|
@@ -330,6 +420,8 @@ var FileInput = function (_a) {
|
|
|
330
420
|
if (onChange)
|
|
331
421
|
onChange(e);
|
|
332
422
|
};
|
|
423
|
+
var effectivePrefix = prefixNode || mergedProps.prefix || mergedProps.startIcon;
|
|
424
|
+
var effectiveSuffix = suffixNode || mergedProps.suffix || mergedProps.endIcon;
|
|
333
425
|
if (btn) {
|
|
334
426
|
var className = generateInputClasses({
|
|
335
427
|
status: mergedProps.status,
|
|
@@ -347,8 +439,8 @@ var FileInput = function (_a) {
|
|
|
347
439
|
var fileInputElement = (react_1.default.createElement("div", { className: "fileInput" },
|
|
348
440
|
button || (react_1.default.createElement(Button_1.default, { funcss: mergedProps.funcss, startIcon: icon || react_1.default.createElement(pi_1.PiCloudArrowUp, null), bg: "primary", fullWidth: true, raised: true }, fileName || label)),
|
|
349
441
|
react_1.default.createElement("input", __assign({ id: id, name: name, className: className, onChange: handleChange, type: "file", style: style, value: value }, rest))));
|
|
350
|
-
var wrappedFileInput = (react_1.default.createElement(IconicInputWrapper, { startIcon:
|
|
351
|
-
return (react_1.default.createElement(InputContainer, { startIcon:
|
|
442
|
+
var wrappedFileInput = (react_1.default.createElement(IconicInputWrapper, { startIcon: effectivePrefix, endIcon: effectiveSuffix, iconicBg: mergedProps.iconicBg, funcss: mergedProps.funcss }, fileInputElement));
|
|
443
|
+
return (react_1.default.createElement(InputContainer, { startIcon: effectivePrefix, label: undefined, status: mergedProps.status, helperText: helperText, isFocused: false, hasValue: !!fileName, fullWidth: mergedProps.fullWidth, id: id }, wrappedFileInput));
|
|
352
444
|
}
|
|
353
445
|
var uploadElement = (react_1.default.createElement("div", { className: "_upload_container" },
|
|
354
446
|
react_1.default.createElement("label", { htmlFor: id, className: "_upload_label" },
|
|
@@ -362,14 +454,14 @@ var FileInput = function (_a) {
|
|
|
362
454
|
} }, fileName || label),
|
|
363
455
|
extra && react_1.default.createElement("div", { className: "text-small opacity-3" }, extra)),
|
|
364
456
|
react_1.default.createElement("input", __assign({ onChange: handleChange, type: "file", id: id, className: "_upload_input" }, rest))));
|
|
365
|
-
return (react_1.default.createElement(InputContainer, { startIcon:
|
|
457
|
+
return (react_1.default.createElement(InputContainer, { startIcon: effectivePrefix, label: undefined, status: mergedProps.status, helperText: helperText, isFocused: false, hasValue: !!fileName, fullWidth: mergedProps.fullWidth, id: id }, uploadElement));
|
|
366
458
|
};
|
|
367
459
|
exports.FileInput = FileInput;
|
|
368
460
|
var Input = function (_a) {
|
|
369
|
-
var select = _a.select, multiline = _a.multiline, file = _a.file, noBorder = _a.noBorder, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, iconicBg = _a.iconicBg, _b = _a.variant, variant = _b === void 0 ? '' : _b, props = __rest(_a, ["select", "multiline", "file", "noBorder", "startIcon", "endIcon", "prefix", "suffix", "iconicBg", "variant"]);
|
|
461
|
+
var select = _a.select, multiline = _a.multiline, file = _a.file, noBorder = _a.noBorder, startIcon = _a.startIcon, endIcon = _a.endIcon, prefix = _a.prefix, suffix = _a.suffix, stringPrefix = _a.stringPrefix, stringSuffix = _a.stringSuffix, iconicBg = _a.iconicBg, _b = _a.variant, variant = _b === void 0 ? '' : _b, props = __rest(_a, ["select", "multiline", "file", "noBorder", "startIcon", "endIcon", "prefix", "suffix", "stringPrefix", "stringSuffix", "iconicBg", "variant"]);
|
|
370
462
|
var mergeWithLocal = (0, componentUtils_1.useComponentConfiguration)('Input', variant).mergeWithLocal;
|
|
371
463
|
var mergedProps = mergeWithLocal(__assign(__assign({}, props), { startIcon: startIcon, endIcon: endIcon, prefix: prefix, suffix: suffix, iconicBg: iconicBg })).props;
|
|
372
|
-
var inputProps = __assign(__assign(__assign({}, props), mergedProps), { variant: variant, borderless: noBorder !== undefined ? noBorder : (props.borderless !== undefined ? props.borderless : mergedProps.borderless) });
|
|
464
|
+
var inputProps = __assign(__assign(__assign({}, props), mergedProps), { variant: variant, stringPrefix: stringPrefix, stringSuffix: stringSuffix, borderless: noBorder !== undefined ? noBorder : (props.borderless !== undefined ? props.borderless : mergedProps.borderless) });
|
|
373
465
|
if (select) {
|
|
374
466
|
return react_1.default.createElement(exports.SelectInput, __assign({}, inputProps));
|
|
375
467
|
}
|
package/ui/theme/theme.js
CHANGED
|
@@ -74,11 +74,6 @@ exports.useGlobalConfig = exports.useColors = exports.useComponentConfig = expor
|
|
|
74
74
|
var react_1 = __importStar(require("react"));
|
|
75
75
|
var themes_1 = require("./themes");
|
|
76
76
|
var darkenUtils_1 = require("./darkenUtils");
|
|
77
|
-
var firestore_1 = require("firebase/firestore");
|
|
78
|
-
var db;
|
|
79
|
-
if (typeof window !== 'undefined') {
|
|
80
|
-
db = require('../../utils/Firebase').default;
|
|
81
|
-
}
|
|
82
77
|
var ThemeContext = (0, react_1.createContext)({
|
|
83
78
|
variant: 'standard',
|
|
84
79
|
setVariant: function () { },
|
|
@@ -96,7 +91,6 @@ var useTheme = function () {
|
|
|
96
91
|
return context;
|
|
97
92
|
};
|
|
98
93
|
exports.useTheme = useTheme;
|
|
99
|
-
// Backward compatibility
|
|
100
94
|
var useVariant = function () {
|
|
101
95
|
var _a = (0, exports.useTheme)(), variant = _a.variant, setVariant = _a.setVariant;
|
|
102
96
|
return { variant: variant, setVariant: setVariant };
|
|
@@ -107,6 +101,7 @@ exports.useVariant = useVariant;
|
|
|
107
101
|
/* -------------------------------------------------------------------------- */
|
|
108
102
|
var CACHE_KEY = 'funui_theme_cache';
|
|
109
103
|
var CACHE_EXPIRY = 1000 * 60 * 60; // 1 hour
|
|
104
|
+
var POLL_INTERVAL = 5 * 60 * 1000; // Check for updates every 5 minutes
|
|
110
105
|
var getThemeFromCache = function (projectId) {
|
|
111
106
|
if (typeof window === 'undefined')
|
|
112
107
|
return null;
|
|
@@ -135,6 +130,7 @@ var saveThemeToCache = function (projectId, data) {
|
|
|
135
130
|
projectId: projectId,
|
|
136
131
|
data: data,
|
|
137
132
|
timestamp: Date.now(),
|
|
133
|
+
version: data.version || Date.now(),
|
|
138
134
|
};
|
|
139
135
|
localStorage.setItem("".concat(CACHE_KEY, "_").concat(projectId), JSON.stringify(cache));
|
|
140
136
|
}
|
|
@@ -143,49 +139,56 @@ var saveThemeToCache = function (projectId, data) {
|
|
|
143
139
|
}
|
|
144
140
|
};
|
|
145
141
|
/* -------------------------------------------------------------------------- */
|
|
146
|
-
/*
|
|
142
|
+
/* CDN THEME LOADER (NO TOKEN!) */
|
|
147
143
|
/* -------------------------------------------------------------------------- */
|
|
148
|
-
var
|
|
149
|
-
var
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
144
|
+
var loadThemeFromCDN = function (projectId) { return __awaiter(void 0, void 0, void 0, function () {
|
|
145
|
+
var publicResponse, data, error_1, publicUrl, response, data, error_2;
|
|
146
|
+
return __generator(this, function (_a) {
|
|
147
|
+
switch (_a.label) {
|
|
148
|
+
case 0:
|
|
149
|
+
_a.trys.push([0, 4, , 5]);
|
|
150
|
+
return [4 /*yield*/, fetch("/funui.json", {
|
|
151
|
+
cache: 'no-cache',
|
|
152
|
+
})];
|
|
153
|
+
case 1:
|
|
154
|
+
publicResponse = _a.sent();
|
|
155
|
+
if (!publicResponse.ok) return [3 /*break*/, 3];
|
|
156
|
+
return [4 /*yield*/, publicResponse.json()];
|
|
157
|
+
case 2:
|
|
158
|
+
data = _a.sent();
|
|
159
|
+
console.log('✅ Loaded theme from public folder');
|
|
160
|
+
return [2 /*return*/, data];
|
|
161
|
+
case 3: return [3 /*break*/, 5];
|
|
162
|
+
case 4:
|
|
163
|
+
error_1 = _a.sent();
|
|
164
|
+
console.log('No theme in public folder, checking Firebase Storage...');
|
|
165
|
+
return [3 /*break*/, 5];
|
|
166
|
+
case 5:
|
|
167
|
+
_a.trys.push([5, 10, , 11]);
|
|
168
|
+
publicUrl = "https://firebasestorage.googleapis.com/v0/b/funui-4bcd1.firebasestorage.app/o/themes%2F".concat(projectId, ".json?alt=media");
|
|
169
|
+
return [4 /*yield*/, fetch(publicUrl, {
|
|
170
|
+
cache: 'no-cache',
|
|
171
|
+
})];
|
|
172
|
+
case 6:
|
|
173
|
+
response = _a.sent();
|
|
174
|
+
if (!response.ok) return [3 /*break*/, 8];
|
|
175
|
+
return [4 /*yield*/, response.json()];
|
|
176
|
+
case 7:
|
|
177
|
+
data = _a.sent();
|
|
178
|
+
console.log('✅ Loaded theme from Firebase Storage (public CDN)');
|
|
179
|
+
return [2 /*return*/, data];
|
|
180
|
+
case 8:
|
|
181
|
+
console.error('Firebase Storage fetch failed:', response.status, response.statusText);
|
|
182
|
+
_a.label = 9;
|
|
183
|
+
case 9: return [3 /*break*/, 11];
|
|
184
|
+
case 10:
|
|
185
|
+
error_2 = _a.sent();
|
|
186
|
+
console.error('Error loading from Firebase Storage:', error_2);
|
|
187
|
+
return [3 /*break*/, 11];
|
|
188
|
+
case 11: return [2 /*return*/, null];
|
|
186
189
|
}
|
|
187
|
-
};
|
|
188
|
-
};
|
|
190
|
+
});
|
|
191
|
+
}); };
|
|
189
192
|
/* -------------------------------------------------------------------------- */
|
|
190
193
|
/* COMPONENT */
|
|
191
194
|
/* -------------------------------------------------------------------------- */
|
|
@@ -197,6 +200,7 @@ var ThemeProvider = function (_a) {
|
|
|
197
200
|
var _g = (0, react_1.useState)(true), isLoading = _g[0], setIsLoading = _g[1];
|
|
198
201
|
var _h = (0, react_1.useState)(true), isInitialLoad = _h[0], setIsInitialLoad = _h[1];
|
|
199
202
|
var _j = (0, react_1.useState)(null), error = _j[0], setError = _j[1];
|
|
203
|
+
var _k = (0, react_1.useState)(null), currentVersion = _k[0], setCurrentVersion = _k[1];
|
|
200
204
|
/* -------------------------- Apply base theme --------------------------- */
|
|
201
205
|
(0, react_1.useEffect)(function () {
|
|
202
206
|
var root = document.documentElement;
|
|
@@ -218,7 +222,7 @@ var ThemeProvider = function (_a) {
|
|
|
218
222
|
});
|
|
219
223
|
}
|
|
220
224
|
}, [theme]);
|
|
221
|
-
/* ----------------------
|
|
225
|
+
/* ---------------------- CDN Theme Sync (No Token!) ----------------------- */
|
|
222
226
|
(0, react_1.useEffect)(function () {
|
|
223
227
|
if (typeof window === 'undefined' || !projectId) {
|
|
224
228
|
setIsLoading(false);
|
|
@@ -226,34 +230,51 @@ var ThemeProvider = function (_a) {
|
|
|
226
230
|
return;
|
|
227
231
|
}
|
|
228
232
|
var root = document.documentElement;
|
|
229
|
-
|
|
233
|
+
var pollTimer;
|
|
234
|
+
// Step 1: Load from cache immediately
|
|
230
235
|
var cachedTheme = getThemeFromCache(projectId);
|
|
231
236
|
if (cachedTheme) {
|
|
232
237
|
applyThemeData(cachedTheme, root);
|
|
238
|
+
setCurrentVersion(cachedTheme.version || null);
|
|
233
239
|
setIsLoading(false);
|
|
234
|
-
|
|
240
|
+
console.log('✅ Using cached theme');
|
|
235
241
|
}
|
|
236
|
-
// Step 2: Fetch
|
|
237
|
-
var
|
|
238
|
-
var
|
|
242
|
+
// Step 2: Fetch from CDN
|
|
243
|
+
var fetchFromCDN = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
244
|
+
var cdnTheme, newVersion, err_1;
|
|
239
245
|
return __generator(this, function (_a) {
|
|
240
246
|
switch (_a.label) {
|
|
241
247
|
case 0:
|
|
242
248
|
_a.trys.push([0, 2, 3, 4]);
|
|
243
|
-
|
|
244
|
-
return [4 /*yield*/, (0, firestore_1.getDoc)(docRef)];
|
|
249
|
+
return [4 /*yield*/, loadThemeFromCDN(projectId)];
|
|
245
250
|
case 1:
|
|
246
|
-
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
+
cdnTheme = _a.sent();
|
|
252
|
+
if (cdnTheme) {
|
|
253
|
+
newVersion = cdnTheme.version || Date.now();
|
|
254
|
+
if (!currentVersion || newVersion !== currentVersion) {
|
|
255
|
+
applyThemeData(cdnTheme, root);
|
|
256
|
+
saveThemeToCache(projectId, cdnTheme);
|
|
257
|
+
setCurrentVersion(newVersion);
|
|
258
|
+
console.log('✅ Theme updated from CDN');
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
console.log('✓ Theme unchanged');
|
|
262
|
+
}
|
|
263
|
+
setError(null);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
console.warn('⚠️ No theme found in CDN');
|
|
267
|
+
if (!cachedTheme) {
|
|
268
|
+
setError('Theme not found');
|
|
269
|
+
}
|
|
251
270
|
}
|
|
252
271
|
return [3 /*break*/, 4];
|
|
253
272
|
case 2:
|
|
254
273
|
err_1 = _a.sent();
|
|
255
|
-
console.error('Error
|
|
256
|
-
|
|
274
|
+
console.error('Error loading theme from CDN:', err_1);
|
|
275
|
+
if (!cachedTheme) {
|
|
276
|
+
setError('Failed to load theme');
|
|
277
|
+
}
|
|
257
278
|
return [3 /*break*/, 4];
|
|
258
279
|
case 3:
|
|
259
280
|
setIsLoading(false);
|
|
@@ -263,21 +284,21 @@ var ThemeProvider = function (_a) {
|
|
|
263
284
|
}
|
|
264
285
|
});
|
|
265
286
|
}); };
|
|
266
|
-
// Only fetch if no cache
|
|
267
287
|
if (!cachedTheme) {
|
|
268
|
-
|
|
288
|
+
fetchFromCDN();
|
|
269
289
|
}
|
|
270
290
|
else {
|
|
271
|
-
// We have cache, mark as loaded after short delay
|
|
272
291
|
setTimeout(function () { return setIsInitialLoad(false); }, 100);
|
|
292
|
+
fetchFromCDN();
|
|
273
293
|
}
|
|
274
|
-
// Step 3:
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
});
|
|
278
|
-
return
|
|
279
|
-
|
|
280
|
-
|
|
294
|
+
// Step 3: Poll for updates every 5 minutes
|
|
295
|
+
pollTimer = setInterval(function () {
|
|
296
|
+
fetchFromCDN();
|
|
297
|
+
}, POLL_INTERVAL);
|
|
298
|
+
return function () {
|
|
299
|
+
clearInterval(pollTimer);
|
|
300
|
+
};
|
|
301
|
+
}, [projectId, currentVersion]);
|
|
281
302
|
var applyThemeData = function (data, root) {
|
|
282
303
|
var _a;
|
|
283
304
|
var config = (_a = data.theme_config) !== null && _a !== void 0 ? _a : {};
|
|
@@ -285,13 +306,11 @@ var ThemeProvider = function (_a) {
|
|
|
285
306
|
setVariant(newVariant);
|
|
286
307
|
setThemeConfig(config);
|
|
287
308
|
setProjectData(data);
|
|
288
|
-
// Apply CSS variables
|
|
289
309
|
Object.entries(config).forEach(function (_a) {
|
|
290
310
|
var key = _a[0], value = _a[1];
|
|
291
311
|
root.style.setProperty(key.startsWith('--') ? key : "--".concat(key), String(value));
|
|
292
312
|
});
|
|
293
313
|
};
|
|
294
|
-
/* Memoize context value to prevent unnecessary re-renders */
|
|
295
314
|
var contextValue = (0, react_1.useMemo)(function () { return ({
|
|
296
315
|
variant: variant,
|
|
297
316
|
setVariant: setVariant,
|
|
@@ -301,40 +320,32 @@ var ThemeProvider = function (_a) {
|
|
|
301
320
|
isInitialLoad: isInitialLoad,
|
|
302
321
|
error: error,
|
|
303
322
|
}); }, [variant, themeConfig, projectData, isLoading, isInitialLoad, error]);
|
|
304
|
-
/* ------------------------------- Render ------------------------------- */
|
|
305
323
|
return (react_1.default.createElement(ThemeContext.Provider, { value: contextValue },
|
|
306
324
|
react_1.default.createElement("div", { className: "theme-".concat(theme, " ").concat(funcss), style: {
|
|
307
325
|
backgroundColor: 'var(--page-bg)',
|
|
308
326
|
color: 'var(--text-color)',
|
|
309
327
|
minHeight: minHeight,
|
|
310
|
-
// Smooth transition when theme changes
|
|
311
328
|
transition: isInitialLoad ? 'none' : 'background-color 0.3s ease, color 0.3s ease',
|
|
312
329
|
} }, children)));
|
|
313
330
|
};
|
|
314
331
|
exports.default = ThemeProvider;
|
|
315
|
-
|
|
316
|
-
/* HELPER HOOKS */
|
|
317
|
-
/* -------------------------------------------------------------------------- */
|
|
318
|
-
// Hook to get specific theme values
|
|
332
|
+
// Helper hooks
|
|
319
333
|
var useThemeValue = function (key) {
|
|
320
334
|
var themeConfig = (0, exports.useTheme)().themeConfig;
|
|
321
335
|
return themeConfig[key];
|
|
322
336
|
};
|
|
323
337
|
exports.useThemeValue = useThemeValue;
|
|
324
|
-
// Hook to get component-specific config
|
|
325
338
|
var useComponentConfig = function (componentName) {
|
|
326
339
|
var _a;
|
|
327
340
|
var projectData = (0, exports.useTheme)().projectData;
|
|
328
341
|
return ((_a = projectData === null || projectData === void 0 ? void 0 : projectData.components) === null || _a === void 0 ? void 0 : _a[componentName]) || {};
|
|
329
342
|
};
|
|
330
343
|
exports.useComponentConfig = useComponentConfig;
|
|
331
|
-
// Hook to get colors
|
|
332
344
|
var useColors = function () {
|
|
333
345
|
var projectData = (0, exports.useTheme)().projectData;
|
|
334
346
|
return (projectData === null || projectData === void 0 ? void 0 : projectData.colors) || {};
|
|
335
347
|
};
|
|
336
348
|
exports.useColors = useColors;
|
|
337
|
-
// Hook to get global config
|
|
338
349
|
var useGlobalConfig = function () {
|
|
339
350
|
var projectData = (0, exports.useTheme)().projectData;
|
|
340
351
|
return (projectData === null || projectData === void 0 ? void 0 : projectData.global) || {};
|