ngx-tethys 19.1.0-next.4 → 19.1.0-next.6

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 (83) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/date-picker/abstract-picker.component.d.ts +50 -52
  3. package/date-picker/abstract-picker.directive.d.ts +15 -40
  4. package/date-picker/base-picker.component.d.ts +11 -40
  5. package/date-picker/date-picker.config.d.ts +1 -0
  6. package/date-picker/lib/calendar/calendar-footer.component.d.ts +24 -19
  7. package/date-picker/lib/calendar/calendar-header.component.d.ts +15 -15
  8. package/date-picker/lib/calendar/calendar-table.component.d.ts +15 -16
  9. package/date-picker/lib/date/date-table-cell.component.d.ts +2 -3
  10. package/date-picker/lib/date/date-table.component.d.ts +2 -3
  11. package/date-picker/lib/date-carousel/date-carousel.component.d.ts +2 -3
  12. package/date-picker/lib/decade/decade-header.component.d.ts +2 -5
  13. package/date-picker/lib/decade/decade-table.component.d.ts +3 -5
  14. package/date-picker/lib/month/month-table.component.d.ts +1 -2
  15. package/date-picker/lib/popups/date-popup.component.d.ts +33 -34
  16. package/date-picker/lib/popups/inner-popup.component.d.ts +22 -29
  17. package/date-picker/lib/quarter/quarter-table.component.d.ts +1 -4
  18. package/date-picker/lib/year/year-header.component.d.ts +2 -4
  19. package/date-picker/lib/year/year-table.component.d.ts +2 -4
  20. package/date-picker/month-picker.component.d.ts +2 -2
  21. package/date-picker/picker.component.d.ts +30 -34
  22. package/date-picker/picker.pipes.d.ts +4 -5
  23. package/date-picker/picker.util.d.ts +5 -5
  24. package/date-picker/picker.validators.d.ts +4 -8
  25. package/date-picker/quarter-picker.component.d.ts +2 -3
  26. package/date-picker/week-picker.component.d.ts +0 -1
  27. package/date-picker/year-picker.component.d.ts +2 -3
  28. package/dropdown/dropdown.directive.d.ts +2 -1
  29. package/fesm2022/ngx-tethys-autocomplete.mjs +4 -4
  30. package/fesm2022/ngx-tethys-autocomplete.mjs.map +1 -1
  31. package/fesm2022/ngx-tethys-checkbox.mjs +2 -2
  32. package/fesm2022/ngx-tethys-checkbox.mjs.map +1 -1
  33. package/fesm2022/ngx-tethys-date-picker.mjs +833 -1060
  34. package/fesm2022/ngx-tethys-date-picker.mjs.map +1 -1
  35. package/fesm2022/ngx-tethys-divider.mjs +5 -5
  36. package/fesm2022/ngx-tethys-divider.mjs.map +1 -1
  37. package/fesm2022/ngx-tethys-dropdown.mjs +2 -1
  38. package/fesm2022/ngx-tethys-dropdown.mjs.map +1 -1
  39. package/fesm2022/ngx-tethys-i18n.mjs +11 -6
  40. package/fesm2022/ngx-tethys-i18n.mjs.map +1 -1
  41. package/fesm2022/ngx-tethys-layout.mjs +291 -334
  42. package/fesm2022/ngx-tethys-layout.mjs.map +1 -1
  43. package/fesm2022/ngx-tethys-list.mjs +11 -10
  44. package/fesm2022/ngx-tethys-list.mjs.map +1 -1
  45. package/fesm2022/ngx-tethys-radio.mjs +4 -4
  46. package/fesm2022/ngx-tethys-radio.mjs.map +1 -1
  47. package/fesm2022/ngx-tethys-select.mjs +164 -228
  48. package/fesm2022/ngx-tethys-select.mjs.map +1 -1
  49. package/fesm2022/ngx-tethys-shared.mjs +371 -523
  50. package/fesm2022/ngx-tethys-shared.mjs.map +1 -1
  51. package/fesm2022/ngx-tethys-tree-select.mjs +215 -281
  52. package/fesm2022/ngx-tethys-tree-select.mjs.map +1 -1
  53. package/fesm2022/ngx-tethys.mjs +1 -1
  54. package/fesm2022/ngx-tethys.mjs.map +1 -1
  55. package/i18n/i18n.d.ts +2 -1
  56. package/i18n/locales/de-de.d.ts +2 -1
  57. package/i18n/locales/en-us.d.ts +2 -1
  58. package/i18n/locales/ja-jp.d.ts +2 -1
  59. package/i18n/locales/zh-hans.d.ts +2 -1
  60. package/i18n/locales/zh-hant.d.ts +2 -1
  61. package/layout/header.component.d.ts +15 -19
  62. package/layout/layout.component.d.ts +3 -2
  63. package/layout/sidebar-header.component.d.ts +7 -8
  64. package/layout/sidebar.component.d.ts +32 -62
  65. package/package.json +54 -54
  66. package/schematics/version.d.ts +1 -1
  67. package/schematics/version.js +1 -1
  68. package/select/custom-select/custom-select.component.d.ts +33 -56
  69. package/select/native-select/native-select.component.d.ts +7 -13
  70. package/shared/base-form-check.component.d.ts +6 -8
  71. package/shared/directives/string-or-template-outlet.directive.d.ts +5 -6
  72. package/shared/directives/thy-autofocus.directive.d.ts +4 -6
  73. package/shared/directives/thy-scroll.directive.d.ts +5 -8
  74. package/shared/directives/thy-show.d.ts +3 -4
  75. package/shared/directives/thy-stop-propagation.directive.d.ts +4 -4
  76. package/shared/directives/view-outlet.directive.d.ts +6 -7
  77. package/shared/ng-transclude.directive.d.ts +2 -3
  78. package/shared/option/group/option-group.component.d.ts +5 -9
  79. package/shared/option/list-option/list-option.component.d.ts +4 -8
  80. package/shared/option/option.component.d.ts +10 -17
  81. package/shared/option/options-container.component.d.ts +1 -1
  82. package/shared/select/select-control/select-control.component.d.ts +27 -47
  83. 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, EventEmitter, Output, computed, output, ContentChildren, KeyValueDiffers, TemplateRef, ChangeDetectorRef, NgModule, Input, linkedSignal, numberAttribute, viewChild, untracked, ChangeDetectionStrategy, Component, InjectionToken, HostListener, HostBinding, 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 也会触发
