ngx-tethys 19.1.0-next.5 → 19.1.0-next.7

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.
Files changed (107) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/color-picker/coordinates.directive.d.ts +1 -2
  3. package/date-picker/abstract-picker.component.d.ts +50 -52
  4. package/date-picker/abstract-picker.directive.d.ts +15 -40
  5. package/date-picker/base-picker.component.d.ts +12 -40
  6. package/date-picker/date-picker.config.d.ts +1 -0
  7. package/date-picker/lib/calendar/calendar-footer.component.d.ts +24 -19
  8. package/date-picker/lib/calendar/calendar-header.component.d.ts +15 -15
  9. package/date-picker/lib/calendar/calendar-table.component.d.ts +15 -16
  10. package/date-picker/lib/date/date-table-cell.component.d.ts +2 -3
  11. package/date-picker/lib/date/date-table.component.d.ts +2 -3
  12. package/date-picker/lib/date-carousel/date-carousel.component.d.ts +2 -3
  13. package/date-picker/lib/decade/decade-header.component.d.ts +2 -5
  14. package/date-picker/lib/decade/decade-table.component.d.ts +3 -5
  15. package/date-picker/lib/month/month-table.component.d.ts +1 -2
  16. package/date-picker/lib/popups/date-popup.component.d.ts +33 -34
  17. package/date-picker/lib/popups/inner-popup.component.d.ts +22 -29
  18. package/date-picker/lib/quarter/quarter-table.component.d.ts +1 -4
  19. package/date-picker/lib/year/year-header.component.d.ts +2 -4
  20. package/date-picker/lib/year/year-table.component.d.ts +2 -4
  21. package/date-picker/month-picker.component.d.ts +2 -2
  22. package/date-picker/picker.component.d.ts +31 -36
  23. package/date-picker/picker.pipes.d.ts +4 -5
  24. package/date-picker/picker.util.d.ts +5 -5
  25. package/date-picker/picker.validators.d.ts +4 -8
  26. package/date-picker/quarter-picker.component.d.ts +2 -3
  27. package/date-picker/week-picker.component.d.ts +0 -1
  28. package/date-picker/year-picker.component.d.ts +2 -3
  29. package/dropdown/dropdown-menu.component.d.ts +1 -1
  30. package/dropdown/dropdown.directive.d.ts +4 -3
  31. package/fesm2022/ngx-tethys-autocomplete.mjs +4 -4
  32. package/fesm2022/ngx-tethys-autocomplete.mjs.map +1 -1
  33. package/fesm2022/ngx-tethys-checkbox.mjs +2 -2
  34. package/fesm2022/ngx-tethys-checkbox.mjs.map +1 -1
  35. package/fesm2022/ngx-tethys-color-picker.mjs +4 -6
  36. package/fesm2022/ngx-tethys-color-picker.mjs.map +1 -1
  37. package/fesm2022/ngx-tethys-copy.mjs +2 -2
  38. package/fesm2022/ngx-tethys-copy.mjs.map +1 -1
  39. package/fesm2022/ngx-tethys-date-picker.mjs +841 -1068
  40. package/fesm2022/ngx-tethys-date-picker.mjs.map +1 -1
  41. package/fesm2022/ngx-tethys-dropdown.mjs +9 -11
  42. package/fesm2022/ngx-tethys-dropdown.mjs.map +1 -1
  43. package/fesm2022/ngx-tethys-flexible-text.mjs +4 -5
  44. package/fesm2022/ngx-tethys-flexible-text.mjs.map +1 -1
  45. package/fesm2022/ngx-tethys-i18n.mjs +11 -6
  46. package/fesm2022/ngx-tethys-i18n.mjs.map +1 -1
  47. package/fesm2022/ngx-tethys-image.mjs +5 -7
  48. package/fesm2022/ngx-tethys-image.mjs.map +1 -1
  49. package/fesm2022/ngx-tethys-layout.mjs +291 -334
  50. package/fesm2022/ngx-tethys-layout.mjs.map +1 -1
  51. package/fesm2022/ngx-tethys-list.mjs +147 -166
  52. package/fesm2022/ngx-tethys-list.mjs.map +1 -1
  53. package/fesm2022/ngx-tethys-message.mjs +1 -2
  54. package/fesm2022/ngx-tethys-message.mjs.map +1 -1
  55. package/fesm2022/ngx-tethys-radio.mjs +4 -4
  56. package/fesm2022/ngx-tethys-radio.mjs.map +1 -1
  57. package/fesm2022/ngx-tethys-select.mjs +164 -228
  58. package/fesm2022/ngx-tethys-select.mjs.map +1 -1
  59. package/fesm2022/ngx-tethys-shared.mjs +386 -569
  60. package/fesm2022/ngx-tethys-shared.mjs.map +1 -1
  61. package/fesm2022/ngx-tethys-skeleton.mjs +1 -2
  62. package/fesm2022/ngx-tethys-skeleton.mjs.map +1 -1
  63. package/fesm2022/ngx-tethys-table.mjs +1 -2
  64. package/fesm2022/ngx-tethys-table.mjs.map +1 -1
  65. package/fesm2022/ngx-tethys-tooltip.mjs +109 -93
  66. package/fesm2022/ngx-tethys-tooltip.mjs.map +1 -1
  67. package/fesm2022/ngx-tethys-tree-select.mjs +215 -281
  68. package/fesm2022/ngx-tethys-tree-select.mjs.map +1 -1
  69. package/fesm2022/ngx-tethys.mjs +1 -1
  70. package/fesm2022/ngx-tethys.mjs.map +1 -1
  71. package/i18n/i18n.d.ts +2 -1
  72. package/i18n/locales/de-de.d.ts +2 -1
  73. package/i18n/locales/en-us.d.ts +2 -1
  74. package/i18n/locales/ja-jp.d.ts +2 -1
  75. package/i18n/locales/zh-hans.d.ts +2 -1
  76. package/i18n/locales/zh-hant.d.ts +2 -1
  77. package/image/preview/image-preview.component.d.ts +2 -2
  78. package/layout/header.component.d.ts +15 -19
  79. package/layout/layout.component.d.ts +3 -2
  80. package/layout/sidebar-header.component.d.ts +7 -8
  81. package/layout/sidebar.component.d.ts +32 -62
  82. package/list/selection/selection-list.d.ts +33 -46
  83. package/package.json +1 -1
  84. package/schematics/version.d.ts +1 -1
  85. package/schematics/version.js +1 -1
  86. package/select/custom-select/custom-select.component.d.ts +33 -56
  87. package/select/native-select/native-select.component.d.ts +7 -13
  88. package/shared/base-form-check.component.d.ts +6 -8
  89. package/shared/directives/string-or-template-outlet.directive.d.ts +5 -6
  90. package/shared/directives/thy-autofocus.directive.d.ts +4 -6
  91. package/shared/directives/thy-contextmenu.directive.d.ts +2 -2
  92. package/shared/directives/thy-ctrl-enter.directive.d.ts +2 -2
  93. package/shared/directives/thy-enter.directive.d.ts +2 -2
  94. package/shared/directives/thy-scroll.directive.d.ts +5 -8
  95. package/shared/directives/thy-show.d.ts +5 -6
  96. package/shared/directives/thy-stop-propagation.directive.d.ts +4 -4
  97. package/shared/directives/view-outlet.directive.d.ts +6 -7
  98. package/shared/ng-transclude.directive.d.ts +2 -3
  99. package/shared/option/group/option-group.component.d.ts +5 -9
  100. package/shared/option/list-option/list-option.component.d.ts +9 -13
  101. package/shared/option/option.component.d.ts +10 -17
  102. package/shared/option/option.token.d.ts +4 -3
  103. package/shared/option/options-container.component.d.ts +1 -1
  104. package/shared/select/select-control/select-control.component.d.ts +27 -47
  105. package/table/table-column.component.d.ts +15 -5
  106. package/tooltip/tooltip.directive.d.ts +20 -22
  107. package/tree-select/tree-select.component.d.ts +53 -70
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ViewContainerRef, Input, Directive, ElementRef, NgZone, Renderer2, EventEmitter, Output, ContentChildren, KeyValueDiffers, TemplateRef, ChangeDetectorRef, NgModule, HostBinding, numberAttribute, ViewChild, ChangeDetectionStrategy, Component, InjectionToken, HostListener, ViewEncapsulation } from '@angular/core';
2
+ import { input, inject, ViewContainerRef, effect, Directive, ElementRef, NgZone, Renderer2, output, computed, ContentChildren, KeyValueDiffers, TemplateRef, ChangeDetectorRef, NgModule, Input, linkedSignal, numberAttribute, viewChild, untracked, ChangeDetectionStrategy, Component, InjectionToken, HostListener, ViewEncapsulation, signal } from '@angular/core';
3
3
  import { reqAnimFrame, TabIndexDisabledControlValueAccessorMixin, ThyTranslate, mixinDisabled, MixinBase } from 'ngx-tethys/core';
4
4
  import { coerceBooleanProperty, keycodes, isTemplateRef, isUndefinedOrNull, ENTER, SPACE, hasModifierKey } from 'ngx-tethys/util';
5
5
  import { useHostRenderer } from '@tethys/cdk/dom';
@@ -14,35 +14,32 @@ import * as i1 from '@angular/forms';
14
14
  import { FormsModule } from '@angular/forms';
15
15
  import * as i2 from 'ngx-tethys/grid';
16
16
  import { ThyGridModule } from 'ngx-tethys/grid';
17
+ import { outputToObservable } from '@angular/core/rxjs-interop';
17
18
 
18
19
  /**
19
20
  * @private
20
21
  */
21
22
  class ThyTranscludeDirective {
22
- set thyTransclude(templateRef) {
23
- this._ngTransclude = templateRef;
24
- if (templateRef) {
25
- this.viewRef.createEmbeddedView(templateRef);
26
- }
27
- }
28
- get thyTransclude() {
29
- return this._ngTransclude;
30
- }
31
23
  constructor() {
24
+ this.thyTransclude = input();
32
25
  const viewRef = inject(ViewContainerRef);
33
26
  this.viewRef = viewRef;
27
+ effect(() => {
28
+ const transclude = this.thyTransclude();
29
+ if (transclude) {
30
+ this.viewRef.createEmbeddedView(transclude);
31
+ }
32
+ });
34
33
  }
35
34
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyTranscludeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
36
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.8", type: ThyTranscludeDirective, isStandalone: true, selector: "[thyTransclude]", inputs: { thyTransclude: "thyTransclude" }, ngImport: i0 }); }
35
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.8", type: ThyTranscludeDirective, isStandalone: true, selector: "[thyTransclude]", inputs: { thyTransclude: { classPropertyName: "thyTransclude", publicName: "thyTransclude", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
37
36
  }
38
37
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyTranscludeDirective, decorators: [{
39
38
  type: Directive,
40
39
  args: [{
41
40
  selector: '[thyTransclude]'
42
41
  }]
43
- }], ctorParameters: () => [], propDecorators: { thyTransclude: [{
44
- type: Input
45
- }] } });
42
+ }], ctorParameters: () => [] });
46
43
 
47
44
  /**
48
45
  * 自动聚焦指令
@@ -54,50 +51,43 @@ class ThyAutofocusDirective {
54
51
  this.ngZone = inject(NgZone);
55
52
  // 自动选择,用于只读的 input 输入框,方便复制粘贴
56
53
  this._autoSelect = false;
57
- }
58
- /**
59
- * 是否自动聚焦
60
- * @default false
61
- */
62
- set thyAutofocus(value) {
63
- if (value) {
64
- // Note: this is being run outside of the Angular zone because `element.focus()` doesn't require
65
- // running change detection.
66
- this.ngZone.runOutsideAngular(() =>
67
- // Note: `element.focus()` causes re-layout and this may lead to frame drop on slower devices.
68
- // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#setting-focus
69
- // `setTimeout` is a macrotask and macrotasks are executed within the current rendering frame.
70
- // Animation tasks are executed within the next rendering frame.
71
- reqAnimFrame(() => {
72
- this.elementRef.nativeElement.focus();
73
- if (this._autoSelect && this.elementRef.nativeElement.select) {
74
- this.elementRef.nativeElement.select();
75
- }
76
- }));
77
- }
78
- }
79
- /**
80
- * 是否自动选择
81
- * @default false
82
- */
83
- set thyAutoSelect(value) {
84
- this._autoSelect = value;
54
+ /**
55
+ * 是否自动聚焦
56
+ * @default false
57
+ */
58
+ this.thyAutofocus = input(false, { transform: coerceBooleanProperty });
59
+ /**
60
+ * 是否自动选择
61
+ * @default false
62
+ */
63
+ this.thyAutoSelect = input(false, { transform: coerceBooleanProperty });
64
+ effect(() => {
65
+ if (this.thyAutofocus()) {
66
+ // Note: this is being run outside of the Angular zone because `element.focus()` doesn't require
67
+ // running change detection.
68
+ this.ngZone.runOutsideAngular(() =>
69
+ // Note: `element.focus()` causes re-layout and this may lead to frame drop on slower devices.
70
+ // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#setting-focus
71
+ // `setTimeout` is a macrotask and macrotasks are executed within the current rendering frame.
72
+ // Animation tasks are executed within the next rendering frame.
73
+ reqAnimFrame(() => {
74
+ this.elementRef.nativeElement.focus();
75
+ if (this.thyAutoSelect() && this.elementRef.nativeElement.select) {
76
+ this.elementRef.nativeElement.select();
77
+ }
78
+ }));
79
+ }
80
+ });
85
81
  }
