ngx-tethys 20.0.1-0 → 20.0.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/CHANGELOG.md +19 -2
- package/action/index.d.ts +3 -3
- package/affix/index.d.ts +1 -1
- package/alert/index.d.ts +3 -3
- package/anchor/index.d.ts +6 -12
- package/arrow-switcher/index.d.ts +6 -6
- package/autocomplete/index.d.ts +23 -28
- package/avatar/index.d.ts +9 -9
- package/back-top/index.d.ts +3 -3
- package/badge/index.d.ts +6 -6
- package/breadcrumb/index.d.ts +7 -7
- package/button/index.d.ts +19 -19
- package/calendar/index.d.ts +8 -8
- package/card/index.d.ts +6 -6
- package/carousel/index.d.ts +4 -4
- package/cascader/index.d.ts +24 -24
- package/collapse/index.d.ts +4 -4
- package/color-picker/index.d.ts +16 -16
- package/comment/index.d.ts +3 -3
- package/copy/index.d.ts +2 -2
- package/core/index.d.ts +22 -22
- package/date-picker/index.d.ts +111 -111
- package/date-range/index.d.ts +5 -5
- package/dialog/index.d.ts +18 -18
- package/divider/index.d.ts +3 -3
- package/drag-drop/index.d.ts +7 -7
- package/dropdown/index.d.ts +10 -10
- package/empty/index.d.ts +12 -12
- package/fesm2022/ngx-tethys-action.mjs +14 -12
- package/fesm2022/ngx-tethys-action.mjs.map +1 -1
- package/fesm2022/ngx-tethys-affix.mjs +7 -7
- package/fesm2022/ngx-tethys-affix.mjs.map +1 -1
- package/fesm2022/ngx-tethys-alert.mjs +10 -10
- package/fesm2022/ngx-tethys-anchor.mjs +28 -65
- package/fesm2022/ngx-tethys-anchor.mjs.map +1 -1
- package/fesm2022/ngx-tethys-arrow-switcher.mjs +7 -7
- package/fesm2022/ngx-tethys-arrow-switcher.mjs.map +1 -1
- package/fesm2022/ngx-tethys-autocomplete.mjs +48 -113
- package/fesm2022/ngx-tethys-autocomplete.mjs.map +1 -1
- package/fesm2022/ngx-tethys-avatar.mjs +23 -22
- package/fesm2022/ngx-tethys-avatar.mjs.map +1 -1
- package/fesm2022/ngx-tethys-back-top.mjs +7 -7
- package/fesm2022/ngx-tethys-badge.mjs +7 -7
- package/fesm2022/ngx-tethys-badge.mjs.map +1 -1
- package/fesm2022/ngx-tethys-breadcrumb.mjs +10 -10
- package/fesm2022/ngx-tethys-breadcrumb.mjs.map +1 -1
- package/fesm2022/ngx-tethys-button.mjs +16 -16
- package/fesm2022/ngx-tethys-button.mjs.map +1 -1
- package/fesm2022/ngx-tethys-calendar.mjs +16 -16
- package/fesm2022/ngx-tethys-calendar.mjs.map +1 -1
- package/fesm2022/ngx-tethys-card.mjs +13 -13
- package/fesm2022/ngx-tethys-card.mjs.map +1 -1
- package/fesm2022/ngx-tethys-carousel.mjs +15 -15
- package/fesm2022/ngx-tethys-carousel.mjs.map +1 -1
- package/fesm2022/ngx-tethys-cascader.mjs +41 -34
- package/fesm2022/ngx-tethys-cascader.mjs.map +1 -1
- package/fesm2022/ngx-tethys-checkbox.mjs +7 -7
- package/fesm2022/ngx-tethys-collapse.mjs +10 -10
- package/fesm2022/ngx-tethys-color-picker.mjs +65 -57
- package/fesm2022/ngx-tethys-color-picker.mjs.map +1 -1
- package/fesm2022/ngx-tethys-comment.mjs +13 -13
- package/fesm2022/ngx-tethys-copy.mjs +10 -10
- package/fesm2022/ngx-tethys-copy.mjs.map +1 -1
- package/fesm2022/ngx-tethys-core.mjs +30 -25
- package/fesm2022/ngx-tethys-core.mjs.map +1 -1
- package/fesm2022/ngx-tethys-date-picker.mjs +184 -174
- package/fesm2022/ngx-tethys-date-picker.mjs.map +1 -1
- package/fesm2022/ngx-tethys-date-range.mjs +16 -16
- package/fesm2022/ngx-tethys-date-range.mjs.map +1 -1
- package/fesm2022/ngx-tethys-dialog.mjs +24 -24
- package/fesm2022/ngx-tethys-dialog.mjs.map +1 -1
- package/fesm2022/ngx-tethys-divider.mjs +7 -7
- package/fesm2022/ngx-tethys-divider.mjs.map +1 -1
- package/fesm2022/ngx-tethys-dot.mjs +7 -7
- package/fesm2022/ngx-tethys-drag-drop.mjs +24 -24
- package/fesm2022/ngx-tethys-drag-drop.mjs.map +1 -1
- package/fesm2022/ngx-tethys-dropdown.mjs +48 -47
- package/fesm2022/ngx-tethys-dropdown.mjs.map +1 -1
- package/fesm2022/ngx-tethys-empty.mjs +13 -13
- package/fesm2022/ngx-tethys-empty.mjs.map +1 -1
- package/fesm2022/ngx-tethys-flexible-text.mjs +7 -7
- package/fesm2022/ngx-tethys-flexible-text.mjs.map +1 -1
- package/fesm2022/ngx-tethys-form.mjs +64 -61
- package/fesm2022/ngx-tethys-form.mjs.map +1 -1
- package/fesm2022/ngx-tethys-fullscreen.mjs +18 -15
- package/fesm2022/ngx-tethys-fullscreen.mjs.map +1 -1
- package/fesm2022/ngx-tethys-grid.mjs +34 -33
- package/fesm2022/ngx-tethys-grid.mjs.map +1 -1
- package/fesm2022/ngx-tethys-guider.mjs +25 -24
- package/fesm2022/ngx-tethys-guider.mjs.map +1 -1
- package/fesm2022/ngx-tethys-i18n.mjs +3 -3
- package/fesm2022/ngx-tethys-i18n.mjs.map +1 -1
- package/fesm2022/ngx-tethys-icon.mjs +15 -13
- package/fesm2022/ngx-tethys-icon.mjs.map +1 -1
- package/fesm2022/ngx-tethys-image.mjs +31 -29
- package/fesm2022/ngx-tethys-image.mjs.map +1 -1
- package/fesm2022/ngx-tethys-input-number.mjs +17 -10
- package/fesm2022/ngx-tethys-input-number.mjs.map +1 -1
- package/fesm2022/ngx-tethys-input.mjs +28 -27
- package/fesm2022/ngx-tethys-input.mjs.map +1 -1
- package/fesm2022/ngx-tethys-layout.mjs +63 -63
- package/fesm2022/ngx-tethys-layout.mjs.map +1 -1
- package/fesm2022/ngx-tethys-list.mjs +21 -18
- package/fesm2022/ngx-tethys-list.mjs.map +1 -1
- package/fesm2022/ngx-tethys-loading.mjs +7 -7
- package/fesm2022/ngx-tethys-mention.mjs +35 -31
- package/fesm2022/ngx-tethys-mention.mjs.map +1 -1
- package/fesm2022/ngx-tethys-menu.mjs +26 -26
- package/fesm2022/ngx-tethys-menu.mjs.map +1 -1
- package/fesm2022/ngx-tethys-message.mjs +24 -24
- package/fesm2022/ngx-tethys-message.mjs.map +1 -1
- package/fesm2022/ngx-tethys-nav.mjs +27 -27
- package/fesm2022/ngx-tethys-nav.mjs.map +1 -1
- package/fesm2022/ngx-tethys-notify.mjs +20 -20
- package/fesm2022/ngx-tethys-notify.mjs.map +1 -1
- package/fesm2022/ngx-tethys-pagination.mjs +18 -18
- package/fesm2022/ngx-tethys-pagination.mjs.map +1 -1
- package/fesm2022/ngx-tethys-popover.mjs +22 -21
- package/fesm2022/ngx-tethys-popover.mjs.map +1 -1
- package/fesm2022/ngx-tethys-progress.mjs +17 -17
- package/fesm2022/ngx-tethys-progress.mjs.map +1 -1
- package/fesm2022/ngx-tethys-property-operation.mjs +11 -11
- package/fesm2022/ngx-tethys-property-operation.mjs.map +1 -1
- package/fesm2022/ngx-tethys-property.mjs +12 -11
- package/fesm2022/ngx-tethys-property.mjs.map +1 -1
- package/fesm2022/ngx-tethys-radio.mjs +17 -17
- package/fesm2022/ngx-tethys-radio.mjs.map +1 -1
- package/fesm2022/ngx-tethys-rate.mjs +12 -12
- package/fesm2022/ngx-tethys-rate.mjs.map +1 -1
- package/fesm2022/ngx-tethys-resizable.mjs +21 -18
- package/fesm2022/ngx-tethys-resizable.mjs.map +1 -1
- package/fesm2022/ngx-tethys-result.mjs +11 -11
- package/fesm2022/ngx-tethys-result.mjs.map +1 -1
- package/fesm2022/ngx-tethys-segment.mjs +19 -16
- package/fesm2022/ngx-tethys-segment.mjs.map +1 -1
- package/fesm2022/ngx-tethys-select.mjs +517 -433
- package/fesm2022/ngx-tethys-select.mjs.map +1 -1
- package/fesm2022/ngx-tethys-shared.mjs +284 -258
- package/fesm2022/ngx-tethys-shared.mjs.map +1 -1
- package/fesm2022/ngx-tethys-skeleton.mjs +32 -32
- package/fesm2022/ngx-tethys-skeleton.mjs.map +1 -1
- package/fesm2022/ngx-tethys-slide.mjs +37 -36
- package/fesm2022/ngx-tethys-slide.mjs.map +1 -1
- package/fesm2022/ngx-tethys-slider.mjs +11 -11
- package/fesm2022/ngx-tethys-slider.mjs.map +1 -1
- package/fesm2022/ngx-tethys-space.mjs +10 -10
- package/fesm2022/ngx-tethys-statistic.mjs +7 -7
- package/fesm2022/ngx-tethys-statistic.mjs.map +1 -1
- package/fesm2022/ngx-tethys-stepper.mjs +22 -22
- package/fesm2022/ngx-tethys-stepper.mjs.map +1 -1
- package/fesm2022/ngx-tethys-strength.mjs +7 -7
- package/fesm2022/ngx-tethys-strength.mjs.map +1 -1
- package/fesm2022/ngx-tethys-switch.mjs +7 -7
- package/fesm2022/ngx-tethys-switch.mjs.map +1 -1
- package/fesm2022/ngx-tethys-table.mjs +28 -28
- package/fesm2022/ngx-tethys-table.mjs.map +1 -1
- package/fesm2022/ngx-tethys-tabs.mjs +13 -13
- package/fesm2022/ngx-tethys-tabs.mjs.map +1 -1
- package/fesm2022/ngx-tethys-tag.mjs +11 -11
- package/fesm2022/ngx-tethys-tag.mjs.map +1 -1
- package/fesm2022/ngx-tethys-testing.mjs +1 -1
- package/fesm2022/ngx-tethys-testing.mjs.map +1 -1
- package/fesm2022/ngx-tethys-time-picker.mjs +22 -22
- package/fesm2022/ngx-tethys-time-picker.mjs.map +1 -1
- package/fesm2022/ngx-tethys-timeline.mjs +14 -14
- package/fesm2022/ngx-tethys-timeline.mjs.map +1 -1
- package/fesm2022/ngx-tethys-tooltip.mjs +19 -16
- package/fesm2022/ngx-tethys-tooltip.mjs.map +1 -1
- package/fesm2022/ngx-tethys-transfer.mjs +15 -15
- package/fesm2022/ngx-tethys-transfer.mjs.map +1 -1
- package/fesm2022/ngx-tethys-tree-select.mjs +17 -17
- package/fesm2022/ngx-tethys-tree-select.mjs.map +1 -1
- package/fesm2022/ngx-tethys-tree.mjs +50 -43
- package/fesm2022/ngx-tethys-tree.mjs.map +1 -1
- package/fesm2022/ngx-tethys-typography.mjs +16 -16
- package/fesm2022/ngx-tethys-typography.mjs.map +1 -1
- package/fesm2022/ngx-tethys-upload.mjs +26 -25
- package/fesm2022/ngx-tethys-upload.mjs.map +1 -1
- package/fesm2022/ngx-tethys-util.mjs +11 -5
- package/fesm2022/ngx-tethys-util.mjs.map +1 -1
- package/fesm2022/ngx-tethys-vote.mjs +7 -7
- package/fesm2022/ngx-tethys-watermark.mjs +18 -15
- package/fesm2022/ngx-tethys-watermark.mjs.map +1 -1
- package/fesm2022/ngx-tethys.mjs +1 -1
- package/fesm2022/ngx-tethys.mjs.map +1 -1
- package/flexible-text/index.d.ts +5 -5
- package/form/index.d.ts +26 -22
- package/fullscreen/index.d.ts +4 -4
- package/grid/index.d.ts +12 -12
- package/guider/index.d.ts +10 -10
- package/i18n/index.d.ts +1 -1
- package/icon/index.d.ts +3 -3
- package/image/index.d.ts +12 -12
- package/input/index.d.ts +22 -22
- package/input-number/index.d.ts +4 -4
- package/layout/index.d.ts +16 -16
- package/list/index.d.ts +16 -15
- package/mention/index.d.ts +4 -4
- package/menu/index.d.ts +7 -7
- package/message/index.d.ts +5 -5
- package/nav/index.d.ts +12 -12
- package/notify/index.d.ts +1 -1
- package/package.json +1 -1
- package/pagination/index.d.ts +21 -17
- package/popover/index.d.ts +8 -8
- package/progress/index.d.ts +18 -18
- package/property/index.d.ts +6 -6
- package/property-operation/index.d.ts +3 -3
- package/radio/index.d.ts +6 -6
- package/rate/index.d.ts +5 -5
- package/resizable/index.d.ts +2 -2
- package/result/index.d.ts +8 -8
- package/schematics/testing/test-workspace.js +1 -0
- package/schematics/version.d.ts +1 -1
- package/schematics/version.js +1 -1
- package/segment/index.d.ts +9 -9
- package/select/index.d.ts +91 -76
- package/shared/index.d.ts +152 -81
- package/shared/option/styles/option.mixin.scss +0 -10
- package/shared/option/styles/select-dropdown.scss +10 -9
- package/skeleton/index.d.ts +52 -52
- package/slide/index.d.ts +5 -5
- package/slider/index.d.ts +6 -6
- package/space/index.d.ts +1 -1
- package/statistic/index.d.ts +18 -18
- package/stepper/index.d.ts +8 -8
- package/switch/index.d.ts +2 -2
- package/table/index.d.ts +24 -24
- package/tabs/index.d.ts +6 -6
- package/testing/index.d.ts +1 -1
- package/time-picker/index.d.ts +21 -21
- package/timeline/index.d.ts +8 -8
- package/tooltip/index.d.ts +12 -12
- package/transfer/index.d.ts +16 -16
- package/tree/index.d.ts +28 -28
- package/tree-select/index.d.ts +13 -13
- package/typography/index.d.ts +3 -3
- package/upload/index.d.ts +4 -4
- package/util/index.d.ts +17 -7
- package/vote/index.d.ts +2 -2
- package/watermark/index.d.ts +2 -2
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { Overlay, CdkConnectedOverlay, CdkOverlayOrigin, OverlayModule } from '@angular/cdk/overlay';
|
|
2
2
|
import { isPlatformBrowser, NgClass, NgTemplateOutlet, CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { InjectionToken, inject, NgZone, ElementRef, ChangeDetectorRef, PLATFORM_ID, input, viewChild, output, contentChild,
|
|
5
|
-
import * as i1 from '@angular/forms';
|
|
4
|
+
import { InjectionToken, inject, NgZone, ElementRef, ChangeDetectorRef, PLATFORM_ID, computed, input, numberAttribute, signal, DestroyRef, viewChild, output, contentChild, contentChildren, linkedSignal, afterRenderEffect, untracked, forwardRef, HostListener, ViewChildren, ViewChild, Input, ChangeDetectionStrategy, Component, model, NgModule } from '@angular/core';
|
|
5
|
+
import * as i1$1 from '@angular/forms';
|
|
6
6
|
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
|
|
7
7
|
import { ThyEmpty, ThyEmptyModule } from 'ngx-tethys/empty';
|
|
8
8
|
import { ThyIcon, ThyIconModule } from 'ngx-tethys/icon';
|
|
9
9
|
import { ThyInputDirective, ThyInputModule } from 'ngx-tethys/input';
|
|
10
10
|
import { ThyLoading, ThyLoadingModule } from 'ngx-tethys/loading';
|
|
11
|
-
import { ThySelectOptionGroup, ThySelectControl, ThyStopPropagationDirective,
|
|
12
|
-
import {
|
|
11
|
+
import { ThyOption, ThySelectOptionGroup, ThySelectControl, ThyStopPropagationDirective, ThyOptionRender, ThyOptionGroupRender, ThyOptionModule, ThySharedModule, ThySelectCommonModule } from 'ngx-tethys/shared';
|
|
12
|
+
import { TabIndexDisabledControlValueAccessorMixin, ThyClickDispatcher, injectPanelEmptyIcon, getFlexiblePositions, scaleXMotion, scaleYMotion, scaleMotion } from 'ngx-tethys/core';
|
|
13
|
+
import { ENTER, isFunction, coerceBooleanProperty, helpers, elementMatchClosest, SPACE, DOWN_ARROW, UP_ARROW, hasModifierKey, HOME, END, A, TAB } from 'ngx-tethys/util';
|
|
14
|
+
import { timer, Observable } from 'rxjs';
|
|
15
|
+
import { map, filter, startWith, take, distinctUntilChanged } from 'rxjs/operators';
|
|
13
16
|
import { coerceElement } from '@angular/cdk/coercion';
|
|
14
|
-
import { SelectionModel } from '@angular/cdk/collections';
|
|
15
|
-
import { TabIndexDisabledControlValueAccessorMixin, ThyClickDispatcher, injectPanelEmptyIcon, ScrollToService, getFlexiblePositions, scaleXMotion, scaleYMotion, scaleMotion } from 'ngx-tethys/core';
|
|
16
|
-
import { ENTER, isFunction, coerceBooleanProperty, elementMatchClosest, DOWN_ARROW, UP_ARROW, LEFT_ARROW, RIGHT_ARROW, SPACE, hasModifierKey, HOME, END, A, helpers, isArray } from 'ngx-tethys/util';
|
|
17
|
-
import { Subject, defer, merge, timer, Observable } from 'rxjs';
|
|
18
|
-
import { map, filter, take, switchMap, takeUntil, startWith, distinctUntilChanged } from 'rxjs/operators';
|
|
19
|
-
import { outputToObservable } from '@angular/core/rxjs-interop';
|
|
20
17
|
import { injectLocale } from 'ngx-tethys/i18n';
|
|
18
|
+
import * as i1 from '@angular/cdk/scrolling';
|
|
19
|
+
import { CdkVirtualScrollViewport, ScrollingModule, ScrollDispatcher } from '@angular/cdk/scrolling';
|
|
20
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
21
|
+
import { isUndefinedOrNull } from '@tethys/cdk/is';
|
|
21
22
|
import { useHostRenderer } from '@tethys/cdk/dom';
|
|
22
23
|
|
|
23
24
|
const THY_SELECT_SCROLL_STRATEGY = new InjectionToken('thy-select-scroll-strategy');
|
|
@@ -41,10 +42,9 @@ const THY_SELECT_CONFIG_PROVIDER = {
|
|
|
41
42
|
|
|
42
43
|
const SELECT_PANEL_MAX_HEIGHT = 300;
|
|
43
44
|
const SELECT_OPTION_MAX_HEIGHT = 40;
|
|
44
|
-
const
|
|
45
|
-
const
|
|
45
|
+
const SELECT_PANEL_PADDING_TOP = 12;
|
|
46
|
+
const SELECT_PANEL_PADDING_BOTTOM = 12;
|
|
46
47
|
const THY_SELECT_PANEL_MIN_WIDTH = 200;
|
|
47
|
-
const noop$1 = () => { };
|
|
48
48
|
/**
|
|
49
49
|
* 下拉选择组件
|
|
50
50
|
* @name thy-select,thy-custom-select
|
|
@@ -61,19 +61,19 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
61
61
|
get thyDisabled() {
|
|
62
62
|
return this.disabled;
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
event.stopPropagation();
|
|
68
|
-
}
|
|
69
|
-
this.panelOpen ? this.handleOpenKeydown(event) : this.handleClosedKeydown(event);
|
|
64
|
+
keydown(event) {
|
|
65
|
+
if (this.disabled) {
|
|
66
|
+
return;
|
|
70
67
|
}
|
|
68
|
+
if (event.keyCode === ENTER) {
|
|
69
|
+
event.stopPropagation();
|
|
70
|
+
}
|
|
71
|
+
this.handleKeydown(event);
|
|
71
72
|
}
|
|
72
73
|
get optionsChanges$() {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return this.options.toArray();
|
|
74
|
+
let previousOptions = this.optionRenders?.toArray();
|
|
75
|
+
return this.optionRenders.changes.pipe(map(data => {
|
|
76
|
+
return this.optionRenders.toArray();
|
|
77
77
|
}), filter(data => {
|
|
78
78
|
const res = previousOptions.length !== data.length || previousOptions.some((op, index) => op !== data[index]);
|
|
79
79
|
previousOptions = data;
|
|
@@ -88,9 +88,6 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
88
88
|
this.scrollStrategy = this.overlay.scrollStrategies.reposition();
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
-
get placement() {
|
|
92
|
-
return this.thyPlacement() || this.config.placement;
|
|
93
|
-
}
|
|
94
91
|
constructor() {
|
|
95
92
|
super();
|
|
96
93
|
this.ngZone = inject(NgZone);
|
|
@@ -106,25 +103,57 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
106
103
|
this.disabled = false;
|
|
107
104
|
this.mode = '';
|
|
108
105
|
this.scrollTop = 0;
|
|
109
|
-
this.modalValue = null;
|
|
110
106
|
this.defaultOffset = 4;
|
|
111
|
-
this.
|
|
107
|
+
this.dropDownClass = computed(() => {
|
|
108
|
+
const modeClass = `thy-select-dropdown-${this.isMultiple() ? 'multiple' : 'single'}`;
|
|
109
|
+
return {
|
|
110
|
+
[`thy-select-dropdown`]: true,
|
|
111
|
+
[modeClass]: true
|
|
112
|
+
};
|
|
113
|
+
}, ...(ngDevMode ? [{ debugName: "dropDownClass" }] : []));
|
|
114
|
+
this.dropDownMinWidth = computed(() => {
|
|
115
|
+
const mode = this.thyDropdownWidthMode() || this.config.dropdownWidthMode;
|
|
116
|
+
let dropdownMinWidth = null;
|
|
117
|
+
if (mode?.minWidth) {
|
|
118
|
+
dropdownMinWidth = mode.minWidth;
|
|
119
|
+
}
|
|
120
|
+
else if (mode === 'min-width') {
|
|
121
|
+
dropdownMinWidth = THY_SELECT_PANEL_MIN_WIDTH;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
dropdownMinWidth = null;
|
|
125
|
+
}
|
|
126
|
+
return dropdownMinWidth;
|
|
127
|
+
}, ...(ngDevMode ? [{ debugName: "dropDownMinWidth" }] : []));
|
|
112
128
|
/**
|
|
113
129
|
* 设置下拉框的最小宽度,默认值 `match-select`,表示与输入框的宽度一致;`min-width` 表示最小宽度为200px;支持自定义最小宽度,比如传 `{minWidth: 150}` 表示最小宽度为150px
|
|
114
130
|
* @default match-select
|
|
115
131
|
*/
|
|
116
132
|
this.thyDropdownWidthMode = input(...(ngDevMode ? [undefined, { debugName: "thyDropdownWidthMode" }] : []));
|
|
133
|
+
this.placement = computed(() => {
|
|
134
|
+
return this.thyPlacement() || this.config.placement;
|
|
135
|
+
}, ...(ngDevMode ? [{ debugName: "placement" }] : []));
|
|
136
|
+
this.dropDownPositions = computed(() => {
|
|
137
|
+
return getFlexiblePositions(this.placement(), this.defaultOffset);
|
|
138
|
+
}, ...(ngDevMode ? [{ debugName: "dropDownPositions" }] : []));
|
|
139
|
+
this.thyItemSize = input(SELECT_OPTION_MAX_HEIGHT, ...(ngDevMode ? [{ debugName: "thyItemSize", transform: value => numberAttribute(value) }] : [{ transform: value => numberAttribute(value) }]));
|
|
140
|
+
this.virtualHeight = computed(() => {
|
|
141
|
+
const maxVirtualHeight = SELECT_PANEL_MAX_HEIGHT - SELECT_PANEL_PADDING_TOP - SELECT_PANEL_PADDING_BOTTOM;
|
|
142
|
+
const height = this.filteredGroupsAndOptions().length * this.thyItemSize();
|
|
143
|
+
return Math.min(height, maxVirtualHeight);
|
|
144
|
+
}, ...(ngDevMode ? [{ debugName: "virtualHeight" }] : []));
|
|
145
|
+
/**
|
|
146
|
+
* 出现滚动条时,视觉上能看到的最大选项个数
|
|
147
|
+
*/
|
|
148
|
+
this.maxItemLength = computed(() => {
|
|
149
|
+
return Math.round(this.virtualHeight() / this.thyItemSize());
|
|
150
|
+
}, ...(ngDevMode ? [{ debugName: "maxItemLength" }] : []));
|
|
151
|
+
this.triggerRectWidth = signal(undefined, ...(ngDevMode ? [{ debugName: "triggerRectWidth" }] : []));
|
|
117
152
|
/**
|
|
118
153
|
* 手动聚焦中的标识
|
|
119
154
|
*/
|
|
120
155
|
this.manualFocusing = false;
|
|
121
|
-
this.
|
|
122
|
-
this.optionSelectionChanges = defer(() => {
|
|
123
|
-
if (this.options) {
|
|
124
|
-
return merge(...this.options.map(option => outputToObservable(option.selectionChange)));
|
|
125
|
-
}
|
|
126
|
-
return this.ngZone.onStable.asObservable().pipe(take(1), switchMap(() => this.optionSelectionChanges));
|
|
127
|
-
});
|
|
156
|
+
this.destroyRef = inject(DestroyRef);
|
|
128
157
|
this.cdkConnectedOverlay = viewChild(CdkConnectedOverlay, ...(ngDevMode ? [{ debugName: "cdkConnectedOverlay" }] : []));
|
|
129
158
|
this.panelOpen = false;
|
|
130
159
|
/**
|
|
@@ -237,70 +266,124 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
237
266
|
* 是否隐藏选择框边框
|
|
238
267
|
*/
|
|
239
268
|
this.thyBorderless = input(false, ...(ngDevMode ? [{ debugName: "thyBorderless", transform: coerceBooleanProperty }] : [{ transform: coerceBooleanProperty }]));
|
|
240
|
-
this.
|
|
241
|
-
this.
|
|
269
|
+
this.scrolledIndex = 0;
|
|
270
|
+
this.cdkVirtualScrollViewport = viewChild(CdkVirtualScrollViewport, ...(ngDevMode ? [{ debugName: "cdkVirtualScrollViewport" }] : []));
|
|
271
|
+
this.shouldActivateOption = false;
|
|
242
272
|
/**
|
|
243
273
|
* option 列表
|
|
244
274
|
*/
|
|
245
275
|
this.thyOptions = input(undefined, ...(ngDevMode ? [{ debugName: "thyOptions", transform: (value) => {
|
|
246
|
-
if (value
|
|
276
|
+
if (helpers.isUndefinedOrNull(value)) {
|
|
247
277
|
value = [];
|
|
248
278
|
}
|
|
249
|
-
this.innerOptions = value;
|
|
250
|
-
this.isReactiveDriven = true;
|
|
251
|
-
this.buildReactiveOptions();
|
|
252
279
|
return value;
|
|
253
280
|
} }] : [{
|
|
254
281
|
transform: (value) => {
|
|
255
|
-
if (value
|
|
282
|
+
if (helpers.isUndefinedOrNull(value)) {
|
|
256
283
|
value = [];
|
|
257
284
|
}
|
|
258
|
-
this.innerOptions = value;
|
|
259
|
-
this.isReactiveDriven = true;
|
|
260
|
-
this.buildReactiveOptions();
|
|
261
285
|
return value;
|
|
262
286
|
}
|
|
263
287
|
}]));
|
|
288
|
+
this.keywords = signal('', ...(ngDevMode ? [{ debugName: "keywords" }] : []));
|
|
264
289
|
/**
|
|
265
290
|
* 目前只支持多选选中项的展示,默认为空,渲染文字模板,传入tag,渲染展示模板,
|
|
266
291
|
* @default ''|tag
|
|
267
292
|
*/
|
|
268
293
|
this.thyPreset = input('', ...(ngDevMode ? [{ debugName: "thyPreset" }] : []));
|
|
269
|
-
this.
|
|
294
|
+
this.options = contentChildren(ThyOption, ...(ngDevMode ? [{ debugName: "options", descendants: true }] : [{ descendants: true }]));
|
|
295
|
+
this.groups = contentChildren(ThySelectOptionGroup, ...(ngDevMode ? [{ debugName: "groups", descendants: true }] : [{ descendants: true }]));
|
|
270
296
|
/**
|
|
271
|
-
*
|
|
297
|
+
* 所有分组和选项
|
|
298
|
+
*/
|
|
299
|
+
this.allGroupsAndOptions = signal([], ...(ngDevMode ? [{ debugName: "allGroupsAndOptions" }] : []));
|
|
300
|
+
/**
|
|
301
|
+
* 渲染的分组和选项,基于 keywords 过滤后
|
|
302
|
+
*/
|
|
303
|
+
this.filteredGroupsAndOptions = computed(() => {
|
|
304
|
+
return this.buildFilteredGroupsAndOptions();
|
|
305
|
+
}, ...(ngDevMode ? [{ debugName: "filteredGroupsAndOptions" }] : []));
|
|
306
|
+
/**
|
|
307
|
+
* 渲染的选项
|
|
272
308
|
*/
|
|
273
|
-
this.
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
this.
|
|
309
|
+
this.filteredOptions = computed(() => {
|
|
310
|
+
return this.filteredGroupsAndOptions().filter(item => item.type === 'option');
|
|
311
|
+
}, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : []));
|
|
312
|
+
this.filteredOptionsMap = computed(() => {
|
|
313
|
+
return this.filteredOptions().reduce((map, item) => {
|
|
314
|
+
if (!isUndefinedOrNull(item.value)) {
|
|
315
|
+
map.set(item.value, item);
|
|
316
|
+
}
|
|
317
|
+
return map;
|
|
318
|
+
}, new Map());
|
|
319
|
+
}, ...(ngDevMode ? [{ debugName: "filteredOptionsMap" }] : []));
|
|
320
|
+
/**
|
|
321
|
+
* 当前选中的值
|
|
322
|
+
*/
|
|
323
|
+
this.selectedValues = linkedSignal(...(ngDevMode ? [{ debugName: "selectedValues", source: () => this.thyMode(),
|
|
324
|
+
computation: () => {
|
|
325
|
+
return [];
|
|
326
|
+
} }] : [{
|
|
327
|
+
source: () => this.thyMode(),
|
|
328
|
+
computation: () => {
|
|
329
|
+
return [];
|
|
330
|
+
}
|
|
331
|
+
}]));
|
|
332
|
+
this.selectedValuesMap = computed(() => {
|
|
333
|
+
return new Map(this.selectedValues().map(value => [value, true]));
|
|
334
|
+
}, ...(ngDevMode ? [{ debugName: "selectedValuesMap" }] : []));
|
|
335
|
+
/**
|
|
336
|
+
* 传给 selectControl 指令的选中值
|
|
337
|
+
*/
|
|
338
|
+
this.selectedOptions = linkedSignal(...(ngDevMode ? [{ debugName: "selectedOptions", source: () => this.thyMode(),
|
|
339
|
+
computation: () => {
|
|
340
|
+
return this.thyMode() === 'multiple' ? [] : null;
|
|
341
|
+
} }] : [{
|
|
342
|
+
source: () => this.thyMode(),
|
|
343
|
+
computation: () => {
|
|
344
|
+
return this.thyMode() === 'multiple' ? [] : null;
|
|
345
|
+
}
|
|
346
|
+
}]));
|
|
347
|
+
this.isMultiple = computed(() => {
|
|
348
|
+
return this.thyMode() === 'multiple';
|
|
349
|
+
}, ...(ngDevMode ? [{ debugName: "isMultiple" }] : []));
|
|
350
|
+
this.empty = computed(() => {
|
|
351
|
+
return !this.selectedValues().length;
|
|
352
|
+
}, ...(ngDevMode ? [{ debugName: "empty" }] : []));
|
|
353
|
+
this.activatedValue = signal(null, ...(ngDevMode ? [{ debugName: "activatedValue" }] : []));
|
|
277
354
|
const selectConfig = this.selectConfig;
|
|
278
355
|
this.config = { ...DEFAULT_SELECT_CONFIG, ...selectConfig };
|
|
279
356
|
this.buildScrollStrategy();
|
|
280
|
-
|
|
281
|
-
|
|
357
|
+
afterRenderEffect(() => {
|
|
358
|
+
const options = this.options();
|
|
359
|
+
const groups = this.groups();
|
|
360
|
+
const reactiveOptions = this.thyOptions();
|
|
282
361
|
untracked(() => {
|
|
283
|
-
this.
|
|
284
|
-
this.getPositions();
|
|
285
|
-
this.setDropDownClass();
|
|
362
|
+
this.buildAllGroupsAndOptions();
|
|
286
363
|
});
|
|
287
364
|
});
|
|
365
|
+
afterRenderEffect(() => {
|
|
366
|
+
this.updateSelectedOptions();
|
|
367
|
+
});
|
|
288
368
|
}
|
|
289
369
|
writeValue(value) {
|
|
290
|
-
|
|
291
|
-
|
|
370
|
+
let selectedValues;
|
|
371
|
+
if (helpers.isUndefinedOrNull(value)) {
|
|
372
|
+
selectedValues = [];
|
|
373
|
+
}
|
|
374
|
+
else if (this.isMultiple()) {
|
|
375
|
+
selectedValues = value;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
selectedValues = [value];
|
|
379
|
+
}
|
|
380
|
+
this.selectedValues.set(selectedValues);
|
|
292
381
|
}
|
|
293
382
|
ngOnInit() {
|
|
294
|
-
this.getPositions();
|
|
295
|
-
this.dropDownMinWidth = this.getDropdownMinWidth();
|
|
296
|
-
if (!this.selectionModel) {
|
|
297
|
-
this.instanceSelectionModel();
|
|
298
|
-
}
|
|
299
|
-
this.setDropDownClass();
|
|
300
383
|
if (isPlatformBrowser(this.platformId)) {
|
|
301
384
|
this.thyClickDispatcher
|
|
302
385
|
.clicked(0)
|
|
303
|
-
.pipe(
|
|
386
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
304
387
|
.subscribe(event => {
|
|
305
388
|
if (!this.elementRef.nativeElement.contains(event.target) && this.panelOpen) {
|
|
306
389
|
this.ngZone.run(() => {
|
|
@@ -311,74 +394,16 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
311
394
|
});
|
|
312
395
|
}
|
|
313
396
|
}
|
|
314
|
-
buildOptionGroups(options) {
|
|
315
|
-
const optionGroups = [];
|
|
316
|
-
const groups = [...new Set(options.filter(item => this.groupBy(item)).map(sub => this.groupBy(sub)))];
|
|
317
|
-
const groupMap = new Map();
|
|
318
|
-
groups.forEach(group => {
|
|
319
|
-
const children = options.filter(item => this.groupBy(item) === group);
|
|
320
|
-
const groupOption = {
|
|
321
|
-
groupLabel: group,
|
|
322
|
-
children: children
|
|
323
|
-
};
|
|
324
|
-
groupMap.set(group, groupOption);
|
|
325
|
-
});
|
|
326
|
-
options.forEach(option => {
|
|
327
|
-
if (this.groupBy(option)) {
|
|
328
|
-
const currentIndex = optionGroups.findIndex(item => item.groupLabel === this.groupBy(option));
|
|
329
|
-
if (currentIndex === -1) {
|
|
330
|
-
const item = groupMap.get(this.groupBy(option));
|
|
331
|
-
optionGroups.push(item);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
optionGroups.push(option);
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
return optionGroups;
|
|
339
|
-
}
|
|
340
|
-
buildReactiveOptions() {
|
|
341
|
-
if (this.innerOptions.filter(item => this.groupBy(item)).length > 0) {
|
|
342
|
-
this.optionGroups = this.buildOptionGroups(this.innerOptions);
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
this.optionGroups = this.innerOptions;
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
getDropdownMinWidth() {
|
|
349
|
-
const mode = this.thyDropdownWidthMode() || this.config.dropdownWidthMode;
|
|
350
|
-
let dropdownMinWidth = null;
|
|
351
|
-
if (mode?.minWidth) {
|
|
352
|
-
dropdownMinWidth = mode.minWidth;
|
|
353
|
-
}
|
|
354
|
-
else if (mode === 'min-width') {
|
|
355
|
-
dropdownMinWidth = THY_SELECT_PANEL_MIN_WIDTH;
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
dropdownMinWidth = null;
|
|
359
|
-
}
|
|
360
|
-
return dropdownMinWidth;
|
|
361
|
-
}
|
|
362
397
|
ngAfterViewInit() {
|
|
363
|
-
|
|
364
|
-
this.setup();
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
ngAfterContentInit() {
|
|
368
|
-
if (!this.isReactiveDriven) {
|
|
369
|
-
this.setup();
|
|
370
|
-
}
|
|
398
|
+
this.setup();
|
|
371
399
|
}
|
|
372
400
|
setup() {
|
|
373
|
-
this.optionsChanges$.pipe(startWith(null),
|
|
374
|
-
|
|
375
|
-
this.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
this.highlightCorrectOption(false);
|
|
379
|
-
this.isSearching = false;
|
|
401
|
+
this.optionsChanges$.pipe(startWith(null), takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
|
402
|
+
// Don't scroll to default highlighted option when scroll load more options
|
|
403
|
+
if (this.shouldActivateOption) {
|
|
404
|
+
this.shouldActivateOption = false;
|
|
405
|
+
this.scrollToActivatedOption();
|
|
380
406
|
}
|
|
381
|
-
this.changeDetectorRef.markForCheck();
|
|
382
407
|
this.ngZone.onStable
|
|
383
408
|
.asObservable()
|
|
384
409
|
.pipe(take(1))
|
|
@@ -396,57 +421,185 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
396
421
|
});
|
|
397
422
|
}
|
|
398
423
|
}
|
|
399
|
-
|
|
400
|
-
|
|
424
|
+
buildAllGroupsAndOptions() {
|
|
425
|
+
let allGroupsAndOptions;
|
|
426
|
+
const isReactiveDriven = this.thyOptions() && this.thyOptions().length > 0;
|
|
427
|
+
if (isReactiveDriven) {
|
|
428
|
+
allGroupsAndOptions = this.allGroupsAndOptionsByReactive();
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
allGroupsAndOptions = this.allGroupsAndOptionsByTemplate();
|
|
432
|
+
}
|
|
433
|
+
this.allGroupsAndOptions.set(allGroupsAndOptions);
|
|
401
434
|
}
|
|
402
|
-
|
|
403
|
-
this.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
435
|
+
allGroupsAndOptionsByReactive() {
|
|
436
|
+
const options = this.thyOptions();
|
|
437
|
+
const groupMap = new Map();
|
|
438
|
+
const ungroupedOptions = [];
|
|
439
|
+
const groupsAndOptions = [];
|
|
440
|
+
for (const option of options) {
|
|
441
|
+
if (option.groupLabel) {
|
|
442
|
+
if (!groupMap.has(option.groupLabel)) {
|
|
443
|
+
groupMap.set(option.groupLabel, []);
|
|
410
444
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
445
|
+
groupMap.get(option.groupLabel).push(option);
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
ungroupedOptions.push(option);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
for (const [groupLabel, groupOptions] of groupMap) {
|
|
452
|
+
groupsAndOptions.push({
|
|
453
|
+
type: 'group',
|
|
454
|
+
label: groupLabel
|
|
455
|
+
});
|
|
456
|
+
for (const option of groupOptions) {
|
|
457
|
+
groupsAndOptions.push({
|
|
458
|
+
type: 'option',
|
|
459
|
+
value: option.value,
|
|
460
|
+
label: option.label,
|
|
461
|
+
rawValue: option,
|
|
462
|
+
showOptionCustom: false,
|
|
463
|
+
disabled: !!option.disabled,
|
|
464
|
+
groupLabel: option.groupLabel
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
for (const option of ungroupedOptions) {
|
|
469
|
+
groupsAndOptions.push({
|
|
470
|
+
type: 'option',
|
|
471
|
+
value: option.value,
|
|
472
|
+
label: option.label,
|
|
473
|
+
rawValue: option,
|
|
474
|
+
showOptionCustom: false,
|
|
475
|
+
disabled: !!option.disabled
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
return groupsAndOptions;
|
|
479
|
+
}
|
|
480
|
+
allGroupsAndOptionsByTemplate() {
|
|
481
|
+
const options = this.options();
|
|
482
|
+
const groups = this.groups();
|
|
483
|
+
let groupsAndOptions = [];
|
|
484
|
+
if (options && options.length > 0) {
|
|
485
|
+
groupsAndOptions = options.map((option) => {
|
|
486
|
+
const { thyValue, thyRawValue, thyLabelText, thyShowOptionCustom, thyDisabled, template, thySearchKey, groupLabel } = option;
|
|
487
|
+
return {
|
|
488
|
+
type: 'option',
|
|
489
|
+
value: thyValue(),
|
|
490
|
+
rawValue: thyRawValue(),
|
|
491
|
+
label: thyLabelText(),
|
|
492
|
+
showOptionCustom: thyShowOptionCustom(),
|
|
493
|
+
disabled: thyDisabled(),
|
|
494
|
+
template: template(),
|
|
495
|
+
searchKey: thySearchKey(),
|
|
496
|
+
groupLabel: groupLabel
|
|
497
|
+
};
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
if (groups && groups.length > 0) {
|
|
501
|
+
for (const group of groups) {
|
|
502
|
+
const groupIndex = groupsAndOptions.findIndex(option => option.groupLabel === group.thyGroupLabel());
|
|
503
|
+
if (groupIndex > -1) {
|
|
504
|
+
const groupItem = {
|
|
505
|
+
type: 'group',
|
|
506
|
+
label: group.thyGroupLabel(),
|
|
507
|
+
disabled: group.thyDisabled()
|
|
508
|
+
};
|
|
509
|
+
groupsAndOptions.splice(groupIndex, 0, groupItem);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return groupsAndOptions;
|
|
514
|
+
}
|
|
515
|
+
buildFilteredGroupsAndOptions() {
|
|
516
|
+
const keywords = this.keywords();
|
|
517
|
+
const isServerSearch = this.thyServerSearch();
|
|
518
|
+
const allGroupsAndOptions = this.allGroupsAndOptions();
|
|
519
|
+
const filteredGroupsAndOptions = [];
|
|
520
|
+
if (keywords && !isServerSearch) {
|
|
521
|
+
const lowerKeywords = keywords.toLowerCase();
|
|
522
|
+
const matchedOptions = new Set();
|
|
523
|
+
const matchedGroupLabels = new Set();
|
|
524
|
+
for (const item of allGroupsAndOptions) {
|
|
525
|
+
if (item.type === 'option') {
|
|
526
|
+
const isMatch = (item.searchKey || item.label) && (item.searchKey || item.label).toLowerCase().indexOf(lowerKeywords) > -1;
|
|
527
|
+
if (isMatch) {
|
|
528
|
+
matchedOptions.add(item.value);
|
|
529
|
+
if (item.groupLabel) {
|
|
530
|
+
matchedGroupLabels.add(item.groupLabel);
|
|
531
|
+
}
|
|
415
532
|
}
|
|
416
533
|
}
|
|
417
534
|
}
|
|
418
|
-
|
|
535
|
+
for (const item of allGroupsAndOptions) {
|
|
536
|
+
if (item.type === 'group' && matchedGroupLabels.has(item.label)) {
|
|
537
|
+
filteredGroupsAndOptions.push(item);
|
|
538
|
+
}
|
|
539
|
+
else if (item.type === 'option' && matchedOptions.has(item.value)) {
|
|
540
|
+
filteredGroupsAndOptions.push(item);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return filteredGroupsAndOptions;
|
|
544
|
+
}
|
|
545
|
+
return allGroupsAndOptions;
|
|
419
546
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
547
|
+
updateSelectedOptions() {
|
|
548
|
+
const selectedValues = this.selectedValues();
|
|
549
|
+
const isMultiple = untracked(() => this.isMultiple());
|
|
550
|
+
const newOptions = [];
|
|
551
|
+
if (selectedValues.length) {
|
|
552
|
+
const filteredOptionsMap = this.filteredOptionsMap();
|
|
553
|
+
const oldSelectedOptionsMap = untracked(() => {
|
|
554
|
+
const selected = this.selectedOptions();
|
|
555
|
+
let oldSelectedOptions;
|
|
556
|
+
if (helpers.isArray(selected)) {
|
|
557
|
+
oldSelectedOptions = selected;
|
|
558
|
+
}
|
|
559
|
+
else if (selected) {
|
|
560
|
+
oldSelectedOptions = [selected];
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
oldSelectedOptions = [];
|
|
564
|
+
}
|
|
565
|
+
return helpers.keyBy(oldSelectedOptions, 'thyValue');
|
|
566
|
+
});
|
|
567
|
+
selectedValues.forEach(value => {
|
|
568
|
+
const option = filteredOptionsMap.get(value);
|
|
569
|
+
if (option) {
|
|
570
|
+
newOptions.push({
|
|
571
|
+
thyLabelText: option.label,
|
|
572
|
+
thyValue: option.value,
|
|
573
|
+
thyRawValue: option.rawValue
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
else if (oldSelectedOptionsMap[value]) {
|
|
577
|
+
newOptions.push(oldSelectedOptionsMap[value]);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
this.selectedOptions.set(isMultiple ? newOptions : newOptions.length ? newOptions[0] : null);
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
this.selectedOptions.set(isMultiple ? [] : null);
|
|
423
584
|
}
|
|
424
585
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
if (
|
|
428
|
-
this.
|
|
586
|
+
optionsScrolled(index) {
|
|
587
|
+
this.scrolledIndex = index;
|
|
588
|
+
if (this.thyEnableScrollLoad()) {
|
|
589
|
+
const isScrollToBottom = index + this.maxItemLength() >= this.filteredGroupsAndOptions().length;
|
|
590
|
+
if (isScrollToBottom) {
|
|
429
591
|
this.thyOnScrollToBottom.emit();
|
|
430
|
-
}
|
|
592
|
+
}
|
|
431
593
|
}
|
|
432
594
|
}
|
|
433
|
-
|
|
434
|
-
|
|
595
|
+
search(keywords) {
|
|
596
|
+
this.shouldActivateOption = true;
|
|
597
|
+
this.activatedValue.set(null);
|
|
598
|
+
this.keywords.set(keywords.trim());
|
|
435
599
|
if (this.thyServerSearch()) {
|
|
436
|
-
this.
|
|
437
|
-
this.thyOnSearch.emit(searchText);
|
|
600
|
+
this.thyOnSearch.emit(keywords);
|
|
438
601
|
}
|
|
439
602
|
else {
|
|
440
|
-
const options = this.options.toArray();
|
|
441
|
-
options.forEach(option => {
|
|
442
|
-
if (option.matchSearchText(searchText)) {
|
|
443
|
-
option.showOption();
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
option.hideOption();
|
|
447
|
-
}
|
|
448
|
-
});
|
|
449
|
-
this.highlightCorrectOption(false);
|
|
450
603
|
this.updateCdkConnectedOverlayPositions();
|
|
451
604
|
}
|
|
452
605
|
}
|
|
@@ -478,14 +631,12 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
478
631
|
if (this.disabled) {
|
|
479
632
|
return;
|
|
480
633
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
this.
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
$event.item.deselect();
|
|
634
|
+
const selectedValue = this.selectedValues();
|
|
635
|
+
const index = selectedValue.indexOf($event.item.thyValue);
|
|
636
|
+
if (index > -1) {
|
|
637
|
+
this.selectedValues.set([...selectedValue.slice(0, index), ...selectedValue.slice(index + 1)]);
|
|
488
638
|
}
|
|
639
|
+
this.emitModelValueChange();
|
|
489
640
|
}
|
|
490
641
|
clearSelectValue(event) {
|
|
491
642
|
if (event) {
|
|
@@ -494,8 +645,7 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
494
645
|
if (this.disabled) {
|
|
495
646
|
return;
|
|
496
647
|
}
|
|
497
|
-
this.
|
|
498
|
-
this.changeDetectorRef.markForCheck();
|
|
648
|
+
this.selectedValues.set([]);
|
|
499
649
|
this.emitModelValueChange();
|
|
500
650
|
}
|
|
501
651
|
updateCdkConnectedOverlayPositions() {
|
|
@@ -505,19 +655,6 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
505
655
|
}
|
|
506
656
|
});
|
|
507
657
|
}
|
|
508
|
-
get selected() {
|
|
509
|
-
return this.isMultiple ? this.selectionModel.selected : this.selectionModel.selected[0];
|
|
510
|
-
}
|
|
511
|
-
get isMultiple() {
|
|
512
|
-
return this.mode === 'multiple';
|
|
513
|
-
}
|
|
514
|
-
get empty() {
|
|
515
|
-
return !this.selectionModel || this.selectionModel.isEmpty();
|
|
516
|
-
}
|
|
517
|
-
getItemCount() {
|
|
518
|
-
const group = this.isReactiveDriven ? this.viewGroups() : this.contentGroups();
|
|
519
|
-
return this.options.length + group.length;
|
|
520
|
-
}
|
|
521
658
|
toggle(event) {
|
|
522
659
|
if (this.panelOpen) {
|
|
523
660
|
if (!this.thyShowSearch()) {
|
|
@@ -529,19 +666,20 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
529
666
|
}
|
|
530
667
|
}
|
|
531
668
|
open() {
|
|
532
|
-
if (this.disabled ||
|
|
669
|
+
if (this.disabled || this.panelOpen) {
|
|
533
670
|
return;
|
|
534
671
|
}
|
|
535
|
-
this.triggerRectWidth
|
|
672
|
+
this.triggerRectWidth.set(this.getOriginRectWidth());
|
|
536
673
|
this.subscribeTriggerResize();
|
|
537
674
|
this.panelOpen = true;
|
|
538
|
-
this.
|
|
675
|
+
this.shouldActivateOption = true;
|
|
539
676
|
this.thyOnExpandStatusChange.emit(this.panelOpen);
|
|
540
677
|
this.changeDetectorRef.markForCheck();
|
|
541
678
|
}
|
|
542
679
|
close() {
|
|
543
680
|
if (this.panelOpen) {
|
|
544
681
|
this.panelOpen = false;
|
|
682
|
+
this.scrolledIndex = 0;
|
|
545
683
|
this.unsubscribeTriggerResize();
|
|
546
684
|
this.thyOnExpandStatusChange.emit(this.panelOpen);
|
|
547
685
|
this.changeDetectorRef.markForCheck();
|
|
@@ -549,252 +687,202 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
549
687
|
}
|
|
550
688
|
}
|
|
551
689
|
emitModelValueChange() {
|
|
552
|
-
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
if (this.isMultiple) {
|
|
557
|
-
this.modalValue = changeValue;
|
|
690
|
+
let modelValue;
|
|
691
|
+
const selectedValues = this.selectedValues();
|
|
692
|
+
if (this.isMultiple()) {
|
|
693
|
+
modelValue = selectedValues;
|
|
558
694
|
}
|
|
559
695
|
else {
|
|
560
|
-
if (
|
|
561
|
-
|
|
696
|
+
if (selectedValues.length === 0) {
|
|
697
|
+
modelValue = null;
|
|
562
698
|
}
|
|
563
699
|
else {
|
|
564
|
-
|
|
700
|
+
modelValue = selectedValues[0];
|
|
565
701
|
}
|
|
566
702
|
}
|
|
567
|
-
this.onChangeFn(
|
|
703
|
+
this.onChangeFn(modelValue);
|
|
568
704
|
this.updateCdkConnectedOverlayPositions();
|
|
569
705
|
}
|
|
570
|
-
|
|
571
|
-
if (this.
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
706
|
+
scrollToActivatedOption(needSelect = false) {
|
|
707
|
+
if (!this.panelOpen) {
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
const filteredOptions = this.filteredOptions();
|
|
711
|
+
if (!filteredOptions.length) {
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
let toActivatedValue = this.activatedValue();
|
|
715
|
+
const filteredOptionsMap = this.filteredOptionsMap();
|
|
716
|
+
if (!toActivatedValue || !filteredOptionsMap.has(toActivatedValue)) {
|
|
717
|
+
let selectedValues = this.selectedValues();
|
|
718
|
+
const lowerKeywords = this.keywords()?.trim()?.toLowerCase();
|
|
719
|
+
if (lowerKeywords) {
|
|
720
|
+
selectedValues = selectedValues.filter(value => {
|
|
721
|
+
const option = filteredOptionsMap.get(value);
|
|
722
|
+
return (option &&
|
|
723
|
+
(option.searchKey || option.label) &&
|
|
724
|
+
(option.searchKey || option.label).toLowerCase().indexOf(lowerKeywords) > -1);
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
if (selectedValues.length > 0) {
|
|
728
|
+
toActivatedValue = selectedValues[0];
|
|
585
729
|
}
|
|
586
730
|
else {
|
|
587
|
-
if (
|
|
588
|
-
|
|
731
|
+
if (this.thyAutoActiveFirstItem()) {
|
|
732
|
+
toActivatedValue = filteredOptions[0].value || null;
|
|
589
733
|
}
|
|
590
|
-
// always set first option active
|
|
591
|
-
this.keyManager.setFirstItemActive();
|
|
592
734
|
}
|
|
735
|
+
if (!toActivatedValue) {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
this.activatedValue.set(toActivatedValue);
|
|
593
739
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
this.keyManager.activeItem.setInactiveStyles();
|
|
740
|
+
const targetIndex = this.filteredGroupsAndOptions().findIndex(item => item.value === toActivatedValue);
|
|
741
|
+
if (targetIndex === -1) {
|
|
742
|
+
return;
|
|
598
743
|
}
|
|
599
|
-
this.
|
|
600
|
-
.
|
|
601
|
-
.withWrap()
|
|
602
|
-
.withVerticalOrientation()
|
|
603
|
-
.withAllowedModifierKeys(['shiftKey']);
|
|
604
|
-
this.keyManager.tabOut.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
605
|
-
this.focus();
|
|
606
|
-
this.close();
|
|
607
|
-
});
|
|
608
|
-
this.keyManager.change.pipe(takeUntil(this.destroy$)).subscribe(() => {
|
|
609
|
-
if (this.panelOpen && this.panel()) {
|
|
610
|
-
if (this.keyManager.activeItem) {
|
|
611
|
-
ScrollToService.scrollToElement(this.keyManager.activeItem.element.nativeElement, this.panel().nativeElement);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
else if (!this.panelOpen && !this.isMultiple && this.keyManager.activeItem) {
|
|
615
|
-
this.keyManager.activeItem.selectViaInteraction();
|
|
616
|
-
}
|
|
617
|
-
});
|
|
618
|
-
}
|
|
619
|
-
handleClosedKeydown(event) {
|
|
620
|
-
const keyCode = event.keyCode;
|
|
621
|
-
const isArrowKey = keyCode === DOWN_ARROW || keyCode === UP_ARROW || keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW;
|
|
622
|
-
const isOpenKey = keyCode === ENTER || keyCode === SPACE;
|
|
623
|
-
const manager = this.keyManager;
|
|
624
|
-
// Open the select on ALT + arrow key to match the native <select>
|
|
625
|
-
if ((isOpenKey && !hasModifierKey(event)) || ((this.isMultiple || event.altKey) && isArrowKey)) {
|
|
626
|
-
event.preventDefault(); // prevents the page from scrolling down when pressing space
|
|
627
|
-
this.open();
|
|
744
|
+
if (targetIndex < this.scrolledIndex || targetIndex >= this.scrolledIndex + this.maxItemLength()) {
|
|
745
|
+
this.cdkVirtualScrollViewport()?.scrollToIndex(targetIndex || 0);
|
|
628
746
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
keyCode === HOME ? manager.setFirstItemActive() : manager.setLastItemActive();
|
|
632
|
-
event.preventDefault();
|
|
633
|
-
}
|
|
634
|
-
else {
|
|
635
|
-
manager.onKeydown(event);
|
|
636
|
-
}
|
|
747
|
+
if (needSelect) {
|
|
748
|
+
this.optionRenders.find(option => option.thyValue() === toActivatedValue)?.selectViaInteraction();
|
|
637
749
|
}
|
|
638
750
|
}
|
|
639
|
-
|
|
751
|
+
handleKeydown(event) {
|
|
640
752
|
const keyCode = event.keyCode;
|
|
753
|
+
const isOpenKey = keyCode === ENTER || keyCode === SPACE;
|
|
641
754
|
const isArrowKey = keyCode === DOWN_ARROW || keyCode === UP_ARROW;
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
755
|
+
if (event.altKey) {
|
|
756
|
+
if (this.panelOpen && isArrowKey) {
|
|
757
|
+
event.preventDefault();
|
|
758
|
+
this.close();
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
646
761
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
762
|
+
if (!this.panelOpen) {
|
|
763
|
+
this.open();
|
|
764
|
+
if (isOpenKey) {
|
|
765
|
+
event.preventDefault();
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
651
768
|
}
|
|
652
|
-
|
|
769
|
+
const filteredOptions = this.filteredOptions();
|
|
770
|
+
if (keyCode === DOWN_ARROW || keyCode === UP_ARROW) {
|
|
653
771
|
event.preventDefault();
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
772
|
+
const activatedValue = this.activatedValue();
|
|
773
|
+
const currentOption = this.filteredOptionsMap().get(activatedValue);
|
|
774
|
+
if (!currentOption) {
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
const currentIndex = filteredOptions.indexOf(currentOption);
|
|
778
|
+
let targetIndex;
|
|
779
|
+
if (keyCode === DOWN_ARROW) {
|
|
780
|
+
targetIndex = currentIndex + 1;
|
|
781
|
+
if (targetIndex > filteredOptions.length - 1) {
|
|
782
|
+
targetIndex = 0;
|
|
783
|
+
}
|
|
784
|
+
let attempts = 0;
|
|
785
|
+
while (filteredOptions[targetIndex]?.disabled && attempts < filteredOptions.length) {
|
|
786
|
+
targetIndex++;
|
|
787
|
+
if (targetIndex > filteredOptions.length - 1) {
|
|
788
|
+
targetIndex = 0;
|
|
789
|
+
}
|
|
790
|
+
attempts++;
|
|
657
791
|
}
|
|
658
792
|
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
793
|
+
else {
|
|
794
|
+
targetIndex = currentIndex - 1;
|
|
795
|
+
if (targetIndex < 0) {
|
|
796
|
+
targetIndex = filteredOptions.length - 1;
|
|
797
|
+
}
|
|
798
|
+
let attempts = 0;
|
|
799
|
+
while (filteredOptions[targetIndex]?.disabled && attempts < filteredOptions.length) {
|
|
800
|
+
targetIndex--;
|
|
801
|
+
if (targetIndex < 0) {
|
|
802
|
+
targetIndex = filteredOptions.length - 1;
|
|
803
|
+
}
|
|
804
|
+
attempts++;
|
|
667
805
|
}
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
else {
|
|
671
|
-
if (manager.activeItemIndex === -1 && !this.empty) {
|
|
672
|
-
manager.setActiveItem(this.selectionModel.selected[0]);
|
|
673
806
|
}
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
807
|
+
const targetOption = filteredOptions[targetIndex];
|
|
808
|
+
if (targetOption?.disabled) {
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
this.activatedValue.set(targetOption.value);
|
|
812
|
+
if (!hasModifierKey(event)) {
|
|
813
|
+
this.scrollToActivatedOption();
|
|
814
|
+
}
|
|
815
|
+
else if (this.isMultiple() && event.shiftKey) {
|
|
816
|
+
this.scrollToActivatedOption(true);
|
|
682
817
|
}
|
|
683
818
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
if (this.selectionModel) {
|
|
690
|
-
this.selectionModel.clear();
|
|
819
|
+
else if (keyCode === HOME || keyCode === END) {
|
|
820
|
+
event.preventDefault();
|
|
821
|
+
const targetOption = keyCode === HOME ? filteredOptions[0] : filteredOptions[filteredOptions.length - 1];
|
|
822
|
+
this.activatedValue.set(targetOption.value);
|
|
823
|
+
this.scrollToActivatedOption();
|
|
691
824
|
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
this.
|
|
695
|
-
this.selectionModelSubscription = null;
|
|
825
|
+
else if ((keyCode === ENTER || keyCode === SPACE) && (this.activatedValue() || !this.empty()) && !hasModifierKey(event)) {
|
|
826
|
+
event.preventDefault();
|
|
827
|
+
this.scrollToActivatedOption(true);
|
|
696
828
|
}
|
|
697
|
-
|
|
698
|
-
event.
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
const changedOrDestroyed$ = merge(this.optionsChanges$, this.destroy$);
|
|
704
|
-
this.optionSelectionChanges.pipe(takeUntil(changedOrDestroyed$)).subscribe((event) => {
|
|
705
|
-
this.onSelect(event.option, event.isUserInput);
|
|
706
|
-
if (event.isUserInput && !this.isMultiple && this.panelOpen) {
|
|
707
|
-
this.close();
|
|
708
|
-
this.focus();
|
|
829
|
+
else if (this.isMultiple() && keyCode === A && event.ctrlKey) {
|
|
830
|
+
event.preventDefault();
|
|
831
|
+
const hasDeselectedOptions = filteredOptions.some(opt => !opt.disabled && !this.selectedValues().includes(opt.value));
|
|
832
|
+
let selectedValues = [];
|
|
833
|
+
if (hasDeselectedOptions) {
|
|
834
|
+
selectedValues = filteredOptions.filter(option => !option.disabled).map(option => option.value);
|
|
709
835
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
initializeSelection() {
|
|
713
|
-
Promise.resolve().then(() => {
|
|
714
|
-
this.setSelectionByModelValue(this.modalValue);
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
setDropDownClass() {
|
|
718
|
-
let modeClass = '';
|
|
719
|
-
if (this.isMultiple) {
|
|
720
|
-
modeClass = `thy-select-dropdown-${this.mode}`;
|
|
836
|
+
this.selectedValues.set(selectedValues);
|
|
837
|
+
this.emitModelValueChange();
|
|
721
838
|
}
|
|
722
|
-
else {
|
|
723
|
-
|
|
839
|
+
else if (keyCode === TAB) {
|
|
840
|
+
this.focus();
|
|
841
|
+
this.close();
|
|
724
842
|
}
|
|
725
|
-
this.dropDownClass = {
|
|
726
|
-
[`thy-select-dropdown`]: true,
|
|
727
|
-
[modeClass]: true
|
|
728
|
-
};
|
|
729
843
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
844
|
+
optionClick(event) {
|
|
845
|
+
const { value, isUserInput } = event;
|
|
846
|
+
const options = this.options();
|
|
847
|
+
if (this.isMultiple()) {
|
|
848
|
+
const selectedValues = this.selectedValues() || [];
|
|
849
|
+
const index = selectedValues.indexOf(value);
|
|
850
|
+
if (index > -1) {
|
|
851
|
+
selectedValues.splice(index, 1);
|
|
735
852
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
if (this.isMultiple) {
|
|
739
|
-
if (isArray(modalValue)) {
|
|
740
|
-
const selected = [...this.selectionModel.selected];
|
|
741
|
-
this.selectionModel.clear();
|
|
742
|
-
modalValue.forEach(itemValue => {
|
|
743
|
-
const option = this.options.find(_option => _option.thyValue === itemValue) ||
|
|
744
|
-
selected.find(_option => _option.thyValue === itemValue);
|
|
745
|
-
if (option) {
|
|
746
|
-
this.selectionModel.select(option);
|
|
747
|
-
}
|
|
748
|
-
});
|
|
853
|
+
else {
|
|
854
|
+
selectedValues.push(value);
|
|
749
855
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
856
|
+
const thySortComparator = this.thySortComparator();
|
|
857
|
+
if (thySortComparator) {
|
|
858
|
+
selectedValues.sort((a, b) => {
|
|
859
|
+
const aOption = options.find(option => option.thyValue() === a);
|
|
860
|
+
const bOption = options.find(option => option.thyValue() === b);
|
|
861
|
+
return thySortComparator(aOption, bOption, [...options]);
|
|
862
|
+
});
|
|
757
863
|
}
|
|
758
|
-
|
|
759
|
-
this.changeDetectorRef.markForCheck();
|
|
760
|
-
}
|
|
761
|
-
onSelect(option, isUserInput) {
|
|
762
|
-
const wasSelected = this.selectionModel.isSelected(option);
|
|
763
|
-
if (option.thyValue == null && !this.isMultiple) {
|
|
764
|
-
option.deselect();
|
|
765
|
-
this.selectionModel.clear();
|
|
864
|
+
this.selectedValues.set([...selectedValues]);
|
|
766
865
|
}
|
|
767
866
|
else {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
}
|
|
771
|
-
if (isUserInput) {
|
|
772
|
-
this.keyManager.setActiveItem(option);
|
|
773
|
-
}
|
|
774
|
-
if (this.isMultiple) {
|
|
775
|
-
this.sortValues();
|
|
776
|
-
if (isUserInput) {
|
|
777
|
-
this.focus();
|
|
778
|
-
}
|
|
779
|
-
}
|
|
867
|
+
this.selectedValues.set([value]);
|
|
868
|
+
this.close();
|
|
780
869
|
}
|
|
781
|
-
|
|
782
|
-
|
|
870
|
+
const option = options.find(option => option.thyValue() === value);
|
|
871
|
+
if (option) {
|
|
872
|
+
const selected = this.selectedValues().includes(value);
|
|
873
|
+
option.selected.set(selected);
|
|
874
|
+
option.selectionChange.emit({ option, isUserInput });
|
|
783
875
|
}
|
|
784
|
-
|
|
876
|
+
this.emitModelValueChange();
|
|
877
|
+
if (!this.isMultiple()) {
|
|
785
878
|
this.onTouchedFn();
|
|
786
879
|
}
|
|
787
|
-
this.changeDetectorRef.markForCheck();
|
|
788
880
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
return this.thySortComparator()(a, b, options);
|
|
795
|
-
});
|
|
796
|
-
}
|
|
797
|
-
}
|
|
881
|
+
optionHover(value) {
|
|
882
|
+
this.activatedValue.set(value);
|
|
883
|
+
}
|
|
884
|
+
mouseLeaveOptions() {
|
|
885
|
+
this.activatedValue.set(null);
|
|
798
886
|
}
|
|
799
887
|
getOriginRectWidth() {
|
|
800
888
|
return this.thyOrigin() ? coerceElement(this.thyOrigin()).offsetWidth : this.trigger.nativeElement.offsetWidth;
|
|
@@ -813,7 +901,7 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
813
901
|
}), distinctUntilChanged())
|
|
814
902
|
.subscribe((width) => {
|
|
815
903
|
this.ngZone.run(() => {
|
|
816
|
-
this.triggerRectWidth
|
|
904
|
+
this.triggerRectWidth.set(width);
|
|
817
905
|
this.updateCdkConnectedOverlayPositions();
|
|
818
906
|
this.changeDetectorRef.markForCheck();
|
|
819
907
|
});
|
|
@@ -826,49 +914,48 @@ class ThySelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
826
914
|
this.resizeSubscription = null;
|
|
827
915
|
}
|
|
828
916
|
}
|
|
917
|
+
trackByFn(index, item) {
|
|
918
|
+
if (item.type === 'group') {
|
|
919
|
+
return item.label || index;
|
|
920
|
+
}
|
|
921
|
+
if (item.type === 'option') {
|
|
922
|
+
return item.value || index;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
829
925
|
ngOnDestroy() {
|
|
830
926
|
this.unsubscribeTriggerResize();
|
|
831
|
-
this.destroy$.next();
|
|
832
|
-
this.destroy$.complete();
|
|
833
927
|
}
|
|
834
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
835
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
836
|
-
{
|
|
837
|
-
provide: THY_OPTION_PARENT_COMPONENT,
|
|
838
|
-
useExisting: ThySelect
|
|
839
|
-
},
|
|
928
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ThySelect, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
929
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ThySelect, isStandalone: true, selector: "thy-select,thy-custom-select", inputs: { thyDropdownWidthMode: { classPropertyName: "thyDropdownWidthMode", publicName: "thyDropdownWidthMode", isSignal: true, isRequired: false, transformFunction: null }, thyItemSize: { classPropertyName: "thyItemSize", publicName: "thyItemSize", isSignal: true, isRequired: false, transformFunction: null }, thyShowSearch: { classPropertyName: "thyShowSearch", publicName: "thyShowSearch", isSignal: true, isRequired: false, transformFunction: null }, thyPlaceHolder: { classPropertyName: "thyPlaceHolder", publicName: "thyPlaceHolder", isSignal: true, isRequired: false, transformFunction: null }, thyServerSearch: { classPropertyName: "thyServerSearch", publicName: "thyServerSearch", isSignal: true, isRequired: false, transformFunction: null }, thyLoadState: { classPropertyName: "thyLoadState", publicName: "thyLoadState", isSignal: true, isRequired: false, transformFunction: null }, thyAutoActiveFirstItem: { classPropertyName: "thyAutoActiveFirstItem", publicName: "thyAutoActiveFirstItem", isSignal: true, isRequired: false, transformFunction: null }, thyMode: { classPropertyName: "thyMode", publicName: "thyMode", isSignal: true, isRequired: false, transformFunction: null }, thySize: { classPropertyName: "thySize", publicName: "thySize", isSignal: true, isRequired: false, transformFunction: null }, thyEmptyStateText: { classPropertyName: "thyEmptyStateText", publicName: "thyEmptyStateText", isSignal: true, isRequired: false, transformFunction: null }, thyEmptySearchMessageText: { classPropertyName: "thyEmptySearchMessageText", publicName: "thyEmptySearchMessageText", isSignal: true, isRequired: false, transformFunction: null }, thyEnableScrollLoad: { classPropertyName: "thyEnableScrollLoad", publicName: "thyEnableScrollLoad", isSignal: true, isRequired: false, transformFunction: null }, thyAllowClear: { classPropertyName: "thyAllowClear", publicName: "thyAllowClear", isSignal: true, isRequired: false, transformFunction: null }, thyDisabled: { classPropertyName: "thyDisabled", publicName: "thyDisabled", isSignal: false, isRequired: false, transformFunction: coerceBooleanProperty }, thySortComparator: { classPropertyName: "thySortComparator", publicName: "thySortComparator", isSignal: true, isRequired: false, transformFunction: null }, thyFooterTemplate: { classPropertyName: "thyFooterTemplate", publicName: "thyFooterTemplate", isSignal: true, isRequired: false, transformFunction: null }, thyPlacement: { classPropertyName: "thyPlacement", publicName: "thyPlacement", isSignal: true, isRequired: false, transformFunction: null }, thyOrigin: { classPropertyName: "thyOrigin", publicName: "thyOrigin", isSignal: true, isRequired: false, transformFunction: null }, thyFooterClass: { classPropertyName: "thyFooterClass", publicName: "thyFooterClass", isSignal: true, isRequired: false, transformFunction: null }, thyAutoExpand: { classPropertyName: "thyAutoExpand", publicName: "thyAutoExpand", isSignal: true, isRequired: false, transformFunction: null }, thyHasBackdrop: { classPropertyName: "thyHasBackdrop", publicName: "thyHasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, thyMaxTagCount: { classPropertyName: "thyMaxTagCount", publicName: "thyMaxTagCount", isSignal: true, isRequired: false, transformFunction: null }, thyBorderless: { classPropertyName: "thyBorderless", publicName: "thyBorderless", isSignal: true, isRequired: false, transformFunction: null }, thyOptions: { classPropertyName: "thyOptions", publicName: "thyOptions", isSignal: true, isRequired: false, transformFunction: null }, thyPreset: { classPropertyName: "thyPreset", publicName: "thyPreset", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { thyOnSearch: "thyOnSearch", thyOnScrollToBottom: "thyOnScrollToBottom", thyOnExpandStatusChange: "thyOnExpandStatusChange" }, host: { listeners: { "focus": "onFocus($event)", "blur": "onBlur($event)", "keydown": "keydown($event)" }, properties: { "class.thy-select-custom": "true", "class.thy-select": "true", "class.menu-is-opened": "panelOpen", "attr.tabindex": "tabIndex" } }, providers: [
|
|
840
930
|
{
|
|
841
931
|
provide: NG_VALUE_ACCESSOR,
|
|
842
932
|
useExisting: forwardRef(() => ThySelect),
|
|
843
933
|
multi: true
|
|
844
|
-
}
|
|
845
|
-
|
|
934
|
+
},
|
|
935
|
+
ScrollDispatcher
|
|
936
|
+
], queries: [{ propertyName: "selectedValueDisplayRef", first: true, predicate: ["selectedDisplay"], descendants: true, isSignal: true }, { propertyName: "options", predicate: ThyOption, descendants: true, isSignal: true }, { propertyName: "groups", predicate: ThySelectOptionGroup, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "cdkConnectedOverlay", first: true, predicate: CdkConnectedOverlay, descendants: true, isSignal: true }, { propertyName: "cdkVirtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }, { propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, read: ElementRef, static: true }, { propertyName: "optionRenders", predicate: ThyOptionRender, descendants: true }], exportAs: ["thySelect"], usesInheritance: true, ngImport: i0, template: "<div\n cdk-overlay-origin\n thySelectControl\n (click)=\"toggle($event)\"\n #origin=\"cdkOverlayOrigin\"\n #trigger\n [thyPanelOpened]=\"panelOpen\"\n [thySelectedOptions]=\"selectedOptions()\"\n [thyIsMultiple]=\"isMultiple()\"\n [thyShowSearch]=\"thyShowSearch()\"\n [thyAllowClear]=\"thyAllowClear()\"\n [thySize]=\"thySize()\"\n [thyPlaceholder]=\"thyPlaceHolder()\"\n [customDisplayTemplate]=\"selectedValueDisplayRef()\"\n [thyDisabled]=\"disabled\"\n [thyBorderless]=\"thyBorderless()\"\n (thyOnClear)=\"clearSelectValue($event)\"\n (thyOnRemove)=\"remove($event)\"\n (thyOnSearch)=\"search($event)\"\n (thyOnBlur)=\"onBlur($event)\"\n [thyMaxTagCount]=\"thyMaxTagCount()\"\n [thyPreset]=\"thyPreset()\"></div>\n\n<ng-template\n cdk-connected-overlay\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayHasBackdrop]=\"thyHasBackdrop()\"\n [cdkConnectedOverlayPositions]=\"dropDownPositions()\"\n [cdkConnectedOverlayOrigin]=\"thyOrigin() || origin\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayWidth]=\"triggerRectWidth()\"\n [cdkConnectedOverlayMinWidth]=\"dropDownMinWidth()\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n cdkConnectedOverlayTransformOriginOn=\".thy-select-dropdown\"\n (detach)=\"close()\">\n <div\n thyStopPropagation\n [attr.tabindex]=\"-1\"\n [ngClass]=\"dropDownClass()\"\n [@scaleYMotion]=\"placement() === 'top' || placement() === 'bottom' ? 'enter' : 'void'\"\n [@scaleXMotion]=\"placement() === 'left' || placement() === 'right' ? 'enter' : 'void'\"\n [@scaleMotion]=\"\n placement() !== 'top' && placement() !== 'bottom' && placement() !== 'left' && placement() !== 'right' ? 'enter' : 'void'\n \">\n @if (filteredGroupsAndOptions()?.length > 0) {\n <div\n #panel\n class=\"thy-select-dropdown-options thy-select-dropdown-options-{{ thySize() }} thy-select-dropdown-options-with-virtual-scroll\">\n <cdk-virtual-scroll-viewport\n class=\"thy-select-scroll-viewport\"\n [itemSize]=\"thyItemSize()\"\n [style.height.px]=\"virtualHeight()\"\n (scrolledIndexChange)=\"optionsScrolled($event)\"\n (mouseleave)=\"mouseLeaveOptions()\">\n <ng-template\n cdkVirtualFor\n [cdkVirtualForOf]=\"filteredGroupsAndOptions()\"\n [cdkVirtualForTrackBy]=\"trackByFn\"\n [cdkVirtualForTemplateCacheSize]=\"0\"\n let-item>\n @if (item.type === 'group') {\n <thy-option-group-render [thyGroupLabel]=\"item.label\"></thy-option-group-render>\n } @else {\n <thy-option-render\n [thyValue]=\"item.value\"\n [thyRawValue]=\"item.rawValue\"\n [thyLabelText]=\"item.label\"\n [thyShowOptionCustom]=\"item.showOptionCustom\"\n [thySearchKey]=\"item.searchKey\"\n [thyDisabled]=\"item.disabled\"\n [thyTemplate]=\"item.template\"\n [thyShowCheckedIcon]=\"isMultiple()\"\n [thySelectedValuesMap]=\"selectedValuesMap()\"\n [thyActivatedValue]=\"activatedValue()\"\n (optionHover)=\"optionHover($event)\"\n (optionClick)=\"optionClick($event)\">\n </thy-option-render>\n }\n </ng-template>\n </cdk-virtual-scroll-viewport>\n <ng-content></ng-content>\n </div>\n } @else {\n <thy-loading [thyDone]=\"thyLoadState()\" thySize=\"sm\"></thy-loading>\n <div class=\"thy-select-empty-content\">\n @if (thyLoadState()) {\n @let isSearching = keywords();\n <thy-empty\n [thyMessage]=\"isSearching ? thyEmptySearchMessageText() : thyEmptyStateText()\"\n thySize=\"sm\"\n [thyIconName]=\"emptyIcon()\"></thy-empty>\n }\n </div>\n }\n @if (thyFooterTemplate()) {\n <div [class]=\"thyFooterClass() ? thyFooterClass() : 'thy-custom-select-footer'\">\n @if (thyFooterTemplate()) {\n <ng-template [ngTemplateOutlet]=\"thyFooterTemplate()\"></ng-template>\n }\n </div>\n }\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: ThySelectControl, selector: "thy-select-control,[thySelectControl]", inputs: ["inputValue", "thyPanelOpened", "thyIsMultiple", "thyShowSearch", "thySelectedOptions", "thyDisabled", "customDisplayTemplate", "thyAllowClear", "thyPlaceholder", "thySize", "thyMaxTagCount", "thyBorderless", "thyPreset"], outputs: ["inputValueChange", "thyOnSearch", "thyOnRemove", "thyOnClear", "thyOnBlur"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: ThyStopPropagationDirective, selector: "[thyStopPropagation]", inputs: ["thyStopPropagation"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ThyLoading, selector: "thy-loading", inputs: ["thyDone", "thyTip", "thyIsMask"] }, { kind: "component", type: ThyEmpty, selector: "thy-empty", inputs: ["thyMessage", "thyTranslationKey", "thyTranslationValues", "thyEntityName", "thyEntityNameTranslateKey", "thyIconName", "thySize", "thyMarginTop", "thyTopAuto", "thyContainer", "thyImageUrl", "thyImageLoading", "thyImageFetchPriority", "thyDescription"] }, { kind: "component", type: ThyOptionRender, selector: "thy-option-render", inputs: ["thyValue", "thyRawValue", "thyLabelText", "thySearchKey", "thyDisabled", "thyShowOptionCustom", "thyTemplate", "thyTemplateContext", "thyShowCheckedIcon", "thySelectedValuesMap", "thyActivatedValue"], outputs: ["optionClick", "optionHover"] }, { kind: "component", type: ThyOptionGroupRender, selector: "thy-option-group-render", inputs: ["thyGroupLabel", "thyDisabled"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], animations: [scaleXMotion, scaleYMotion, scaleMotion], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
846
937
|
}
|
|
847
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
938
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ThySelect, decorators: [{
|
|
848
939
|
type: Component,
|
|
849
940
|
args: [{ selector: 'thy-select,thy-custom-select', exportAs: 'thySelect', providers: [
|
|
850
|
-
{
|
|
851
|
-
provide: THY_OPTION_PARENT_COMPONENT,
|
|
852
|
-
useExisting: ThySelect
|
|
853
|
-
},
|
|
854
941
|
{
|
|
855
942
|
provide: NG_VALUE_ACCESSOR,
|
|
856
943
|
useExisting: forwardRef(() => ThySelect),
|
|
857
944
|
multi: true
|
|
858
|
-
}
|
|
945
|
+
},
|
|
946
|
+
ScrollDispatcher
|
|
859
947
|
], changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
860
948
|
CdkOverlayOrigin,
|
|
861
949
|
ThySelectControl,
|
|
862
950
|
CdkConnectedOverlay,
|
|
863
951
|
ThyStopPropagationDirective,
|
|
864
952
|
NgClass,
|
|
865
|
-
ThyScrollDirective,
|
|
866
953
|
ThyLoading,
|
|
867
954
|
ThyEmpty,
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
955
|
+
ThyOptionRender,
|
|
956
|
+
ThyOptionGroupRender,
|
|
957
|
+
NgTemplateOutlet,
|
|
958
|
+
ScrollingModule
|
|
872
959
|
], host: {
|
|
873
960
|
'[class.thy-select-custom]': 'true',
|
|
874
961
|
'[class.thy-select]': 'true',
|
|
@@ -876,20 +963,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
876
963
|
'[attr.tabindex]': 'tabIndex',
|
|
877
964
|
'(focus)': 'onFocus($event)',
|
|
878
965
|
'(blur)': 'onBlur($event)'
|
|
879
|
-
}, animations: [scaleXMotion, scaleYMotion, scaleMotion], template: "<div\n cdk-overlay-origin\n thySelectControl\n (click)=\"toggle($event)\"\n #origin=\"cdkOverlayOrigin\"\n #trigger\n [thyPanelOpened]=\"panelOpen\"\n [thySelectedOptions]=\"
|
|
880
|
-
}], ctorParameters: () => [], propDecorators: { thyDropdownWidthMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyDropdownWidthMode", required: false }] }], cdkConnectedOverlay: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkConnectedOverlay), { isSignal: true }] }], thyOnSearch: [{ type: i0.Output, args: ["thyOnSearch"] }], thyOnScrollToBottom: [{ type: i0.Output, args: ["thyOnScrollToBottom"] }], thyOnExpandStatusChange: [{ type: i0.Output, args: ["thyOnExpandStatusChange"] }], thyShowSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyShowSearch", required: false }] }], thyPlaceHolder: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyPlaceHolder", required: false }] }], thyServerSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyServerSearch", required: false }] }], thyLoadState: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyLoadState", required: false }] }], thyAutoActiveFirstItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyAutoActiveFirstItem", required: false }] }], thyMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyMode", required: false }] }], thySize: [{ type: i0.Input, args: [{ isSignal: true, alias: "thySize", required: false }] }], thyEmptyStateText: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyEmptyStateText", required: false }] }], thyEmptySearchMessageText: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyEmptySearchMessageText", required: false }] }], thyEnableScrollLoad: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyEnableScrollLoad", required: false }] }], thyAllowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyAllowClear", required: false }] }], thyDisabled: [{
|
|
966
|
+
}, animations: [scaleXMotion, scaleYMotion, scaleMotion], template: "<div\n cdk-overlay-origin\n thySelectControl\n (click)=\"toggle($event)\"\n #origin=\"cdkOverlayOrigin\"\n #trigger\n [thyPanelOpened]=\"panelOpen\"\n [thySelectedOptions]=\"selectedOptions()\"\n [thyIsMultiple]=\"isMultiple()\"\n [thyShowSearch]=\"thyShowSearch()\"\n [thyAllowClear]=\"thyAllowClear()\"\n [thySize]=\"thySize()\"\n [thyPlaceholder]=\"thyPlaceHolder()\"\n [customDisplayTemplate]=\"selectedValueDisplayRef()\"\n [thyDisabled]=\"disabled\"\n [thyBorderless]=\"thyBorderless()\"\n (thyOnClear)=\"clearSelectValue($event)\"\n (thyOnRemove)=\"remove($event)\"\n (thyOnSearch)=\"search($event)\"\n (thyOnBlur)=\"onBlur($event)\"\n [thyMaxTagCount]=\"thyMaxTagCount()\"\n [thyPreset]=\"thyPreset()\"></div>\n\n<ng-template\n cdk-connected-overlay\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n [cdkConnectedOverlayHasBackdrop]=\"thyHasBackdrop()\"\n [cdkConnectedOverlayPositions]=\"dropDownPositions()\"\n [cdkConnectedOverlayOrigin]=\"thyOrigin() || origin\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayWidth]=\"triggerRectWidth()\"\n [cdkConnectedOverlayMinWidth]=\"dropDownMinWidth()\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n cdkConnectedOverlayTransformOriginOn=\".thy-select-dropdown\"\n (detach)=\"close()\">\n <div\n thyStopPropagation\n [attr.tabindex]=\"-1\"\n [ngClass]=\"dropDownClass()\"\n [@scaleYMotion]=\"placement() === 'top' || placement() === 'bottom' ? 'enter' : 'void'\"\n [@scaleXMotion]=\"placement() === 'left' || placement() === 'right' ? 'enter' : 'void'\"\n [@scaleMotion]=\"\n placement() !== 'top' && placement() !== 'bottom' && placement() !== 'left' && placement() !== 'right' ? 'enter' : 'void'\n \">\n @if (filteredGroupsAndOptions()?.length > 0) {\n <div\n #panel\n class=\"thy-select-dropdown-options thy-select-dropdown-options-{{ thySize() }} thy-select-dropdown-options-with-virtual-scroll\">\n <cdk-virtual-scroll-viewport\n class=\"thy-select-scroll-viewport\"\n [itemSize]=\"thyItemSize()\"\n [style.height.px]=\"virtualHeight()\"\n (scrolledIndexChange)=\"optionsScrolled($event)\"\n (mouseleave)=\"mouseLeaveOptions()\">\n <ng-template\n cdkVirtualFor\n [cdkVirtualForOf]=\"filteredGroupsAndOptions()\"\n [cdkVirtualForTrackBy]=\"trackByFn\"\n [cdkVirtualForTemplateCacheSize]=\"0\"\n let-item>\n @if (item.type === 'group') {\n <thy-option-group-render [thyGroupLabel]=\"item.label\"></thy-option-group-render>\n } @else {\n <thy-option-render\n [thyValue]=\"item.value\"\n [thyRawValue]=\"item.rawValue\"\n [thyLabelText]=\"item.label\"\n [thyShowOptionCustom]=\"item.showOptionCustom\"\n [thySearchKey]=\"item.searchKey\"\n [thyDisabled]=\"item.disabled\"\n [thyTemplate]=\"item.template\"\n [thyShowCheckedIcon]=\"isMultiple()\"\n [thySelectedValuesMap]=\"selectedValuesMap()\"\n [thyActivatedValue]=\"activatedValue()\"\n (optionHover)=\"optionHover($event)\"\n (optionClick)=\"optionClick($event)\">\n </thy-option-render>\n }\n </ng-template>\n </cdk-virtual-scroll-viewport>\n <ng-content></ng-content>\n </div>\n } @else {\n <thy-loading [thyDone]=\"thyLoadState()\" thySize=\"sm\"></thy-loading>\n <div class=\"thy-select-empty-content\">\n @if (thyLoadState()) {\n @let isSearching = keywords();\n <thy-empty\n [thyMessage]=\"isSearching ? thyEmptySearchMessageText() : thyEmptyStateText()\"\n thySize=\"sm\"\n [thyIconName]=\"emptyIcon()\"></thy-empty>\n }\n </div>\n }\n @if (thyFooterTemplate()) {\n <div [class]=\"thyFooterClass() ? thyFooterClass() : 'thy-custom-select-footer'\">\n @if (thyFooterTemplate()) {\n <ng-template [ngTemplateOutlet]=\"thyFooterTemplate()\"></ng-template>\n }\n </div>\n }\n </div>\n</ng-template>\n" }]
|
|
967
|
+
}], ctorParameters: () => [], propDecorators: { thyDropdownWidthMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyDropdownWidthMode", required: false }] }], thyItemSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyItemSize", required: false }] }], cdkConnectedOverlay: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkConnectedOverlay), { isSignal: true }] }], thyOnSearch: [{ type: i0.Output, args: ["thyOnSearch"] }], thyOnScrollToBottom: [{ type: i0.Output, args: ["thyOnScrollToBottom"] }], thyOnExpandStatusChange: [{ type: i0.Output, args: ["thyOnExpandStatusChange"] }], thyShowSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyShowSearch", required: false }] }], thyPlaceHolder: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyPlaceHolder", required: false }] }], thyServerSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyServerSearch", required: false }] }], thyLoadState: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyLoadState", required: false }] }], thyAutoActiveFirstItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyAutoActiveFirstItem", required: false }] }], thyMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyMode", required: false }] }], thySize: [{ type: i0.Input, args: [{ isSignal: true, alias: "thySize", required: false }] }], thyEmptyStateText: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyEmptyStateText", required: false }] }], thyEmptySearchMessageText: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyEmptySearchMessageText", required: false }] }], thyEnableScrollLoad: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyEnableScrollLoad", required: false }] }], thyAllowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyAllowClear", required: false }] }], thyDisabled: [{
|
|
881
968
|
type: Input,
|
|
882
969
|
args: [{ transform: coerceBooleanProperty }]
|
|
883
|
-
}], thySortComparator: [{ type: i0.Input, args: [{ isSignal: true, alias: "thySortComparator", required: false }] }], thyFooterTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyFooterTemplate", required: false }] }], thyPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyPlacement", required: false }] }], thyOrigin: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyOrigin", required: false }] }], thyFooterClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyFooterClass", required: false }] }], selectedValueDisplayRef: [{ type: i0.ContentChild, args: ['selectedDisplay', { isSignal: true }] }], thyAutoExpand: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyAutoExpand", required: false }] }], thyHasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyHasBackdrop", required: false }] }], thyMaxTagCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyMaxTagCount", required: false }] }], thyBorderless: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyBorderless", required: false }] }], thyOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyOptions", required: false }] }], thyPreset: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyPreset", required: false }] }], trigger: [{
|
|
970
|
+
}], thySortComparator: [{ type: i0.Input, args: [{ isSignal: true, alias: "thySortComparator", required: false }] }], thyFooterTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyFooterTemplate", required: false }] }], thyPlacement: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyPlacement", required: false }] }], thyOrigin: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyOrigin", required: false }] }], thyFooterClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyFooterClass", required: false }] }], selectedValueDisplayRef: [{ type: i0.ContentChild, args: ['selectedDisplay', { isSignal: true }] }], thyAutoExpand: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyAutoExpand", required: false }] }], thyHasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyHasBackdrop", required: false }] }], thyMaxTagCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyMaxTagCount", required: false }] }], thyBorderless: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyBorderless", required: false }] }], cdkVirtualScrollViewport: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkVirtualScrollViewport), { isSignal: true }] }], thyOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyOptions", required: false }] }], thyPreset: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyPreset", required: false }] }], trigger: [{
|
|
884
971
|
type: ViewChild,
|
|
885
972
|
args: ['trigger', { read: ElementRef, static: true }]
|
|
886
|
-
}],
|
|
887
|
-
type: ContentChildren,
|
|
888
|
-
args: [ThyOption, { descendants: true }]
|
|
889
|
-
}], viewOptions: [{
|
|
973
|
+
}], options: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ThyOption), { ...{ descendants: true }, isSignal: true }] }], groups: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ThySelectOptionGroup), { ...{ descendants: true }, isSignal: true }] }], optionRenders: [{
|
|
890
974
|
type: ViewChildren,
|
|
891
|
-
args: [
|
|
892
|
-
}],
|
|
975
|
+
args: [ThyOptionRender]
|
|
976
|
+
}], keydown: [{
|
|
893
977
|
type: HostListener,
|
|
894
978
|
args: ['keydown', ['$event']]
|
|
895
979
|
}] } });
|
|
@@ -911,7 +995,7 @@ class ThyNativeSelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
911
995
|
}
|
|
912
996
|
constructor() {
|
|
913
997
|
super();
|
|
914
|
-
this.selectElement = viewChild('select'
|
|
998
|
+
this.selectElement = viewChild.required('select');
|
|
915
999
|
this.innerValue = model(null, ...(ngDevMode ? [{ debugName: "innerValue" }] : []));
|
|
916
1000
|
this.disabled = signal(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
917
1001
|
this.hostRenderer = useHostRenderer();
|
|
@@ -942,16 +1026,16 @@ class ThyNativeSelect extends TabIndexDisabledControlValueAccessorMixin {
|
|
|
942
1026
|
this.innerValue.set('');
|
|
943
1027
|
this.onChangeFn(this.innerValue());
|
|
944
1028
|
}
|
|
945
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
946
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.
|
|
1029
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ThyNativeSelect, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1030
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ThyNativeSelect, isStandalone: true, selector: "thy-native-select", inputs: { innerValue: { classPropertyName: "innerValue", publicName: "innerValue", isSignal: true, isRequired: false, transformFunction: null }, thySize: { classPropertyName: "thySize", publicName: "thySize", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, thyAllowClear: { classPropertyName: "thyAllowClear", publicName: "thyAllowClear", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { innerValue: "innerValueChange" }, host: { listeners: { "focus": "onFocus($event)", "blur": "onBlur($event)" }, properties: { "attr.tabindex": "tabIndex" }, classAttribute: "thy-select" }, providers: [
|
|
947
1031
|
{
|
|
948
1032
|
provide: NG_VALUE_ACCESSOR,
|
|
949
1033
|
useExisting: forwardRef(() => ThyNativeSelect),
|
|
950
1034
|
multi: true
|
|
951
1035
|
}
|
|
952
|
-
], viewQueries: [{ propertyName: "selectElement", first: true, predicate: ["select"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<select\n #select\n thyInput\n [tabindex]=\"-1\"\n [thySize]=\"thySize()\"\n [disabled]=\"disabled()\"\n [(ngModel)]=\"innerValue\"\n (ngModelChange)=\"ngModelChange()\"\n (blur)=\"onBlur($event)\"\n [class.thy-select-selection-allow-clear]=\"thyAllowClear()\">\n <ng-content></ng-content>\n</select>\n<thy-icon thyIconName=\"angle-down\"></thy-icon>\n@if (thyAllowClear() && innerValue()) {\n <a class=\"thy-select-remove remove-link\" href=\"javascript:;\" (click)=\"clearSelectValue($event)\">\n <thy-icon class=\"remove-link-icon\" thyIconName=\"close-circle-bold-fill\"></thy-icon>\n </a>\n}\n", dependencies: [{ kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }] }); }
|
|
1036
|
+
], viewQueries: [{ propertyName: "selectElement", first: true, predicate: ["select"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<select\n #select\n thyInput\n [tabindex]=\"-1\"\n [thySize]=\"thySize()\"\n [disabled]=\"disabled()\"\n [(ngModel)]=\"innerValue\"\n (ngModelChange)=\"ngModelChange()\"\n (blur)=\"onBlur($event)\"\n [class.thy-select-selection-allow-clear]=\"thyAllowClear()\">\n <ng-content></ng-content>\n</select>\n<thy-icon thyIconName=\"angle-down\"></thy-icon>\n@if (thyAllowClear() && innerValue()) {\n <a class=\"thy-select-remove remove-link\" href=\"javascript:;\" (click)=\"clearSelectValue($event)\">\n <thy-icon class=\"remove-link-icon\" thyIconName=\"close-circle-bold-fill\"></thy-icon>\n </a>\n}\n", dependencies: [{ kind: "directive", type: ThyInputDirective, selector: "input[thyInput], select[thyInput], textarea[thyInput]", inputs: ["thySize"], exportAs: ["thyInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }] }); }
|
|
953
1037
|
}
|
|
954
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1038
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ThyNativeSelect, decorators: [{
|
|
955
1039
|
type: Component,
|
|
956
1040
|
args: [{ selector: 'thy-native-select', providers: [
|
|
957
1041
|
{
|
|
@@ -968,8 +1052,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
968
1052
|
}], ctorParameters: () => [], propDecorators: { selectElement: [{ type: i0.ViewChild, args: ['select', { isSignal: true }] }], innerValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "innerValue", required: false }] }, { type: i0.Output, args: ["innerValueChange"] }], thySize: [{ type: i0.Input, args: [{ isSignal: true, alias: "thySize", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], thyAllowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "thyAllowClear", required: false }] }] } });
|
|
969
1053
|
|
|
970
1054
|
class ThySelectModule {
|
|
971
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
972
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
1055
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ThySelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1056
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: ThySelectModule, imports: [CommonModule,
|
|
973
1057
|
FormsModule,
|
|
974
1058
|
ThyInputModule,
|
|
975
1059
|
OverlayModule,
|
|
@@ -981,7 +1065,7 @@ class ThySelectModule {
|
|
|
981
1065
|
ThyOptionModule,
|
|
982
1066
|
ThyNativeSelect,
|
|
983
1067
|
ThySelect], exports: [ThyNativeSelect, ThySelect, ThyOptionModule] }); }
|
|
984
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
1068
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ThySelectModule, providers: [THY_SELECT_SCROLL_STRATEGY_PROVIDER, THY_SELECT_CONFIG_PROVIDER], imports: [CommonModule,
|
|
985
1069
|
FormsModule,
|
|
986
1070
|
ThyInputModule,
|
|
987
1071
|
OverlayModule,
|
|
@@ -994,7 +1078,7 @@ class ThySelectModule {
|
|
|
994
1078
|
ThyNativeSelect,
|
|
995
1079
|
ThySelect, ThyOptionModule] }); }
|
|
996
1080
|
}
|
|
997
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1081
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ThySelectModule, decorators: [{
|
|
998
1082
|
type: NgModule,
|
|
999
1083
|
args: [{
|
|
1000
1084
|
imports: [
|