@@ -181,54 +171,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
181
171
  * @name thyShow
182
172
  */
183
173
  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
174
  unListenDocument() {
192
175
  if (this.unListenEvent) {
193
176
  this.unListenEvent();
194
177
  this.unListenEvent = null;
195
178
  }
196
179
  }
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) {
204
- this.ngZone.run(() => this.thyShowChange.emit(false));
180
+ constructor() {
181
+ this.elementRef = inject(ElementRef);
182
+ this.renderer = inject(Renderer2);
183
+ this.ngZone = inject(NgZone);
184
+ this.thyShowChange = new EventEmitter();
185
+ this.hostRenderer = useHostRenderer();
186
+ this.thyShow = input(false, { transform: coerceBooleanProperty });
187
+ effect(() => {
188
+ if (this.thyShow()) {
189
+ this.hostRenderer.setStyle('display', 'block');
190
+ this.ngZone.runOutsideAngular(() => setTimeout(() => {
191
+ this.unListenEvent = this.renderer.listen('document', 'click', event => {
192
+ if (!this.elementRef.nativeElement.contains(event.target)) {
193
+ if (this.thyShowChange.observers.length) {
194
+ this.ngZone.run(() => this.thyShowChange.emit(false));
195
+ }
196
+ this.unListenDocument();
205
197
  }
206
- this.unListenDocument();
207
- }
208
- });
209
- }));
210
- }
211
- else {
212
- this.hostRenderer.setStyle('display', 'none');
213
- this.unListenDocument();
214
- }
198
+ });
199
+ }));
200
+ }
201
+ else {
202
+ this.hostRenderer.setStyle('display', 'none');
203
+ this.unListenDocument();
204
+ }
205
+ });
215
206
  }
216
207
  ngOnDestroy() {
217
208
  this.unListenDocument();
218
209
  }
219
210
  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 }); }
211
+ 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
212
  }
222
213
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyShowDirective, decorators: [{
223
214
  type: Directive,
224
215
  args: [{
225
216
  selector: '[thyShow]'
226
217
  }]
227
- }], propDecorators: { thyShowChange: [{
218
+ }], ctorParameters: () => [], propDecorators: { thyShowChange: [{
228
219
  type: Output
229
- }], thyShow: [{
230
- type: Input,
231
- args: [{ transform: coerceBooleanProperty }]
232
220
  }] } });
233
221
 
234
222
  /**
@@ -236,34 +224,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
236
224
  * @name thyStopPropagation
237
225
  */
238
226
  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
227
  constructor() {
255
- this._eventName = 'click';
256
- this._shouldStopPropagation = true;
228
+ this.thyStopPropagation = input(true);
229
+ this._eventName = computed(() => {
230
+ const stopPropagation = this.thyStopPropagation();
231
+ if (stopPropagation !== false) {
232
+ if (!stopPropagation || stopPropagation === true || stopPropagation === 'true') {
233
+ return 'click';
234
+ }
235
+ else {
236
+ return stopPropagation;
237
+ }
238
+ }
239
+ });
240
+ this._shouldStopPropagation = computed(() => {
241
+ const stopPropagation = this.thyStopPropagation();
242
+ return stopPropagation === false || stopPropagation === 'false' ? false : true;
243
+ });
257
244
  this._changes$ = new Subject();
258
245
  this._destroy$ = new Subject();
259
246
  const _host = inject(ElementRef);
260
247
  const _ngZone = inject(NgZone);
248
+ effect(() => {
249
+ this._changes$.next(this.thyStopPropagation());
250
+ });
261
251
  this._changes$
262
252
  .pipe(
263
253
  // 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$))
254
+ startWith(null), switchMap(() => new Observable(subscriber => _ngZone.runOutsideAngular(() => fromEvent(_host.nativeElement, this._eventName()).subscribe(subscriber)))), takeUntil(this._destroy$))
265
255
  .subscribe(event => {
266
- if (this._shouldStopPropagation) {
256
+ if (this._shouldStopPropagation()) {
267
257
  event.stopPropagation();
268
258
  }
269
259
  });
@@ -272,16 +262,14 @@ class ThyStopPropagationDirective {
272
262
  this._destroy$.next();
273
263
  }
274
264
  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 }); }
265
+ 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
266
  }
277
267
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyStopPropagationDirective, decorators: [{
278
268
  type: Directive,
279
269
  args: [{
280
270
  selector: '[thyStopPropagation]'
281
271
  }]
282
- }], ctorParameters: () => [], propDecorators: { thyStopPropagation: [{
283
- type: Input
284
- }] } });
272
+ }], ctorParameters: () => [] });
285
273
 
