@aquera/nile-visualization 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,10 +7,10 @@ export type { TrendlineSeriesData, ForecastConfig } from './nile-trendline-chart
7
7
  export { NileAnomalyChart } from './nile-anomaly-chart/index.js';
8
8
  export type { AnomalySeriesData, AnomalyConfig } from './nile-anomaly-chart/index.js';
9
9
  export { NileChart } from './nile-chart/index.js';
10
- export type { NileChartConfig, NileBarChartConfig, NilePieChartConfig, NileTrendlineChartConfig, NileAnomalyChartConfig, NileLineChartConfig, NileAreaChartConfig, NileColumnChartConfig, NileDonutChartConfig, NileScatterChartConfig, NileBubbleChartConfig, NileSplineChartConfig, NileRadarChartConfig, NileGaugeChartConfig, NileWaterfallChartConfig, ChartType, SwitchAggregation, NileAiConfig, } from './nile-chart/index.js';
10
+ export type { NileChartConfig, NileBarChartConfig, NilePieChartConfig, NileTrendlineChartConfig, NileAnomalyChartConfig, NileLineChartConfig, NileAreaChartConfig, NileColumnChartConfig, NileDonutChartConfig, NileScatterChartConfig, NileBubbleChartConfig, NileSplineChartConfig, NileRadarChartConfig, NileGaugeChartConfig, NileWaterfallChartConfig, NileKpiChartConfig, ChartType, SwitchAggregation, NileAiConfig, } from './nile-chart/index.js';
11
11
  export { convertConfig, registerAdapter } from './nile-chart/index.js';
12
12
  export { nileChartConfig } from './nile-chart/index.js';
13
- export type { AiConfigType, SwitchableConfigType, AqConfigType, ChartBarConfigType, ChartPieConfigType, ChartTrendlineConfigType, ChartAnomalyConfigType, ChartLineConfigType, ChartAreaConfigType, ChartInvertedAreaConfigType, ChartColumnConfigType, ChartDonutConfigType, ChartScatterConfigType, ChartBubbleConfigType, ChartSplineConfigType, ChartRadarConfigType, ChartGaugeConfigType, ChartWaterfallConfigType, ChartClusterConfigType, ChartStackedConfigType, ChartHistogramConfigType, ChartBellcurveConfigType, ChartBoxplotConfigType, ChartTimelineConfigType, ChartDumbbellConfigType, ChartDumbbellLowerConfigType, ChartDumbbellUpperConfigType, ChartColumnPyramidConfigType, ChartLollipopConfigType, ChartAreaSplineConfigType, ChartAreaNegativeConfigType, ChartAreaRangeConfigType, ChartColumnRangeConfigType, ChartColumnDrilldownConfigType, ChartRadialBarConfigType, ChartVariablePieConfigType, ChartEulerConfigType, ChartPolygonConfigType, ChartVectorConfigType, ChartXrangeConfigType, ChartFanConfigType, ChartFunnelConfigType, ChartOrganizationConfigType, ChartLineColumnConfigType, ChartHeatmapConfigType, ChartFlameConfigType, ChartSpiderwebConfigType, ChartKpiPropsType, PrimitiveChartConfigType, SeparatedChartConfigInputType, AllChartConfigType, ChartConfigType, NileChartConfigInputType, ChartAiPanelPayload, ChartAiSenderPayload, NileAiPanelConfigInputType, NileAiSenderConfigInputType, } from './nile-chart/index.js';
13
+ export type { AiConfigType, SwitchableConfigType, AqConfigType, ChartBarConfigType, ChartPieConfigType, ChartTrendlineConfigType, ChartAnomalyConfigType, ChartLineConfigType, ChartAreaConfigType, ChartInvertedAreaConfigType, ChartColumnConfigType, ChartDonutConfigType, ChartScatterConfigType, ChartBubbleConfigType, ChartSplineConfigType, ChartRadarConfigType, ChartGaugeConfigType, ChartWaterfallConfigType, ChartClusterConfigType, ChartStackedConfigType, ChartHistogramConfigType, ChartBellcurveConfigType, ChartBoxplotConfigType, ChartTimelineConfigType, ChartDumbbellConfigType, ChartDumbbellLowerConfigType, ChartDumbbellUpperConfigType, ChartColumnPyramidConfigType, ChartLollipopConfigType, ChartAreaSplineConfigType, ChartAreaNegativeConfigType, ChartAreaRangeConfigType, ChartColumnRangeConfigType, ChartColumnDrilldownConfigType, ChartRadialBarConfigType, ChartVariablePieConfigType, ChartEulerConfigType, ChartPolygonConfigType, ChartVectorConfigType, ChartXrangeConfigType, ChartFanConfigType, ChartFunnelConfigType, ChartOrganizationConfigType, ChartLineColumnConfigType, ChartHeatmapConfigType, ChartFlameConfigType, ChartSpiderwebConfigType, ChartKpiConfigType, ChartKpiPropsType, PrimitiveChartConfigType, SeparatedChartConfigInputType, AllChartConfigType, ChartConfigType, NileChartConfigInputType, ChartAiPanelPayload, ChartAiSenderPayload, NileAiPanelConfigInputType, NileAiSenderConfigInputType, } from './nile-chart/index.js';
14
14
  export type { SeparatedChartDemoConfig } from './internal/separated-chart-config.js';
