@foxeltech/angular-ui 0.7.44 → 0.7.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/components.css +320 -18
  2. package/familjen-grotesk/familjen-grotesk-400-latin-ext.woff2 +0 -0
  3. package/familjen-grotesk/familjen-grotesk-400-latin.woff2 +0 -0
  4. package/familjen-grotesk/familjen-grotesk-400-vietnamese.woff2 +0 -0
  5. package/familjen-grotesk/familjen-grotesk-500-latin-ext.woff2 +0 -0
  6. package/familjen-grotesk/familjen-grotesk-500-latin.woff2 +0 -0
  7. package/familjen-grotesk/familjen-grotesk-500-vietnamese.woff2 +0 -0
  8. package/familjen-grotesk/familjen-grotesk-600-latin-ext.woff2 +0 -0
  9. package/familjen-grotesk/familjen-grotesk-600-latin.woff2 +0 -0
  10. package/familjen-grotesk/familjen-grotesk-600-vietnamese.woff2 +0 -0
  11. package/familjen-grotesk/familjen-grotesk-700-latin-ext.woff2 +0 -0
  12. package/familjen-grotesk/familjen-grotesk-700-latin.woff2 +0 -0
  13. package/familjen-grotesk/familjen-grotesk-700-vietnamese.woff2 +0 -0
  14. package/fesm2022/foxeltech-angular-ui-chart.mjs +197 -24
  15. package/fesm2022/foxeltech-angular-ui-chart.mjs.map +1 -1
  16. package/fesm2022/foxeltech-angular-ui.mjs +504 -108
  17. package/fesm2022/foxeltech-angular-ui.mjs.map +1 -1
  18. package/fonts.css +104 -3
  19. package/package.json +1 -1
  20. package/src/lib/styles/components.css +320 -18
  21. package/src/lib/styles/fonts.css +104 -3
  22. package/src/lib/styles/tailwind.css +12 -0
  23. package/src/lib/styles/theme.css +160 -114
  24. package/src/lib/styles/tokens.css +25 -0
  25. package/src/lib/styles/utilities.css +12 -0
  26. package/src/lib/ui/components/button/button.component.html +2 -0
  27. package/src/lib/ui/components/drawer/drawer.component.scss +3 -1
  28. package/src/lib/ui/components/facets-rail/facets-rail.component.html +1 -6
  29. package/src/lib/ui/components/master-detail/master-detail.component.css +65 -13
  30. package/src/lib/ui/components/master-detail/master-detail.component.html +26 -8
  31. package/src/lib/ui/components/route-skeleton/route-skeleton.component.css +38 -0
  32. package/src/lib/ui/components/route-skeleton/route-skeleton.component.html +184 -0
  33. package/src/lib/ui/components/section-card/section-card.component.html +1 -5
  34. package/src/lib/ui/components/skeleton-dashboard/skeleton-dashboard.component.html +24 -0
  35. package/src/lib/ui/components/skeleton-detail/skeleton-detail.component.html +8 -8
  36. package/src/lib/ui/components/skeleton-facets/skeleton-facets.component.html +15 -0
  37. package/src/lib/ui/components/skeleton-frame/skeleton-frame.component.html +59 -0
  38. package/src/lib/ui/components/skeleton-list/skeleton-list.component.html +6 -6
  39. package/src/lib/ui/components/switch/switch.component.html +1 -1
  40. package/src/lib/ui/components/toast/toast.component.html +6 -6
  41. package/tailwind.css +12 -0
  42. package/theme.css +160 -114
  43. package/tokens.css +25 -0
  44. package/types/foxeltech-angular-ui-chart.d.ts +76 -1
  45. package/types/foxeltech-angular-ui.d.ts +278 -33
  46. package/utilities.css +12 -0
  47. package/src/lib/ui/components/skeleton-table-loading/skeleton-table-loading.component.html +0 -21
  48. package/src/lib/ui/components/skeleton-table-loading/skeleton-table-loading.component.scss +0 -0
  49. package/src/lib/ui/components/tab-component/tab.component.html +0 -1
