@aquera/nile-visualization 2.9.7 → 2.9.8

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.
@@ -524,8 +524,6 @@ export interface NileKpiChartConfig extends NileChartConfigBase {
524
524
  cardPaddingVertical?: string | number;
525
525
  cardPaddingHorizontal?: string | number;
526
526
  contentGap?: string | number;
527
- /** Accent bar colour for the 'accent' variant. */
528
- accentColor?: string;
529
527
  /** Abbreviation scale. Default 'auto'. */
530
528
  valueFormat?: KpiValueFormat;
531
529
  /** Decimal places on the abbreviated value. */
@@ -421,13 +421,6 @@ export const styles = css `
421
421
  overflow-y: auto;
422
422
  -webkit-overflow-scrolling: touch;
423
423
  contain: none;
424
- display: flex;
425
- }
426
-
427
- :host([fit]) .nile-chart-inner--kpi > nile-kpi-chart {
428
- flex: 1 1 auto;
429
- min-height: 0;
430
- height: 100%;
431
424
  }
432
425
 
433
426
  .nile-chart-inner--filter {
@@ -466,36 +459,19 @@ export const styles = css `
466
459
  pointer-events: none;
467
460
  }
468
461
 
469
- /* When loading, the card becomes a flex column that fills the host so the
470
- skeleton can shrink with the container instead of forcing a fixed size. */
471
- .nile-chart-card--loading {
472
- display: flex;
473
- flex-direction: column;
474
- height: 100%;
475
- }
476
- .nile-chart-card--loading .nile-chart-wrapper {
477
- flex: 1 1 auto;
478
- min-height: 0;
479
- }
480
- .nile-chart-card--loading .nile-chart-inner {
481
- height: 100%;
482
- }
483
-
484
462
  .nile-chart-skeleton {
485
463
  display: flex;
486
464
  flex-direction: column;
487
465
  gap: 0;
488
466
  padding: var(--nile-spacing-3xl, var(--ng-spacing-3xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl)) var(--nile-spacing-xl, var(--ng-spacing-xl));
489
- height: 100%;
490
- box-sizing: border-box;
467
+ min-height: var(--nile-chart-skeleton-height, 300px);
491
468
  }
492
469
 
493
470
  .nile-chart-skeleton-body {
494
471
  display: flex;
495
472
  flex-direction: column;
496
473
  justify-content: space-around;
497
- flex: 1 1 auto;
498
- min-height: 0;
474
+ flex: 1;
499
475
  gap: var(--nile-spacing-14px, var(--ng-spacing-lg));
500
476
  padding-left: 44px;
501
477
  position: relative;
@@ -508,8 +484,8 @@ export const styles = css `
508
484
  left: 34px;
509
485
  top: var(--nile-spacing-xs, var(--ng-spacing-xs));
510
486
  bottom: var(--nile-spacing-xs, var(--ng-spacing-xs));
511
- width: 4px;
512
- border-radius: 2px;
487
+ width: var(--nile-border-width-2, var(--ng-stroke-width-2));
488
+ border-radius: var(--nile-border-width-1, var(--ng-stroke-width-1));
513
489
  background: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
514
490
  }
515
491
 
@@ -517,398 +493,59 @@ export const styles = css `
517
493
  display: flex;
518
494
  align-items: center;
519
495
  gap: var(--nile-spacing-md, var(--ng-spacing-md));
520
- flex: 1 1 var(--nile-spacing-3xl, var(--ng-spacing-3xl));
521
- min-height: 0;
522
- max-height: var(--nile-spacing-3xl, var(--ng-spacing-3xl));
523
- }
524
-
525
- .nile-chart-skeleton-row .nile-chart-skeleton-ylabel-sk { flex-shrink: 0; }
526
- /* Horizontal bar — uses <nile-skeleton-loader>. The host takes flex-basis
527
- w% (inline style); ::part(base) forces the inner wrapper to fill the
528
- host so the shimmer rectangle spans the full w% of the row. */
529
- .nile-chart-skeleton-bar-sk::part(base) {
530
- width: 100%;
531
- height: 100%;
496
+ height: var(--nile-spacing-3xl, var(--ng-spacing-3xl));
532
497
  }