15
15
  export { NileLineChart } from './nile-line-chart/index.js';
16
16
  export type { LineChartSeriesData } from './nile-line-chart/index.js';
@@ -1,21 +1,5 @@
1
- import type { KpiVariant, TrendDirection } from '../../nile-kpi-chart/nile-kpi-chart.js';
2
- /**
3
- * KPI tile / sparkline / gauge props (`<nile-kpi-chart>`).
4
- * This is not a `config` object; properties map to Lit `@property` fields.
5
- */
6
- export interface ChartKpiPropsType {
7
- variant?: KpiVariant;
8
- label?: string;
9
- value?: string | number;
10
- prefix?: string;
11
- suffix?: string;
12
- trendValue?: number | null;
13
- trendDirection?: TrendDirection;
14
- trendLabel?: string;
15
- description?: string;
16
- sparkline?: number[];
17
- sparklineColor?: string;
18
- gaugeValue?: number;
19
- gaugeMin?: number;
20
- gaugeMax?: number;
21
- }
1
+ import type { ChartKpiSeparatedPayload } from '../../nile-kpi-chart/nile-kpi-chart.js';
2
+ /** `chart` slice for `type: 'kpi'` — use with `<nile-chart>` or `{ chart, aq }` on `<nile-kpi-chart>`. */
3
+ export type ChartKpiConfigType = ChartKpiSeparatedPayload;
4
+ /** KPI fields without the `type` discriminator (partial props / documentation). */
5
+ export type ChartKpiPropsType = Omit<ChartKpiSeparatedPayload, 'type'>;
@@ -44,7 +44,7 @@ export type { ChartLineColumnConfigType } from './chart-line-column-config.type.
44
44
  export type { ChartHeatmapConfigType } from './chart-heatmap-config.type.js';
45
45
  export type { ChartFlameConfigType } from './chart-flame-config.type.js';
46
46
  export type { ChartSpiderwebConfigType } from './chart-spiderweb-config.type.js';
47
- export type { ChartKpiPropsType } from './chart-kpi-config.type.js';
47
+ export type { ChartKpiConfigType, ChartKpiPropsType } from './chart-kpi-config.type.js';
48
48
  export type { PrimitiveChartConfigType } from './primitive-chart-config.type.js';
49
49
  export type { SeparatedChartConfigInputType } from './separated-chart-config-input.type.js';
50
50
  export type { AllChartConfigType } from './all-chart-config.type.js';
@@ -12,6 +12,7 @@ import type { ChartLineColumnConfigType } from './chart-line-column-config.type.
12
12
  import type { ChartHeatmapConfigType } from './chart-heatmap-config.type.js';
13
13
  import type { ChartFlameConfigType } from './chart-flame-config.type.js';
14
14
  import type { ChartSpiderwebConfigType } from './chart-spiderweb-config.type.js';
15
+ import type { ChartKpiConfigType } from './chart-kpi-config.type.js';
15
16
  import type { ChartInvertedAreaConfigType } from './chart-area-config.type.js';
16
17
  import type { ChartColumnPyramidConfigType } from './chart-column-pyramid-config.type.js';
17
18
  import type { ChartLollipopConfigType } from './chart-lollipop-config.type.js';
@@ -32,4 +33,4 @@ import type { ChartXrangeConfigType } from './chart-xrange-config.type.js';
32
33
  * Chart configs for primitive `<nile-*-chart>` elements (`el.config = { chart, aq }`).
33
34
  * Discriminated on `chart.type`.
34
35
  */
