@angular-bootstrap/ngbootstrap 0.0.7 → 0.0.9
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.
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Input, Directive, EventEmitter, Output, ChangeDetectionStrategy, Component, inject, Injectable, TemplateRef, QueryList, ContentChildren, ContentChild, InjectionToken, signal, Optional, Inject, ElementRef, HostListener, HostBinding, ViewChild, ViewChildren } from '@angular/core';
|
|
2
|
+
import { Input, Directive, EventEmitter, Output, ChangeDetectionStrategy, Component, inject, Injectable, TemplateRef, QueryList, ContentChildren, ContentChild, InjectionToken, signal, Optional, Inject, ElementRef, HostListener, HostBinding, ViewChild, forwardRef, ViewChildren } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import * as i2 from '@angular/forms';
|
|
6
|
-
import { FormBuilder, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
6
|
+
import { FormBuilder, FormControl, Validators, FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
7
7
|
import { firstValueFrom, isObservable } from 'rxjs';
|
|
8
8
|
|
|
9
9
|
class NgbCellTemplate {
|
|
@@ -1755,365 +1755,576 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
1755
1755
|
}] } });
|
|
1756
1756
|
|
|
1757
1757
|
class NgbSplitterPaneComponent {
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1758
|
+
size = ''; // e.g., '30%' or '200px'
|
|
1759
|
+
min = '0px';
|
|
1760
|
+
max = '100%';
|
|
1761
|
+
scrollable = true;
|
|
1762
1762
|
collapsible = false;
|
|
1763
1763
|
collapsed = false;
|
|
1764
1764
|
collapsedChange = new EventEmitter();
|
|
1765
|
-
|
|
1766
|
-
const value = next ?? !this.collapsed;
|
|
1767
|
-
if (value !== this.collapsed) {
|
|
1768
|
-
this.collapsed = value;
|
|
1769
|
-
this.collapsedChange.emit(this.collapsed);
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1765
|
+
template;
|
|
1772
1766
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbSplitterPaneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1773
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgbSplitterPaneComponent, isStandalone: true, selector: "ngb-splitter-pane", inputs: { size: "size", min: "min", max: "max", collapsible: "collapsible", collapsed: "collapsed" }, outputs: { collapsedChange: "collapsedChange" }, viewQueries: [{ propertyName: "
|
|
1767
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgbSplitterPaneComponent, isStandalone: true, selector: "ngb-splitter-pane", inputs: { size: "size", min: "min", max: "max", scrollable: "scrollable", collapsible: "collapsible", collapsed: "collapsed" }, outputs: { collapsedChange: "collapsedChange" }, viewQueries: [{ propertyName: "template", first: true, predicate: ["content"], descendants: true, static: true }], ngImport: i0, template: `<ng-template #content>
|
|
1768
|
+
<div [style.overflow]="scrollable ? 'auto' : 'hidden'" style="height: 100%; width: 100%;">
|
|
1769
|
+
<ng-content></ng-content>
|
|
1770
|
+
</div>
|
|
1771
|
+
</ng-template>`, isInline: true, styles: [":host{display:block;position:relative}\n"] });
|
|
1774
1772
|
}
|
|
1775
1773
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbSplitterPaneComponent, decorators: [{
|
|
1776
1774
|
type: Component,
|
|
1777
|
-
args: [{
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
}], propDecorators: {
|
|
1783
|
-
type: ViewChild,
|
|
1784
|
-
args: ['paneTpl', { static: true }]
|
|
1785
|
-
}], size: [{
|
|
1775
|
+
args: [{ selector: 'ngb-splitter-pane', standalone: true, template: `<ng-template #content>
|
|
1776
|
+
<div [style.overflow]="scrollable ? 'auto' : 'hidden'" style="height: 100%; width: 100%;">
|
|
1777
|
+
<ng-content></ng-content>
|
|
1778
|
+
</div>
|
|
1779
|
+
</ng-template>`, styles: [":host{display:block;position:relative}\n"] }]
|
|
1780
|
+
}], propDecorators: { size: [{
|
|
1786
1781
|
type: Input
|
|
1787
1782
|
}], min: [{
|
|
1788
1783
|
type: Input
|
|
1789
1784
|
}], max: [{
|
|
1790
1785
|
type: Input
|
|
1786
|
+
}], scrollable: [{
|
|
1787
|
+
type: Input
|
|
1791
1788
|
}], collapsible: [{
|
|
1792
1789
|
type: Input
|
|
1793
1790
|
}], collapsed: [{
|
|
1794
1791
|
type: Input
|
|
1795
1792
|
}], collapsedChange: [{
|
|
1796
1793
|
type: Output
|
|
1794
|
+
}], template: [{
|
|
1795
|
+
type: ViewChild,
|
|
1796
|
+
args: ['content', { static: true }]
|
|
1797
1797
|
}] } });
|
|
1798
1798
|
|
|
1799
1799
|
class NgbSplitterComponent {
|
|
1800
|
+
el;
|
|
1800
1801
|
panes;
|
|
1801
|
-
container;
|
|
1802
1802
|
orientation = 'horizontal';
|
|
1803
1803
|
handleThickness = 12;
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1804
|
+
handleIconColor = '#000';
|
|
1805
|
+
verticalMinHeight = '280px';
|
|
1806
|
+
resizable = true; // New Resize Input
|
|
1807
|
+
barColor = '#ccc'; // Custom Bar Color
|
|
1808
|
+
lineColor = '#000'; // Custom Line Color
|
|
1809
|
+
isDragging = false;
|
|
1810
|
+
currentHandleIndex = -1;
|
|
1811
|
+
constructor(el) {
|
|
1812
|
+
this.el = el;
|
|
1813
|
+
}
|
|
1814
|
+
// Listeners for global mouse movement
|
|
1815
|
+
onMouseMove(event) {
|
|
1816
|
+
if (!this.isDragging || !this.resizable)
|
|
1817
|
+
return;
|
|
1818
|
+
this.resize(event);
|
|
1818
1819
|
}
|
|
1819
|
-
|
|
1820
|
-
this.
|
|
1820
|
+
onMouseUp() {
|
|
1821
|
+
this.isDragging = false;
|
|
1822
|
+
document.body.style.cursor = 'default';
|
|
1821
1823
|
}
|
|
1822
|
-
|
|
1824
|
+
onMouseDown(event, index) {
|
|
1825
|
+
if (!this.resizable)
|
|
1826
|
+
return;
|
|
1823
1827
|
event.preventDefault();
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
const
|
|
1832
|
-
const
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
onHandleKeydown(index, event) {
|
|
1828
|
+
this.isDragging = true;
|
|
1829
|
+
this.currentHandleIndex = index;
|
|
1830
|
+
document.body.style.cursor = this.orientation === 'horizontal' ? 'col-resize' : 'row-resize';
|
|
1831
|
+
}
|
|
1832
|
+
resize(event) {
|
|
1833
|
+
const container = this.el.nativeElement.querySelector('.splitter-container');
|
|
1834
|
+
const rect = container.getBoundingClientRect();
|
|
1835
|
+
const paneArr = this.panes.toArray();
|
|
1836
|
+
const paneWrappers = Array.from(this.el.nativeElement.querySelectorAll('.pane-wrapper'));
|
|
1837
|
+
const targetPane = paneArr[this.currentHandleIndex];
|
|
1838
|
+
if (!targetPane || !paneWrappers.length) {
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1838
1841
|
const isHorizontal = this.orientation === 'horizontal';
|
|
1839
|
-
const
|
|
1840
|
-
if (
|
|
1841
|
-
|
|
1842
|
-
event.preventDefault();
|
|
1843
|
-
const direction = event.key === 'ArrowLeft' || event.key === 'ArrowUp' ? -1 : 1;
|
|
1844
|
-
this.adjustPaneSizes(index, delta * direction);
|
|
1842
|
+
const totalPixels = isHorizontal ? rect.width : rect.height;
|
|
1843
|
+
if (totalPixels <= 0) {
|
|
1844
|
+
return;
|
|
1845
1845
|
}
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1846
|
+
const mousePos = isHorizontal ? event.clientX - rect.left : event.clientY - rect.top;
|
|
1847
|
+
let consumed = 0;
|
|
1848
|
+
for (let i = 0; i < this.currentHandleIndex; i++) {
|
|
1849
|
+
const prevPaneElement = paneWrappers[i];
|
|
1850
|
+
if (!prevPaneElement) {
|
|
1851
|
+
continue;
|
|
1852
|
+
}
|
|
1853
|
+
const prevRect = prevPaneElement.getBoundingClientRect();
|
|
1854
|
+
consumed += isHorizontal ? prevRect.width : prevRect.height;
|
|
1855
|
+
consumed += this.handleThickness;
|
|
1849
1856
|
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
const
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
target.toggleCollapsed();
|
|
1856
|
-
this.initStates();
|
|
1857
|
+
let newSizeValue = ((mousePos - consumed) / totalPixels) * 100;
|
|
1858
|
+
const minPercent = this.sizeToPercent(targetPane.min, totalPixels);
|
|
1859
|
+
const maxPercent = this.sizeToPercent(targetPane.max, totalPixels);
|
|
1860
|
+
if (minPercent !== null) {
|
|
1861
|
+
newSizeValue = Math.max(newSizeValue, minPercent);
|
|
1857
1862
|
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
if (!this.currentDrag) {
|
|
1861
|
-
return;
|
|
1863
|
+
if (maxPercent !== null) {
|
|
1864
|
+
newSizeValue = Math.min(newSizeValue, maxPercent);
|
|
1862
1865
|
}
|
|
1866
|
+
newSizeValue = Math.max(0, Math.min(100, newSizeValue));
|
|
1867
|
+
targetPane.size = `${newSizeValue}%`;
|
|
1868
|
+
}
|
|
1869
|
+
onHandleToggle(event, index) {
|
|
1870
|
+
event.stopPropagation();
|
|
1863
1871
|
event.preventDefault();
|
|
1864
|
-
|
|
1865
|
-
this.adjustPaneSizes(this.currentDrag.index, delta, this.currentDrag.startSizes);
|
|
1866
|
-
}
|
|
1867
|
-
stopDrag() {
|
|
1868
|
-
this.detachDragListeners();
|
|
1869
|
-
this.currentDrag = undefined;
|
|
1870
|
-
}
|
|
1871
|
-
adjustPaneSizes(index, delta, startSizes) {
|
|
1872
|
-
const total = this.getContainerSize();
|
|
1873
|
-
const sizes = startSizes ?? this.computePaneSizes(total);
|
|
1874
|
-
const panesArray = this.panes.toArray();
|
|
1875
|
-
const first = panesArray[index];
|
|
1876
|
-
const second = panesArray[index + 1];
|
|
1877
|
-
if (first.collapsed || second.collapsed) {
|
|
1878
|
-
return;
|
|
1879
|
-
}
|
|
1880
|
-
let firstSize = sizes[0] + delta;
|
|
1881
|
-
let secondSize = sizes[1] - delta;
|
|
1882
|
-
const firstLimits = this.getLimits(first, total);
|
|
1883
|
-
const secondLimits = this.getLimits(second, total);
|
|
1884
|
-
firstSize = this.clamp(firstSize, firstLimits.minPx, firstLimits.maxPx);
|
|
1885
|
-
secondSize = this.clamp(secondSize, secondLimits.minPx, secondLimits.maxPx);
|
|
1886
|
-
if (firstSize + secondSize > 0) {
|
|
1887
|
-
this.paneStates[index].sizePx = firstSize;
|
|
1888
|
-
this.paneStates[index + 1].sizePx = secondSize;
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
initStates() {
|
|
1892
|
-
const total = this.getContainerSize();
|
|
1893
|
-
const sizes = this.computePaneSizes(total);
|
|
1894
|
-
const panesArray = this.panes.toArray();
|
|
1895
|
-
this.paneStates = panesArray.map((pane, idx) => {
|
|
1896
|
-
const limits = this.getLimits(pane, total);
|
|
1897
|
-
return {
|
|
1898
|
-
id: `ngb-splitter-pane-${idx}`,
|
|
1899
|
-
sizePx: pane.collapsed ? 0 : sizes[idx],
|
|
1900
|
-
minPx: limits.minPx,
|
|
1901
|
-
maxPx: limits.maxPx,
|
|
1902
|
-
};
|
|
1903
|
-
});
|
|
1872
|
+
this.togglePane(index);
|
|
1904
1873
|
}
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
const autoSize = unspecified > 0 ? remaining / unspecified : 0;
|
|
1914
|
-
return resolved.map((val) => {
|
|
1915
|
-
if (val != null) {
|
|
1916
|
-
return val;
|
|
1917
|
-
}
|
|
1918
|
-
if (autoSize) {
|
|
1919
|
-
return autoSize;
|
|
1920
|
-
}
|
|
1921
|
-
return total / panesArray.length;
|
|
1922
|
-
});
|
|
1874
|
+
getCollapseIcon(pane) {
|
|
1875
|
+
if (!pane.collapsible) {
|
|
1876
|
+
return '';
|
|
1877
|
+
}
|
|
1878
|
+
if (this.orientation === 'horizontal') {
|
|
1879
|
+
return pane.collapsed ? 'bi-caret-right-fill' : 'bi-caret-left-fill';
|
|
1880
|
+
}
|
|
1881
|
+
return pane.collapsed ? 'bi-caret-down-fill' : 'bi-caret-up-fill';
|
|
1923
1882
|
}
|
|
1924
|
-
|
|
1925
|
-
if (
|
|
1926
|
-
return
|
|
1883
|
+
getPaneFlex(pane) {
|
|
1884
|
+
if (pane.collapsed) {
|
|
1885
|
+
return '0 0 0px';
|
|
1886
|
+
}
|
|
1887
|
+
if (pane.size) {
|
|
1888
|
+
return `0 0 ${pane.size}`;
|
|
1889
|
+
}
|
|
1890
|
+
return '1 1 0px';
|
|
1891
|
+
}
|
|
1892
|
+
sizeToPercent(value, totalPixels) {
|
|
1893
|
+
if (!value) {
|
|
1894
|
+
return null;
|
|
1895
|
+
}
|
|
1927
1896
|
const trimmed = value.trim();
|
|
1897
|
+
if (!trimmed) {
|
|
1898
|
+
return null;
|
|
1899
|
+
}
|
|
1928
1900
|
if (trimmed.endsWith('%')) {
|
|
1929
|
-
const
|
|
1930
|
-
return (
|
|
1901
|
+
const percent = parseFloat(trimmed);
|
|
1902
|
+
return Number.isFinite(percent) ? percent : null;
|
|
1903
|
+
}
|
|
1904
|
+
const numeric = parseFloat(trimmed);
|
|
1905
|
+
if (!Number.isFinite(numeric)) {
|
|
1906
|
+
return null;
|
|
1931
1907
|
}
|
|
1932
1908
|
if (trimmed.endsWith('px')) {
|
|
1933
|
-
return
|
|
1909
|
+
return totalPixels > 0 ? (numeric / totalPixels) * 100 : null;
|
|
1910
|
+
}
|
|
1911
|
+
return numeric;
|
|
1912
|
+
}
|
|
1913
|
+
togglePane(index) {
|
|
1914
|
+
const pane = this.panes.toArray()[index];
|
|
1915
|
+
pane.collapsed = !pane.collapsed;
|
|
1916
|
+
pane.collapsedChange.emit(pane.collapsed);
|
|
1917
|
+
}
|
|
1918
|
+
getSeparatorAriaOrientation() {
|
|
1919
|
+
// For left/right panes, the separator is vertical. For top/bottom panes, it is horizontal.
|
|
1920
|
+
return this.orientation === 'horizontal' ? 'vertical' : 'horizontal';
|
|
1921
|
+
}
|
|
1922
|
+
getHandleValueNow(index) {
|
|
1923
|
+
const container = this.el.nativeElement.querySelector('.splitter-container');
|
|
1924
|
+
const rect = container.getBoundingClientRect();
|
|
1925
|
+
const paneWrappers = Array.from(this.el.nativeElement.querySelectorAll('.pane-wrapper'));
|
|
1926
|
+
const target = paneWrappers[index];
|
|
1927
|
+
const totalPixels = this.orientation === 'horizontal' ? rect.width : rect.height;
|
|
1928
|
+
if (!target || totalPixels <= 0) {
|
|
1929
|
+
return null;
|
|
1934
1930
|
}
|
|
1935
|
-
const
|
|
1936
|
-
|
|
1931
|
+
const paneRect = target.getBoundingClientRect();
|
|
1932
|
+
const panePixels = this.orientation === 'horizontal' ? paneRect.width : paneRect.height;
|
|
1933
|
+
return Math.round((panePixels / totalPixels) * 100);
|
|
1937
1934
|
}
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1935
|
+
getHandleValueMin(index) {
|
|
1936
|
+
const pane = this.panes?.toArray?.()[index];
|
|
1937
|
+
const container = this.el.nativeElement.querySelector('.splitter-container');
|
|
1938
|
+
const rect = container.getBoundingClientRect();
|
|
1939
|
+
const totalPixels = this.orientation === 'horizontal' ? rect.width : rect.height;
|
|
1940
|
+
if (!pane || totalPixels <= 0) {
|
|
1941
|
+
return null;
|
|
1942
|
+
}
|
|
1943
|
+
return this.sizeToPercent(pane.min, totalPixels);
|
|
1944
|
+
}
|
|
1945
|
+
getHandleValueMax(index) {
|
|
1946
|
+
const pane = this.panes?.toArray?.()[index];
|
|
1947
|
+
const container = this.el.nativeElement.querySelector('.splitter-container');
|
|
1948
|
+
const rect = container.getBoundingClientRect();
|
|
1949
|
+
const totalPixels = this.orientation === 'horizontal' ? rect.width : rect.height;
|
|
1950
|
+
if (!pane || totalPixels <= 0) {
|
|
1951
|
+
return null;
|
|
1952
|
+
}
|
|
1953
|
+
return this.sizeToPercent(pane.max, totalPixels);
|
|
1943
1954
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
}
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1955
|
+
onHandleKeyDown(event, index) {
|
|
1956
|
+
if (event.key === 'Enter') {
|
|
1957
|
+
const pane = this.panes.toArray()[index];
|
|
1958
|
+
if (pane?.collapsible) {
|
|
1959
|
+
event.preventDefault();
|
|
1960
|
+
this.togglePane(index);
|
|
1961
|
+
}
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1964
|
+
const isHorizontal = this.orientation === 'horizontal';
|
|
1965
|
+
const negativeKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp';
|
|
1966
|
+
const positiveKey = isHorizontal ? 'ArrowRight' : 'ArrowDown';
|
|
1967
|
+
if (event.key !== negativeKey && event.key !== positiveKey) {
|
|
1968
|
+
return;
|
|
1969
|
+
}
|
|
1970
|
+
if (!this.resizable) {
|
|
1971
|
+
return;
|
|
1972
|
+
}
|
|
1973
|
+
event.preventDefault();
|
|
1974
|
+
const delta = (event.shiftKey ? 5 : 2) * (event.key === positiveKey ? 1 : -1);
|
|
1975
|
+
this.resizeByPercent(index, delta);
|
|
1976
|
+
}
|
|
1977
|
+
resizeByPercent(index, deltaPercent) {
|
|
1978
|
+
const container = this.el.nativeElement.querySelector('.splitter-container');
|
|
1979
|
+
const rect = container.getBoundingClientRect();
|
|
1980
|
+
const paneArr = this.panes.toArray();
|
|
1981
|
+
const paneWrappers = Array.from(this.el.nativeElement.querySelectorAll('.pane-wrapper'));
|
|
1982
|
+
const targetPane = paneArr[index];
|
|
1983
|
+
const targetWrapper = paneWrappers[index];
|
|
1984
|
+
if (!targetPane || !targetWrapper) {
|
|
1985
|
+
return;
|
|
1986
|
+
}
|
|
1987
|
+
const totalPixels = this.orientation === 'horizontal' ? rect.width : rect.height;
|
|
1988
|
+
if (totalPixels <= 0) {
|
|
1989
|
+
return;
|
|
1990
|
+
}
|
|
1991
|
+
const wrapperRect = targetWrapper.getBoundingClientRect();
|
|
1992
|
+
const currentPixels = this.orientation === 'horizontal' ? wrapperRect.width : wrapperRect.height;
|
|
1993
|
+
let nextPercent = (currentPixels / totalPixels) * 100 + deltaPercent;
|
|
1994
|
+
const minPercent = this.sizeToPercent(targetPane.min, totalPixels);
|
|
1995
|
+
const maxPercent = this.sizeToPercent(targetPane.max, totalPixels);
|
|
1996
|
+
if (minPercent !== null) {
|
|
1997
|
+
nextPercent = Math.max(nextPercent, minPercent);
|
|
1998
|
+
}
|
|
1999
|
+
if (maxPercent !== null) {
|
|
2000
|
+
nextPercent = Math.min(nextPercent, maxPercent);
|
|
2001
|
+
}
|
|
2002
|
+
nextPercent = Math.max(0, Math.min(100, nextPercent));
|
|
2003
|
+
targetPane.size = `${nextPercent}%`;
|
|
2004
|
+
}
|
|
2005
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbSplitterComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2006
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgbSplitterComponent, isStandalone: true, selector: "ngb-splitter", inputs: { orientation: "orientation", handleThickness: "handleThickness", handleIconColor: "handleIconColor", verticalMinHeight: "verticalMinHeight", resizable: "resizable", barColor: "barColor", lineColor: "lineColor" }, host: { listeners: { "window:mousemove": "onMouseMove($event)", "window:mouseup": "onMouseUp()" } }, queries: [{ propertyName: "panes", predicate: NgbSplitterPaneComponent }], ngImport: i0, template: `
|
|
2007
|
+
<div class="splitter-container" [class.vertical]="orientation === 'vertical'"
|
|
2008
|
+
[style.min-height]="orientation === 'vertical' ? verticalMinHeight : null"
|
|
2009
|
+
[style.height]="orientation === 'vertical' ? verticalMinHeight : null">
|
|
2010
|
+
<!-- Iterate through the QueryList of panes -->
|
|
2011
|
+
<ng-container *ngFor="let pane of panes; let i = index">
|
|
2012
|
+
<div class="pane-wrapper" [style.flex]="getPaneFlex(pane)"
|
|
2013
|
+
[style.min-width]="orientation === 'horizontal' ? (pane.min || '0px') : null"
|
|
2014
|
+
[style.max-width]="orientation === 'horizontal' ? pane.max : null"
|
|
2015
|
+
[style.min-height]="orientation === 'vertical' ? (pane.min || '0px') : null"
|
|
2016
|
+
[style.max-height]="orientation === 'vertical' ? pane.max : null"
|
|
1985
2017
|
>
|
|
1986
|
-
|
|
2018
|
+
<!-- Access the 'template' property we defined in the Pane component -->
|
|
2019
|
+
<ng-container [ngTemplateOutlet]="pane.template"></ng-container>
|
|
1987
2020
|
</div>
|
|
1988
2021
|
|
|
1989
|
-
<
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2022
|
+
<div *ngIf="i < panes.length - 1" class="splitbar"
|
|
2023
|
+
[class.resizable]="resizable"
|
|
2024
|
+
[style.background-color]="barColor"
|
|
2025
|
+
[style.width.px]="orientation === 'horizontal' ? handleThickness : '100%'"
|
|
2026
|
+
[style.height.px]="orientation === 'vertical' ? handleThickness : '100%'"
|
|
2027
|
+
role="separator"
|
|
2028
|
+
tabindex="0"
|
|
2029
|
+
[attr.aria-orientation]="getSeparatorAriaOrientation()"
|
|
2030
|
+
[attr.aria-valuenow]="getHandleValueNow(i)"
|
|
2031
|
+
[attr.aria-valuemin]="getHandleValueMin(i)"
|
|
2032
|
+
[attr.aria-valuemax]="getHandleValueMax(i)"
|
|
2033
|
+
(keydown)="onHandleKeyDown($event, i)"
|
|
2034
|
+
(mousedown)="onMouseDown($event, i)">
|
|
2035
|
+
<div class="handle-line" [style.background-color]="lineColor">
|
|
2036
|
+
<span
|
|
2037
|
+
*ngIf="pane.collapsible"
|
|
2038
|
+
class="collapse-arrow bi"
|
|
2039
|
+
[ngClass]="getCollapseIcon(pane)"
|
|
2040
|
+
[style.color]="handleIconColor"
|
|
2041
|
+
(click)="onHandleToggle($event, i)"
|
|
2042
|
+
aria-hidden="true"
|
|
2043
|
+
></span>
|
|
2044
|
+
</div>
|
|
2045
|
+
</div>
|
|
2008
2046
|
</ng-container>
|
|
2009
2047
|
</div>
|
|
2010
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2048
|
+
`, isInline: true, styles: [":host{display:block;width:100%}.splitter-container{display:flex;height:100%;width:100%}.splitter-container.vertical{flex-direction:column}.splitbar{background:#ccc;width:5px;position:relative;align-items:center;justify-content:center;flex:0 0 auto;z-index:10}.splitbar.resizable{cursor:col-resize}.splitbar:hover{filter:brightness(90%)}.handle-line{border-radius:2px;opacity:.8;left:45%;position:absolute;top:45%;display:flex;align-items:center;justify-content:center}.splitter-container:not(.vertical) .handle-line{width:2px;height:10px}.pane-wrapper{position:relative;min-width:0;min-height:0;overflow:hidden;flex-shrink:1}.vertical .handle-line{height:2px;width:10px}.vertical .splitbar.resizable{cursor:row-resize}.splitter-container.vertical .splitter-container .splitbar.resizable{cursor:col-resize}.vertical .splitbar{width:100%}.collapse-btn{cursor:pointer;background:#666;width:10px;height:10px;position:absolute;top:50%}.collapse-arrow{font-size:.95rem;-webkit-user-select:none;user-select:none;cursor:pointer;line-height:1;display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;position:absolute;top:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2011
2049
|
}
|
|
2012
2050
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbSplitterComponent, decorators: [{
|
|
2013
2051
|
type: Component,
|
|
2014
|
-
args: [{
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
role="group"
|
|
2026
|
-
>
|
|
2027
|
-
<ng-container *ngFor="let pane of panes.toArray(); let i = index">
|
|
2028
|
-
<div
|
|
2029
|
-
class="d-flex flex-column overflow-auto"
|
|
2030
|
-
[attr.data-pane-id]="paneStates[i]?.id"
|
|
2031
|
-
[class.d-none]="pane.collapsed"
|
|
2032
|
-
[style.flex-basis.px]="paneStates[i]?.sizePx"
|
|
2033
|
-
[style.min-width.px]="orientation === 'horizontal' ? paneStates[i]?.minPx : undefined"
|
|
2034
|
-
[style.max-width.px]="orientation === 'horizontal' ? paneStates[i]?.maxPx : undefined"
|
|
2035
|
-
[style.min-height.px]="orientation === 'vertical' ? paneStates[i]?.minPx : undefined"
|
|
2036
|
-
[style.max-height.px]="orientation === 'vertical' ? paneStates[i]?.maxPx : undefined"
|
|
2052
|
+
args: [{ selector: 'ngb-splitter', standalone: true, imports: [CommonModule, NgbSplitterPaneComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
2053
|
+
<div class="splitter-container" [class.vertical]="orientation === 'vertical'"
|
|
2054
|
+
[style.min-height]="orientation === 'vertical' ? verticalMinHeight : null"
|
|
2055
|
+
[style.height]="orientation === 'vertical' ? verticalMinHeight : null">
|
|
2056
|
+
<!-- Iterate through the QueryList of panes -->
|
|
2057
|
+
<ng-container *ngFor="let pane of panes; let i = index">
|
|
2058
|
+
<div class="pane-wrapper" [style.flex]="getPaneFlex(pane)"
|
|
2059
|
+
[style.min-width]="orientation === 'horizontal' ? (pane.min || '0px') : null"
|
|
2060
|
+
[style.max-width]="orientation === 'horizontal' ? pane.max : null"
|
|
2061
|
+
[style.min-height]="orientation === 'vertical' ? (pane.min || '0px') : null"
|
|
2062
|
+
[style.max-height]="orientation === 'vertical' ? pane.max : null"
|
|
2037
2063
|
>
|
|
2038
|
-
|
|
2064
|
+
<!-- Access the 'template' property we defined in the Pane component -->
|
|
2065
|
+
<ng-container [ngTemplateOutlet]="pane.template"></ng-container>
|
|
2039
2066
|
</div>
|
|
2040
2067
|
|
|
2041
|
-
<
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2068
|
+
<div *ngIf="i < panes.length - 1" class="splitbar"
|
|
2069
|
+
[class.resizable]="resizable"
|
|
2070
|
+
[style.background-color]="barColor"
|
|
2071
|
+
[style.width.px]="orientation === 'horizontal' ? handleThickness : '100%'"
|
|
2072
|
+
[style.height.px]="orientation === 'vertical' ? handleThickness : '100%'"
|
|
2073
|
+
role="separator"
|
|
2074
|
+
tabindex="0"
|
|
2075
|
+
[attr.aria-orientation]="getSeparatorAriaOrientation()"
|
|
2076
|
+
[attr.aria-valuenow]="getHandleValueNow(i)"
|
|
2077
|
+
[attr.aria-valuemin]="getHandleValueMin(i)"
|
|
2078
|
+
[attr.aria-valuemax]="getHandleValueMax(i)"
|
|
2079
|
+
(keydown)="onHandleKeyDown($event, i)"
|
|
2080
|
+
(mousedown)="onMouseDown($event, i)">
|
|
2081
|
+
<div class="handle-line" [style.background-color]="lineColor">
|
|
2082
|
+
<span
|
|
2083
|
+
*ngIf="pane.collapsible"
|
|
2084
|
+
class="collapse-arrow bi"
|
|
2085
|
+
[ngClass]="getCollapseIcon(pane)"
|
|
2086
|
+
[style.color]="handleIconColor"
|
|
2087
|
+
(click)="onHandleToggle($event, i)"
|
|
2088
|
+
aria-hidden="true"
|
|
2089
|
+
></span>
|
|
2090
|
+
</div>
|
|
2091
|
+
</div>
|
|
2060
2092
|
</ng-container>
|
|
2061
2093
|
</div>
|
|
2062
|
-
`,
|
|
2063
|
-
|
|
2064
|
-
}], propDecorators: { panes: [{
|
|
2094
|
+
`, styles: [":host{display:block;width:100%}.splitter-container{display:flex;height:100%;width:100%}.splitter-container.vertical{flex-direction:column}.splitbar{background:#ccc;width:5px;position:relative;align-items:center;justify-content:center;flex:0 0 auto;z-index:10}.splitbar.resizable{cursor:col-resize}.splitbar:hover{filter:brightness(90%)}.handle-line{border-radius:2px;opacity:.8;left:45%;position:absolute;top:45%;display:flex;align-items:center;justify-content:center}.splitter-container:not(.vertical) .handle-line{width:2px;height:10px}.pane-wrapper{position:relative;min-width:0;min-height:0;overflow:hidden;flex-shrink:1}.vertical .handle-line{height:2px;width:10px}.vertical .splitbar.resizable{cursor:row-resize}.splitter-container.vertical .splitter-container .splitbar.resizable{cursor:col-resize}.vertical .splitbar{width:100%}.collapse-btn{cursor:pointer;background:#666;width:10px;height:10px;position:absolute;top:50%}.collapse-arrow{font-size:.95rem;-webkit-user-select:none;user-select:none;cursor:pointer;line-height:1;display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;position:absolute;top:100%}\n"] }]
|
|
2095
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { panes: [{
|
|
2065
2096
|
type: ContentChildren,
|
|
2066
2097
|
args: [NgbSplitterPaneComponent]
|
|
2067
|
-
}], container: [{
|
|
2068
|
-
type: ViewChild,
|
|
2069
|
-
args: ['container', { static: true }]
|
|
2070
2098
|
}], orientation: [{
|
|
2071
2099
|
type: Input
|
|
2072
2100
|
}], handleThickness: [{
|
|
2073
2101
|
type: Input
|
|
2074
|
-
}],
|
|
2102
|
+
}], handleIconColor: [{
|
|
2103
|
+
type: Input
|
|
2104
|
+
}], verticalMinHeight: [{
|
|
2105
|
+
type: Input
|
|
2106
|
+
}], resizable: [{
|
|
2107
|
+
type: Input
|
|
2108
|
+
}], barColor: [{
|
|
2109
|
+
type: Input
|
|
2110
|
+
}], lineColor: [{
|
|
2111
|
+
type: Input
|
|
2112
|
+
}], onMouseMove: [{
|
|
2113
|
+
type: HostListener,
|
|
2114
|
+
args: ['window:mousemove', ['$event']]
|
|
2115
|
+
}], onMouseUp: [{
|
|
2075
2116
|
type: HostListener,
|
|
2076
|
-
args: ['window:
|
|
2117
|
+
args: ['window:mouseup']
|
|
2118
|
+
}] } });
|
|
2119
|
+
|
|
2120
|
+
class NgbChipsComponent {
|
|
2121
|
+
items = [];
|
|
2122
|
+
removable = true;
|
|
2123
|
+
ariaLabel;
|
|
2124
|
+
removeLabel;
|
|
2125
|
+
remove = new EventEmitter();
|
|
2126
|
+
trackById = (_, item) => item.id;
|
|
2127
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2128
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgbChipsComponent, isStandalone: true, selector: "ngb-chips", inputs: { items: "items", removable: "removable", ariaLabel: "ariaLabel", removeLabel: "removeLabel" }, outputs: { remove: "remove" }, ngImport: i0, template: `
|
|
2129
|
+
<div class="ngb-chips" [attr.aria-label]="ariaLabel">
|
|
2130
|
+
<span
|
|
2131
|
+
*ngFor="let item of items; trackBy: trackById"
|
|
2132
|
+
class="badge rounded-pill bg-secondary ngb-chip"
|
|
2133
|
+
[class.opacity-50]="!!item.disabled"
|
|
2134
|
+
>
|
|
2135
|
+
<span class="ngb-chip-label">{{ item.label }}</span>
|
|
2136
|
+
<button
|
|
2137
|
+
*ngIf="removable"
|
|
2138
|
+
type="button"
|
|
2139
|
+
class="ngb-chip-remove"
|
|
2140
|
+
[disabled]="!!item.disabled"
|
|
2141
|
+
(click)="remove.emit(item)"
|
|
2142
|
+
[attr.aria-label]="removeLabel || 'Remove'"
|
|
2143
|
+
>
|
|
2144
|
+
×
|
|
2145
|
+
</button>
|
|
2146
|
+
</span>
|
|
2147
|
+
</div>
|
|
2148
|
+
`, isInline: true, styles: [":host{display:block}.ngb-chips{display:flex;flex-wrap:wrap;gap:.35rem;align-items:center}.ngb-chip{display:inline-flex;align-items:center;gap:.25rem;max-width:100%}.ngb-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ngb-chip-remove{border:0;background:transparent;padding:0;line-height:1;cursor:pointer;font-size:1rem;opacity:.85}.ngb-chip-remove:disabled{cursor:default;opacity:.4}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2149
|
+
}
|
|
2150
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbChipsComponent, decorators: [{
|
|
2151
|
+
type: Component,
|
|
2152
|
+
args: [{ selector: 'ngb-chips', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
2153
|
+
<div class="ngb-chips" [attr.aria-label]="ariaLabel">
|
|
2154
|
+
<span
|
|
2155
|
+
*ngFor="let item of items; trackBy: trackById"
|
|
2156
|
+
class="badge rounded-pill bg-secondary ngb-chip"
|
|
2157
|
+
[class.opacity-50]="!!item.disabled"
|
|
2158
|
+
>
|
|
2159
|
+
<span class="ngb-chip-label">{{ item.label }}</span>
|
|
2160
|
+
<button
|
|
2161
|
+
*ngIf="removable"
|
|
2162
|
+
type="button"
|
|
2163
|
+
class="ngb-chip-remove"
|
|
2164
|
+
[disabled]="!!item.disabled"
|
|
2165
|
+
(click)="remove.emit(item)"
|
|
2166
|
+
[attr.aria-label]="removeLabel || 'Remove'"
|
|
2167
|
+
>
|
|
2168
|
+
×
|
|
2169
|
+
</button>
|
|
2170
|
+
</span>
|
|
2171
|
+
</div>
|
|
2172
|
+
`, styles: [":host{display:block}.ngb-chips{display:flex;flex-wrap:wrap;gap:.35rem;align-items:center}.ngb-chip{display:inline-flex;align-items:center;gap:.25rem;max-width:100%}.ngb-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ngb-chip-remove{border:0;background:transparent;padding:0;line-height:1;cursor:pointer;font-size:1rem;opacity:.85}.ngb-chip-remove:disabled{cursor:default;opacity:.4}\n"] }]
|
|
2173
|
+
}], propDecorators: { items: [{
|
|
2174
|
+
type: Input
|
|
2175
|
+
}], removable: [{
|
|
2176
|
+
type: Input
|
|
2177
|
+
}], ariaLabel: [{
|
|
2178
|
+
type: Input
|
|
2179
|
+
}], removeLabel: [{
|
|
2180
|
+
type: Input
|
|
2181
|
+
}], remove: [{
|
|
2182
|
+
type: Output
|
|
2077
2183
|
}] } });
|
|
2078
2184
|
|
|
2079
2185
|
class NgbTypeaheadComponent {
|
|
2186
|
+
host;
|
|
2187
|
+
cdr;
|
|
2080
2188
|
data = [];
|
|
2081
2189
|
debounceTime = 200;
|
|
2082
2190
|
characterTyped = 1;
|
|
2083
2191
|
limit = 10;
|
|
2084
2192
|
selectExact = false;
|
|
2085
2193
|
multiSelect = false;
|
|
2086
|
-
|
|
2194
|
+
matchSelection = false;
|
|
2195
|
+
showDropdownButton = false;
|
|
2196
|
+
showClearButton = false;
|
|
2197
|
+
updateOnBlur = false;
|
|
2198
|
+
updateOnTab = true;
|
|
2199
|
+
separator = ',';
|
|
2200
|
+
chips = false;
|
|
2201
|
+
vScroll = false;
|
|
2202
|
+
vItemSize = 40;
|
|
2203
|
+
// `TemplateRef` types can become non-assignable in monorepo setups with multiple Angular installations.
|
|
2204
|
+
// Using `any` keeps the API flexible while still supporting Angular templates at runtime.
|
|
2087
2205
|
itemTemplate;
|
|
2206
|
+
i18n;
|
|
2207
|
+
projectedItemTemplate;
|
|
2208
|
+
completeMethod = new EventEmitter();
|
|
2209
|
+
onSelect = new EventEmitter();
|
|
2210
|
+
onUnselect = new EventEmitter();
|
|
2211
|
+
onAdd = new EventEmitter();
|
|
2212
|
+
onFocus = new EventEmitter();
|
|
2213
|
+
onBlur = new EventEmitter();
|
|
2214
|
+
onDropdownClick = new EventEmitter();
|
|
2215
|
+
onClear = new EventEmitter();
|
|
2216
|
+
onInputKeydown = new EventEmitter();
|
|
2217
|
+
onKeyUp = new EventEmitter();
|
|
2218
|
+
onShow = new EventEmitter();
|
|
2219
|
+
onHide = new EventEmitter();
|
|
2220
|
+
onLazyLoad = new EventEmitter();
|
|
2088
2221
|
selectedItems = new EventEmitter();
|
|
2089
2222
|
selectionChange = new EventEmitter();
|
|
2090
2223
|
onChange = new EventEmitter();
|
|
2091
|
-
onScrollEvent = new EventEmitter();
|
|
2224
|
+
onScrollEvent = new EventEmitter(); // legacy, kept for compatibility
|
|
2092
2225
|
scroller;
|
|
2093
2226
|
inputEl;
|
|
2094
2227
|
itemButtons;
|
|
2228
|
+
disabled = false;
|
|
2095
2229
|
query = '';
|
|
2096
2230
|
filtered = [];
|
|
2097
2231
|
visible = [];
|
|
2098
2232
|
selected = [];
|
|
2233
|
+
overlayVisible = false;
|
|
2234
|
+
openedByDropdown = false;
|
|
2235
|
+
hasSearched = false;
|
|
2236
|
+
activeIndex = -1;
|
|
2237
|
+
inputFocused = false;
|
|
2238
|
+
pointerDownInside = false;
|
|
2239
|
+
lastFilterTerm = '';
|
|
2240
|
+
keepOpenOnEmpty = false;
|
|
2241
|
+
overlayId = `ngb-typeahead-overlay-${Math.random().toString(36).slice(2)}`;
|
|
2099
2242
|
viewportHeight = 240;
|
|
2100
2243
|
itemHeight = 40;
|
|
2101
2244
|
beforePadding = 0;
|
|
2102
2245
|
afterPadding = 0;
|
|
2246
|
+
viewportStartIndex = 0;
|
|
2103
2247
|
debounceId;
|
|
2248
|
+
onControlChange = () => { };
|
|
2249
|
+
onControlTouched = () => { };
|
|
2250
|
+
controlValue = null;
|
|
2104
2251
|
ngAfterViewInit() {
|
|
2252
|
+
// do not open overlay on init; just ensure viewport state is consistent
|
|
2105
2253
|
this.applyFilter('');
|
|
2106
2254
|
}
|
|
2107
2255
|
ngOnChanges(changes) {
|
|
2256
|
+
if (changes['vScroll'] || changes['vItemSize']) {
|
|
2257
|
+
const nextSize = Number(this.vItemSize);
|
|
2258
|
+
this.itemHeight = Number.isFinite(nextSize) && nextSize > 0 ? nextSize : 40;
|
|
2259
|
+
this.updateViewport(this.scroller?.nativeElement.scrollTop || 0);
|
|
2260
|
+
}
|
|
2108
2261
|
if (changes['data'] && !changes['data'].firstChange) {
|
|
2109
2262
|
this.applyFilter(this.query);
|
|
2110
2263
|
}
|
|
2264
|
+
if (changes['data'] && this.controlValue != null && !this.inputFocused && !this.overlayVisible) {
|
|
2265
|
+
this.applyControlValue(this.controlValue);
|
|
2266
|
+
}
|
|
2111
2267
|
}
|
|
2112
2268
|
ngOnDestroy() {
|
|
2113
2269
|
if (this.debounceId) {
|
|
2114
2270
|
clearTimeout(this.debounceId);
|
|
2115
2271
|
}
|
|
2116
2272
|
}
|
|
2273
|
+
constructor(host, cdr) {
|
|
2274
|
+
this.host = host;
|
|
2275
|
+
this.cdr = cdr;
|
|
2276
|
+
}
|
|
2277
|
+
onDocumentMouseDown(event) {
|
|
2278
|
+
const target = event.target;
|
|
2279
|
+
if (!target)
|
|
2280
|
+
return;
|
|
2281
|
+
const inside = this.host.nativeElement.contains(target);
|
|
2282
|
+
this.pointerDownInside = inside;
|
|
2283
|
+
if (inside)
|
|
2284
|
+
return;
|
|
2285
|
+
if (!this.overlayVisible)
|
|
2286
|
+
return;
|
|
2287
|
+
this.commitInputOnClose();
|
|
2288
|
+
this.hideOverlay(event);
|
|
2289
|
+
}
|
|
2290
|
+
onDocumentFocusIn(event) {
|
|
2291
|
+
if (!this.overlayVisible)
|
|
2292
|
+
return;
|
|
2293
|
+
const target = event.target;
|
|
2294
|
+
if (!target)
|
|
2295
|
+
return;
|
|
2296
|
+
if (this.host.nativeElement.contains(target))
|
|
2297
|
+
return;
|
|
2298
|
+
this.commitInputOnClose();
|
|
2299
|
+
this.hideOverlay(event);
|
|
2300
|
+
}
|
|
2301
|
+
get activeDescendantId() {
|
|
2302
|
+
if (!this.overlayVisible)
|
|
2303
|
+
return null;
|
|
2304
|
+
if (this.activeIndex < 0 || this.activeIndex >= this.visible.length)
|
|
2305
|
+
return null;
|
|
2306
|
+
return this.getOptionId(this.activeIndex);
|
|
2307
|
+
}
|
|
2308
|
+
get showNoResults() {
|
|
2309
|
+
return this.overlayVisible && this.hasSearched && this.filtered.length === 0;
|
|
2310
|
+
}
|
|
2311
|
+
get displayQuery() {
|
|
2312
|
+
if (!this.multiSelect) {
|
|
2313
|
+
return this.query;
|
|
2314
|
+
}
|
|
2315
|
+
if (this.chips) {
|
|
2316
|
+
return this.query;
|
|
2317
|
+
}
|
|
2318
|
+
const term = (this.query || '').trim();
|
|
2319
|
+
const prefix = this.selected.map((s) => s.label).join(', ');
|
|
2320
|
+
if (!prefix) {
|
|
2321
|
+
return this.query;
|
|
2322
|
+
}
|
|
2323
|
+
if (term) {
|
|
2324
|
+
return `${prefix}, ${term}`;
|
|
2325
|
+
}
|
|
2326
|
+
return prefix;
|
|
2327
|
+
}
|
|
2117
2328
|
get selectionSummary() {
|
|
2118
2329
|
if (!this.selected.length)
|
|
2119
2330
|
return '';
|
|
@@ -2123,28 +2334,201 @@ class NgbTypeaheadComponent {
|
|
|
2123
2334
|
const firstTwo = this.selected.slice(0, 2).map((s) => s.label).join(', ');
|
|
2124
2335
|
return `${firstTwo} (+${this.selected.length - 2})`;
|
|
2125
2336
|
}
|
|
2337
|
+
get resolvedItemTemplate() {
|
|
2338
|
+
return this.itemTemplate ?? this.projectedItemTemplate;
|
|
2339
|
+
}
|
|
2340
|
+
writeValue(value) {
|
|
2341
|
+
this.controlValue = value;
|
|
2342
|
+
this.applyControlValue(value);
|
|
2343
|
+
}
|
|
2344
|
+
applyControlValue(value) {
|
|
2345
|
+
if (this.multiSelect) {
|
|
2346
|
+
const asArray = Array.isArray(value) ? value : value == null ? [] : [value];
|
|
2347
|
+
const next = asArray.map((v) => this.coerceToItem(v)).filter(Boolean);
|
|
2348
|
+
const seen = new Set();
|
|
2349
|
+
this.selected = next.filter((i) => (seen.has(i.id) ? false : (seen.add(i.id), true)));
|
|
2350
|
+
this.query = '';
|
|
2351
|
+
this.keepOpenOnEmpty = false;
|
|
2352
|
+
this.applyFilter('');
|
|
2353
|
+
this.cdr.markForCheck();
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
if (value == null) {
|
|
2357
|
+
this.selected = [];
|
|
2358
|
+
this.query = '';
|
|
2359
|
+
this.keepOpenOnEmpty = false;
|
|
2360
|
+
this.applyFilter('');
|
|
2361
|
+
this.cdr.markForCheck();
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
const item = this.coerceToItem(value);
|
|
2365
|
+
if (!item)
|
|
2366
|
+
return;
|
|
2367
|
+
this.selected = [item];
|
|
2368
|
+
this.query = item.label;
|
|
2369
|
+
if (this.inputEl?.nativeElement) {
|
|
2370
|
+
this.inputEl.nativeElement.value = item.label;
|
|
2371
|
+
}
|
|
2372
|
+
this.keepOpenOnEmpty = false;
|
|
2373
|
+
this.applyFilter(this.query);
|
|
2374
|
+
this.cdr.markForCheck();
|
|
2375
|
+
}
|
|
2376
|
+
registerOnChange(fn) {
|
|
2377
|
+
this.onControlChange = fn;
|
|
2378
|
+
}
|
|
2379
|
+
registerOnTouched(fn) {
|
|
2380
|
+
this.onControlTouched = fn;
|
|
2381
|
+
}
|
|
2382
|
+
setDisabledState(isDisabled) {
|
|
2383
|
+
this.disabled = isDisabled;
|
|
2384
|
+
if (isDisabled) {
|
|
2385
|
+
this.hideOverlay();
|
|
2386
|
+
}
|
|
2387
|
+
this.cdr.markForCheck();
|
|
2388
|
+
}
|
|
2126
2389
|
onInput(value) {
|
|
2127
|
-
this.
|
|
2390
|
+
if (this.disabled)
|
|
2391
|
+
return;
|
|
2392
|
+
this.keepOpenOnEmpty = false;
|
|
2393
|
+
const trimmed = (value ?? '').trim();
|
|
2394
|
+
if (!this.multiSelect && this.selected.length) {
|
|
2395
|
+
const selectedLabel = (this.selected[0]?.label ?? '').trim();
|
|
2396
|
+
if (trimmed.toLowerCase() !== selectedLabel.toLowerCase()) {
|
|
2397
|
+
const previous = this.selected[0];
|
|
2398
|
+
this.selected = [];
|
|
2399
|
+
this.selectedItems.emit(this.selected);
|
|
2400
|
+
this.selectionChange.emit(this.selected);
|
|
2401
|
+
if (previous) {
|
|
2402
|
+
this.onUnselect.emit(previous);
|
|
2403
|
+
}
|
|
2404
|
+
this.propagateControlValue();
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
if (this.chips && this.multiSelect) {
|
|
2408
|
+
const tokens = this.splitBySeparators(value);
|
|
2409
|
+
if (tokens.tokensToAdd.length) {
|
|
2410
|
+
for (const token of tokens.tokensToAdd) {
|
|
2411
|
+
this.addToken(token);
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
this.query = tokens.remaining;
|
|
2415
|
+
}
|
|
2416
|
+
else {
|
|
2417
|
+
this.query = value;
|
|
2418
|
+
}
|
|
2128
2419
|
this.onChange.emit(value);
|
|
2420
|
+
// Input events imply the user is interacting with the field; treat as focused so the overlay can open immediately.
|
|
2421
|
+
this.inputFocused = true;
|
|
2129
2422
|
if (this.debounceId)
|
|
2130
2423
|
clearTimeout(this.debounceId);
|
|
2131
2424
|
if (this.debounceTime <= 0) {
|
|
2132
2425
|
this.applyFilter(value);
|
|
2426
|
+
this.completeMethod.emit(value);
|
|
2133
2427
|
}
|
|
2134
2428
|
else {
|
|
2135
|
-
this.debounceId = setTimeout(() =>
|
|
2429
|
+
this.debounceId = setTimeout(() => {
|
|
2430
|
+
this.applyFilter(value);
|
|
2431
|
+
this.completeMethod.emit(value);
|
|
2432
|
+
this.cdr.markForCheck();
|
|
2433
|
+
}, this.debounceTime);
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
onNativeInput(event) {
|
|
2437
|
+
const target = event.target;
|
|
2438
|
+
const value = target?.value ?? '';
|
|
2439
|
+
if (this.multiSelect && !this.chips && this.selected.length) {
|
|
2440
|
+
const prefix = this.selected.map((s) => s.label).join(', ');
|
|
2441
|
+
const normalizedPrefix = prefix.trim();
|
|
2442
|
+
if (normalizedPrefix && value.toLowerCase().startsWith(normalizedPrefix.toLowerCase())) {
|
|
2443
|
+
let rest = value.slice(normalizedPrefix.length);
|
|
2444
|
+
rest = rest.replace(/^[\s,]+/, '');
|
|
2445
|
+
this.onInput(rest);
|
|
2446
|
+
return;
|
|
2447
|
+
}
|
|
2136
2448
|
}
|
|
2449
|
+
this.onInput(value);
|
|
2137
2450
|
}
|
|
2138
2451
|
onKeydown(event) {
|
|
2452
|
+
if (this.disabled)
|
|
2453
|
+
return;
|
|
2454
|
+
this.onInputKeydown.emit(event);
|
|
2455
|
+
if (this.chips && this.multiSelect && event.key === 'Tab' && this.updateOnTab) {
|
|
2456
|
+
event.preventDefault();
|
|
2457
|
+
this.addToken((this.query || '').trim());
|
|
2458
|
+
this.focusInput();
|
|
2459
|
+
return;
|
|
2460
|
+
}
|
|
2461
|
+
if (event.key === 'Tab' && this.overlayVisible) {
|
|
2462
|
+
const active = this.visible[this.activeIndex];
|
|
2463
|
+
if (active) {
|
|
2464
|
+
this.selectItem(active);
|
|
2465
|
+
this.hideOverlay(event);
|
|
2466
|
+
}
|
|
2467
|
+
return;
|
|
2468
|
+
}
|
|
2139
2469
|
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
2140
2470
|
event.preventDefault();
|
|
2141
|
-
this.
|
|
2471
|
+
this.moveActive(event.key === 'ArrowDown' ? 1 : -1);
|
|
2472
|
+
}
|
|
2473
|
+
else if (event.key === 'Home') {
|
|
2474
|
+
if (this.overlayVisible) {
|
|
2475
|
+
event.preventDefault();
|
|
2476
|
+
this.setActiveGlobalIndex(0);
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
else if (event.key === 'End') {
|
|
2480
|
+
if (this.overlayVisible) {
|
|
2481
|
+
event.preventDefault();
|
|
2482
|
+
this.setActiveGlobalIndex(this.filtered.length - 1);
|
|
2483
|
+
}
|
|
2142
2484
|
}
|
|
2143
2485
|
else if (event.key === 'Enter') {
|
|
2144
2486
|
event.preventDefault();
|
|
2145
|
-
const
|
|
2146
|
-
if (
|
|
2147
|
-
this.selectItem(
|
|
2487
|
+
const active = this.visible[this.activeIndex] || this.visible[0];
|
|
2488
|
+
if (active) {
|
|
2489
|
+
this.selectItem(active);
|
|
2490
|
+
this.hideOverlay(event);
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
else if (event.key === 'Escape') {
|
|
2494
|
+
if (this.overlayVisible) {
|
|
2495
|
+
event.preventDefault();
|
|
2496
|
+
this.hideOverlay(event);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
onKeyup(event) {
|
|
2501
|
+
this.onKeyUp.emit(event);
|
|
2502
|
+
}
|
|
2503
|
+
onInputFocus(event) {
|
|
2504
|
+
if (this.disabled)
|
|
2505
|
+
return;
|
|
2506
|
+
this.onFocus.emit(event);
|
|
2507
|
+
this.inputFocused = true;
|
|
2508
|
+
if (this.multiSelect && !this.overlayVisible) {
|
|
2509
|
+
// When multi-select is displaying the selection summary, start searching with a clean query.
|
|
2510
|
+
this.query = '';
|
|
2511
|
+
// After a multi-select session, re-opening the field should show the list again even with an empty query.
|
|
2512
|
+
if (!this.chips && this.selected.length) {
|
|
2513
|
+
this.keepOpenOnEmpty = true;
|
|
2514
|
+
this.applyFilter('');
|
|
2515
|
+
this.activatePreferredOption();
|
|
2516
|
+
return;
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
// Opening behavior: only show overlay when threshold met, or dropdown button explicitly used.
|
|
2520
|
+
if (this.query.length >= this.characterTyped) {
|
|
2521
|
+
this.showOverlay(event);
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
onInputBlur(event) {
|
|
2525
|
+
this.onBlur.emit(event);
|
|
2526
|
+
this.onControlTouched();
|
|
2527
|
+
this.inputFocused = false;
|
|
2528
|
+
// Do not close on blur directly: scrolling/clicking within the overlay can blur the input.
|
|
2529
|
+
// Closing/commit is handled by outside click (document:mousedown) and focus moving outside (document:focusin).
|
|
2530
|
+
if (this.chips && this.multiSelect && this.updateOnBlur) {
|
|
2531
|
+
this.addToken((this.query || '').trim());
|
|
2148
2532
|
}
|
|
2149
2533
|
}
|
|
2150
2534
|
onScroll(event) {
|
|
@@ -2152,8 +2536,14 @@ class NgbTypeaheadComponent {
|
|
|
2152
2536
|
const scrollTop = target.scrollTop;
|
|
2153
2537
|
this.onScrollEvent.emit();
|
|
2154
2538
|
this.updateViewport(scrollTop);
|
|
2539
|
+
const remaining = target.scrollHeight - (target.scrollTop + target.clientHeight);
|
|
2540
|
+
if (remaining < 48) {
|
|
2541
|
+
this.onLazyLoad.emit();
|
|
2542
|
+
}
|
|
2155
2543
|
}
|
|
2156
2544
|
selectItem(item) {
|
|
2545
|
+
if (this.disabled)
|
|
2546
|
+
return;
|
|
2157
2547
|
if (!item || item.disabled)
|
|
2158
2548
|
return;
|
|
2159
2549
|
this.validateItem(item);
|
|
@@ -2161,29 +2551,118 @@ class NgbTypeaheadComponent {
|
|
|
2161
2551
|
const exists = this.selected.find((s) => s.id === item.id);
|
|
2162
2552
|
if (exists) {
|
|
2163
2553
|
this.selected = this.selected.filter((s) => s.id !== item.id);
|
|
2554
|
+
this.onUnselect.emit(item);
|
|
2164
2555
|
}
|
|
2165
2556
|
else {
|
|
2166
2557
|
this.selected = [...this.selected, item];
|
|
2558
|
+
this.onSelect.emit(item);
|
|
2167
2559
|
}
|
|
2560
|
+
this.propagateControlValue();
|
|
2561
|
+
// After selecting/unselecting, show the chosen values in the input and keep the panel open.
|
|
2562
|
+
this.keepOpenOnEmpty = true;
|
|
2563
|
+
if (this.chips) {
|
|
2564
|
+
this.query = '';
|
|
2565
|
+
}
|
|
2566
|
+
else {
|
|
2567
|
+
this.query = '';
|
|
2568
|
+
}
|
|
2569
|
+
this.applyFilter('');
|
|
2168
2570
|
}
|
|
2169
2571
|
else {
|
|
2572
|
+
if (this.selected.length && this.selected[0]?.id !== item.id) {
|
|
2573
|
+
this.onUnselect.emit(this.selected[0]);
|
|
2574
|
+
}
|
|
2170
2575
|
this.selected = [item];
|
|
2576
|
+
this.query = item.label;
|
|
2577
|
+
if (this.inputEl?.nativeElement) {
|
|
2578
|
+
this.inputEl.nativeElement.value = item.label;
|
|
2579
|
+
}
|
|
2580
|
+
this.onSelect.emit(item);
|
|
2581
|
+
this.propagateControlValue();
|
|
2582
|
+
this.hideOverlay();
|
|
2171
2583
|
}
|
|
2172
2584
|
this.selectedItems.emit(this.selected);
|
|
2173
2585
|
this.selectionChange.emit(this.selected);
|
|
2586
|
+
this.cdr.markForCheck();
|
|
2587
|
+
}
|
|
2588
|
+
focusInput() {
|
|
2589
|
+
this.inputEl?.nativeElement?.focus();
|
|
2590
|
+
}
|
|
2591
|
+
removeSelected(item) {
|
|
2592
|
+
if (this.disabled)
|
|
2593
|
+
return;
|
|
2594
|
+
if (!item)
|
|
2595
|
+
return;
|
|
2596
|
+
const exists = this.selected.find((s) => s.id === item.id);
|
|
2597
|
+
if (!exists)
|
|
2598
|
+
return;
|
|
2599
|
+
this.selected = this.selected.filter((s) => s.id !== item.id);
|
|
2600
|
+
this.onUnselect.emit(item);
|
|
2601
|
+
this.propagateControlValue();
|
|
2602
|
+
this.selectedItems.emit(this.selected);
|
|
2603
|
+
this.selectionChange.emit(this.selected);
|
|
2604
|
+
this.cdr.markForCheck();
|
|
2174
2605
|
}
|
|
2175
2606
|
clearSelection() {
|
|
2607
|
+
const previous = [...this.selected];
|
|
2176
2608
|
this.selected = [];
|
|
2177
2609
|
this.selectedItems.emit(this.selected);
|
|
2178
2610
|
this.selectionChange.emit(this.selected);
|
|
2611
|
+
if (!this.multiSelect && previous[0]) {
|
|
2612
|
+
this.onUnselect.emit(previous[0]);
|
|
2613
|
+
}
|
|
2614
|
+
this.propagateControlValue();
|
|
2615
|
+
this.cdr.markForCheck();
|
|
2179
2616
|
}
|
|
2180
2617
|
isSelected(item) {
|
|
2181
2618
|
return this.selected.some((s) => s.id === item.id);
|
|
2182
2619
|
}
|
|
2183
2620
|
trackById = (_, item) => item.id;
|
|
2621
|
+
getOptionId(index) {
|
|
2622
|
+
return `${this.overlayId}-opt-${index}`;
|
|
2623
|
+
}
|
|
2624
|
+
onDropdownButtonClick(event) {
|
|
2625
|
+
if (this.disabled)
|
|
2626
|
+
return;
|
|
2627
|
+
this.onDropdownClick.emit(event);
|
|
2628
|
+
if (this.overlayVisible) {
|
|
2629
|
+
this.hideOverlay(event);
|
|
2630
|
+
this.openedByDropdown = false;
|
|
2631
|
+
}
|
|
2632
|
+
else {
|
|
2633
|
+
this.openedByDropdown = true;
|
|
2634
|
+
if (this.scroller?.nativeElement) {
|
|
2635
|
+
this.scroller.nativeElement.scrollTop = 0;
|
|
2636
|
+
}
|
|
2637
|
+
this.showOverlay(event, true);
|
|
2638
|
+
// Show all items when the dropdown button is used, regardless of current query.
|
|
2639
|
+
this.applyFilter('');
|
|
2640
|
+
this.activatePreferredOption();
|
|
2641
|
+
}
|
|
2642
|
+
this.inputEl?.nativeElement.focus();
|
|
2643
|
+
this.cdr.markForCheck();
|
|
2644
|
+
}
|
|
2645
|
+
onClearClick(event) {
|
|
2646
|
+
if (this.disabled)
|
|
2647
|
+
return;
|
|
2648
|
+
this.onClear.emit(event);
|
|
2649
|
+
this.query = '';
|
|
2650
|
+
this.clearSelection();
|
|
2651
|
+
this.applyFilter('');
|
|
2652
|
+
this.hideOverlay(event);
|
|
2653
|
+
this.inputEl?.nativeElement.focus();
|
|
2654
|
+
this.cdr.markForCheck();
|
|
2655
|
+
}
|
|
2184
2656
|
applyFilter(value) {
|
|
2185
2657
|
const term = (value || '').toLowerCase();
|
|
2186
|
-
|
|
2658
|
+
if (term !== this.lastFilterTerm) {
|
|
2659
|
+
this.lastFilterTerm = term;
|
|
2660
|
+
if (this.scroller?.nativeElement) {
|
|
2661
|
+
this.scroller.nativeElement.scrollTop = 0;
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
const meetsThreshold = term.length >= this.characterTyped || this.openedByDropdown || (this.multiSelect && this.keepOpenOnEmpty);
|
|
2665
|
+
this.hasSearched = term.length >= this.characterTyped || this.openedByDropdown;
|
|
2187
2666
|
const base = meetsThreshold ? this.data.filter((d) => (d.label || '').toLowerCase().includes(term)) : [];
|
|
2188
2667
|
const limited = this.limit ? base.slice(0, this.limit) : base;
|
|
2189
2668
|
this.filtered = limited;
|
|
@@ -2191,8 +2670,23 @@ class NgbTypeaheadComponent {
|
|
|
2191
2670
|
this.selectItem(limited[0]);
|
|
2192
2671
|
}
|
|
2193
2672
|
this.updateViewport(this.scroller?.nativeElement.scrollTop || 0);
|
|
2673
|
+
if (meetsThreshold && !this.overlayVisible && (this.inputFocused || this.openedByDropdown)) {
|
|
2674
|
+
this.showOverlay();
|
|
2675
|
+
}
|
|
2676
|
+
if (!meetsThreshold && this.overlayVisible && !this.openedByDropdown) {
|
|
2677
|
+
this.hideOverlay();
|
|
2678
|
+
}
|
|
2679
|
+
this.cdr.markForCheck();
|
|
2194
2680
|
}
|
|
2195
2681
|
updateViewport(scrollTop) {
|
|
2682
|
+
if (!this.vScroll) {
|
|
2683
|
+
this.beforePadding = 0;
|
|
2684
|
+
this.afterPadding = 0;
|
|
2685
|
+
this.visible = this.filtered;
|
|
2686
|
+
this.viewportStartIndex = 0;
|
|
2687
|
+
this.activeIndex = this.visible.length ? Math.min(this.activeIndex, this.visible.length - 1) : -1;
|
|
2688
|
+
return;
|
|
2689
|
+
}
|
|
2196
2690
|
const total = this.filtered.length;
|
|
2197
2691
|
const visibleCount = Math.ceil(this.viewportHeight / this.itemHeight) + 2;
|
|
2198
2692
|
const start = Math.max(Math.floor(scrollTop / this.itemHeight), 0);
|
|
@@ -2200,140 +2694,489 @@ class NgbTypeaheadComponent {
|
|
|
2200
2694
|
this.beforePadding = start * this.itemHeight;
|
|
2201
2695
|
this.afterPadding = Math.max(total - end, 0) * this.itemHeight;
|
|
2202
2696
|
this.visible = this.filtered.slice(start, end);
|
|
2697
|
+
this.viewportStartIndex = start;
|
|
2698
|
+
this.activeIndex = this.visible.length ? Math.min(this.activeIndex, this.visible.length - 1) : -1;
|
|
2203
2699
|
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2700
|
+
activatePreferredOption() {
|
|
2701
|
+
if (!this.filtered.length || !this.scroller?.nativeElement) {
|
|
2702
|
+
this.activeIndex = -1;
|
|
2207
2703
|
return;
|
|
2208
|
-
|
|
2209
|
-
const
|
|
2210
|
-
|
|
2211
|
-
|
|
2704
|
+
}
|
|
2705
|
+
const trimmed = (this.query || '').trim().toLowerCase();
|
|
2706
|
+
let preferredIndex = -1;
|
|
2707
|
+
if (trimmed) {
|
|
2708
|
+
preferredIndex = this.filtered.findIndex((d) => (d.label || '').trim().toLowerCase() === trimmed);
|
|
2709
|
+
}
|
|
2710
|
+
if (preferredIndex === -1 && this.selected.length) {
|
|
2711
|
+
const firstSelected = this.selected[0];
|
|
2712
|
+
preferredIndex = this.filtered.findIndex((d) => d.id === firstSelected.id);
|
|
2713
|
+
}
|
|
2714
|
+
if (preferredIndex === -1) {
|
|
2715
|
+
preferredIndex = 0;
|
|
2716
|
+
}
|
|
2717
|
+
const scrollTop = Math.max(0, preferredIndex * this.itemHeight - this.itemHeight);
|
|
2718
|
+
this.scroller.nativeElement.scrollTop = scrollTop;
|
|
2719
|
+
this.updateViewport(scrollTop);
|
|
2720
|
+
const start = Math.max(Math.floor(scrollTop / this.itemHeight), 0);
|
|
2721
|
+
this.activeIndex = Math.max(0, Math.min(preferredIndex - start, this.visible.length - 1));
|
|
2722
|
+
}
|
|
2723
|
+
moveActive(direction) {
|
|
2724
|
+
if (!this.overlayVisible) {
|
|
2725
|
+
this.showOverlay();
|
|
2726
|
+
}
|
|
2727
|
+
if (!this.filtered.length)
|
|
2728
|
+
return;
|
|
2729
|
+
const currentGlobal = this.activeGlobalIndex();
|
|
2730
|
+
const total = this.filtered.length;
|
|
2731
|
+
const nextGlobal = currentGlobal < 0 ? 0 : (currentGlobal + direction + total) % total;
|
|
2732
|
+
this.setActiveGlobalIndex(nextGlobal);
|
|
2733
|
+
}
|
|
2734
|
+
activeGlobalIndex() {
|
|
2735
|
+
if (this.activeIndex < 0)
|
|
2736
|
+
return -1;
|
|
2737
|
+
return this.viewportStartIndex + this.activeIndex;
|
|
2738
|
+
}
|
|
2739
|
+
setActiveGlobalIndex(globalIndex) {
|
|
2740
|
+
if (!this.filtered.length) {
|
|
2741
|
+
this.activeIndex = -1;
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
const clamped = Math.max(0, Math.min(globalIndex, this.filtered.length - 1));
|
|
2745
|
+
const scroller = this.scroller?.nativeElement;
|
|
2746
|
+
if (!scroller) {
|
|
2747
|
+
this.activeIndex = 0;
|
|
2748
|
+
return;
|
|
2749
|
+
}
|
|
2750
|
+
const itemTop = clamped * this.itemHeight;
|
|
2751
|
+
const itemBottom = itemTop + this.itemHeight;
|
|
2752
|
+
const viewTop = scroller.scrollTop;
|
|
2753
|
+
const viewBottom = viewTop + (scroller.clientHeight || this.viewportHeight);
|
|
2754
|
+
let nextScrollTop = viewTop;
|
|
2755
|
+
if (itemTop < viewTop) {
|
|
2756
|
+
nextScrollTop = itemTop;
|
|
2757
|
+
}
|
|
2758
|
+
else if (itemBottom > viewBottom) {
|
|
2759
|
+
nextScrollTop = Math.max(0, itemBottom - (scroller.clientHeight || this.viewportHeight));
|
|
2760
|
+
}
|
|
2761
|
+
if (nextScrollTop !== viewTop) {
|
|
2762
|
+
scroller.scrollTop = nextScrollTop;
|
|
2763
|
+
}
|
|
2764
|
+
this.updateViewport(scroller.scrollTop);
|
|
2765
|
+
this.activeIndex = Math.max(0, Math.min(clamped - this.viewportStartIndex, this.visible.length - 1));
|
|
2766
|
+
this.cdr.markForCheck();
|
|
2212
2767
|
}
|
|
2213
2768
|
validateItem(item) {
|
|
2214
|
-
if (
|
|
2215
|
-
|
|
2216
|
-
|
|
2769
|
+
if (item.id == null) {
|
|
2770
|
+
throw new Error('Typeahead items must include an id.');
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
showOverlay(event, openedByDropdown = false) {
|
|
2774
|
+
this.openedByDropdown = openedByDropdown;
|
|
2775
|
+
if (this.overlayVisible)
|
|
2776
|
+
return;
|
|
2777
|
+
this.overlayVisible = true;
|
|
2778
|
+
this.activeIndex = this.visible.length ? 0 : -1;
|
|
2779
|
+
this.onShow.emit(event ?? new Event('show'));
|
|
2780
|
+
this.cdr.markForCheck();
|
|
2781
|
+
}
|
|
2782
|
+
hideOverlay(event) {
|
|
2783
|
+
if (!this.overlayVisible)
|
|
2784
|
+
return;
|
|
2785
|
+
this.overlayVisible = false;
|
|
2786
|
+
this.openedByDropdown = false;
|
|
2787
|
+
this.activeIndex = -1;
|
|
2788
|
+
this.onHide.emit(event ?? new Event('hide'));
|
|
2789
|
+
this.cdr.markForCheck();
|
|
2790
|
+
}
|
|
2791
|
+
commitInputOnClose() {
|
|
2792
|
+
const trimmed = (this.query || '').trim();
|
|
2793
|
+
if (!trimmed) {
|
|
2794
|
+
return;
|
|
2795
|
+
}
|
|
2796
|
+
if (this.matchSelection) {
|
|
2797
|
+
const exact = this.data.find((d) => (d.label || '').toLowerCase() === trimmed.toLowerCase());
|
|
2798
|
+
if (!exact) {
|
|
2799
|
+
this.query = '';
|
|
2800
|
+
if (!this.multiSelect) {
|
|
2801
|
+
this.clearSelection();
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
else if (!this.multiSelect) {
|
|
2805
|
+
this.selected = [exact];
|
|
2806
|
+
this.selectionChange.emit(this.selected);
|
|
2807
|
+
this.selectedItems.emit(this.selected);
|
|
2808
|
+
this.propagateControlValue();
|
|
2217
2809
|
}
|
|
2810
|
+
return;
|
|
2811
|
+
}
|
|
2812
|
+
if (this.updateOnBlur && !this.multiSelect && this.selected.length === 0) {
|
|
2813
|
+
const added = { id: trimmed, label: trimmed, value: trimmed };
|
|
2814
|
+
this.selected = [added];
|
|
2815
|
+
this.onAdd.emit(added);
|
|
2816
|
+
this.selectionChange.emit(this.selected);
|
|
2817
|
+
this.selectedItems.emit(this.selected);
|
|
2818
|
+
this.propagateControlValue();
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
splitBySeparators(value) {
|
|
2822
|
+
const separators = Array.isArray(this.separator) ? this.separator : [this.separator];
|
|
2823
|
+
const safe = separators.filter((s) => s != null && `${s}`.length > 0).map((s) => `${s}`.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
2824
|
+
if (!safe.length) {
|
|
2825
|
+
return { tokensToAdd: [], remaining: value };
|
|
2826
|
+
}
|
|
2827
|
+
const regex = new RegExp(`(?:${safe.join('|')})`);
|
|
2828
|
+
if (!regex.test(value)) {
|
|
2829
|
+
return { tokensToAdd: [], remaining: value };
|
|
2830
|
+
}
|
|
2831
|
+
const parts = value.split(new RegExp(`(?:${safe.join('|')})`, 'g')).map((p) => p.trim());
|
|
2832
|
+
const endsWithSeparator = separators.some((sep) => value.endsWith(sep));
|
|
2833
|
+
const tokensToAdd = (endsWithSeparator ? parts : parts.slice(0, -1)).filter(Boolean);
|
|
2834
|
+
const remaining = endsWithSeparator ? '' : (parts[parts.length - 1] || '');
|
|
2835
|
+
return { tokensToAdd, remaining };
|
|
2836
|
+
}
|
|
2837
|
+
addToken(raw) {
|
|
2838
|
+
const token = (raw || '').trim();
|
|
2839
|
+
if (!this.chips || !this.multiSelect)
|
|
2840
|
+
return;
|
|
2841
|
+
if (!token)
|
|
2842
|
+
return;
|
|
2843
|
+
const match = this.data.find((d) => (d.label || '').trim().toLowerCase() === token.toLowerCase());
|
|
2844
|
+
const item = match ?? { id: token, label: token, value: token };
|
|
2845
|
+
if (this.matchSelection && !match) {
|
|
2846
|
+
this.query = '';
|
|
2847
|
+
return;
|
|
2848
|
+
}
|
|
2849
|
+
if (this.selected.some((s) => s.id === item.id)) {
|
|
2850
|
+
this.query = '';
|
|
2851
|
+
return;
|
|
2218
2852
|
}
|
|
2853
|
+
this.selected = [...this.selected, item];
|
|
2854
|
+
this.onAdd.emit(item);
|
|
2855
|
+
this.propagateControlValue();
|
|
2856
|
+
this.selectedItems.emit(this.selected);
|
|
2857
|
+
this.selectionChange.emit(this.selected);
|
|
2858
|
+
this.query = '';
|
|
2859
|
+
this.keepOpenOnEmpty = true;
|
|
2860
|
+
this.applyFilter('');
|
|
2219
2861
|
}
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
(
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2862
|
+
propagateControlValue() {
|
|
2863
|
+
if (this.multiSelect) {
|
|
2864
|
+
const next = this.selected.map((item) => (item.value !== undefined ? item.value : item));
|
|
2865
|
+
this.controlValue = next;
|
|
2866
|
+
this.onControlChange(next);
|
|
2867
|
+
return;
|
|
2868
|
+
}
|
|
2869
|
+
const first = this.selected[0];
|
|
2870
|
+
const next = first ? (first.value !== undefined ? first.value : first) : null;
|
|
2871
|
+
this.controlValue = next;
|
|
2872
|
+
this.onControlChange(next);
|
|
2873
|
+
}
|
|
2874
|
+
coerceToItem(value) {
|
|
2875
|
+
if (value == null)
|
|
2876
|
+
return null;
|
|
2877
|
+
if (typeof value === 'object' && value.id != null && value.label != null) {
|
|
2878
|
+
return value;
|
|
2879
|
+
}
|
|
2880
|
+
const match = this.data.find((d) => d.value === value || d.id === value || (d.label || '').toLowerCase() === `${value}`.toLowerCase());
|
|
2881
|
+
if (match)
|
|
2882
|
+
return match;
|
|
2883
|
+
return { id: `${value}`, label: `${value}`, value };
|
|
2884
|
+
}
|
|
2885
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbTypeaheadComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
2886
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgbTypeaheadComponent, isStandalone: true, selector: "ngb-typeahead", inputs: { data: "data", debounceTime: "debounceTime", characterTyped: "characterTyped", limit: "limit", selectExact: "selectExact", multiSelect: "multiSelect", matchSelection: "matchSelection", showDropdownButton: "showDropdownButton", showClearButton: "showClearButton", updateOnBlur: "updateOnBlur", updateOnTab: "updateOnTab", separator: "separator", chips: "chips", vScroll: "vScroll", vItemSize: "vItemSize", itemTemplate: "itemTemplate", i18n: "i18n" }, outputs: { completeMethod: "completeMethod", onSelect: "onSelect", onUnselect: "onUnselect", onAdd: "onAdd", onFocus: "onFocus", onBlur: "onBlur", onDropdownClick: "onDropdownClick", onClear: "onClear", onInputKeydown: "onInputKeydown", onKeyUp: "onKeyUp", onShow: "onShow", onHide: "onHide", onLazyLoad: "onLazyLoad", selectedItems: "selectedItems", selectionChange: "selectionChange", onChange: "onChange", onScrollEvent: "onScrollEvent" }, host: { listeners: { "document:mousedown": "onDocumentMouseDown($event)", "document:focusin": "onDocumentFocusIn($event)" } }, providers: [
|
|
2887
|
+
{
|
|
2888
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2889
|
+
useExisting: forwardRef(() => NgbTypeaheadComponent),
|
|
2890
|
+
multi: true,
|
|
2891
|
+
},
|
|
2892
|
+
], queries: [{ propertyName: "projectedItemTemplate", first: true, predicate: TemplateRef, descendants: true }], viewQueries: [{ propertyName: "scroller", first: true, predicate: ["scroller"], descendants: true, static: true }, { propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true }, { propertyName: "itemButtons", predicate: ["itemButton"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
2893
|
+
<div class="typeahead-root">
|
|
2894
|
+
<div class="input-group mb-2">
|
|
2895
|
+
<ng-container *ngIf="chips && multiSelect; else plainInput">
|
|
2896
|
+
<div class="form-control typeahead-chips-control" (click)="disabled ? null : focusInput()">
|
|
2897
|
+
<ngb-chips
|
|
2898
|
+
[items]="selected"
|
|
2899
|
+
[removable]="true"
|
|
2900
|
+
(remove)="removeSelected($event)"
|
|
2901
|
+
ariaLabel="Selected items"
|
|
2902
|
+
></ngb-chips>
|
|
2903
|
+
<input
|
|
2904
|
+
#inputEl
|
|
2905
|
+
type="text"
|
|
2906
|
+
[disabled]="disabled"
|
|
2907
|
+
[attr.placeholder]="selected.length ? '' : (i18n?.placeholder || 'Type to search')"
|
|
2908
|
+
[value]="query"
|
|
2909
|
+
(input)="onNativeInput($event)"
|
|
2910
|
+
(focus)="onInputFocus($event)"
|
|
2911
|
+
(blur)="onInputBlur($event)"
|
|
2912
|
+
(keydown)="onKeydown($event)"
|
|
2913
|
+
(keyup)="onKeyup($event)"
|
|
2914
|
+
aria-autocomplete="list"
|
|
2915
|
+
role="combobox"
|
|
2916
|
+
[attr.aria-expanded]="overlayVisible"
|
|
2917
|
+
[attr.aria-controls]="overlayId"
|
|
2918
|
+
[attr.aria-activedescendant]="activeDescendantId"
|
|
2919
|
+
/>
|
|
2920
|
+
</div>
|
|
2921
|
+
</ng-container>
|
|
2922
|
+
<ng-template #plainInput>
|
|
2923
|
+
<input
|
|
2924
|
+
#inputEl
|
|
2925
|
+
type="text"
|
|
2926
|
+
class="form-control"
|
|
2927
|
+
[disabled]="disabled"
|
|
2928
|
+
[attr.placeholder]="i18n?.placeholder || 'Type to search'"
|
|
2929
|
+
[value]="displayQuery"
|
|
2930
|
+
(input)="onNativeInput($event)"
|
|
2931
|
+
(focus)="onInputFocus($event)"
|
|
2932
|
+
(blur)="onInputBlur($event)"
|
|
2933
|
+
(keydown)="onKeydown($event)"
|
|
2934
|
+
(keyup)="onKeyup($event)"
|
|
2935
|
+
aria-autocomplete="list"
|
|
2936
|
+
role="combobox"
|
|
2937
|
+
[attr.aria-expanded]="overlayVisible"
|
|
2938
|
+
[attr.aria-controls]="overlayId"
|
|
2939
|
+
[attr.aria-activedescendant]="activeDescendantId"
|
|
2940
|
+
/>
|
|
2941
|
+
</ng-template>
|
|
2942
|
+
|
|
2943
|
+
<button
|
|
2944
|
+
*ngIf="showClearButton && (query || (!multiSelect && selected.length))"
|
|
2945
|
+
type="button"
|
|
2946
|
+
class="btn btn-outline-secondary"
|
|
2947
|
+
(click)="onClearClick($event)"
|
|
2948
|
+
[disabled]="disabled"
|
|
2949
|
+
[attr.aria-label]="i18n?.clear || 'Clear'"
|
|
2950
|
+
>
|
|
2951
|
+
×
|
|
2952
|
+
</button>
|
|
2953
|
+
|
|
2954
|
+
<button
|
|
2955
|
+
*ngIf="showDropdownButton"
|
|
2956
|
+
type="button"
|
|
2957
|
+
class="btn btn-outline-secondary"
|
|
2958
|
+
(click)="onDropdownButtonClick($event)"
|
|
2959
|
+
[disabled]="disabled"
|
|
2960
|
+
[attr.aria-label]="i18n?.dropdownButtonLabel || 'Toggle suggestions'"
|
|
2961
|
+
>
|
|
2962
|
+
▾
|
|
2963
|
+
</button>
|
|
2964
|
+
</div>
|
|
2236
2965
|
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
<div [style.height.px]="beforePadding"></div>
|
|
2245
|
-
<button
|
|
2246
|
-
*ngFor="let item of visible; trackBy: trackById"
|
|
2247
|
-
type="button"
|
|
2248
|
-
class="list-group-item list-group-item-action d-flex align-items-center justify-content-between"
|
|
2249
|
-
[class.active]="isSelected(item)"
|
|
2250
|
-
[attr.aria-selected]="isSelected(item)"
|
|
2251
|
-
(click)="selectItem(item)"
|
|
2252
|
-
[disabled]="item.disabled"
|
|
2966
|
+
<div
|
|
2967
|
+
#scroller
|
|
2968
|
+
class="dropdown-menu w-100 p-0 typeahead-panel"
|
|
2969
|
+
[class.show]="overlayVisible"
|
|
2970
|
+
[id]="overlayId"
|
|
2971
|
+
role="listbox"
|
|
2972
|
+
(scroll)="onScroll($event)"
|
|
2253
2973
|
>
|
|
2254
|
-
<
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2974
|
+
<div *ngIf="vScroll" [style.height.px]="beforePadding"></div>
|
|
2975
|
+
|
|
2976
|
+
<button
|
|
2977
|
+
*ngFor="let item of visible; trackBy: trackById; let idx = index"
|
|
2978
|
+
type="button"
|
|
2979
|
+
class="dropdown-item"
|
|
2980
|
+
[class.active]="idx === activeIndex"
|
|
2981
|
+
[class.fw-semibold]="isSelected(item)"
|
|
2982
|
+
[attr.aria-selected]="isSelected(item)"
|
|
2983
|
+
[attr.id]="getOptionId(idx)"
|
|
2984
|
+
(click)="selectItem(item)"
|
|
2985
|
+
[disabled]="item.disabled"
|
|
2986
|
+
>
|
|
2987
|
+
<div class="typeahead-item">
|
|
2988
|
+
<span *ngIf="multiSelect" class="typeahead-item-checkbox">
|
|
2989
|
+
<input
|
|
2990
|
+
type="checkbox"
|
|
2991
|
+
class="form-check-input m-0"
|
|
2992
|
+
[checked]="isSelected(item)"
|
|
2993
|
+
[disabled]="item.disabled"
|
|
2994
|
+
tabindex="-1"
|
|
2995
|
+
aria-hidden="true"
|
|
2996
|
+
/>
|
|
2997
|
+
</span>
|
|
2998
|
+
<ng-container *ngIf="resolvedItemTemplate as tpl; else defaultTpl">
|
|
2999
|
+
<ng-container
|
|
3000
|
+
[ngTemplateOutlet]="tpl"
|
|
3001
|
+
[ngTemplateOutletContext]="{
|
|
3002
|
+
$implicit: item,
|
|
3003
|
+
item: item,
|
|
3004
|
+
query: query,
|
|
3005
|
+
selected: isSelected(item),
|
|
3006
|
+
index: idx
|
|
3007
|
+
}"
|
|
3008
|
+
></ng-container>
|
|
3009
|
+
</ng-container>
|
|
3010
|
+
<ng-template #defaultTpl>
|
|
3011
|
+
<span>{{ item.label }}</span>
|
|
3012
|
+
</ng-template>
|
|
3013
|
+
</div>
|
|
3014
|
+
</button>
|
|
2261
3015
|
|
|
2262
|
-
|
|
2263
|
-
|
|
3016
|
+
<div *ngIf="vScroll" [style.height.px]="afterPadding"></div>
|
|
3017
|
+
|
|
3018
|
+
<div *ngIf="showNoResults" class="dropdown-item text-muted text-center">
|
|
3019
|
+
{{ i18n?.noResults || 'No results' }}
|
|
3020
|
+
</div>
|
|
2264
3021
|
</div>
|
|
2265
|
-
</div>
|
|
2266
3022
|
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
3023
|
+
<div *ngIf="multiSelect && selected.length" class="mt-2 small text-muted">
|
|
3024
|
+
{{ selectionSummary }}
|
|
3025
|
+
<button type="button" class="btn btn-link btn-sm ps-1" (click)="clearSelection()">
|
|
3026
|
+
{{ i18n?.clearSelection || 'Clear' }}
|
|
3027
|
+
</button>
|
|
3028
|
+
</div>
|
|
2272
3029
|
</div>
|
|
2273
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "
|
|
3030
|
+
`, isInline: true, styles: [":host{display:block}.typeahead-root{position:relative}.typeahead-chips-control{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;min-height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem}.typeahead-chips-control input{border:0;outline:0;flex:1 1 9rem;min-width:6rem;padding:0;margin:0;background:transparent}.typeahead-chips-control input:focus{outline:0;box-shadow:none}.typeahead-panel{position:absolute;top:calc(100% + .25rem);left:0;right:0;z-index:1050;max-height:240px;overflow:auto;opacity:0;transform:translateY(-.25rem);pointer-events:none;transition:opacity .12s ease,transform .12s ease}.typeahead-panel.show{opacity:1;transform:translateY(0);pointer-events:auto}.typeahead-item{display:flex;align-items:center;gap:.5rem}.typeahead-item-checkbox{display:inline-flex;align-items:center;justify-content:center;width:1.15rem;height:1.15rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgbChipsComponent, selector: "ngb-chips", inputs: ["items", "removable", "ariaLabel", "removeLabel"], outputs: ["remove"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2274
3031
|
}
|
|
2275
3032
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbTypeaheadComponent, decorators: [{
|
|
2276
3033
|
type: Component,
|
|
2277
|
-
args: [{
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
3034
|
+
args: [{ selector: 'ngb-typeahead', standalone: true, imports: [CommonModule, NgbChipsComponent], providers: [
|
|
3035
|
+
{
|
|
3036
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3037
|
+
useExisting: forwardRef(() => NgbTypeaheadComponent),
|
|
3038
|
+
multi: true,
|
|
3039
|
+
},
|
|
3040
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
3041
|
+
<div class="typeahead-root">
|
|
3042
|
+
<div class="input-group mb-2">
|
|
3043
|
+
<ng-container *ngIf="chips && multiSelect; else plainInput">
|
|
3044
|
+
<div class="form-control typeahead-chips-control" (click)="disabled ? null : focusInput()">
|
|
3045
|
+
<ngb-chips
|
|
3046
|
+
[items]="selected"
|
|
3047
|
+
[removable]="true"
|
|
3048
|
+
(remove)="removeSelected($event)"
|
|
3049
|
+
ariaLabel="Selected items"
|
|
3050
|
+
></ngb-chips>
|
|
3051
|
+
<input
|
|
3052
|
+
#inputEl
|
|
3053
|
+
type="text"
|
|
3054
|
+
[disabled]="disabled"
|
|
3055
|
+
[attr.placeholder]="selected.length ? '' : (i18n?.placeholder || 'Type to search')"
|
|
3056
|
+
[value]="query"
|
|
3057
|
+
(input)="onNativeInput($event)"
|
|
3058
|
+
(focus)="onInputFocus($event)"
|
|
3059
|
+
(blur)="onInputBlur($event)"
|
|
3060
|
+
(keydown)="onKeydown($event)"
|
|
3061
|
+
(keyup)="onKeyup($event)"
|
|
3062
|
+
aria-autocomplete="list"
|
|
3063
|
+
role="combobox"
|
|
3064
|
+
[attr.aria-expanded]="overlayVisible"
|
|
3065
|
+
[attr.aria-controls]="overlayId"
|
|
3066
|
+
[attr.aria-activedescendant]="activeDescendantId"
|
|
3067
|
+
/>
|
|
3068
|
+
</div>
|
|
3069
|
+
</ng-container>
|
|
3070
|
+
<ng-template #plainInput>
|
|
3071
|
+
<input
|
|
3072
|
+
#inputEl
|
|
3073
|
+
type="text"
|
|
3074
|
+
class="form-control"
|
|
3075
|
+
[disabled]="disabled"
|
|
3076
|
+
[attr.placeholder]="i18n?.placeholder || 'Type to search'"
|
|
3077
|
+
[value]="displayQuery"
|
|
3078
|
+
(input)="onNativeInput($event)"
|
|
3079
|
+
(focus)="onInputFocus($event)"
|
|
3080
|
+
(blur)="onInputBlur($event)"
|
|
3081
|
+
(keydown)="onKeydown($event)"
|
|
3082
|
+
(keyup)="onKeyup($event)"
|
|
3083
|
+
aria-autocomplete="list"
|
|
3084
|
+
role="combobox"
|
|
3085
|
+
[attr.aria-expanded]="overlayVisible"
|
|
3086
|
+
[attr.aria-controls]="overlayId"
|
|
3087
|
+
[attr.aria-activedescendant]="activeDescendantId"
|
|
3088
|
+
/>
|
|
3089
|
+
</ng-template>
|
|
2297
3090
|
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
3091
|
+
<button
|
|
3092
|
+
*ngIf="showClearButton && (query || (!multiSelect && selected.length))"
|
|
3093
|
+
type="button"
|
|
3094
|
+
class="btn btn-outline-secondary"
|
|
3095
|
+
(click)="onClearClick($event)"
|
|
3096
|
+
[disabled]="disabled"
|
|
3097
|
+
[attr.aria-label]="i18n?.clear || 'Clear'"
|
|
3098
|
+
>
|
|
3099
|
+
×
|
|
3100
|
+
</button>
|
|
3101
|
+
|
|
3102
|
+
<button
|
|
3103
|
+
*ngIf="showDropdownButton"
|
|
3104
|
+
type="button"
|
|
3105
|
+
class="btn btn-outline-secondary"
|
|
3106
|
+
(click)="onDropdownButtonClick($event)"
|
|
3107
|
+
[disabled]="disabled"
|
|
3108
|
+
[attr.aria-label]="i18n?.dropdownButtonLabel || 'Toggle suggestions'"
|
|
3109
|
+
>
|
|
3110
|
+
▾
|
|
3111
|
+
</button>
|
|
3112
|
+
</div>
|
|
3113
|
+
|
|
3114
|
+
<div
|
|
3115
|
+
#scroller
|
|
3116
|
+
class="dropdown-menu w-100 p-0 typeahead-panel"
|
|
3117
|
+
[class.show]="overlayVisible"
|
|
3118
|
+
[id]="overlayId"
|
|
3119
|
+
role="listbox"
|
|
3120
|
+
(scroll)="onScroll($event)"
|
|
2314
3121
|
>
|
|
2315
|
-
<
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
3122
|
+
<div *ngIf="vScroll" [style.height.px]="beforePadding"></div>
|
|
3123
|
+
|
|
3124
|
+
<button
|
|
3125
|
+
*ngFor="let item of visible; trackBy: trackById; let idx = index"
|
|
3126
|
+
type="button"
|
|
3127
|
+
class="dropdown-item"
|
|
3128
|
+
[class.active]="idx === activeIndex"
|
|
3129
|
+
[class.fw-semibold]="isSelected(item)"
|
|
3130
|
+
[attr.aria-selected]="isSelected(item)"
|
|
3131
|
+
[attr.id]="getOptionId(idx)"
|
|
3132
|
+
(click)="selectItem(item)"
|
|
3133
|
+
[disabled]="item.disabled"
|
|
3134
|
+
>
|
|
3135
|
+
<div class="typeahead-item">
|
|
3136
|
+
<span *ngIf="multiSelect" class="typeahead-item-checkbox">
|
|
3137
|
+
<input
|
|
3138
|
+
type="checkbox"
|
|
3139
|
+
class="form-check-input m-0"
|
|
3140
|
+
[checked]="isSelected(item)"
|
|
3141
|
+
[disabled]="item.disabled"
|
|
3142
|
+
tabindex="-1"
|
|
3143
|
+
aria-hidden="true"
|
|
3144
|
+
/>
|
|
3145
|
+
</span>
|
|
3146
|
+
<ng-container *ngIf="resolvedItemTemplate as tpl; else defaultTpl">
|
|
3147
|
+
<ng-container
|
|
3148
|
+
[ngTemplateOutlet]="tpl"
|
|
3149
|
+
[ngTemplateOutletContext]="{
|
|
3150
|
+
$implicit: item,
|
|
3151
|
+
item: item,
|
|
3152
|
+
query: query,
|
|
3153
|
+
selected: isSelected(item),
|
|
3154
|
+
index: idx
|
|
3155
|
+
}"
|
|
3156
|
+
></ng-container>
|
|
3157
|
+
</ng-container>
|
|
3158
|
+
<ng-template #defaultTpl>
|
|
3159
|
+
<span>{{ item.label }}</span>
|
|
3160
|
+
</ng-template>
|
|
3161
|
+
</div>
|
|
3162
|
+
</button>
|
|
2322
3163
|
|
|
2323
|
-
|
|
2324
|
-
|
|
3164
|
+
<div *ngIf="vScroll" [style.height.px]="afterPadding"></div>
|
|
3165
|
+
|
|
3166
|
+
<div *ngIf="showNoResults" class="dropdown-item text-muted text-center">
|
|
3167
|
+
{{ i18n?.noResults || 'No results' }}
|
|
3168
|
+
</div>
|
|
2325
3169
|
</div>
|
|
2326
|
-
</div>
|
|
2327
3170
|
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
3171
|
+
<div *ngIf="multiSelect && selected.length" class="mt-2 small text-muted">
|
|
3172
|
+
{{ selectionSummary }}
|
|
3173
|
+
<button type="button" class="btn btn-link btn-sm ps-1" (click)="clearSelection()">
|
|
3174
|
+
{{ i18n?.clearSelection || 'Clear' }}
|
|
3175
|
+
</button>
|
|
3176
|
+
</div>
|
|
2333
3177
|
</div>
|
|
2334
|
-
`,
|
|
2335
|
-
|
|
2336
|
-
}], propDecorators: { data: [{
|
|
3178
|
+
`, styles: [":host{display:block}.typeahead-root{position:relative}.typeahead-chips-control{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem;min-height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem}.typeahead-chips-control input{border:0;outline:0;flex:1 1 9rem;min-width:6rem;padding:0;margin:0;background:transparent}.typeahead-chips-control input:focus{outline:0;box-shadow:none}.typeahead-panel{position:absolute;top:calc(100% + .25rem);left:0;right:0;z-index:1050;max-height:240px;overflow:auto;opacity:0;transform:translateY(-.25rem);pointer-events:none;transition:opacity .12s ease,transform .12s ease}.typeahead-panel.show{opacity:1;transform:translateY(0);pointer-events:auto}.typeahead-item{display:flex;align-items:center;gap:.5rem}.typeahead-item-checkbox{display:inline-flex;align-items:center;justify-content:center;width:1.15rem;height:1.15rem}\n"] }]
|
|
3179
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { data: [{
|
|
2337
3180
|
type: Input
|
|
2338
3181
|
}], debounceTime: [{
|
|
2339
3182
|
type: Input
|
|
@@ -2345,11 +3188,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2345
3188
|
type: Input
|
|
2346
3189
|
}], multiSelect: [{
|
|
2347
3190
|
type: Input
|
|
2348
|
-
}],
|
|
3191
|
+
}], matchSelection: [{
|
|
3192
|
+
type: Input
|
|
3193
|
+
}], showDropdownButton: [{
|
|
3194
|
+
type: Input
|
|
3195
|
+
}], showClearButton: [{
|
|
3196
|
+
type: Input
|
|
3197
|
+
}], updateOnBlur: [{
|
|
3198
|
+
type: Input
|
|
3199
|
+
}], updateOnTab: [{
|
|
3200
|
+
type: Input
|
|
3201
|
+
}], separator: [{
|
|
3202
|
+
type: Input
|
|
3203
|
+
}], chips: [{
|
|
3204
|
+
type: Input
|
|
3205
|
+
}], vScroll: [{
|
|
3206
|
+
type: Input
|
|
3207
|
+
}], vItemSize: [{
|
|
2349
3208
|
type: Input
|
|
2350
3209
|
}], itemTemplate: [{
|
|
3210
|
+
type: Input
|
|
3211
|
+
}], i18n: [{
|
|
3212
|
+
type: Input
|
|
3213
|
+
}], projectedItemTemplate: [{
|
|
2351
3214
|
type: ContentChild,
|
|
2352
3215
|
args: [TemplateRef]
|
|
3216
|
+
}], completeMethod: [{
|
|
3217
|
+
type: Output
|
|
3218
|
+
}], onSelect: [{
|
|
3219
|
+
type: Output
|
|
3220
|
+
}], onUnselect: [{
|
|
3221
|
+
type: Output
|
|
3222
|
+
}], onAdd: [{
|
|
3223
|
+
type: Output
|
|
3224
|
+
}], onFocus: [{
|
|
3225
|
+
type: Output
|
|
3226
|
+
}], onBlur: [{
|
|
3227
|
+
type: Output
|
|
3228
|
+
}], onDropdownClick: [{
|
|
3229
|
+
type: Output
|
|
3230
|
+
}], onClear: [{
|
|
3231
|
+
type: Output
|
|
3232
|
+
}], onInputKeydown: [{
|
|
3233
|
+
type: Output
|
|
3234
|
+
}], onKeyUp: [{
|
|
3235
|
+
type: Output
|
|
3236
|
+
}], onShow: [{
|
|
3237
|
+
type: Output
|
|
3238
|
+
}], onHide: [{
|
|
3239
|
+
type: Output
|
|
3240
|
+
}], onLazyLoad: [{
|
|
3241
|
+
type: Output
|
|
2353
3242
|
}], selectedItems: [{
|
|
2354
3243
|
type: Output
|
|
2355
3244
|
}], selectionChange: [{
|
|
@@ -2363,10 +3252,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2363
3252
|
args: ['scroller', { static: true }]
|
|
2364
3253
|
}], inputEl: [{
|
|
2365
3254
|
type: ViewChild,
|
|
2366
|
-
args: ['inputEl'
|
|
3255
|
+
args: ['inputEl']
|
|
2367
3256
|
}], itemButtons: [{
|
|
2368
3257
|
type: ViewChildren,
|
|
2369
3258
|
args: ['itemButton']
|
|
3259
|
+
}], onDocumentMouseDown: [{
|
|
3260
|
+
type: HostListener,
|
|
3261
|
+
args: ['document:mousedown', ['$event']]
|
|
3262
|
+
}], onDocumentFocusIn: [{
|
|
3263
|
+
type: HostListener,
|
|
3264
|
+
args: ['document:focusin', ['$event']]
|
|
2370
3265
|
}] } });
|
|
2371
3266
|
|
|
2372
3267
|
class NgbTreeComponent {
|
|
@@ -2374,6 +3269,10 @@ class NgbTreeComponent {
|
|
|
2374
3269
|
type = 'text';
|
|
2375
3270
|
showCheckbox = false;
|
|
2376
3271
|
i18n;
|
|
3272
|
+
expandIcon = 'bi-caret-right-fill';
|
|
3273
|
+
collapseIcon = 'bi-caret-down-fill';
|
|
3274
|
+
plusIcon = 'bi-file-plus-fill';
|
|
3275
|
+
minusIcon = 'bi-file-minus-fill';
|
|
2377
3276
|
expand = new EventEmitter();
|
|
2378
3277
|
collapse = new EventEmitter();
|
|
2379
3278
|
expandAll = new EventEmitter();
|
|
@@ -2454,7 +3353,7 @@ class NgbTreeComponent {
|
|
|
2454
3353
|
return acc;
|
|
2455
3354
|
}
|
|
2456
3355
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2457
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgbTreeComponent, isStandalone: true, selector: "ngb-tree", inputs: { nodes: "nodes", type: "type", showCheckbox: "showCheckbox", i18n: "i18n" }, outputs: { expand: "expand", collapse: "collapse", expandAll: "expandAll", collapseAll: "collapseAll", selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "nodeButtons", predicate: ["nodeBtn"], descendants: true, read: ElementRef }], ngImport: i0, template: `
|
|
3356
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.6", type: NgbTreeComponent, isStandalone: true, selector: "ngb-tree", inputs: { nodes: "nodes", type: "type", showCheckbox: "showCheckbox", i18n: "i18n", expandIcon: "expandIcon", collapseIcon: "collapseIcon", plusIcon: "plusIcon", minusIcon: "minusIcon" }, outputs: { expand: "expand", collapse: "collapse", expandAll: "expandAll", collapseAll: "collapseAll", selectionChange: "selectionChange" }, viewQueries: [{ propertyName: "nodeButtons", predicate: ["nodeBtn"], descendants: true, read: ElementRef }], ngImport: i0, template: `
|
|
2458
3357
|
<div class="d-flex gap-2 mb-2">
|
|
2459
3358
|
<button type="button" class="btn btn-sm btn-outline-secondary" (click)="expandAllNodes()" [attr.aria-label]="i18n?.expandAll || 'Expand all'">
|
|
2460
3359
|
{{ i18n?.expandAll || 'Expand all' }}
|
|
@@ -2477,21 +3376,22 @@ class NgbTreeComponent {
|
|
|
2477
3376
|
[attr.aria-expanded]="hasChildren(node) ? !!node.expanded : null"
|
|
2478
3377
|
[attr.aria-level]="level"
|
|
2479
3378
|
>
|
|
2480
|
-
<
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
<span *ngIf="type
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
3379
|
+
<ng-container *ngIf="hasChildren(node); else leafSpacer">
|
|
3380
|
+
<button
|
|
3381
|
+
#nodeBtn
|
|
3382
|
+
type="button"
|
|
3383
|
+
class="btn btn-sm px-1"
|
|
3384
|
+
(click)="toggleNode(node)"
|
|
3385
|
+
(keydown)="onNodeKeydown($event, node)"
|
|
3386
|
+
[attr.aria-label]="(node.expanded ? i18n?.collapse || 'Collapse' : i18n?.expand || 'Expand') + ' ' + node.label"
|
|
3387
|
+
>
|
|
3388
|
+
<span *ngIf="type === 'json'" class="bi" [ngClass]="node.expanded ? minusIcon : plusIcon" aria-hidden="true"></span>
|
|
3389
|
+
<span *ngIf="type !== 'json'" class="bi" [ngClass]="node.expanded ? collapseIcon : expandIcon" aria-hidden="true"></span>
|
|
3390
|
+
</button>
|
|
3391
|
+
</ng-container>
|
|
3392
|
+
<ng-template #leafSpacer>
|
|
3393
|
+
<span class="d-inline-block px-1" style="width: 1.5rem;"></span>
|
|
3394
|
+
</ng-template>
|
|
2495
3395
|
|
|
2496
3396
|
<label class="form-check d-inline-flex align-items-center gap-2 flex-grow-1 mb-0">
|
|
2497
3397
|
<input
|
|
@@ -2517,7 +3417,7 @@ class NgbTreeComponent {
|
|
|
2517
3417
|
</ng-container>
|
|
2518
3418
|
</ul>
|
|
2519
3419
|
</ng-template>
|
|
2520
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3420
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2521
3421
|
}
|
|
2522
3422
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbTreeComponent, decorators: [{
|
|
2523
3423
|
type: Component,
|
|
@@ -2549,21 +3449,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2549
3449
|
[attr.aria-expanded]="hasChildren(node) ? !!node.expanded : null"
|
|
2550
3450
|
[attr.aria-level]="level"
|
|
2551
3451
|
>
|
|
2552
|
-
<
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
<span *ngIf="type
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
3452
|
+
<ng-container *ngIf="hasChildren(node); else leafSpacer">
|
|
3453
|
+
<button
|
|
3454
|
+
#nodeBtn
|
|
3455
|
+
type="button"
|
|
3456
|
+
class="btn btn-sm px-1"
|
|
3457
|
+
(click)="toggleNode(node)"
|
|
3458
|
+
(keydown)="onNodeKeydown($event, node)"
|
|
3459
|
+
[attr.aria-label]="(node.expanded ? i18n?.collapse || 'Collapse' : i18n?.expand || 'Expand') + ' ' + node.label"
|
|
3460
|
+
>
|
|
3461
|
+
<span *ngIf="type === 'json'" class="bi" [ngClass]="node.expanded ? minusIcon : plusIcon" aria-hidden="true"></span>
|
|
3462
|
+
<span *ngIf="type !== 'json'" class="bi" [ngClass]="node.expanded ? collapseIcon : expandIcon" aria-hidden="true"></span>
|
|
3463
|
+
</button>
|
|
3464
|
+
</ng-container>
|
|
3465
|
+
<ng-template #leafSpacer>
|
|
3466
|
+
<span class="d-inline-block px-1" style="width: 1.5rem;"></span>
|
|
3467
|
+
</ng-template>
|
|
2567
3468
|
|
|
2568
3469
|
<label class="form-check d-inline-flex align-items-center gap-2 flex-grow-1 mb-0">
|
|
2569
3470
|
<input
|
|
@@ -2599,6 +3500,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2599
3500
|
type: Input
|
|
2600
3501
|
}], i18n: [{
|
|
2601
3502
|
type: Input
|
|
3503
|
+
}], expandIcon: [{
|
|
3504
|
+
type: Input
|
|
3505
|
+
}], collapseIcon: [{
|
|
3506
|
+
type: Input
|
|
3507
|
+
}], plusIcon: [{
|
|
3508
|
+
type: Input
|
|
3509
|
+
}], minusIcon: [{
|
|
3510
|
+
type: Input
|
|
2602
3511
|
}], expand: [{
|
|
2603
3512
|
type: Output
|
|
2604
3513
|
}], collapse: [{
|
|
@@ -2620,5 +3529,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2620
3529
|
* Generated bundle index. Do not edit.
|
|
2621
3530
|
*/
|
|
2622
3531
|
|
|
2623
|
-
export { DATAGRID_TEMPLATE_DIRECTIVES, DND_I18N, DND_LIVE_ANNOUNCE, Datagrid, ExcelExportAdapter, ExportButtonDirective, JsPdfAdapter, NgbCellTemplate, NgbDndItemDirective, NgbDndListDirective, NgbDndState, NgbEditorTemplate, NgbExportService, NgbFilterTemplate, NgbGlobalFilterTemplate, NgbLiveAnnouncer, NgbPaginationComponent, NgbRowDetailTemplate, NgbSplitterComponent, NgbStepLabelDirective, NgbStepperComponent, NgbTreeComponent, NgbTypeaheadComponent, PdfExportAdapter, XlsxAdapter, defaultDndI18n };
|
|
3532
|
+
export { DATAGRID_TEMPLATE_DIRECTIVES, DND_I18N, DND_LIVE_ANNOUNCE, Datagrid, ExcelExportAdapter, ExportButtonDirective, JsPdfAdapter, NgbCellTemplate, NgbChipsComponent, NgbDndItemDirective, NgbDndListDirective, NgbDndState, NgbEditorTemplate, NgbExportService, NgbFilterTemplate, NgbGlobalFilterTemplate, NgbLiveAnnouncer, NgbPaginationComponent, NgbRowDetailTemplate, NgbSplitterComponent, NgbSplitterPaneComponent, NgbStepLabelDirective, NgbStepperComponent, NgbTreeComponent, NgbTypeaheadComponent, PdfExportAdapter, XlsxAdapter, defaultDndI18n };
|
|
2624
3533
|
//# sourceMappingURL=angular-bootstrap-ngbootstrap.mjs.map
|