286
274
  /**
287
275
  * @name thyContextMenu
@@ -328,11 +316,10 @@ class ThyScrollDirective {
328
316
  this.elementRef = inject(ElementRef);
329
317
  this.ngZone = inject(NgZone);
330
318
  this._destroyed = new Subject();
331
- this._enable = true;
332
- this._initialled = false;
333
319
  this._elementScrolled = new Observable((observer) => this.ngZone.runOutsideAngular(() => fromEvent(this.elementRef.nativeElement, 'scroll', passiveEventListenerOptions)
334
320
  .pipe(takeUntil(this._destroyed))
335
321
  .subscribe(observer)));
322
+ this.thyEnable = input(true, { transform: coerceBooleanProperty });
336
323
  /**
337
324
  * @description
338
325
  *
@@ -352,12 +339,10 @@ class ThyScrollDirective {
352
339
  * }
353
340
  * ```
354
341
  */
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) {
342
+ this.thyOnScrolled = output();
343
+ effect(() => {
344
+ const thyEnable = this.thyEnable();
345
+ if (thyEnable && !this._subscription) {
361
346
  this._subscription = this._elementScrolled.subscribe(() => this.thyOnScrolled.emit(this.elementRef));
362
347
  }
363
348
  else {
@@ -366,14 +351,9 @@ class ThyScrollDirective {
366
351
  this._subscription = null;
367
352
  }
368
353
  }
369
- }
370
- }
371
- ngOnInit() {
372
- if (this._enable) {
373
- this._subscription = this._elementScrolled.subscribe(() => this.thyOnScrolled.emit(this.elementRef));
374
- }
375
- this._initialled = true;
354
+ });
376
355
  }
356
+ ngOnInit() { }
377
357
  ngOnDestroy() {
378
358
  this._destroyed.next();
379
359
  this._destroyed.complete();
@@ -382,19 +362,14 @@ class ThyScrollDirective {
382
362
  return this.elementRef;
383
363
  }
384
364
  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 }); }
365
+ 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
366
  }
387
367
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyScrollDirective, decorators: [{
388
368
  type: Directive,
389
369
  args: [{
390
370
  selector: '[thyScroll]'
391
371
  }]
392
- }], propDecorators: { thyEnable: [{
393
- type: Input,
394
- args: [{ transform: coerceBooleanProperty }]
395
- }], thyOnScrolled: [{
396
- type: Output
397
- }] } });
372
+ }], ctorParameters: () => [] });
398
373
 
399
374
  /**
400
375
  * @private
@@ -448,23 +423,26 @@ class ThyStringOrTemplateOutletDirective {
448
423
  constructor() {
449
424
  this.viewContainerRef = inject(ViewContainerRef);
450
425
  this.renderer = inject(Renderer2);
451
- }
452
- ngOnChanges(changes) {
453
- if (changes['thyStringOrTemplateOutlet']) {
426
+ this.thyStringOrTemplateOutletContext = input();
427
+ this.thyStringOrTemplateOutlet = input();
428
+ effect(() => {
454
429
  this.updateView();
455
- }
456
- else if (this.viewRef && changes['thyStringOrTemplateOutletContext'] && this.thyStringOrTemplateOutletContext) {
457
- this.viewRef.context = this.thyStringOrTemplateOutletContext;
458
- }
430
+ });
431
+ effect(() => {
432
+ if (this.viewRef && this.thyStringOrTemplateOutletContext()) {
433
+ this.viewRef.context = this.thyStringOrTemplateOutletContext();
434
+ }
435
+ });
459
436
  }
460
437
  updateView() {
438
+ const thyStringOrTemplateOutlet = this.thyStringOrTemplateOutlet();
461
439
  this.clear();
462
- if (this.thyStringOrTemplateOutlet) {
463
- if (isTemplateRef(this.thyStringOrTemplateOutlet)) {
464
- this.viewRef = this.viewContainerRef.createEmbeddedView(this.thyStringOrTemplateOutlet, this.thyStringOrTemplateOutletContext);
440
+ if (thyStringOrTemplateOutlet) {
441
+ if (isTemplateRef(thyStringOrTemplateOutlet)) {
442
+ this.viewRef = this.viewContainerRef.createEmbeddedView(thyStringOrTemplateOutlet, this.thyStringOrTemplateOutletContext());
465
443
  }
466
444
  else {
467
- this.textNode = this.renderer.createText(this.thyStringOrTemplateOutlet + '');
445
+ this.textNode = this.renderer.createText(thyStringOrTemplateOutlet + '');
468
446
  const element = this.viewContainerRef.element.nativeElement;
469
447
  this.renderer.insertBefore(element.parentNode, this.textNode, element);
470
448
  }
@@ -480,7 +458,7 @@ class ThyStringOrTemplateOutletDirective {
480
458
  }
481
459
  }
482
460
  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 }); }
461
+ 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
462
  }
485
463
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyStringOrTemplateOutletDirective, decorators: [{
486
464
  type: Directive,
@@ -488,11 +466,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
488
466
  selector: '[thyStringOrTemplateOutlet]',
489
467
  exportAs: 'thyStringOrTemplateOutlet'
490
468
  }]
491
- }], propDecorators: { thyStringOrTemplateOutletContext: [{
492
- type: Input
493
- }], thyStringOrTemplateOutlet: [{
494
- type: Input
495
- }] } });
469
+ }], ctorParameters: () => [] });
496
470
 
497
471
  function hasInput(componentRef, inputKey) {
498
472
  return componentRef['_tNode'].inputs?.[inputKey];
@@ -509,37 +483,43 @@ class ThyViewOutletDirective {
509
483
  /**
510
484
  * 组件或者模板 TemplateRef
511
485
  */