35
- export type PrimitiveChartConfigType = ChartInvertedAreaConfigType | ChartColumnPyramidConfigType | ChartLollipopConfigType | ChartAreaSplineConfigType | ChartAreaNegativeConfigType | ChartAreaRangeConfigType | ChartColumnRangeConfigType | ChartColumnDrilldownConfigType | ChartRadialBarConfigType | ChartVariablePieConfigType | ChartDumbbellLowerConfigType | ChartDumbbellUpperConfigType | ChartEulerConfigType | ChartPolygonConfigType | ChartVectorConfigType | ChartXrangeConfigType | ChartClusterConfigType | ChartStackedConfigType | ChartHistogramConfigType | ChartBellcurveConfigType | ChartBoxplotConfigType | ChartTimelineConfigType | ChartDumbbellConfigType | ChartFanConfigType | ChartFunnelConfigType | ChartOrganizationConfigType | ChartLineColumnConfigType | ChartHeatmapConfigType | ChartFlameConfigType | ChartSpiderwebConfigType;
36
+ export type PrimitiveChartConfigType = ChartInvertedAreaConfigType | ChartColumnPyramidConfigType | ChartLollipopConfigType | ChartAreaSplineConfigType | ChartAreaNegativeConfigType | ChartAreaRangeConfigType | ChartColumnRangeConfigType | ChartColumnDrilldownConfigType | ChartRadialBarConfigType | ChartVariablePieConfigType | ChartDumbbellLowerConfigType | ChartDumbbellUpperConfigType | ChartEulerConfigType | ChartPolygonConfigType | ChartVectorConfigType | ChartXrangeConfigType | ChartClusterConfigType | ChartStackedConfigType | ChartHistogramConfigType | ChartBellcurveConfigType | ChartBoxplotConfigType | ChartTimelineConfigType | ChartDumbbellConfigType | ChartFanConfigType | ChartFunnelConfigType | ChartOrganizationConfigType | ChartLineColumnConfigType | ChartHeatmapConfigType | ChartFlameConfigType | ChartSpiderwebConfigType | ChartKpiConfigType;
@@ -40,6 +40,14 @@ export const styles = css `
40
40
  border-bottom-left-radius: var(--nile-radius-radius-sm, var(--ng-radius-xs));
41
41
  }
42
42
 
43
+ .message--summary {
44
+ align-self: flex-start;
45
+ background: var(--nile-colors-primary-50, #eff6ff);
46
+ color: var(--nile-colors-primary-800, #1e40af);
47
+ border: var(--nile-border-width-1, 1px) solid var(--nile-colors-primary-200, #bfdbfe);
48
+ border-bottom-left-radius: var(--nile-radius-radius-sm, var(--ng-radius-xs));
49
+ }
50
+
43
51
  .typing {
44
52
  align-self: flex-start;
45
53
  padding: var(--nile-spacing-md, var(--ng-spacing-md)) var(--nile-spacing-14px, var(--ng-spacing-3-5));
@@ -10,6 +10,8 @@ export declare class NileAiPanel extends NileElement {
10
10
  placeholder: string;
11
11
  /** Welcome message shown when the panel opens. */
12
12
  welcomeMessage: string;
13
+ /** Summary / insight shown as a second assistant bubble after the welcome message. */
14
+ summaryMessage: string;
13
15
  private messages;
14
16
  private loading;
15
17
  private messagesEl;
@@ -13,6 +13,8 @@ let NileAiPanel = class NileAiPanel extends NileElement {
13
13
  this.placeholder = 'Ask about this chart...';
14
14
  /** Welcome message shown when the panel opens. */
15
15
  this.welcomeMessage = '';
16
+ /** Summary / insight shown as a second assistant bubble after the welcome message. */
17
+ this.summaryMessage = '';
16
18
  this.messages = [];
17
19
  this.loading = false;
18
20
  }
@@ -87,6 +89,9 @@ let NileAiPanel = class NileAiPanel extends NileElement {
87
89
  ${this.welcomeMessage
88
90
  ? html `<div class="message message--assistant">${this.welcomeMessage}</div>`
89
91
  : nothing}
92
+ ${this.summaryMessage
93
+ ? html `<div class="message message--summary">${this.summaryMessage}</div>`
94
+ : nothing}
90
95
  ${this.messages.map(m => html `<div class="message message--${m.role}">${m.text}</div>`)}
91
96
  ${this.loading
92
97
  ? html `<div class="typing">