86
82
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyAutofocusDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
87
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.8", type: ThyAutofocusDirective, isStandalone: true, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: { thyAutofocus: ["thyAutofocus", "thyAutofocus", coerceBooleanProperty], thyAutoSelect: ["thyAutoSelect", "thyAutoSelect", coerceBooleanProperty] }, ngImport: i0 }); }
83
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.8", type: ThyAutofocusDirective, isStandalone: true, selector: "input[thyAutofocus],textarea[thyAutofocus]", inputs: { thyAutofocus: { classPropertyName: "thyAutofocus", publicName: "thyAutofocus", isSignal: true, isRequired: false, transformFunction: null }, thyAutoSelect: { classPropertyName: "thyAutoSelect", publicName: "thyAutoSelect", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
88
84
  }
89
85
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyAutofocusDirective, decorators: [{
90
86
  type: Directive,
91
87
  args: [{
92
88
  selector: 'input[thyAutofocus],textarea[thyAutofocus]'
93
89
  }]
94
- }], propDecorators: { thyAutofocus: [{
95
- type: Input,
96
- args: [{ transform: coerceBooleanProperty }]
97
- }], thyAutoSelect: [{
98
- type: Input,
99
- args: [{ transform: coerceBooleanProperty }]
100
- }] } });
90
+ }], ctorParameters: () => [] });
101
91
 
102
92
  /**
103
93
  * 与 (keydown.enter) 区别是支持组合键,当按 Ctrl + Enter 或者 Command + Enter 也会触发
@@ -108,7 +98,7 @@ class ThyEnterDirective {
108
98
  this.ngZone = inject(NgZone);
109
99
  this.elementRef = inject(ElementRef);
110
100
  this.renderer = inject(Renderer2);
111
- this.thyEnter = new EventEmitter();
101
+ this.thyEnter = output();
112
102
  this.onKeydown = (event) => {
113
103
  const keyCode = event.which || event.keyCode;
114
104
  if (keyCode === keycodes.ENTER) {
@@ -134,9 +124,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
134
124
  args: [{
135
125
  selector: '[thyEnter]'
136
126
  }]
137
- }], propDecorators: { thyEnter: [{
138
- type: Output
139
- }] } });
127
+ }] });
140
128
 
141
129
  /**
142
130
  * @name thyCtrlEnter
@@ -146,7 +134,7 @@ class ThyCtrlEnterDirective {
146
134
  this.ngZone = inject(NgZone);
147
135
  this.elementRef = inject(ElementRef);
148
136
  this.renderer = inject(Renderer2);
149
- this.thyCtrlEnter = new EventEmitter();
137
+ this.thyCtrlEnter = output();
150
138
  this.onKeydown = (event) => {
151
139
  const keyCode = event.which || event.keyCode;
152
140
  if ((event.ctrlKey || event.metaKey) && keyCode === keycodes.ENTER) {
@@ -173,97 +161,91 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
173
161
  args: [{
174
162
  selector: '[thyCtrlEnter]'
175
163
  }]
176
- }], propDecorators: { thyCtrlEnter: [{
177
- type: Output
178
- }] } });
164
+ }] });
179
165
 
180
166
  /**
181
167
  * @name thyShow
182
168
  */
183
169
  class ThyShowDirective {
184
- constructor() {
185
- this.elementRef = inject(ElementRef);
186
- this.renderer = inject(Renderer2);
187
- this.ngZone = inject(NgZone);
188
- this.thyShowChange = new EventEmitter();
189
- this.hostRenderer = useHostRenderer();
190
- }
191
170
  unListenDocument() {
192
171
  if (this.unListenEvent) {
193
172
  this.unListenEvent();
194
173
  this.unListenEvent = null;
195
174
  }
196
175
  }
197
- set thyShow(condition) {
198
- if (condition) {
199
- this.hostRenderer.setStyle('display', 'block');
200
- this.ngZone.runOutsideAngular(() => setTimeout(() => {
201
- this.unListenEvent = this.renderer.listen('document', 'click', event => {
202
- if (!this.elementRef.nativeElement.contains(event.target)) {
203
- if (this.thyShowChange.observers.length) {
176
+ constructor() {
177
+ this.elementRef = inject(ElementRef);
178
+ this.renderer = inject(Renderer2);
179
+ this.ngZone = inject(NgZone);
180
+ this.thyShowChange = output();
181
+ this.hostRenderer = useHostRenderer();
182
+ this.thyShow = input(false, { transform: coerceBooleanProperty });
183
+ effect(() => {
184
+ if (this.thyShow()) {
185
+ this.hostRenderer.setStyle('display', 'block');
186
+ this.ngZone.runOutsideAngular(() => setTimeout(() => {
187
+ this.unListenEvent = this.renderer.listen('document', 'click', event => {
188
+ if (!this.elementRef.nativeElement.contains(event.target)) {
204
189
  this.ngZone.run(() => this.thyShowChange.emit(false));
190
+ this.unListenDocument();
205
191
  }
206
- this.unListenDocument();
207
- }
208
- });
209
- }));
210
- }
211
- else {
212
- this.hostRenderer.setStyle('display', 'none');
213
- this.unListenDocument();
214
- }
192
+ });
193
+ }));
194
+ }
195
+ else {
196
+ this.hostRenderer.setStyle('display', 'none');
197
+ this.unListenDocument();
198
+ }
199
+ });
215
200
  }
216
201
  ngOnDestroy() {
217
202
  this.unListenDocument();
218
203
  }
219
204
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyShowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
220
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.8", type: ThyShowDirective, isStandalone: true, selector: "[thyShow]", inputs: { thyShow: ["thyShow", "thyShow", coerceBooleanProperty] }, outputs: { thyShowChange: "thyShowChange" }, ngImport: i0 }); }
205
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.8", type: ThyShowDirective, isStandalone: true, selector: "[thyShow]", inputs: { thyShow: { classPropertyName: "thyShow", publicName: "thyShow", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { thyShowChange: "thyShowChange" }, ngImport: i0 }); }
221
206
  }
222
207
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyShowDirective, decorators: [{
223
208
  type: Directive,
224
209
  args: [{
225
210
  selector: '[thyShow]'
226
211
  }]
227
- }], propDecorators: { thyShowChange: [{
228
- type: Output
229
- }], thyShow: [{
230
- type: Input,
231
- args: [{ transform: coerceBooleanProperty }]
232
- }] } });
212
+ }], ctorParameters: () => [] });
233
213
 
234
214
  /**
235
215
  * 阻止事件冒泡
236
216
  * @name thyStopPropagation
237
217
  */
238
218
  class ThyStopPropagationDirective {
239
- set thyStopPropagation(value) {
240
- if (value === false || value === 'false') {
241
- this._shouldStopPropagation = false;
242
- }
243
- else {
244
- this._shouldStopPropagation = true;
245
- if (!value || value === true || value === 'true') {
246
- this._eventName = 'click';
247
- }
248
- else {
249
- this._eventName = value;
250
- }
251
- }
252
- this._changes$.next();
253
- }
254
219
  constructor() {
255
- this._eventName = 'click';
256
- this._shouldStopPropagation = true;
220
+ this.thyStopPropagation = input(true);
221
+ this._eventName = computed(() => {
222
+ const stopPropagation = this.thyStopPropagation();
223
+ if (stopPropagation !== false) {
224
+ if (!stopPropagation || stopPropagation === true || stopPropagation === 'true') {
225
+ return 'click';
226
+ }
227
+ else {
228
+ return stopPropagation;
229
+ }
230
+ }
231
+ });
232
+ this._shouldStopPropagation = computed(() => {
233
+ const stopPropagation = this.thyStopPropagation();
234
+ return stopPropagation === false || stopPropagation === 'false' ? false : true;
235
+ });
257
236
  this._changes$ = new Subject();
258
237
  this._destroy$ = new Subject();
259
238
  const _host = inject(ElementRef);
260
239
  const _ngZone = inject(NgZone);
240
+ effect(() => {
241
+ this._changes$.next(this.thyStopPropagation());
242
+ });
261
243
  this._changes$
262
244
  .pipe(
263
245
  // Note: we start the stream immediately since the `thyStopPropagation` setter may never be reached.
264
- startWith(null), switchMap(() => new Observable(subscriber => _ngZone.runOutsideAngular(() => fromEvent(_host.nativeElement, this._eventName).subscribe(subscriber)))), takeUntil(this._destroy$))
246
+ startWith(null), switchMap(() => new Observable(subscriber => _ngZone.runOutsideAngular(() => fromEvent(_host.nativeElement, this._eventName()).subscribe(subscriber)))), takeUntil(this._destroy$))
265
247
  .subscribe(event => {
266
- if (this._shouldStopPropagation) {
248
+ if (this._shouldStopPropagation()) {
267
249
  event.stopPropagation();
268
250
  }
269
251
  });
@@ -272,16 +254,14 @@ class ThyStopPropagationDirective {
272
254
  this._destroy$.next();
273
255
  }
274
256
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyStopPropagationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
275
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.8", type: ThyStopPropagationDirective, isStandalone: true, selector: "[thyStopPropagation]", inputs: { thyStopPropagation: "thyStopPropagation" }, ngImport: i0 }); }
257
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.8", type: ThyStopPropagationDirective, isStandalone: true, selector: "[thyStopPropagation]", inputs: { thyStopPropagation: { classPropertyName: "thyStopPropagation", publicName: "thyStopPropagation", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
276
258
  }
277
259
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyStopPropagationDirective, decorators: [{
278
260
  type: Directive,
279
261
  args: [{
280
262
  selector: '[thyStopPropagation]'
281
263
  }]
282
- }], ctorParameters: () => [], propDecorators: { thyStopPropagation: [{
283
- type: Input
284
- }] } });
264
+ }], ctorParameters: () => [] });
285
265
 
286
266
  /**
287
267
  * @name thyContextMenu
@@ -291,7 +271,7 @@ class ThyContextMenuDirective {
291
271
  this.ngZone = inject(NgZone);
292
272
  this.elementRef = inject(ElementRef);
293
273
  this.renderer = inject(Renderer2);
294
- this.thyContextMenu = new EventEmitter();
274
+ this.thyContextMenu = output();
295
275
  this.rightClick = (event) => {
296
276
  event.preventDefault();
297
277
  this.ngZone.run(() => {
@@ -315,9 +295,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
315
295
  args: [{
316
296
  selector: '[thyContextMenu]'
317
297
  }]
318
- }], propDecorators: { thyContextMenu: [{
319
- type: Output
320
- }] } });
298
+ }] });
321
299
 
322
300
  const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true });
323
301
  /**
@@ -328,11 +306,10 @@ class ThyScrollDirective {
328
306
  this.elementRef = inject(ElementRef);
329
307
  this.ngZone = inject(NgZone);
330
308
  this._destroyed = new Subject();
331
- this._enable = true;
332
- this._initialled = false;
333
309
  this._elementScrolled = new Observable((observer) => this.ngZone.runOutsideAngular(() => fromEvent(this.elementRef.nativeElement, 'scroll', passiveEventListenerOptions)
334
310
  .pipe(takeUntil(this._destroyed))
335
311
  .subscribe(observer)));
312
+ this.thyEnable = input(true, { transform: coerceBooleanProperty });
336
313
  /**
337
314
  * @description
338
315
  *
@@ -352,12 +329,10 @@ class ThyScrollDirective {
352
329
  * }
353
330
  * ```
354
331
  */