533
- .nile-chart-skeleton-row:nth-child(1) .nile-chart-skeleton-bar-rect { animation-delay: 0ms; }
534
- .nile-chart-skeleton-row:nth-child(2) .nile-chart-skeleton-bar-rect { animation-delay: 100ms; }
535
- .nile-chart-skeleton-row:nth-child(3) .nile-chart-skeleton-bar-rect { animation-delay: 200ms; }
536
- .nile-chart-skeleton-row:nth-child(4) .nile-chart-skeleton-bar-rect { animation-delay: 300ms; }
537
- .nile-chart-skeleton-row:nth-child(5) .nile-chart-skeleton-bar-rect { animation-delay: 400ms; }
538
498
 
539
- /* Horizontal x-axis labels row */
540
- .nile-chart-skeleton-xaxis-row {
541
- display: flex;
542
- justify-content: space-around;
543
- padding-left: 44px;
544
- margin-top: var(--nile-spacing-14px, var(--ng-spacing-lg));
499
+ .nile-chart-skeleton-ylabel {
500
+ width: var(--nile-height-26px, 26px);
501
+ height: var(--nile-spacing-10px, var(--ng-spacing-md-alt));
502
+ border-radius: var(--nile-radius-radius-sm, var(--ng-radius-xs));
545
503
  flex-shrink: 0;
546
- min-width: 0;
547
- gap: var(--nile-spacing-sm, var(--ng-spacing-sm));
548
- }
549
- .nile-chart-skeleton-xaxis-row nile-skeleton-loader { flex-shrink: 1; min-width: 0; }
550
-
551
- /* Compact paddings + y-axis offset for narrow widths so the skeleton
552
- doesn't overflow when the chart is shrunk. */
553
- @container (max-width: 400px) {
554
- .nile-chart-skeleton {
555
- padding: var(--nile-spacing-xl, var(--ng-spacing-xl)) var(--nile-spacing-2xl, var(--ng-spacing-2xl)) var(--nile-spacing-lg, var(--ng-spacing-lg));
556
- }
557
- .nile-chart-skeleton-body { padding-left: 32px; }
558
- .nile-chart-skeleton-body::before { left: 24px; }
559
- .nile-chart-skeleton-xaxis-row { padding-left: 32px; }
560
- }
561
-
562
- @container (max-width: 280px) {
563
- .nile-chart-skeleton {
564
- padding: var(--nile-spacing-lg, var(--ng-spacing-lg)) var(--nile-spacing-xl, var(--ng-spacing-xl));
565
- }
566
- .nile-chart-skeleton-body { padding-left: 22px; }
567
- .nile-chart-skeleton-body::before { left: 14px; }
568
- .nile-chart-skeleton-xaxis-row { padding-left: 22px; }
569
- .nile-chart-skeleton-ylabel { display: none; }
570
- }
571
-
572
- @keyframes nile-skeleton-blink {
573
- 0%, 100% { opacity: 0.5; }
574
- 50% { opacity: 1; }
575
- }
576
-
577
- /* ── Variant: columns (vertical bars) — wraps nile-skeleton-loader ── */
578
- .nile-chart-skeleton-columns {
579
- display: flex;
580
- align-items: flex-end;
581
- justify-content: space-between;
582
- gap: var(--nile-spacing-md, var(--ng-spacing-md));
583
- flex: 1 1 auto;
584
- min-height: 0;
585
- padding-left: 28px;
586
- position: relative;
587
- }
588
- .nile-chart-skeleton-columns::before,
589
- .nile-chart-skeleton-columns::after {
590
- content: '';
591
- position: absolute;
592
504
  background: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
593
- border-radius: 1px;
594
- }
595
- .nile-chart-skeleton-columns::before { left: 18px; top: 0; bottom: 0; width: 2px; }
596
- .nile-chart-skeleton-columns::after { left: 18px; right: 0; bottom: 0; height: 2px; }
597
- .nile-chart-skeleton-col-cell {
598
- flex: 1 1 0;
599
- min-width: 0;
600
- height: 60%;
601
- display: flex;
602
- align-items: stretch;
603
- border-radius: var(--nile-radius-radius-sm, var(--ng-radius-xs)) var(--nile-radius-radius-sm, var(--ng-radius-xs)) 0 0;
604
- overflow: hidden;
605
- }
606
- .nile-chart-skeleton-col-cell nile-skeleton-loader {
607
- width: 100%;
608
- height: 100%;
609
- display: block;
610
- }
611
- /* Percentage heights don't pass through the loader's shadow DOM by default.
612
- Use ::part() to push height: 100% all the way to the shimmer rectangle. */
613
- .nile-chart-skeleton-col-cell nile-skeleton-loader::part(base),
614
- .nile-chart-skeleton-col-cell nile-skeleton-loader::part(skeleton),
615
- .nile-chart-skeleton-heatmap-cell nile-skeleton-loader::part(base),
616
- .nile-chart-skeleton-heatmap-cell nile-skeleton-loader::part(skeleton) {
617
- height: 100%;
618
- width: 100%;
619
- }
620
- .nile-chart-skeleton-xaxis-row--columns { padding-left: 28px; }
621
-
622
- /* ── Variant: line ── */
623
- .nile-chart-skeleton-line {
624
- flex: 1 1 auto;
625
- min-height: 0;
626
- padding-left: 28px;
627
- position: relative;
628
- }
629
- .nile-chart-skeleton-line::before {
630
- content: '';
631
- position: absolute;
632
- left: 18px; top: 0; bottom: 0;
633
- width: 2px;
634
- border-radius: 1px;
635
- background: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
636
- }
637
- .nile-chart-skeleton-line svg { width: 100%; height: 100%; display: block; }
638
- .nile-chart-skeleton-line-area {
639
- fill: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
640
- opacity: 0.35;
641
- animation: nile-skeleton-blink 1.6s ease-in-out infinite;
642
- }
643
- .nile-chart-skeleton-line-stroke {
644
- fill: none;
645
- stroke: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
646
- stroke-width: 1.6;
647
- stroke-linecap: round;
648
- stroke-linejoin: round;
649
- animation: nile-skeleton-blink 1.2s ease-in-out infinite;
650
- }
651
-
652
- /* Trendline: faint guide line + actuals stroke + dashed forecast + split rule */
653
- .nile-chart-skeleton-trend-line {
654
- stroke: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
655
- stroke-width: 0.8;
656
- opacity: 0.45;
657
- }
658
- .nile-chart-skeleton-trend-forecast {
659
- fill: none;
660
- stroke: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
661
- stroke-width: 1.6;
662
- stroke-linecap: round;
663
- stroke-dasharray: 3 3;
664
505
  animation: nile-skeleton-blink 1.2s ease-in-out infinite;
665
- animation-delay: 200ms;
666
- }
667
- .nile-chart-skeleton-trend-divider {
668
- stroke: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
669
- stroke-width: 0.5;
670
- stroke-dasharray: 1 2;
671
- opacity: 0.5;
672
- }
673
-
674
- /* Anomaly: halo pulses around outlier dots, dot itself blinks */
675
- .nile-chart-skeleton-anomaly-dot {
676
- fill: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
677
- animation: nile-skeleton-blink 1.1s ease-in-out infinite;
678
- }
679
- .nile-chart-skeleton-anomaly-halo {
680
- fill: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
681
- opacity: 0.25;
682
- transform-origin: center;
683
- transform-box: fill-box;
684
- animation: nile-skeleton-anomaly-pulse 1.8s ease-in-out infinite;
685
- }
686
- .nile-chart-skeleton-anomaly-halo:nth-of-type(1) { animation-delay: 0ms; }
687
- .nile-chart-skeleton-anomaly-halo:nth-of-type(2) { animation-delay: 300ms; }
688
- .nile-chart-skeleton-anomaly-halo:nth-of-type(3) { animation-delay: 600ms; }
689
- @keyframes nile-skeleton-anomaly-pulse {
690
- 0%, 100% { opacity: 0.15; transform: scale(0.7); }
691
- 50% { opacity: 0.35; transform: scale(1.2); }
692
- }
693
-
694
- /* ── Variant: pie / donut ── */
695
- .nile-chart-skeleton-pie-wrap {
696
- display: flex;
697
- align-items: center;
698
- justify-content: center;
699
- gap: var(--nile-spacing-3xl, var(--ng-spacing-3xl));
700
- flex: 1 1 auto;
701
- min-height: 0;
702
- }
703
- .nile-chart-skeleton-pie {
704
- width: min(60%, 220px);
705
- aspect-ratio: 1;
706
- border-radius: 50%;
707
- background: conic-gradient(
708
- var(--nile-colors-neutral-400, var(--ng-colors-border-secondary)) 0 25%,
709
- var(--nile-colors-neutral-300, #e5e7eb) 25% 55%,
710
- var(--nile-colors-neutral-400, var(--ng-colors-border-secondary)) 55% 80%,
711
- var(--nile-colors-neutral-300, #e5e7eb) 80% 100%
712
- );
713
- mask: radial-gradient(circle, transparent 28%, black 30%);
714
- -webkit-mask: radial-gradient(circle, transparent 28%, black 30%);
715
- animation: nile-skeleton-spin 6s linear infinite, nile-skeleton-blink 1.6s ease-in-out infinite;
716
- }
717
- .nile-chart-skeleton-legend {
718
- display: flex;
719
- flex-direction: column;
720
- gap: var(--nile-spacing-md, var(--ng-spacing-md));
721
- flex-shrink: 0;
722
506
  }
723
- .nile-chart-skeleton-legend-row {
724
- display: flex;
725
- align-items: center;
726
- gap: var(--nile-spacing-sm, var(--ng-spacing-sm));
727
- }
728
- @container (max-width: 320px) {
729
- .nile-chart-skeleton-legend { display: none; }
730
- }
731
- @keyframes nile-skeleton-spin { to { transform: rotate(360deg); } }
732
507
 
733
- /* ── Variant: scatter ── */
734
- .nile-chart-skeleton-scatter {
735
- flex: 1 1 auto;
736
- min-height: 0;
737
- position: relative;
738
- padding-left: 28px;
739
- }
740
- .nile-chart-skeleton-scatter::before,
741
- .nile-chart-skeleton-scatter::after {
742
- content: '';
743
- position: absolute;
508
+ .nile-chart-skeleton-bar {
509
+ height: var(--nile-spacing-2xl, var(--ng-spacing-2xl));
510
+ width: var(--w, 60%);
511
+ border-radius: 0 var(--nile-radius-radius-sm, var(--ng-radius-xs)) var(--nile-radius-radius-sm, var(--ng-radius-xs)) 0;
744
512
  background: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
745
- border-radius: 1px;
746
- }
747
- .nile-chart-skeleton-scatter::before { left: 18px; top: 0; bottom: 0; width: 2px; }
748
- .nile-chart-skeleton-scatter::after { left: 18px; right: 0; bottom: 0; height: 2px; }
749
- .nile-chart-skeleton-dot-pos {
750
- position: absolute;
751
- transform: translate(-50%, -50%);
752
- display: inline-flex;
753
- }
754
-
755
- /* ── Variant: heatmap ── */
756
- .nile-chart-skeleton-heatmap {
757
- display: flex;
758
- flex-direction: column;
759
- gap: var(--nile-spacing-sm, var(--ng-spacing-sm));
760
- flex: 1 1 auto;
761
- min-height: 0;
762
- }
763
- .nile-chart-skeleton-heatmap-row {
764
- display: flex;
765
- gap: var(--nile-spacing-sm, var(--ng-spacing-sm));
766
- flex: 1 1 0;
767
- min-height: 0;
768
- }
769
- .nile-chart-skeleton-heatmap-cell {
770
- flex: 1 1 0;
771
- min-width: 0;
772
- display: flex;
773
- }
774
- .nile-chart-skeleton-heatmap-cell nile-skeleton-loader { width: 100%; height: 100%; }
775
-
776
- /* ── Variant: radar ── */
777
- .nile-chart-skeleton-radar-wrap {
778
- display: flex;
779
- align-items: center;
780
- justify-content: center;
781
- flex: 1 1 auto;
782
- min-height: 0;
783
- }
784
- .nile-chart-skeleton-radar-svg {
785
- width: min(78%, 260px);
786
- aspect-ratio: 1;
787
- display: block;
788
- }
789
- .nile-chart-skeleton-radar-grid {
790
- fill: none;
791
- stroke: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
792
- stroke-width: 0.8;
793
- stroke-linejoin: round;
794
- opacity: 0.7;
795
- }
796
- .nile-chart-skeleton-radar-spoke {
797
- stroke: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
798
- stroke-width: 0.6;
799
- opacity: 0.5;
800
- }
801
- .nile-chart-skeleton-radar-data {
802
- fill: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
803
- stroke: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
804
- stroke-width: 1.2;
805
- stroke-linejoin: round;
806
- opacity: 0.45;
807
- animation: nile-skeleton-blink 1.4s ease-in-out infinite;
808
- transform-origin: 50px 50px;
809
- transform-box: fill-box;
810
- }
811
- .nile-chart-skeleton-radar-dot {
812
- fill: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
813
513
  animation: nile-skeleton-blink 1.2s ease-in-out infinite;
814
514
  }
815
- .nile-chart-skeleton-radar-dot:nth-child(5) { animation-delay: 0ms; }
816
- .nile-chart-skeleton-radar-dot:nth-child(6) { animation-delay: 120ms; }
817
- .nile-chart-skeleton-radar-dot:nth-child(7) { animation-delay: 240ms; }
818
- .nile-chart-skeleton-radar-dot:nth-child(8) { animation-delay: 360ms; }
819
- .nile-chart-skeleton-radar-dot:nth-child(9) { animation-delay: 480ms; }
820
515
 
821
- /* ── Variant: timeline ── */
822
- .nile-chart-skeleton-timeline {
516
+ /* Staggered wave across the bars */
517
+ .nile-chart-skeleton-row:nth-child(1) .nile-chart-skeleton-bar { animation-delay: 0ms; }
518
+ .nile-chart-skeleton-row:nth-child(2) .nile-chart-skeleton-bar { animation-delay: 100ms; }
519
+ .nile-chart-skeleton-row:nth-child(3) .nile-chart-skeleton-bar { animation-delay: 200ms; }
520
+ .nile-chart-skeleton-row:nth-child(4) .nile-chart-skeleton-bar { animation-delay: 300ms; }
521
+ .nile-chart-skeleton-row:nth-child(5) .nile-chart-skeleton-bar { animation-delay: 400ms; }
522
+
523
+ /* Horizontal x-axis labels row */
524
+ .nile-chart-skeleton-xaxis-row {
823
525
  display: flex;
824
- flex-direction: column;
825
- gap: var(--nile-spacing-md, var(--ng-spacing-md));
826
- flex: 1 1 auto;
827
- min-height: 0;
828
526
  justify-content: space-around;
829
- }
830
- .nile-chart-skeleton-tl-row {
831
- position: relative;
832
- height: 12px;
833
- }
834
- .nile-chart-skeleton-tl-bar-pos {
835
- position: absolute;
836
- top: 0; bottom: 0;
837
- display: inline-flex;
527
+ padding-left: 44px;
528
+ margin-top: var(--nile-spacing-14px, var(--ng-spacing-lg));
838
529
  }
839
530
 
840
- /* ── Variant: kpi ── */
841
- .nile-chart-skeleton-kpi {
842
- display: flex;
843
- flex-direction: column;
844
- gap: var(--nile-spacing-md, var(--ng-spacing-md));
845
- flex: 1 1 auto;
846
- min-height: 0;
847
- justify-content: center;
848
- }
849
- .nile-chart-skeleton-kpi-spark {
850
- width: 100%;
851
- height: 40px;
852
- margin-top: var(--nile-spacing-sm, var(--ng-spacing-sm));
853
- }
854
- .nile-chart-skeleton-kpi-spark path {
855
- fill: none;
856
- stroke: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
857
- stroke-width: 1.6;
858
- stroke-linecap: round;
859
- stroke-linejoin: round;
531
+ .nile-chart-skeleton-xlabel {
532
+ height: var(--nile-spacing-10px, var(--ng-spacing-md-alt));
533
+ width: var(--nile-height-30px, 30px);
534
+ border-radius: var(--nile-radius-radius-sm, var(--ng-radius-xs));
535
+ background: var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
860
536
  animation: nile-skeleton-blink 1.2s ease-in-out infinite;
537
+ animation-delay: var(--d, 0ms);
861
538
  }
862
539
 
863
- /* ── Variant: grid (table) ── */
864
- .nile-chart-skeleton-grid {
865
- display: flex;
866
- flex-direction: column;
867
- gap: var(--nile-spacing-sm, var(--ng-spacing-sm));
868
- flex: 1 1 auto;
869
- min-height: 0;
870
- }
871
- .nile-chart-skeleton-grid-head,
872
- .nile-chart-skeleton-grid-row {
873
- display: flex;
874
- gap: var(--nile-spacing-md, var(--ng-spacing-md));
875
- align-items: center;
876
- flex: 1 1 0;
877
- min-height: 0;
878
- max-height: 28px;
879
- }
880
- .nile-chart-skeleton-grid-head {
881
- border-bottom: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
882
- padding-bottom: var(--nile-spacing-sm, var(--ng-spacing-sm));
883
- }
884
- .nile-chart-skeleton-grid-head nile-skeleton-loader,
885
- .nile-chart-skeleton-grid-row nile-skeleton-loader {
886
- flex: 1 1 0;
887
- min-width: 0;
888
- }
889
-
890
- /* ── Variant: filter ── */
891
- .nile-chart-skeleton-filter {
892
- display: flex;
893
- flex-direction: column;
894
- gap: var(--nile-spacing-lg, var(--ng-spacing-lg));
895
- flex: 1 1 auto;
896
- min-height: 0;
897
- justify-content: center;
898
- }
899
- .nile-chart-skeleton-filter-chips {
900
- display: flex;
901
- gap: var(--nile-spacing-sm, var(--ng-spacing-sm));
902
- flex-wrap: wrap;
540
+ @keyframes nile-skeleton-blink {
541
+ 0%, 100% { opacity: 0.5; }
542
+ 50% { opacity: 1; }
903
543
  }
904
544
 
905
545
  @media (prefers-reduced-motion: reduce) {
906
- .nile-chart-skeleton-line-area,
907
- .nile-chart-skeleton-line-stroke,
908
- .nile-chart-skeleton-pie,
909
- .nile-chart-skeleton-radar-data,
910
- .nile-chart-skeleton-radar-dot,
911
- .nile-chart-skeleton-kpi-spark path {
546
+ .nile-chart-skeleton-bar,
547
+ .nile-chart-skeleton-ylabel,
548
+ .nile-chart-skeleton-xlabel {
912
549
  animation: none;
913
550
  opacity: 0.7;
914
551
  }
@@ -4,7 +4,6 @@ import { html, nothing } from 'lit';
4
4
  import NileElement from '../internal/nile-element.js';
5
5
  import { styles, tooltipCss } from './nile-chart.css.js';
6
6
  import { nileChartConfig } from './nile-chart-config-builder.js';
7
- import { renderChartSkeleton } from './nile-chart-skeleton.js';
8
7
  import { convertConfig } from '../internal/chart-adapters.js';
9
8
  import { deepMerge } from '../internal/utils.js';
10
9
  import { initNileChartExporting, getHighcharts } from '../internal/highcharts-provider.js';
@@ -1711,13 +1710,27 @@ let NileChart = class NileChart extends NileElement {
1711
1710
  }
1712
1711
  }
1713
1712
  renderSkeleton() {
1714
- return renderChartSkeleton(this.activeConfig?.type);
1713
+ return html `
1714
+ <div class="nile-chart-skeleton" aria-busy="true" aria-label="Loading chart">
1715
+ <div class="nile-chart-skeleton-body">
1716
+ ${[78, 55, 91, 42, 68].map(w => html `
1717
+ <div class="nile-chart-skeleton-row">
1718
+ <div class="nile-chart-skeleton-ylabel"></div>
1719
+ <div class="nile-chart-skeleton-bar" style="--w: ${w}%"></div>
1720
+ </div>
1721
+ `)}
1722
+ </div>
1723
+ <div class="nile-chart-skeleton-xaxis-row">
1724
+ ${[0, 1, 2, 3, 4].map(i => html `<div class="nile-chart-skeleton-xlabel" style="--d: ${i * 80}ms"></div>`)}
1725
+ </div>
1726
+ </div>
1727
+ `;
1715
1728
  }
1716
1729
  render() {
1717
1730
  const isLoading = this.loading || (this.activeConfig?.loading ?? false);
1718
1731
  const isGrid = this.activeConfig?.type === 'grid';
1719
1732
  return html `
1720
- <div class="nile-chart-card ${isGrid ? 'nile-chart-card--grid' : ''} ${isLoading ? 'nile-chart-card--loading' : ''}" part="chart-card">
1733
+ <div class="nile-chart-card ${isGrid ? 'nile-chart-card--grid' : ''}" part="chart-card">
1721
1734
  ${this.renderHeader()}
1722
1735
  <div class="nile-chart-wrapper">
1723
1736
  <div class="nile-chart-inner ${this.activeConfig?.type === 'kpi' ? 'nile-chart-inner--kpi' : ''} ${this.activeConfig?.type === 'filter' ? 'nile-chart-inner--filter' : ''}" part="chart-inner">