@@ -116,6 +121,9 @@ __decorate([
116
121
  __decorate([
117
122
  property({ type: String, attribute: 'welcome-message' })
118
123
  ], NileAiPanel.prototype, "welcomeMessage", void 0);
124
+ __decorate([
125
+ property({ type: String, attribute: 'summary-message' })
126
+ ], NileAiPanel.prototype, "summaryMessage", void 0);
119
127
  __decorate([
120
128
  state()
121
129
  ], NileAiPanel.prototype, "messages", void 0);
@@ -1,5 +1,5 @@
1
1
  export { NileChart } from './nile-chart.js';
2
- export type { NileChartConfig, NileBarChartConfig, NilePieChartConfig, NileTrendlineChartConfig, NileAnomalyChartConfig, NileLineChartConfig, NileAreaChartConfig, NileColumnChartConfig, NileDonutChartConfig, NileScatterChartConfig, NileBubbleChartConfig, NileSplineChartConfig, NileRadarChartConfig, NileGaugeChartConfig, NileWaterfallChartConfig, ChartType, SwitchAggregation, NileAiConfig, } from './nile-chart-config.js';
2
+ export type { NileChartConfig, NileBarChartConfig, NilePieChartConfig, NileTrendlineChartConfig, NileAnomalyChartConfig, NileLineChartConfig, NileAreaChartConfig, NileColumnChartConfig, NileDonutChartConfig, NileScatterChartConfig, NileBubbleChartConfig, NileSplineChartConfig, NileRadarChartConfig, NileGaugeChartConfig, NileWaterfallChartConfig, NileKpiChartConfig, ChartType, SwitchAggregation, NileAiConfig, } from './nile-chart-config.js';
3
3
  export { convertConfig, registerAdapter } from '../internal/chart-adapters.js';
4
4
  export { nileChartConfig } from './nile-chart-config-builder.js';
5
- export type { AiConfigType, SwitchableConfigType, AqConfigType, ChartBarConfigType, ChartPieConfigType, ChartTrendlineConfigType, ChartAnomalyConfigType, ChartLineConfigType, ChartAreaConfigType, ChartInvertedAreaConfigType, ChartColumnConfigType, ChartDonutConfigType, ChartScatterConfigType, ChartBubbleConfigType, ChartSplineConfigType, ChartRadarConfigType, ChartGaugeConfigType, ChartWaterfallConfigType, ChartClusterConfigType, ChartStackedConfigType, ChartHistogramConfigType, ChartBellcurveConfigType, ChartBoxplotConfigType, ChartTimelineConfigType, ChartDumbbellConfigType, ChartDumbbellLowerConfigType, ChartDumbbellUpperConfigType, ChartColumnPyramidConfigType, ChartLollipopConfigType, ChartAreaSplineConfigType, ChartAreaNegativeConfigType, ChartAreaRangeConfigType, ChartColumnRangeConfigType, ChartColumnDrilldownConfigType, ChartRadialBarConfigType, ChartVariablePieConfigType, ChartEulerConfigType, ChartPolygonConfigType, ChartVectorConfigType, ChartXrangeConfigType, ChartFanConfigType, ChartFunnelConfigType, ChartOrganizationConfigType, ChartLineColumnConfigType, ChartHeatmapConfigType, ChartFlameConfigType, ChartSpiderwebConfigType, ChartKpiPropsType, PrimitiveChartConfigType, SeparatedChartConfigInputType, AllChartConfigType, ChartConfigType, NileChartConfigInputType, ChartAiPanelPayload, ChartAiSenderPayload, NileAiPanelConfigInputType, NileAiSenderConfigInputType, } from '../internal/types/index.js';
5
+ export type { AiConfigType, SwitchableConfigType, AqConfigType, ChartBarConfigType, ChartPieConfigType, ChartTrendlineConfigType, ChartAnomalyConfigType, ChartLineConfigType, ChartAreaConfigType, ChartInvertedAreaConfigType, ChartColumnConfigType, ChartDonutConfigType, ChartScatterConfigType, ChartBubbleConfigType, ChartSplineConfigType, ChartRadarConfigType, ChartGaugeConfigType, ChartWaterfallConfigType, ChartClusterConfigType, ChartStackedConfigType, ChartHistogramConfigType, ChartBellcurveConfigType, ChartBoxplotConfigType, ChartTimelineConfigType, ChartDumbbellConfigType, ChartDumbbellLowerConfigType, ChartDumbbellUpperConfigType, ChartColumnPyramidConfigType, ChartLollipopConfigType, ChartAreaSplineConfigType, ChartAreaNegativeConfigType, ChartAreaRangeConfigType, ChartColumnRangeConfigType, ChartColumnDrilldownConfigType, ChartRadialBarConfigType, ChartVariablePieConfigType, ChartEulerConfigType, ChartPolygonConfigType, ChartVectorConfigType, ChartXrangeConfigType, ChartFanConfigType, ChartFunnelConfigType, ChartOrganizationConfigType, ChartLineColumnConfigType, ChartHeatmapConfigType, ChartFlameConfigType, ChartSpiderwebConfigType, ChartKpiConfigType, ChartKpiPropsType, PrimitiveChartConfigType, SeparatedChartConfigInputType, AllChartConfigType, ChartConfigType, NileChartConfigInputType, ChartAiPanelPayload, ChartAiSenderPayload, NileAiPanelConfigInputType, NileAiSenderConfigInputType, } from '../internal/types/index.js';
@@ -70,3 +70,6 @@ export type NileGaugeChartConfig = Extract<NileChartConfig, {
70
70
  export type NileWaterfallChartConfig = Extract<NileChartConfig, {
71
71
  type: 'waterfall';
72
72
  }>;
73
+ export type NileKpiChartConfig = Extract<NileChartConfig, {
74
+ type: 'kpi';
75
+ }>;
@@ -13,7 +13,7 @@ export const styles = css `
13
13
  /* ── Unified Card Container ── */
14
14
 
15
15
  .chart-card {
16
- background: var(--nile-colors-white-base, var(--ng-colors-bg-quaternary-alt));
16
+ background: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
17
17
  border: var(--nile-border-width-1, var(--ng-stroke-width-1)) solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
18
18
  border-radius: var(--nile-radius-radius-3xl, var(--ng-radius-xl));
19
19
  box-shadow: var(--nile-box-shadow-3, var(--ng-shadow-sm));
@@ -33,7 +33,7 @@ export const styles = css `
33
33
  position: relative;
34
34
  z-index: 10;
35
35
  padding: var(--nile-spacing-2xl, var(--ng-spacing-2xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl)) var(--nile-spacing-xl, var(--ng-spacing-xl));
36
- background: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
36
+ background: transparent;
37
37
  border-bottom: var(--nile-border-width-1, var(--ng-stroke-width-1)) solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
38
38
  border-radius: var(--nile-radius-radius-3xl, var(--ng-radius-xl)) var(--nile-radius-radius-3xl, var(--ng-radius-xl)) 0 0;
39
39
  }
@@ -82,10 +82,35 @@ export const styles = css `
82
82
  contain: layout style;
83
83
  }
84
84
 
85
- ::slotted(*) {
85
+ /* ── Default slot (custom chart body only — not named slots) ── */
86
+ slot:not([name])::slotted(*) {
87
+ display: block;
86
88
  width: 100%;
87
89
  }
88
90
 
91
+ /* ── header / header-actions slots (one row; built-in AI + switcher on the right) ── */
92
+ slot[name='header']::slotted(*) {
93
+ display: block;
94
+ width: 100%;
95
+ }
96
+
97
+ slot[name='header-actions']::slotted(*) {
98
+ display: inline-flex;
99
+ align-items: center;
100
+ gap: var(--nile-spacing-xs, var(--ng-spacing-xs));
101
+ }
102
+
103
+ /* ── footer slot ── */
104
+ slot[name='footer']::slotted(*) {
105
+ display: block;
106
+ margin: 0;
107
+ padding: var(--nile-spacing-xl, var(--ng-spacing-xl)) var(--nile-spacing-3xl, var(--ng-spacing-3xl));
108
+ border-top: var(--nile-border-width-1, var(--ng-stroke-width-1)) solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
109
+ font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
110
+ font-size: var(--nile-type-scale-2, var(--ng-font-size-text-xs));
111
+ color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));
112
+ }
113
+
89
114
  nile-bar-chart,
90
115
  nile-pie-chart,
91
116
  nile-trendline-chart,
@@ -128,7 +153,7 @@ export const styles = css `
128
153
  }
129
154
 
130
155
  .chart-toggle:hover {
131
- background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
156
+ background: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
132
157
  box-shadow: var(--nile-box-shadow-3, var(--ng-shadow-sm));
133
158
  }
134
159
 
@@ -188,7 +213,7 @@ export const styles = css `
188
213
  }
189
214
 
190
215
  .chart-menu-trigger:hover {
191
- background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
216
+ background: transparent;
192
217
  color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
193
218
  }
194
219
 
@@ -228,7 +253,7 @@ export const styles = css `
228
253
  }
