@koobiq/components 21.0.1 → 21.1.0

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 (180) hide show
  1. package/badge/_badge-theme.scss +31 -0
  2. package/breadcrumbs/breadcrumbs.scss +5 -1
  3. package/checkbox/_checkbox-theme.scss +0 -17
  4. package/checkbox/checkbox-tokens.scss +0 -4
  5. package/code-block/_code-block-theme.scss +7 -6
  6. package/code-block/code-block-tokens.scss +8 -4
  7. package/code-block/code-block.scss +54 -32
  8. package/content-panel/content-panel-header.scss +2 -3
  9. package/content-panel/content-panel.scss +3 -0
  10. package/core/selection/pseudo-checkbox/pseudo-checkbox-tokens.scss +0 -2
  11. package/fesm2022/koobiq-components-accordion.mjs +4 -4
  12. package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
  13. package/fesm2022/koobiq-components-actions-panel.mjs +10 -2
  14. package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
  15. package/fesm2022/koobiq-components-app-switcher.mjs +1 -1
  16. package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
  17. package/fesm2022/koobiq-components-badge.mjs +2 -2
  18. package/fesm2022/koobiq-components-badge.mjs.map +1 -1
  19. package/fesm2022/koobiq-components-breadcrumbs.mjs +2 -2
  20. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  21. package/fesm2022/koobiq-components-button-toggle.mjs +1 -1
  22. package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
  23. package/fesm2022/koobiq-components-checkbox.mjs +18 -8
  24. package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
  25. package/fesm2022/koobiq-components-clamped-text.mjs +78 -10
  26. package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
  27. package/fesm2022/koobiq-components-code-block.mjs +63 -379
  28. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  29. package/fesm2022/koobiq-components-content-panel.mjs +4 -4
  30. package/fesm2022/koobiq-components-content-panel.mjs.map +1 -1
  31. package/fesm2022/koobiq-components-core.mjs +300 -37
  32. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  33. package/fesm2022/koobiq-components-datepicker.mjs +151 -60
  34. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  35. package/fesm2022/koobiq-components-divider.mjs +3 -3
  36. package/fesm2022/koobiq-components-divider.mjs.map +1 -1
  37. package/fesm2022/koobiq-components-dropdown.mjs +3 -3
  38. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  39. package/fesm2022/koobiq-components-file-upload.mjs +17 -8
  40. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  41. package/fesm2022/koobiq-components-filter-bar.mjs +115 -36
  42. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  43. package/fesm2022/koobiq-components-flag.mjs +3 -3
  44. package/fesm2022/koobiq-components-flag.mjs.map +1 -1
  45. package/fesm2022/koobiq-components-form-field.mjs +90 -27
  46. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  47. package/fesm2022/koobiq-components-icon.mjs +2 -2
  48. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  49. package/fesm2022/koobiq-components-inline-edit.mjs +19 -2
  50. package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
  51. package/fesm2022/koobiq-components-input.mjs +76 -17
  52. package/fesm2022/koobiq-components-input.mjs.map +1 -1
  53. package/fesm2022/koobiq-components-list.mjs +1 -1
  54. package/fesm2022/koobiq-components-list.mjs.map +1 -1
  55. package/fesm2022/koobiq-components-modal.mjs +3 -3
  56. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  57. package/fesm2022/koobiq-components-navbar.mjs +86 -25
  58. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  59. package/fesm2022/koobiq-components-notification-center.mjs +4 -4
  60. package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
  61. package/fesm2022/koobiq-components-overflow-items.mjs +116 -38
  62. package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
  63. package/fesm2022/koobiq-components-popover.mjs +86 -7
  64. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  65. package/fesm2022/koobiq-components-radio.mjs +41 -19
  66. package/fesm2022/koobiq-components-radio.mjs.map +1 -1
  67. package/fesm2022/koobiq-components-search-expandable.mjs +29 -17
  68. package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
  69. package/fesm2022/koobiq-components-select.mjs +49 -12
  70. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  71. package/fesm2022/koobiq-components-sidepanel.mjs +198 -186
  72. package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
  73. package/fesm2022/koobiq-components-splitter.mjs +49 -25
  74. package/fesm2022/koobiq-components-splitter.mjs.map +1 -1
  75. package/fesm2022/koobiq-components-tabs.mjs +30 -11
  76. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  77. package/fesm2022/koobiq-components-tags.mjs +1 -1
  78. package/fesm2022/koobiq-components-tags.mjs.map +1 -1
  79. package/fesm2022/koobiq-components-textarea.mjs +28 -11
  80. package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
  81. package/fesm2022/koobiq-components-time-range.mjs +2 -2
  82. package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
  83. package/fesm2022/koobiq-components-timepicker.mjs +71 -16
  84. package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
  85. package/fesm2022/koobiq-components-timezone.mjs +2 -2
  86. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  87. package/fesm2022/koobiq-components-toast.mjs +2 -2
  88. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  89. package/fesm2022/koobiq-components-toggle.mjs +25 -9
  90. package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
  91. package/fesm2022/koobiq-components-tooltip.mjs +90 -17
  92. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  93. package/fesm2022/koobiq-components-top-bar.mjs +27 -7
  94. package/fesm2022/koobiq-components-top-bar.mjs.map +1 -1
  95. package/fesm2022/koobiq-components-tree-select.mjs +4 -4
  96. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  97. package/fesm2022/koobiq-components-tree.mjs +71 -27
  98. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  99. package/file-upload/_file-upload-theme.scss +0 -12
  100. package/file-upload/file-upload-tokens.scss +0 -1
  101. package/file-upload/file-upload.scss +0 -1
  102. package/filter-bar/_filter-bar-theme.scss +7 -8
  103. package/filter-bar/filter-bar.scss +0 -1
  104. package/filter-bar/pipes/base-pipe.scss +36 -2
  105. package/filter-bar/pipes/pipe-multi-tree-select.scss +27 -0
  106. package/form-field/_fieldset-theme.scss +2 -7
  107. package/form-field/_form-field-theme.scss +9 -22
  108. package/form-field/_hint-theme.scss +20 -0
  109. package/form-field/fieldset-tokens.scss +0 -1
  110. package/form-field/fieldset.scss +0 -3
  111. package/form-field/form-field-tokens.scss +1 -1
  112. package/form-field/form-field.scss +9 -0
  113. package/form-field/hint-tokens.scss +3 -0
  114. package/modal/modal.scss +2 -0
  115. package/navbar/_navbar-item_vertical.scss +48 -2
  116. package/navbar/_navbar-theme.scss +11 -3
  117. package/navbar/navbar-item.scss +17 -0
  118. package/navbar/navbar-tokens.scss +3 -0
  119. package/package.json +4 -4
  120. package/popover/popover.scss +1 -1
  121. package/radio/_radio-theme.scss +0 -30
  122. package/radio/radio-tokens.scss +0 -2
  123. package/schematics/migrations/deprecated-icons/README.md +21 -5
  124. package/schematics/migrations/deprecated-icons/index.cjs +8 -22
  125. package/schematics/migrations/deprecated-icons/schema.json +1 -1
  126. package/schematics/migrations/icons-replacement/README.md +16 -2
  127. package/schematics/migrations/icons-replacement/index.cjs +18 -16
  128. package/schematics/migrations/icons-replacement/schema.json +12 -3
  129. package/schematics/migrations/new-icons-pack/README.md +37 -25
  130. package/schematics/migrations/new-icons-pack/index.cjs +22 -32
  131. package/schematics/migrations/new-icons-pack/replacement.json +2 -14
  132. package/schematics/migrations/new-icons-pack/schema.json +3 -3
  133. package/schematics/ng-add/index.cjs +4 -4
  134. package/schematics/utils/custom-data.cjs +64 -0
  135. package/schematics/utils/icon-migration.cjs +9 -3
  136. package/schematics/utils/messages.cjs +4 -0
  137. package/schematics/utils/package-config.cjs +19 -0
  138. package/select/select.scss +7 -0
  139. package/tabs/_tabs-common.scss +23 -0
  140. package/textarea/textarea-tokens.scss +4 -1
  141. package/toast/toast.component.scss +1 -0
  142. package/toggle/_toggle-theme.scss +0 -17
  143. package/tooltip/tooltip.scss +1 -1
  144. package/top-bar/top-bar-tokens.scss +1 -0
  145. package/top-bar/top-bar.scss +10 -0
  146. package/types/koobiq-components-accordion.d.ts +25 -0
  147. package/types/koobiq-components-button-toggle.d.ts +6 -0
  148. package/types/koobiq-components-checkbox.d.ts +30 -0
  149. package/types/koobiq-components-clamped-text.d.ts +16 -3
  150. package/types/koobiq-components-code-block.d.ts +17 -3
  151. package/types/koobiq-components-core.d.ts +226 -13
  152. package/types/koobiq-components-datepicker.d.ts +28 -1
  153. package/types/koobiq-components-divider.d.ts +28 -10
  154. package/types/koobiq-components-dropdown.d.ts +19 -0
  155. package/types/koobiq-components-filter-bar.d.ts +77 -4
  156. package/types/koobiq-components-flag.d.ts +18 -0
  157. package/types/koobiq-components-form-field.d.ts +87 -6
  158. package/types/koobiq-components-icon.d.ts +15 -0
  159. package/types/koobiq-components-inline-edit.d.ts +8 -1
  160. package/types/koobiq-components-input.d.ts +22 -3
  161. package/types/koobiq-components-list.d.ts +6 -0
  162. package/types/koobiq-components-modal.d.ts +7 -0
  163. package/types/koobiq-components-navbar.d.ts +71 -7
  164. package/types/koobiq-components-notification-center.d.ts +13 -0
  165. package/types/koobiq-components-overflow-items.d.ts +26 -2
  166. package/types/koobiq-components-popover.d.ts +38 -3
  167. package/types/koobiq-components-radio.d.ts +30 -0
  168. package/types/koobiq-components-search-expandable.d.ts +10 -0
  169. package/types/koobiq-components-select.d.ts +36 -4
  170. package/types/koobiq-components-sidepanel.d.ts +52 -1
  171. package/types/koobiq-components-splitter.d.ts +13 -4
  172. package/types/koobiq-components-tabs.d.ts +4 -0
  173. package/types/koobiq-components-tags.d.ts +6 -0
  174. package/types/koobiq-components-textarea.d.ts +9 -2
  175. package/types/koobiq-components-timepicker.d.ts +15 -0
  176. package/types/koobiq-components-toggle.d.ts +30 -0
  177. package/types/koobiq-components-tooltip.d.ts +55 -10
  178. package/types/koobiq-components-top-bar.d.ts +11 -3
  179. package/types/koobiq-components-tree-select.d.ts +12 -0
  180. package/types/koobiq-components-tree.d.ts +37 -2
