@aquera/nile-visualization 2.9.11 → 2.9.13
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/dist/src/nile-chart/nile-chart-config.d.ts +27 -1
- package/dist/src/nile-chart/nile-chart.css.js +21 -3
- package/dist/src/nile-chart/nile-chart.d.ts +1 -0
- package/dist/src/nile-chart/nile-chart.js +28 -15
- package/dist/src/nile-filter-chart/nile-filter-chart.css.js +53 -29
- package/dist/src/nile-filter-chart/nile-filter-chart.d.ts +0 -1
- package/dist/src/nile-filter-chart/nile-filter-chart.js +0 -14
- package/dist/src/nile-filter-chart/utils/prompt.js +1 -4
- package/package.json +1 -1
|
@@ -59,6 +59,8 @@ export interface NileChartMenuItemDefault {
|
|
|
59
59
|
type: 'default';
|
|
60
60
|
/** Override the default label (e.g. "Download PNG"). */
|
|
61
61
|
label?: string;
|
|
62
|
+
/** Optional nile-glyph icon name shown as a leading prefix (e.g. `'download'`). */
|
|
63
|
+
glyph?: string;
|
|
62
64
|
/** Show a divider line above this item. */
|
|
63
65
|
divider?: boolean;
|
|
64
66
|
fullscreen?: true;
|
|
@@ -79,10 +81,34 @@ export interface NileChartMenuItemCustom {
|
|
|
79
81
|
label: string;
|
|
80
82
|
/** Identifier emitted in the `nile-menu-change` event when clicked. */
|
|
81
83
|
id: string;
|
|
84
|
+
/** Optional nile-glyph icon name shown as a leading prefix (e.g. `'share-07'`). */
|
|
85
|
+
glyph?: string;
|
|
82
86
|
/** Show a divider line above this item. */
|
|
83
87
|
divider?: boolean;
|
|
84
88
|
}
|
|
85
|
-
|
|
89
|
+
/**
|
|
90
|
+
* A group that renders a section header followed by its child items.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* {
|
|
94
|
+
* type: 'group',
|
|
95
|
+
* label: 'Export',
|
|
96
|
+
* items: [
|
|
97
|
+
* { type: 'default', downloadPng: true },
|
|
98
|
+
* { type: 'default', downloadCsv: true },
|
|
99
|
+
* ]
|
|
100
|
+
* }
|
|
101
|
+
*/
|
|
102
|
+
export interface NileChartMenuItemGroup {
|
|
103
|
+
type: 'group';
|
|
104
|
+
/** Text shown as the section header. */
|
|
105
|
+
label: string;
|
|
106
|
+
/** Items rendered under this group header. */
|
|
107
|
+
items: Array<NileChartMenuItemDefault | NileChartMenuItemCustom>;
|
|
108
|
+
/** Show a divider line above the group header. */
|
|
109
|
+
divider?: boolean;
|
|
110
|
+
}
|
|
111
|
+
export type NileChartMenuItem = NileChartMenuItemDefault | NileChartMenuItemCustom | NileChartMenuItemGroup;
|
|
86
112
|
/**
|
|
87
113
|
* Controls the chart's actions menu.
|
|
88
114
|
*
|
|
@@ -365,12 +365,14 @@ export const styles = css `
|
|
|
365
365
|
}
|
|
366
366
|
|
|
367
367
|
.nile-chart-menu-item {
|
|
368
|
-
display:
|
|
368
|
+
display: flex;
|
|
369
|
+
align-items: center;
|
|
370
|
+
gap: var(--nile-spacing-6px, var(--ng-spacing-sm));
|
|
369
371
|
width: 100%;
|
|
370
372
|
padding: var(--nile-spacing-md, var(--ng-spacing-md)) var(--nile-spacing-14px, var(--ng-spacing-3-5));
|
|
371
373
|
border: none;
|
|
372
374
|
background: none;
|
|
373
|
-
color: var(--nile-colors-dark-
|
|
375
|
+
color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
|
|
374
376
|
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
375
377
|
font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
|
|
376
378
|
font-weight: var(--nile-font-weight-medium, var(--ng-font-weight-medium));
|
|
@@ -379,6 +381,11 @@ export const styles = css `
|
|
|
379
381
|
transition: background var(--nile-transition-duration-short, var(--ng-transition-duration-fast)) ease;
|
|
380
382
|
}
|
|
381
383
|
|
|
384
|
+
.nile-chart-menu-item-glyph {
|
|
385
|
+
flex-shrink: 0;
|
|
386
|
+
color: var(--nile-colors-neutral-700, var(--ng-colors-text-quaternary-500));
|
|
387
|
+
}
|
|
388
|
+
|
|
382
389
|
.nile-chart-menu-item:hover {
|
|
383
390
|
background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
|
|
384
391
|
color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
|
|
@@ -397,7 +404,18 @@ export const styles = css `
|
|
|
397
404
|
.nile-chart-menu-separator {
|
|
398
405
|
height: var(--nile-border-width-1, var(--ng-stroke-width-1));
|
|
399
406
|
background: var(--nile-colors-neutral-200, var(--ng-colors-border-secondary));
|
|
400
|
-
margin: var(--nile-spacing-
|
|
407
|
+
margin: var(--nile-spacing-md, var(--ng-spacing-md));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.nile-chart-menu-group-header {
|
|
411
|
+
display: block;
|
|
412
|
+
padding: var(--nile-spacing-md, var(--ng-spacing-md)) var(--nile-spacing-14px, var(--ng-spacing-3-5)) var(--nile-spacing-xs, var(--ng-spacing-xs));
|
|
413
|
+
font-family: var(--nile-font-family-serif, var(--ng-font-family-body));
|
|
414
|
+
font-size: var(--nile-type-scale-3, var(--ng-font-size-text-sm));
|
|
415
|
+
font-weight: var(--nile-font-weight-medium, var(--ng-font-weight-medium));
|
|
416
|
+
color: var(--nile-colors-neutral-500, var(--ng-colors-text-tertiary-600));
|
|
417
|
+
pointer-events: none;
|
|
418
|
+
user-select: none;
|
|
401
419
|
}
|
|
402
420
|
|
|
403
421
|
/* ── AI Chat Trigger (in header) ── */
|
|
@@ -426,6 +426,30 @@ let NileChart = class NileChart extends NileElement {
|
|
|
426
426
|
await this.ensureExporting();
|
|
427
427
|
this._hcChart?.downloadCSV?.();
|
|
428
428
|
}
|
|
429
|
+
_renderMenuItem(item, hasChart) {
|
|
430
|
+
const glyph = item.glyph
|
|
431
|
+
? html `<nile-glyph class="nile-chart-menu-item-glyph" name=${item.glyph} size="16"></nile-glyph>`
|
|
432
|
+
: nothing;
|
|
433
|
+
if (item.type === 'custom') {
|
|
434
|
+
return html `
|
|
435
|
+
${item.divider ? html `<div class="nile-chart-menu-separator"></div>` : nothing}
|
|
436
|
+
<button type="button" class="nile-chart-menu-item" role="menuitem"
|
|
437
|
+
@click=${() => { this.menuOpen = false; this.emit('nile-menu-change', { id: item.id }); }}>
|
|
438
|
+
${glyph}${item.label}
|
|
439
|
+
</button>
|
|
440
|
+
`;
|
|
441
|
+
}
|
|
442
|
+
if (!hasChart)
|
|
443
|
+
return nothing;
|
|
444
|
+
return html `
|
|
445
|
+
${item.divider ? html `<div class="nile-chart-menu-separator"></div>` : nothing}
|
|
446
|
+
${item.fullscreen ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.viewFullscreen()}>${glyph}${item.label ?? 'Fullscreen'}</button>` : nothing}
|
|
447
|
+
${item.print ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.printChart()}>${glyph}${item.label ?? 'Print'}</button>` : nothing}
|
|
448
|
+
${item.downloadPng ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.exportChart('image/png')}>${glyph}${item.label ?? 'Download PNG'}</button>` : nothing}
|
|
449
|
+
${item.downloadSvg ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.exportChart('image/svg+xml')}>${glyph}${item.label ?? 'Download SVG'}</button>` : nothing}
|
|
450
|
+
${item.downloadCsv ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.downloadCsv()}>${glyph}${item.label ?? 'Download CSV'}</button>` : nothing}
|
|
451
|
+
`;
|
|
452
|
+
}
|
|
429
453
|
renderActionsMenu() {
|
|
430
454
|
if (!this.resolvedConfig)
|
|
431
455
|
return nothing;
|
|
@@ -462,25 +486,14 @@ let NileChart = class NileChart extends NileElement {
|
|
|
462
486
|
${allItems.length ? html `<div class="nile-chart-menu-separator"></div>` : nothing}
|
|
463
487
|
` : nothing}
|
|
464
488
|
${allItems.map(item => {
|
|
465
|
-
if (item.type === '
|
|
489
|
+
if (item.type === 'group') {
|
|
466
490
|
return html `
|
|
467
491
|
${item.divider ? html `<div class="nile-chart-menu-separator"></div>` : nothing}
|
|
468
|
-
<
|
|
469
|
-
|
|
470
|
-
${item.label}
|
|
471
|
-
</button>
|
|
492
|
+
<span class="nile-chart-menu-group-header" role="presentation">${item.label}</span>
|
|
493
|
+
${item.items.map(child => this._renderMenuItem(child, hasChart))}
|
|
472
494
|
`;
|
|
473
495
|
}
|
|
474
|
-
|
|
475
|
-
return nothing;
|
|
476
|
-
return html `
|
|
477
|
-
${item.divider ? html `<div class="nile-chart-menu-separator"></div>` : nothing}
|
|
478
|
-
${item.fullscreen ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.viewFullscreen()}>${item.label ?? 'Fullscreen'}</button>` : nothing}
|
|
479
|
-
${item.print ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.printChart()}>${item.label ?? 'Print'}</button>` : nothing}
|
|
480
|
-
${item.downloadPng ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.exportChart('image/png')}>${item.label ?? 'Download PNG'}</button>` : nothing}
|
|
481
|
-
${item.downloadSvg ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.exportChart('image/svg+xml')}>${item.label ?? 'Download SVG'}</button>` : nothing}
|
|
482
|
-
${item.downloadCsv ? html `<button type="button" class="nile-chart-menu-item" role="menuitem" @click=${() => this.downloadCsv()}>${item.label ?? 'Download CSV'}</button>` : nothing}
|
|
483
|
-
`;
|
|
496
|
+
return this._renderMenuItem(item, hasChart);
|
|
484
497
|
})}
|
|
485
498
|
</div>
|
|
486
499
|
` : nothing}
|
|
@@ -609,9 +609,10 @@ export const styles = css `
|
|
|
609
609
|
color: var(--nile-colors-dark-900, var(--ng-colors-text-primary-900));
|
|
610
610
|
overflow-x: auto;
|
|
611
611
|
overflow-y: hidden;
|
|
612
|
-
scrollbar-width: none;
|
|
612
|
+
scrollbar-width: none;
|
|
613
|
+
z-index: 1;
|
|
613
614
|
}
|
|
614
|
-
.fc-prompt__highlight::-webkit-scrollbar { display: none; }
|
|
615
|
+
.fc-prompt__highlight::-webkit-scrollbar { display: none; }
|
|
615
616
|
|
|
616
617
|
.fc-prompt__input {
|
|
617
618
|
position: relative;
|
|
@@ -629,46 +630,31 @@ export const styles = css `
|
|
|
629
630
|
color: transparent;
|
|
630
631
|
}
|
|
631
632
|
|
|
632
|
-
.fc-
|
|
633
|
-
background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
|
|
634
|
-
color: transparent;
|
|
635
|
-
}
|
|
636
|
-
.fc-prompt__field--highlight .fc-prompt__input::-moz-selection {
|
|
637
|
-
background: var(--nile-colors-neutral-100, var(--ng-colors-bg-secondary));
|
|
638
|
-
color: transparent;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
.fc-prompt__dropdown {
|
|
633
|
+
.fc-prompt__dd {
|
|
642
634
|
flex: 1;
|
|
643
635
|
min-width: 0;
|
|
644
636
|
display: block;
|
|
645
637
|
}
|
|
646
638
|
|
|
647
|
-
.fc-prompt__inner > .fc-
|
|
639
|
+
.fc-prompt__inner > .fc-prompt__dd {
|
|
648
640
|
display: block;
|
|
649
641
|
flex: 1;
|
|
650
642
|
min-width: 0;
|
|
651
643
|
width: 100%;
|
|
652
644
|
}
|
|
653
|
-
.fc-prompt__inner > .fc-
|
|
645
|
+
.fc-prompt__inner > .fc-prompt__dd > [slot="trigger"] {
|
|
654
646
|
width: 100%;
|
|
655
647
|
}
|
|
656
|
-
.fc-prompt__inner > .fc-
|
|
648
|
+
.fc-prompt__inner > .fc-prompt__dd::part(trigger) {
|
|
657
649
|
display: block;
|
|
658
650
|
width: 100%;
|
|
659
651
|
}
|
|
660
652
|
|
|
661
|
-
.fc-
|
|
653
|
+
.fc-prompt__dd::part(panel) {
|
|
662
654
|
display: flex;
|
|
663
655
|
flex-direction: column;
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
background: var(--nile-colors-white-base, var(--ng-colors-bg-primary));
|
|
667
|
-
border: 1px solid var(--nile-colors-neutral-400, var(--ng-colors-border-secondary));
|
|
668
|
-
border-radius: var(--nile-radius-md, var(--ng-radius-md));
|
|
669
|
-
box-shadow: 0 12px 24px -8px rgba(16, 24, 40, 0.12),
|
|
670
|
-
0 4px 8px -2px rgba(16, 24, 40, 0.06);
|
|
671
|
-
padding: var(--nile-spacing-4px, var(--ng-spacing-xs));
|
|
656
|
+
/* background: var(--nile-colors-white-base, var(--ng-colors-bg-primary)); */
|
|
657
|
+
|
|
672
658
|
}
|
|
673
659
|
|
|
674
660
|
.fc-prompt__suggestion {
|
|
@@ -677,7 +663,7 @@ export const styles = css `
|
|
|
677
663
|
justify-content: space-between;
|
|
678
664
|
gap: var(--nile-spacing-md, var(--ng-spacing-md));
|
|
679
665
|
width: 100%;
|
|
680
|
-
padding:
|
|
666
|
+
padding: 0 var(--nile-spacing-md, var(--ng-spacing-md));
|
|
681
667
|
border: 0;
|
|
682
668
|
border-radius: var(--nile-radius-radius-lg, var(--ng-radius-sm));
|
|
683
669
|
background: transparent;
|
|
@@ -701,11 +687,23 @@ export const styles = css `
|
|
|
701
687
|
}
|
|
702
688
|
|
|
703
689
|
.fc-prompt__suggestion-label {
|
|
704
|
-
|
|
690
|
+
display: block;
|
|
705
691
|
min-width: 0;
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
692
|
+
max-width: 100%;
|
|
693
|
+
white-space: nowrap;
|
|
694
|
+
overflow: hidden;
|
|
695
|
+
text-overflow: ellipsis;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/* nile-lite-tooltip renders into its own light DOM and defaults to
|
|
699
|
+
display:inline, so it gives the label no width to truncate against.
|
|
700
|
+
Make it a transparent, width-constraining block. */
|
|
701
|
+
.fc-prompt__suggestion-tooltip {
|
|
702
|
+
display: block;
|
|
703
|
+
flex: 1 1 auto;
|
|
704
|
+
min-width: 0;
|
|
705
|
+
max-width: 100%;
|
|
706
|
+
overflow: hidden;
|
|
709
707
|
}
|
|
710
708
|
|
|
711
709
|
.fc-prompt__suggestion-tag {
|
|
@@ -720,6 +718,32 @@ export const styles = css `
|
|
|
720
718
|
letter-spacing: 0.04em;
|
|
721
719
|
}
|
|
722
720
|
|
|
721
|
+
/* Label and the type badge sit in separate nile-menu-item slots, so the
|
|
722
|
+
row layout is owned by the menu-item's internal flex (::part). Stretch
|
|
723
|
+
the label slot and push the suffix slot to the right edge. */
|
|
724
|
+
.fc-prompt__suggestion::part(base) {
|
|
725
|
+
width: 100%;
|
|
726
|
+
}
|
|
727
|
+
.fc-prompt__suggestion::part(label) {
|
|
728
|
+
display: flex;
|
|
729
|
+
align-items: center;
|
|
730
|
+
flex: 1 1 auto;
|
|
731
|
+
min-width: 0;
|
|
732
|
+
overflow: hidden;
|
|
733
|
+
}
|
|
734
|
+
.fc-prompt__suggestion::part(suffix) {
|
|
735
|
+
margin-left: auto;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/* nile-menu scrolls inside its own .menu__items-wrapper, capped at
|
|
739
|
+
--auto-size-available-height. That var is unset in this non-portal
|
|
740
|
+
setup, so max-height resolves to none and the host's overflow:hidden
|
|
741
|
+
just clips the list with no scrollbar. Give the wrapper a concrete cap
|
|
742
|
+
so the suggestion list actually scrolls. */
|
|
743
|
+
.fc-prompt__menu::part(menu__items-wrapper) {
|
|
744
|
+
max-height: 280px;
|
|
745
|
+
}
|
|
746
|
+
|
|
723
747
|
.fc-prompt__input::placeholder {
|
|
724
748
|
color: var(--nile-colors-dark-500, var(--ng-colors-text-secondary-700));
|
|
725
749
|
opacity: 0.85;
|
|
@@ -52,7 +52,6 @@ export declare class NileFilterChart extends NileElement implements FilterChartH
|
|
|
52
52
|
connectedCallback(): void;
|
|
53
53
|
disconnectedCallback(): void;
|
|
54
54
|
updated(changed: Map<string, unknown>): void;
|
|
55
|
-
private _syncPortalDropdowns;
|
|
56
55
|
setValue(id: string, value: unknown): void;
|
|
57
56
|
/**
|
|
58
57
|
* Update a prompt control's value. The value lands in `selectedValues`
|
|
@@ -91,20 +91,6 @@ let NileFilterChart = NileFilterChart_1 = class NileFilterChart extends NileElem
|
|
|
91
91
|
if (cfgAppearance === 'minimal' || cfgAppearance === 'default')
|
|
92
92
|
this.appearance = cfgAppearance;
|
|
93
93
|
}
|
|
94
|
-
// Keep portaled suggestion panels in sync with the latest panel content.
|
|
95
|
-
// nile-dropdown clones the panel once at open-time and never re-clones,
|
|
96
|
-
// so without this the suggestions appear frozen at the value they had
|
|
97
|
-
// when the dropdown first opened.
|
|
98
|
-
this._syncPortalDropdowns();
|
|
99
|
-
}
|
|
100
|
-
_syncPortalDropdowns() {
|
|
101
|
-
const dropdowns = this.shadowRoot?.querySelectorAll('nile-dropdown.fc-prompt__dropdown');
|
|
102
|
-
dropdowns?.forEach((dd) => {
|
|
103
|
-
const d = dd;
|
|
104
|
-
if (d.open && d.portal && d.portalManager?.clonedPanel) {
|
|
105
|
-
d.portalManager.updatePortalPanel?.();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
94
|
}
|
|
109
95
|
// ── FilterChartHost surface ─────────────────────────────────────────────────
|
|
110
96
|
setValue(id, value) {
|
|
@@ -751,13 +751,10 @@ export function renderPrompt(host, ctrl) {
|
|
|
751
751
|
<div class="${classes} fc-prompt--row-input" part="filter-prompt" style="${inlineStyle}">
|
|
752
752
|
<div class="fc-prompt__inner">
|
|
753
753
|
<nile-dropdown
|
|
754
|
-
class="fc-
|
|
754
|
+
class="fc-prompt__dd"
|
|
755
755
|
placement="bottom-start"
|
|
756
756
|
sync="width"
|
|
757
757
|
distance="6"
|
|
758
|
-
hoist
|
|
759
|
-
portal
|
|
760
|
-
stay-open-on-select
|
|
761
758
|
?open=${dropdownOpen}
|
|
762
759
|
.noOpenOnClick=${true}
|
|
763
760
|
>
|