355
- this.thyOnScrolled = new EventEmitter();
356
- }
357
- set thyEnable(value) {
358
- this._enable = value;
359
- if (this._initialled) {
360
- if (this._enable && this._subscription === null) {
332
+ this.thyOnScrolled = output();
333
+ effect(() => {
334
+ const thyEnable = this.thyEnable();
335
+ if (thyEnable && !this._subscription) {
361
336
  this._subscription = this._elementScrolled.subscribe(() => this.thyOnScrolled.emit(this.elementRef));
362
337
  }
363
338
  else {
@@ -366,14 +341,9 @@ class ThyScrollDirective {
366
341
  this._subscription = null;
367
342
  }
368
343
  }
369
- }
370
- }
371
- ngOnInit() {
372
- if (this._enable) {
373
- this._subscription = this._elementScrolled.subscribe(() => this.thyOnScrolled.emit(this.elementRef));
374
- }
375
- this._initialled = true;
344
+ });
376
345
  }
346
+ ngOnInit() { }
377
347
  ngOnDestroy() {
378
348
  this._destroyed.next();
379
349
  this._destroyed.complete();
@@ -382,19 +352,14 @@ class ThyScrollDirective {
382
352
  return this.elementRef;
383
353
  }
384
354
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
385
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.8", type: ThyScrollDirective, isStandalone: true, selector: "[thyScroll]", inputs: { thyEnable: ["thyEnable", "thyEnable", coerceBooleanProperty] }, outputs: { thyOnScrolled: "thyOnScrolled" }, ngImport: i0 }); }
355
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.8", type: ThyScrollDirective, isStandalone: true, selector: "[thyScroll]", inputs: { thyEnable: { classPropertyName: "thyEnable", publicName: "thyEnable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { thyOnScrolled: "thyOnScrolled" }, ngImport: i0 }); }
386
356
  }
387
357
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyScrollDirective, decorators: [{
388
358
  type: Directive,
389
359
  args: [{
390
360
  selector: '[thyScroll]'
391
361
  }]
392
- }], propDecorators: { thyEnable: [{
393
- type: Input,
394
- args: [{ transform: coerceBooleanProperty }]
395
- }], thyOnScrolled: [{
396
- type: Output
397
- }] } });
362
+ }], ctorParameters: () => [] });
398
363
 
399
364
  /**
400
365
  * @private
@@ -448,23 +413,26 @@ class ThyStringOrTemplateOutletDirective {
448
413
  constructor() {
449
414
  this.viewContainerRef = inject(ViewContainerRef);
450
415
  this.renderer = inject(Renderer2);
451
- }
452
- ngOnChanges(changes) {
453
- if (changes['thyStringOrTemplateOutlet']) {
416
+ this.thyStringOrTemplateOutletContext = input();
417
+ this.thyStringOrTemplateOutlet = input();
418
+ effect(() => {
454
419
  this.updateView();
455
- }
456
- else if (this.viewRef && changes['thyStringOrTemplateOutletContext'] && this.thyStringOrTemplateOutletContext) {
457
- this.viewRef.context = this.thyStringOrTemplateOutletContext;
458
- }
420
+ });
421
+ effect(() => {
422
+ if (this.viewRef && this.thyStringOrTemplateOutletContext()) {
423
+ this.viewRef.context = this.thyStringOrTemplateOutletContext();
424
+ }
425
+ });
459
426
  }
460
427
  updateView() {
428
+ const thyStringOrTemplateOutlet = this.thyStringOrTemplateOutlet();
461
429
  this.clear();
462
- if (this.thyStringOrTemplateOutlet) {
463
- if (isTemplateRef(this.thyStringOrTemplateOutlet)) {
464
- this.viewRef = this.viewContainerRef.createEmbeddedView(this.thyStringOrTemplateOutlet, this.thyStringOrTemplateOutletContext);
430
+ if (thyStringOrTemplateOutlet) {
431
+ if (isTemplateRef(thyStringOrTemplateOutlet)) {
432
+ this.viewRef = this.viewContainerRef.createEmbeddedView(thyStringOrTemplateOutlet, this.thyStringOrTemplateOutletContext());
465
433
  }
466
434
  else {
467
- this.textNode = this.renderer.createText(this.thyStringOrTemplateOutlet + '');
435
+ this.textNode = this.renderer.createText(thyStringOrTemplateOutlet + '');
468
436
  const element = this.viewContainerRef.element.nativeElement;
469
437
  this.renderer.insertBefore(element.parentNode, this.textNode, element);
470
438
  }
@@ -480,7 +448,7 @@ class ThyStringOrTemplateOutletDirective {
480
448
  }
481
449
  }
482
450
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyStringOrTemplateOutletDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
483
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.8", type: ThyStringOrTemplateOutletDirective, isStandalone: true, selector: "[thyStringOrTemplateOutlet]", inputs: { thyStringOrTemplateOutletContext: "thyStringOrTemplateOutletContext", thyStringOrTemplateOutlet: "thyStringOrTemplateOutlet" }, exportAs: ["thyStringOrTemplateOutlet"], usesOnChanges: true, ngImport: i0 }); }
451
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.8", type: ThyStringOrTemplateOutletDirective, isStandalone: true, selector: "[thyStringOrTemplateOutlet]", inputs: { thyStringOrTemplateOutletContext: { classPropertyName: "thyStringOrTemplateOutletContext", publicName: "thyStringOrTemplateOutletContext", isSignal: true, isRequired: false, transformFunction: null }, thyStringOrTemplateOutlet: { classPropertyName: "thyStringOrTemplateOutlet", publicName: "thyStringOrTemplateOutlet", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["thyStringOrTemplateOutlet"], ngImport: i0 }); }
484
452
  }
485
453
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyStringOrTemplateOutletDirective, decorators: [{
486
454
  type: Directive,
@@ -488,11 +456,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
488
456
  selector: '[thyStringOrTemplateOutlet]',
489
457
  exportAs: 'thyStringOrTemplateOutlet'
490
458
  }]
491
- }], propDecorators: { thyStringOrTemplateOutletContext: [{
492
- type: Input
493
- }], thyStringOrTemplateOutlet: [{
494
- type: Input
495
- }] } });
459
+ }], ctorParameters: () => [] });
496
460
 
497
461
  function hasInput(componentRef, inputKey) {
498
462
  return componentRef['_tNode'].inputs?.[inputKey];
@@ -509,37 +473,43 @@ class ThyViewOutletDirective {
509
473
  /**
510
474
  * 组件或者模板 TemplateRef
511
475
  */
512
- this.thyViewOutlet = null;
513
- }
514
- ngOnChanges(changes) {
515
- const { viewContainerRef: viewContainerRef } = this;
516
- if (changes['thyViewOutlet']) {
476
+ this.thyViewOutlet = input(null);
477
+ /**
478
+ * 组件和模板上下文传递数据
479
+ */
480
+ this.thyViewOutletContext = input();
481
+ effect(() => {
482
+ const thyViewOutlet = this.thyViewOutlet();
483
+ const { viewContainerRef: viewContainerRef } = this;
517
484
  viewContainerRef.clear();
518
485
  this.componentRef = undefined;
519
486
  this.embeddedViewRef = undefined;
520
- if (this.thyViewOutlet) {
521
- if (this.thyViewOutlet instanceof TemplateRef) {
522
- this.embeddedViewRef = viewContainerRef.createEmbeddedView(this.thyViewOutlet, this.thyViewOutletContext);
487
+ if (thyViewOutlet) {
488
+ if (thyViewOutlet instanceof TemplateRef) {
489
+ this.embeddedViewRef = viewContainerRef.createEmbeddedView(thyViewOutlet, this.thyViewOutletContext());
523
490
  }
524
491
  else {
525
- this.componentRef = viewContainerRef.createComponent(this.thyViewOutlet, {
492
+ this.componentRef = viewContainerRef.createComponent(thyViewOutlet, {
526
493
  index: viewContainerRef.length
527
494
  });
528
495
  }
529
496
  }
530
- }
531
- if (changes['thyViewOutletContext']) {
497
+ });
498
+ effect(() => {
499
+ const thyViewOutletContext = this.thyViewOutletContext();
532
500
  let updatedKeys = [];
533
- if (changes['thyViewOutletContext'].isFirstChange()) {
534
- this.keyValueDiffer = this.keyValueDiffers.find(this.thyViewOutletContext).create();
535
- this.keyValueDiffer.diff(this.thyViewOutletContext);
536
- updatedKeys = Object.keys(this.thyViewOutletContext);
537
- }
538
- else {
539
- const diffChanges = this.keyValueDiffer.diff(this.thyViewOutletContext);
540
- diffChanges?.forEachChangedItem(item => {
541
- updatedKeys.push(item.key);
542
- });
501
+ if (thyViewOutletContext) {
502
+ if (!this.keyValueDiffer) {
503
+ this.keyValueDiffer = this.keyValueDiffers.find(this.thyViewOutletContext()).create();
504
+ this.keyValueDiffer.diff(thyViewOutletContext);
505
+ updatedKeys = Object.keys(thyViewOutletContext);
506
+ }
507
+ else {
508
+ const diffChanges = this.keyValueDiffer.diff(this.thyViewOutletContext());
509
+ diffChanges?.forEachChangedItem(item => {
510
+ updatedKeys.push(item.key);
511
+ });
512
+ }
543
513
  }
544
514
  if (this.componentRef) {
545
515
  this.updateContext(this.componentRef.instance, updatedKeys);
@@ -549,32 +519,28 @@ class ThyViewOutletDirective {
549
519
  this.updateContext(this.embeddedViewRef.context, updatedKeys);
550
520
  this.embeddedViewRef.markForCheck();
551
521
  }
552
- }
522
+ });
553
523
  }
554
524
  updateContext(context, updatedKeys) {
555
525
  updatedKeys.forEach(key => {
556
526
  // 兼容组件输入属性没有通过 @Input,设置了 @Input 采用 setInput,否则直接赋值,setInput 会触发 Angular 组件的 onChanges
557
527
  if (this.componentRef && hasInput(this.componentRef, key)) {
558
- this.componentRef.setInput(key, this.thyViewOutletContext[key]);
528
+ this.componentRef.setInput(key, this.thyViewOutletContext()[key]);
559
529
  }
560
530
  else {
561
- context[key] = this.thyViewOutletContext[key];
531
+ context[key] = this.thyViewOutletContext()[key];
562
532
  }
563
533
  });
564
534
  }
565
535
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyViewOutletDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
566
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.8", type: ThyViewOutletDirective, isStandalone: true, selector: "[thyViewOutlet]", inputs: { thyViewOutlet: "thyViewOutlet", thyViewOutletContext: "thyViewOutletContext" }, usesOnChanges: true, ngImport: i0 }); }
536
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.8", type: ThyViewOutletDirective, isStandalone: true, selector: "[thyViewOutlet]", inputs: { thyViewOutlet: { classPropertyName: "thyViewOutlet", publicName: "thyViewOutlet", isSignal: true, isRequired: false, transformFunction: null }, thyViewOutletContext: { classPropertyName: "thyViewOutletContext", publicName: "thyViewOutletContext", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
567
537
  }
568
538
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyViewOutletDirective, decorators: [{
569
539
  type: Directive,
570
540
  args: [{
571
541
  selector: '[thyViewOutlet]'
572
542
  }]
573
- }], propDecorators: { thyViewOutlet: [{
574
- type: Input
575
- }], thyViewOutletContext: [{
576
- type: Input
577
- }] } });
543
+ }], ctorParameters: () => [] });
578
544
 
579
545
  class ThySharedModule {
580
546
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThySharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
@@ -639,33 +605,6 @@ const noop = () => { };
639
605
  * @private
640
606
  */
641
607
  class ThyFormCheckBaseComponent extends TabIndexDisabledControlValueAccessorMixin {
642
- get _isNoText() {
643
- return this._isFormCheckInline && !this._labelText;
644
- }
645
- /**
646
- * 是否同一行展示
647
- * @default false
648
- */
649
- set thyInline(value) {
650
- this._isFormCheckInline = value;
651
- }
652
- /**
653
- * Label 展示文本
654
- */
655
- set thyLabelText(value) {
656
- this._labelText = value;
657
- }
658
- /**
659
- * Label 文本多语言 key
660
- */
661
- set thyLabelTextTranslateKey(value) {
662
- if (value) {
663
- this._labelText = this.thyTranslate.instant(value);
664
- }
665
- else {
666
- this._labelText = '';
667
- }
668
- }
669
608
  /**
670
609
  * 是否禁用
671
610
  * @default false
@@ -709,8 +648,28 @@ class ThyFormCheckBaseComponent extends TabIndexDisabledControlValueAccessorMixi
709
648
  this.onTouchedCallback = noop;
710
649
  this.onChangeCallback = noop;
711
650
  this._isFormCheck = true;
712
- this._isFormCheckInline = false;
713
651
  this._isChecked = false;
652
+ /**
653
+ * 是否同一行展示
654
+ * @default false
655
+ */
656
+ this.thyInline = input(false, { transform: coerceBooleanProperty });
657
+ /**
658
+ * Label 展示文本
659
+ */
660
+ this.thyLabelText = input();
661
+ /**
662
+ * Label 文本多语言 key
663
+ */
664
+ this.thyLabelTextTranslateKey = input();
665
+ this._labelText = computed(() => {
666
+ const labelTextTranslateKey = this.thyLabelTextTranslateKey();
667
+ const labelText = this.thyLabelText();
668
+ return labelTextTranslateKey ? this.thyTranslate.instant(labelTextTranslateKey) : labelText || '';
669
+ });
670
+ this._isNoText = computed(() => {
671
+ return this.thyInline() && !this._labelText();
672
+ });
714
673
  this.disabled = false;
715
674
  }
716
675
  change() {
@@ -722,30 +681,19 @@ class ThyFormCheckBaseComponent extends TabIndexDisabledControlValueAccessorMixi
722
681
  }
723
682
  }