@@ -68,6 +68,11 @@ class KbqTextarea {
68
68
  * @docs-private
69
69
  */
70
70
  this.disabled = computed(() => this.formDisabled() ?? this.disabledInput(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
71
+ /**
72
+ * Whether the textarea is read-only: its value can be selected and copied, but not changed. A read-only
73
+ * textarea shows no placeholder. Defaults to `false`.
74
+ */
75
+ this.readonly = input(false, { ...(ngDevMode ? { debugName: "readonly" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
71
76
  /** @docs-private */
72
77
  this.idInput = input(undefined, { ...(ngDevMode ? { debugName: "idInput" } : /* istanbul ignore next */ {}), alias: 'id' });
73
78
  /**
@@ -123,8 +128,10 @@ class KbqTextarea {
123
128
  this.uid = inject(_IdGenerator).getId('kbq-textarea-');
124
129
  /** Measured once the textarea has been rendered; the growth arithmetic is in terms of these. */
125
130
  this.lineHeight = signal(0, ...(ngDevMode ? [{ debugName: "lineHeight" }] : /* istanbul ignore next */ []));
126
- this.minHeight = signal(0, ...(ngDevMode ? [{ debugName: "minHeight" }] : /* istanbul ignore next */ []));
131
+ this.verticalPadding = signal(0, ...(ngDevMode ? [{ debugName: "verticalPadding" }] : /* istanbul ignore next */ []));
127
132
  this.rowsCount = signal(0, ...(ngDevMode ? [{ debugName: "rowsCount" }] : /* istanbul ignore next */ []));
133
+ /** The `min-height` growth wrote last, so that turning growth off removes it and keeps a consumer's own. */
134
+ this.grownMinHeight = '';
128
135
  const inputValueAccessor = inject(KBQ_TEXTAREA_VALUE_ACCESSOR, { optional: true, self: true });
129
136
  // If no input value accessor was explicitly specified, use the element as the textarea value
130
137
  // accessor.
@@ -184,9 +191,8 @@ class KbqTextarea {
184
191
  return;
185
192
  Promise.resolve().then(() => {
186
193
  const styles = this.window.getComputedStyle(this.elementRef.nativeElement);
187
- const lineHeight = parseInt(styles.lineHeight, 10);
188
- this.lineHeight.set(lineHeight);
189
- this.minHeight.set(lineHeight + parseInt(styles.paddingTop, 10) + parseInt(styles.paddingBottom, 10));
194
+ this.lineHeight.set(parseInt(styles.lineHeight, 10));
195
+ this.verticalPadding.set(parseInt(styles.paddingTop, 10) + parseInt(styles.paddingBottom, 10));
190
196
  });
191
197
  setTimeout(() => this.grow(), 0);
192
198
  }
@@ -218,21 +224,31 @@ class KbqTextarea {
218
224
  */
219
225
  grow() {
220
226
  // Every call is deferred, so it can land once the textarea is destroyed and has no parent to measure in.
221
- if (!this.isBrowser || this.destroyRef.destroyed || !this.canGrow())
227
+ if (!this.isBrowser || this.destroyRef.destroyed)
222
228
  return;
229
+ const textarea = this.elementRef.nativeElement;
230
+ // A resizable textarea ignores maxRows and takes its floor from the stylesheet, not from the grown height.
231
+ if (!this.canGrow()) {
232
+ if (textarea.style.minHeight === this.grownMinHeight)
233
+ textarea.style.minHeight = '';
234
+ this.grownMinHeight = '';
235
+ this.rowsCount.set(0);
236
+ return;
237
+ }
223
238
  this.ngZone.runOutsideAngular(() => {
224
- const textarea = this.elementRef.nativeElement;
225
239
  const clone = textarea.cloneNode(false);
226
240
  this.renderer.appendChild(this.renderer.parentNode(textarea), clone);
227
241
  const outerHeight = parseInt(this.window.getComputedStyle(textarea).height, 10);
228
242
  const diff = outerHeight - +textarea.clientHeight;
229
243
  clone.style.minHeight = '0'; // this line is important to height recalculation
230
244
  const lineHeight = this.lineHeight();
231
- const height = Math.max(this.minHeight(), +clone.scrollHeight + diff + this.resolvedFreeRowsHeight());
245
+ const verticalPadding = this.verticalPadding();
246
+ const height = Math.max(lineHeight + verticalPadding, +clone.scrollHeight + diff + this.resolvedFreeRowsHeight());
232
247
  clone.remove();
233
248
  this.rowsCount.set(lineHeight > 0 ? Math.floor(height / lineHeight) : 0);
234
249
  const maxRows = this.maxRows();
235
- textarea.style.minHeight = coerceCssPixelValue(maxRows !== undefined && this.maxRowLimitReached() ? maxRows * lineHeight : height);
250
+ textarea.style.minHeight = coerceCssPixelValue(maxRows !== undefined && this.maxRowLimitReached() ? maxRows * lineHeight + verticalPadding : height);
251
+ this.grownMinHeight = textarea.style.minHeight;
236
252
  });
237
253
  }
238
254
  /** Focuses the textarea. */
@@ -283,7 +299,7 @@ class KbqTextarea {
283
299
  return !this.elementRef.nativeElement.value && !this.isBadInput();
284
300
  }
285
301
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTextarea, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
286
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: KbqTextarea, isStandalone: true, selector: "textarea[kbqTextarea]", inputs: { canGrow: { classPropertyName: "canGrow", publicName: "canGrow", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, placeholderInput: { classPropertyName: "placeholderInput", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, freeRowsHeight: { classPropertyName: "freeRowsHeight", publicName: "freeRowsHeight", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "blur": "onBlur()", "focus": "focusChanged(true)", "input": "dirtyCheckNativeValue()" }, properties: { "class.kbq-textarea-resizable": "!growing()", "class.kbq-textarea_max-row-limit-reached": "maxRowLimitReached()", "attr.id": "id()", "attr.placeholder": "placeholder()", "attr.aria-invalid": "errorState()", "disabled": "disabled()", "required": "required()" }, classAttribute: "kbq-textarea" }, providers: [{ provide: KbqFormFieldControl, useExisting: KbqTextarea }], exportAs: ["kbqTextarea"], hostDirectives: [{ directive: i1.KbqNativeScrollbar }], ngImport: i0 }); }
302
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: KbqTextarea, isStandalone: true, selector: "textarea[kbqTextarea]", inputs: { canGrow: { classPropertyName: "canGrow", publicName: "canGrow", isSignal: true, isRequired: false, transformFunction: null }, maxRows: { classPropertyName: "maxRows", publicName: "maxRows", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, placeholderInput: { classPropertyName: "placeholderInput", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, freeRowsHeight: { classPropertyName: "freeRowsHeight", publicName: "freeRowsHeight", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "blur": "onBlur()", "focus": "focusChanged(true)", "input": "dirtyCheckNativeValue()" }, properties: { "class.kbq-textarea-resizable": "!growing()", "class.kbq-textarea_max-row-limit-reached": "maxRowLimitReached()", "attr.id": "id()", "attr.placeholder": "readonly() ? null : placeholder()", "attr.aria-invalid": "errorState()", "disabled": "disabled()", "readonly": "readonly()", "required": "required()" }, classAttribute: "kbq-textarea" }, providers: [{ provide: KbqFormFieldControl, useExisting: KbqTextarea }], exportAs: ["kbqTextarea"], hostDirectives: [{ directive: i1.KbqNativeScrollbar }], ngImport: i0 }); }
287
303
  }
288
304
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTextarea, decorators: [{
289
305
  type: Directive,
@@ -295,9 +311,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
295
311
  '[class.kbq-textarea-resizable]': '!growing()',
296
312
  '[class.kbq-textarea_max-row-limit-reached]': 'maxRowLimitReached()',
297
313
  '[attr.id]': 'id()',
298
- '[attr.placeholder]': 'placeholder()',
314
+ '[attr.placeholder]': 'readonly() ? null : placeholder()',
299
315
  '[attr.aria-invalid]': 'errorState()',
300
316
  '[disabled]': 'disabled()',
317
+ '[readonly]': 'readonly()',
301
318
  '[required]': 'required()',
302
319
  '(blur)': 'onBlur()',
303
320
  '(focus)': 'focusChanged(true)',
@@ -306,7 +323,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
306
323
  hostDirectives: [KbqNativeScrollbar],
307
324
  exportAs: 'kbqTextarea'
308
325
  }]
309
- }], ctorParameters: () => [], propDecorators: { canGrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "canGrow", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], idInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], placeholderInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], freeRowsHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "freeRowsHeight", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
326
+ }], ctorParameters: () => [], propDecorators: { canGrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "canGrow", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], idInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], placeholderInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], freeRowsHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "freeRowsHeight", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
310
327
 
