@lucca-front/ng 22.0.5 → 22.1.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/lucca-front-ng-activity-feed.mjs +12 -9
- package/fesm2022/lucca-front-ng-activity-feed.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-approbation-inbox.mjs +1 -1
- package/fesm2022/lucca-front-ng-approbation-inbox.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-callout.mjs +1 -1
- package/fesm2022/lucca-front-ng-callout.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select.mjs +236 -8
- package/fesm2022/lucca-front-ng-core-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core.mjs +5 -1
- package/fesm2022/lucca-front-ng-core.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-data-table.mjs +2 -2
- package/fesm2022/lucca-front-ng-data-table.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-date2.mjs +217 -159
- package/fesm2022/lucca-front-ng-date2.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-dialog.mjs +2 -2
- package/fesm2022/lucca-front-ng-dialog.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-fancy-box.mjs +47 -24
- package/fesm2022/lucca-front-ng-fancy-box.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-file-upload.mjs +1 -1
- package/fesm2022/lucca-front-ng-file-upload.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-filter-pills-core.mjs +55 -0
- package/fesm2022/lucca-front-ng-filter-pills-core.mjs.map +1 -0
- package/fesm2022/lucca-front-ng-filter-pills.mjs +74 -69
- package/fesm2022/lucca-front-ng-filter-pills.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-form-field.mjs +37 -5
- package/fesm2022/lucca-front-ng-form-field.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-form-label.mjs +1 -1
- package/fesm2022/lucca-front-ng-form-label.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-form.mjs +42 -5
- package/fesm2022/lucca-front-ng-form.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs +3 -3
- package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms.mjs +12 -6
- package/fesm2022/lucca-front-ng-forms.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-highlight-data.mjs +6 -7
- package/fesm2022/lucca-front-ng-highlight-data.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-impersonation.mjs +19 -4
- package/fesm2022/lucca-front-ng-impersonation.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-link.mjs +8 -3
- package/fesm2022/lucca-front-ng-link.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-markdown.mjs +51 -0
- package/fesm2022/lucca-front-ng-markdown.mjs.map +1 -0
- package/fesm2022/lucca-front-ng-multi-select.mjs +147 -43
- package/fesm2022/lucca-front-ng-multi-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-popover2.mjs +11 -5
- package/fesm2022/lucca-front-ng-popover2.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-priority-levels.mjs +128 -0
- package/fesm2022/lucca-front-ng-priority-levels.mjs.map +1 -0
- package/fesm2022/lucca-front-ng-safe-content.mjs +5 -2
- package/fesm2022/lucca-front-ng-safe-content.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-simple-select.mjs +63 -12
- package/fesm2022/lucca-front-ng-simple-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-software-icon-wrapper.mjs +1 -1
- package/fesm2022/lucca-front-ng-software-icon-wrapper.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-user-popover.mjs +3 -2
- package/fesm2022/lucca-front-ng-user-popover.mjs.map +1 -1
- package/package.json +17 -4
- package/src/components/cdk/_overlay.scss +3 -1
- package/types/lucca-front-ng-activity-feed.d.ts +3 -1
- package/types/lucca-front-ng-core-select.d.ts +90 -7
- package/types/lucca-front-ng-core.d.ts +3 -1
- package/types/lucca-front-ng-date2.d.ts +31 -5
- package/types/lucca-front-ng-fancy-box.d.ts +29 -12
- package/types/lucca-front-ng-filter-pills-core.d.ts +69 -0
- package/types/lucca-front-ng-filter-pills.d.ts +28 -55
- package/types/lucca-front-ng-form-field.d.ts +12 -4
- package/types/lucca-front-ng-form.d.ts +7 -1
- package/types/lucca-front-ng-forms.d.ts +7 -2
- package/types/lucca-front-ng-highlight-data.d.ts +1 -2
- package/types/lucca-front-ng-impersonation.d.ts +14 -1
- package/types/lucca-front-ng-link.d.ts +5 -1
- package/types/lucca-front-ng-markdown.d.ts +24 -0
- package/types/lucca-front-ng-multi-select.d.ts +10 -1
- package/types/lucca-front-ng-popover2.d.ts +7 -1
- package/types/lucca-front-ng-priority-levels.d.ts +44 -0
- package/types/lucca-front-ng-simple-select.d.ts +4 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, Directive, InjectionToken, inject, ChangeDetectionStrategy, Component, TemplateRef, Pipe, ViewContainerRef, Injector, afterNextRender, DestroyRef,
|
|
3
|
-
import { syncInputSignal, ɵeffectWithDeps as _effectWithDeps, isNotNil, luBooleanAttribute, intlInputOptions, luOptionalNumberAttribute, isNil, PortalDirective, luNumberAttribute } from '@lucca-front/ng/core';
|
|
2
|
+
import { input, Directive, InjectionToken, inject, ChangeDetectionStrategy, Component, TemplateRef, Pipe, ViewContainerRef, Injector, afterNextRender, DestroyRef, afterRenderEffect, untracked, computed, Injectable, ElementRef, signal, model, linkedSignal, output, contentChild, viewChild, ChangeDetectorRef, forwardRef, booleanAttribute, ViewEncapsulation, effect, EventEmitter, ApplicationRef, DOCUMENT, NgZone } from '@angular/core';
|
|
3
|
+
import { syncInputSignal, ɵeffectWithDeps as _effectWithDeps, isNotNil, luBooleanAttribute, intlInputOptions, luOptionalNumberAttribute, isNil, PortalDirective, luNullableNumberAttribute, injectMediaMinBreakpoint, luNumberAttribute } from '@lucca-front/ng/core';
|
|
4
4
|
import { OverlayContainer } from '@angular/cdk/overlay';
|
|
5
5
|
import { toObservable, toSignal, takeUntilDestroyed, outputFromObservable } from '@angular/core/rxjs-interop';
|
|
6
|
-
import { FILTER_PILL_INPUT_COMPONENT, FILTER_PILL_HOST_COMPONENT } from '@lucca-front/ng/filter-pills';
|
|
6
|
+
import { FILTER_PILL_INPUT_COMPONENT, FILTER_PILL_HOST_COMPONENT } from '@lucca-front/ng/filter-pills/core';
|
|
7
|
+
import { FORM_FIELD_INSTANCE } from '@lucca-front/ng/form-field';
|
|
7
8
|
import { BehaviorSubject, skip, take, map, startWith, switchMap, of, distinctUntilChanged, observeOn, asyncScheduler, filter, EMPTY, timer, defer, catchError, defaultIfEmpty, tap, expand, scan, takeWhile, finalize, ReplaySubject, Subject } from 'rxjs';
|
|
8
9
|
import { AsyncPipe, NgTemplateOutlet } from '@angular/common';
|
|
9
10
|
import { Treeitem, OptionComponent } from '@lucca-front/ng/listbox';
|
|
@@ -268,6 +269,53 @@ function getGroupTemplateLocation(hasGrouping, clue, options, searchable = true)
|
|
|
268
269
|
}));
|
|
269
270
|
return toSignal(location$, { initialValue: hasGrouping() ? 'group-header' : 'none' });
|
|
270
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Requests the next page for as long as the panel's scroll viewport can't scroll.
|
|
274
|
+
*
|
|
275
|
+
* Pagination is driven by the scroll event: reaching the bottom of the viewport asks the consumer
|
|
276
|
+
* for the next page. A page that doesn't overflow the viewport therefore never asks for anything —
|
|
277
|
+
* there is nothing to scroll. The popover panel caps its content at 20rem, which a page of options
|
|
278
|
+
* always overflows, so this never came up; the bottom sheet is only as tall as its content instead,
|
|
279
|
+
* so a first page of a few options leaves it short of a scrollbar and pagination stops right there.
|
|
280
|
+
*
|
|
281
|
+
* So the viewport is measured again after every render and, while it still can't scroll, the next
|
|
282
|
+
* page is requested. The option count is what guards against an endless loop: a page that brought
|
|
283
|
+
* no new option — the data source is exhausted — is never requested twice. A new search landing on
|
|
284
|
+
* exactly the same count as the last requested page is the one case left unfilled, which the next
|
|
285
|
+
* scroll — or the next keystroke — resolves on its own.
|
|
286
|
+
*
|
|
287
|
+
* The request itself is deferred by a microtask: the panel's first render happens inside the sheet's
|
|
288
|
+
* own `ApplicationRef.tick()`, which `openPanel` runs *before* subscribing the select input to the
|
|
289
|
+
* panel ref, so a page requested straight from that render would be emitted into the void. A
|
|
290
|
+
* microtask lands once `openPanel` has returned, still well ahead of anything the user could do.
|
|
291
|
+
*
|
|
292
|
+
* Must be called from an injection context.
|
|
293
|
+
*/
|
|
294
|
+
function fillScrollViewport({ viewport, optionCount, loading, nextPage, }) {
|
|
295
|
+
let lastRequestedCount = null;
|
|
296
|
+
let destroyed = false;
|
|
297
|
+
inject(DestroyRef).onDestroy(() => (destroyed = true));
|
|
298
|
+
afterRenderEffect({
|
|
299
|
+
read: () => {
|
|
300
|
+
const element = viewport();
|
|
301
|
+
const count = optionCount();
|
|
302
|
+
if (!element || loading() || count === 0 || count === lastRequestedCount) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
// `scrollHeight` and `clientHeight` are both rounded, so a sub-pixel difference between
|
|
306
|
+
// them isn't a scrollbar: the same 1px tolerance as the panels' scroll handler applies.
|
|
307
|
+
if (element.scrollHeight - element.clientHeight > 1) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
lastRequestedCount = count;
|
|
311
|
+
queueMicrotask(() => {
|
|
312
|
+
if (!destroyed) {
|
|
313
|
+
untracked(nextPage);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
},
|
|
317
|
+
});
|
|
318
|
+
}
|
|
271
319
|
|
|
272
320
|
class CoreSelectKeyManager {
|
|
273
321
|
#destroyRef = inject(DestroyRef);
|
|
@@ -675,6 +723,15 @@ function accumulatedPages(ds, clue, { nextPage$, setLoading }) {
|
|
|
675
723
|
const coreSelectDefaultOptionComparer = (option1, option2) => JSON.stringify(option1) === JSON.stringify(option2);
|
|
676
724
|
const coreSelectDefaultOptionKey = (option) => option;
|
|
677
725
|
class ALuSelectInputComponent {
|
|
726
|
+
// Signal-backed because a filter pill takes the select over *after* it has rendered, and
|
|
727
|
+
// `bottomSheetMode` — which gates the trigger element itself — is computed from it.
|
|
728
|
+
#filterPillMode;
|
|
729
|
+
get filterPillMode() {
|
|
730
|
+
return this.#filterPillMode();
|
|
731
|
+
}
|
|
732
|
+
set filterPillMode(filterPillMode) {
|
|
733
|
+
this.#filterPillMode.set(filterPillMode);
|
|
734
|
+
}
|
|
678
735
|
#defaultFilterPillClearable;
|
|
679
736
|
#defaultClearable;
|
|
680
737
|
get searchable() {
|
|
@@ -751,12 +808,24 @@ class ALuSelectInputComponent {
|
|
|
751
808
|
this.overlayContainerRef = inject(OverlayContainer).getContainerElement();
|
|
752
809
|
this.labelElement = inject(SELECT_LABEL);
|
|
753
810
|
this.labelId = inject(SELECT_LABEL_ID);
|
|
811
|
+
this.formField = inject(FORM_FIELD_INSTANCE, { optional: true });
|
|
754
812
|
this.filterPillHost = inject(FILTER_PILL_HOST_COMPONENT, { optional: true });
|
|
755
|
-
|
|
813
|
+
// Signal-backed because a filter pill takes the select over *after* it has rendered, and
|
|
814
|
+
// `bottomSheetMode` — which gates the trigger element itself — is computed from it.
|
|
815
|
+
this.#filterPillMode = signal(false, /* @ts-ignore */
|
|
816
|
+
...(ngDevMode ? [{ debugName: "#filterPillMode" }] : /* istanbul ignore next */ []));
|
|
756
817
|
this.ignorePresentation = input(false, { ...(ngDevMode ? { debugName: "ignorePresentation" } : /* istanbul ignore next */ {}), transform: luBooleanAttribute });
|
|
818
|
+
/**
|
|
819
|
+
* Width of the select itself, using the same scale as the form field width
|
|
820
|
+
*/
|
|
821
|
+
this.width = input(null, { ...(ngDevMode ? { debugName: "width" } : /* istanbul ignore next */ {}), transform: (luNullableNumberAttribute) });
|
|
822
|
+
this.widthClass = computed(() => (this.width() ? `mod-width${this.width()}` : null), /* @ts-ignore */
|
|
823
|
+
...(ngDevMode ? [{ debugName: "widthClass" }] : /* istanbul ignore next */ []));
|
|
757
824
|
this.panelClosed = output();
|
|
758
825
|
this.panelOpened = output();
|
|
759
826
|
this.highlightedOption = output();
|
|
827
|
+
// Below the `S` breakpoint the trigger is a `<button>` rather than the text input, so this is only
|
|
828
|
+
// ever focused, never read as an input.
|
|
760
829
|
this.inputElementRef = viewChild('inputElement', /* @ts-ignore */
|
|
761
830
|
...(ngDevMode ? [{ debugName: "inputElementRef" }] : /* istanbul ignore next */ []));
|
|
762
831
|
this.disabled$ = new BehaviorSubject(false);
|
|
@@ -779,6 +848,29 @@ class ALuSelectInputComponent {
|
|
|
779
848
|
this.isPanelOpen$ = new BehaviorSubject(false);
|
|
780
849
|
// TODO Might be temporary, check after merging signalize PR
|
|
781
850
|
this.panelOpenSignal = toSignal(this.isPanelOpen$);
|
|
851
|
+
this.belowSmallBreakpoint = injectMediaMinBreakpoint('S', true);
|
|
852
|
+
/**
|
|
853
|
+
* Below the `S` breakpoint (800px) the panel opens as a dialog in `sheet` mode that embeds its own
|
|
854
|
+
* search input, instead of a popover anchored to the field — mirroring how filter pills move the input
|
|
855
|
+
* inside their overlay. Filter pills already provide their own overlay, so they keep their behavior.
|
|
856
|
+
*/
|
|
857
|
+
this.bottomSheetMode = computed(() => (this.belowSmallBreakpoint() ?? false) && !this.filterPillMode, /* @ts-ignore */
|
|
858
|
+
...(ngDevMode ? [{ debugName: "bottomSheetMode" }] : /* istanbul ignore next */ []));
|
|
859
|
+
/**
|
|
860
|
+
* Whether the currently open panel is a sheet, snapshotted when it opens rather than tracking
|
|
861
|
+
* `bottomSheetMode()` live: the panel's own ref (`SelectPanelSheetRef` vs `SelectPanelRef`) is
|
|
862
|
+
* chosen once at open time too, so resizing across the breakpoint while the panel stays open must
|
|
863
|
+
* not flip which surface its template renders — that surface was never actually attached as a
|
|
864
|
+
* dialog, so switching to it crashes with a missing `LuDialogRef` provider.
|
|
865
|
+
*/
|
|
866
|
+
this.panelBottomSheetMode = signal(false, /* @ts-ignore */
|
|
867
|
+
...(ngDevMode ? [{ debugName: "panelBottomSheetMode" }] : /* istanbul ignore next */ []));
|
|
868
|
+
/** Field label echoed as the bottom sheet's title, snapshotted when the sheet opens. */
|
|
869
|
+
this.panelTitle = signal('', /* @ts-ignore */
|
|
870
|
+
...(ngDevMode ? [{ debugName: "panelTitle" }] : /* istanbul ignore next */ []));
|
|
871
|
+
/** Whether that field label carries the required marker, so the sheet's title can echo it too. */
|
|
872
|
+
this.panelTitleRequired = computed(() => this.formField?.isInputRequired() ?? false, /* @ts-ignore */
|
|
873
|
+
...(ngDevMode ? [{ debugName: "panelTitleRequired" }] : /* istanbul ignore next */ []));
|
|
782
874
|
this.activeDescendant$ = new BehaviorSubject('');
|
|
783
875
|
this.manualOptions$ = new ReplaySubject(1);
|
|
784
876
|
this.overlayConfig = input({ hasBackdrop: true, backdropClass: 'cdk-overlay-transparent-backdrop' }, /* @ts-ignore */
|
|
@@ -854,6 +946,7 @@ class ALuSelectInputComponent {
|
|
|
854
946
|
})));
|
|
855
947
|
this.destroyed$ = new Subject();
|
|
856
948
|
this.injector = inject(Injector);
|
|
949
|
+
this.hostElementRef = inject(ElementRef);
|
|
857
950
|
// Re-entrancy guard: opening the panel (focus, clueChanged, overlay creation) can synchronously
|
|
858
951
|
// trigger openPanel again, which used to cause a double tap.
|
|
859
952
|
this.#isOpeningPanel = false;
|
|
@@ -865,6 +958,13 @@ class ALuSelectInputComponent {
|
|
|
865
958
|
this.manualOptions$.next(options);
|
|
866
959
|
}
|
|
867
960
|
});
|
|
961
|
+
// Rather than leaving an open panel stuck in a stale sheet/overlay style once `bottomSheetMode()`
|
|
962
|
+
// no longer matches it, close it outright — the next open picks the right style for the new breakpoint.
|
|
963
|
+
_effectWithDeps([this.bottomSheetMode], (bottomSheetMode) => {
|
|
964
|
+
if (this.isPanelOpen && bottomSheetMode !== this.panelBottomSheetMode()) {
|
|
965
|
+
this.closePanel();
|
|
966
|
+
}
|
|
967
|
+
});
|
|
868
968
|
// When options arrive asynchronously via a dataSource, dataSourceOptions changes but options doesn't.
|
|
869
969
|
// We need to reposition the panel after the DOM updates in both cases.
|
|
870
970
|
_effectWithDeps([this.dataSourceOptions], (_options, onCleanup) => {
|
|
@@ -894,6 +994,11 @@ class ALuSelectInputComponent {
|
|
|
894
994
|
this.panelRef?.close();
|
|
895
995
|
break;
|
|
896
996
|
case 'Tab':
|
|
997
|
+
// A bottom sheet is modal: its focus trap cycles Tab between the sheet's own controls, so
|
|
998
|
+
// tabbing must not close it the way leaving the field does on desktop.
|
|
999
|
+
if (this.bottomSheetMode()) {
|
|
1000
|
+
break;
|
|
1001
|
+
}
|
|
897
1002
|
// If we are in a filterpill, this will close it on tab press, but we want it to not lose any
|
|
898
1003
|
// displayed stuff and properly close on focus exit
|
|
899
1004
|
this.panelRef?.close();
|
|
@@ -976,7 +1081,17 @@ class ALuSelectInputComponent {
|
|
|
976
1081
|
}
|
|
977
1082
|
this.#isOpeningPanel = true;
|
|
978
1083
|
try {
|
|
979
|
-
this.
|
|
1084
|
+
const isSheet = this.bottomSheetMode();
|
|
1085
|
+
this.panelBottomSheetMode.set(isSheet);
|
|
1086
|
+
if (isSheet) {
|
|
1087
|
+
// The sheet shows the field label as its title and embeds its own search input (auto-focused by
|
|
1088
|
+
// `openSelectPanelSheet`); focusing the covered host input would pop the mobile keyboard on a
|
|
1089
|
+
// hidden field.
|
|
1090
|
+
this.panelTitle.set(this.resolvePanelTitle());
|
|
1091
|
+
}
|
|
1092
|
+
else {
|
|
1093
|
+
this.focusInput();
|
|
1094
|
+
}
|
|
980
1095
|
const isSearchable = this.searchable;
|
|
981
1096
|
this.isPanelOpen$.next(true);
|
|
982
1097
|
this.panelOpened.emit();
|
|
@@ -1011,6 +1126,31 @@ class ALuSelectInputComponent {
|
|
|
1011
1126
|
this.inputElementRef()?.nativeElement.focus();
|
|
1012
1127
|
}
|
|
1013
1128
|
}
|
|
1129
|
+
// The bottom sheet echoes the field label as its title. Standalone selects may be wrapped in a <label>,
|
|
1130
|
+
// but inside a form-field the label is a separate element referenced through the control's aria-labelledby.
|
|
1131
|
+
resolvePanelTitle() {
|
|
1132
|
+
if (this.labelElement) {
|
|
1133
|
+
return this.getLabelText(this.labelElement);
|
|
1134
|
+
}
|
|
1135
|
+
// The field points its own `aria-labelledby` at its value displayer, so only an actual `<label>`
|
|
1136
|
+
// counts here — otherwise a select without any label would echo its selected value as the title.
|
|
1137
|
+
// `aria-labelledby` can list several ids (label, hint, …), and some can be stale — e.g. leftover
|
|
1138
|
+
// from before the trigger was torn down and rebuilt as the breakpoint flipped between the button
|
|
1139
|
+
// and input variants — so every id is checked instead of trusting the first one to be the label.
|
|
1140
|
+
const host = this.hostElementRef.nativeElement;
|
|
1141
|
+
const labelledByIds = host.querySelector('[aria-labelledby]')?.getAttribute('aria-labelledby')?.split(' ') ?? [];
|
|
1142
|
+
const label = labelledByIds.map((id) => host.ownerDocument.getElementById(id)).find((element) => element?.tagName === 'LABEL');
|
|
1143
|
+
return label ? this.getLabelText(label) : '';
|
|
1144
|
+
}
|
|
1145
|
+
// Read the label text without its adornments (help tooltip, required marker, screen-reader-only copy)
|
|
1146
|
+
// nor, when the label wraps the select, the field's own rendered content — its selected value or the
|
|
1147
|
+
// placeholder standing in for it — so the title stays the plain field label.
|
|
1148
|
+
getLabelText(label) {
|
|
1149
|
+
const clone = label.cloneNode(true);
|
|
1150
|
+
const selectTag = this.hostElementRef.nativeElement.tagName.toLowerCase();
|
|
1151
|
+
clone.querySelectorAll(`${selectTag}, [role="button"], .pr-u-mask, .formLabel-required`).forEach((node) => node.remove());
|
|
1152
|
+
return (clone.textContent ?? '').trim();
|
|
1153
|
+
}
|
|
1014
1154
|
emptyClue() {
|
|
1015
1155
|
if (this.clue) {
|
|
1016
1156
|
this.clue = null;
|
|
@@ -1070,7 +1210,7 @@ class ALuSelectInputComponent {
|
|
|
1070
1210
|
this.isPanelOpen$.next(false);
|
|
1071
1211
|
}
|
|
1072
1212
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ALuSelectInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1073
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.1.4", type: ALuSelectInputComponent, isStandalone: true, inputs: { ignorePresentation: { classPropertyName: "ignorePresentation", publicName: "ignorePresentation", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, clearableInput: { classPropertyName: "clearableInput", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, addOptionLabelInput: { classPropertyName: "addOptionLabelInput", publicName: "addOptionLabel", isSignal: true, isRequired: false, transformFunction: null }, addOptionStrategy: { classPropertyName: "addOptionStrategy", publicName: "addOptionStrategy", isSignal: true, isRequired: false, transformFunction: null }, overlayConfig: { classPropertyName: "overlayConfig", publicName: "overlayConfig", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, optionsInput: { classPropertyName: "optionsInput", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionComparerInput: { classPropertyName: "optionComparerInput", publicName: "optionComparer", isSignal: true, isRequired: false, transformFunction: null }, optionKeyInput: { classPropertyName: "optionKeyInput", publicName: "optionKey", isSignal: true, isRequired: false, transformFunction: null }, noClueIcon: { classPropertyName: "noClueIcon", publicName: "noClueIcon", isSignal: true, isRequired: false, transformFunction: null }, inputTabindex: { classPropertyName: "inputTabindex", publicName: "inputTabindex", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, colorPicker: { classPropertyName: "colorPicker", publicName: "colorPicker", isSignal: true, isRequired: false, transformFunction: null }, optionTpl: { classPropertyName: "optionTpl", publicName: "optionTpl", isSignal: true, isRequired: false, transformFunction: null }, valueTpl: { classPropertyName: "valueTpl", publicName: "valueTpl", isSignal: true, isRequired: false, transformFunction: null }, panelHeaderTpl: { classPropertyName: "panelHeaderTpl", publicName: "panelHeaderTpl", isSignal: true, isRequired: false, transformFunction: null }, panelFooterTpl: { classPropertyName: "panelFooterTpl", publicName: "panelFooterTpl", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { panelClosed: "panelClosed", panelOpened: "panelOpened", highlightedOption: "highlightedOption", optionTpl: "optionTplChange", valueTpl: "valueTplChange", panelHeaderTpl: "panelHeaderTplChange", panelFooterTpl: "panelFooterTplChange", clueChange: "clueChange", nextPage: "nextPage", addOption: "addOption", dataSource: "dataSourceChange" }, host: { listeners: { "click": "onClickOpenPanel($event)", "keydown": "onKeyDownNavigation($event)" }, properties: { "class.colorPicker": "colorPicker()", "class.mod-compact": "compact()", "class.is-clearable": "isClearable()", "class.is-selected": "isSelectedClass", "class.is-searchFilled": "isSearchFilledClass", "class.mod-noClueIcon": "isNoClueIconClass" } }, viewQueries: [{ propertyName: "inputElementRef", first: true, predicate: ["inputElement"], descendants: true, isSignal: true }], ngImport: i0 }); }
|
|
1213
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "22.1.4", type: ALuSelectInputComponent, isStandalone: true, inputs: { ignorePresentation: { classPropertyName: "ignorePresentation", publicName: "ignorePresentation", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, clearableInput: { classPropertyName: "clearableInput", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, addOptionLabelInput: { classPropertyName: "addOptionLabelInput", publicName: "addOptionLabel", isSignal: true, isRequired: false, transformFunction: null }, addOptionStrategy: { classPropertyName: "addOptionStrategy", publicName: "addOptionStrategy", isSignal: true, isRequired: false, transformFunction: null }, overlayConfig: { classPropertyName: "overlayConfig", publicName: "overlayConfig", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, optionsInput: { classPropertyName: "optionsInput", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionComparerInput: { classPropertyName: "optionComparerInput", publicName: "optionComparer", isSignal: true, isRequired: false, transformFunction: null }, optionKeyInput: { classPropertyName: "optionKeyInput", publicName: "optionKey", isSignal: true, isRequired: false, transformFunction: null }, noClueIcon: { classPropertyName: "noClueIcon", publicName: "noClueIcon", isSignal: true, isRequired: false, transformFunction: null }, inputTabindex: { classPropertyName: "inputTabindex", publicName: "inputTabindex", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, colorPicker: { classPropertyName: "colorPicker", publicName: "colorPicker", isSignal: true, isRequired: false, transformFunction: null }, optionTpl: { classPropertyName: "optionTpl", publicName: "optionTpl", isSignal: true, isRequired: false, transformFunction: null }, valueTpl: { classPropertyName: "valueTpl", publicName: "valueTpl", isSignal: true, isRequired: false, transformFunction: null }, panelHeaderTpl: { classPropertyName: "panelHeaderTpl", publicName: "panelHeaderTpl", isSignal: true, isRequired: false, transformFunction: null }, panelFooterTpl: { classPropertyName: "panelFooterTpl", publicName: "panelFooterTpl", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { panelClosed: "panelClosed", panelOpened: "panelOpened", highlightedOption: "highlightedOption", optionTpl: "optionTplChange", valueTpl: "valueTplChange", panelHeaderTpl: "panelHeaderTplChange", panelFooterTpl: "panelFooterTplChange", clueChange: "clueChange", nextPage: "nextPage", addOption: "addOption", dataSource: "dataSourceChange" }, host: { listeners: { "click": "onClickOpenPanel($event)", "keydown": "onKeyDownNavigation($event)" }, properties: { "class.colorPicker": "colorPicker()", "class.mod-compact": "compact()", "class.is-clearable": "isClearable()", "class.is-selected": "isSelectedClass", "class.is-searchFilled": "isSearchFilledClass", "class.mod-noClueIcon": "isNoClueIconClass", "class": "widthClass()" } }, viewQueries: [{ propertyName: "inputElementRef", first: true, predicate: ["inputElement"], descendants: true, isSignal: true }], ngImport: i0 }); }
|
|
1074
1214
|
}
|
|
1075
1215
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: ALuSelectInputComponent, decorators: [{
|
|
1076
1216
|
type: Directive,
|
|
@@ -1082,11 +1222,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1082
1222
|
'[class.is-selected]': 'isSelectedClass',
|
|
1083
1223
|
'[class.is-searchFilled]': 'isSearchFilledClass',
|
|
1084
1224
|
'[class.mod-noClueIcon]': 'isNoClueIconClass',
|
|
1225
|
+
'[class]': 'widthClass()',
|
|
1085
1226
|
'(click)': 'onClickOpenPanel($event)',
|
|
1086
1227
|
'(keydown)': 'onKeyDownNavigation($event)',
|
|
1087
1228
|
},
|
|
1088
1229
|
}]
|
|
1089
|
-
}], ctorParameters: () => [], propDecorators: { ignorePresentation: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignorePresentation", required: false }] }], panelClosed: [{ type: i0.Output, args: ["panelClosed"] }], panelOpened: [{ type: i0.Output, args: ["panelOpened"] }], highlightedOption: [{ type: i0.Output, args: ["highlightedOption"] }], inputElementRef: [{ type: i0.ViewChild, args: ['inputElement', { isSignal: true }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], clearableInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], addOptionLabelInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "addOptionLabel", required: false }] }], addOptionStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "addOptionStrategy", required: false }] }], overlayConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayConfig", required: false }] }], loadingInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], optionsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionComparerInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionComparer", required: false }] }], optionKeyInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionKey", required: false }] }], noClueIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "noClueIcon", required: false }] }], inputTabindex: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputTabindex", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], colorPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorPicker", required: false }] }], optionTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionTpl", required: false }] }, { type: i0.Output, args: ["optionTplChange"] }], valueTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueTpl", required: false }] }, { type: i0.Output, args: ["valueTplChange"] }], panelHeaderTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelHeaderTpl", required: false }] }, { type: i0.Output, args: ["panelHeaderTplChange"] }], panelFooterTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelFooterTpl", required: false }] }, { type: i0.Output, args: ["panelFooterTplChange"] }], clueChange: [{ type: i0.Output, args: ["clueChange"] }], nextPage: [{ type: i0.Output, args: ["nextPage"] }], addOption: [{ type: i0.Output, args: ["addOption"] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }, { type: i0.Output, args: ["dataSourceChange"] }] } });
|
|
1230
|
+
}], ctorParameters: () => [], propDecorators: { ignorePresentation: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignorePresentation", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], panelClosed: [{ type: i0.Output, args: ["panelClosed"] }], panelOpened: [{ type: i0.Output, args: ["panelOpened"] }], highlightedOption: [{ type: i0.Output, args: ["highlightedOption"] }], inputElementRef: [{ type: i0.ViewChild, args: ['inputElement', { isSignal: true }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], clearableInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], addOptionLabelInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "addOptionLabel", required: false }] }], addOptionStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "addOptionStrategy", required: false }] }], overlayConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayConfig", required: false }] }], loadingInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], optionsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionComparerInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionComparer", required: false }] }], optionKeyInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionKey", required: false }] }], noClueIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "noClueIcon", required: false }] }], inputTabindex: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputTabindex", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], colorPicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorPicker", required: false }] }], optionTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionTpl", required: false }] }, { type: i0.Output, args: ["optionTplChange"] }], valueTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueTpl", required: false }] }, { type: i0.Output, args: ["valueTplChange"] }], panelHeaderTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelHeaderTpl", required: false }] }, { type: i0.Output, args: ["panelHeaderTplChange"] }], panelFooterTpl: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelFooterTpl", required: false }] }, { type: i0.Output, args: ["panelFooterTplChange"] }], clueChange: [{ type: i0.Output, args: ["clueChange"] }], nextPage: [{ type: i0.Output, args: ["nextPage"] }], addOption: [{ type: i0.Output, args: ["addOption"] }], dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }, { type: i0.Output, args: ["dataSourceChange"] }] } });
|
|
1090
1231
|
|
|
1091
1232
|
let selectId = 0;
|
|
1092
1233
|
function selectIdFactory() {
|
|
@@ -1252,6 +1393,93 @@ class LuSelectPanelRef {
|
|
|
1252
1393
|
}
|
|
1253
1394
|
}
|
|
1254
1395
|
|
|
1396
|
+
/**
|
|
1397
|
+
* Opens a select panel as a bottom sheet.
|
|
1398
|
+
*
|
|
1399
|
+
* Below the `S` breakpoint the panel stops being a popover anchored to the field and becomes a modal
|
|
1400
|
+
* surface pinned to the bottom of the viewport. That surface already exists as the dialog's `sheet`
|
|
1401
|
+
* mode — backdrop, blocked page scroll, focus trap, focus restoration and close button all come with
|
|
1402
|
+
* it — so the panel is opened as a dialog instead of as a bespoke overlay.
|
|
1403
|
+
*
|
|
1404
|
+
* The opening animation is disabled (`mod-select`, styled by the select packages themselves — see their
|
|
1405
|
+
* `sheet` mixin) and the search input is focused by hand instead of through CDK's `autoFocus`. iOS
|
|
1406
|
+
* Safari only raises the virtual keyboard for a `focus()` call made synchronously inside the tap that
|
|
1407
|
+
* triggered it; CDK's own autofocus defers the actual `focus()` through `afterNextRender`, which always
|
|
1408
|
+
* lands after that window has closed, so the keyboard silently never opens. Forcing a render with
|
|
1409
|
+
* `ApplicationRef.tick()` right here — still inside the same synchronous call stack as the tap — makes
|
|
1410
|
+
* the search input exist in the DOM in time to focus it for real, and skipping the animation keeps the
|
|
1411
|
+
* sheet from visibly jumping once the keyboard's own viewport resize kicks in immediately after.
|
|
1412
|
+
*
|
|
1413
|
+
* @param dialogService the dialog service provided alongside the select input
|
|
1414
|
+
* @param panel the panel component to render inside the sheet
|
|
1415
|
+
* @param injector the injector carrying the panel ref and the select input for the panel
|
|
1416
|
+
* @param ariaLabel names the sheet, so it stays named even before its header has rendered
|
|
1417
|
+
*/
|
|
1418
|
+
function openSelectPanelSheet(dialogService, panel, injector, ariaLabel) {
|
|
1419
|
+
const config = {
|
|
1420
|
+
content: panel,
|
|
1421
|
+
mode: 'sheet',
|
|
1422
|
+
size: 'maxContent',
|
|
1423
|
+
ariaLabel: ariaLabel || undefined,
|
|
1424
|
+
// `mod-select` lets the select packages scope their own dialog header tweaks (centered title,
|
|
1425
|
+
// close button pulled out of flow, no opening animation) without reaching into the generic
|
|
1426
|
+
// dialog styles.
|
|
1427
|
+
panelClasses: ['mod-select'],
|
|
1428
|
+
// The panel ref and the select input reach the panel through this injector: the dialog's own
|
|
1429
|
+
// `providers` hook is reserved by the service for `LuDialogRef`. `autoFocus: false` disables
|
|
1430
|
+
// CDK's own deferred autofocus — the search input is focused by hand right below instead.
|
|
1431
|
+
cdkConfigOverride: { injector, autoFocus: false },
|
|
1432
|
+
};
|
|
1433
|
+
const dialogRef = dialogService.open(config);
|
|
1434
|
+
injector.get(ApplicationRef).tick();
|
|
1435
|
+
const searchInput = dialogRef.cdkRef.overlayRef.overlayElement.querySelector('.textField-input-value');
|
|
1436
|
+
searchInput?.focus();
|
|
1437
|
+
trackVisibleViewport(dialogRef);
|
|
1438
|
+
return dialogRef;
|
|
1439
|
+
}
|
|
1440
|
+
/**
|
|
1441
|
+
* Keeps `--components-dialog-visibleViewportBlockSize` and `--components-dialog-insetBlockEnd`
|
|
1442
|
+
* in sync with the visual viewport for as long as the sheet stays open.
|
|
1443
|
+
*
|
|
1444
|
+
* iOS doesn't shrink the layout viewport when the on-screen keyboard opens — only the visual one — so
|
|
1445
|
+
* a sheet pinned with a plain `bottom: 0` stays anchored to the bottom of the full, keyboard-unaware
|
|
1446
|
+
* layout viewport, which is now hidden behind the keyboard: most of the sheet renders underneath it,
|
|
1447
|
+
* clamped height or not. Nudging `bottom` up by the amount the keyboard currently obscures — on top of
|
|
1448
|
+
* clamping the max height — keeps the sheet entirely above the keyboard, using all the space that's
|
|
1449
|
+
* actually visible, instead of a second, outer page scroll on top of the listbox's own.
|
|
1450
|
+
*
|
|
1451
|
+
* Set on the sheet's own overlay element rather than `document.documentElement`: these custom properties
|
|
1452
|
+
* are also read by any other dialog in `mode: 'sheet'` (e.g. approbation-inbox's), and a document-wide
|
|
1453
|
+
* value would leak this select's keyboard tracking onto an unrelated sheet stacked underneath it.
|
|
1454
|
+
*/
|
|
1455
|
+
function trackVisibleViewport(dialogRef) {
|
|
1456
|
+
const viewport = window.visualViewport;
|
|
1457
|
+
if (!viewport) {
|
|
1458
|
+
return;
|
|
1459
|
+
}
|
|
1460
|
+
const style = dialogRef.cdkRef.overlayRef.overlayElement.style;
|
|
1461
|
+
const update = () => {
|
|
1462
|
+
style.setProperty('--components-dialog-visibleViewportBlockSize', `${viewport.height}px`);
|
|
1463
|
+
style.setProperty('--components-dialog-insetBlockEnd', `${window.innerHeight - viewport.height - viewport.offsetTop}px`);
|
|
1464
|
+
// The initially-selected option scrolls into view as soon as it's rendered (see
|
|
1465
|
+
// `scrollIntoViewOnceReady`), which — with the opening animation disabled — happens before the
|
|
1466
|
+
// keyboard has finished opening and before the resize above has clamped the sheet down to its
|
|
1467
|
+
// final size. That earlier scroll position is stale once the sheet's own geometry has changed
|
|
1468
|
+
// size underneath it, so it's redone here on every viewport update, landing correctly once the
|
|
1469
|
+
// keyboard settles.
|
|
1470
|
+
dialogRef.cdkRef.overlayRef.overlayElement.querySelector('.is-highlighted')?.scrollIntoView({ block: 'nearest' });
|
|
1471
|
+
};
|
|
1472
|
+
update();
|
|
1473
|
+
viewport.addEventListener('resize', update);
|
|
1474
|
+
viewport.addEventListener('scroll', update);
|
|
1475
|
+
dialogRef.closed$.pipe(take(1)).subscribe(() => {
|
|
1476
|
+
viewport.removeEventListener('resize', update);
|
|
1477
|
+
viewport.removeEventListener('scroll', update);
|
|
1478
|
+
style.removeProperty('--components-dialog-visibleViewportBlockSize');
|
|
1479
|
+
style.removeProperty('--components-dialog-insetBlockEnd');
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1255
1483
|
/**
|
|
1256
1484
|
* Tracks whether the user is currently navigating with the pointer or with the keyboard.
|
|
1257
1485
|
*
|
|
@@ -1353,5 +1581,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1353
1581
|
* Generated bundle index. Do not edit.
|
|
1354
1582
|
*/
|
|
1355
1583
|
|
|
1356
|
-
export { ALuSelectInputComponent, CORE_SELECT_API_TOTAL_COUNT_PROVIDER, CoreSelectKeyManager, LU_CORE_SELECT_TRANSLATIONS, LU_OPTION_CONTEXT, LuCoreSelectNoClueDirective, LuCoreSelectPanelHeaderDirective, LuCoreSelectTotalCountDirective, LuDisabledOptionDirective, LuDisplayerDirective, LuIsOptionSelectedPipe, LuOptionDirective, LuOptionGroupDirective, LuSelectPanelLayoutComponent, LuSelectPanelRef, LuSimpleSelectDefaultOptionComponent, SELECT_ID, SELECT_LABEL, SELECT_LABEL_ID, SELECT_PANEL_INSTANCE, TreeDisplayPipe, addAttributesOnCdkContainer, applySearchDelimiter, coreSelectDefaultOptionComparer, coreSelectDefaultOptionKey, luCoreSelectTranslations, provideLuSelectLabelsAndIds, provideOptionContext, CoreSelectPanelElement as ɵCoreSelectPanelElement, ɵIsSelectedStrategy, LuOptionComponent as ɵLuOptionComponent, LuOptionGroupPipe as ɵLuOptionGroupPipe, LuOptionOutletDirective as ɵLuOptionOutletDirective, generateGroups as ɵgenerateGroups, getGroupTemplateLocation as ɵgetGroupTemplateLocation, injectPointerNavigation as ɵinjectPointerNavigation, scrollIntoViewOnceReady as ɵscrollIntoViewOnceReady };
|
|
1584
|
+
export { ALuSelectInputComponent, CORE_SELECT_API_TOTAL_COUNT_PROVIDER, CoreSelectKeyManager, LU_CORE_SELECT_TRANSLATIONS, LU_OPTION_CONTEXT, LuCoreSelectNoClueDirective, LuCoreSelectPanelHeaderDirective, LuCoreSelectTotalCountDirective, LuDisabledOptionDirective, LuDisplayerDirective, LuIsOptionSelectedPipe, LuOptionDirective, LuOptionGroupDirective, LuSelectPanelLayoutComponent, LuSelectPanelRef, LuSimpleSelectDefaultOptionComponent, SELECT_ID, SELECT_LABEL, SELECT_LABEL_ID, SELECT_PANEL_INSTANCE, TreeDisplayPipe, addAttributesOnCdkContainer, applySearchDelimiter, coreSelectDefaultOptionComparer, coreSelectDefaultOptionKey, luCoreSelectTranslations, provideLuSelectLabelsAndIds, provideOptionContext, CoreSelectPanelElement as ɵCoreSelectPanelElement, ɵIsSelectedStrategy, LuOptionComponent as ɵLuOptionComponent, LuOptionGroupPipe as ɵLuOptionGroupPipe, LuOptionOutletDirective as ɵLuOptionOutletDirective, fillScrollViewport as ɵfillScrollViewport, generateGroups as ɵgenerateGroups, getGroupTemplateLocation as ɵgetGroupTemplateLocation, injectPointerNavigation as ɵinjectPointerNavigation, openSelectPanelSheet as ɵopenSelectPanelSheet, scrollIntoViewOnceReady as ɵscrollIntoViewOnceReady };
|
|
1357
1585
|
//# sourceMappingURL=lucca-front-ng-core-select.mjs.map
|