229
254
 
230
255
  .chart-menu-item:hover {
231
- background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
256
+ background: transparent;
232
257
  }
233
258
 
234
259
  .chart-menu-item.active {
@@ -259,7 +284,7 @@ export const styles = css `
259
284
  }
260
285
 
261
286
  .ai-trigger:hover {
262
- background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
287
+ background: transparent;
263
288
  color: var(--nile-colors-primary-600, var(--ng-colors-fg-brand-primary-600));
264
289
  }
265
290
 
@@ -46,6 +46,7 @@ import '../nile-euler-chart/index.js';
46
46
  import '../nile-polygon-chart/index.js';
47
47
  import '../nile-vector-chart/index.js';
48
48
  import '../nile-xrange-chart/index.js';
49
+ import '../nile-kpi-chart/index.js';
49
50
  import '../nile-ai-panel/index.js';
50
51
  export declare class NileChart extends NileElement {
51
52
  static styles: CSSResultGroup;
@@ -56,19 +57,19 @@ export declare class NileChart extends NileElement {
56
57
  * Usage: `<nile-chart chart-type="pie" />` plus `config.chart` with series data only.
57
58
  */
58
59
  chartTypeAttr: string;
59
- /** The summary/insight text displayed in the overlay (fallback when config is not set). */
60
+ /** Summary/insight text shown as the AI panel's opening message when the chat is opened. */
60
61
  summary: string;
61
- /** Label for the toggle button (fallback when config is not set). */
62
- toggleLabel: string;
63
- /** Whether the insight overlay is visible. */
64
- open: boolean;
65
62
  private activeType;
66
63
  private activeConfig;
67
64
  private menuOpen;
68
65
  private chatOpen;
66
+ /** True when elements are projected into the `header` slot (default title/subtitle hidden). */
67
+ private hasHeaderSlotContent;
68
+ /** True when elements are projected into `header-actions` (used to show the header row). */
69
+ private hasHeaderActionsSlot;
69
70
  private aiPanel;
70
71
  private get effectiveSummary();
71
- private get effectiveToggleLabel();
72
+ /** AI panel shows when ai.enabled is true OR when a summary is provided. */
72
73
  private get aiEnabled();
73
74
  private handleOutsideClick;
74
75
  connectedCallback(): void;
@@ -78,7 +79,6 @@ export declare class NileChart extends NileElement {
78
79
  private resolveConfig;
79
80
  private resolvedConfig;
80
81
  protected updated(changedProperties: PropertyValues): void;
81
- private toggle;
82
82
  private toggleMenu;
83
83
  private toggleChat;
84
84
  /** Push an AI response into the chat panel. Call this from your AI handler. */
@@ -87,6 +87,11 @@ export declare class NileChart extends NileElement {
87
87
  private switchType;
88
88
  private get headerTitle();
89
89
  private get headerSubtitle();
90
+ private onHeaderSlotChange;
91
+ private onHeaderActionsSlotChange;
92
+ private syncHeaderSlots;
93
+ protected firstUpdated(changedProperties: PropertyValues): void;
94
+ private shouldShowHeader;
90
95
  private renderTypeSwitcher;
91
96
  private renderAiTrigger;
92
97
  private renderHeader;
@@ -49,6 +49,7 @@ import '../nile-euler-chart/index.js';
49
49
  import '../nile-polygon-chart/index.js';
50
50
  import '../nile-vector-chart/index.js';
51
51
  import '../nile-xrange-chart/index.js';
52
+ import '../nile-kpi-chart/index.js';
52
53
  import '../nile-ai-panel/index.js';
53
54
  const CORE_CHART_LABELS = {
54
55
  bar: 'Bar',
@@ -84,6 +85,7 @@ const CORE_CHART_LABELS = {
84
85
  xrange: 'X-range',
85
86
  lollipop: 'Lollipop',
86
87
  'line-column': 'Line + column',
88
+ kpi: 'KPI',
87
89
  };
88
90
  function chartTypeLabel(type) {
89
91
  const hit = CORE_CHART_LABELS[type];
@@ -104,21 +106,20 @@ let NileChart = class NileChart extends NileElement {
104
106
  * Usage: `<nile-chart chart-type="pie" />` plus `config.chart` with series data only.
105
107
  */
106
108
  this.chartTypeAttr = '';
107
- /** The summary/insight text displayed in the overlay (fallback when config is not set). */
109
+ /** Summary/insight text shown as the AI panel's opening message when the chat is opened. */
108
110
  this.summary = '';
109
- /** Label for the toggle button (fallback when config is not set). */
110
- this.toggleLabel = 'Summary';
111
- /** Whether the insight overlay is visible. */
112
- this.open = false;
113
111
  this.activeType = null;
114
112
  this.activeConfig = null;
115
113
  this.menuOpen = false;
116
114
  this.chatOpen = false;
115
+ /** True when elements are projected into the `header` slot (default title/subtitle hidden). */
116
+ this.hasHeaderSlotContent = false;
117
+ /** True when elements are projected into `header-actions` (used to show the header row). */
118
+ this.hasHeaderActionsSlot = false;
117
119
  this.handleOutsideClick = (e) => {
118
120
  if (!this.contains(e.target)) {
119
- this.open = false;
120
121
  this.menuOpen = false;
121
- this.emit('nile-chart-toggle', { open: this.open });
122
+ this.chatOpen = false;
122
123
  }
123
124
  };
124
125
  this.resolvedConfig = null;
@@ -126,11 +127,9 @@ let NileChart = class NileChart extends NileElement {
126
127
  get effectiveSummary() {
127
128
  return this.resolvedConfig?.summary ?? this.summary;
128
129
  }
129
- get effectiveToggleLabel() {
130
- return this.resolvedConfig?.toggleLabel ?? this.toggleLabel;
131
- }
130
+ /** AI panel shows when ai.enabled is true OR when a summary is provided. */
132
131
  get aiEnabled() {
133
- return this.resolvedConfig?.ai?.enabled === true;
132
+ return this.resolvedConfig?.ai?.enabled === true || !!this.effectiveSummary;
134
133
  }
135
134
  connectedCallback() {
136
135
  super.connectedCallback();
@@ -169,13 +168,6 @@ let NileChart = class NileChart extends NileElement {
169
168
  this.activeConfig = this.resolvedConfig;
170
169
  }
171
170
  }
172
- toggle(e) {
173
- e.stopPropagation();
174
- this.open = !this.open;
175
- if (this.open)
176
- this.chatOpen = false;
177
- this.emit('nile-chart-toggle', { open: this.open });
178
- }
179
171
  toggleMenu(e) {
180
172
  e.stopPropagation();
181
173
  this.menuOpen = !this.menuOpen;
@@ -183,8 +175,6 @@ let NileChart = class NileChart extends NileElement {
183
175
  toggleChat(e) {
184
176
  e.stopPropagation();
185
177
  this.chatOpen = !this.chatOpen;
186
- if (this.chatOpen)
187
- this.open = false;
188
178
  this.emit('nile-chart-ai-toggle', { open: this.chatOpen });
189
179
  }
190
180
  /** Push an AI response into the chat panel. Call this from your AI handler. */
@@ -220,6 +210,52 @@ let NileChart = class NileChart extends NileElement {
220
210
  get headerSubtitle() {
221
211
  return this.activeConfig?.chartSubtitle ?? this.resolvedConfig?.chartSubtitle ?? '';
222
212
  }
213
+ onHeaderSlotChange(e) {
214
+ const slot = e.target;
215
+ this.hasHeaderSlotContent = slot.assignedElements({ flatten: true }).length > 0;
216
+ this.requestUpdate();
217
+ }
218
+ onHeaderActionsSlotChange(e) {
219
+ const slot = e.target;
220
+ this.hasHeaderActionsSlot = slot.assignedElements({ flatten: true }).length > 0;
221
+ this.requestUpdate();
222
+ }
223
+ syncHeaderSlots() {
224
+ const root = this.shadowRoot;
225
+ if (!root)
226
+ return;
227
+ const headerSlot = root.querySelector('slot[name="header"]');
228
+ const actionsSlot = root.querySelector('slot[name="header-actions"]');
229
+ let changed = false;
230
+ if (headerSlot) {
231
+ const next = headerSlot.assignedElements({ flatten: true }).length > 0;
232
+ if (next !== this.hasHeaderSlotContent) {
233
+ this.hasHeaderSlotContent = next;
234
+ changed = true;
235
+ }
236
+ }
237
+ if (actionsSlot) {
238
+ const next = actionsSlot.assignedElements({ flatten: true }).length > 0;
239
+ if (next !== this.hasHeaderActionsSlot) {
240
+ this.hasHeaderActionsSlot = next;
241
+ changed = true;
242
+ }
243
+ }
244
+ if (changed)
245
+ this.requestUpdate();
246
+ }
247
+ firstUpdated(changedProperties) {
248
+ super.firstUpdated(changedProperties);
249
+ this.syncHeaderSlots();
250
+ }
251
+ shouldShowHeader() {
252
+ const hasTitles = !!(this.headerTitle || this.headerSubtitle);
253
+ const hasBuiltinActions = this.aiEnabled || (this.resolvedConfig?.switchableTypes?.length ?? 0) > 0;
254
+ return (hasTitles ||
255
+ this.hasHeaderSlotContent ||
256
+ this.hasHeaderActionsSlot ||
257
+ hasBuiltinActions);
258
+ }
223
259
  renderTypeSwitcher() {
224
260
  const types = this.resolvedConfig?.switchableTypes;
225
261
  if (!types || types.length === 0)
@@ -268,19 +304,24 @@ let NileChart = class NileChart extends NileElement {
268
304
  `;
269
305
  }