311
328
  class KbqTextareaModule {
312
329
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTextareaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
@@ -1 +1 @@
1
- {"version":3,"file":"koobiq-components-textarea.mjs","sources":["../../../packages/components/textarea/textarea.component.ts","../../../packages/components/textarea/textarea.module.ts","../../../packages/components/textarea/koobiq-components-textarea.ts"],"sourcesContent":["import { _IdGenerator } from '@angular/cdk/a11y';\nimport { coerceCssPixelValue } from '@angular/cdk/coercion';\nimport { Platform } from '@angular/cdk/platform';\nimport {\n booleanAttribute,\n computed,\n DestroyRef,\n Directive,\n DoCheck,\n effect,\n ElementRef,\n inject,\n InjectionToken,\n input,\n linkedSignal,\n NgZone,\n OnInit,\n Renderer2,\n signal,\n untracked,\n WritableSignal\n} from '@angular/core';\nimport { outputToObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormGroupDirective, NgControl, NgForm } from '@angular/forms';\nimport {\n CanUpdateErrorState,\n ErrorStateMatcher,\n KBQ_PARENT_ANIMATION_COMPONENT,\n KBQ_WINDOW,\n KbqErrorStateTracker,\n kbqInjectAutofilled,\n kbqOptionalNumberAttribute\n} from '@koobiq/components/core';\nimport { KbqFormFieldControl } from '@koobiq/components/form-field';\nimport { KbqNativeScrollbar } from '@koobiq/components/scrollbar';\nimport { asapScheduler } from 'rxjs';\n\nexport const KBQ_TEXTAREA_VALUE_ACCESSOR = new InjectionToken<{ value: any }>('KBQ_TEXTAREA_VALUE_ACCESSOR');\n\nconst isObject = (value: unknown): value is object => typeof value === 'object' && value !== null;\n\n@Directive({\n selector: 'textarea[kbqTextarea]',\n providers: [{ provide: KbqFormFieldControl, useExisting: KbqTextarea }],\n host: {\n class: 'kbq-textarea',\n '[class.kbq-textarea-resizable]': '!growing()',\n '[class.kbq-textarea_max-row-limit-reached]': 'maxRowLimitReached()',\n '[attr.id]': 'id()',\n '[attr.placeholder]': 'placeholder()',\n '[attr.aria-invalid]': 'errorState()',\n '[disabled]': 'disabled()',\n '[required]': 'required()',\n '(blur)': 'onBlur()',\n '(focus)': 'focusChanged(true)',\n '(input)': 'dirtyCheckNativeValue()'\n },\n hostDirectives: [KbqNativeScrollbar],\n exportAs: 'kbqTextarea'\n})\nexport class KbqTextarea implements KbqFormFieldControl<any>, OnInit, DoCheck, CanUpdateErrorState {\n protected elementRef = inject<ElementRef<HTMLTextAreaElement>>(ElementRef);\n readonly ngControl = inject(NgControl, { optional: true, self: true });\n readonly parentForm = inject(NgForm, { optional: true });\n readonly parentFormGroup = inject(FormGroupDirective, { optional: true });\n readonly defaultErrorStateMatcher = inject(ErrorStateMatcher);\n private readonly parent = inject(KBQ_PARENT_ANIMATION_COMPONENT, { optional: true, host: true });\n private readonly ngZone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly errorStateTracker = new KbqErrorStateTracker(\n this.defaultErrorStateMatcher,\n this.ngControl,\n this.parentFormGroup,\n this.parentForm\n );\n\n /** Whether the component is in an error state. */\n readonly errorState = this.errorStateTracker.errorState;\n\n /**\n * Parameter enables or disables the ability to automatically increase the height.\n * If set to false, the textarea becomes vertically resizable.\n */\n readonly canGrow = input(true, { transform: booleanAttribute });\n\n protected readonly isBrowser = inject(Platform).isBrowser;\n protected readonly renderer = inject(Renderer2);\n private readonly window = inject(KBQ_WINDOW);\n\n /** Maximum number of lines to which the textarea will grow. Unlimited when unset. */\n readonly maxRows = input<number | undefined, unknown>(undefined, { transform: kbqOptionalNumberAttribute });\n\n /** An object used to control when error messages are shown. */\n readonly errorStateMatcher = input<ErrorStateMatcher>();\n\n private readonly focusedValue = signal(false);\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly focused = this.focusedValue.asReadonly();\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly autofilled = kbqInjectAutofilled();\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n controlType: string = 'textarea';\n\n /** @docs-private */\n readonly disabledInput = input<boolean, boolean | string | null | undefined>(false, {\n alias: 'disabled',\n transform: booleanAttribute\n });\n\n /** `disabled` of the bound form control, which takes precedence over the input. */\n private readonly formDisabled = signal<boolean | null>(null);\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly disabled = computed(() => this.formDisabled() ?? this.disabledInput());\n\n /** @docs-private */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly id = computed(() => this.idInput() || this.uid);\n\n /** @docs-private */\n readonly placeholderInput = input<string | undefined>(undefined, { alias: 'placeholder' });\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly placeholder = linkedSignal(() => this.placeholderInput());\n\n /** Distance from the last line to the bottom border. Defaults to a single line height. */\n readonly freeRowsHeight = input<number | undefined, unknown>(undefined, { transform: kbqOptionalNumberAttribute });\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly required = input<boolean, boolean | string | null | undefined>(false, { transform: booleanAttribute });\n\n /** @docs-private */\n readonly valueInput = input<string | undefined>(undefined, { alias: 'value' });\n\n /**\n * Implemented as part of KbqFormFieldControl. Follows what the user types; a value bound with `[value]` or set\n * here is written to the element.\n *\n * @docs-private\n */\n readonly value: WritableSignal<string>;\n\n private readonly emptyValue = signal(true);\n\n /** The value the element and `value` last agreed on, and the text the element showed then. */\n private syncedValue: unknown;\n private syncedText: string;\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly empty = this.emptyValue.asReadonly();\n\n /**\n * Flag that will be set to true when the maximum number of lines is reached.\n * Maximum number of rows can be set using the maxRows input.\n */\n readonly maxRowLimitReached = computed(() => {\n const maxRows = this.maxRows();\n\n return maxRows !== undefined && this.rowsCount() > maxRows;\n });\n\n /**\n * Whether the textarea still grows with its content. It stops once `maxRows` is reached, and from\n * there the element keeps its own scrollbar: `kbq-textarea_max-row-limit-reached` sets\n * `resize: unset`, which follows `kbq-textarea-resizable` in the stylesheet and wins on source\n * order, so no native handle appears.\n *\n * @docs-private\n */\n protected readonly growing = computed(() => !this.maxRowLimitReached() && this.canGrow());\n\n /** Distance from the last line to the bottom border, falling back to the measured line height. */\n private readonly resolvedFreeRowsHeight = computed(() => this.freeRowsHeight() ?? this.lineHeight());\n\n protected readonly uid = inject(_IdGenerator).getId('kbq-textarea-');\n\n private valueAccessor: { value: any };\n\n /** Measured once the textarea has been rendered; the growth arithmetic is in terms of these. */\n private readonly lineHeight = signal(0);\n private readonly minHeight = signal(0);\n private readonly rowsCount = signal(0);\n\n constructor() {\n const inputValueAccessor = inject(KBQ_TEXTAREA_VALUE_ACCESSOR, { optional: true, self: true });\n\n // If no input value accessor was explicitly specified, use the element as the textarea value\n // accessor.\n this.valueAccessor = inputValueAccessor || this.elementRef.nativeElement;\n\n // Read once: a custom accessor may build a new value on every read.\n const initialValue = this.valueAccessor.value;\n\n this.value = signal(initialValue);\n this.syncedValue = initialValue;\n this.syncedText = this.elementRef.nativeElement.value;\n\n if (this.parent) {\n outputToObservable(this.parent.animationDone)\n .pipe(takeUntilDestroyed())\n // eslint-disable-next-line @angular-eslint/no-lifecycle-call\n .subscribe(() => this.ngOnInit());\n }\n\n // A bound value replaces the current one whenever the binding changes.\n effect(() => {\n const value = this.valueInput();\n\n if (value !== undefined) {\n untracked(() => this.value.set(value));\n }\n });\n\n // A value set in code is written to the element on the next change detection. The one the element last agreed\n // on is not written back: a custom accessor that builds a new value on every read would be written on every\n // keystroke.\n effect(() => {\n const value = this.value();\n\n untracked(() => {\n if (value !== this.syncedValue) {\n if (this.valueAccessor.value !== value) {\n this.valueAccessor.value = value;\n }\n\n this.syncedValue = value;\n this.syncedText = this.elementRef.nativeElement.value;\n }\n\n this.emptyValue.set(this.isEmpty());\n });\n });\n\n // The height follows the content and the inputs that size it, measured once the change is rendered.\n effect(() => {\n this.value();\n this.canGrow();\n this.maxRows();\n this.freeRowsHeight();\n\n untracked(() => asapScheduler.schedule(() => this.grow()));\n });\n\n // Browsers may not fire the blur event if the textarea is disabled too quickly.\n // Reset from here to ensure that the element doesn't become stuck.\n effect(() => {\n if (this.disabled()) {\n untracked(() => this.focusedValue.set(false));\n }\n });\n }\n\n ngOnInit() {\n if (!this.isBrowser) return;\n\n Promise.resolve().then(() => {\n const styles = this.window.getComputedStyle(this.elementRef.nativeElement);\n const lineHeight = parseInt(styles.lineHeight!, 10);\n\n this.lineHeight.set(lineHeight);\n this.minHeight.set(lineHeight + parseInt(styles.paddingTop!, 10) + parseInt(styles.paddingBottom!, 10));\n });\n\n setTimeout(() => this.grow(), 0);\n }\n\n ngDoCheck() {\n if (this.ngControl) {\n // We need to re-evaluate this on every change detection cycle, because there are some\n // error triggers that we can't subscribe to (e.g. parent form submissions). This means\n // that whatever logic is in here has to be super lean or we risk destroying the performance.\n this.updateErrorState();\n this.formDisabled.set(this.ngControl.disabled);\n }\n\n // We need to dirty-check the native element's value, because there are some cases where\n // we won't be notified when it changes (e.g. the consumer isn't using forms or they're\n // updating the value using `emitEvent: false`).\n this.dirtyCheckNativeValue();\n }\n\n updateErrorState() {\n this.errorStateTracker.errorStateMatcher = this.errorStateMatcher();\n this.errorStateTracker.updateErrorState();\n }\n\n /** @docs-private */\n onBlur(): void {\n this.focusChanged(false);\n }\n\n /**\n * Grow textarea height to avoid vertical scroll.\n *\n * @docs-private\n */\n protected grow(): void {\n // Every call is deferred, so it can land once the textarea is destroyed and has no parent to measure in.\n if (!this.isBrowser || this.destroyRef.destroyed || !this.canGrow()) return;\n\n this.ngZone.runOutsideAngular(() => {\n const textarea = this.elementRef.nativeElement;\n\n const clone = textarea.cloneNode(false) as HTMLTextAreaElement;\n\n this.renderer.appendChild(this.renderer.parentNode(textarea), clone);\n\n const outerHeight = parseInt(this.window.getComputedStyle(textarea).height!, 10);\n const diff = outerHeight - +textarea.clientHeight;\n\n clone.style.minHeight = '0'; // this line is important to height recalculation\n\n const lineHeight = this.lineHeight();\n const height = Math.max(this.minHeight(), +clone.scrollHeight + diff + this.resolvedFreeRowsHeight());\n\n clone.remove();\n\n this.rowsCount.set(lineHeight > 0 ? Math.floor(height / lineHeight) : 0);\n\n const maxRows = this.maxRows();\n\n textarea.style.minHeight = coerceCssPixelValue(\n maxRows !== undefined && this.maxRowLimitReached() ? maxRows * lineHeight : height\n );\n });\n }\n\n /** Focuses the textarea. */\n focus(): void {\n this.elementRef.nativeElement.focus();\n }\n\n /**\n * Callback for the cases where the focused state of the textarea changes.\n *\n * @docs-private\n */\n focusChanged(isFocused: boolean) {\n this.focusedValue.set(isFocused);\n }\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n onContainerClick() {\n this.focus();\n }\n\n /**\n * Reads the native value back, since it changes without notice: through the forms API, which writes the\n * element directly, or by the user typing into a textarea that no form listens to.\n *\n * @docs-private\n */\n dirtyCheckNativeValue() {\n const nativeValue = this.valueAccessor.value;\n const text = this.elementRef.nativeElement.value;\n\n // Only a change of the element itself: a value set in code and not yet written must not be overwritten. An\n // object counts as changed only with the text, as a custom accessor may build a new one on every read.\n if (nativeValue !== this.syncedValue && (!isObject(nativeValue) || text !== this.syncedText)) {\n this.syncedValue = nativeValue;\n this.syncedText = text;\n this.value.set(nativeValue);\n }\n\n this.emptyValue.set(this.isEmpty());\n }\n\n /** Checks whether the textarea is invalid based on the native validation. */\n protected isBadInput(): boolean {\n // The `validity` property won't be present on platform-server.\n const validity = (this.elementRef.nativeElement as HTMLTextAreaElement).validity;\n\n return validity && validity.badInput;\n }\n\n private isEmpty(): boolean {\n return !this.elementRef.nativeElement.value && !this.isBadInput();\n }\n}\n","import { A11yModule } from '@angular/cdk/a11y';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { KbqFormFieldModule } from '@koobiq/components/form-field';\nimport { KbqTextarea } from './textarea.component';\n\n@NgModule({\n imports: [A11yModule, FormsModule, KbqTextarea],\n exports: [KbqTextarea, KbqFormFieldModule]\n})\nexport class KbqTextareaModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;;;;MAqCa,2BAA2B,GAAG,IAAI,cAAc,CAAiB,6BAA6B;AAE3G,MAAM,QAAQ,GAAG,CAAC,KAAc,KAAsB,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;MAqBpF,WAAW,CAAA;AAiKpB,IAAA,WAAA,GAAA;AAhKU,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAkC,UAAU,CAAC;AACjE,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAC7D,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC/C,IAAA,CAAA,eAAe,GAAG,MAAM,CAAC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAChE,QAAA,IAAA,CAAA,wBAAwB,GAAG,MAAM,CAAC,iBAAiB,CAAC;AAC5C,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,8BAA8B,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC/E,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAE/B,IAAA,CAAA,iBAAiB,GAAG,IAAI,oBAAoB,CACzD,IAAI,CAAC,wBAAwB,EAC7B,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,UAAU,CAClB;;AAGQ,QAAA,IAAA,CAAA,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU;AAEvD;;;AAGG;QACM,IAAA,CAAA,OAAO,GAAG,KAAK,CAAC,IAAI,+EAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;AAE5C,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS;AACtC,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;AAC9B,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;;QAGnC,IAAA,CAAA,OAAO,GAAG,KAAK,CAA8B,SAAS,+EAAI,SAAS,EAAE,0BAA0B,EAAA,CAAG;;QAGlG,IAAA,CAAA,iBAAiB,GAAG,KAAK,CAAA,IAAA,SAAA,GAAA,CAAA,SAAA,EAAA,EAAA,SAAA,EAAA,mBAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAqB;AAEtC,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAC,KAAK,mFAAC;AAE7C;;;;AAIG;AACM,QAAA,IAAA,CAAA,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE;AAEjD;;;;AAIG;QACM,IAAA,CAAA,UAAU,GAAG,mBAAmB,EAAE;AAE3C;;;;AAIG;QACH,IAAA,CAAA,WAAW,GAAW,UAAU;;AAGvB,QAAA,IAAA,CAAA,aAAa,GAAG,KAAK,CAA+C,KAAK,EAAA,EAAA,IAAA,SAAA,GAAA,EAAA,SAAA,EAAA,eAAA,EAAA,8BAAA,EAAA,CAAA,EAC9E,KAAK,EAAE,UAAU;YACjB,SAAS,EAAE,gBAAgB,EAAA,CAC7B;;AAGe,QAAA,IAAA,CAAA,YAAY,GAAG,MAAM,CAAiB,IAAI,mFAAC;AAE5D;;;;AAIG;AACM,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,IAAI,IAAI,CAAC,aAAa,EAAE,+EAAC;;QAGtE,IAAA,CAAA,OAAO,GAAG,KAAK,CAAqB,SAAS,+EAAI,KAAK,EAAE,IAAI,EAAA,CAAG;AAExE;;;;AAIG;AACM,QAAA,IAAA,CAAA,EAAE,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,yEAAC;;QAG/C,IAAA,CAAA,gBAAgB,GAAG,KAAK,CAAqB,SAAS,wFAAI,KAAK,EAAE,aAAa,EAAA,CAAG;AAE1F;;;;AAIG;QACM,IAAA,CAAA,WAAW,GAAG,YAAY,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,aAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;;QAGzD,IAAA,CAAA,cAAc,GAAG,KAAK,CAA8B,SAAS,sFAAI,SAAS,EAAE,0BAA0B,EAAA,CAAG;AAElH;;;;AAIG;QACM,IAAA,CAAA,QAAQ,GAAG,KAAK,CAA+C,KAAK,gFAAI,SAAS,EAAE,gBAAgB,EAAA,CAAG;;QAGtG,IAAA,CAAA,UAAU,GAAG,KAAK,CAAqB,SAAS,kFAAI,KAAK,EAAE,OAAO,EAAA,CAAG;AAU7D,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,IAAI,iFAAC;AAM1C;;;;AAIG;AACM,QAAA,IAAA,CAAA,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE;AAE7C;;;AAGG;AACM,QAAA,IAAA,CAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAK;AACxC,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE;YAE9B,OAAO,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,GAAG,OAAO;AAC9D,QAAA,CAAC,yFAAC;AAEF;;;;;;;AAOG;AACgB,QAAA,IAAA,CAAA,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,8EAAC;;AAGxE,QAAA,IAAA,CAAA,sBAAsB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,6FAAC;QAEjF,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC;;AAKnD,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,CAAC,iFAAC;AACtB,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,CAAC,gFAAC;AACrB,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,CAAC,gFAAC;AAGlC,QAAA,MAAM,kBAAkB,GAAG,MAAM,CAAC,2BAA2B,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;;;QAI9F,IAAI,CAAC,aAAa,GAAG,kBAAkB,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa;;AAGxE,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK;AAE7C,QAAA,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,YAAY,4EAAC;AACjC,QAAA,IAAI,CAAC,WAAW,GAAG,YAAY;QAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK;AAErD,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACb,YAAA,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa;iBACvC,IAAI,CAAC,kBAAkB,EAAE;;iBAEzB,SAAS,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzC;;QAGA,MAAM,CAAC,MAAK;AACR,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE;AAE/B,YAAA,IAAI,KAAK,KAAK,SAAS,EAAE;AACrB,gBAAA,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1C;AACJ,QAAA,CAAC,CAAC;;;;QAKF,MAAM,CAAC,MAAK;AACR,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE;YAE1B,SAAS,CAAC,MAAK;AACX,gBAAA,IAAI,KAAK,KAAK,IAAI,CAAC,WAAW,EAAE;oBAC5B,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,KAAK,KAAK,EAAE;AACpC,wBAAA,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,KAAK;oBACpC;AAEA,oBAAA,IAAI,CAAC,WAAW,GAAG,KAAK;oBACxB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK;gBACzD;gBAEA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;AACvC,YAAA,CAAC,CAAC;AACN,QAAA,CAAC,CAAC;;QAGF,MAAM,CAAC,MAAK;YACR,IAAI,CAAC,KAAK,EAAE;YACZ,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,OAAO,EAAE;YACd,IAAI,CAAC,cAAc,EAAE;AAErB,YAAA,SAAS,CAAC,MAAM,aAAa,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAC9D,QAAA,CAAC,CAAC;;;QAIF,MAAM,CAAC,MAAK;AACR,YAAA,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE;AACjB,gBAAA,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACjD;AACJ,QAAA,CAAC,CAAC;IACN;IAEA,QAAQ,GAAA;QACJ,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE;AAErB,QAAA,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAK;AACxB,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;YAC1E,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAW,EAAE,EAAE,CAAC;AAEnD,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC;YAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAW,EAAE,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAc,EAAE,EAAE,CAAC,CAAC;AAC3G,QAAA,CAAC,CAAC;QAEF,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpC;IAEA,SAAS,GAAA;AACL,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;;;;YAIhB,IAAI,CAAC,gBAAgB,EAAE;YACvB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;QAClD;;;;QAKA,IAAI,CAAC,qBAAqB,EAAE;IAChC;IAEA,gBAAgB,GAAA;QACZ,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE;AACnE,QAAA,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,EAAE;IAC7C;;IAGA,MAAM,GAAA;AACF,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;IAC5B;AAEA;;;;AAIG;IACO,IAAI,GAAA;;AAEV,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE;AAErE,QAAA,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAK;AAC/B,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;YAE9C,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAwB;AAE9D,YAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;AAEpE,YAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,MAAO,EAAE,EAAE,CAAC;YAChF,MAAM,IAAI,GAAG,WAAW,GAAG,CAAC,QAAQ,CAAC,YAAY;YAEjD,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC;AAE5B,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAErG,KAAK,CAAC,MAAM,EAAE;YAEd,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;AAExE,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE;YAE9B,QAAQ,CAAC,KAAK,CAAC,SAAS,GAAG,mBAAmB,CAC1C,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,kBAAkB,EAAE,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CACrF;AACL,QAAA,CAAC,CAAC;IACN;;IAGA,KAAK,GAAA;AACD,QAAA,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,EAAE;IACzC;AAEA;;;;AAIG;AACH,IAAA,YAAY,CAAC,SAAkB,EAAA;AAC3B,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC;IACpC;AAEA;;;;AAIG;IACH,gBAAgB,GAAA;QACZ,IAAI,CAAC,KAAK,EAAE;IAChB;AAEA;;;;;AAKG;IACH,qBAAqB,GAAA;AACjB,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK;;;QAIhD,IAAI,WAAW,KAAK,IAAI,CAAC,WAAW,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,EAAE;AAC1F,YAAA,IAAI,CAAC,WAAW,GAAG,WAAW;AAC9B,YAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AACtB,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;QAC/B;QAEA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACvC;;IAGU,UAAU,GAAA;;QAEhB,MAAM,QAAQ,GAAI,IAAI,CAAC,UAAU,CAAC,aAAqC,CAAC,QAAQ;AAEhF,QAAA,OAAO,QAAQ,IAAI,QAAQ,CAAC,QAAQ;IACxC;IAEQ,OAAO,GAAA;AACX,QAAA,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;IACrE;kIAvWS,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;sHAAX,WAAW,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,UAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,MAAA,EAAA,UAAA,EAAA,OAAA,EAAA,oBAAA,EAAA,OAAA,EAAA,yBAAA,EAAA,EAAA,UAAA,EAAA,EAAA,8BAAA,EAAA,YAAA,EAAA,0CAAA,EAAA,sBAAA,EAAA,SAAA,EAAA,MAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,mBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,cAAA,EAAA,cAAA,EAAA,EAAA,SAAA,EAjBT,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,cAAA,EAAA,CAAA,EAAA,SAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;4FAiB9D,WAAW,EAAA,UAAA,EAAA,CAAA;kBAnBvB,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACP,oBAAA,QAAQ,EAAE,uBAAuB;oBACjC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAA,WAAa,EAAE,CAAC;AACvE,oBAAA,IAAI,EAAE;AACF,wBAAA,KAAK,EAAE,cAAc;AACrB,wBAAA,gCAAgC,EAAE,YAAY;AAC9C,wBAAA,4CAA4C,EAAE,sBAAsB;AACpE,wBAAA,WAAW,EAAE,MAAM;AACnB,wBAAA,oBAAoB,EAAE,eAAe;AACrC,wBAAA,qBAAqB,EAAE,cAAc;AACrC,wBAAA,YAAY,EAAE,YAAY;AAC1B,wBAAA,YAAY,EAAE,YAAY;AAC1B,wBAAA,QAAQ,EAAE,UAAU;AACpB,wBAAA,SAAS,EAAE,oBAAoB;AAC/B,wBAAA,SAAS,EAAE;AACd,qBAAA;oBACD,cAAc,EAAE,CAAC,kBAAkB,CAAC;AACpC,oBAAA,QAAQ,EAAE;AACb,iBAAA;;;MCjDY,iBAAiB,CAAA;kIAAjB,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;mIAAjB,iBAAiB,EAAA,OAAA,EAAA,CAHhB,UAAU,EAAE,WAAW,EAAE,WAAW,CAAA,EAAA,OAAA,EAAA,CACpC,WAAW,EAAE,kBAAkB,CAAA,EAAA,CAAA,CAAA;AAEhC,uBAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,EAAA,OAAA,EAAA,CAHhB,UAAU,EAAE,WAAW,EACV,kBAAkB,CAAA,EAAA,CAAA,CAAA;;4FAEhC,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAJ7B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACN,oBAAA,OAAO,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,WAAW,CAAC;AAC/C,oBAAA,OAAO,EAAE,CAAC,WAAW,EAAE,kBAAkB;AAC5C,iBAAA;;;ACTD;;AAEG;;;;"}
1
+ {"version":3,"file":"koobiq-components-textarea.mjs","sources":["../../../packages/components/textarea/textarea.component.ts","../../../packages/components/textarea/textarea.module.ts","../../../packages/components/textarea/koobiq-components-textarea.ts"],"sourcesContent":["import { _IdGenerator } from '@angular/cdk/a11y';\nimport { coerceCssPixelValue } from '@angular/cdk/coercion';\nimport { Platform } from '@angular/cdk/platform';\nimport {\n booleanAttribute,\n computed,\n DestroyRef,\n Directive,\n DoCheck,\n effect,\n ElementRef,\n inject,\n InjectionToken,\n input,\n linkedSignal,\n NgZone,\n OnInit,\n Renderer2,\n signal,\n untracked,\n WritableSignal\n} from '@angular/core';\nimport { outputToObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormGroupDirective, NgControl, NgForm } from '@angular/forms';\nimport {\n CanUpdateErrorState,\n ErrorStateMatcher,\n KBQ_PARENT_ANIMATION_COMPONENT,\n KBQ_WINDOW,\n KbqErrorStateTracker,\n kbqInjectAutofilled,\n kbqOptionalNumberAttribute\n} from '@koobiq/components/core';\nimport { KbqFormFieldControl } from '@koobiq/components/form-field';\nimport { KbqNativeScrollbar } from '@koobiq/components/scrollbar';\nimport { asapScheduler } from 'rxjs';\n\nexport const KBQ_TEXTAREA_VALUE_ACCESSOR = new InjectionToken<{ value: any }>('KBQ_TEXTAREA_VALUE_ACCESSOR');\n\nconst isObject = (value: unknown): value is object => typeof value === 'object' && value !== null;\n\n@Directive({\n selector: 'textarea[kbqTextarea]',\n providers: [{ provide: KbqFormFieldControl, useExisting: KbqTextarea }],\n host: {\n class: 'kbq-textarea',\n '[class.kbq-textarea-resizable]': '!growing()',\n '[class.kbq-textarea_max-row-limit-reached]': 'maxRowLimitReached()',\n '[attr.id]': 'id()',\n '[attr.placeholder]': 'readonly() ? null : placeholder()',\n '[attr.aria-invalid]': 'errorState()',\n '[disabled]': 'disabled()',\n '[readonly]': 'readonly()',\n '[required]': 'required()',\n '(blur)': 'onBlur()',\n '(focus)': 'focusChanged(true)',\n '(input)': 'dirtyCheckNativeValue()'\n },\n hostDirectives: [KbqNativeScrollbar],\n exportAs: 'kbqTextarea'\n})\nexport class KbqTextarea implements KbqFormFieldControl<any>, OnInit, DoCheck, CanUpdateErrorState {\n protected elementRef = inject<ElementRef<HTMLTextAreaElement>>(ElementRef);\n readonly ngControl = inject(NgControl, { optional: true, self: true });\n readonly parentForm = inject(NgForm, { optional: true });\n readonly parentFormGroup = inject(FormGroupDirective, { optional: true });\n readonly defaultErrorStateMatcher = inject(ErrorStateMatcher);\n private readonly parent = inject(KBQ_PARENT_ANIMATION_COMPONENT, { optional: true, host: true });\n private readonly ngZone = inject(NgZone);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly errorStateTracker = new KbqErrorStateTracker(\n this.defaultErrorStateMatcher,\n this.ngControl,\n this.parentFormGroup,\n this.parentForm\n );\n\n /** Whether the component is in an error state. */\n readonly errorState = this.errorStateTracker.errorState;\n\n /**\n * Parameter enables or disables the ability to automatically increase the height.\n * If set to false, the textarea becomes vertically resizable.\n */\n readonly canGrow = input(true, { transform: booleanAttribute });\n\n protected readonly isBrowser = inject(Platform).isBrowser;\n protected readonly renderer = inject(Renderer2);\n private readonly window = inject(KBQ_WINDOW);\n\n /** Maximum number of lines to which the textarea will grow. Unlimited when unset. */\n readonly maxRows = input<number | undefined, unknown>(undefined, { transform: kbqOptionalNumberAttribute });\n\n /** An object used to control when error messages are shown. */\n readonly errorStateMatcher = input<ErrorStateMatcher>();\n\n private readonly focusedValue = signal(false);\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly focused = this.focusedValue.asReadonly();\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly autofilled = kbqInjectAutofilled();\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n controlType: string = 'textarea';\n\n /** @docs-private */\n readonly disabledInput = input<boolean, boolean | string | null | undefined>(false, {\n alias: 'disabled',\n transform: booleanAttribute\n });\n\n /** `disabled` of the bound form control, which takes precedence over the input. */\n private readonly formDisabled = signal<boolean | null>(null);\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly disabled = computed(() => this.formDisabled() ?? this.disabledInput());\n\n /**\n * Whether the textarea is read-only: its value can be selected and copied, but not changed. A read-only\n * textarea shows no placeholder. Defaults to `false`.\n */\n readonly readonly = input<boolean, boolean | string | null | undefined>(false, { transform: booleanAttribute });\n\n /** @docs-private */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly id = computed(() => this.idInput() || this.uid);\n\n /** @docs-private */\n readonly placeholderInput = input<string | undefined>(undefined, { alias: 'placeholder' });\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly placeholder = linkedSignal(() => this.placeholderInput());\n\n /** Distance from the last line to the bottom border. Defaults to a single line height. */\n readonly freeRowsHeight = input<number | undefined, unknown>(undefined, { transform: kbqOptionalNumberAttribute });\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly required = input<boolean, boolean | string | null | undefined>(false, { transform: booleanAttribute });\n\n /** @docs-private */\n readonly valueInput = input<string | undefined>(undefined, { alias: 'value' });\n\n /**\n * Implemented as part of KbqFormFieldControl. Follows what the user types; a value bound with `[value]` or set\n * here is written to the element.\n *\n * @docs-private\n */\n readonly value: WritableSignal<string>;\n\n private readonly emptyValue = signal(true);\n\n /** The value the element and `value` last agreed on, and the text the element showed then. */\n private syncedValue: unknown;\n private syncedText: string;\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n readonly empty = this.emptyValue.asReadonly();\n\n /**\n * Flag that will be set to true when the maximum number of lines is reached.\n * Maximum number of rows can be set using the maxRows input.\n */\n readonly maxRowLimitReached = computed(() => {\n const maxRows = this.maxRows();\n\n return maxRows !== undefined && this.rowsCount() > maxRows;\n });\n\n /**\n * Whether the textarea still grows with its content. It stops once `maxRows` is reached, and from\n * there the element keeps its own scrollbar: `kbq-textarea_max-row-limit-reached` sets\n * `resize: unset`, which follows `kbq-textarea-resizable` in the stylesheet and wins on source\n * order, so no native handle appears.\n *\n * @docs-private\n */\n protected readonly growing = computed(() => !this.maxRowLimitReached() && this.canGrow());\n\n /** Distance from the last line to the bottom border, falling back to the measured line height. */\n private readonly resolvedFreeRowsHeight = computed(() => this.freeRowsHeight() ?? this.lineHeight());\n\n protected readonly uid = inject(_IdGenerator).getId('kbq-textarea-');\n\n private valueAccessor: { value: any };\n\n /** Measured once the textarea has been rendered; the growth arithmetic is in terms of these. */\n private readonly lineHeight = signal(0);\n private readonly verticalPadding = signal(0);\n private readonly rowsCount = signal(0);\n\n /** The `min-height` growth wrote last, so that turning growth off removes it and keeps a consumer's own. */\n private grownMinHeight = '';\n\n constructor() {\n const inputValueAccessor = inject(KBQ_TEXTAREA_VALUE_ACCESSOR, { optional: true, self: true });\n\n // If no input value accessor was explicitly specified, use the element as the textarea value\n // accessor.\n this.valueAccessor = inputValueAccessor || this.elementRef.nativeElement;\n\n // Read once: a custom accessor may build a new value on every read.\n const initialValue = this.valueAccessor.value;\n\n this.value = signal(initialValue);\n this.syncedValue = initialValue;\n this.syncedText = this.elementRef.nativeElement.value;\n\n if (this.parent) {\n outputToObservable(this.parent.animationDone)\n .pipe(takeUntilDestroyed())\n // eslint-disable-next-line @angular-eslint/no-lifecycle-call\n .subscribe(() => this.ngOnInit());\n }\n\n // A bound value replaces the current one whenever the binding changes.\n effect(() => {\n const value = this.valueInput();\n\n if (value !== undefined) {\n untracked(() => this.value.set(value));\n }\n });\n\n // A value set in code is written to the element on the next change detection. The one the element last agreed\n // on is not written back: a custom accessor that builds a new value on every read would be written on every\n // keystroke.\n effect(() => {\n const value = this.value();\n\n untracked(() => {\n if (value !== this.syncedValue) {\n if (this.valueAccessor.value !== value) {\n this.valueAccessor.value = value;\n }\n\n this.syncedValue = value;\n this.syncedText = this.elementRef.nativeElement.value;\n }\n\n this.emptyValue.set(this.isEmpty());\n });\n });\n\n // The height follows the content and the inputs that size it, measured once the change is rendered.\n effect(() => {\n this.value();\n this.canGrow();\n this.maxRows();\n this.freeRowsHeight();\n\n untracked(() => asapScheduler.schedule(() => this.grow()));\n });\n\n // Browsers may not fire the blur event if the textarea is disabled too quickly.\n // Reset from here to ensure that the element doesn't become stuck.\n effect(() => {\n if (this.disabled()) {\n untracked(() => this.focusedValue.set(false));\n }\n });\n }\n\n ngOnInit() {\n if (!this.isBrowser) return;\n\n Promise.resolve().then(() => {\n const styles = this.window.getComputedStyle(this.elementRef.nativeElement);\n\n this.lineHeight.set(parseInt(styles.lineHeight!, 10));\n this.verticalPadding.set(parseInt(styles.paddingTop!, 10) + parseInt(styles.paddingBottom!, 10));\n });\n\n setTimeout(() => this.grow(), 0);\n }\n\n ngDoCheck() {\n if (this.ngControl) {\n // We need to re-evaluate this on every change detection cycle, because there are some\n // error triggers that we can't subscribe to (e.g. parent form submissions). This means\n // that whatever logic is in here has to be super lean or we risk destroying the performance.\n this.updateErrorState();\n this.formDisabled.set(this.ngControl.disabled);\n }\n\n // We need to dirty-check the native element's value, because there are some cases where\n // we won't be notified when it changes (e.g. the consumer isn't using forms or they're\n // updating the value using `emitEvent: false`).\n this.dirtyCheckNativeValue();\n }\n\n updateErrorState() {\n this.errorStateTracker.errorStateMatcher = this.errorStateMatcher();\n this.errorStateTracker.updateErrorState();\n }\n\n /** @docs-private */\n onBlur(): void {\n this.focusChanged(false);\n }\n\n /**\n * Grow textarea height to avoid vertical scroll.\n *\n * @docs-private\n */\n protected grow(): void {\n // Every call is deferred, so it can land once the textarea is destroyed and has no parent to measure in.\n if (!this.isBrowser || this.destroyRef.destroyed) return;\n\n const textarea = this.elementRef.nativeElement;\n\n // A resizable textarea ignores maxRows and takes its floor from the stylesheet, not from the grown height.\n if (!this.canGrow()) {\n if (textarea.style.minHeight === this.grownMinHeight) textarea.style.minHeight = '';\n\n this.grownMinHeight = '';\n this.rowsCount.set(0);\n\n return;\n }\n\n this.ngZone.runOutsideAngular(() => {\n const clone = textarea.cloneNode(false) as HTMLTextAreaElement;\n\n this.renderer.appendChild(this.renderer.parentNode(textarea), clone);\n\n const outerHeight = parseInt(this.window.getComputedStyle(textarea).height!, 10);\n const diff = outerHeight - +textarea.clientHeight;\n\n clone.style.minHeight = '0'; // this line is important to height recalculation\n\n const lineHeight = this.lineHeight();\n const verticalPadding = this.verticalPadding();\n const height = Math.max(\n lineHeight + verticalPadding,\n +clone.scrollHeight + diff + this.resolvedFreeRowsHeight()\n );\n\n clone.remove();\n\n this.rowsCount.set(lineHeight > 0 ? Math.floor(height / lineHeight) : 0);\n\n const maxRows = this.maxRows();\n\n textarea.style.minHeight = coerceCssPixelValue(\n maxRows !== undefined && this.maxRowLimitReached() ? maxRows * lineHeight + verticalPadding : height\n );\n this.grownMinHeight = textarea.style.minHeight;\n });\n }\n\n /** Focuses the textarea. */\n focus(): void {\n this.elementRef.nativeElement.focus();\n }\n\n /**\n * Callback for the cases where the focused state of the textarea changes.\n *\n * @docs-private\n */\n focusChanged(isFocused: boolean) {\n this.focusedValue.set(isFocused);\n }\n\n /**\n * Implemented as part of KbqFormFieldControl.\n *\n * @docs-private\n */\n onContainerClick() {\n this.focus();\n }\n\n /**\n * Reads the native value back, since it changes without notice: through the forms API, which writes the\n * element directly, or by the user typing into a textarea that no form listens to.\n *\n * @docs-private\n */\n dirtyCheckNativeValue() {\n const nativeValue = this.valueAccessor.value;\n const text = this.elementRef.nativeElement.value;\n\n // Only a change of the element itself: a value set in code and not yet written must not be overwritten. An\n // object counts as changed only with the text, as a custom accessor may build a new one on every read.\n if (nativeValue !== this.syncedValue && (!isObject(nativeValue) || text !== this.syncedText)) {\n this.syncedValue = nativeValue;\n this.syncedText = text;\n this.value.set(nativeValue);\n }\n\n this.emptyValue.set(this.isEmpty());\n }\n\n /** Checks whether the textarea is invalid based on the native validation. */\n protected isBadInput(): boolean {\n // The `validity` property won't be present on platform-server.\n const validity = (this.elementRef.nativeElement as HTMLTextAreaElement).validity;\n\n return validity && validity.badInput;\n }\n\n private isEmpty(): boolean {\n return !this.elementRef.nativeElement.value && !this.isBadInput();\n }\n}\n","import { A11yModule } from '@angular/cdk/a11y';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { KbqFormFieldModule } from '@koobiq/components/form-field';\nimport { KbqTextarea } from './textarea.component';\n\n@NgModule({\n imports: [A11yModule, FormsModule, KbqTextarea],\n exports: [KbqTextarea, KbqFormFieldModule]\n})\nexport class KbqTextareaModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -703,7 +703,7 @@ class KbqTimeRangeEditor {
703
703
  provide: NG_VALIDATORS,
704
704
  useExisting: KbqTimeRangeEditor
705
705
  }
706
- ], ngImport: i0, template: "<form [formGroup]=\"form\">\n @let localeConfig = localeConfiguration();\n @let types = timeRangeTypesWithoutRange();\n @let bounds = boundsHint();\n\n <!-- The radiogroup holds only radios: the from/to block is its sibling rather than its child, so the\n text fields and the calendar button are not announced as part of the group. -->\n <div class=\"kbq-time-range-editor__container\">\n @if (types.length) {\n <kbq-radio-group [formControl]=\"form.controls.type\">\n <div class=\"kbq-time-range-editor__predefined\">\n @for (type of types; track type) {\n <kbq-radio-button class=\"kbq-time-range-editor__predefined-option\" [value]=\"type.type\">\n <ng-container\n *ngTemplateOutlet=\"\n optionTemplate() || defaultOptionTemplate;\n context: { $implicit: type }\n \"\n />\n </kbq-radio-button>\n }\n </div>\n\n @if (isRangeVisible()) {\n <kbq-radio-button class=\"kbq-time-range-editor__range-option\" [value]=\"'range'\">\n {{ localeConfig.editor.rangeLabel }}\n @if (bounds) {\n <kbq-hint>{{ bounds }}</kbq-hint>\n }\n </kbq-radio-button>\n }\n </kbq-radio-group>\n }\n\n @if (isRangeVisible()) {\n <div\n class=\"kbq-time-range-editor__range\"\n role=\"group\"\n [attr.aria-label]=\"localeConfig.editor.rangeLabel\"\n (focusout)=\"onRangeFocusOut($event)\"\n >\n <div\n class=\"kbq-time-range-editor__date-time\"\n (input)=\"onBorderInput('from')\"\n (focusout)=\"onBorderFocusOut('from', $event)\"\n >\n <span class=\"kbq-time-range-editor__date-time-prefix\" [id]=\"fromLabelId\">\n {{ localeConfig.editor.from }}\n </span>\n <kbq-fieldset>\n <kbq-form-field kbqFieldsetItem>\n <i kbq-icon=\"kbq-clock_16\" kbqPrefix [autoColor]=\"true\"></i>\n <input\n kbqTimepicker\n data-time-range-field=\"fromTime\"\n [attr.aria-labelledby]=\"fromLabelId\"\n [format]=\"timepickerFormat\"\n [formControl]=\"form.controls.fromTime\"\n [errorStateMatcher]=\"rangeStateMatcher\"\n />\n </kbq-form-field>\n\n <kbq-form-field>\n <input\n data-time-range-field=\"fromDate\"\n [attr.aria-labelledby]=\"fromLabelId\"\n [kbqDatepicker]=\"datepickerFrom\"\n [formControl]=\"form.controls.fromDate\"\n [errorStateMatcher]=\"rangeStateMatcher\"\n />\n <kbq-datepicker-toggle-icon kbqSuffix [for]=\"datepickerFrom\" />\n <kbq-datepicker #datepickerFrom [minDate]=\"minDate()\" [maxDate]=\"maxDate()\" />\n </kbq-form-field>\n </kbq-fieldset>\n </div>\n\n <div\n class=\"kbq-time-range-editor__date-time\"\n (input)=\"onBorderInput('to')\"\n (focusout)=\"onBorderFocusOut('to', $event)\"\n >\n <span class=\"kbq-time-range-editor__date-time-prefix\" [id]=\"toLabelId\">\n {{ localeConfig.editor.to }}\n </span>\n <kbq-fieldset>\n <kbq-form-field kbqFieldsetItem>\n <i kbq-icon=\"kbq-clock_16\" kbqPrefix [autoColor]=\"true\"></i>\n <input\n kbqTimepicker\n data-time-range-field=\"toTime\"\n [attr.aria-labelledby]=\"toLabelId\"\n [format]=\"timepickerFormat\"\n [formControl]=\"form.controls.toTime\"\n [errorStateMatcher]=\"rangeStateMatcher\"\n />\n </kbq-form-field>\n\n <kbq-form-field>\n <input\n data-time-range-field=\"toDate\"\n [attr.aria-labelledby]=\"toLabelId\"\n [kbqDatepicker]=\"datepickerTo\"\n [formControl]=\"form.controls.toDate\"\n [errorStateMatcher]=\"rangeStateMatcher\"\n />\n <kbq-datepicker-toggle-icon kbqSuffix [for]=\"datepickerTo\" />\n <kbq-datepicker #datepickerTo [minDate]=\"minDate()\" [maxDate]=\"maxDate()\" />\n </kbq-form-field>\n\n <!-- The range is judged as a whole, so what is wrong with it is said once, below the\n last of its two ends - in place of the caption, which spells the same bounds out. -->\n @if (outOfBoundsMessage(); as message) {\n <kbq-error>{{ message }}</kbq-error>\n } @else if (!types.length && bounds) {\n <!-- With no presets there is no option to hang the bounds off, so they go in the\n fieldset's own hint area rather than loose in the block. -->\n <kbq-hint>{{ bounds }}</kbq-hint>\n }\n </kbq-fieldset>\n </div>\n </div>\n }\n </div>\n</form>\n\n<ng-template #defaultOptionTemplate let-context>\n @let localeConfig = localeConfiguration();\n @switch (context.translationType) {\n @case ('other') {\n @switch (context.type) {\n @case ('allTime') {\n {{ localeConfig.editor.allTimeOption ?? localeConfig.editor.allTime }}\n }\n @case ('currentQuarter') {\n {{ localeConfig.editor.currentQuarterOption ?? localeConfig.editor.currentQuarter }}\n }\n @case ('currentYear') {\n {{ localeConfig.editor.currentYearOption ?? localeConfig.editor.currentYear }}\n }\n }\n }\n @default {\n {{ context.formattedValue }}\n }\n }\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: KbqError, selector: "kbq-error", exportAs: ["kbqError"] }, { kind: "component", type: KbqFieldset, selector: "kbq-fieldset", exportAs: ["kbqFieldset"] }, { kind: "directive", type: KbqFieldsetItem, selector: "[kbqFieldsetItem]", exportAs: ["kbqFieldsetItem"] }, { kind: "component", type: KbqHint, selector: "kbq-hint", inputs: ["id", "fillTextOff", "compact"], exportAs: ["kbqHint"] }, { kind: "ngmodule", type: KbqDatepickerModule }, { kind: "component", type: i2.KbqDatepicker, selector: "kbq-datepicker", inputs: ["hasBackdrop", "startAt", "disabled", "opened", "minDate", "maxDate", "panelClass", "dateClass", "backdropClass"], outputs: ["yearSelected", "monthSelected", "opened", "closed"], exportAs: ["kbqDatepicker"] }, { kind: "directive", type: i2.KbqDatepickerInput, selector: "input[kbqDatepicker], input[kbqCalendar]", inputs: ["errorStateMatcher", "placeholder", "required", "kbqDatepicker", "kbqCalendar", "kbqDatepickerFilter", "value", "min", "max", "disabled", "id", "kbqValidationTooltip"], outputs: ["incorrectInput", "dateChange", "dateInput"], exportAs: ["kbqDatepickerInput"] }, { kind: "component", type: i2.KbqDatepickerToggleIconComponent, selector: "kbq-datepicker-toggle-icon", inputs: ["disabled", "for"] }, { kind: "component", type: i3.KbqFormField, selector: "kbq-form-field", inputs: ["noBorders", "inOverlay", "horizontal", "labelClass", "contentClass"], outputs: ["inOverlayChange"], exportAs: ["kbqFormField"] }, { kind: "directive", type: i3.KbqPrefix, selector: "[kbqPrefix]", exportAs: ["kbqPrefix"] }, { kind: "directive", type: i3.KbqSuffix, selector: "[kbqSuffix]", exportAs: ["kbqSuffix"] }, { kind: "ngmodule", type: KbqTimepickerModule }, { kind: "directive", type: i4.KbqTimepicker, selector: "input[kbqTimepicker]", inputs: ["errorStateMatcher", "placeholder", "disabled", "id", "required", "format", "min", "max", "value", "kbqValidationTooltip"], outputs: ["incorrectInput"], exportAs: ["kbqTimepicker"] }, { kind: "ngmodule", type: KbqRadioModule }, { kind: "component", type: i5.KbqRadioGroup, selector: "kbq-radio-group", inputs: ["errorStateMatcher", "big", "name", "labelPosition", "value", "selected", "disabled", "required"], outputs: ["change"], exportAs: ["kbqRadioGroup"] }, { kind: "component", type: i5.KbqRadioButton, selector: "kbq-radio-button", inputs: ["id", "value", "checked", "disabled", "tabIndex", "required", "labelPosition", "name"], outputs: ["change"], exportAs: ["kbqRadioButton"] }, { kind: "component", type: KbqIcon, selector: "[kbq-icon]", inputs: ["aria-hidden", "iconSize", "autoColor", "kbq-icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
706
+ ], ngImport: i0, template: "<form [formGroup]=\"form\">\n @let localeConfig = localeConfiguration();\n @let types = timeRangeTypesWithoutRange();\n @let bounds = boundsHint();\n\n <!-- The radiogroup holds only radios: the from/to block is its sibling rather than its child, so the\n text fields and the calendar button are not announced as part of the group. -->\n <div class=\"kbq-time-range-editor__container\">\n @if (types.length) {\n <kbq-radio-group [formControl]=\"form.controls.type\">\n <div class=\"kbq-time-range-editor__predefined\">\n @for (type of types; track type) {\n <kbq-radio-button class=\"kbq-time-range-editor__predefined-option\" [value]=\"type.type\">\n <ng-container\n *ngTemplateOutlet=\"\n optionTemplate() || defaultOptionTemplate;\n context: { $implicit: type }\n \"\n />\n </kbq-radio-button>\n }\n </div>\n\n @if (isRangeVisible()) {\n <kbq-radio-button class=\"kbq-time-range-editor__range-option\" [value]=\"'range'\">\n {{ localeConfig.editor.rangeLabel }}\n @if (bounds) {\n <kbq-hint>{{ bounds }}</kbq-hint>\n }\n </kbq-radio-button>\n }\n </kbq-radio-group>\n }\n\n @if (isRangeVisible()) {\n <div\n class=\"kbq-time-range-editor__range\"\n role=\"group\"\n [attr.aria-label]=\"localeConfig.editor.rangeLabel\"\n (focusout)=\"onRangeFocusOut($event)\"\n >\n <div\n class=\"kbq-time-range-editor__date-time\"\n (input)=\"onBorderInput('from')\"\n (focusout)=\"onBorderFocusOut('from', $event)\"\n >\n <span class=\"kbq-time-range-editor__date-time-prefix\" [id]=\"fromLabelId\">\n {{ localeConfig.editor.from }}\n </span>\n <kbq-fieldset>\n <kbq-form-field kbqFieldsetItem>\n <i kbq-icon=\"kbq-clock_16\" kbqPrefix [autoColor]=\"true\"></i>\n <input\n kbqTimepicker\n data-time-range-field=\"fromTime\"\n [attr.aria-labelledby]=\"fromLabelId\"\n [format]=\"timepickerFormat\"\n [formControl]=\"form.controls.fromTime\"\n [errorStateMatcher]=\"rangeStateMatcher\"\n />\n </kbq-form-field>\n\n <kbq-form-field>\n <input\n data-time-range-field=\"fromDate\"\n [attr.aria-labelledby]=\"fromLabelId\"\n [kbqDatepicker]=\"datepickerFrom\"\n [formControl]=\"form.controls.fromDate\"\n [errorStateMatcher]=\"rangeStateMatcher\"\n />\n <kbq-datepicker-toggle-icon kbqSuffix [for]=\"datepickerFrom\" />\n <kbq-datepicker #datepickerFrom [minDate]=\"minDate()\" [maxDate]=\"maxDate()\" />\n </kbq-form-field>\n </kbq-fieldset>\n </div>\n\n <div\n class=\"kbq-time-range-editor__date-time\"\n (input)=\"onBorderInput('to')\"\n (focusout)=\"onBorderFocusOut('to', $event)\"\n >\n <span class=\"kbq-time-range-editor__date-time-prefix\" [id]=\"toLabelId\">\n {{ localeConfig.editor.to }}\n </span>\n <kbq-fieldset>\n <kbq-form-field kbqFieldsetItem>\n <i kbq-icon=\"kbq-clock_16\" kbqPrefix [autoColor]=\"true\"></i>\n <input\n kbqTimepicker\n data-time-range-field=\"toTime\"\n [attr.aria-labelledby]=\"toLabelId\"\n [format]=\"timepickerFormat\"\n [formControl]=\"form.controls.toTime\"\n [errorStateMatcher]=\"rangeStateMatcher\"\n />\n </kbq-form-field>\n\n <kbq-form-field>\n <input\n data-time-range-field=\"toDate\"\n [attr.aria-labelledby]=\"toLabelId\"\n [kbqDatepicker]=\"datepickerTo\"\n [formControl]=\"form.controls.toDate\"\n [errorStateMatcher]=\"rangeStateMatcher\"\n />\n <kbq-datepicker-toggle-icon kbqSuffix [for]=\"datepickerTo\" />\n <kbq-datepicker #datepickerTo [minDate]=\"minDate()\" [maxDate]=\"maxDate()\" />\n </kbq-form-field>\n\n <!-- The range is judged as a whole, so what is wrong with it is said once, below the\n last of its two ends - in place of the caption, which spells the same bounds out. -->\n @if (outOfBoundsMessage(); as message) {\n <kbq-error>{{ message }}</kbq-error>\n } @else if (!types.length && bounds) {\n <!-- With no presets there is no option to hang the bounds off, so they go in the\n fieldset's own hint area rather than loose in the block. -->\n <kbq-hint>{{ bounds }}</kbq-hint>\n }\n </kbq-fieldset>\n </div>\n </div>\n }\n </div>\n</form>\n\n<ng-template #defaultOptionTemplate let-context>\n @let localeConfig = localeConfiguration();\n @switch (context.translationType) {\n @case ('other') {\n @switch (context.type) {\n @case ('allTime') {\n {{ localeConfig.editor.allTimeOption ?? localeConfig.editor.allTime }}\n }\n @case ('currentQuarter') {\n {{ localeConfig.editor.currentQuarterOption ?? localeConfig.editor.currentQuarter }}\n }\n @case ('currentYear') {\n {{ localeConfig.editor.currentYearOption ?? localeConfig.editor.currentYear }}\n }\n }\n }\n @default {\n {{ context.formattedValue }}\n }\n }\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: KbqError, selector: "kbq-error", exportAs: ["kbqError"] }, { kind: "component", type: KbqFieldset, selector: "kbq-fieldset", exportAs: ["kbqFieldset"] }, { kind: "directive", type: KbqFieldsetItem, selector: "[kbqFieldsetItem]", exportAs: ["kbqFieldsetItem"] }, { kind: "component", type: KbqHint, selector: "kbq-hint", inputs: ["id", "fillTextOff", "compact"], exportAs: ["kbqHint"] }, { kind: "ngmodule", type: KbqDatepickerModule }, { kind: "component", type: i2.KbqDatepicker, selector: "kbq-datepicker", inputs: ["hasBackdrop", "startAt", "disabled", "opened", "minDate", "maxDate", "panelClass", "dateClass", "backdropClass"], outputs: ["yearSelected", "monthSelected", "opened", "closed"], exportAs: ["kbqDatepicker"] }, { kind: "directive", type: i2.KbqDatepickerInput, selector: "input[kbqDatepicker], input[kbqCalendar]", inputs: ["errorStateMatcher", "placeholder", "required", "kbqDatepicker", "kbqCalendar", "kbqDatepickerFilter", "value", "min", "max", "disabled", "id", "kbqValidationTooltip"], outputs: ["incorrectInput", "dateChange", "dateInput"], exportAs: ["kbqDatepickerInput"] }, { kind: "component", type: i2.KbqDatepickerToggleIconComponent, selector: "kbq-datepicker-toggle-icon", inputs: ["disabled", "for"] }, { kind: "component", type: i3.KbqFormField, selector: "kbq-form-field", inputs: ["noBorders", "inOverlay", "horizontal", "labelClass", "contentClass", "showRequiredMarker"], outputs: ["inOverlayChange"], exportAs: ["kbqFormField"] }, { kind: "directive", type: i3.KbqPrefix, selector: "[kbqPrefix]", exportAs: ["kbqPrefix"] }, { kind: "directive", type: i3.KbqSuffix, selector: "[kbqSuffix]", exportAs: ["kbqSuffix"] }, { kind: "ngmodule", type: KbqTimepickerModule }, { kind: "directive", type: i4.KbqTimepicker, selector: "input[kbqTimepicker]", inputs: ["errorStateMatcher", "placeholder", "disabled", "id", "required", "format", "min", "max", "value", "kbqValidationTooltip"], outputs: ["incorrectInput"], exportAs: ["kbqTimepicker"] }, { kind: "ngmodule", type: KbqRadioModule }, { kind: "component", type: i5.KbqRadioGroup, selector: "kbq-radio-group", inputs: ["errorStateMatcher", "big", "name", "labelPosition", "value", "selected", "disabled", "required"], outputs: ["change"], exportAs: ["kbqRadioGroup"] }, { kind: "component", type: i5.KbqRadioButton, selector: "kbq-radio-button", inputs: ["id", "value", "checked", "disabled", "tabIndex", "required", "labelPosition", "name"], outputs: ["change"], exportAs: ["kbqRadioButton"] }, { kind: "component", type: KbqIcon, selector: "[kbq-icon]", inputs: ["aria-hidden", "iconSize", "autoColor", "kbq-icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
707
707
  }