512
- this.thyViewOutlet = null;
513
- }
514
- ngOnChanges(changes) {
515
- const { viewContainerRef: viewContainerRef } = this;
516
- if (changes['thyViewOutlet']) {
486
+ this.thyViewOutlet = input(null);
487
+ /**
488
+ * 组件和模板上下文传递数据
489
+ */
490
+ this.thyViewOutletContext = input();
491
+ effect(() => {
492
+ const thyViewOutlet = this.thyViewOutlet();
493
+ const { viewContainerRef: viewContainerRef } = this;
517
494
  viewContainerRef.clear();
518
495
  this.componentRef = undefined;
519
496
  this.embeddedViewRef = undefined;
520
- if (this.thyViewOutlet) {
521
- if (this.thyViewOutlet instanceof TemplateRef) {
522
- this.embeddedViewRef = viewContainerRef.createEmbeddedView(this.thyViewOutlet, this.thyViewOutletContext);
497
+ if (thyViewOutlet) {
498
+ if (thyViewOutlet instanceof TemplateRef) {
499
+ this.embeddedViewRef = viewContainerRef.createEmbeddedView(thyViewOutlet, this.thyViewOutletContext());
523
500
  }
524
501
  else {
525
- this.componentRef = viewContainerRef.createComponent(this.thyViewOutlet, {
502
+ this.componentRef = viewContainerRef.createComponent(thyViewOutlet, {
526
503
  index: viewContainerRef.length
527
504
  });
528
505
  }
529
506
  }
530
- }
531
- if (changes['thyViewOutletContext']) {
507
+ });
508
+ effect(() => {
509
+ const thyViewOutletContext = this.thyViewOutletContext();
532
510
  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
- });
511
+ if (thyViewOutletContext) {
512
+ if (!this.keyValueDiffer) {
513
+ this.keyValueDiffer = this.keyValueDiffers.find(this.thyViewOutletContext()).create();
514
+ this.keyValueDiffer.diff(thyViewOutletContext);
515
+ updatedKeys = Object.keys(thyViewOutletContext);
516
+ }
517
+ else {
518
+ const diffChanges = this.keyValueDiffer.diff(this.thyViewOutletContext());
519
+ diffChanges?.forEachChangedItem(item => {
520
+ updatedKeys.push(item.key);
521
+ });
522
+ }
543
523
  }
544
524
  if (this.componentRef) {
545
525
  this.updateContext(this.componentRef.instance, updatedKeys);
@@ -549,32 +529,28 @@ class ThyViewOutletDirective {
549
529
  this.updateContext(this.embeddedViewRef.context, updatedKeys);
550
530
  this.embeddedViewRef.markForCheck();
551
531
  }
552
- }
532
+ });
553
533
  }
554
534
  updateContext(context, updatedKeys) {
555
535
  updatedKeys.forEach(key => {
556
536
  // 兼容组件输入属性没有通过 @Input,设置了 @Input 采用 setInput,否则直接赋值,setInput 会触发 Angular 组件的 onChanges
557
537
  if (this.componentRef && hasInput(this.componentRef, key)) {
558
- this.componentRef.setInput(key, this.thyViewOutletContext[key]);
538
+ this.componentRef.setInput(key, this.thyViewOutletContext()[key]);
559
539
  }
560
540
  else {
561
- context[key] = this.thyViewOutletContext[key];
541
+ context[key] = this.thyViewOutletContext()[key];
562
542
  }
563
543
  });
564
544
  }
565
545
  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 }); }
546
+ 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
547
  }
568
548
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyViewOutletDirective, decorators: [{
569
549
  type: Directive,
570
550
  args: [{
571
551
  selector: '[thyViewOutlet]'
572
552
  }]
573
- }], propDecorators: { thyViewOutlet: [{
574
- type: Input
575
- }], thyViewOutletContext: [{
576
- type: Input
577
- }] } });
553
+ }], ctorParameters: () => [] });
578
554
 
579
555
  class ThySharedModule {
580
556
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThySharedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
@@ -639,33 +615,6 @@ const noop = () => { };
639
615
  * @private
640
616
  */
641
617
  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
618
  /**
670
619
  * 是否禁用
671
620
  * @default false
@@ -709,8 +658,28 @@ class ThyFormCheckBaseComponent extends TabIndexDisabledControlValueAccessorMixi
709
658
  this.onTouchedCallback = noop;
710
659
  this.onChangeCallback = noop;
711
660
  this._isFormCheck = true;
712
- this._isFormCheckInline = false;
713
661
  this._isChecked = false;
662
+ /**
663
+ * 是否同一行展示
664
+ * @default false
665
+ */
666
+ this.thyInline = input(false, { transform: coerceBooleanProperty });
667
+ /**
668
+ * Label 展示文本
669
+ */
670
+ this.thyLabelText = input();
671
+ /**
672
+ * Label 文本多语言 key
673
+ */
674
+ this.thyLabelTextTranslateKey = input();
675
+ this._labelText = computed(() => {
676
+ const labelTextTranslateKey = this.thyLabelTextTranslateKey();
677
+ const labelText = this.thyLabelText();
678
+ return labelTextTranslateKey ? this.thyTranslate.instant(labelTextTranslateKey) : labelText || '';
679
+ });
680
+ this._isNoText = computed(() => {
681
+ return this.thyInline() && !this._labelText();
682
+ });
714
683
  this.disabled = false;
715
684
  }