package/components.css CHANGED
@@ -299,23 +299,35 @@ input[type='password'] {
299
299
  .txt-tag-default {
300
300
  @apply txt-tag-common text-text-secondary;
301
301
  }
302
+ /* ---- fx-ui-tag: tông theo hệ MỚI ------------------------------------
303
+ `fx-ui-tag` là tag DÙNG CHUNG (priority, status, category…), không phải
304
+ badge severity đứng một mình — nên nền mềm theo THANG ĐO (`--og-sev-*` pha
305
+ loãng), KHÔNG dùng pill đen đặc của `.tone-tint-critical`. Trước đây trỏ
306
+ vào bộ LEGACY vivid (`bg-critical/20` → hồng #fe0453) nên mọi badge trong
307
+ list ở mọi tab vẫn ra màu cũ (anh Tú báo 03/09). */
302
308
  .txt-tag-success {
303
- @apply txt-tag-common text-success;
309
+ @apply txt-tag-common;
310
+ color: rgb(var(--og-positive));
304
311
  }
305
312
  .txt-tag-warning {
306
- @apply txt-tag-common text-warning;
313
+ @apply txt-tag-common;
314
+ color: rgb(var(--og-warning));
307
315
  }
308
316
  .txt-tag-critical {
309
- @apply txt-tag-common text-critical;
317
+ @apply txt-tag-common;
318
+ color: rgb(var(--og-sev-critical));
310
319
  }
311
320
  .txt-tag-danger {
312
- @apply txt-tag-common text-danger;
321
+ @apply txt-tag-common;
322
+ color: rgb(var(--og-sev-danger));
313
323
  }
314
324
  .txt-tag-information {
315
- @apply txt-tag-common text-information;
325
+ @apply txt-tag-common;
326
+ color: rgb(var(--og-neutral-soft-fg));
316
327
  }
317
328
  .txt-tag-discovery {
318
- @apply txt-tag-common text-discovery;
329
+ @apply txt-tag-common;
330
+ color: rgb(var(--og-accent-soft-fg));
319
331
  }
320
332
  .txt-link {
321
333
  @apply font-semibold text-text-link text-sm tracking-normal;
@@ -336,6 +348,267 @@ input[type='password'] {
336
348
  .btn-success {
337
349
  @apply btn-common bg-gradient-success hover:opacity-75 text-surface;
338
350
  }
351
+ /* Nút hành động chính theo demo (`.bi-newbtn`): màu cố định, không phải accent. */
352
+ /* ---- Tông severity theo ĐÚNG mô hình demo (đo 03/09) -----------------
353
+ Demo KHÔNG tô badge bằng màu rực. Nó dùng token semantic, và bậc nặng
354
+ nhất được nhấn bằng ĐỘ ĐẬM chứ không bằng màu:
355
+ Critical → nền --og-text (#26282c), chữ --og-surface (pill đen đặc)
356
+ High → nền --og-negative-soft-bg, chữ --og-negative
357
+ Medium → nền --og-warning-soft-bg, chữ --og-warning
358
+ Low → nền --og-positive-soft-bg, chữ --og-positive
359
+ Info → nền --og-neutral-soft-bg, chữ --og-neutral-soft-fg
360
+ Neutral → nền --og-surface-sunken, chữ --og-text-muted
361
+
362
+ Dùng class thay vì utility Tailwind vì tên `warning`/`critical` trong theme
363
+ Tailwind đang trỏ vào bộ LEGACY `--og-tone-*`, không phải token semantic —
364
+ gọi `text-warning` ở đây sẽ lấy sai màu.
365
+
366
+ MÀU (`tone-tint-*`) tách khỏi HÌNH DẠNG (`tone-badge`) có chủ đích: ô icon
367
+ vuông của stat-card và chip filter cần đúng màu nhưng KHÔNG được nhận
368
+ `border-radius:999px` + padding của pill. */
369
+ /* ---- Tông THANG ĐO cho filter chip -----------------------------------
370
+ Filter chip severity là một THANG ĐO (giống chấm legend), không phải badge
371
+ của một finding — nên KHÔNG dùng `.tone-tint-critical` (pill đen đặc, dành
372
+ riêng cho badge Critical theo `.og-badge--solid`). Ở đây Critical phải đọc
373
+ ra ĐỎ SẪM: nền mềm pha từ ramp `--og-sev-*`, chữ lấy bản dễ đọc nhất.
374
+ (Demo không có mẫu để copy: filter chip của demo theo TRẠNG THÁI —
375
+ "Confirmed / Reachable / Blocked" — chứ không theo severity.) */
376
+ .tone-scale-critical {
377
+ background: color-mix(in srgb, rgb(var(--og-sev-critical)) 12%, rgb(var(--og-surface)));
378
+ color: rgb(var(--og-sev-critical));
379
+ }
380
+ .tone-scale-danger {
381
+ background: color-mix(in srgb, rgb(var(--og-sev-danger)) 12%, rgb(var(--og-surface)));
382
+ color: rgb(var(--og-sev-danger));
383
+ }
384
+ .tone-scale-warning {
385
+ background: color-mix(in srgb, rgb(var(--og-sev-warning)) 16%, rgb(var(--og-surface)));
386
+ color: rgb(var(--og-warning));
387
+ }
388
+ .tone-scale-success {
389
+ background: color-mix(in srgb, rgb(var(--og-sev-success)) 12%, rgb(var(--og-surface)));
390
+ color: rgb(var(--og-positive));
391
+ }
392
+ .tone-scale-information {
393
+ background: rgb(var(--og-neutral-soft-bg));
394
+ color: rgb(var(--og-neutral-soft-fg));
395
+ }
396
+ .tone-scale-discovery {
397
+ background: rgb(var(--og-accent-soft-bg));
398
+ color: rgb(var(--og-accent-soft-fg));
399
+ }
400
+ .tone-scale-neutral {
401
+ background: rgb(var(--og-surface-sunken));
402
+ color: rgb(var(--og-text-muted));
403
+ }
404
+ /* ---- Nền ĐẶC theo tông ------------------------------------------------
405
+ Cho trạng thái ĐANG CHỌN (chip filter active) — nơi cần khối màu đậm kèm
406
+ chữ tương phản. Khác `.tone-tint-*`: cái đó là bộ badge severity theo demo
407
+ (Critical = đen), còn đây là màu của chính bậc severity. */
408
+ .tone-solid-critical {
409
+ background: rgb(var(--og-sev-critical));
410
+ color: rgb(var(--og-surface));
411
+ }
412
+ .tone-solid-danger {
413
+ background: rgb(var(--og-sev-danger));
414
+ color: rgb(var(--og-surface));
415
+ }
416
+ .tone-solid-warning {
417
+ background: rgb(var(--og-warning));
418
+ color: rgb(var(--og-surface));
419
+ }
420
+ .tone-solid-success {
421
+ background: rgb(var(--og-positive));
422
+ color: rgb(var(--og-surface));
423
+ }
424
+ .tone-solid-information {
425
+ background: rgb(var(--og-neutral-soft-fg));
426
+ color: rgb(var(--og-surface));
427
+ }
428
+ .tone-solid-discovery {
429
+ background: rgb(var(--og-accent));
430
+ color: rgb(var(--og-surface));
431
+ }
432
+ .tone-solid-neutral {
433
+ background: rgb(var(--og-text-faint));
434
+ color: rgb(var(--og-surface));
435
+ }
436
+
437
+ /* ---- Viền theo tông ---------------------------------------------------
438
+ Tách riêng vì `border-color` là thuộc tính khác: panel trạng thái (dropzone
439
+ upload) cần viền + nền + chữ cùng tông. `tone-hover-border-*` cho chỗ chỉ
440
+ đổi viền khi hover (KPI card) — modifier `hover:` của Tailwind không áp
441
+ được lên class CSS thật nên khai thẳng pseudo-class. */
442
+ .tone-border-critical {
443
+ border-color: rgb(var(--og-sev-critical));
444
+ }
445
+ .tone-border-danger {
446
+ border-color: rgb(var(--og-sev-danger));
447
+ }
448
+ .tone-border-warning {
449
+ border-color: rgb(var(--og-warning));
450
+ }
451
+ .tone-border-success {
452
+ border-color: rgb(var(--og-positive));
453
+ }
454
+ .tone-border-information {
455
+ border-color: rgb(var(--og-neutral-soft-fg));
456
+ }
457
+ .tone-border-discovery {
458
+ border-color: rgb(var(--og-accent));
459
+ }
460
+ .tone-border-neutral {
461
+ border-color: rgb(var(--og-border));
462
+ }
463
+ .tone-hover-border-critical:hover {
464
+ border-color: rgb(var(--og-sev-critical));
465
+ }
466
+ .tone-hover-border-danger:hover {
467
+ border-color: rgb(var(--og-sev-danger));
468
+ }
469
+ .tone-hover-border-warning:hover {
470
+ border-color: rgb(var(--og-warning));
471
+ }
472
+ .tone-hover-border-success:hover {
473
+ border-color: rgb(var(--og-positive));
474
+ }
475
+ .tone-hover-border-information:hover {
476
+ border-color: rgb(var(--og-neutral-soft-fg));
477
+ }
478
+ .tone-hover-border-discovery:hover {
479
+ border-color: rgb(var(--og-accent));
480
+ }
481
+ .tone-hover-border-neutral:hover {
482
+ border-color: rgb(var(--og-border));
483
+ }
484
+
485
+ .tone-tint-critical {
486
+ background: rgb(var(--og-text));
487
+ color: rgb(var(--og-surface));
488
+ }
489
+ .tone-tint-danger {
490
+ background: rgb(var(--og-negative-soft-bg));
491
+ color: rgb(var(--og-negative));
492
+ }
493
+ .tone-tint-warning {
494
+ background: rgb(var(--og-warning-soft-bg));
495
+ color: rgb(var(--og-warning));
496
+ }
497
+ .tone-tint-success {
498
+ background: rgb(var(--og-positive-soft-bg));
499
+ color: rgb(var(--og-positive));
500
+ }
501
+ .tone-tint-information {
502
+ background: rgb(var(--og-neutral-soft-bg));
503
+ color: rgb(var(--og-neutral-soft-fg));
504
+ }
505
+ .tone-tint-discovery {
506
+ /* demo: `.og-badge--accent` */
507
+ background: rgb(var(--og-accent-soft-bg));
508
+ color: rgb(var(--og-accent-soft-fg));
509
+ }
510
+ .tone-tint-neutral {
511
+ background: rgb(var(--og-surface-sunken));
512
+ color: rgb(var(--og-text-muted));
513
+ }
514
+
515
+ /* ---- Chữ / chấm theo tông (tầng 3 của mô hình demo) -----------------
516
+ Demo tách RÕ ba tầng (nguồn: `sevMeta` + `.og-badge--*` + `.og-statusdot--*`):
517
+ ① chart → màu literal `--og-sev-*`
518
+ ② badge/pill → `.tone-tint-*` (token semantic, Critical = solid)
519
+ ③ chữ & chấm → màu SEMANTIC, không phải ramp chart
520
+
521
+ `.tone-fg-*` chọn thành viên DỄ ĐỌC NHẤT trong mỗi họ severity (contrast
522
+ trên surface trắng): critical #7f1d1d 10.0:1 · danger #dc2626 4.83:1 ·
523
+ warning --og-warning #a8741f 4.0:1 (ramp #f59e0b chỉ 2.15:1 → không dùng
524
+ cho chữ) · success --og-positive #3f7d55 4.4:1 (ramp #16a34a 3.30:1). */
525
+ .tone-fg-critical {
526
+ color: rgb(var(--og-sev-critical));
527
+ }
528
+ .tone-fg-danger {
529
+ color: rgb(var(--og-sev-danger));
530
+ }
531
+ .tone-fg-warning {
532
+ color: rgb(var(--og-warning));
533
+ }
534
+ .tone-fg-success {
535
+ color: rgb(var(--og-positive));
536
+ }
537
+ .tone-fg-information {
538
+ color: rgb(var(--og-neutral-soft-fg));
539
+ }
540
+ .tone-fg-discovery {
541
+ color: rgb(var(--og-accent-soft-fg));
542
+ }
543
+ .tone-fg-neutral {
544
+ color: rgb(var(--og-text-faint));
545
+ }
546
+
547
+ /* Chấm trạng thái trong HÀNG (`● Confirmed`) — demo dùng màu semantic. */
548
+ .tone-dot-critical {
549
+ background: rgb(var(--og-sev-critical));
550
+ }
551
+ .tone-dot-danger {
552
+ background: rgb(var(--og-negative));
553
+ }
554
+ .tone-dot-warning {
555
+ background: rgb(var(--og-warning));
556
+ }
557
+ .tone-dot-success {
558
+ background: rgb(var(--og-positive));
559
+ }
560
+ .tone-dot-information {
561
+ background: rgb(var(--og-neutral-soft-fg));
562
+ }
563
+ .tone-dot-discovery {
564
+ background: rgb(var(--og-accent));
565
+ }
566
+ .tone-dot-neutral {
567
+ background: rgb(var(--og-text-faint));
568
+ }
569
+
570
+ /* Chấm LEGEND của chart — phải TRÙNG màu cung nên dùng ramp `--og-sev-*`. */
571
+ .tone-dot-chart-critical {
572
+ background: rgb(var(--og-sev-critical));
573
+ }
574
+ .tone-dot-chart-danger {
575
+ background: rgb(var(--og-sev-danger));
576
+ }
577
+ .tone-dot-chart-warning {
578
+ background: rgb(var(--og-sev-warning));
579
+ }
580
+ .tone-dot-chart-success {
581
+ background: rgb(var(--og-sev-success));
582
+ }
583
+ .tone-dot-chart-information {
584
+ background: rgb(var(--og-neutral-soft-fg));
585
+ }
586
+ .tone-dot-chart-discovery {
587
+ background: rgb(var(--og-accent));
588
+ }
589
+ .tone-dot-chart-neutral {
590
+ background: rgb(var(--og-text-faint));
591
+ }
592
+
593
+ /* Hình dạng pill của badge severity — demo: 999px · 11.5px · weight 400. */
594
+ .tone-badge {
595
+ display: inline-flex;
596
+ align-items: center;
597
+ border-radius: var(--og-radius-pill);
598
+ gap: 5px;
599
+ padding: 3px 10px;
600
+ font-size: var(--og-fs-xs);
601
+ font-weight: 400;
602
+ line-height: 1.5;
603
+ white-space: nowrap;
604
+ }
605
+
606
+ .btn-cta {
607
+ @apply btn-common bg-cta hover:bg-cta-hover text-white;
608
+ box-shadow:
609
+ inset 0 1px 0 rgb(255 255 255 / 0.18),
610
+ 0 1px 2px rgb(0 0 0 / 0.15);
611
+ }
339
612
  .btn-alternative {
340
613
  @apply btn-common hover:bg-bg-hover text-text-primary border border-border-default;
341
614
  }
@@ -376,43 +649,55 @@ input[type='password'] {
376
649
  @apply tag-common bg-bg-hover;
377
650
  }
378
651
  .tag-success {
379
- @apply tag-common bg-success/20;
652
+ @apply tag-common;
653
+ background: color-mix(in srgb, rgb(var(--og-sev-success)) 12%, rgb(var(--og-surface)));
380
654
  }
381
655
  .tag-warning {
382
- @apply tag-common bg-warning/20;
656
+ @apply tag-common;
657
+ background: color-mix(in srgb, rgb(var(--og-sev-warning)) 16%, rgb(var(--og-surface)));
383
658
  }
384
659
  .tag-danger {
385
- @apply tag-common bg-danger/20;
660
+ @apply tag-common;
661
+ background: color-mix(in srgb, rgb(var(--og-sev-danger)) 12%, rgb(var(--og-surface)));
386
662
  }
387
663
  .tag-critical {
388
- @apply tag-common bg-critical/20;
664
+ @apply tag-common;
665
+ background: color-mix(in srgb, rgb(var(--og-sev-critical)) 12%, rgb(var(--og-surface)));
389
666
  }
390
667
  .tag-discovery {
391
- @apply tag-common bg-discovery/20;
668
+ @apply tag-common;
669
+ background: rgb(var(--og-accent-soft-bg));
392
670
  }
393
671
  .tag-information {
394
- @apply tag-common bg-information/20;
672
+ @apply tag-common;
673
+ background: rgb(var(--og-neutral-soft-bg));
395
674
  }
396
675
  .tag-default-solid {
397
676
  @apply tag-common bg-bg-hover;
398
677
  }
399
678
  .tag-success-solid {
400
- @apply tag-common bg-success;
679
+ @apply tag-common;
680
+ background: rgb(var(--og-positive));
401
681
  }
402
682
  .tag-warning-solid {
403
- @apply tag-common bg-warning;
683
+ @apply tag-common;
684
+ background: rgb(var(--og-warning));
404
685
  }
405
686
  .tag-danger-solid {
406
- @apply tag-common bg-danger;
687
+ @apply tag-common;
688
+ background: rgb(var(--og-sev-danger));
407
689
  }
408
690
  .tag-critical-solid {
409
- @apply tag-common bg-critical;
691
+ @apply tag-common;
692
+ background: rgb(var(--og-sev-critical));
410
693
  }
411
694
  .tag-discovery-solid {
412
- @apply tag-common bg-discovery;
695
+ @apply tag-common;
696
+ background: rgb(var(--og-accent));
413
697
  }
414
698
  .tag-information-solid {
415
- @apply tag-common bg-information;
699
+ @apply tag-common;
700
+ background: rgb(var(--og-neutral-soft-fg));
416
701
  }
417
702
  .tag-square {
418
703
  @apply rounded-md px-semi py-small;
@@ -484,3 +769,20 @@ input[type='password'] {
484
769
  .skeleton-load {
485
770
  @apply rounded bg-track animate-pulse motion-reduce:animate-none;
486
771
  }
772
+
773
+ /* ============================================================================
774
+ Route skeleton — ẩn nội dung CŨ trong lúc skeleton của route mới đang hiện.
775
+
776
+ ⚠️ PHẢI ĐỂ Ở CSS TOÀN CỤC, không đặt trong .scss của component.
777
+ Component đang active do ROUTER tạo, nên nó KHÔNG mang attribute
778
+ `_ngcontent-*` của template chứa `<router-outlet>`. View encapsulation
779
+ (emulated) thêm attribute đó vào selector con, nên rule viết trong
780
+ component .scss chỉ ẩn được `<router-outlet>` — chính component thật thì
781
+ không. Đã bị đúng bẫy này khi test standalone (`app-projects` vẫn hiện).
782
+
783
+ `<router-outlet>` và component active là hai node NGANG CẤP nên không bọc
784
+ được, phải loại trừ theo selector.
785
+ ============================================================================ */
786
+ .fx-rs-busy > *:not(fx-ui-route-skeleton) {
787
+ display: none !important;
788
+ }