724
683
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyFormCheckBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
725
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.8", type: ThyFormCheckBaseComponent, isStandalone: true, inputs: { thyInline: ["thyInline", "thyInline", coerceBooleanProperty], thyLabelText: "thyLabelText", thyLabelTextTranslateKey: "thyLabelTextTranslateKey", thyDisabled: ["thyDisabled", "thyDisabled", coerceBooleanProperty] }, host: { properties: { "class.form-check": "this._isFormCheck", "class.form-check-inline": "this._isFormCheckInline", "class.form-check-checked": "this._isChecked", "class.form-check-inline-no-label-text": "this._isNoText" } }, usesInheritance: true, ngImport: i0 }); }
684
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.8", type: ThyFormCheckBaseComponent, isStandalone: true, inputs: { thyInline: { classPropertyName: "thyInline", publicName: "thyInline", isSignal: true, isRequired: false, transformFunction: null }, thyLabelText: { classPropertyName: "thyLabelText", publicName: "thyLabelText", isSignal: true, isRequired: false, transformFunction: null }, thyLabelTextTranslateKey: { classPropertyName: "thyLabelTextTranslateKey", publicName: "thyLabelTextTranslateKey", isSignal: true, isRequired: false, transformFunction: null }, thyDisabled: { classPropertyName: "thyDisabled", publicName: "thyDisabled", isSignal: false, isRequired: false, transformFunction: coerceBooleanProperty } }, host: { properties: { "class.form-check": "_isFormCheck", "class.form-check-inline": "thyInline()", "class.form-check-checked": "_isChecked", "class.form-check-inline-no-label-text": "_isNoText()" } }, usesInheritance: true, ngImport: i0 }); }
726
685
  }
727
686
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyFormCheckBaseComponent, decorators: [{
728
- type: Directive
729
- }], ctorParameters: () => [], propDecorators: { _isFormCheck: [{
730
- type: HostBinding,
731
- args: ['class.form-check']
732
- }], _isFormCheckInline: [{
733
- type: HostBinding,
734
- args: ['class.form-check-inline']
735
- }], _isChecked: [{
736
- type: HostBinding,
737
- args: ['class.form-check-checked']
738
- }], _isNoText: [{
739
- type: HostBinding,
740
- args: ['class.form-check-inline-no-label-text']
741
- }], thyInline: [{
742
- type: Input,
743
- args: [{ transform: coerceBooleanProperty }]
744
- }], thyLabelText: [{
745
- type: Input
746
- }], thyLabelTextTranslateKey: [{
747
- type: Input
748
- }], thyDisabled: [{
687
+ type: Directive,
688
+ args: [{
689
+ host: {
690
+ '[class.form-check]': '_isFormCheck',
691
+ '[class.form-check-inline]': 'thyInline()',
692
+ '[class.form-check-checked]': '_isChecked',
693
+ '[class.form-check-inline-no-label-text]': '_isNoText()'
694
+ }
695
+ }]
696
+ }], ctorParameters: () => [], propDecorators: { thyDisabled: [{
749
697
  type: Input,
750
698
  args: [{ transform: coerceBooleanProperty }]
751
699
  }] } });
@@ -754,117 +702,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
754
702
  * @private
755
703
  */