716
685
  change() {
@@ -722,30 +691,19 @@ class ThyFormCheckBaseComponent extends TabIndexDisabledControlValueAccessorMixi
722
691
  }
723
692
  }
724
693
  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 }); }
694
+ 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
695
  }
727
696
  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: [{
697
+ type: Directive,
698
+ args: [{
699
+ host: {
700
+ '[class.form-check]': '_isFormCheck',
701
+ '[class.form-check-inline]': 'thyInline()',
702
+ '[class.form-check-checked]': '_isChecked',
703
+ '[class.form-check-inline-no-label-text]': '_isNoText()'
704
+ }
705
+ }]
706
+ }], ctorParameters: () => [], propDecorators: { thyDisabled: [{
749
707
  type: Input,
750
708
  args: [{ transform: coerceBooleanProperty }]
751
709
  }] } });
@@ -754,117 +712,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
754
712
  * @private
755
713
  */
756
714
  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
715
  get selectedValueStyle() {
865
716
  let showSelectedValue = false;
866
- if (this.showSearch) {
867
- if (this.panelOpened) {
717
+ if (this.thyShowSearch()) {
718
+ if (this.thyPanelOpened()) {
868
719
  showSelectedValue = !(this.isComposing || this.inputValue);
869
720
  }
870
721
  else {
@@ -878,10 +729,10 @@ class ThySelectControl {
878
729
  }
879
730
  get placeholderStyle() {
880
731
  let placeholder = true;
881
- if (this.isSelectedValue) {
732
+ if (this.isSelectedValue()) {
882
733
  placeholder = false;
883
734
  }
884
- if (!this.thyPlaceholder) {
735
+ if (!this.thyPlaceholder()) {
885
736
  placeholder = false;
886
737
  }
887
738
  if (this.isComposing || this.inputValue) {
@@ -889,47 +740,138 @@ class ThySelectControl {
889
740
  }
890
741
  return { display: placeholder ? 'block' : 'none' };
891
742
  }
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();
743
+ constructor() {
744
+ this.renderer = inject(Renderer2);
745
+ this.inputValue = '';
746
+ this.isComposing = false;
747
+ this.hostRenderer = useHostRenderer();
748
+ this.thyPanelOpened = input(false, { transform: coerceBooleanProperty });
749
+ this.thyIsMultiple = input(false, { transform: coerceBooleanProperty });
750
+ this.thyShowSearch = input(false, { transform: coerceBooleanProperty });
751
+ this.thySelectedOptions = input();
752
+ this.previousSelectedOptions = linkedSignal({
753
+ source: () => this.thySelectedOptions(),
754
+ computation: (source, previous) => previous?.source
755
+ });
756
+ this.thyDisabled = input(false, { transform: coerceBooleanProperty });
757
+ this.customDisplayTemplate = input(undefined);
758
+ this.thyAllowClear = input(false, { transform: coerceBooleanProperty });
759
+ this.thyPlaceholder = input('');
760
+ this.thySize = input();
761
+ this.tagSize = computed(() => {
762
+ const value = this.thySize();
763
+ if (value === 'xs' || value === 'sm') {
764
+ return 'sm';
765
+ }
766
+ else if (value === 'lg') {
767
+ return 'lg';
768
+ }
769
+ else {
770
+ return 'md';
771
+ }
772
+ });
773
+ this.thyMaxTagCount = input(0, { transform: numberAttribute });
774
+ this.thyBorderless = input(false, { transform: coerceBooleanProperty });
775
+ this.thyPreset = input('');
776
+ this.thyOnSearch = output();
777
+ this.thyOnRemove = output();
778
+ this.thyOnClear = output();
779
+ this.thyOnBlur = output();
780
+ this.inputElement = viewChild('inputElement');
781
+ this.isSelectedValue = computed(() => {
782
+ return ((!this.thyIsMultiple() && !isUndefinedOrNull(this.thySelectedOptions())) ||
783
+ (this.thyIsMultiple() && this.thySelectedOptions().length > 0));
784
+ });
785
+ this.showClearIcon = computed(() => {
786
+ return this.thyAllowClear() && this.isSelectedValue();
787
+ });
788
+ this.maxSelectedTags = computed(() => {
789
+ const selectedOptions = this.thySelectedOptions();
790
+ if (this.thyMaxTagCount() > 0 && selectedOptions instanceof Array && selectedOptions.length > this.thyMaxTagCount()) {
791
+ return selectedOptions.slice(0, this.thyMaxTagCount() - 1);
792
+ }
793
+ return selectedOptions;
794
+ });
795
+ effect(() => {
796
+ const panelOpened = this.thyPanelOpened();
797
+ if (panelOpened) {
798
+ untracked(() => {
799
+ if (this.thyShowSearch()) {
800
+ Promise.resolve(null).then(() => {
801
+ this.inputElement().nativeElement.focus();
802
+ });
803
+ }
804
+ });
805
+ }
806
+ else {
807
+ untracked(() => {
808
+ if (this.thyShowSearch()) {
809
+ new Promise(resolve => setTimeout(resolve, 100)).then(() => {
810
+ if (this.inputValue) {
811
+ this.inputValue = '';
812
+ this.updateWidth();
813
+ this.thyOnSearch.emit(this.inputValue);
814
+ }
815
+ });
816
+ }
817
+ });
818
+ }
819
+ });
820
+ effect(() => {
821
+ this.setSelectControlClass();
822
+ });
823
+ effect(() => {
824
+ let sameValue = false;
825
+ const oldValue = this.previousSelectedOptions();
826
+ const value = this.thySelectedOptions();
827
+ untracked(() => {
828
+ if (this.thyIsMultiple()) {
829
+ if (oldValue instanceof Array && value instanceof Array && oldValue.length === value.length) {
830
+ sameValue = value.every((option, index) => option.thyValue === oldValue[index].thyValue);
831
+ }
832
+ }
833
+ else {
834
+ if (oldValue && value) {
835
+ sameValue = oldValue.thyValue === value.thyValue;
836
+ }
837
+ }
838
+ if (this.thyPanelOpened() && this.thyShowSearch()) {
839
+ if (!sameValue) {
840
+ Promise.resolve(null).then(() => {
841
+ this.inputValue = '';
842
+ this.updateWidth();
843
+ });
844
+ }
845
+ //等待组件渲染好再聚焦
846
+ setTimeout(() => {
847
+ if (this.thyPanelOpened()) {
848
+ this.inputElement().nativeElement.focus();
849
+ }
850
+ }, 200);
851
+ }
852
+ });
853
+ });
913
854
  }
855
+ ngOnInit() { }
914
856
  setSelectControlClass() {
915
- const modeType = this.isMultiple ? 'multiple' : 'single';
857
+ const modeType = this.thyIsMultiple() ? 'multiple' : 'single';
916
858
  const selectControlClass = {
917
859
  [`form-control`]: true,
918
- [`form-control-${this.thySize}`]: !!this.thySize,
860
+ [`form-control-${this.thySize()}`]: !!this.thySize(),
919
861
  [`form-control-custom`]: true,
920
862
  [`select-control`]: true,
921
863
  [`select-control-${modeType}`]: true,
922
- [`select-control-show-search`]: this.showSearch,
923
- [`panel-is-opened`]: this.panelOpened,
924
- [`disabled`]: this.disabled
864
+ [`select-control-show-search`]: this.thyShowSearch(),
865
+ [`panel-is-opened`]: this.thyPanelOpened(),
866
+ [`disabled`]: this.thyDisabled()
925
867
  };
926
868
  this.hostRenderer.updateClassByMap(selectControlClass);
927
869
  this.searchInputControlClass = {
928
870
  [`form-control`]: true,
929
- [`form-control-${this.thySize}`]: !!this.thySize,
871
+ [`form-control-${this.thySize()}`]: !!this.thySize(),
930
872
  [`search-input-field`]: true,
931
- [`hidden`]: !this.thyShowSearch,
932
- [`disabled`]: this.thyDisabled
873
+ [`hidden`]: !this.thyShowSearch(),
874
+ [`disabled`]: this.thyDisabled()
933
875
  };
934
876
  }
935
877
  setInputValue(value) {
@@ -943,19 +885,20 @@ class ThySelectControl {
943
885
  if (event.isComposing) {
944
886
  return;
945
887
  }
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);
888
+ const selectedOptions = this.thySelectedOptions();
889
+ if (!this.inputValue?.length && selectedOptions instanceof Array) {
890
+ if (selectedOptions.length > 0) {
891
+ this.removeHandle(selectedOptions[selectedOptions.length - 1], event);
949
892
  }
950
893
  }
951
894
  }
952
895
  updateWidth() {
953
- if (this.isMultiple && this.thyShowSearch) {
896
+ if (this.thyIsMultiple() && this.thyShowSearch()) {
954
897
  if (this.inputValue || this.isComposing) {
955
- this.renderer.setStyle(this.inputElement.nativeElement, 'width', `${this.inputElement.nativeElement.scrollWidth}px`);
898
+ this.renderer.setStyle(this.inputElement().nativeElement, 'width', `${this.inputElement().nativeElement.scrollWidth}px`);
956
899
  }
957
900
  else {
958
- this.renderer.removeStyle(this.inputElement.nativeElement, 'width');
901
+ this.renderer.removeStyle(this.inputElement().nativeElement, 'width');
959
902
  }
960
903
  }
961
904
  }
@@ -972,56 +915,14 @@ class ThySelectControl {
972
915
  this.thyOnBlur.emit(event);
973
916
  }
974
917
  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 }); }
918
+ 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
919
  }
977
920
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThySelectControl, decorators: [{
978
921
  type: Component,
979
922
  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
- }] } });
923
+ '[class.select-control-borderless]': 'thyBorderless()'
924
+ }, 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" }]
925
+ }], ctorParameters: () => [] });
1025
926
 
