@angular-bootstrap/ngbootstrap 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -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,568 @@ 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: [{
|
|
2075
2113
|
type: HostListener,
|
|
2076
|
-
args: ['window:
|
|
2114
|
+
args: ['window:mousemove', ['$event']]
|
|
2115
|
+
}], onMouseUp: [{
|
|
2116
|
+
type: HostListener,
|
|
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
|
+
// `TemplateRef` types can become non-assignable in monorepo setups with multiple Angular installations.
|
|
2202
|
+
// Using `any` keeps the API flexible while still supporting Angular templates at runtime.
|
|
2087
2203
|
itemTemplate;
|
|
2204
|
+
i18n;
|
|
2205
|
+
projectedItemTemplate;
|
|
2206
|
+
completeMethod = new EventEmitter();
|
|
2207
|
+
onSelect = new EventEmitter();
|
|
2208
|
+
onUnselect = new EventEmitter();
|
|
2209
|
+
onAdd = new EventEmitter();
|
|
2210
|
+
onFocus = new EventEmitter();
|
|
2211
|
+
onBlur = new EventEmitter();
|
|
2212
|
+
onDropdownClick = new EventEmitter();
|
|
2213
|
+
onClear = new EventEmitter();
|
|
2214
|
+
onInputKeydown = new EventEmitter();
|
|
2215
|
+
onKeyUp = new EventEmitter();
|
|
2216
|
+
onShow = new EventEmitter();
|
|
2217
|
+
onHide = new EventEmitter();
|
|
2218
|
+
onLazyLoad = new EventEmitter();
|
|
2088
2219
|
selectedItems = new EventEmitter();
|
|
2089
2220
|
selectionChange = new EventEmitter();
|
|
2090
2221
|
onChange = new EventEmitter();
|
|
2091
|
-
onScrollEvent = new EventEmitter();
|
|
2222
|
+
onScrollEvent = new EventEmitter(); // legacy, kept for compatibility
|
|
2092
2223
|
scroller;
|
|
2093
2224
|
inputEl;
|
|
2094
2225
|
itemButtons;
|
|
2226
|
+
disabled = false;
|
|
2095
2227
|
query = '';
|
|
2096
2228
|
filtered = [];
|
|
2097
2229
|
visible = [];
|
|
2098
2230
|
selected = [];
|
|
2231
|
+
overlayVisible = false;
|
|
2232
|
+
openedByDropdown = false;
|
|
2233
|
+
hasSearched = false;
|
|
2234
|
+
activeIndex = -1;
|
|
2235
|
+
inputFocused = false;
|
|
2236
|
+
pointerDownInside = false;
|
|
2237
|
+
lastFilterTerm = '';
|
|
2238
|
+
keepOpenOnEmpty = false;
|
|
2239
|
+
overlayId = `ngb-typeahead-overlay-${Math.random().toString(36).slice(2)}`;
|
|
2099
2240
|
viewportHeight = 240;
|
|
2100
2241
|
itemHeight = 40;
|
|
2101
2242
|
beforePadding = 0;
|
|
2102
2243
|
afterPadding = 0;
|
|
2103
2244
|
debounceId;
|
|
2245
|
+
onControlChange = () => { };
|
|
2246
|
+
onControlTouched = () => { };
|
|
2247
|
+
controlValue = null;
|
|
2104
2248
|
ngAfterViewInit() {
|
|
2249
|
+
// do not open overlay on init; just ensure viewport state is consistent
|
|
2105
2250
|
this.applyFilter('');
|
|
2106
2251
|
}
|
|
2107
2252
|
ngOnChanges(changes) {
|
|
2108
2253
|
if (changes['data'] && !changes['data'].firstChange) {
|
|
2109
2254
|
this.applyFilter(this.query);
|
|
2110
2255
|
}
|
|
2256
|
+
if (changes['data'] && this.controlValue != null && !this.inputFocused && !this.overlayVisible) {
|
|
2257
|
+
this.applyControlValue(this.controlValue);
|
|
2258
|
+
}
|
|
2111
2259
|
}
|
|
2112
2260
|
ngOnDestroy() {
|
|
2113
2261
|
if (this.debounceId) {
|
|
2114
2262
|
clearTimeout(this.debounceId);
|
|
2115
2263
|
}
|
|
2116
2264
|
}
|
|
2265
|
+
constructor(host, cdr) {
|
|
2266
|
+
this.host = host;
|
|
2267
|
+
this.cdr = cdr;
|
|
2268
|
+
}
|
|
2269
|
+
onDocumentMouseDown(event) {
|
|
2270
|
+
const target = event.target;
|
|
2271
|
+
if (!target)
|
|
2272
|
+
return;
|
|
2273
|
+
const inside = this.host.nativeElement.contains(target);
|
|
2274
|
+
this.pointerDownInside = inside;
|
|
2275
|
+
if (inside)
|
|
2276
|
+
return;
|
|
2277
|
+
if (!this.overlayVisible)
|
|
2278
|
+
return;
|
|
2279
|
+
this.commitInputOnClose();
|
|
2280
|
+
this.hideOverlay(event);
|
|
2281
|
+
}
|
|
2282
|
+
onDocumentFocusIn(event) {
|
|
2283
|
+
if (!this.overlayVisible)
|
|
2284
|
+
return;
|
|
2285
|
+
const target = event.target;
|
|
2286
|
+
if (!target)
|
|
2287
|
+
return;
|
|
2288
|
+
if (this.host.nativeElement.contains(target))
|
|
2289
|
+
return;
|
|
2290
|
+
this.commitInputOnClose();
|
|
2291
|
+
this.hideOverlay(event);
|
|
2292
|
+
}
|
|
2293
|
+
get activeDescendantId() {
|
|
2294
|
+
if (!this.overlayVisible)
|
|
2295
|
+
return null;
|
|
2296
|
+
if (this.activeIndex < 0 || this.activeIndex >= this.visible.length)
|
|
2297
|
+
return null;
|
|
2298
|
+
return this.getOptionId(this.activeIndex);
|
|
2299
|
+
}
|
|
2300
|
+
get showNoResults() {
|
|
2301
|
+
return this.overlayVisible && this.hasSearched && this.filtered.length === 0;
|
|
2302
|
+
}
|
|
2303
|
+
get displayQuery() {
|
|
2304
|
+
if (!this.multiSelect) {
|
|
2305
|
+
return this.query;
|
|
2306
|
+
}
|
|
2307
|
+
if (this.chips) {
|
|
2308
|
+
return this.query;
|
|
2309
|
+
}
|
|
2310
|
+
const term = (this.query || '').trim();
|
|
2311
|
+
const prefix = this.selected.map((s) => s.label).join(', ');
|
|
2312
|
+
if (!prefix) {
|
|
2313
|
+
return this.query;
|
|
2314
|
+
}
|
|
2315
|
+
if (term) {
|
|
2316
|
+
return `${prefix}, ${term}`;
|
|
2317
|
+
}
|
|
2318
|
+
return prefix;
|
|
2319
|
+
}
|
|
2117
2320
|
get selectionSummary() {
|
|
2118
2321
|
if (!this.selected.length)
|
|
2119
2322
|
return '';
|
|
@@ -2123,28 +2326,179 @@ class NgbTypeaheadComponent {
|
|
|
2123
2326
|
const firstTwo = this.selected.slice(0, 2).map((s) => s.label).join(', ');
|
|
2124
2327
|
return `${firstTwo} (+${this.selected.length - 2})`;
|
|
2125
2328
|
}
|
|
2329
|
+
get resolvedItemTemplate() {
|
|
2330
|
+
return this.itemTemplate ?? this.projectedItemTemplate;
|
|
2331
|
+
}
|
|
2332
|
+
writeValue(value) {
|
|
2333
|
+
this.controlValue = value;
|
|
2334
|
+
this.applyControlValue(value);
|
|
2335
|
+
}
|
|
2336
|
+
applyControlValue(value) {
|
|
2337
|
+
if (this.multiSelect) {
|
|
2338
|
+
const asArray = Array.isArray(value) ? value : value == null ? [] : [value];
|
|
2339
|
+
const next = asArray.map((v) => this.coerceToItem(v)).filter(Boolean);
|
|
2340
|
+
const seen = new Set();
|
|
2341
|
+
this.selected = next.filter((i) => (seen.has(i.id) ? false : (seen.add(i.id), true)));
|
|
2342
|
+
this.query = '';
|
|
2343
|
+
this.keepOpenOnEmpty = false;
|
|
2344
|
+
this.applyFilter('');
|
|
2345
|
+
this.cdr.markForCheck();
|
|
2346
|
+
return;
|
|
2347
|
+
}
|
|
2348
|
+
if (value == null) {
|
|
2349
|
+
this.selected = [];
|
|
2350
|
+
this.query = '';
|
|
2351
|
+
this.keepOpenOnEmpty = false;
|
|
2352
|
+
this.applyFilter('');
|
|
2353
|
+
this.cdr.markForCheck();
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
const item = this.coerceToItem(value);
|
|
2357
|
+
if (!item)
|
|
2358
|
+
return;
|
|
2359
|
+
this.selected = [item];
|
|
2360
|
+
this.query = item.label;
|
|
2361
|
+
if (this.inputEl?.nativeElement) {
|
|
2362
|
+
this.inputEl.nativeElement.value = item.label;
|
|
2363
|
+
}
|
|
2364
|
+
this.keepOpenOnEmpty = false;
|
|
2365
|
+
this.applyFilter(this.query);
|
|
2366
|
+
this.cdr.markForCheck();
|
|
2367
|
+
}
|
|
2368
|
+
registerOnChange(fn) {
|
|
2369
|
+
this.onControlChange = fn;
|
|
2370
|
+
}
|
|
2371
|
+
registerOnTouched(fn) {
|
|
2372
|
+
this.onControlTouched = fn;
|
|
2373
|
+
}
|
|
2374
|
+
setDisabledState(isDisabled) {
|
|
2375
|
+
this.disabled = isDisabled;
|
|
2376
|
+
if (isDisabled) {
|
|
2377
|
+
this.hideOverlay();
|
|
2378
|
+
}
|
|
2379
|
+
this.cdr.markForCheck();
|
|
2380
|
+
}
|
|
2126
2381
|
onInput(value) {
|
|
2127
|
-
this.
|
|
2382
|
+
if (this.disabled)
|
|
2383
|
+
return;
|
|
2384
|
+
this.keepOpenOnEmpty = false;
|
|
2385
|
+
const trimmed = (value ?? '').trim();
|
|
2386
|
+
if (!this.multiSelect && this.selected.length) {
|
|
2387
|
+
const selectedLabel = (this.selected[0]?.label ?? '').trim();
|
|
2388
|
+
if (trimmed.toLowerCase() !== selectedLabel.toLowerCase()) {
|
|
2389
|
+
const previous = this.selected[0];
|
|
2390
|
+
this.selected = [];
|
|
2391
|
+
this.selectedItems.emit(this.selected);
|
|
2392
|
+
this.selectionChange.emit(this.selected);
|
|
2393
|
+
if (previous) {
|
|
2394
|
+
this.onUnselect.emit(previous);
|
|
2395
|
+
}
|
|
2396
|
+
this.propagateControlValue();
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
if (this.chips && this.multiSelect) {
|
|
2400
|
+
const tokens = this.splitBySeparators(value);
|
|
2401
|
+
if (tokens.tokensToAdd.length) {
|
|
2402
|
+
for (const token of tokens.tokensToAdd) {
|
|
2403
|
+
this.addToken(token);
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
this.query = tokens.remaining;
|
|
2407
|
+
}
|
|
2408
|
+
else {
|
|
2409
|
+
this.query = value;
|
|
2410
|
+
}
|
|
2128
2411
|
this.onChange.emit(value);
|
|
2412
|
+
// Input events imply the user is interacting with the field; treat as focused so the overlay can open immediately.
|
|
2413
|
+
this.inputFocused = true;
|
|
2129
2414
|
if (this.debounceId)
|
|
2130
2415
|
clearTimeout(this.debounceId);
|
|
2131
2416
|
if (this.debounceTime <= 0) {
|
|
2132
2417
|
this.applyFilter(value);
|
|
2418
|
+
this.completeMethod.emit(value);
|
|
2133
2419
|
}
|
|
2134
2420
|
else {
|
|
2135
|
-
this.debounceId = setTimeout(() =>
|
|
2421
|
+
this.debounceId = setTimeout(() => {
|
|
2422
|
+
this.applyFilter(value);
|
|
2423
|
+
this.completeMethod.emit(value);
|
|
2424
|
+
this.cdr.markForCheck();
|
|
2425
|
+
}, this.debounceTime);
|
|
2136
2426
|
}
|
|
2137
2427
|
}
|
|
2428
|
+
onNativeInput(event) {
|
|
2429
|
+
const target = event.target;
|
|
2430
|
+
const value = target?.value ?? '';
|
|
2431
|
+
if (this.multiSelect && !this.chips && this.selected.length) {
|
|
2432
|
+
const prefix = this.selected.map((s) => s.label).join(', ');
|
|
2433
|
+
const normalizedPrefix = prefix.trim();
|
|
2434
|
+
if (normalizedPrefix && value.toLowerCase().startsWith(normalizedPrefix.toLowerCase())) {
|
|
2435
|
+
let rest = value.slice(normalizedPrefix.length);
|
|
2436
|
+
rest = rest.replace(/^[\s,]+/, '');
|
|
2437
|
+
this.onInput(rest);
|
|
2438
|
+
return;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
this.onInput(value);
|
|
2442
|
+
}
|
|
2138
2443
|
onKeydown(event) {
|
|
2444
|
+
if (this.disabled)
|
|
2445
|
+
return;
|
|
2446
|
+
this.onInputKeydown.emit(event);
|
|
2447
|
+
if (this.chips && this.multiSelect && event.key === 'Tab' && this.updateOnTab) {
|
|
2448
|
+
event.preventDefault();
|
|
2449
|
+
this.addToken((this.query || '').trim());
|
|
2450
|
+
this.focusInput();
|
|
2451
|
+
return;
|
|
2452
|
+
}
|
|
2139
2453
|
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
2140
2454
|
event.preventDefault();
|
|
2141
|
-
this.
|
|
2455
|
+
this.moveActive(event.key === 'ArrowDown' ? 1 : -1);
|
|
2142
2456
|
}
|
|
2143
2457
|
else if (event.key === 'Enter') {
|
|
2144
2458
|
event.preventDefault();
|
|
2145
|
-
const
|
|
2146
|
-
if (
|
|
2147
|
-
this.selectItem(
|
|
2459
|
+
const active = this.visible[this.activeIndex] || this.visible[0];
|
|
2460
|
+
if (active)
|
|
2461
|
+
this.selectItem(active);
|
|
2462
|
+
}
|
|
2463
|
+
else if (event.key === 'Escape') {
|
|
2464
|
+
if (this.overlayVisible) {
|
|
2465
|
+
event.preventDefault();
|
|
2466
|
+
this.hideOverlay(event);
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
onKeyup(event) {
|
|
2471
|
+
this.onKeyUp.emit(event);
|
|
2472
|
+
}
|
|
2473
|
+
onInputFocus(event) {
|
|
2474
|
+
if (this.disabled)
|
|
2475
|
+
return;
|
|
2476
|
+
this.onFocus.emit(event);
|
|
2477
|
+
this.inputFocused = true;
|
|
2478
|
+
if (this.multiSelect && !this.overlayVisible) {
|
|
2479
|
+
// When multi-select is displaying the selection summary, start searching with a clean query.
|
|
2480
|
+
this.query = '';
|
|
2481
|
+
// After a multi-select session, re-opening the field should show the list again even with an empty query.
|
|
2482
|
+
if (!this.chips && this.selected.length) {
|
|
2483
|
+
this.keepOpenOnEmpty = true;
|
|
2484
|
+
this.applyFilter('');
|
|
2485
|
+
this.activatePreferredOption();
|
|
2486
|
+
return;
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
// Opening behavior: only show overlay when threshold met, or dropdown button explicitly used.
|
|
2490
|
+
if (this.query.length >= this.characterTyped) {
|
|
2491
|
+
this.showOverlay(event);
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
onInputBlur(event) {
|
|
2495
|
+
this.onBlur.emit(event);
|
|
2496
|
+
this.onControlTouched();
|
|
2497
|
+
this.inputFocused = false;
|
|
2498
|
+
// Do not close on blur directly: scrolling/clicking within the overlay can blur the input.
|
|
2499
|
+
// Closing/commit is handled by outside click (document:mousedown) and focus moving outside (document:focusin).
|
|
2500
|
+
if (this.chips && this.multiSelect && this.updateOnBlur) {
|
|
2501
|
+
this.addToken((this.query || '').trim());
|
|
2148
2502
|
}
|
|
2149
2503
|
}
|
|
2150
2504
|
onScroll(event) {
|
|
@@ -2152,8 +2506,14 @@ class NgbTypeaheadComponent {
|
|
|
2152
2506
|
const scrollTop = target.scrollTop;
|
|
2153
2507
|
this.onScrollEvent.emit();
|
|
2154
2508
|
this.updateViewport(scrollTop);
|
|
2509
|
+
const remaining = target.scrollHeight - (target.scrollTop + target.clientHeight);
|
|
2510
|
+
if (remaining < 48) {
|
|
2511
|
+
this.onLazyLoad.emit();
|
|
2512
|
+
}
|
|
2155
2513
|
}
|
|
2156
2514
|
selectItem(item) {
|
|
2515
|
+
if (this.disabled)
|
|
2516
|
+
return;
|
|
2157
2517
|
if (!item || item.disabled)
|
|
2158
2518
|
return;
|
|
2159
2519
|
this.validateItem(item);
|
|
@@ -2161,29 +2521,118 @@ class NgbTypeaheadComponent {
|
|
|
2161
2521
|
const exists = this.selected.find((s) => s.id === item.id);
|
|
2162
2522
|
if (exists) {
|
|
2163
2523
|
this.selected = this.selected.filter((s) => s.id !== item.id);
|
|
2524
|
+
this.onUnselect.emit(item);
|
|
2164
2525
|
}
|
|
2165
2526
|
else {
|
|
2166
2527
|
this.selected = [...this.selected, item];
|
|
2528
|
+
this.onSelect.emit(item);
|
|
2529
|
+
}
|
|
2530
|
+
this.propagateControlValue();
|
|
2531
|
+
// After selecting/unselecting, show the chosen values in the input and keep the panel open.
|
|
2532
|
+
this.keepOpenOnEmpty = true;
|
|
2533
|
+
if (this.chips) {
|
|
2534
|
+
this.query = '';
|
|
2535
|
+
}
|
|
2536
|
+
else {
|
|
2537
|
+
this.query = '';
|
|
2167
2538
|
}
|
|
2539
|
+
this.applyFilter('');
|
|
2168
2540
|
}
|
|
2169
2541
|
else {
|
|
2542
|
+
if (this.selected.length && this.selected[0]?.id !== item.id) {
|
|
2543
|
+
this.onUnselect.emit(this.selected[0]);
|
|
2544
|
+
}
|
|
2170
2545
|
this.selected = [item];
|
|
2546
|
+
this.query = item.label;
|
|
2547
|
+
if (this.inputEl?.nativeElement) {
|
|
2548
|
+
this.inputEl.nativeElement.value = item.label;
|
|
2549
|
+
}
|
|
2550
|
+
this.onSelect.emit(item);
|
|
2551
|
+
this.propagateControlValue();
|
|
2552
|
+
this.hideOverlay();
|
|
2171
2553
|
}
|
|
2172
2554
|
this.selectedItems.emit(this.selected);
|
|
2173
2555
|
this.selectionChange.emit(this.selected);
|
|
2556
|
+
this.cdr.markForCheck();
|
|
2557
|
+
}
|
|
2558
|
+
focusInput() {
|
|
2559
|
+
this.inputEl?.nativeElement?.focus();
|
|
2560
|
+
}
|
|
2561
|
+
removeSelected(item) {
|
|
2562
|
+
if (this.disabled)
|
|
2563
|
+
return;
|
|
2564
|
+
if (!item)
|
|
2565
|
+
return;
|
|
2566
|
+
const exists = this.selected.find((s) => s.id === item.id);
|
|
2567
|
+
if (!exists)
|
|
2568
|
+
return;
|
|
2569
|
+
this.selected = this.selected.filter((s) => s.id !== item.id);
|
|
2570
|
+
this.onUnselect.emit(item);
|
|
2571
|
+
this.propagateControlValue();
|
|
2572
|
+
this.selectedItems.emit(this.selected);
|
|
2573
|
+
this.selectionChange.emit(this.selected);
|
|
2574
|
+
this.cdr.markForCheck();
|
|
2174
2575
|
}
|
|
2175
2576
|
clearSelection() {
|
|
2577
|
+
const previous = [...this.selected];
|
|
2176
2578
|
this.selected = [];
|
|
2177
2579
|
this.selectedItems.emit(this.selected);
|
|
2178
2580
|
this.selectionChange.emit(this.selected);
|
|
2581
|
+
if (!this.multiSelect && previous[0]) {
|
|
2582
|
+
this.onUnselect.emit(previous[0]);
|
|
2583
|
+
}
|
|
2584
|
+
this.propagateControlValue();
|
|
2585
|
+
this.cdr.markForCheck();
|
|
2179
2586
|
}
|
|
2180
2587
|
isSelected(item) {
|
|
2181
2588
|
return this.selected.some((s) => s.id === item.id);
|
|
2182
2589
|
}
|
|
2183
2590
|
trackById = (_, item) => item.id;
|
|
2591
|
+
getOptionId(index) {
|
|
2592
|
+
return `${this.overlayId}-opt-${index}`;
|
|
2593
|
+
}
|
|
2594
|
+
onDropdownButtonClick(event) {
|
|
2595
|
+
if (this.disabled)
|
|
2596
|
+
return;
|
|
2597
|
+
this.onDropdownClick.emit(event);
|
|
2598
|
+
if (this.overlayVisible) {
|
|
2599
|
+
this.hideOverlay(event);
|
|
2600
|
+
this.openedByDropdown = false;
|
|
2601
|
+
}
|
|
2602
|
+
else {
|
|
2603
|
+
this.openedByDropdown = true;
|
|
2604
|
+
if (this.scroller?.nativeElement) {
|
|
2605
|
+
this.scroller.nativeElement.scrollTop = 0;
|
|
2606
|
+
}
|
|
2607
|
+
this.showOverlay(event, true);
|
|
2608
|
+
// Show all items when the dropdown button is used, regardless of current query.
|
|
2609
|
+
this.applyFilter('');
|
|
2610
|
+
this.activatePreferredOption();
|
|
2611
|
+
}
|
|
2612
|
+
this.inputEl?.nativeElement.focus();
|
|
2613
|
+
this.cdr.markForCheck();
|
|
2614
|
+
}
|
|
2615
|
+
onClearClick(event) {
|
|
2616
|
+
if (this.disabled)
|
|
2617
|
+
return;
|
|
2618
|
+
this.onClear.emit(event);
|
|
2619
|
+
this.query = '';
|
|
2620
|
+
this.clearSelection();
|
|
2621
|
+
this.applyFilter('');
|
|
2622
|
+
this.hideOverlay(event);
|
|
2623
|
+
this.inputEl?.nativeElement.focus();
|
|
2624
|
+
this.cdr.markForCheck();
|
|
2625
|
+
}
|
|
2184
2626
|
applyFilter(value) {
|
|
2185
2627
|
const term = (value || '').toLowerCase();
|
|
2186
|
-
|
|
2628
|
+
if (term !== this.lastFilterTerm) {
|
|
2629
|
+
this.lastFilterTerm = term;
|
|
2630
|
+
if (this.scroller?.nativeElement) {
|
|
2631
|
+
this.scroller.nativeElement.scrollTop = 0;
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
const meetsThreshold = term.length >= this.characterTyped || this.openedByDropdown || (this.multiSelect && this.keepOpenOnEmpty);
|
|
2635
|
+
this.hasSearched = term.length >= this.characterTyped || this.openedByDropdown;
|
|
2187
2636
|
const base = meetsThreshold ? this.data.filter((d) => (d.label || '').toLowerCase().includes(term)) : [];
|
|
2188
2637
|
const limited = this.limit ? base.slice(0, this.limit) : base;
|
|
2189
2638
|
this.filtered = limited;
|
|
@@ -2191,6 +2640,13 @@ class NgbTypeaheadComponent {
|
|
|
2191
2640
|
this.selectItem(limited[0]);
|
|
2192
2641
|
}
|
|
2193
2642
|
this.updateViewport(this.scroller?.nativeElement.scrollTop || 0);
|
|
2643
|
+
if (meetsThreshold && !this.overlayVisible && (this.inputFocused || this.openedByDropdown)) {
|
|
2644
|
+
this.showOverlay();
|
|
2645
|
+
}
|
|
2646
|
+
if (!meetsThreshold && this.overlayVisible && !this.openedByDropdown) {
|
|
2647
|
+
this.hideOverlay();
|
|
2648
|
+
}
|
|
2649
|
+
this.cdr.markForCheck();
|
|
2194
2650
|
}
|
|
2195
2651
|
updateViewport(scrollTop) {
|
|
2196
2652
|
const total = this.filtered.length;
|
|
@@ -2200,140 +2656,454 @@ class NgbTypeaheadComponent {
|
|
|
2200
2656
|
this.beforePadding = start * this.itemHeight;
|
|
2201
2657
|
this.afterPadding = Math.max(total - end, 0) * this.itemHeight;
|
|
2202
2658
|
this.visible = this.filtered.slice(start, end);
|
|
2659
|
+
this.activeIndex = this.visible.length ? Math.min(this.activeIndex, this.visible.length - 1) : -1;
|
|
2203
2660
|
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2661
|
+
activatePreferredOption() {
|
|
2662
|
+
if (!this.filtered.length || !this.scroller?.nativeElement) {
|
|
2663
|
+
this.activeIndex = -1;
|
|
2207
2664
|
return;
|
|
2208
|
-
|
|
2209
|
-
const
|
|
2210
|
-
|
|
2211
|
-
|
|
2665
|
+
}
|
|
2666
|
+
const trimmed = (this.query || '').trim().toLowerCase();
|
|
2667
|
+
let preferredIndex = -1;
|
|
2668
|
+
if (trimmed) {
|
|
2669
|
+
preferredIndex = this.filtered.findIndex((d) => (d.label || '').trim().toLowerCase() === trimmed);
|
|
2670
|
+
}
|
|
2671
|
+
if (preferredIndex === -1 && this.selected.length) {
|
|
2672
|
+
const firstSelected = this.selected[0];
|
|
2673
|
+
preferredIndex = this.filtered.findIndex((d) => d.id === firstSelected.id);
|
|
2674
|
+
}
|
|
2675
|
+
if (preferredIndex === -1) {
|
|
2676
|
+
preferredIndex = 0;
|
|
2677
|
+
}
|
|
2678
|
+
const scrollTop = Math.max(0, preferredIndex * this.itemHeight - this.itemHeight);
|
|
2679
|
+
this.scroller.nativeElement.scrollTop = scrollTop;
|
|
2680
|
+
this.updateViewport(scrollTop);
|
|
2681
|
+
const start = Math.max(Math.floor(scrollTop / this.itemHeight), 0);
|
|
2682
|
+
this.activeIndex = Math.max(0, Math.min(preferredIndex - start, this.visible.length - 1));
|
|
2683
|
+
}
|
|
2684
|
+
moveActive(direction) {
|
|
2685
|
+
if (!this.overlayVisible) {
|
|
2686
|
+
this.showOverlay();
|
|
2687
|
+
}
|
|
2688
|
+
if (!this.visible.length)
|
|
2689
|
+
return;
|
|
2690
|
+
const nextIndex = this.activeIndex < 0 ? 0 : (this.activeIndex + direction + this.visible.length) % this.visible.length;
|
|
2691
|
+
this.activeIndex = nextIndex;
|
|
2692
|
+
const buttons = this.scroller?.nativeElement.querySelectorAll('button.dropdown-item');
|
|
2693
|
+
buttons?.[this.activeIndex]?.focus();
|
|
2212
2694
|
}
|
|
2213
2695
|
validateItem(item) {
|
|
2214
|
-
if (
|
|
2215
|
-
|
|
2216
|
-
|
|
2696
|
+
if (item.id == null) {
|
|
2697
|
+
throw new Error('Typeahead items must include an id.');
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
showOverlay(event, openedByDropdown = false) {
|
|
2701
|
+
this.openedByDropdown = openedByDropdown;
|
|
2702
|
+
if (this.overlayVisible)
|
|
2703
|
+
return;
|
|
2704
|
+
this.overlayVisible = true;
|
|
2705
|
+
this.activeIndex = this.visible.length ? 0 : -1;
|
|
2706
|
+
this.onShow.emit(event ?? new Event('show'));
|
|
2707
|
+
this.cdr.markForCheck();
|
|
2708
|
+
}
|
|
2709
|
+
hideOverlay(event) {
|
|
2710
|
+
if (!this.overlayVisible)
|
|
2711
|
+
return;
|
|
2712
|
+
this.overlayVisible = false;
|
|
2713
|
+
this.openedByDropdown = false;
|
|
2714
|
+
this.activeIndex = -1;
|
|
2715
|
+
this.onHide.emit(event ?? new Event('hide'));
|
|
2716
|
+
this.cdr.markForCheck();
|
|
2717
|
+
}
|
|
2718
|
+
commitInputOnClose() {
|
|
2719
|
+
const trimmed = (this.query || '').trim();
|
|
2720
|
+
if (!trimmed) {
|
|
2721
|
+
return;
|
|
2722
|
+
}
|
|
2723
|
+
if (this.matchSelection) {
|
|
2724
|
+
const exact = this.data.find((d) => (d.label || '').toLowerCase() === trimmed.toLowerCase());
|
|
2725
|
+
if (!exact) {
|
|
2726
|
+
this.query = '';
|
|
2727
|
+
if (!this.multiSelect) {
|
|
2728
|
+
this.clearSelection();
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
else if (!this.multiSelect) {
|
|
2732
|
+
this.selected = [exact];
|
|
2733
|
+
this.selectionChange.emit(this.selected);
|
|
2734
|
+
this.selectedItems.emit(this.selected);
|
|
2735
|
+
this.propagateControlValue();
|
|
2217
2736
|
}
|
|
2737
|
+
return;
|
|
2738
|
+
}
|
|
2739
|
+
if (this.updateOnBlur && !this.multiSelect && this.selected.length === 0) {
|
|
2740
|
+
const added = { id: trimmed, label: trimmed, value: trimmed };
|
|
2741
|
+
this.selected = [added];
|
|
2742
|
+
this.onAdd.emit(added);
|
|
2743
|
+
this.selectionChange.emit(this.selected);
|
|
2744
|
+
this.selectedItems.emit(this.selected);
|
|
2745
|
+
this.propagateControlValue();
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
splitBySeparators(value) {
|
|
2749
|
+
const separators = Array.isArray(this.separator) ? this.separator : [this.separator];
|
|
2750
|
+
const safe = separators.filter((s) => s != null && `${s}`.length > 0).map((s) => `${s}`.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
2751
|
+
if (!safe.length) {
|
|
2752
|
+
return { tokensToAdd: [], remaining: value };
|
|
2753
|
+
}
|
|
2754
|
+
const regex = new RegExp(`(?:${safe.join('|')})`);
|
|
2755
|
+
if (!regex.test(value)) {
|
|
2756
|
+
return { tokensToAdd: [], remaining: value };
|
|
2757
|
+
}
|
|
2758
|
+
const parts = value.split(new RegExp(`(?:${safe.join('|')})`, 'g')).map((p) => p.trim());
|
|
2759
|
+
const endsWithSeparator = separators.some((sep) => value.endsWith(sep));
|
|
2760
|
+
const tokensToAdd = (endsWithSeparator ? parts : parts.slice(0, -1)).filter(Boolean);
|
|
2761
|
+
const remaining = endsWithSeparator ? '' : (parts[parts.length - 1] || '');
|
|
2762
|
+
return { tokensToAdd, remaining };
|
|
2763
|
+
}
|
|
2764
|
+
addToken(raw) {
|
|
2765
|
+
const token = (raw || '').trim();
|
|
2766
|
+
if (!this.chips || !this.multiSelect)
|
|
2767
|
+
return;
|
|
2768
|
+
if (!token)
|
|
2769
|
+
return;
|
|
2770
|
+
const match = this.data.find((d) => (d.label || '').trim().toLowerCase() === token.toLowerCase());
|
|
2771
|
+
const item = match ?? { id: token, label: token, value: token };
|
|
2772
|
+
if (this.matchSelection && !match) {
|
|
2773
|
+
this.query = '';
|
|
2774
|
+
return;
|
|
2218
2775
|
}
|
|
2776
|
+
if (this.selected.some((s) => s.id === item.id)) {
|
|
2777
|
+
this.query = '';
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
this.selected = [...this.selected, item];
|
|
2781
|
+
this.onAdd.emit(item);
|
|
2782
|
+
this.propagateControlValue();
|
|
2783
|
+
this.selectedItems.emit(this.selected);
|
|
2784
|
+
this.selectionChange.emit(this.selected);
|
|
2785
|
+
this.query = '';
|
|
2786
|
+
this.keepOpenOnEmpty = true;
|
|
2787
|
+
this.applyFilter('');
|
|
2219
2788
|
}
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
(
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2789
|
+
propagateControlValue() {
|
|
2790
|
+
if (this.multiSelect) {
|
|
2791
|
+
const next = this.selected.map((item) => (item.value !== undefined ? item.value : item));
|
|
2792
|
+
this.controlValue = next;
|
|
2793
|
+
this.onControlChange(next);
|
|
2794
|
+
return;
|
|
2795
|
+
}
|
|
2796
|
+
const first = this.selected[0];
|
|
2797
|
+
const next = first ? (first.value !== undefined ? first.value : first) : null;
|
|
2798
|
+
this.controlValue = next;
|
|
2799
|
+
this.onControlChange(next);
|
|
2800
|
+
}
|
|
2801
|
+
coerceToItem(value) {
|
|
2802
|
+
if (value == null)
|
|
2803
|
+
return null;
|
|
2804
|
+
if (typeof value === 'object' && value.id != null && value.label != null) {
|
|
2805
|
+
return value;
|
|
2806
|
+
}
|
|
2807
|
+
const match = this.data.find((d) => d.value === value || d.id === value || (d.label || '').toLowerCase() === `${value}`.toLowerCase());
|
|
2808
|
+
if (match)
|
|
2809
|
+
return match;
|
|
2810
|
+
return { id: `${value}`, label: `${value}`, value };
|
|
2811
|
+
}
|
|
2812
|
+
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 });
|
|
2813
|
+
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", 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: [
|
|
2814
|
+
{
|
|
2815
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2816
|
+
useExisting: forwardRef(() => NgbTypeaheadComponent),
|
|
2817
|
+
multi: true,
|
|
2818
|
+
},
|
|
2819
|
+
], 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: `
|
|
2820
|
+
<div class="typeahead-root">
|
|
2821
|
+
<div class="input-group mb-2">
|
|
2822
|
+
<ng-container *ngIf="chips && multiSelect; else plainInput">
|
|
2823
|
+
<div class="form-control typeahead-chips-control" (click)="disabled ? null : focusInput()">
|
|
2824
|
+
<ngb-chips
|
|
2825
|
+
[items]="selected"
|
|
2826
|
+
[removable]="true"
|
|
2827
|
+
(remove)="removeSelected($event)"
|
|
2828
|
+
ariaLabel="Selected items"
|
|
2829
|
+
></ngb-chips>
|
|
2830
|
+
<input
|
|
2831
|
+
#inputEl
|
|
2832
|
+
type="text"
|
|
2833
|
+
[disabled]="disabled"
|
|
2834
|
+
[attr.placeholder]="selected.length ? '' : (i18n?.placeholder || 'Type to search')"
|
|
2835
|
+
[value]="query"
|
|
2836
|
+
(input)="onNativeInput($event)"
|
|
2837
|
+
(focus)="onInputFocus($event)"
|
|
2838
|
+
(blur)="onInputBlur($event)"
|
|
2839
|
+
(keydown)="onKeydown($event)"
|
|
2840
|
+
(keyup)="onKeyup($event)"
|
|
2841
|
+
aria-autocomplete="list"
|
|
2842
|
+
role="combobox"
|
|
2843
|
+
[attr.aria-expanded]="overlayVisible"
|
|
2844
|
+
[attr.aria-controls]="overlayId"
|
|
2845
|
+
[attr.aria-activedescendant]="activeDescendantId"
|
|
2846
|
+
/>
|
|
2847
|
+
</div>
|
|
2848
|
+
</ng-container>
|
|
2849
|
+
<ng-template #plainInput>
|
|
2850
|
+
<input
|
|
2851
|
+
#inputEl
|
|
2852
|
+
type="text"
|
|
2853
|
+
class="form-control"
|
|
2854
|
+
[disabled]="disabled"
|
|
2855
|
+
[attr.placeholder]="i18n?.placeholder || 'Type to search'"
|
|
2856
|
+
[value]="displayQuery"
|
|
2857
|
+
(input)="onNativeInput($event)"
|
|
2858
|
+
(focus)="onInputFocus($event)"
|
|
2859
|
+
(blur)="onInputBlur($event)"
|
|
2860
|
+
(keydown)="onKeydown($event)"
|
|
2861
|
+
(keyup)="onKeyup($event)"
|
|
2862
|
+
aria-autocomplete="list"
|
|
2863
|
+
role="combobox"
|
|
2864
|
+
[attr.aria-expanded]="overlayVisible"
|
|
2865
|
+
[attr.aria-controls]="overlayId"
|
|
2866
|
+
[attr.aria-activedescendant]="activeDescendantId"
|
|
2867
|
+
/>
|
|
2868
|
+
</ng-template>
|
|
2236
2869
|
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2870
|
+
<button
|
|
2871
|
+
*ngIf="showClearButton && (query || (!multiSelect && selected.length))"
|
|
2872
|
+
type="button"
|
|
2873
|
+
class="btn btn-outline-secondary"
|
|
2874
|
+
(click)="onClearClick($event)"
|
|
2875
|
+
[disabled]="disabled"
|
|
2876
|
+
[attr.aria-label]="i18n?.clear || 'Clear'"
|
|
2877
|
+
>
|
|
2878
|
+
×
|
|
2879
|
+
</button>
|
|
2880
|
+
|
|
2881
|
+
<button
|
|
2882
|
+
*ngIf="showDropdownButton"
|
|
2883
|
+
type="button"
|
|
2884
|
+
class="btn btn-outline-secondary"
|
|
2885
|
+
(click)="onDropdownButtonClick($event)"
|
|
2886
|
+
[disabled]="disabled"
|
|
2887
|
+
[attr.aria-label]="i18n?.dropdownButtonLabel || 'Toggle suggestions'"
|
|
2888
|
+
>
|
|
2889
|
+
▾
|
|
2890
|
+
</button>
|
|
2891
|
+
</div>
|
|
2892
|
+
|
|
2893
|
+
<div
|
|
2894
|
+
#scroller
|
|
2895
|
+
class="dropdown-menu w-100 p-0 typeahead-panel"
|
|
2896
|
+
[class.show]="overlayVisible"
|
|
2897
|
+
[id]="overlayId"
|
|
2898
|
+
role="listbox"
|
|
2899
|
+
(scroll)="onScroll($event)"
|
|
2253
2900
|
>
|
|
2254
|
-
<
|
|
2255
|
-
<ng-template #defaultTpl>
|
|
2256
|
-
<span>{{ item.label }}</span>
|
|
2257
|
-
<span *ngIf="multiSelect && isSelected(item)" class="badge bg-secondary">✓</span>
|
|
2258
|
-
</ng-template>
|
|
2259
|
-
</button>
|
|
2260
|
-
<div [style.height.px]="afterPadding"></div>
|
|
2901
|
+
<div [style.height.px]="beforePadding"></div>
|
|
2261
2902
|
|
|
2262
|
-
|
|
2263
|
-
|
|
2903
|
+
<button
|
|
2904
|
+
*ngFor="let item of visible; trackBy: trackById; let idx = index"
|
|
2905
|
+
type="button"
|
|
2906
|
+
class="dropdown-item"
|
|
2907
|
+
[class.active]="idx === activeIndex"
|
|
2908
|
+
[class.fw-semibold]="isSelected(item)"
|
|
2909
|
+
[attr.aria-selected]="isSelected(item)"
|
|
2910
|
+
[attr.id]="getOptionId(idx)"
|
|
2911
|
+
(click)="selectItem(item)"
|
|
2912
|
+
[disabled]="item.disabled"
|
|
2913
|
+
>
|
|
2914
|
+
<div class="typeahead-item">
|
|
2915
|
+
<span *ngIf="multiSelect" class="typeahead-item-checkbox">
|
|
2916
|
+
<input
|
|
2917
|
+
type="checkbox"
|
|
2918
|
+
class="form-check-input m-0"
|
|
2919
|
+
[checked]="isSelected(item)"
|
|
2920
|
+
[disabled]="item.disabled"
|
|
2921
|
+
tabindex="-1"
|
|
2922
|
+
aria-hidden="true"
|
|
2923
|
+
/>
|
|
2924
|
+
</span>
|
|
2925
|
+
<ng-container *ngIf="resolvedItemTemplate as tpl; else defaultTpl">
|
|
2926
|
+
<ng-container
|
|
2927
|
+
[ngTemplateOutlet]="tpl"
|
|
2928
|
+
[ngTemplateOutletContext]="{
|
|
2929
|
+
$implicit: item,
|
|
2930
|
+
item: item,
|
|
2931
|
+
query: query,
|
|
2932
|
+
selected: isSelected(item),
|
|
2933
|
+
index: idx
|
|
2934
|
+
}"
|
|
2935
|
+
></ng-container>
|
|
2936
|
+
</ng-container>
|
|
2937
|
+
<ng-template #defaultTpl>
|
|
2938
|
+
<span>{{ item.label }}</span>
|
|
2939
|
+
</ng-template>
|
|
2940
|
+
</div>
|
|
2941
|
+
</button>
|
|
2942
|
+
|
|
2943
|
+
<div [style.height.px]="afterPadding"></div>
|
|
2944
|
+
|
|
2945
|
+
<div *ngIf="showNoResults" class="dropdown-item text-muted text-center">
|
|
2946
|
+
{{ i18n?.noResults || 'No results' }}
|
|
2947
|
+
</div>
|
|
2264
2948
|
</div>
|
|
2265
|
-
</div>
|
|
2266
2949
|
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2950
|
+
<div *ngIf="multiSelect && selected.length" class="mt-2 small text-muted">
|
|
2951
|
+
{{ selectionSummary }}
|
|
2952
|
+
<button type="button" class="btn btn-link btn-sm ps-1" (click)="clearSelection()">
|
|
2953
|
+
{{ i18n?.clearSelection || 'Clear' }}
|
|
2954
|
+
</button>
|
|
2955
|
+
</div>
|
|
2272
2956
|
</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: "
|
|
2957
|
+
`, 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
2958
|
}
|
|
2275
2959
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbTypeaheadComponent, decorators: [{
|
|
2276
2960
|
type: Component,
|
|
2277
|
-
args: [{
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2961
|
+
args: [{ selector: 'ngb-typeahead', standalone: true, imports: [CommonModule, NgbChipsComponent], providers: [
|
|
2962
|
+
{
|
|
2963
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2964
|
+
useExisting: forwardRef(() => NgbTypeaheadComponent),
|
|
2965
|
+
multi: true,
|
|
2966
|
+
},
|
|
2967
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
2968
|
+
<div class="typeahead-root">
|
|
2969
|
+
<div class="input-group mb-2">
|
|
2970
|
+
<ng-container *ngIf="chips && multiSelect; else plainInput">
|
|
2971
|
+
<div class="form-control typeahead-chips-control" (click)="disabled ? null : focusInput()">
|
|
2972
|
+
<ngb-chips
|
|
2973
|
+
[items]="selected"
|
|
2974
|
+
[removable]="true"
|
|
2975
|
+
(remove)="removeSelected($event)"
|
|
2976
|
+
ariaLabel="Selected items"
|
|
2977
|
+
></ngb-chips>
|
|
2978
|
+
<input
|
|
2979
|
+
#inputEl
|
|
2980
|
+
type="text"
|
|
2981
|
+
[disabled]="disabled"
|
|
2982
|
+
[attr.placeholder]="selected.length ? '' : (i18n?.placeholder || 'Type to search')"
|
|
2983
|
+
[value]="query"
|
|
2984
|
+
(input)="onNativeInput($event)"
|
|
2985
|
+
(focus)="onInputFocus($event)"
|
|
2986
|
+
(blur)="onInputBlur($event)"
|
|
2987
|
+
(keydown)="onKeydown($event)"
|
|
2988
|
+
(keyup)="onKeyup($event)"
|
|
2989
|
+
aria-autocomplete="list"
|
|
2990
|
+
role="combobox"
|
|
2991
|
+
[attr.aria-expanded]="overlayVisible"
|
|
2992
|
+
[attr.aria-controls]="overlayId"
|
|
2993
|
+
[attr.aria-activedescendant]="activeDescendantId"
|
|
2994
|
+
/>
|
|
2995
|
+
</div>
|
|
2996
|
+
</ng-container>
|
|
2997
|
+
<ng-template #plainInput>
|
|
2998
|
+
<input
|
|
2999
|
+
#inputEl
|
|
3000
|
+
type="text"
|
|
3001
|
+
class="form-control"
|
|
3002
|
+
[disabled]="disabled"
|
|
3003
|
+
[attr.placeholder]="i18n?.placeholder || 'Type to search'"
|
|
3004
|
+
[value]="displayQuery"
|
|
3005
|
+
(input)="onNativeInput($event)"
|
|
3006
|
+
(focus)="onInputFocus($event)"
|
|
3007
|
+
(blur)="onInputBlur($event)"
|
|
3008
|
+
(keydown)="onKeydown($event)"
|
|
3009
|
+
(keyup)="onKeyup($event)"
|
|
3010
|
+
aria-autocomplete="list"
|
|
3011
|
+
role="combobox"
|
|
3012
|
+
[attr.aria-expanded]="overlayVisible"
|
|
3013
|
+
[attr.aria-controls]="overlayId"
|
|
3014
|
+
[attr.aria-activedescendant]="activeDescendantId"
|
|
3015
|
+
/>
|
|
3016
|
+
</ng-template>
|
|
2297
3017
|
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
3018
|
+
<button
|
|
3019
|
+
*ngIf="showClearButton && (query || (!multiSelect && selected.length))"
|
|
3020
|
+
type="button"
|
|
3021
|
+
class="btn btn-outline-secondary"
|
|
3022
|
+
(click)="onClearClick($event)"
|
|
3023
|
+
[disabled]="disabled"
|
|
3024
|
+
[attr.aria-label]="i18n?.clear || 'Clear'"
|
|
3025
|
+
>
|
|
3026
|
+
×
|
|
3027
|
+
</button>
|
|
3028
|
+
|
|
3029
|
+
<button
|
|
3030
|
+
*ngIf="showDropdownButton"
|
|
3031
|
+
type="button"
|
|
3032
|
+
class="btn btn-outline-secondary"
|
|
3033
|
+
(click)="onDropdownButtonClick($event)"
|
|
3034
|
+
[disabled]="disabled"
|
|
3035
|
+
[attr.aria-label]="i18n?.dropdownButtonLabel || 'Toggle suggestions'"
|
|
3036
|
+
>
|
|
3037
|
+
▾
|
|
3038
|
+
</button>
|
|
3039
|
+
</div>
|
|
3040
|
+
|
|
3041
|
+
<div
|
|
3042
|
+
#scroller
|
|
3043
|
+
class="dropdown-menu w-100 p-0 typeahead-panel"
|
|
3044
|
+
[class.show]="overlayVisible"
|
|
3045
|
+
[id]="overlayId"
|
|
3046
|
+
role="listbox"
|
|
3047
|
+
(scroll)="onScroll($event)"
|
|
2314
3048
|
>
|
|
2315
|
-
<
|
|
2316
|
-
<ng-template #defaultTpl>
|
|
2317
|
-
<span>{{ item.label }}</span>
|
|
2318
|
-
<span *ngIf="multiSelect && isSelected(item)" class="badge bg-secondary">✓</span>
|
|
2319
|
-
</ng-template>
|
|
2320
|
-
</button>
|
|
2321
|
-
<div [style.height.px]="afterPadding"></div>
|
|
3049
|
+
<div [style.height.px]="beforePadding"></div>
|
|
2322
3050
|
|
|
2323
|
-
|
|
2324
|
-
|
|
3051
|
+
<button
|
|
3052
|
+
*ngFor="let item of visible; trackBy: trackById; let idx = index"
|
|
3053
|
+
type="button"
|
|
3054
|
+
class="dropdown-item"
|
|
3055
|
+
[class.active]="idx === activeIndex"
|
|
3056
|
+
[class.fw-semibold]="isSelected(item)"
|
|
3057
|
+
[attr.aria-selected]="isSelected(item)"
|
|
3058
|
+
[attr.id]="getOptionId(idx)"
|
|
3059
|
+
(click)="selectItem(item)"
|
|
3060
|
+
[disabled]="item.disabled"
|
|
3061
|
+
>
|
|
3062
|
+
<div class="typeahead-item">
|
|
3063
|
+
<span *ngIf="multiSelect" class="typeahead-item-checkbox">
|
|
3064
|
+
<input
|
|
3065
|
+
type="checkbox"
|
|
3066
|
+
class="form-check-input m-0"
|
|
3067
|
+
[checked]="isSelected(item)"
|
|
3068
|
+
[disabled]="item.disabled"
|
|
3069
|
+
tabindex="-1"
|
|
3070
|
+
aria-hidden="true"
|
|
3071
|
+
/>
|
|
3072
|
+
</span>
|
|
3073
|
+
<ng-container *ngIf="resolvedItemTemplate as tpl; else defaultTpl">
|
|
3074
|
+
<ng-container
|
|
3075
|
+
[ngTemplateOutlet]="tpl"
|
|
3076
|
+
[ngTemplateOutletContext]="{
|
|
3077
|
+
$implicit: item,
|
|
3078
|
+
item: item,
|
|
3079
|
+
query: query,
|
|
3080
|
+
selected: isSelected(item),
|
|
3081
|
+
index: idx
|
|
3082
|
+
}"
|
|
3083
|
+
></ng-container>
|
|
3084
|
+
</ng-container>
|
|
3085
|
+
<ng-template #defaultTpl>
|
|
3086
|
+
<span>{{ item.label }}</span>
|
|
3087
|
+
</ng-template>
|
|
3088
|
+
</div>
|
|
3089
|
+
</button>
|
|
3090
|
+
|
|
3091
|
+
<div [style.height.px]="afterPadding"></div>
|
|
3092
|
+
|
|
3093
|
+
<div *ngIf="showNoResults" class="dropdown-item text-muted text-center">
|
|
3094
|
+
{{ i18n?.noResults || 'No results' }}
|
|
3095
|
+
</div>
|
|
2325
3096
|
</div>
|
|
2326
|
-
</div>
|
|
2327
3097
|
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
3098
|
+
<div *ngIf="multiSelect && selected.length" class="mt-2 small text-muted">
|
|
3099
|
+
{{ selectionSummary }}
|
|
3100
|
+
<button type="button" class="btn btn-link btn-sm ps-1" (click)="clearSelection()">
|
|
3101
|
+
{{ i18n?.clearSelection || 'Clear' }}
|
|
3102
|
+
</button>
|
|
3103
|
+
</div>
|
|
2333
3104
|
</div>
|
|
2334
|
-
`,
|
|
2335
|
-
|
|
2336
|
-
}], propDecorators: { data: [{
|
|
3105
|
+
`, 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"] }]
|
|
3106
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { data: [{
|
|
2337
3107
|
type: Input
|
|
2338
3108
|
}], debounceTime: [{
|
|
2339
3109
|
type: Input
|
|
@@ -2345,11 +3115,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2345
3115
|
type: Input
|
|
2346
3116
|
}], multiSelect: [{
|
|
2347
3117
|
type: Input
|
|
2348
|
-
}],
|
|
3118
|
+
}], matchSelection: [{
|
|
3119
|
+
type: Input
|
|
3120
|
+
}], showDropdownButton: [{
|
|
3121
|
+
type: Input
|
|
3122
|
+
}], showClearButton: [{
|
|
3123
|
+
type: Input
|
|
3124
|
+
}], updateOnBlur: [{
|
|
3125
|
+
type: Input
|
|
3126
|
+
}], updateOnTab: [{
|
|
3127
|
+
type: Input
|
|
3128
|
+
}], separator: [{
|
|
3129
|
+
type: Input
|
|
3130
|
+
}], chips: [{
|
|
2349
3131
|
type: Input
|
|
2350
3132
|
}], itemTemplate: [{
|
|
3133
|
+
type: Input
|
|
3134
|
+
}], i18n: [{
|
|
3135
|
+
type: Input
|
|
3136
|
+
}], projectedItemTemplate: [{
|
|
2351
3137
|
type: ContentChild,
|
|
2352
3138
|
args: [TemplateRef]
|
|
3139
|
+
}], completeMethod: [{
|
|
3140
|
+
type: Output
|
|
3141
|
+
}], onSelect: [{
|
|
3142
|
+
type: Output
|
|
3143
|
+
}], onUnselect: [{
|
|
3144
|
+
type: Output
|
|
3145
|
+
}], onAdd: [{
|
|
3146
|
+
type: Output
|
|
3147
|
+
}], onFocus: [{
|
|
3148
|
+
type: Output
|
|
3149
|
+
}], onBlur: [{
|
|
3150
|
+
type: Output
|
|
3151
|
+
}], onDropdownClick: [{
|
|
3152
|
+
type: Output
|
|
3153
|
+
}], onClear: [{
|
|
3154
|
+
type: Output
|
|
3155
|
+
}], onInputKeydown: [{
|
|
3156
|
+
type: Output
|
|
3157
|
+
}], onKeyUp: [{
|
|
3158
|
+
type: Output
|
|
3159
|
+
}], onShow: [{
|
|
3160
|
+
type: Output
|
|
3161
|
+
}], onHide: [{
|
|
3162
|
+
type: Output
|
|
3163
|
+
}], onLazyLoad: [{
|
|
3164
|
+
type: Output
|
|
2353
3165
|
}], selectedItems: [{
|
|
2354
3166
|
type: Output
|
|
2355
3167
|
}], selectionChange: [{
|
|
@@ -2363,10 +3175,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2363
3175
|
args: ['scroller', { static: true }]
|
|
2364
3176
|
}], inputEl: [{
|
|
2365
3177
|
type: ViewChild,
|
|
2366
|
-
args: ['inputEl'
|
|
3178
|
+
args: ['inputEl']
|
|
2367
3179
|
}], itemButtons: [{
|
|
2368
3180
|
type: ViewChildren,
|
|
2369
3181
|
args: ['itemButton']
|
|
3182
|
+
}], onDocumentMouseDown: [{
|
|
3183
|
+
type: HostListener,
|
|
3184
|
+
args: ['document:mousedown', ['$event']]
|
|
3185
|
+
}], onDocumentFocusIn: [{
|
|
3186
|
+
type: HostListener,
|
|
3187
|
+
args: ['document:focusin', ['$event']]
|
|
2370
3188
|
}] } });
|
|
2371
3189
|
|
|
2372
3190
|
class NgbTreeComponent {
|
|
@@ -2374,6 +3192,10 @@ class NgbTreeComponent {
|
|
|
2374
3192
|
type = 'text';
|
|
2375
3193
|
showCheckbox = false;
|
|
2376
3194
|
i18n;
|
|
3195
|
+
expandIcon = 'bi-caret-right-fill';
|
|
3196
|
+
collapseIcon = 'bi-caret-down-fill';
|
|
3197
|
+
plusIcon = 'bi-file-plus-fill';
|
|
3198
|
+
minusIcon = 'bi-file-minus-fill';
|
|
2377
3199
|
expand = new EventEmitter();
|
|
2378
3200
|
collapse = new EventEmitter();
|
|
2379
3201
|
expandAll = new EventEmitter();
|
|
@@ -2454,7 +3276,7 @@ class NgbTreeComponent {
|
|
|
2454
3276
|
return acc;
|
|
2455
3277
|
}
|
|
2456
3278
|
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: `
|
|
3279
|
+
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
3280
|
<div class="d-flex gap-2 mb-2">
|
|
2459
3281
|
<button type="button" class="btn btn-sm btn-outline-secondary" (click)="expandAllNodes()" [attr.aria-label]="i18n?.expandAll || 'Expand all'">
|
|
2460
3282
|
{{ i18n?.expandAll || 'Expand all' }}
|
|
@@ -2477,21 +3299,22 @@ class NgbTreeComponent {
|
|
|
2477
3299
|
[attr.aria-expanded]="hasChildren(node) ? !!node.expanded : null"
|
|
2478
3300
|
[attr.aria-level]="level"
|
|
2479
3301
|
>
|
|
2480
|
-
<
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
<span *ngIf="type
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
3302
|
+
<ng-container *ngIf="hasChildren(node); else leafSpacer">
|
|
3303
|
+
<button
|
|
3304
|
+
#nodeBtn
|
|
3305
|
+
type="button"
|
|
3306
|
+
class="btn btn-sm px-1"
|
|
3307
|
+
(click)="toggleNode(node)"
|
|
3308
|
+
(keydown)="onNodeKeydown($event, node)"
|
|
3309
|
+
[attr.aria-label]="(node.expanded ? i18n?.collapse || 'Collapse' : i18n?.expand || 'Expand') + ' ' + node.label"
|
|
3310
|
+
>
|
|
3311
|
+
<span *ngIf="type === 'json'" class="bi" [ngClass]="node.expanded ? minusIcon : plusIcon" aria-hidden="true"></span>
|
|
3312
|
+
<span *ngIf="type !== 'json'" class="bi" [ngClass]="node.expanded ? collapseIcon : expandIcon" aria-hidden="true"></span>
|
|
3313
|
+
</button>
|
|
3314
|
+
</ng-container>
|
|
3315
|
+
<ng-template #leafSpacer>
|
|
3316
|
+
<span class="d-inline-block px-1" style="width: 1.5rem;"></span>
|
|
3317
|
+
</ng-template>
|
|
2495
3318
|
|
|
2496
3319
|
<label class="form-check d-inline-flex align-items-center gap-2 flex-grow-1 mb-0">
|
|
2497
3320
|
<input
|
|
@@ -2517,7 +3340,7 @@ class NgbTreeComponent {
|
|
|
2517
3340
|
</ng-container>
|
|
2518
3341
|
</ul>
|
|
2519
3342
|
</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 });
|
|
3343
|
+
`, 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
3344
|
}
|
|
2522
3345
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgbTreeComponent, decorators: [{
|
|
2523
3346
|
type: Component,
|
|
@@ -2549,21 +3372,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2549
3372
|
[attr.aria-expanded]="hasChildren(node) ? !!node.expanded : null"
|
|
2550
3373
|
[attr.aria-level]="level"
|
|
2551
3374
|
>
|
|
2552
|
-
<
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
<span *ngIf="type
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
3375
|
+
<ng-container *ngIf="hasChildren(node); else leafSpacer">
|
|
3376
|
+
<button
|
|
3377
|
+
#nodeBtn
|
|
3378
|
+
type="button"
|
|
3379
|
+
class="btn btn-sm px-1"
|
|
3380
|
+
(click)="toggleNode(node)"
|
|
3381
|
+
(keydown)="onNodeKeydown($event, node)"
|
|
3382
|
+
[attr.aria-label]="(node.expanded ? i18n?.collapse || 'Collapse' : i18n?.expand || 'Expand') + ' ' + node.label"
|
|
3383
|
+
>
|
|
3384
|
+
<span *ngIf="type === 'json'" class="bi" [ngClass]="node.expanded ? minusIcon : plusIcon" aria-hidden="true"></span>
|
|
3385
|
+
<span *ngIf="type !== 'json'" class="bi" [ngClass]="node.expanded ? collapseIcon : expandIcon" aria-hidden="true"></span>
|
|
3386
|
+
</button>
|
|
3387
|
+
</ng-container>
|
|
3388
|
+
<ng-template #leafSpacer>
|
|
3389
|
+
<span class="d-inline-block px-1" style="width: 1.5rem;"></span>
|
|
3390
|
+
</ng-template>
|
|
2567
3391
|
|
|
2568
3392
|
<label class="form-check d-inline-flex align-items-center gap-2 flex-grow-1 mb-0">
|
|
2569
3393
|
<input
|
|
@@ -2599,6 +3423,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2599
3423
|
type: Input
|
|
2600
3424
|
}], i18n: [{
|
|
2601
3425
|
type: Input
|
|
3426
|
+
}], expandIcon: [{
|
|
3427
|
+
type: Input
|
|
3428
|
+
}], collapseIcon: [{
|
|
3429
|
+
type: Input
|
|
3430
|
+
}], plusIcon: [{
|
|
3431
|
+
type: Input
|
|
3432
|
+
}], minusIcon: [{
|
|
3433
|
+
type: Input
|
|
2602
3434
|
}], expand: [{
|
|
2603
3435
|
type: Output
|
|
2604
3436
|
}], collapse: [{
|
|
@@ -2620,5 +3452,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
2620
3452
|
* Generated bundle index. Do not edit.
|
|
2621
3453
|
*/
|
|
2622
3454
|
|
|
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 };
|
|
3455
|
+
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
3456
|
//# sourceMappingURL=angular-bootstrap-ngbootstrap.mjs.map
|