756
704
  class ThySelectControl {
757
- constructor() {
758
- this.renderer = inject(Renderer2);
759
- this.inputValue = '';
760
- this.isComposing = false;
761
- this.panelOpened = false;
762
- this.isMultiple = false;
763
- this.showSearch = false;
764
- this.disabled = false;
765
- this.hostRenderer = useHostRenderer();
766
- this.thyAllowClear = false;
767
- this.thyPlaceholder = '';
768
- this.thyMaxTagCount = 0;
769
- this.thyBorderless = false;
770
- this.thyPreset = '';
771
- this.thyOnSearch = new EventEmitter();
772
- this.thyOnRemove = new EventEmitter();
773
- this.thyOnClear = new EventEmitter();
774
- this.thyOnBlur = new EventEmitter();
775
- }
776
- get thyPanelOpened() {
777
- return this.panelOpened;
778
- }
779
- set thyPanelOpened(value) {
780
- this.panelOpened = value;
781
- if (this.panelOpened && this.thyShowSearch) {
782
- Promise.resolve(null).then(() => {
783
- this.inputElement.nativeElement.focus();
784
- });
785
- }
786
- if (!this.panelOpened && this.thyShowSearch) {
787
- new Promise(resolve => setTimeout(resolve, 100)).then(() => {
788
- this.inputValue = '';
789
- this.updateWidth();
790
- this.thyOnSearch.emit(this.inputValue);
791
- });
792
- }
793
- this.setSelectControlClass();
794
- }
795
- get thyIsMultiple() {
796
- return this.isMultiple;
797
- }
798
- set thyIsMultiple(value) {
799
- this.isMultiple = value;
800
- this.setSelectControlClass();
801
- }
802
- get thyShowSearch() {
803
- return this.showSearch;
804
- }
805
- set thyShowSearch(value) {
806
- this.showSearch = value;
807
- this.setSelectControlClass();
808
- }
809
- get thySelectedOptions() {
810
- return this.selectedOptions;
811
- }
812
- set thySelectedOptions(value) {
813
- let sameValue = false;
814
- const oldValue = this.selectedOptions;
815
- if (this.isMultiple) {
816
- if (oldValue instanceof Array && value instanceof Array && oldValue.length === value.length) {
817
- sameValue = value.every((option, index) => option.thyValue === oldValue[index].thyValue);
818
- }
819
- }
820
- else {
821
- if (oldValue && value) {
822
- sameValue = oldValue.thyValue === value.thyValue;
823
- }
824
- }
825
- this.selectedOptions = value;
826
- if (this.panelOpened && this.thyShowSearch) {
827
- if (!sameValue) {
828
- Promise.resolve(null).then(() => {
829
- this.inputValue = '';
830
- this.updateWidth();
831
- });
832
- }
833
- //等待组件渲染好再聚焦
834
- setTimeout(() => {
835
- if (this.panelOpened) {
836
- this.inputElement.nativeElement.focus();
837
- }
838
- }, 200);
839
- }
840
- }
841
- get thyDisabled() {
842
- return this.disabled;
843
- }
844
- set thyDisabled(value) {
845
- this.disabled = value;
846
- this.setSelectControlClass();
847
- }
848
- get thySize() {
849
- return this.size;
850
- }
851
- set thySize(value) {
852
- this.size = value;
853
- this.setSelectControlClass();
854
- if (value === 'xs' || value === 'sm') {
855
- this.tagSize = 'sm';
856
- }
857
- else if (value === 'lg') {
858
- this.tagSize = 'lg';
859
- }
860
- else {
861
- this.tagSize = 'md';
862
- }
863
- }
864
705
  get selectedValueStyle() {
865
706
  let showSelectedValue = false;
866
- if (this.showSearch) {
867
- if (this.panelOpened) {
707
+ if (this.thyShowSearch()) {
708
+ if (this.thyPanelOpened()) {
868
709
  showSelectedValue = !(this.isComposing || this.inputValue);
869
710
  }
870
711
  else {
@@ -878,10 +719,10 @@ class ThySelectControl {
878
719
  }
879
720
  get placeholderStyle() {
880
721
  let placeholder = true;
881
- if (this.isSelectedValue) {
722
+ if (this.isSelectedValue()) {
882
723
  placeholder = false;
883
724
  }
884
- if (!this.thyPlaceholder) {
725
+ if (!this.thyPlaceholder()) {
885
726
  placeholder = false;
886
727
  }
887
728
  if (this.isComposing || this.inputValue) {
@@ -889,47 +730,138 @@ class ThySelectControl {
889
730
  }
890
731
  return { display: placeholder ? 'block' : 'none' };
891
732
  }
892
- get selectedValue() {
893
- return this.thySelectedOptions;
894
- }
895
- get multipleSelectedValue() {
896
- return this.thySelectedOptions;
897
- }
898
- get maxSelectedTags() {
899
- if (this.thyMaxTagCount > 0 && this.thySelectedOptions instanceof Array && this.thySelectedOptions.length > this.thyMaxTagCount) {
900
- return this.thySelectedOptions.slice(0, this.thyMaxTagCount - 1);
901
- }
902
- return this.thySelectedOptions;
903
- }
904
- get showClearIcon() {
905
- return this.thyAllowClear && this.isSelectedValue;
906
- }
907
- get isSelectedValue() {
908
- return ((!this.isMultiple && !isUndefinedOrNull(this.thySelectedOptions)) ||
909
- (this.isMultiple && this.thySelectedOptions.length > 0));
910
- }
911
- ngOnInit() {
912
- this.setSelectControlClass();
733
+ constructor() {
734
+ this.renderer = inject(Renderer2);
735
+ this.inputValue = '';
736
+ this.isComposing = false;
737
+ this.hostRenderer = useHostRenderer();
738
+ this.thyPanelOpened = input(false, { transform: coerceBooleanProperty });
739
+ this.thyIsMultiple = input(false, { transform: coerceBooleanProperty });
740
+ this.thyShowSearch = input(false, { transform: coerceBooleanProperty });
741
+ this.thySelectedOptions = input();
742
+ this.previousSelectedOptions = linkedSignal({
743
+ source: () => this.thySelectedOptions(),
744
+ computation: (source, previous) => previous?.source
745
+ });
746
+ this.thyDisabled = input(false, { transform: coerceBooleanProperty });
747
+ this.customDisplayTemplate = input(undefined);
748
+ this.thyAllowClear = input(false, { transform: coerceBooleanProperty });
749
+ this.thyPlaceholder = input('');
750
+ this.thySize = input();
751
+ this.tagSize = computed(() => {
752
+ const value = this.thySize();
753
+ if (value === 'xs' || value === 'sm') {
754
+ return 'sm';
755
+ }
756
+ else if (value === 'lg') {
757
+ return 'lg';
758
+ }
759
+ else {
760
+ return 'md';
761
+ }
762
+ });
763
+ this.thyMaxTagCount = input(0, { transform: numberAttribute });
764
+ this.thyBorderless = input(false, { transform: coerceBooleanProperty });
765
+ this.thyPreset = input('');
766
+ this.thyOnSearch = output();
767
+ this.thyOnRemove = output();
768
+ this.thyOnClear = output();
769
+ this.thyOnBlur = output();
770
+ this.inputElement = viewChild('inputElement');
771
+ this.isSelectedValue = computed(() => {
772
+ return ((!this.thyIsMultiple() && !isUndefinedOrNull(this.thySelectedOptions())) ||
773
+ (this.thyIsMultiple() && this.thySelectedOptions().length > 0));
774
+ });
775
+ this.showClearIcon = computed(() => {
776
+ return this.thyAllowClear() && this.isSelectedValue();
777
+ });
778
+ this.maxSelectedTags = computed(() => {
779
+ const selectedOptions = this.thySelectedOptions();
780
+ if (this.thyMaxTagCount() > 0 && selectedOptions instanceof Array && selectedOptions.length > this.thyMaxTagCount()) {
781
+ return selectedOptions.slice(0, this.thyMaxTagCount() - 1);
782
+ }
783
+ return selectedOptions;
784
+ });
785
+ effect(() => {
786
+ const panelOpened = this.thyPanelOpened();
787
+ if (panelOpened) {
788
+ untracked(() => {
789
+ if (this.thyShowSearch()) {
790
+ Promise.resolve(null).then(() => {
791
+ this.inputElement().nativeElement.focus();
792
+ });
793
+ }
794
+ });
795
+ }
796
+ else {
797
+ untracked(() => {
798
+ if (this.thyShowSearch()) {
799
+ new Promise(resolve => setTimeout(resolve, 100)).then(() => {
800
+ if (this.inputValue) {
801
+ this.inputValue = '';
802
+ this.updateWidth();
803
+ this.thyOnSearch.emit(this.inputValue);
804
+ }
805
+ });
806
+ }
807
+ });
808
+ }
809
+ });
810
+ effect(() => {
811
+ this.setSelectControlClass();
812
+ });
813
+ effect(() => {
814
+ let sameValue = false;
815
+ const oldValue = this.previousSelectedOptions();
816
+ const value = this.thySelectedOptions();
817
+ untracked(() => {
818
+ if (this.thyIsMultiple()) {
819
+ if (oldValue instanceof Array && value instanceof Array && oldValue.length === value.length) {
820
+ sameValue = value.every((option, index) => option.thyValue === oldValue[index].thyValue);
821
+ }
822
+ }
823
+ else {
824
+ if (oldValue && value) {
825
+ sameValue = oldValue.thyValue === value.thyValue;
826
+ }
827
+ }
828
+ if (this.thyPanelOpened() && this.thyShowSearch()) {
829
+ if (!sameValue) {
830
+ Promise.resolve(null).then(() => {
831
+ this.inputValue = '';
832
+ this.updateWidth();
833
+ });
834
+ }
835
+ //等待组件渲染好再聚焦
836
+ setTimeout(() => {
837
+ if (this.thyPanelOpened()) {
838
+ this.inputElement().nativeElement.focus();
839
+ }
840
+ }, 200);
841
+ }
842
+ });
843
+ });
913
844
  }
845
+ ngOnInit() { }
914
846
  setSelectControlClass() {
915
- const modeType = this.isMultiple ? 'multiple' : 'single';
847
+ const modeType = this.thyIsMultiple() ? 'multiple' : 'single';
916
848
  const selectControlClass = {
917
849
  [`form-control`]: true,
918
- [`form-control-${this.thySize}`]: !!this.thySize,
850
+ [`form-control-${this.thySize()}`]: !!this.thySize(),
919
851
  [`form-control-custom`]: true,
920
852
  [`select-control`]: true,
921
853
  [`select-control-${modeType}`]: true,
922
- [`select-control-show-search`]: this.showSearch,
923
- [`panel-is-opened`]: this.panelOpened,
924
- [`disabled`]: this.disabled
854
+ [`select-control-show-search`]: this.thyShowSearch(),
855
+ [`panel-is-opened`]: this.thyPanelOpened(),
856
+ [`disabled`]: this.thyDisabled()
925
857
  };
926
858
  this.hostRenderer.updateClassByMap(selectControlClass);
927
859
  this.searchInputControlClass = {
928
860
  [`form-control`]: true,
929
- [`form-control-${this.thySize}`]: !!this.thySize,
861
+ [`form-control-${this.thySize()}`]: !!this.thySize(),
930
862
  [`search-input-field`]: true,
931
- [`hidden`]: !this.thyShowSearch,
932
- [`disabled`]: this.thyDisabled
863
+ [`hidden`]: !this.thyShowSearch(),
864
+ [`disabled`]: this.thyDisabled()
933
865
  };
934
866
  }
935
867
  setInputValue(value) {
@@ -943,19 +875,20 @@ class ThySelectControl {
943
875
  if (event.isComposing) {
944
876
  return;
945
877
  }
946
- if (!this.inputValue?.length && this.selectedOptions instanceof Array) {
947
- if (this.selectedOptions.length > 0) {
948
- this.removeHandle(this.selectedOptions[this.selectedOptions.length - 1], event);
878
+ const selectedOptions = this.thySelectedOptions();
879
+ if (!this.inputValue?.length && selectedOptions instanceof Array) {
880
+ if (selectedOptions.length > 0) {
881
+ this.removeHandle(selectedOptions[selectedOptions.length - 1], event);
949
882
  }
950
883
  }
951
884
  }
952
885
  updateWidth() {
953
- if (this.isMultiple && this.thyShowSearch) {
886
+ if (this.thyIsMultiple() && this.thyShowSearch()) {
954
887
  if (this.inputValue || this.isComposing) {
955
- this.renderer.setStyle(this.inputElement.nativeElement, 'width', `${this.inputElement.nativeElement.scrollWidth}px`);
888
+ this.renderer.setStyle(this.inputElement().nativeElement, 'width', `${this.inputElement().nativeElement.scrollWidth}px`);
956
889
  }
957
890
  else {
958
- this.renderer.removeStyle(this.inputElement.nativeElement, 'width');
891
+ this.renderer.removeStyle(this.inputElement().nativeElement, 'width');
959
892
  }
960
893
  }
961
894
  }
@@ -972,56 +905,14 @@ class ThySelectControl {
972
905
  this.thyOnBlur.emit(event);
973
906
  }
974
907
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThySelectControl, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
975
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.8", type: ThySelectControl, isStandalone: true, selector: "thy-select-control,[thySelectControl]", inputs: { thyPanelOpened: ["thyPanelOpened", "thyPanelOpened", coerceBooleanProperty], thyIsMultiple: ["thyIsMultiple", "thyIsMultiple", coerceBooleanProperty], thyShowSearch: ["thyShowSearch", "thyShowSearch", coerceBooleanProperty], thySelectedOptions: "thySelectedOptions", thyDisabled: ["thyDisabled", "thyDisabled", coerceBooleanProperty], customDisplayTemplate: "customDisplayTemplate", thyAllowClear: ["thyAllowClear", "thyAllowClear", coerceBooleanProperty], thyPlaceholder: "thyPlaceholder", thySize: "thySize", thyMaxTagCount: ["thyMaxTagCount", "thyMaxTagCount", numberAttribute], thyBorderless: ["thyBorderless", "thyBorderless", coerceBooleanProperty], thyPreset: "thyPreset" }, outputs: { thyOnSearch: "thyOnSearch", thyOnRemove: "thyOnRemove", thyOnClear: "thyOnClear", thyOnBlur: "thyOnBlur" }, host: { properties: { "class.select-control-borderless": "thyBorderless" } }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }], ngImport: i0, template: "<ng-template #inputTemplate>\n <input\n #inputElement\n [tabindex]=\"-1\"\n (compositionstart)=\"isComposing = true\"\n (compositionend)=\"isComposing = false\"\n autocomplete=\"something-new\"\n [ngClass]=\"searchInputControlClass\"\n (input)=\"updateWidth()\"\n [ngModel]=\"inputValue\"\n (ngModelChange)=\"setInputValue($event)\"\n (keydown.backspace)=\"handleBackspace($event)\"\n [disabled]=\"thyDisabled\"\n (blur)=\"onBlur($event)\" />\n</ng-template>\n\n<div class=\"select-control-rendered\">\n @if (!isSelectedValue) {\n <div class=\"text-placeholder text-truncate\" [ngStyle]=\"placeholderStyle\">\n {{ thyPlaceholder }}\n </div>\n }\n @if (isMultiple) {\n <div thyFlex thyWrap=\"wrap\" thyGap=\"4\" thyAlignItems=\"center\" class=\"w-100\">\n @if (thyPreset === 'tag') {\n @for (item of maxSelectedTags; track trackValue($index, item)) {\n <div thyFlexItem class=\"custom-choice-item text-truncate\">\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.thyRawValue || item.thyValue || item }\">\n </ng-template>\n @if (!disabled) {\n <div class=\"choice-remove-link ml-1\" (click)=\"removeHandle(item, $event)\">\n <span>\n <thy-icon thyIconName=\"close\" class=\"font-size-sm\"></thy-icon>\n </span>\n </div>\n }\n </div>\n }\n } @else {\n @for (item of maxSelectedTags; track trackValue($index, item)) {\n <div\n thyFlexItem\n thyTag\n class=\"choice-item\"\n [ngClass]=\"{ disabled: disabled === true }\"\n [thySize]=\"tagSize\"\n >\n <div class=\"text-truncate h-100\">\n @if (!customDisplayTemplate) {\n {{ item.thyLabelText }}\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.thyRawValue || item.thyValue || item }\"></ng-template>\n }\n </div>\n @if (!disabled) {\n <div class=\"choice-remove-link ml-1\" (click)=\"removeHandle(item, $event)\">\n <span>\n <thy-icon thyIconName=\"close\" class=\"font-size-sm\"></thy-icon>\n </span>\n </div>\n }\n </div>\n }\n }\n @if (thyMaxTagCount && multipleSelectedValue.length > thyMaxTagCount) {\n <div\n thyFlexItem\n class=\"choice-item max-tag-count-choice\"\n thyTag\n [thySize]=\"tagSize\"\n [ngClass]=\"{ disabled: disabled === true }\">\n <div class=\"text-truncate\">+{{ multipleSelectedValue.length - thyMaxTagCount + 1 }}...</div>\n </div>\n }\n <div thyFlexItem class=\"select-control-search\">\n <ng-template [ngTemplateOutlet]=\"inputTemplate\"></ng-template>\n </div>\n </div>\n } @else {\n @if (isSelectedValue) {\n <div class=\"selected-value text-truncate\" [ngStyle]=\"selectedValueStyle\">\n @if (!customDisplayTemplate) {\n <span class=\"text-truncate\">{{ selectedValue?.thyLabelText }}</span>\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate\"\n [ngTemplateOutletContext]=\"{\n $implicit: selectedValue.thyRawValue || selectedValue.thyValue || selectedValue\n }\"></ng-template>\n }\n </div>\n }\n <div class=\"select-control-search\">\n <ng-template [ngTemplateOutlet]=\"inputTemplate\"></ng-template>\n </div>\n }\n</div>\n<span class=\"select-control-arrow\">\n <thy-icon thyIconName=\"angle-down\" class=\"font-size-base\"></thy-icon>\n</span>\n@if (showClearIcon) {\n <span class=\"select-control-clear remove-link\" (click)=\"clearHandle($event)\">\n <thy-icon class=\"remove-link-icon font-size-base\" thyIconName=\"close-circle-bold-fill\"></thy-icon>\n </span>\n}\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "ngmodule", type: ThyGridModule }, { kind: "directive", type: i2.ThyFlex, selector: "[thyFlex]", inputs: ["thyDirection", "thyWrap", "thyJustifyContent", "thyAlignItems", "thyGap"] }, { kind: "directive", type: i2.ThyFlexItem, selector: "[thyFlexItem]", inputs: ["thyFlexItem", "thyGrow", "thyShrink", "thyBasis"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
908
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.8", type: ThySelectControl, isStandalone: true, selector: "thy-select-control,[thySelectControl]", inputs: { thyPanelOpened: { classPropertyName: "thyPanelOpened", publicName: "thyPanelOpened", isSignal: true, isRequired: false, transformFunction: null }, thyIsMultiple: { classPropertyName: "thyIsMultiple", publicName: "thyIsMultiple", isSignal: true, isRequired: false, transformFunction: null }, thyShowSearch: { classPropertyName: "thyShowSearch", publicName: "thyShowSearch", isSignal: true, isRequired: false, transformFunction: null }, thySelectedOptions: { classPropertyName: "thySelectedOptions", publicName: "thySelectedOptions", isSignal: true, isRequired: false, transformFunction: null }, thyDisabled: { classPropertyName: "thyDisabled", publicName: "thyDisabled", isSignal: true, isRequired: false, transformFunction: null }, customDisplayTemplate: { classPropertyName: "customDisplayTemplate", publicName: "customDisplayTemplate", isSignal: true, isRequired: false, transformFunction: null }, thyAllowClear: { classPropertyName: "thyAllowClear", publicName: "thyAllowClear", isSignal: true, isRequired: false, transformFunction: null }, thyPlaceholder: { classPropertyName: "thyPlaceholder", publicName: "thyPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, thySize: { classPropertyName: "thySize", publicName: "thySize", 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 }, thyPreset: { classPropertyName: "thyPreset", publicName: "thyPreset", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { thyOnSearch: "thyOnSearch", thyOnRemove: "thyOnRemove", thyOnClear: "thyOnClear", thyOnBlur: "thyOnBlur" }, host: { properties: { "class.select-control-borderless": "thyBorderless()" } }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #inputTemplate>\n <input\n #inputElement\n [tabindex]=\"-1\"\n (compositionstart)=\"isComposing = true\"\n (compositionend)=\"isComposing = false\"\n autocomplete=\"something-new\"\n [ngClass]=\"searchInputControlClass\"\n (input)=\"updateWidth()\"\n [ngModel]=\"inputValue\"\n (ngModelChange)=\"setInputValue($event)\"\n (keydown.backspace)=\"handleBackspace($event)\"\n [disabled]=\"thyDisabled()\"\n (blur)=\"onBlur($event)\" />\n</ng-template>\n\n<div class=\"select-control-rendered\">\n @if (!isSelectedValue()) {\n <div class=\"text-placeholder text-truncate\" [ngStyle]=\"placeholderStyle\">\n {{ thyPlaceholder() }}\n </div>\n }\n @if (thyIsMultiple()) {\n <div thyFlex thyWrap=\"wrap\" thyGap=\"4\" thyAlignItems=\"center\" class=\"w-100\">\n @if (thyPreset() === 'tag') {\n @for (item of maxSelectedTags(); track trackValue($index, item)) {\n <div thyFlexItem class=\"custom-choice-item text-truncate\">\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: item.thyRawValue || item.thyValue || item }\">\n </ng-template>\n @if (!thyDisabled()) {\n <div class=\"choice-remove-link ml-1\" (click)=\"removeHandle(item, $event)\">\n <span>\n <thy-icon thyIconName=\"close\" class=\"font-size-sm\"></thy-icon>\n </span>\n </div>\n }\n </div>\n }\n } @else {\n @for (item of maxSelectedTags(); track trackValue($index, item)) {\n <div thyFlexItem thyTag class=\"choice-item\" [ngClass]=\"{ disabled: thyDisabled() === true }\" [thySize]=\"tagSize()\">\n <div class=\"text-truncate h-100\">\n @if (!customDisplayTemplate()) {\n {{ item?.thyLabelText }}\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: item.thyRawValue || item.thyValue || item }\"></ng-template>\n }\n </div>\n @if (!thyDisabled()) {\n <div class=\"choice-remove-link ml-1\" (click)=\"removeHandle(item, $event)\">\n <span>\n <thy-icon thyIconName=\"close\" class=\"font-size-sm\"></thy-icon>\n </span>\n </div>\n }\n </div>\n }\n }\n @if (thyMaxTagCount() && thySelectedOptions()?.length > thyMaxTagCount()) {\n <div\n thyFlexItem\n class=\"choice-item max-tag-count-choice\"\n thyTag\n [thySize]=\"tagSize()\"\n [ngClass]=\"{ disabled: thyDisabled() === true }\">\n <div class=\"text-truncate\">+{{ thySelectedOptions()?.length - thyMaxTagCount() + 1 }}...</div>\n </div>\n }\n <div thyFlexItem class=\"select-control-search\">\n <ng-template [ngTemplateOutlet]=\"inputTemplate\"></ng-template>\n </div>\n </div>\n } @else {\n @if (isSelectedValue()) {\n <div class=\"selected-value text-truncate\" [ngStyle]=\"selectedValueStyle\">\n @if (!customDisplayTemplate()) {\n <span class=\"text-truncate\">{{ thySelectedOptions()?.thyLabelText }}</span>\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate()\"\n [ngTemplateOutletContext]=\"{\n $implicit: thySelectedOptions()?.thyRawValue || thySelectedOptions()?.thyValue || thySelectedOptions()\n }\"></ng-template>\n }\n </div>\n }\n <div class=\"select-control-search\">\n <ng-template [ngTemplateOutlet]=\"inputTemplate\"></ng-template>\n </div>\n }\n</div>\n<span class=\"select-control-arrow\">\n <thy-icon thyIconName=\"angle-down\" class=\"font-size-base\"></thy-icon>\n</span>\n@if (showClearIcon()) {\n <span class=\"select-control-clear remove-link\" (click)=\"clearHandle($event)\">\n <thy-icon class=\"remove-link-icon font-size-base\" thyIconName=\"close-circle-bold-fill\"></thy-icon>\n </span>\n}\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { 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: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ThyTag, selector: "thy-tag,[thyTag]", inputs: ["thyTag", "thyShape", "thyColor", "thyTheme", "thySize", "thyHoverable"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }, { kind: "ngmodule", type: ThyGridModule }, { kind: "directive", type: i2.ThyFlex, selector: "[thyFlex]", inputs: ["thyDirection", "thyWrap", "thyJustifyContent", "thyAlignItems", "thyGap"] }, { kind: "directive", type: i2.ThyFlexItem, selector: "[thyFlexItem]", inputs: ["thyFlexItem", "thyGrow", "thyShrink", "thyBasis"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
976
909
  }
977
910
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThySelectControl, decorators: [{
978
911
  type: Component,
979
912
  args: [{ selector: 'thy-select-control,[thySelectControl]', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule, NgClass, NgStyle, ThyTag, NgTemplateOutlet, ThyIcon, ThyGridModule], host: {
980
- '[class.select-control-borderless]': 'thyBorderless'
981
- }, template: "<ng-template #inputTemplate>\n <input\n #inputElement\n [tabindex]=\"-1\"\n (compositionstart)=\"isComposing = true\"\n (compositionend)=\"isComposing = false\"\n autocomplete=\"something-new\"\n [ngClass]=\"searchInputControlClass\"\n (input)=\"updateWidth()\"\n [ngModel]=\"inputValue\"\n (ngModelChange)=\"setInputValue($event)\"\n (keydown.backspace)=\"handleBackspace($event)\"\n [disabled]=\"thyDisabled\"\n (blur)=\"onBlur($event)\" />\n</ng-template>\n\n<div class=\"select-control-rendered\">\n @if (!isSelectedValue) {\n <div class=\"text-placeholder text-truncate\" [ngStyle]=\"placeholderStyle\">\n {{ thyPlaceholder }}\n </div>\n }\n @if (isMultiple) {\n <div thyFlex thyWrap=\"wrap\" thyGap=\"4\" thyAlignItems=\"center\" class=\"w-100\">\n @if (thyPreset === 'tag') {\n @for (item of maxSelectedTags; track trackValue($index, item)) {\n <div thyFlexItem class=\"custom-choice-item text-truncate\">\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.thyRawValue || item.thyValue || item }\">\n </ng-template>\n @if (!disabled) {\n <div class=\"choice-remove-link ml-1\" (click)=\"removeHandle(item, $event)\">\n <span>\n <thy-icon thyIconName=\"close\" class=\"font-size-sm\"></thy-icon>\n </span>\n </div>\n }\n </div>\n }\n } @else {\n @for (item of maxSelectedTags; track trackValue($index, item)) {\n <div\n thyFlexItem\n thyTag\n class=\"choice-item\"\n [ngClass]=\"{ disabled: disabled === true }\"\n [thySize]=\"tagSize\"\n >\n <div class=\"text-truncate h-100\">\n @if (!customDisplayTemplate) {\n {{ item.thyLabelText }}\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item.thyRawValue || item.thyValue || item }\"></ng-template>\n }\n </div>\n @if (!disabled) {\n <div class=\"choice-remove-link ml-1\" (click)=\"removeHandle(item, $event)\">\n <span>\n <thy-icon thyIconName=\"close\" class=\"font-size-sm\"></thy-icon>\n </span>\n </div>\n }\n </div>\n }\n }\n @if (thyMaxTagCount && multipleSelectedValue.length > thyMaxTagCount) {\n <div\n thyFlexItem\n class=\"choice-item max-tag-count-choice\"\n thyTag\n [thySize]=\"tagSize\"\n [ngClass]=\"{ disabled: disabled === true }\">\n <div class=\"text-truncate\">+{{ multipleSelectedValue.length - thyMaxTagCount + 1 }}...</div>\n </div>\n }\n <div thyFlexItem class=\"select-control-search\">\n <ng-template [ngTemplateOutlet]=\"inputTemplate\"></ng-template>\n </div>\n </div>\n } @else {\n @if (isSelectedValue) {\n <div class=\"selected-value text-truncate\" [ngStyle]=\"selectedValueStyle\">\n @if (!customDisplayTemplate) {\n <span class=\"text-truncate\">{{ selectedValue?.thyLabelText }}</span>\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate\"\n [ngTemplateOutletContext]=\"{\n $implicit: selectedValue.thyRawValue || selectedValue.thyValue || selectedValue\n }\"></ng-template>\n }\n </div>\n }\n <div class=\"select-control-search\">\n <ng-template [ngTemplateOutlet]=\"inputTemplate\"></ng-template>\n </div>\n }\n</div>\n<span class=\"select-control-arrow\">\n <thy-icon thyIconName=\"angle-down\" class=\"font-size-base\"></thy-icon>\n</span>\n@if (showClearIcon) {\n <span class=\"select-control-clear remove-link\" (click)=\"clearHandle($event)\">\n <thy-icon class=\"remove-link-icon font-size-base\" thyIconName=\"close-circle-bold-fill\"></thy-icon>\n </span>\n}\n" }]
982
- }], propDecorators: { thyPanelOpened: [{
983
- type: Input,
984
- args: [{ transform: coerceBooleanProperty }]
985
- }], thyIsMultiple: [{
986
- type: Input,
987
- args: [{ transform: coerceBooleanProperty }]
988
- }], thyShowSearch: [{
989
- type: Input,
990
- args: [{ transform: coerceBooleanProperty }]
991
- }], thySelectedOptions: [{
992
- type: Input
993
- }], thyDisabled: [{
994
- type: Input,
995
- args: [{ transform: coerceBooleanProperty }]
996
- }], customDisplayTemplate: [{
997
- type: Input
998
- }], thyAllowClear: [{
999
- type: Input,
1000
- args: [{ transform: coerceBooleanProperty }]
1001
- }], thyPlaceholder: [{
1002
- type: Input
1003
- }], thySize: [{
1004
- type: Input
1005
- }], thyMaxTagCount: [{
1006
- type: Input,
1007
- args: [{ transform: numberAttribute }]
1008
- }], thyBorderless: [{
1009
- type: Input,
1010
- args: [{ transform: coerceBooleanProperty }]
1011
- }], thyPreset: [{
1012
- type: Input
1013
- }], thyOnSearch: [{
1014
- type: Output
1015
- }], thyOnRemove: [{
1016
- type: Output
1017
- }], thyOnClear: [{
1018
- type: Output
1019
- }], thyOnBlur: [{
1020
- type: Output
1021
- }], inputElement: [{
1022
- type: ViewChild,
1023
- args: ['inputElement']
1024
- }] } });
913
+ '[class.select-control-borderless]': 'thyBorderless()'
914
+ }, template: "<ng-template #inputTemplate>\n <input\n #inputElement\n [tabindex]=\"-1\"\n (compositionstart)=\"isComposing = true\"\n (compositionend)=\"isComposing = false\"\n autocomplete=\"something-new\"\n [ngClass]=\"searchInputControlClass\"\n (input)=\"updateWidth()\"\n [ngModel]=\"inputValue\"\n (ngModelChange)=\"setInputValue($event)\"\n (keydown.backspace)=\"handleBackspace($event)\"\n [disabled]=\"thyDisabled()\"\n (blur)=\"onBlur($event)\" />\n</ng-template>\n\n<div class=\"select-control-rendered\">\n @if (!isSelectedValue()) {\n <div class=\"text-placeholder text-truncate\" [ngStyle]=\"placeholderStyle\">\n {{ thyPlaceholder() }}\n </div>\n }\n @if (thyIsMultiple()) {\n <div thyFlex thyWrap=\"wrap\" thyGap=\"4\" thyAlignItems=\"center\" class=\"w-100\">\n @if (thyPreset() === 'tag') {\n @for (item of maxSelectedTags(); track trackValue($index, item)) {\n <div thyFlexItem class=\"custom-choice-item text-truncate\">\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: item.thyRawValue || item.thyValue || item }\">\n </ng-template>\n @if (!thyDisabled()) {\n <div class=\"choice-remove-link ml-1\" (click)=\"removeHandle(item, $event)\">\n <span>\n <thy-icon thyIconName=\"close\" class=\"font-size-sm\"></thy-icon>\n </span>\n </div>\n }\n </div>\n }\n } @else {\n @for (item of maxSelectedTags(); track trackValue($index, item)) {\n <div thyFlexItem thyTag class=\"choice-item\" [ngClass]=\"{ disabled: thyDisabled() === true }\" [thySize]=\"tagSize()\">\n <div class=\"text-truncate h-100\">\n @if (!customDisplayTemplate()) {\n {{ item?.thyLabelText }}\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: item.thyRawValue || item.thyValue || item }\"></ng-template>\n }\n </div>\n @if (!thyDisabled()) {\n <div class=\"choice-remove-link ml-1\" (click)=\"removeHandle(item, $event)\">\n <span>\n <thy-icon thyIconName=\"close\" class=\"font-size-sm\"></thy-icon>\n </span>\n </div>\n }\n </div>\n }\n }\n @if (thyMaxTagCount() && thySelectedOptions()?.length > thyMaxTagCount()) {\n <div\n thyFlexItem\n class=\"choice-item max-tag-count-choice\"\n thyTag\n [thySize]=\"tagSize()\"\n [ngClass]=\"{ disabled: thyDisabled() === true }\">\n <div class=\"text-truncate\">+{{ thySelectedOptions()?.length - thyMaxTagCount() + 1 }}...</div>\n </div>\n }\n <div thyFlexItem class=\"select-control-search\">\n <ng-template [ngTemplateOutlet]=\"inputTemplate\"></ng-template>\n </div>\n </div>\n } @else {\n @if (isSelectedValue()) {\n <div class=\"selected-value text-truncate\" [ngStyle]=\"selectedValueStyle\">\n @if (!customDisplayTemplate()) {\n <span class=\"text-truncate\">{{ thySelectedOptions()?.thyLabelText }}</span>\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"customDisplayTemplate()\"\n [ngTemplateOutletContext]=\"{\n $implicit: thySelectedOptions()?.thyRawValue || thySelectedOptions()?.thyValue || thySelectedOptions()\n }\"></ng-template>\n }\n </div>\n }\n <div class=\"select-control-search\">\n <ng-template [ngTemplateOutlet]=\"inputTemplate\"></ng-template>\n </div>\n }\n</div>\n<span class=\"select-control-arrow\">\n <thy-icon thyIconName=\"angle-down\" class=\"font-size-base\"></thy-icon>\n</span>\n@if (showClearIcon()) {\n <span class=\"select-control-clear remove-link\" (click)=\"clearHandle($event)\">\n <thy-icon class=\"remove-link-icon font-size-base\" thyIconName=\"close-circle-bold-fill\"></thy-icon>\n </span>\n}\n" }]
915
+ }], ctorParameters: () => [] });
1025
916
 
1026
917
  /**
1027
918
  * @license
@@ -1060,39 +951,26 @@ let _uniqueIdCounter = 0;
1060
951
  class ThyListOption {
1061
952
  constructor() {
1062
953
  this.element = inject(ElementRef);
1063
- this.changeDetector = inject(ChangeDetectorRef);
1064
954
  this.parentSelectionList = inject(THY_LIST_OPTION_PARENT_COMPONENT, { optional: true });
1065
- this._role = 'option';
1066
- this._tabIndex = -1;
1067
- this.id = `thy-list-option-${_uniqueIdCounter++}`;
1068
- }
1069
- get _isListOption() {
1070
- return this.parentSelectionList.layout === 'list';
1071
- }
1072
- get _parentLayout() {
1073
- return this.parentSelectionList.layout === 'grid';
1074
- }
1075
- set thyDisabled(value) {
1076
- this.disabled = value;
955
+ this.role = 'option';
956
+ this.tabIndex = -1;
957
+ this.isMultiple = computed(() => this.parentSelectionList.multiple());
958
+ this.isListOption = computed(() => this.parentSelectionList.layout() === 'list');
959
+ this.isGridOption = computed(() => this.parentSelectionList.layout() === 'grid');
960
+ this.id = input(`thy-list-option-${_uniqueIdCounter++}`);
961
+ this.thyValue = input(undefined);
962
+ this.thyDisabled = input(false, { transform: coerceBooleanProperty });
1077
963
  }
1078
964
  /** Whether the option is selected. */
1079
965
  get selected() {
1080
966
  return this.parentSelectionList.isSelected(this);
1081
967
  }
1082
968
  onClick(event) {
1083
- if (this.parentSelectionList.multiple || !this.parentSelectionList.isSelected(this)) {
969
+ if (this.parentSelectionList.multiple() || !this.parentSelectionList.isSelected(this)) {
1084
970
  this.parentSelectionList.toggleOption(this, event);
1085
971
  this.parentSelectionList.setActiveOption(this);
1086
972
  }
1087
973
  }
1088
- // @HostListener('focus', ['$event'])
1089
- // onFocus(event: Event) {
1090
- // this.parentSelectionList.setFocusedOption(this, event);
1091
- // }
1092
- /** Allows for programmatic focusing of the option. */
1093
- // focus(origin?: FocusOrigin): void {
1094
- // this.element.nativeElement.focus();
1095
- // }
1096
974
  setActiveStyles() {
1097
975
  this.element.nativeElement.classList.add('hover');
1098
976
  this.parentSelectionList.scrollIntoView(this);
@@ -1108,37 +986,19 @@ class ThyListOption {
1108
986
  return '';
1109
987
  }
1110
988
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyListOption, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1111
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.8", type: ThyListOption, isStandalone: true, selector: "thy-list-option,[thy-list-option]", inputs: { id: "id", thyValue: "thyValue", thyDisabled: ["thyDisabled", "thyDisabled", coerceBooleanProperty] }, host: { listeners: { "click": "onClick($event)" }, properties: { "class.thy-list-option": "this._isListOption", "class.thy-grid-option": "this._parentLayout", "attr.role": "this._role", "attr.tabindex": "this._tabIndex", "class.disabled": "this.disabled", "class.active": "this.selected" } }, ngImport: i0, template: "<ng-content></ng-content>\n@if (parentSelectionList.multiple && parentSelectionList.layout === 'list') {\n <span class=\"checked-icon\">\n <thy-icon thyIconName=\"check\"></thy-icon>\n </span>\n}\n@if (parentSelectionList.layout === 'grid') {\n <span class=\"checked-icon\">\n <thy-icon thyIconName=\"check-circle-fill\"></thy-icon>\n </span>\n}\n", dependencies: [{ kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }] }); }
989
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.8", type: ThyListOption, isStandalone: true, selector: "thy-list-option,[thy-list-option]", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, thyValue: { classPropertyName: "thyValue", publicName: "thyValue", isSignal: true, isRequired: false, transformFunction: null }, thyDisabled: { classPropertyName: "thyDisabled", publicName: "thyDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" }, properties: { "class.disabled": "thyDisabled()", "class.thy-list-option": "isListOption()", "class.thy-grid-option": "isGridOption()", "class.active": "selected", "attr.role": "role", "attr.tabindex": "tabIndex" } }, ngImport: i0, template: "<ng-content></ng-content>\n@if (isMultiple() && isListOption()) {\n <span class=\"checked-icon\">\n <thy-icon thyIconName=\"check\"></thy-icon>\n </span>\n}\n@if (isGridOption()) {\n <span class=\"checked-icon\">\n <thy-icon thyIconName=\"check-circle-fill\"></thy-icon>\n </span>\n}\n", dependencies: [{ kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }] }); }
1112
990
  }
1113
991
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyListOption, decorators: [{
1114
992
  type: Component,
1115
- args: [{ selector: 'thy-list-option,[thy-list-option]', imports: [ThyIcon], template: "<ng-content></ng-content>\n@if (parentSelectionList.multiple && parentSelectionList.layout === 'list') {\n <span class=\"checked-icon\">\n <thy-icon thyIconName=\"check\"></thy-icon>\n </span>\n}\n@if (parentSelectionList.layout === 'grid') {\n <span class=\"checked-icon\">\n <thy-icon thyIconName=\"check-circle-fill\"></thy-icon>\n </span>\n}\n" }]
1116
- }], propDecorators: { _isListOption: [{
1117
- type: HostBinding,
1118
- args: [`class.thy-list-option`]
1119
- }], _parentLayout: [{
1120
- type: HostBinding,
1121
- args: [`class.thy-grid-option`]
1122
- }], _role: [{
1123
- type: HostBinding,
1124
- args: [`attr.role`]
1125
- }], _tabIndex: [{
1126
- type: HostBinding,
1127
- args: [`attr.tabindex`]
1128
- }], id: [{
1129
- type: Input
1130
- }], thyValue: [{
1131
- type: Input
1132
- }], thyDisabled: [{
1133
- type: Input,
1134
- args: [{ transform: coerceBooleanProperty }]
1135
- }], disabled: [{
1136
- type: HostBinding,
1137
- args: [`class.disabled`]
1138
- }], selected: [{
1139
- type: HostBinding,
1140
- args: [`class.active`]
1141
- }], onClick: [{
993
+ args: [{ selector: 'thy-list-option,[thy-list-option]', imports: [ThyIcon], host: {
994
+ '[class.disabled]': 'thyDisabled()',
995
+ '[class.thy-list-option]': 'isListOption()',
996
+ '[class.thy-grid-option]': 'isGridOption()',
997
+ '[class.active]': 'selected',
998
+ '[attr.role]': 'role',
999
+ '[attr.tabindex]': 'tabIndex'
1000
+ }, template: "<ng-content></ng-content>\n@if (isMultiple() && isListOption()) {\n <span class=\"checked-icon\">\n <thy-icon thyIconName=\"check\"></thy-icon>\n </span>\n}\n@if (isGridOption()) {\n <span class=\"checked-icon\">\n <thy-icon thyIconName=\"check-circle-fill\"></thy-icon>\n </span>\n}\n" }]
1001
+ }], propDecorators: { onClick: [{
1142
1002
  type: HostListener,
1143
1003
  args: ['click', ['$event']]
1144
1004
  }] } });