1026
927
  /**
1027
928
  * @license
@@ -1060,11 +961,12 @@ let _uniqueIdCounter = 0;
1060
961
  class ThyListOption {
1061
962
  constructor() {
1062
963
  this.element = inject(ElementRef);
1063
- this.changeDetector = inject(ChangeDetectorRef);
1064
964
  this.parentSelectionList = inject(THY_LIST_OPTION_PARENT_COMPONENT, { optional: true });
1065
965
  this._role = 'option';
1066
966
  this._tabIndex = -1;
1067
- this.id = `thy-list-option-${_uniqueIdCounter++}`;
967
+ this.id = input(`thy-list-option-${_uniqueIdCounter++}`);
968
+ this.thyValue = input(undefined);
969
+ this.thyDisabled = input(false, { transform: coerceBooleanProperty });
1068
970
  }
1069
971
  get _isListOption() {
1070
972
  return this.parentSelectionList.layout === 'list';
@@ -1072,9 +974,6 @@ class ThyListOption {
1072
974
  get _parentLayout() {
1073
975
  return this.parentSelectionList.layout === 'grid';
1074
976
  }
1075
- set thyDisabled(value) {
1076
- this.disabled = value;
1077
- }
1078
977
  /** Whether the option is selected. */
1079
978
  get selected() {
1080
979
  return this.parentSelectionList.isSelected(this);
@@ -1108,11 +1007,13 @@ class ThyListOption {
1108
1007
  return '';
1109
1008
  }
1110
1009
  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"] }] }); }
1010
+ 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": "this._isListOption", "class.thy-grid-option": "this._parentLayout", "attr.role": "this._role", "attr.tabindex": "this._tabIndex", "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"] }] }); }
1112
1011
  }
