carbon-components-angular 5.72.0 → 5.72.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/combobox/combobox.component.d.ts +3 -0
  2. package/docs/documentation/components/ComboBox.html +214 -67
  3. package/docs/documentation/components/Dropdown.html +322 -134
  4. package/docs/documentation/components/DropdownList.html +6 -2
  5. package/docs/documentation/components/RadioGroup.html +166 -77
  6. package/docs/documentation/components/TextInputLabelComponent.html +171 -65
  7. package/docs/documentation/components/TextareaLabelComponent.html +142 -74
  8. package/docs/documentation/coverage.html +22 -22
  9. package/docs/documentation/directives/TextArea.html +106 -11
  10. package/docs/documentation/directives/TextInput.html +118 -24
  11. package/docs/documentation/js/search/search_index.js +2 -2
  12. package/docs/documentation/modules/CheckboxModule/dependencies.svg +42 -42
  13. package/docs/documentation/modules/CheckboxModule.html +42 -42
  14. package/docs/documentation/modules/CodeSnippetModule/dependencies.svg +4 -4
  15. package/docs/documentation/modules/CodeSnippetModule.html +4 -4
  16. package/docs/documentation/modules/ComboBoxModule/dependencies.svg +6 -6
  17. package/docs/documentation/modules/ComboBoxModule.html +6 -6
  18. package/docs/documentation/modules/ContentSwitcherModule/dependencies.svg +4 -4
  19. package/docs/documentation/modules/ContentSwitcherModule.html +4 -4
  20. package/docs/documentation/modules/ContextMenuModule/dependencies.svg +67 -67
  21. package/docs/documentation/modules/ContextMenuModule.html +67 -67
  22. package/docs/documentation/modules/DatePickerInputModule/dependencies.svg +4 -4
  23. package/docs/documentation/modules/DatePickerInputModule.html +4 -4
  24. package/docs/documentation/modules/DatePickerModule/dependencies.svg +6 -6
  25. package/docs/documentation/modules/DatePickerModule.html +6 -6
  26. package/docs/documentation/modules/DialogModule/dependencies.svg +33 -33
  27. package/docs/documentation/modules/DialogModule.html +33 -33
  28. package/docs/documentation/modules/DocumentationModule/dependencies.svg +4 -4
  29. package/docs/documentation/modules/DocumentationModule.html +4 -4
  30. package/docs/documentation/modules/DropdownModule/dependencies.svg +53 -53
  31. package/docs/documentation/modules/DropdownModule.html +53 -53
  32. package/docs/documentation/modules/FileUploaderModule/dependencies.svg +35 -35
  33. package/docs/documentation/modules/FileUploaderModule.html +35 -35
  34. package/docs/documentation/modules/GridModule/dependencies.svg +61 -61
  35. package/docs/documentation/modules/GridModule.html +61 -61
  36. package/docs/documentation/modules/HeaderModule/dependencies.svg +4 -4
  37. package/docs/documentation/modules/HeaderModule.html +4 -4
  38. package/docs/documentation/modules/I18nModule/dependencies.svg +13 -13
  39. package/docs/documentation/modules/I18nModule.html +13 -13
  40. package/docs/documentation/modules/InlineLoadingModule/dependencies.svg +15 -15
  41. package/docs/documentation/modules/InlineLoadingModule.html +15 -15
  42. package/docs/documentation/modules/InputModule/dependencies.svg +4 -4
  43. package/docs/documentation/modules/InputModule.html +4 -4
  44. package/docs/documentation/modules/LayerModule/dependencies.svg +4 -4
  45. package/docs/documentation/modules/LayerModule.html +4 -4
  46. package/docs/documentation/modules/MenuButtonModule/dependencies.svg +4 -4
  47. package/docs/documentation/modules/MenuButtonModule.html +4 -4
  48. package/docs/documentation/modules/ModalModule/dependencies.svg +114 -114
  49. package/docs/documentation/modules/ModalModule.html +114 -114
  50. package/docs/documentation/modules/NFormsModule/dependencies.svg +4 -4
  51. package/docs/documentation/modules/NFormsModule.html +4 -4
  52. package/docs/documentation/modules/NotificationModule/dependencies.svg +4 -4
  53. package/docs/documentation/modules/NotificationModule.html +4 -4
  54. package/docs/documentation/modules/NumberModule/dependencies.svg +25 -25
  55. package/docs/documentation/modules/NumberModule.html +25 -25
  56. package/docs/documentation/modules/PaginationModule/dependencies.svg +4 -4
  57. package/docs/documentation/modules/PaginationModule.html +4 -4
  58. package/docs/documentation/modules/PanelModule/dependencies.svg +4 -4
  59. package/docs/documentation/modules/PanelModule.html +4 -4
  60. package/docs/documentation/modules/PlaceholderModule/dependencies.svg +4 -4
  61. package/docs/documentation/modules/PlaceholderModule.html +4 -4
  62. package/docs/documentation/modules/RadioModule/dependencies.svg +4 -4
  63. package/docs/documentation/modules/RadioModule.html +4 -4
  64. package/docs/documentation/modules/SearchModule/dependencies.svg +48 -44
  65. package/docs/documentation/modules/SearchModule.html +48 -44
  66. package/docs/documentation/modules/SelectModule/dependencies.svg +4 -4
  67. package/docs/documentation/modules/SelectModule.html +4 -4
  68. package/docs/documentation/modules/SideNavModule/dependencies.svg +4 -4
  69. package/docs/documentation/modules/SideNavModule.html +4 -4
  70. package/docs/documentation/modules/SkeletonModule/dependencies.svg +4 -4
  71. package/docs/documentation/modules/SkeletonModule.html +4 -4
  72. package/docs/documentation/modules/SliderModule/dependencies.svg +26 -26
  73. package/docs/documentation/modules/SliderModule.html +26 -26
  74. package/docs/documentation/modules/StructuredListModule/dependencies.svg +43 -43
  75. package/docs/documentation/modules/StructuredListModule.html +43 -43
  76. package/docs/documentation/modules/TableModule/dependencies.svg +225 -225
  77. package/docs/documentation/modules/TableModule.html +225 -225
  78. package/docs/documentation/modules/TabsModule/dependencies.svg +136 -136
  79. package/docs/documentation/modules/TabsModule.html +136 -136
  80. package/docs/documentation/modules/TagModule/dependencies.svg +38 -38
  81. package/docs/documentation/modules/TagModule.html +38 -38
  82. package/docs/documentation/modules/ThemeModule/dependencies.svg +4 -4
  83. package/docs/documentation/modules/ThemeModule.html +4 -4
  84. package/docs/documentation/modules/TilesModule/dependencies.svg +108 -108
  85. package/docs/documentation/modules/TilesModule.html +108 -108
  86. package/docs/documentation/modules/TimePickerModule/dependencies.svg +41 -45
  87. package/docs/documentation/modules/TimePickerModule.html +41 -45
  88. package/docs/documentation/modules/TimePickerSelectModule/dependencies.svg +46 -42
  89. package/docs/documentation/modules/TimePickerSelectModule.html +46 -42
  90. package/docs/documentation/modules/ToggleModule/dependencies.svg +7 -7
  91. package/docs/documentation/modules/ToggleModule.html +7 -7
  92. package/docs/documentation/modules/TooltipModule/dependencies.svg +28 -28
  93. package/docs/documentation/modules/TooltipModule.html +28 -28
  94. package/docs/documentation/modules/TreeviewModule/dependencies.svg +28 -28
  95. package/docs/documentation/modules/TreeviewModule.html +28 -28
  96. package/docs/documentation.json +510 -362
  97. package/docs/storybook/1345.da6e3dec.iframe.bundle.js +1 -0
  98. package/docs/storybook/3224.14e2c79a.iframe.bundle.js +1 -0
  99. package/docs/storybook/557.d4341469.iframe.bundle.js +1 -0
  100. package/docs/storybook/7019.75ad5817.iframe.bundle.js +2 -0
  101. package/docs/storybook/955.7522f55b.iframe.bundle.js +1 -0
  102. package/docs/storybook/combobox-combobox-stories.e3d08f7d.iframe.bundle.js +1 -0
  103. package/docs/storybook/dropdown-dropdown-stories.cf59b2ab.iframe.bundle.js +1 -0
  104. package/docs/storybook/iframe.html +2 -2
  105. package/docs/storybook/{input-input-stories.85a9e65e.iframe.bundle.js → input-input-stories.8bf34960.iframe.bundle.js} +1 -1
  106. package/docs/storybook/{input-textarea-stories.77240fb3.iframe.bundle.js → input-textarea-stories.ad775432.iframe.bundle.js} +1 -1
  107. package/docs/storybook/main.a1247bb8.iframe.bundle.js +1 -0
  108. package/docs/storybook/modal-modal-stories.cc2d04cb.iframe.bundle.js +1 -0
  109. package/docs/storybook/{pagination-pagination-nav-stories.547eede3.iframe.bundle.js → pagination-pagination-nav-stories.01637d11.iframe.bundle.js} +1 -1
  110. package/docs/storybook/{pagination-pagination-stories.fa7c9094.iframe.bundle.js → pagination-pagination-stories.40d17ebd.iframe.bundle.js} +1 -1
  111. package/docs/storybook/{patterns-filtering-single-selection-stories.ec91f833.iframe.bundle.js → patterns-filtering-multi-selection-stories.a46a1d6e.iframe.bundle.js} +1 -1
  112. package/docs/storybook/{patterns-filtering-multiple-categories-stories.531f27d7.iframe.bundle.js → patterns-filtering-multiple-categories-stories.740c719e.iframe.bundle.js} +1 -1
  113. package/docs/storybook/{patterns-filtering-multi-selection-stories.9086f77f.iframe.bundle.js → patterns-filtering-single-selection-stories.cc647b4a.iframe.bundle.js} +1 -1
  114. package/docs/storybook/{patterns-forms-multi-step-form-stories.8696062a.iframe.bundle.js → patterns-forms-multi-step-form-stories.2ea46e56.iframe.bundle.js} +1 -1
  115. package/docs/storybook/{patterns-loading-large-loading-stories.734fb9bc.iframe.bundle.js → patterns-loading-large-loading-stories.e6ae3e31.iframe.bundle.js} +1 -1
  116. package/docs/storybook/{patterns-loading-progressive-loading-stories.10bcf9f2.iframe.bundle.js → patterns-loading-progressive-loading-stories.63165c09.iframe.bundle.js} +1 -1
  117. package/docs/storybook/project.json +1 -1
  118. package/docs/storybook/radio-radio-stories.8ff73370.iframe.bundle.js +1 -0
  119. package/docs/storybook/runtime~main.b11c471e.iframe.bundle.js +1 -0
  120. package/dropdown/dropdown.component.d.ts +8 -1
  121. package/dropdown/list/dropdown-list.component.d.ts +1 -1
  122. package/esm2020/combobox/combobox.component.mjs +19 -9
  123. package/esm2020/dropdown/dropdown.component.mjs +31 -15
  124. package/esm2020/dropdown/list/dropdown-list.component.mjs +1 -1
  125. package/esm2020/input/input.directive.mjs +11 -5
  126. package/esm2020/input/text-area.directive.mjs +11 -5
  127. package/esm2020/input/text-input-label.component.mjs +38 -15
  128. package/esm2020/input/textarea-label.component.mjs +46 -21
  129. package/esm2020/radio/radio-group.component.mjs +19 -7
  130. package/fesm2015/carbon-components-angular-combobox.mjs +18 -8
  131. package/fesm2015/carbon-components-angular-combobox.mjs.map +1 -1
  132. package/fesm2015/carbon-components-angular-dropdown.mjs +31 -14
  133. package/fesm2015/carbon-components-angular-dropdown.mjs.map +1 -1
  134. package/fesm2015/carbon-components-angular-input.mjs +112 -46
  135. package/fesm2015/carbon-components-angular-input.mjs.map +1 -1
  136. package/fesm2015/carbon-components-angular-radio.mjs +18 -6
  137. package/fesm2015/carbon-components-angular-radio.mjs.map +1 -1
  138. package/fesm2020/carbon-components-angular-combobox.mjs +18 -8
  139. package/fesm2020/carbon-components-angular-combobox.mjs.map +1 -1
  140. package/fesm2020/carbon-components-angular-dropdown.mjs +30 -14
  141. package/fesm2020/carbon-components-angular-dropdown.mjs.map +1 -1
  142. package/fesm2020/carbon-components-angular-input.mjs +102 -45
  143. package/fesm2020/carbon-components-angular-input.mjs.map +1 -1
  144. package/fesm2020/carbon-components-angular-radio.mjs +18 -6
  145. package/fesm2020/carbon-components-angular-radio.mjs.map +1 -1
  146. package/input/input.directive.d.ts +4 -1
  147. package/input/text-area.directive.d.ts +4 -1
  148. package/input/text-input-label.component.d.ts +9 -5
  149. package/input/textarea-label.component.d.ts +5 -3
  150. package/package.json +1 -1
  151. package/radio/radio-group.component.d.ts +4 -2
  152. package/docs/storybook/1250.47c381c1.iframe.bundle.js +0 -1
  153. package/docs/storybook/1345.9ccf4f3f.iframe.bundle.js +0 -1
  154. package/docs/storybook/3224.3e279e46.iframe.bundle.js +0 -1
  155. package/docs/storybook/7019.b8944046.iframe.bundle.js +0 -2
  156. package/docs/storybook/955.99b6ac85.iframe.bundle.js +0 -1
  157. package/docs/storybook/combobox-combobox-stories.e7427226.iframe.bundle.js +0 -1
  158. package/docs/storybook/dropdown-dropdown-stories.a76101be.iframe.bundle.js +0 -1
  159. package/docs/storybook/main.cdbf1814.iframe.bundle.js +0 -1
  160. package/docs/storybook/modal-modal-stories.0a864a6a.iframe.bundle.js +0 -1
  161. package/docs/storybook/radio-radio-stories.444fc044.iframe.bundle.js +0 -1
  162. package/docs/storybook/runtime~main.e32f2dfb.iframe.bundle.js +0 -1
  163. /package/docs/storybook/{7019.b8944046.iframe.bundle.js.LICENSE.txt → 7019.75ad5817.iframe.bundle.js.LICENSE.txt} +0 -0