@@ -1180,35 +1040,26 @@ class ThyOptionVisibleChangeEvent {
1180
1040
  * @order 20
1181
1041
  */
1182
1042
  class ThyOption extends SelectOptionBase {
1183
- set thyDisabled(value) {
1184
- this._disabled = value;
1185
- }
1186
- get thyDisabled() {
1187
- return this._disabled;
1188
- }
1043
+ // 继承至 Highlightable,无法修改为 Signal
1189
1044
  get disabled() {
1190
- return this.hidden || this._disabled;
1191
- }
1192
- get hidden() {
1193
- return this._hidden;
1045
+ return this.hidden() || this.thyDisabled();
1194
1046
  }
1195
1047
  get tabIndex() {
1196
1048
  return this.disabled ? '-1' : '0';
1197
1049
  }
1198
- get selected() {
1199
- return this._selected;
1200
- }
1201
1050
  constructor() {
1202
1051
  super();
1203
1052
  this.element = inject(ElementRef);
1204
1053
  this.parent = inject(THY_OPTION_PARENT_COMPONENT, { optional: true });
1205
1054
  this.cdr = inject(ChangeDetectorRef);
1206
- this._selected = false;
1207
- this._hidden = false;
1208
- this._disabled = false;
1209
- this._isOptionItem = true;
1210
- this.selectionChange = new EventEmitter();
1211
- this.visibleChange = new EventEmitter();
1055
+ this.thyShowOptionCustom = input();
1056
+ this.thySearchKey = input();
1057
+ this.template = viewChild(TemplateRef);
1058
+ this.thyDisabled = input(false, { transform: coerceBooleanProperty });
1059
+ this.hidden = signal(false);
1060
+ this.selected = signal(false);
1061
+ this.selectionChange = output();
1062
+ this.visibleChange = output();
1212
1063
  }
1213
1064
  getHostElement() {
1214
1065
  return this.element.nativeElement;
@@ -1224,44 +1075,46 @@ class ThyOption extends SelectOptionBase {
1224
1075
  }
1225
1076
  selectViaInteraction() {
1226
1077
  if (!this.disabled) {
1227
- this._selected = this.parent.isMultiple ? !this._selected : true;
1078
+ const selected = this.parent.isMultiple ? !this.selected() : true;
1079
+ this.selected.set(selected);
1228
1080
  this.cdr.markForCheck();
1229
1081
  this.emitSelectionChangeEvent(true);
1230
1082
  }
1231
1083
  }
1232
1084
  select(event) {
1233
1085
  if (!this.disabled) {
1234
- if (!this._selected) {
1235
- this._selected = true;
1086
+ if (!this.selected()) {
1087
+ this.selected.set(true);
1236
1088
  this.emitSelectionChangeEvent();
1237
1089
  this.cdr.markForCheck();
1238
1090
  }
1239
1091
  }
1240
1092
  }
1241
1093
  deselect() {
1242
- if (this._selected || this.disabled) {
1243
- this._selected = false;
1094
+ if (this.selected() || this.disabled) {
1095
+ this.selected.set(false);
1244
1096
  this.emitSelectionChangeEvent();
1245
1097
  this.cdr.markForCheck();
1246
1098
  }
1247
1099
  }
1248
1100
  hideOption() {
1249
- if (!this._hidden) {
1250
- this._hidden = true;
1101
+ if (!this.hidden()) {
1102
+ this.hidden.set(true);
1251
1103
  this.visibleChange.emit({ option: this });
1252
1104
  this.cdr.markForCheck();
1253
1105
  }
1254
1106
  }
1255
1107
  showOption() {
1256
- if (this._hidden) {
1257
- this._hidden = false;
1108
+ if (this.hidden()) {
1109
+ this.hidden.set(false);
1258
1110
  this.visibleChange.emit({ option: this });
1259
1111
  this.cdr.markForCheck();
1260
1112
  }
1261
1113
  }
1262
1114
  matchSearchText(searchText) {
1263
- if (this.thySearchKey) {
1264
- if (this.thySearchKey.toLowerCase().indexOf(searchText.toLowerCase()) >= 0) {
1115
+ const thySearchKey = this.thySearchKey();
1116
+ if (thySearchKey) {
1117
+ if (thySearchKey.toLowerCase().indexOf(searchText.toLowerCase()) >= 0) {
1265
1118
  return true;
1266
1119
  }
1267
1120
  else {
@@ -1293,46 +1146,23 @@ class ThyOption extends SelectOptionBase {
1293
1146
  }
1294
1147
  ngOnDestroy() { }
1295
1148
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyOption, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1296
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.8", type: ThyOption, isStandalone: true, selector: "thy-option", inputs: { thyValue: "thyValue", thyRawValue: "thyRawValue", thyLabelText: "thyLabelText", thyShowOptionCustom: "thyShowOptionCustom", thySearchKey: "thySearchKey", thyDisabled: ["thyDisabled", "thyDisabled", coerceBooleanProperty] }, outputs: { selectionChange: "selectionChange", visibleChange: "visibleChange" }, host: { listeners: { "click": "onClick($event)", "keydown": "handleKeydown($event)" }, properties: { "class.thy-option-item": "this._isOptionItem", "class.disabled": "this.thyDisabled", "class.hidden": "this.hidden", "attr.tabindex": "this.tabIndex", "class.active": "this.selected" } }, viewQueries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "@if (thyShowOptionCustom) {\n <ng-content></ng-content>\n <thy-icon class=\"checked-icon\" thyIconName=\"check\"></thy-icon>\n} @else {\n <span class=\"text-truncate\">{{ thyLabelText }}</span>\n <thy-icon class=\"checked-icon\" thyIconName=\"check\"></thy-icon>\n}\n", dependencies: [{ kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1149
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.8", type: ThyOption, isStandalone: true, selector: "thy-option", inputs: { thyValue: { classPropertyName: "thyValue", publicName: "thyValue", isSignal: false, isRequired: false, transformFunction: null }, thyRawValue: { classPropertyName: "thyRawValue", publicName: "thyRawValue", isSignal: false, isRequired: false, transformFunction: null }, thyLabelText: { classPropertyName: "thyLabelText", publicName: "thyLabelText", isSignal: false, isRequired: false, transformFunction: null }, thyShowOptionCustom: { classPropertyName: "thyShowOptionCustom", publicName: "thyShowOptionCustom", isSignal: true, isRequired: false, transformFunction: null }, thySearchKey: { classPropertyName: "thySearchKey", publicName: "thySearchKey", isSignal: true, isRequired: false, transformFunction: null }, thyDisabled: { classPropertyName: "thyDisabled", publicName: "thyDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", visibleChange: "visibleChange" }, host: { listeners: { "click": "onClick($event)", "keydown": "handleKeydown($event)" }, properties: { "class.disabled": "thyDisabled()", "class.hidden": "hidden()", "attr.tabindex": "tabIndex", "class.active": "selected()" }, classAttribute: "thy-option-item" }, viewQueries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (thyShowOptionCustom()) {\n <ng-content></ng-content>\n <thy-icon class=\"checked-icon\" thyIconName=\"check\"></thy-icon>\n} @else {\n <span class=\"text-truncate\">{{ thyLabelText }}</span>\n <thy-icon class=\"checked-icon\" thyIconName=\"check\"></thy-icon>\n}\n", dependencies: [{ kind: "component", type: ThyIcon, selector: "thy-icon, [thy-icon]", inputs: ["thyIconType", "thyTwotoneColor", "thyIconName", "thyIconRotate", "thyIconSet", "thyIconLegging", "thyIconLinearGradient"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1297
1150
  }
1298
1151
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyOption, decorators: [{
1299
1152
  type: Component,
1300
- args: [{ selector: 'thy-option', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ThyIcon], template: "@if (thyShowOptionCustom) {\n <ng-content></ng-content>\n <thy-icon class=\"checked-icon\" thyIconName=\"check\"></thy-icon>\n} @else {\n <span class=\"text-truncate\">{{ thyLabelText }}</span>\n <thy-icon class=\"checked-icon\" thyIconName=\"check\"></thy-icon>\n}\n" }]
1153
+ args: [{ selector: 'thy-option', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ThyIcon], host: {
1154
+ class: 'thy-option-item',
1155
+ '[class.disabled]': 'thyDisabled()',
1156
+ '[class.hidden]': 'hidden()',
1157
+ '[attr.tabindex]': `tabIndex`,
1158
+ '[class.active]': 'selected()'
1159
+ }, template: "@if (thyShowOptionCustom()) {\n <ng-content></ng-content>\n <thy-icon class=\"checked-icon\" thyIconName=\"check\"></thy-icon>\n} @else {\n <span class=\"text-truncate\">{{ thyLabelText }}</span>\n <thy-icon class=\"checked-icon\" thyIconName=\"check\"></thy-icon>\n}\n" }]
1301
1160
  }], ctorParameters: () => [], propDecorators: { thyValue: [{
1302
1161
  type: Input
1303
1162
  }], thyRawValue: [{
1304
1163
  type: Input
1305
1164
  }], thyLabelText: [{
1306
1165
  type: Input
1307
- }], thyShowOptionCustom: [{
1308
- type: Input
1309
- }], thySearchKey: [{
1310
- type: Input
1311
- }], _isOptionItem: [{
1312
- type: HostBinding,
1313
- args: ['class.thy-option-item']
1314
- }], template: [{
1315
- type: ViewChild,
1316
- args: [TemplateRef, { static: true }]
1317
- }], thyDisabled: [{
1318
- type: Input,
1319
- args: [{ transform: coerceBooleanProperty }]
1320
- }, {
1321
- type: HostBinding,
1322
- args: [`class.disabled`]
1323
- }], hidden: [{
1324
- type: HostBinding,
1325
- args: ['class.hidden']
1326
- }], tabIndex: [{
1327
- type: HostBinding,
1328
- args: ['attr.tabindex']
1329
- }], selected: [{
1330
- type: HostBinding,
1331
- args: [`class.active`]
1332
- }], selectionChange: [{
1333
- type: Output
1334
- }], visibleChange: [{
1335
- type: Output
1336
1166
  }], onClick: [{
1337
1167
  type: HostListener,
1338
1168
  args: ['click', ['$event']]
@@ -1348,19 +1178,17 @@ class ThySelectOptionGroup {
1348
1178
  constructor() {
1349
1179
  this._ngZone = inject(NgZone);
1350
1180
  this.cdr = inject(ChangeDetectorRef);
1351
- this._hidden = false;
1352
- this._isOptionGroup = true;
1181
+ this.thyDisabled = input(false, { transform: coerceBooleanProperty });
1182
+ this.hidden = signal(false);
1183
+ this.thyGroupLabel = input(undefined);
1353
1184
  this._destroy$ = new Subject();
1354
1185
  this.optionVisibleChanges = defer(() => {
1355
1186
  if (this.options) {
1356
- return merge(...this.options.map(option => option.visibleChange));
1187
+ return merge(...this.options.map(option => outputToObservable(option.visibleChange)));
1357
1188
  }
1358
1189
  return this._ngZone.onStable.asObservable().pipe(take(1), switchMap(() => this.optionVisibleChanges));
1359
1190
  });
1360
1191
  }
1361
- get hidden() {
1362
- return this._hidden;
1363
- }
1364
1192
  ngAfterContentInit() {
1365
1193
  this.options.changes.pipe(startWith(null), takeUntil(this._destroy$)).subscribe(() => {
1366
1194
  this._resetOptions();
@@ -1368,10 +1196,10 @@ class ThySelectOptionGroup {
1368
1196
  }
1369
1197
  _resetOptions() {
1370
1198
  const changedOrDestroyed$ = merge(this.options.changes, this._destroy$);
1371
- merge(...this.options.map(option => option.visibleChange))
1199
+ merge(...this.options.map(option => outputToObservable(option.visibleChange)))
1372
1200
  .pipe(takeUntil(changedOrDestroyed$), debounceTime(10), map((event) => {
1373
1201
  const hasOption = this.options.find(option => {
1374
- if (!option.hidden) {
1202
+ if (!option.hidden()) {
1375
1203
  return true;
1376
1204
  }
1377
1205
  });
@@ -1383,7 +1211,7 @@ class ThySelectOptionGroup {
1383
1211
  }
1384
1212
  }))
1385
1213
  .subscribe((data) => {
1386
- this._hidden = data;
1214
+ this.hidden.set(data);
1387
1215
  this.cdr.markForCheck();
1388
1216
  });
1389
1217
  }
@@ -1392,35 +1220,27 @@ class ThySelectOptionGroup {
1392
1220
  this._destroy$.complete();
1393
1221
  }
1394
1222
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThySelectOptionGroup, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1395
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "19.2.8", type: ThySelectOptionGroup, isStandalone: true, selector: "thy-option-group", inputs: { thyDisabled: ["thyDisabled", "thyDisabled", coerceBooleanProperty], thyGroupLabel: "thyGroupLabel" }, host: { properties: { "class.disabled": "this.thyDisabled", "class.thy-option-item-group": "this._isOptionGroup", "class.thy-select-option-group-hidden": "this.hidden" } }, queries: [{ propertyName: "options", predicate: ThyOption }], ngImport: i0, template: "<span class=\"group-name text-truncate\">{{ thyGroupLabel }}</span>\n<ng-content></ng-content>\n" }); }
1223
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.8", type: ThySelectOptionGroup, isStandalone: true, selector: "thy-option-group", inputs: { thyDisabled: { classPropertyName: "thyDisabled", publicName: "thyDisabled", isSignal: true, isRequired: false, transformFunction: null }, thyGroupLabel: { classPropertyName: "thyGroupLabel", publicName: "thyGroupLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.disabled": "thyDisabled()", "class.thy-select-option-group-hidden": "hidden()" }, classAttribute: "thy-option-item-group" }, queries: [{ propertyName: "options", predicate: ThyOption }], ngImport: i0, template: "<span class=\"group-name text-truncate\">{{ thyGroupLabel() }}</span>\n<ng-content></ng-content>\n" }); }
1396
1224
  }
1397
1225
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThySelectOptionGroup, decorators: [{
1398
1226
  type: Component,
1399
- args: [{ selector: 'thy-option-group', template: "<span class=\"group-name text-truncate\">{{ thyGroupLabel }}</span>\n<ng-content></ng-content>\n" }]
1400
- }], propDecorators: { thyDisabled: [{
1401
- type: Input,
1402
- args: [{ transform: coerceBooleanProperty }]
1403
- }, {
1404
- type: HostBinding,
1405
- args: [`class.disabled`]
1406
- }], _isOptionGroup: [{
1407
- type: HostBinding,
1408
- args: ['class.thy-option-item-group']
1409
- }], hidden: [{
1410
- type: HostBinding,
1411
- args: ['class.thy-select-option-group-hidden']
1412
- }], thyGroupLabel: [{
1413
- type: Input
1414
- }], options: [{
1227
+ args: [{ selector: 'thy-option-group', host: {
1228
+ class: 'thy-option-item-group',
1229
+ '[class.disabled]': 'thyDisabled()',
1230
+ '[class.thy-select-option-group-hidden]': 'hidden()'
1231
+ }, template: "<span class=\"group-name text-truncate\">{{ thyGroupLabel() }}</span>\n<ng-content></ng-content>\n" }]
1232
+ }], propDecorators: { options: [{
1415
1233
  type: ContentChildren,
1416
1234
  args: [ThyOption]
1417
1235
  }] } });
1418
1236
 
1419
1237
  class ThyOptionsContainer {
1420
- constructor() { }
1238
+ constructor() {
1239
+ this.optionsTemplate = viewChild('options');
1240
+ }
1421
1241
  ngOnInit() { }
1422
1242
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyOptionsContainer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1423
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.8", type: ThyOptionsContainer, isStandalone: true, selector: "thy-options-container", viewQueries: [{ propertyName: "optionsTemplate", first: true, predicate: ["options"], descendants: true }], ngImport: i0, template: `
1243
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.8", type: ThyOptionsContainer, isStandalone: true, selector: "thy-options-container", viewQueries: [{ propertyName: "optionsTemplate", first: true, predicate: ["options"], descendants: true, isSignal: true }], ngImport: i0, template: `
1424
1244
  <ng-template #options>
1425
1245
  <ng-content></ng-content>
1426
1246
  </ng-template>
@@ -1437,10 +1257,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
1437
1257
  `,
1438
1258
  changeDetection: ChangeDetectionStrategy.OnPush
1439
1259
  }]
1440
- }], ctorParameters: () => [], propDecorators: { optionsTemplate: [{
1441
- type: ViewChild,
1442
- args: ['options']
1443
- }] } });
1260
+ }], ctorParameters: () => [] });
1444
1261
 
1445
1262
  /**
1446
1263
  * @license