1113
1012
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyListOption, decorators: [{
1114
1013
  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" }]
1014
+ args: [{ selector: 'thy-list-option,[thy-list-option]', imports: [ThyIcon], host: {
1015
+ '[class.disabled]': 'thyDisabled()'
1016
+ }, 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
1017
  }], propDecorators: { _isListOption: [{
1117
1018
  type: HostBinding,
1118
1019
  args: [`class.thy-list-option`]
@@ -1125,16 +1026,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
1125
1026
  }], _tabIndex: [{
1126
1027
  type: HostBinding,
1127
1028
  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
1029
  }], selected: [{
1139
1030
  type: HostBinding,
1140
1031
  args: [`class.active`]
@@ -1180,35 +1071,26 @@ class ThyOptionVisibleChangeEvent {
1180
1071
  * @order 20
1181
1072
  */
1182
1073
  class ThyOption extends SelectOptionBase {
1183
- set thyDisabled(value) {
1184
- this._disabled = value;
1185
- }
1186
- get thyDisabled() {
1187
- return this._disabled;
1188
- }
1074
+ // 继承至 Highlightable,无法修改为 Signal
1189
1075
  get disabled() {
1190
- return this.hidden || this._disabled;
1191
- }
1192
- get hidden() {
1193
- return this._hidden;
1076
+ return this.hidden() || this.thyDisabled();
1194
1077
  }
1195
1078
  get tabIndex() {
1196
1079
  return this.disabled ? '-1' : '0';
1197
1080
  }
1198
- get selected() {
1199
- return this._selected;
1200
- }
1201
1081
  constructor() {
1202
1082
  super();
1203
1083
  this.element = inject(ElementRef);
1204
1084
  this.parent = inject(THY_OPTION_PARENT_COMPONENT, { optional: true });
1205
1085
  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();
1086
+ this.thyShowOptionCustom = input();
1087
+ this.thySearchKey = input();
1088
+ this.template = viewChild(TemplateRef);
1089
+ this.thyDisabled = input(false, { transform: coerceBooleanProperty });
1090
+ this.hidden = signal(false);
1091
+ this.selected = signal(false);
1092
+ this.selectionChange = output();
1093
+ this.visibleChange = output();
1212
1094
  }
1213
1095
  getHostElement() {
1214
1096
  return this.element.nativeElement;
@@ -1224,44 +1106,46 @@ class ThyOption extends SelectOptionBase {
1224
1106
  }
1225
1107
  selectViaInteraction() {
1226
1108
  if (!this.disabled) {
1227
- this._selected = this.parent.isMultiple ? !this._selected : true;
1109
+ const selected = this.parent.isMultiple ? !this.selected() : true;
1110
+ this.selected.set(selected);
1228
1111
  this.cdr.markForCheck();
1229
1112
  this.emitSelectionChangeEvent(true);
1230
1113
  }
1231
1114
  }
1232
1115
  select(event) {
1233
1116
  if (!this.disabled) {
1234
- if (!this._selected) {
1235
- this._selected = true;
1117
+ if (!this.selected()) {
1118
+ this.selected.set(true);
1236
1119
  this.emitSelectionChangeEvent();
1237
1120
  this.cdr.markForCheck();
1238
1121
  }
1239
1122
  }
1240
1123
  }
1241
1124
  deselect() {
1242
- if (this._selected || this.disabled) {
1243
- this._selected = false;
1125
+ if (this.selected() || this.disabled) {
1126
+ this.selected.set(false);
1244
1127
  this.emitSelectionChangeEvent();
1245
1128
  this.cdr.markForCheck();
1246
1129
  }
1247
1130
  }
1248
1131
  hideOption() {
1249
- if (!this._hidden) {
1250
- this._hidden = true;
1132
+ if (!this.hidden()) {
1133
+ this.hidden.set(true);
1251
1134
  this.visibleChange.emit({ option: this });
1252
1135
  this.cdr.markForCheck();
1253
1136
  }
1254
1137
  }
1255
1138
  showOption() {
1256
- if (this._hidden) {
1257
- this._hidden = false;
1139
+ if (this.hidden()) {
1140
+ this.hidden.set(false);
1258
1141
  this.visibleChange.emit({ option: this });
1259
1142
  this.cdr.markForCheck();
1260
1143
  }
1261
1144
  }
1262
1145
  matchSearchText(searchText) {
1263
- if (this.thySearchKey) {
1264
- if (this.thySearchKey.toLowerCase().indexOf(searchText.toLowerCase()) >= 0) {
1146
+ const thySearchKey = this.thySearchKey();
1147
+ if (thySearchKey) {
1148
+ if (thySearchKey.toLowerCase().indexOf(searchText.toLowerCase()) >= 0) {
1265
1149
  return true;
1266
1150
  }
1267
1151
  else {
@@ -1293,46 +1177,23 @@ class ThyOption extends SelectOptionBase {
1293
1177
  }
1294
1178
  ngOnDestroy() { }
1295
1179
  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 }); }
1180
+ 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
1181
  }
1298
1182
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThyOption, decorators: [{
1299
1183
  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" }]
1184
+ args: [{ selector: 'thy-option', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ThyIcon], host: {
1185
+ class: 'thy-option-item',
1186
+ '[class.disabled]': 'thyDisabled()',
1187
+ '[class.hidden]': 'hidden()',
1188
+ '[attr.tabindex]': `tabIndex`,
1189
+ '[class.active]': 'selected()'
1190
+ }, 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
1191
  }], ctorParameters: () => [], propDecorators: { thyValue: [{
1302
1192
  type: Input
1303
1193
  }], thyRawValue: [{
1304
1194
  type: Input
1305
1195
  }], thyLabelText: [{
1306
1196
  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
1197
  }], onClick: [{
1337
1198
  type: HostListener,
1338
1199
  args: ['click', ['$event']]
@@ -1348,19 +1209,17 @@ class ThySelectOptionGroup {
1348
1209
  constructor() {
1349
1210
  this._ngZone = inject(NgZone);
1350
1211
  this.cdr = inject(ChangeDetectorRef);
1351
- this._hidden = false;
1352
- this._isOptionGroup = true;
1212
+ this.thyDisabled = input(false, { transform: coerceBooleanProperty });
1213
+ this.hidden = signal(false);
1214
+ this.thyGroupLabel = input(undefined);
1353
1215
  this._destroy$ = new Subject();
1354
1216
  this.optionVisibleChanges = defer(() => {
1355
1217
  if (this.options) {
1356
- return merge(...this.options.map(option => option.visibleChange));
1218
+ return merge(...this.options.map(option => outputToObservable(option.visibleChange)));
1357
1219
  }
1358
1220
  return this._ngZone.onStable.asObservable().pipe(take(1), switchMap(() => this.optionVisibleChanges));
1359
1221
  });
1360
1222
  }
1361
- get hidden() {
1362
- return this._hidden;
1363
- }
1364
1223
  ngAfterContentInit() {
1365
1224
  this.options.changes.pipe(startWith(null), takeUntil(this._destroy$)).subscribe(() => {
1366
1225
  this._resetOptions();
@@ -1368,10 +1227,10 @@ class ThySelectOptionGroup {
1368
1227
  }
1369
1228
  _resetOptions() {
1370
1229
  const changedOrDestroyed$ = merge(this.options.changes, this._destroy$);
1371
- merge(...this.options.map(option => option.visibleChange))
1230
+ merge(...this.options.map(option => outputToObservable(option.visibleChange)))
1372
1231
  .pipe(takeUntil(changedOrDestroyed$), debounceTime(10), map((event) => {
1373
1232
  const hasOption = this.options.find(option => {
1374
- if (!option.hidden) {
1233
+ if (!option.hidden()) {
1375
1234
  return true;
1376
1235
  }
1377
1236
  });
@@ -1383,7 +1242,7 @@ class ThySelectOptionGroup {
1383
1242
  }
1384
1243
  }))
1385
1244
  .subscribe((data) => {
1386
- this._hidden = data;
1245
+ this.hidden.set(data);
1387
1246
  this.cdr.markForCheck();
1388
1247
  });
1389
1248
  }
@@ -1392,35 +1251,27 @@ class ThySelectOptionGroup {
1392
1251
  this._destroy$.complete();
1393
1252
  }
1394
1253
  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" }); }
1254
+ 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
1255
  }
1397
1256
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: ThySelectOptionGroup, decorators: [{
1398
1257
  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: [{
1258
+ args: [{ selector: 'thy-option-group', host: {
1259
+ class: 'thy-option-item-group',
1260
+ '[class.disabled]': 'thyDisabled()',
1261
+ '[class.thy-select-option-group-hidden]': 'hidden()'
1262
+ }, template: "<span class=\"group-name text-truncate\">{{ thyGroupLabel() }}</span>\n<ng-content></ng-content>\n" }]
1263
+ }], propDecorators: { options: [{
1415
1264
  type: ContentChildren,
1416
1265
  args: [ThyOption]
1417
1266
  }] } });
1418
1267
 
1419
1268
  class ThyOptionsContainer {
1420
- constructor() { }
1269
+ constructor() {
1270
+ this.optionsTemplate = viewChild('options');
1271
+ }
1421
1272
  ngOnInit() { }
1422
1273
  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: `
1274
+ 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
1275
  <ng-template #options>
1425
1276
  <ng-content></ng-content>
1426
1277
  </ng-template>
@@ -1437,10 +1288,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
1437
1288
  `,
1438
1289
  changeDetection: ChangeDetectionStrategy.OnPush
1439
1290
  }]
1440
- }], ctorParameters: () => [], propDecorators: { optionsTemplate: [{
1441
- type: ViewChild,
1442
- args: ['options']
1443
- }] } });
1291
+ }], ctorParameters: () => [] });
1444
1292
 
1445
1293
  /**
1446
1294
  * @license