@@ -1,10 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, Input, HostBinding, TemplateRef, Component, ViewChild, ContentChild, EventEmitter, Output, NgModule } from '@angular/core';
2
+ import { Directive, Self, Optional, Input, HostBinding, TemplateRef, Component, ViewChild, ContentChild, EventEmitter, Output, NgModule } from '@angular/core';
3
+ import * as i1 from '@angular/forms';
3
4
  import { FormsModule } from '@angular/forms';
4
- import * as i1 from '@angular/common';
5
+ import * as i1$1 from '@angular/common';
5
6
  import { CommonModule } from '@angular/common';
6
7
  import * as i2 from 'carbon-components-angular/icon';
7
8
  import { IconModule } from 'carbon-components-angular/icon';
9
+ import { startWith } from 'rxjs/operators';
8
10
  import { BaseIconButton, ButtonModule } from 'carbon-components-angular/button';
9
11
  import * as i3 from 'carbon-components-angular/tooltip';
10
12
  import { TooltipModule } from 'carbon-components-angular/tooltip';
@@ -21,7 +23,8 @@ import { TooltipModule } from 'carbon-components-angular/tooltip';
21
23
  * See the [vanilla carbon docs](http://www.carbondesignsystem.com/components/text-input/code) for more detail.
22
24
  */
23
25
  class TextInput {
24
- constructor() {
26
+ constructor(ngControl) {
27
+ this.ngControl = ngControl;
25
28
  /**
26
29
  * @deprecated since v5 - Use `cdsLayer` directive instead
27
30
  * `light` or `dark` input theme
@@ -65,14 +68,20 @@ class TextInput {
65
68
  return this.invalid ? true : undefined;
66
69
  }
67
70
  }
68
- TextInput.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
71
+ TextInput.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextInput, deps: [{ token: i1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
69
72
  TextInput.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: TextInput, selector: "[cdsText], [ibmText]", inputs: { theme: "theme", size: "size", invalid: "invalid", warn: "warn", skeleton: "skeleton" }, host: { properties: { "class.cds--text-input": "this.inputClass", "class.cds--text-input--sm": "this.isSizeSm", "class.cds--text-input--md": "this.isSizeMd", "class.cds--text-input--lg": "this.isSizelg", "class.cds--layout--size-sm": "this.sizeSm", "class.cds--layout--size-md": "this.sizeMd", "class.cds--layout--size-lg": "this.sizelg", "class.cds--text-input--invalid": "this.invalid", "class.cds--text-input--warning": "this.warn", "class.cds--skeleton": "this.skeleton", "class.cds--text-input--light": "this.isLightTheme", "attr.data-invalid": "this.getInvalidAttribute" } }, ngImport: i0 });
70
73
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextInput, decorators: [{
71
74
  type: Directive,
72
75
  args: [{
73
76
  selector: "[cdsText], [ibmText]"
74
77
  }]
75
- }], propDecorators: { theme: [{
78
+ }], ctorParameters: function () {
79
+ return [{ type: i1.NgControl, decorators: [{
80
+ type: Self
81
+ }, {
82
+ type: Optional
83
+ }] }];
84
+ }, propDecorators: { theme: [{
76
85
  type: Input
77
86
  }], size: [{
78
87
  type: Input
@@ -132,7 +141,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
132
141
  * See the [vanilla carbon docs](http://www.carbondesignsystem.com/components/text-input/code) for more detail.
133
142
  */
134
143
  class TextArea {
135
- constructor() {
144
+ constructor(ngControl) {
145
+ this.ngControl = ngControl;
136
146
  /**
137
147
  * @deprecated since v5 - Use `cdsLayer` directive instead
138
148
  * `light` or `dark` input theme
@@ -153,14 +163,20 @@ class TextArea {
153
163
  return this.invalid ? true : undefined;
154
164
  }
155
165
  }
156
- TextArea.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextArea, deps: [], target: i0.ɵɵFactoryTarget.Directive });
166
+ TextArea.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextArea, deps: [{ token: i1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Directive });
157
167
  TextArea.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: TextArea, selector: "[cdsTextArea], [ibmTextArea]", inputs: { theme: "theme", invalid: "invalid", warn: "warn", skeleton: "skeleton" }, host: { properties: { "class.cds--text-area": "this.baseClass", "class.cds--text-area--invalid": "this.invalid", "class.cds--text-area--warn": "this.warn", "class.cds--skeleton": "this.skeleton", "class.cds--text-area--light": "this.isLightTheme", "attr.data-invalid": "this.getInvalidAttr" } }, ngImport: i0 });
158
168
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextArea, decorators: [{
159
169
  type: Directive,
160
170
  args: [{
161
171
  selector: "[cdsTextArea], [ibmTextArea]"
162
172
  }]
163
- }], propDecorators: { theme: [{
173
+ }], ctorParameters: function () {
174
+ return [{ type: i1.NgControl, decorators: [{
175
+ type: Self
176
+ }, {
177
+ type: Optional
178
+ }] }];
179
+ }, propDecorators: { theme: [{
164
180
  type: Input
165
181
  }], baseClass: [{
166
182
  type: HostBinding,
@@ -371,12 +387,14 @@ class TextareaLabelComponent {
371
387
  * on each change. Excess words are trimmed from the end of the value.
372
388
  */
373
389
  this.counterMode = "character";
374
- // Tracks current character / word count for the counter display.
390
+ // Tracks current character / word count for the counter display.
375
391
  this.textCount = 0;
376
392
  this.labelClass = true;
377
393
  // Cached reference to the textarea element, set once in ngAfterViewInit.
378
394
  this._textareaElement = null;
379
- // Cached listener so it can be removed precisely (avoids anonymous-function leak)
395
+ // RxJS subscription used when NgControl is available (template-driven & reactive forms).
396
+ this._subscription = null;
397
+ // Fallback DOM listener used only when no NgControl is present (plain textarea).
380
398
  this._inputListener = null;
381
399
  }
382
400
  get isReadonly() {
@@ -424,7 +442,6 @@ class TextareaLabelComponent {
424
442
  }
425
443
  /**
426
444
  * Attach/remove listener and seed `textCount` from the textarea's current value.
427
- * @param changes
428
445
  */
429
446
  ngOnChanges(changes) {
430
447
  var _a, _b;
@@ -469,27 +486,49 @@ class TextareaLabelComponent {
469
486
  }
470
487
  }
471
488
  /**
472
- * Attaches the input event listener, ensuring it is never added twice.
489
+ * Attaches the counter listener, listen for either ngControl or native DOM input
490
+ * event listener
473
491
  */
474
492
  _attachCounterListener() {
493
+ var _a;
475
494
  this._detachCounterListener();
476
- if (!this._textareaElement) {
477
- return;
478
- }
479
- this._inputListener = (e) => {
480
- const el = e.target;
481
- // Word-mode enforcement: clamp value to maxCount words on each input so
482
- // the textarea never holds more words than allowed. Character mode relies
483
- // on the native `maxlength` attribute set by the developer.
484
- if (this.counterMode === "word" && this.maxCount != null) {
485
- const clamped = this._truncateToWordLimit(el.value || "", this.maxCount);
486
- if (clamped !== el.value) {
487
- el.value = clamped;
495
+ const control = (_a = this.textArea) === null || _a === void 0 ? void 0 : _a.ngControl;
496
+ if (control === null || control === void 0 ? void 0 : control.valueChanges) {
497
+ // NgControl listener
498
+ this._subscription = control.valueChanges
499
+ .pipe(startWith(control.value))
500
+ .subscribe((value) => {
501
+ var _a;
502
+ const raw = value || "";
503
+ if (this.counterMode === "word" && this.maxCount != null) {
504
+ const clamped = this._truncateToWordLimit(raw, this.maxCount);
505
+ if (clamped !== raw) {
506
+ // Write back through the control so the form model stays in sync.
507
+ // emitEvent false to avoid infinite loop
508
+ (_a = control === null || control === void 0 ? void 0 : control.control) === null || _a === void 0 ? void 0 : _a.setValue(clamped, { emitEvent: false });
509
+ }
488
510
  }
511
+ this.textCount = this._countValue(raw);
512
+ this.changeDetectorRef.markForCheck();
513
+ });
514
+ }
515
+ else {
516
+ // Fallback DOM path
517
+ if (!this._textareaElement) {
518
+ return;
489
519
  }
490
- this.textCount = this._countValue(el.value || "");
491
- };
492
- this._textareaElement.addEventListener("input", this._inputListener);
520
+ this._inputListener = (e) => {
521
+ const el = e.target;
522
+ if (this.counterMode === "word" && this.maxCount != null) {
523
+ const clamped = this._truncateToWordLimit(el.value || "", this.maxCount);
524
+ if (clamped !== el.value) {
525
+ el.value = clamped;
526
+ }
527
+ }
528
+ this.textCount = this._countValue(el.value || "");
529
+ };
530
+ this._textareaElement.addEventListener("input", this._inputListener);
531
+ }
493
532
  }
494
533
  /**
495
534
  * Truncates `value` so it contains at most `limit` Unicode words.
@@ -513,9 +552,13 @@ class TextareaLabelComponent {
513
552
  return wordsSeen < limit ? value : value.slice(0, cutIndex);
514
553
  }
515
554
  /**
516
- * Removes the input event listener and clears the cached reference.
555
+ * Removes the subscription (NgControl path) and removes the DOM listener
556
+ * (fallback path). Safe to call when neither is active.
517
557
  */
518
558
  _detachCounterListener() {
559
+ var _a;
560
+ (_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
561
+ this._subscription = null;
519
562
  if (this._inputListener && this._textareaElement) {
520
563
  this._textareaElement.removeEventListener("input", this._inputListener);
521
564
  this._inputListener = null;
@@ -632,7 +675,7 @@ TextareaLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0",
632
675
  </div>
633
676
  </ng-container>
634
677
  </ng-container>
635
- `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] });
678
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] });
636
679
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextareaLabelComponent, decorators: [{
637
680
  type: Component,
638
681
  args: [{
@@ -863,7 +906,9 @@ class TextInputLabelComponent {
863
906
  this.textInputWrapper = true;
864
907
  // Cached reference to the input element, set once in ngAfterViewInit.
865
908
  this._inputElement = null;
866
- // Cached listener so it can be removed precisely (avoids anonymous-function leak).
909
+ // RxJS subscription used when NgControl is available (template-driven & reactive forms).
910
+ this._subscription = null;
911
+ // Fallback cached DOM listener so it can be removed precisely (avoids anonymous-function leak).
867
912
  this._inputListener = null;
868
913
  }
869
914
  get isInlineWrapper() {
@@ -913,8 +958,7 @@ class TextInputLabelComponent {
913
958
  }
914
959
  }
915
960
  /**
916
- * Attach/remove listener and seed `textCount` from the textarea's current value.
917
- * @param changes
961
+ * Attach/remove listener and seed `textCount` from the input's current value.
918
962
  */
919
963
  ngOnChanges(changes) {
920
964
  var _a;
@@ -941,24 +985,43 @@ class TextInputLabelComponent {
941
985
  return value instanceof TemplateRef;
942
986
  }
943
987
  /**
944
- * Attaches the input event listener, ensuring it is never added twice.
988
+ * Attaches the counter listener, listen for either ngControl or native DOM input
989
+ * event listener
945
990
  */
946
991
  _attachCounterListener() {
992
+ var _a;
947
993
  this._detachCounterListener();
948
- if (!this._inputElement) {
949
- return;
994
+ const control = (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.ngControl;
995
+ if (control === null || control === void 0 ? void 0 : control.valueChanges) {
996
+ // NgControl listener
997
+ this._subscription = control.valueChanges
998
+ .pipe(startWith(control.value))
999
+ .subscribe((value) => {
1000
+ this.textCount = (value === null || value === void 0 ? void 0 : value.length) || 0;
1001
+ this.changeDetectorRef.markForCheck();
1002
+ });
1003
+ }
1004
+ else {
1005
+ // Fallback DOM path
1006
+ if (!this._inputElement) {
1007
+ return;
1008
+ }
1009
+ this._inputListener = (e) => {
1010
+ var _a;
1011
+ this.textCount = ((_a = e.target.value) === null || _a === void 0 ? void 0 : _a.length) || 0;
1012
+ this.changeDetectorRef.detectChanges();
1013
+ };
1014
+ this._inputElement.addEventListener("input", this._inputListener);
950
1015
  }
951
- this._inputListener = (e) => {
952
- var _a;
953
- this.textCount = ((_a = e.target.value) === null || _a === void 0 ? void 0 : _a.length) || 0;
954
- this.changeDetectorRef.detectChanges();
955
- };
956
- this._inputElement.addEventListener("input", this._inputListener);
957
1016
  }
958
1017
  /**
959
- * Removes the input event listener and clears the cached reference.
1018
+ * Removes the subscription (NgControl path) or removes the DOM listener.
1019
+ * Safe to call when neither is active.
960
1020
  */
961
1021
  _detachCounterListener() {
1022
+ var _a;
1023
+ (_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
1024
+ this._subscription = null;
962
1025
  if (this._inputListener && this._inputElement) {
963
1026
  this._inputElement.removeEventListener("input", this._inputListener);
964
1027
  this._inputListener = null;
@@ -970,7 +1033,7 @@ class TextInputLabelComponent {
970
1033
  */
971
1034
  TextInputLabelComponent.labelCounter = 0;
972
1035
  TextInputLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextInputLabelComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
973
- TextInputLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: { labelInputID: "labelInputID", disabled: "disabled", skeleton: "skeleton", labelTemplate: "labelTemplate", textInputTemplate: "textInputTemplate", helperText: "helperText", invalidText: "invalidText", invalid: "invalid", warn: "warn", warnText: "warnText", ariaLabel: "ariaLabel", fluid: "fluid", decorator: "decorator", hideLabel: "hideLabel", inline: "inline", size: "size", enableCounter: "enableCounter", maxCount: "maxCount" }, host: { properties: { "class.cds--text-input-wrapper--inline": "this.isInlineWrapper", "class.cds--text-input-wrapper--readonly": "this.isReadonly", "class.cds--text-input--fluid": "this.fluidClass", "class.cds--text-input--fluid__skeleton": "this.fluidSkeletonClass", "class.cds--form-item": "this.labelClass", "class.cds--text-input-wrapper": "this.textInputWrapper" } }, viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
1036
+ TextInputLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: { labelInputID: "labelInputID", disabled: "disabled", skeleton: "skeleton", labelTemplate: "labelTemplate", textInputTemplate: "textInputTemplate", helperText: "helperText", invalidText: "invalidText", invalid: "invalid", warn: "warn", warnText: "warnText", ariaLabel: "ariaLabel", fluid: "fluid", decorator: "decorator", hideLabel: "hideLabel", inline: "inline", size: "size", enableCounter: "enableCounter", maxCount: "maxCount" }, host: { properties: { "class.cds--text-input-wrapper--inline": "this.isInlineWrapper", "class.cds--text-input-wrapper--readonly": "this.isReadonly", "class.cds--text-input--fluid": "this.fluidClass", "class.cds--text-input--fluid__skeleton": "this.fluidSkeletonClass", "class.cds--form-item": "this.labelClass", "class.cds--text-input-wrapper": "this.textInputWrapper" } }, queries: [{ propertyName: "textInput", first: true, predicate: TextInput, descendants: true }], viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
974
1037
  <ng-container *ngIf="skeleton">
975
1038
  <span class="cds--label cds--skeleton"></span>
976
1039
  <div class="cds--text-input cds--skeleton"></div>
@@ -1094,7 +1157,7 @@ TextInputLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0"
1094
1157
  <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
1095
1158
  </div>
1096
1159
  </ng-template>
1097
- `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] });
1160
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] });
1098
1161
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TextInputLabelComponent, decorators: [{
1099
1162
  type: Component,
1100
1163
  args: [{
@@ -1276,6 +1339,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1276
1339
  }], wrapper: [{
1277
1340
  type: ViewChild,
1278
1341
  args: ["wrapper", { static: false }]
1342
+ }], textInput: [{
1343
+ type: ContentChild,
1344
+ args: [TextInput, { static: false }]
1279
1345
  }], labelClass: [{
1280
1346
  type: HostBinding,
1281
1347
  args: ["class.cds--form-item"]
@@ -1524,7 +1590,7 @@ PasswordInputLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.
1524
1590
  </div>
1525
1591
  </ng-container>
1526
1592
  </div>
1527
- `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: i3.Tooltip, selector: "cds-tooltip, ibm-tooltip", inputs: ["id", "enterDelayMs", "leaveDelayMs", "disabled", "description", "templateContext"] }] });
1593
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: i3.Tooltip, selector: "cds-tooltip, ibm-tooltip", inputs: ["id", "enterDelayMs", "leaveDelayMs", "disabled", "description", "templateContext"] }] });
1528
1594
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PasswordInputLabelComponent, decorators: [{
1529
1595
  type: Component,
1530
1596
  args: [{
@@ -1937,7 +2003,7 @@ Label.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0
1937
2003
  <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template>
1938
2004
  </div>
1939
2005
  </ng-template>
1940
- `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: TextareaLabelComponent, selector: "cds-textarea-label, ibm-textarea-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textAreaTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid", "hideLabel", "enableCounter", "maxCount", "counterMode", "decorator"] }, { kind: "component", type: TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid", "decorator", "hideLabel", "inline", "size", "enableCounter", "maxCount"] }, { kind: "component", type: PasswordInputLabelComponent, selector: "cds-password-label, ibm-password-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "passwordInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "hidePasswordLabel", "showPasswordLabel", "fluid", "hideLabel", "inline"], outputs: ["togglePasswordVisibility"] }] });
2006
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: TextareaLabelComponent, selector: "cds-textarea-label, ibm-textarea-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textAreaTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid", "hideLabel", "enableCounter", "maxCount", "counterMode", "decorator"] }, { kind: "component", type: TextInputLabelComponent, selector: "cds-text-label, ibm-text-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "textInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "fluid", "decorator", "hideLabel", "inline", "size", "enableCounter", "maxCount"] }, { kind: "component", type: PasswordInputLabelComponent, selector: "cds-password-label, ibm-password-label", inputs: ["labelInputID", "disabled", "skeleton", "labelTemplate", "passwordInputTemplate", "helperText", "invalidText", "invalid", "warn", "warnText", "ariaLabel", "hidePasswordLabel", "showPasswordLabel", "fluid", "hideLabel", "inline"], outputs: ["togglePasswordVisibility"] }] });
1941
2007
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Label, decorators: [{
1942
2008
  type: Component,
1943
2009
  args: [{