708
708
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTimeRangeEditor, decorators: [{
709
709
  type: Component,
@@ -1076,7 +1076,7 @@ class KbqTimeRange {
1076
1076
  <button kbq-button (click)="onCancel(popover)">{{ localeConfig.editor.cancel }}</button>
1077
1077
  </div>
1078
1078
  </ng-template>
1079
- `, isInline: true, styles: [".kbq-time-range .kbq-time-range__trigger{display:block}.kbq-time-range__popover .kbq-time-range__buttons{display:flex;flex-direction:row;gap:var(--kbq-size-l)}.kbq-time-range__editor{display:block}.kbq-time-range__editor .kbq-time-range-editor__container{display:flex;flex-direction:column;gap:var(--kbq-size-s);width:100%}.kbq-time-range__editor .kbq-time-range-editor__predefined{column-count:2}.kbq-time-range__editor .kbq-time-range-editor__predefined .kbq-time-range-editor__predefined-option{display:block;margin-bottom:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range{display:flex;flex-direction:column;gap:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time{display:flex;flex-direction:row;justify-content:space-between;gap:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time .kbq-time-range-editor__date-time-prefix{display:flex;align-items:center;align-self:flex-start;min-height:var(--kbq-size-3xl);flex:none;width:57px}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time .kbq-fieldset{flex:1;min-width:0}.kbq-time-range-title-as-form-field{white-space:nowrap;text-overflow:ellipsis;min-height:calc(var(--kbq-form-field-size-height) - 2 * var(--kbq-size-border-width))}.kbq-time-range-title-as-form-field .kbq-time-range-title__placeholder{color:var(--kbq-foreground-contrast-tertiary)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: KbqPopoverModule }, { kind: "directive", type: i3$1.KbqPopoverTrigger, selector: "[kbqPopover]", inputs: ["kbqPopoverHideIfNotInViewPort", "kbqTrigger", "kbqLeaveDelay", "kbqEnterDelay", "kbqPopoverPreventClose", "kbqPopoverStickToWindow", "kbqPopoverContainer", "kbqPopoverHasBackdrop", "kbqPopoverBackdropClass", "kbqPopoverDefaultPaddings", "kbqPopoverSize", "kbqPopoverClass", "kbqPopoverHeader", "kbqPopoverContent", "kbqPopoverFooter", "kbqPopoverContext", "kbqPopoverAriaLabel", "kbqPopoverHasCloseButton", "kbqPopoverCloseOnScroll", "kbqPopoverArrow", "kbqPopoverOffset", "kbqPopoverAutoFocus", "kbqPopoverOrigin", "kbqPopoverDisabled", "kbqPopoverPlacementPriority", "kbqPopoverPlacement", "kbqPopoverVisible"], outputs: ["kbqPopoverPlacementChange", "kbqPopoverVisibleChange"], exportAs: ["kbqPopover"] }, { kind: "ngmodule", type: KbqButtonModule }, { kind: "component", type: i4$1.KbqButton, selector: "[kbq-button]", inputs: ["kbqStyle", "disabled", "tabIndex"] }, { kind: "directive", type: i4$1.KbqButtonCssStyler, selector: "[kbq-button]" }, { kind: "component", type: KbqTimeRangeEditor, selector: "kbq-time-range-editor", inputs: ["maxDate", "minDate", "availableTimeRangeTypes", "rangeValue", "showRangeAsDefault", "localeConfiguration", "optionTemplate"] }, { kind: "component", type: KbqTimeRangeTitle, selector: "kbq-time-range-title", inputs: ["timeRange", "localeConfiguration", "titleTemplate", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1079
+ `, isInline: true, styles: [".kbq-time-range .kbq-time-range__trigger{display:block}.kbq-time-range__popover .kbq-time-range__buttons{display:flex;flex-direction:row;gap:var(--kbq-size-l)}.kbq-time-range__editor{display:block}.kbq-time-range__editor .kbq-time-range-editor__container{display:flex;flex-direction:column;gap:var(--kbq-size-s);width:100%}.kbq-time-range__editor .kbq-time-range-editor__predefined{column-count:2}.kbq-time-range__editor .kbq-time-range-editor__predefined .kbq-time-range-editor__predefined-option{display:block;margin-bottom:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range{display:flex;flex-direction:column;gap:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time{display:flex;flex-direction:row;justify-content:space-between;gap:var(--kbq-size-s)}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time .kbq-time-range-editor__date-time-prefix{display:flex;align-items:center;align-self:flex-start;min-height:var(--kbq-size-3xl);flex:none;width:57px}.kbq-time-range__editor .kbq-time-range-editor__range .kbq-time-range-editor__date-time .kbq-fieldset{flex:1;min-width:0}.kbq-time-range-title-as-form-field{white-space:nowrap;text-overflow:ellipsis;min-height:calc(var(--kbq-form-field-size-height) - 2 * var(--kbq-size-border-width))}.kbq-time-range-title-as-form-field .kbq-time-range-title__placeholder{color:var(--kbq-foreground-contrast-tertiary)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: KbqPopoverModule }, { kind: "directive", type: i3$1.KbqPopoverTrigger, selector: "[kbqPopover]", inputs: ["kbqPopoverHideIfNotInViewPort", "kbqTrigger", "kbqLeaveDelay", "kbqEnterDelay", "kbqPopoverPreventClose", "kbqPopoverStickToWindow", "kbqPopoverContainer", "kbqPopoverHasBackdrop", "kbqPopoverBackdropClass", "kbqPopoverDefaultPaddings", "kbqPopoverSize", "kbqPopoverClass", "kbqPopoverHeader", "kbqPopoverContent", "kbqPopoverFooter", "kbqPopoverContext", "kbqPopoverAriaLabel", "kbqPopoverHasCloseButton", "kbqPopoverCloseOnScroll", "kbqPopoverArrow", "kbqPopoverArrowCentered", "kbqPopoverOffset", "kbqPopoverAutoFocus", "kbqRelativeToPointer", "kbqPopoverOrigin", "kbqPopoverDisabled", "kbqPopoverPlacementPriority", "kbqPopoverPlacement", "kbqPopoverVisible"], outputs: ["kbqPopoverPlacementChange", "kbqPopoverVisibleChange"], exportAs: ["kbqPopover"] }, { kind: "ngmodule", type: KbqButtonModule }, { kind: "component", type: i4$1.KbqButton, selector: "[kbq-button]", inputs: ["kbqStyle", "disabled", "tabIndex"] }, { kind: "directive", type: i4$1.KbqButtonCssStyler, selector: "[kbq-button]" }, { kind: "component", type: KbqTimeRangeEditor, selector: "kbq-time-range-editor", inputs: ["maxDate", "minDate", "availableTimeRangeTypes", "rangeValue", "showRangeAsDefault", "localeConfiguration", "optionTemplate"] }, { kind: "component", type: KbqTimeRangeTitle, selector: "kbq-time-range-title", inputs: ["timeRange", "localeConfiguration", "titleTemplate", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1080
1080
  }
1081
1081
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqTimeRange, decorators: [{
1082
1082
  type: Component,