270
306
  renderHeader() {
307
+ if (!this.shouldShowHeader())
308
+ return nothing;
271
309
  const title = this.headerTitle;
272
310
  const subtitle = this.headerSubtitle;
273
- const hasTypeSwitcher = (this.resolvedConfig?.switchableTypes?.length ?? 0) > 0;
274
- const hasActions = hasTypeSwitcher || this.aiEnabled;
275
- if (!title && !subtitle && !hasActions)
276
- return nothing;
311
+ const showDefaultTitles = !this.hasHeaderSlotContent && !!(title || subtitle);
277
312
  return html `
278
313
  <div class="chart-header">
279
314
  <div class="chart-header-titles">
280
- ${title ? html `<h3 class="chart-header-title">${title}</h3>` : nothing}
281
- ${subtitle ? html `<p class="chart-header-subtitle">${subtitle}</p>` : nothing}
315
+ <slot name="header" @slotchange=${this.onHeaderSlotChange}></slot>
316
+ ${showDefaultTitles
317
+ ? html `
318
+ ${title ? html `<h3 class="chart-header-title">${title}</h3>` : nothing}
319
+ ${subtitle ? html `<p class="chart-header-subtitle">${subtitle}</p>` : nothing}
320
+ `
321
+ : nothing}
282
322
  </div>
283
323
  <div class="chart-header-actions">
324
+ <slot name="header-actions" @slotchange=${this.onHeaderActionsSlotChange}></slot>
284
325
  ${this.renderAiTrigger()}
285
326
  ${this.renderTypeSwitcher()}
286
327
  </div>
@@ -290,12 +331,19 @@ let NileChart = class NileChart extends NileElement {
290
331
  renderAiPanel() {
291
332
  if (!this.aiEnabled)
292
333
  return nothing;
293
- const aiConfig = this.resolvedConfig.ai;
334
+ const aiConfig = this.resolvedConfig?.ai;
335
+ const summary = this.effectiveSummary;
336
+ // Summary always takes priority. When summary is present it is the only
337
+ // opening message (shown in blue). welcomeMessage is only used when there
338
+ // is no summary at all.
339
+ const summaryMessage = summary;
340
+ const welcomeMessage = summary ? '' : (aiConfig?.welcomeMessage ?? '');
294
341
  return html `
295
342
  <div class="ai-panel-overlay" ?data-open=${this.chatOpen}>
296
343
  <nile-ai-panel
297
- .placeholder=${aiConfig.placeholder ?? 'Ask about this chart...'}
298
- .welcomeMessage=${aiConfig.welcomeMessage ?? ''}
344
+ .placeholder=${aiConfig?.placeholder ?? 'Ask about this chart...'}
345
+ .welcomeMessage=${welcomeMessage}
346
+ .summaryMessage=${summaryMessage}
299
347
  @nile-ai-send=${this.handleAiSend}
300
348
  ></nile-ai-panel>
301
349
  </div>
@@ -768,6 +816,37 @@ let NileChart = class NileChart extends NileElement {
768
816
  .options=${mergedOptions}
769
817
  .loading=${config.loading ?? false}
770
818
  ></nile-xrange-chart>`;
819
+ case 'kpi': {
820
+ const k = config;
821
+ return html `<nile-kpi-chart
822
+ .config=${{
823
+ chart: {
824
+ type: 'kpi',
825
+ variant: k.variant,
826
+ label: k.label,
827
+ value: k.value,
828
+ prefix: k.prefix,
829
+ suffix: k.suffix,
830
+ trendValue: k.trendValue,
831
+ trendDirection: k.trendDirection,
832
+ trendLabel: k.trendLabel,
833
+ description: k.description,
834
+ sparkline: k.sparkline,
835
+ sparklineColor: k.sparklineColor,
836
+ gaugeValue: k.gaugeValue,
837
+ gaugeMin: k.gaugeMin,
838
+ gaugeMax: k.gaugeMax,
839
+ gaugeColor: k.gaugeColor,
840
+ loading: k.loading,
841
+ options: k.options,
842
+ height: k.height,
843
+ },
844
+ aq: {
845
+ chartSubtitle: k.chartSubtitle,
846
+ },
847
+ }}
848
+ ></nile-kpi-chart>`;
849
+ }
771
850
  default: {
772
851
  const _exhaustive = config;
773
852
  return _exhaustive;
@@ -781,23 +860,10 @@ let NileChart = class NileChart extends NileElement {
781
860
  <div class="chart-wrapper">
782
861
  <div class="chart-inner">
783
862
  ${this.activeConfig ? this.renderChartContent() : html `<slot></slot>`}
784
- <button
785
- class="chart-toggle"
786
- aria-expanded="${this.open}"
787
- @click="${this.toggle}"
788
- >
789
- ${this.effectiveToggleLabel}
790
- </button>
791
- <div class="chart-overlay" ?data-open="${this.open}">
792
- <div class="chart-content">
793
- ${this.resolvedConfig
794
- ? this.effectiveSummary
795
- : html `<slot name="insight">${this.summary}</slot>`}
796
- </div>
797
- </div>
798
863
  ${this.renderAiPanel()}
799
864
  </div>
800
865
  </div>
866
+ <slot name="footer"></slot>
801
867
  </div>
802
868
  `;
803
869
  }
@@ -812,12 +878,6 @@ __decorate([
812
878
  __decorate([
813
879
  property({ type: String })
814
880
  ], NileChart.prototype, "summary", void 0);
815
- __decorate([
816
- property({ type: String, attribute: 'toggle-label' })
817
- ], NileChart.prototype, "toggleLabel", void 0);
818
- __decorate([
819
- state()
820
- ], NileChart.prototype, "open", void 0);
821
881
  __decorate([
822
882
  state()
823
883
  ], NileChart.prototype, "activeType", void 0);
@@ -830,6 +890,12 @@ __decorate([
830
890
  __decorate([
831
891
  state()
832
892
  ], NileChart.prototype, "chatOpen", void 0);
893
+ __decorate([
894
+ state()
895
+ ], NileChart.prototype, "hasHeaderSlotContent", void 0);
896
+ __decorate([
897
+ state()
898
+ ], NileChart.prototype, "hasHeaderActionsSlot", void 0);
833
899
  __decorate([
834
900
  query('nile-ai-panel')
835
901
  ], NileChart.prototype, "aiPanel", void 0);
@@ -13,7 +13,7 @@ export const styles = css `
13
13
  /* ── Card variant ── */
14
14
 
15
15
  .kpi-card {
16
- background: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
16
+ background: transparent;
17
17
  border: var(--nile-border-width-1, var(--ng-stroke-width-1)) solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
18
18
  border-radius: var(--nile-radius-radius-3xl, var(--ng-radius-xl));
19
19
  box-shadow: var(--nile-box-shadow-3, var(--ng-shadow-sm));
@@ -79,17 +79,17 @@ export const styles = css `
79
79
  }
80
80
 
81
81
  .kpi-trend--up {
82
- background: var(--nile-colors-success-100, #ECFDF3);
82
+ background: none;
83
83
  color: var(--nile-colors-success-700, #067647);
84
84
  }
85
85
 
86
86
  .kpi-trend--down {
87
- background: var(--nile-colors-error-100, #FEF3F2);
87
+ background: none;
88
88
  color: var(--nile-colors-error-700, #B42318);
89
89
  }
90
90
 
91
91
  .kpi-trend--neutral {
92
- background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
92
+ background: none;
93
93
  color: var(--nile-colors-neutral-700, var(--ng-colors-text-secondary-700));
94
94
  }
95
95
 
@@ -24,6 +24,8 @@ export interface ChartKpiSeparatedPayload {
24
24
  gaugeColor?: string;
25
25
  loading?: boolean;
26
26
  options?: Highcharts.Options;
27
+ /** Optional min height when embedded in `<nile-chart>` (maps to host `min-height`). */
28
+ height?: string;
27
29
  }
28
30
  /** Separated `{ chart, aq }` input for `<nile-kpi-chart>`. */
29
31
  export interface NileKpiConfigInputType {
@@ -86,6 +86,12 @@ let NileKpiChart = class NileKpiChart extends NileElement {
86
86
  this.loading = c.loading;
87
87
  if (c.options !== undefined)
88
88
  this.options = c.options;
89
+ if (c.height !== undefined) {
90
+ if (c.height)
91
+ this.style.minHeight = c.height;
92
+ else
93
+ this.style.removeProperty('min-height');
94
+ }
89
95
  }
90
96
  if (aq) {
91
97
  if (aq.chartTitle != null)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aquera/nile-visualization",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "A visualization Library for the Nile Design System",
5
5
  "license": "MIT",
6
6
  "author": "Aquera Inc",