@koobiq/components 21.0.0 → 21.0.1

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 (222) hide show
  1. package/fesm2022/koobiq-components-code-block.mjs +45 -17
  2. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  3. package/fesm2022/koobiq-components-core.mjs +1 -1
  4. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  5. package/fesm2022/koobiq-components-filter-bar.mjs +9 -5
  6. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  7. package/fesm2022/koobiq-components-icon.mjs +37 -16
  8. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  9. package/fesm2022/koobiq-components-tree-select.mjs +20 -5
  10. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  11. package/fesm2022/koobiq-components-tree.mjs +218 -83
  12. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  13. package/package.json +3 -3
  14. package/schematics/collection.json +94 -89
  15. package/schematics/migrations/accordion-state-saving-default/{index.js → index.cjs} +5 -4
  16. package/schematics/migrations/actions-panel-overlay-container/{index.js → index.cjs} +5 -4
  17. package/schematics/migrations/alert-signals/{index.js → index.cjs} +14 -13
  18. package/schematics/migrations/angular-animations-removal/index.cjs +21 -0
  19. package/schematics/migrations/app-switcher-signals/{index.js → index.cjs} +7 -6
  20. package/schematics/migrations/autocomplete-panel-width-auto/{index.js → index.cjs} +6 -5
  21. package/schematics/migrations/autocomplete-signals/{index.js → index.cjs} +7 -6
  22. package/schematics/migrations/badge-signals/{index.js → index.cjs} +7 -6
  23. package/schematics/migrations/button-state-and-styles/{index.js → index.cjs} +7 -6
  24. package/schematics/migrations/button-supported-colors/{index.js → index.cjs} +7 -6
  25. package/schematics/migrations/button-toggle-signals-and-aria/{index.js → index.cjs} +7 -6
  26. package/schematics/migrations/button-truncation/{index.js → index.cjs} +7 -6
  27. package/schematics/migrations/checkbox-signals/{index.js → index.cjs} +9 -8
  28. package/schematics/migrations/clamped-text-disclosure/{index.js → index.cjs} +5 -4
  29. package/schematics/migrations/code-block-highlight-js-core/README.md +53 -0
  30. package/schematics/migrations/code-block-highlight-js-core/data.cjs +64 -0
  31. package/schematics/migrations/code-block-highlight-js-core/index.cjs +319 -0
  32. package/schematics/migrations/code-block-highlight-js-core/schema.json +20 -0
  33. package/schematics/migrations/code-block-signals/{index.js → index.cjs} +7 -6
  34. package/schematics/migrations/color-signals/index.cjs +20 -0
  35. package/schematics/migrations/core-mixins-removal/index.cjs +18 -0
  36. package/schematics/migrations/css-selectors/{index.js → index.cjs} +4 -3
  37. package/schematics/migrations/datepicker-signals/index.cjs +18 -0
  38. package/schematics/migrations/deprecated-icons/{index.js → index.cjs} +8 -7
  39. package/schematics/migrations/design-tokens-v4/{index.js → index.cjs} +3 -2
  40. package/schematics/migrations/divider-signals-and-aria/{index.js → index.cjs} +5 -4
  41. package/schematics/migrations/dl-attribute-coercion/{index.js → index.cjs} +7 -6
  42. package/schematics/migrations/dl-standalone-names/{index.js → index.cjs} +11 -10
  43. package/schematics/migrations/dropdown-demote-overlay/{index.js → index.cjs} +7 -6
  44. package/schematics/migrations/dropdown-signals/index.cjs +20 -0
  45. package/schematics/migrations/empty-state-error-color/{index.js → index.cjs} +5 -4
  46. package/schematics/migrations/empty-state-size-attr/{index.js → index.cjs} +6 -5
  47. package/schematics/migrations/file-upload-cva-and-primitives/{index.js → index.cjs} +5 -4
  48. package/schematics/migrations/file-upload-deprecated-outputs/{index.js → index.cjs} +5 -4
  49. package/schematics/migrations/filter-bar-rename-action/{index.js → index.cjs} +5 -4
  50. package/schematics/migrations/filter-bar-signals/{index.js → index.cjs} +16 -15
  51. package/schematics/migrations/filter-bar-state-saving-default/{index.js → index.cjs} +5 -4
  52. package/schematics/migrations/flag-inner-html/{index.js → index.cjs} +5 -4
  53. package/schematics/migrations/form-field-signals/{index.js → index.cjs} +18 -17
  54. package/schematics/migrations/icon-semantics-and-api/{data.js → data.cjs} +4 -4
  55. package/schematics/migrations/icon-semantics-and-api/{index.js → index.cjs} +6 -5
  56. package/schematics/migrations/icons-replacement/{index.js → index.cjs} +4 -3
  57. package/schematics/migrations/inline-edit-a11y-and-types/{index.js → index.cjs} +5 -4
  58. package/schematics/migrations/input-number-surface/{index.js → index.cjs} +5 -4
  59. package/schematics/migrations/input-signals/index.cjs +18 -0
  60. package/schematics/migrations/link-deprecated-path/{index.js → index.cjs} +4 -3
  61. package/schematics/migrations/link-signals/{index.js → index.cjs} +5 -4
  62. package/schematics/migrations/list-signals/index.cjs +18 -0
  63. package/schematics/migrations/list-tree-multiple-input/{index.js → index.cjs} +7 -6
  64. package/schematics/migrations/loader-overlay-signals/{index.js → index.cjs} +7 -6
  65. package/schematics/migrations/loader-overlay-size-attr/{index.js → index.cjs} +6 -5
  66. package/schematics/migrations/locale-configuration-providers/{index.js → index.cjs} +5 -4
  67. package/schematics/migrations/mandatory-peer-dependencies/{index.js → index.cjs} +3 -2
  68. package/schematics/migrations/markdown-signals/{index.js → index.cjs} +7 -6
  69. package/schematics/migrations/modal-dialog-semantics/{index.js → index.cjs} +5 -4
  70. package/schematics/migrations/modal-signals/index.cjs +20 -0
  71. package/schematics/migrations/navbar-signals-and-aria/{index.js → index.cjs} +7 -6
  72. package/schematics/migrations/new-icons-pack/{index.js → index.cjs} +8 -7
  73. package/schematics/migrations/notification-center-signals/{index.js → index.cjs} +5 -4
  74. package/schematics/migrations/option-signals/index.cjs +20 -0
  75. package/schematics/migrations/popover-leave-delay/{index.js → index.cjs} +5 -4
  76. package/schematics/migrations/progress-bar-percentage-and-aria/{index.js → index.cjs} +5 -4
  77. package/schematics/migrations/progress-spinner-signals/{index.js → index.cjs} +7 -6
  78. package/schematics/migrations/query-list-signals/index.cjs +18 -0
  79. package/schematics/migrations/radio-signals-and-aria/{index.js → index.cjs} +9 -8
  80. package/schematics/migrations/read-state-dwell-handlers/{index.js → index.cjs} +5 -4
  81. package/schematics/migrations/scrollbar-deprecated-path/{index.js → index.cjs} +4 -3
  82. package/schematics/migrations/select-signal-inputs/{index.js → index.cjs} +5 -4
  83. package/schematics/migrations/sidepanel-non-modal-behavior/{index.js → index.cjs} +5 -4
  84. package/schematics/migrations/signal-inputs-subclasses/index.cjs +18 -0
  85. package/schematics/migrations/split-button-optional-disabled/{index.js → index.cjs} +5 -4
  86. package/schematics/migrations/splitter-deprecated-path/{index.js → index.cjs} +4 -3
  87. package/schematics/migrations/state-saving-default/{index.js → index.cjs} +5 -4
  88. package/schematics/migrations/table-cell-content/{index.js → index.cjs} +5 -4
  89. package/schematics/migrations/tabs-signals-and-aria/{index.js → index.cjs} +5 -4
  90. package/schematics/migrations/tag-list-cleaner/{index.js → index.cjs} +7 -6
  91. package/schematics/migrations/tag-slots/{index.js → index.cjs} +6 -5
  92. package/schematics/migrations/tags-signals/{index.js → index.cjs} +7 -6
  93. package/schematics/migrations/textarea-signals/{index.js → index.cjs} +7 -6
  94. package/schematics/migrations/time-range-title-for/{index.js → index.cjs} +5 -4
  95. package/schematics/migrations/timepicker-signals/{index.js → index.cjs} +7 -6
  96. package/schematics/migrations/timezone-grouping-utils/{index.js → index.cjs} +5 -4
  97. package/schematics/migrations/title-encapsulation/{index.js → index.cjs} +5 -4
  98. package/schematics/migrations/toast-stack-and-defaults/{index.js → index.cjs} +5 -4
  99. package/schematics/migrations/tooltip-pointer-events-and-types/{index.js → index.cjs} +5 -4
  100. package/schematics/migrations/top-bar-container-selectors/{index.js → index.cjs} +5 -4
  101. package/schematics/migrations/tree-select-signals/{index.js → index.cjs} +5 -4
  102. package/schematics/migrations/tree-signals/{index.js → index.cjs} +5 -4
  103. package/schematics/migrations/tree-state-saving-default/{index.js → index.cjs} +5 -4
  104. package/schematics/migrations/username-pipe-injection/{index.js → index.cjs} +5 -4
  105. package/schematics/migrations/v20-upgrade/{data.js → data.cjs} +7 -7
  106. package/schematics/migrations/v20-upgrade/index.cjs +19 -0
  107. package/schematics/migrations/v21-upgrade/{data.js → data.cjs} +22 -22
  108. package/schematics/migrations/v21-upgrade/{index.js → index.cjs} +11 -10
  109. package/schematics/migrations/zoneless-change-detection/index.cjs +21 -0
  110. package/schematics/migrations.json +87 -82
  111. package/schematics/ng-add/{index.js → index.cjs} +12 -286
  112. package/schematics/utils/{angular-parsing.js → angular-parsing.cjs} +2 -2
  113. package/schematics/utils/{deprecated-path-migration.js → deprecated-path-migration.cjs} +4 -3
  114. package/schematics/utils/html-config.cjs +148 -0
  115. package/schematics/utils/{icon-migration.js → icon-migration.cjs} +2 -2
  116. package/schematics/utils/list-item-pattern.cjs +16 -0
  117. package/schematics/utils/package-config.cjs +80 -0
  118. package/schematics/utils/project-files.cjs +25 -0
  119. package/schematics/utils/replacement-driver.cjs +337 -0
  120. package/schematics/utils/safe-rule.cjs +23 -0
  121. package/schematics/utils/signal-members-migration.cjs +779 -0
  122. package/schematics/utils/tag-patterns.cjs +21 -0
  123. package/schematics/utils/template-ref-access.cjs +155 -0
  124. package/schematics/utils/{typescript.js → typescript.cjs} +1 -1
  125. package/schematics/utils/warn-only-migration.cjs +52 -0
  126. package/schematics/utils/workspace-styles.cjs +123 -0
  127. package/types/koobiq-components-code-block.d.ts +38 -11
  128. package/types/koobiq-components-filter-bar.d.ts +2 -2
  129. package/types/koobiq-components-tree-select.d.ts +11 -8
  130. package/types/koobiq-components-tree.d.ts +108 -59
  131. package/schematics/migrations/angular-animations-removal/index.js +0 -20
  132. package/schematics/migrations/color-signals/index.js +0 -19
  133. package/schematics/migrations/core-mixins-removal/index.js +0 -17
  134. package/schematics/migrations/datepicker-signals/index.js +0 -17
  135. package/schematics/migrations/dropdown-signals/index.js +0 -19
  136. package/schematics/migrations/input-signals/index.js +0 -17
  137. package/schematics/migrations/list-signals/index.js +0 -17
  138. package/schematics/migrations/modal-signals/index.js +0 -19
  139. package/schematics/migrations/option-signals/index.js +0 -19
  140. package/schematics/migrations/query-list-signals/index.js +0 -17
  141. package/schematics/migrations/signal-inputs-subclasses/index.js +0 -17
  142. package/schematics/migrations/v20-upgrade/index.js +0 -18
  143. package/schematics/migrations/zoneless-change-detection/index.js +0 -20
  144. package/schematics/utils/package-config.js +0 -13
  145. /package/schematics/migrations/accordion-state-saving-default/{data.js → data.cjs} +0 -0
  146. /package/schematics/migrations/actions-panel-overlay-container/{data.js → data.cjs} +0 -0
  147. /package/schematics/migrations/alert-signals/{data.js → data.cjs} +0 -0
  148. /package/schematics/migrations/angular-animations-removal/{data.js → data.cjs} +0 -0
  149. /package/schematics/migrations/app-switcher-signals/{data.js → data.cjs} +0 -0
  150. /package/schematics/migrations/autocomplete-signals/{data.js → data.cjs} +0 -0
  151. /package/schematics/migrations/badge-signals/{data.js → data.cjs} +0 -0
  152. /package/schematics/migrations/button-state-and-styles/{data.js → data.cjs} +0 -0
  153. /package/schematics/migrations/button-supported-colors/{data.js → data.cjs} +0 -0
  154. /package/schematics/migrations/button-toggle-signals-and-aria/{data.js → data.cjs} +0 -0
  155. /package/schematics/migrations/button-truncation/{data.js → data.cjs} +0 -0
  156. /package/schematics/migrations/checkbox-signals/{data.js → data.cjs} +0 -0
  157. /package/schematics/migrations/clamped-text-disclosure/{data.js → data.cjs} +0 -0
  158. /package/schematics/migrations/code-block-signals/{data.js → data.cjs} +0 -0
  159. /package/schematics/migrations/color-signals/{data.js → data.cjs} +0 -0
  160. /package/schematics/migrations/core-mixins-removal/{data.js → data.cjs} +0 -0
  161. /package/schematics/migrations/css-selectors/{data.js → data.cjs} +0 -0
  162. /package/schematics/migrations/datepicker-signals/{data.js → data.cjs} +0 -0
  163. /package/schematics/migrations/deprecated-icons/{data.js → data.cjs} +0 -0
  164. /package/schematics/migrations/divider-signals-and-aria/{data.js → data.cjs} +0 -0
  165. /package/schematics/migrations/dl-attribute-coercion/{data.js → data.cjs} +0 -0
  166. /package/schematics/migrations/dl-standalone-names/{data.js → data.cjs} +0 -0
  167. /package/schematics/migrations/dropdown-demote-overlay/{data.js → data.cjs} +0 -0
  168. /package/schematics/migrations/dropdown-signals/{data.js → data.cjs} +0 -0
  169. /package/schematics/migrations/empty-state-error-color/{data.js → data.cjs} +0 -0
  170. /package/schematics/migrations/file-upload-cva-and-primitives/{data.js → data.cjs} +0 -0
  171. /package/schematics/migrations/file-upload-deprecated-outputs/{data.js → data.cjs} +0 -0
  172. /package/schematics/migrations/filter-bar-rename-action/{data.js → data.cjs} +0 -0
  173. /package/schematics/migrations/filter-bar-signals/{data.js → data.cjs} +0 -0
  174. /package/schematics/migrations/filter-bar-state-saving-default/{data.js → data.cjs} +0 -0
  175. /package/schematics/migrations/flag-inner-html/{data.js → data.cjs} +0 -0
  176. /package/schematics/migrations/form-field-signals/{data.js → data.cjs} +0 -0
  177. /package/schematics/migrations/icons-replacement/{data.js → data.cjs} +0 -0
  178. /package/schematics/migrations/inline-edit-a11y-and-types/{data.js → data.cjs} +0 -0
  179. /package/schematics/migrations/input-number-surface/{data.js → data.cjs} +0 -0
  180. /package/schematics/migrations/input-signals/{data.js → data.cjs} +0 -0
  181. /package/schematics/migrations/link-signals/{data.js → data.cjs} +0 -0
  182. /package/schematics/migrations/list-signals/{data.js → data.cjs} +0 -0
  183. /package/schematics/migrations/list-tree-multiple-input/{data.js → data.cjs} +0 -0
  184. /package/schematics/migrations/loader-overlay-signals/{data.js → data.cjs} +0 -0
  185. /package/schematics/migrations/locale-configuration-providers/{data.js → data.cjs} +0 -0
  186. /package/schematics/migrations/markdown-signals/{data.js → data.cjs} +0 -0
  187. /package/schematics/migrations/modal-dialog-semantics/{data.js → data.cjs} +0 -0
  188. /package/schematics/migrations/modal-signals/{data.js → data.cjs} +0 -0
  189. /package/schematics/migrations/navbar-signals-and-aria/{data.js → data.cjs} +0 -0
  190. /package/schematics/migrations/new-icons-pack/{data.js → data.cjs} +0 -0
  191. /package/schematics/migrations/notification-center-signals/{data.js → data.cjs} +0 -0
  192. /package/schematics/migrations/option-signals/{data.js → data.cjs} +0 -0
  193. /package/schematics/migrations/popover-leave-delay/{data.js → data.cjs} +0 -0
  194. /package/schematics/migrations/progress-bar-percentage-and-aria/{data.js → data.cjs} +0 -0
  195. /package/schematics/migrations/progress-spinner-signals/{data.js → data.cjs} +0 -0
  196. /package/schematics/migrations/query-list-signals/{data.js → data.cjs} +0 -0
  197. /package/schematics/migrations/radio-signals-and-aria/{data.js → data.cjs} +0 -0
  198. /package/schematics/migrations/read-state-dwell-handlers/{data.js → data.cjs} +0 -0
  199. /package/schematics/migrations/select-signal-inputs/{data.js → data.cjs} +0 -0
  200. /package/schematics/migrations/sidepanel-non-modal-behavior/{data.js → data.cjs} +0 -0
  201. /package/schematics/migrations/signal-inputs-subclasses/{data.js → data.cjs} +0 -0
  202. /package/schematics/migrations/split-button-optional-disabled/{data.js → data.cjs} +0 -0
  203. /package/schematics/migrations/state-saving-default/{data.js → data.cjs} +0 -0
  204. /package/schematics/migrations/table-cell-content/{data.js → data.cjs} +0 -0
  205. /package/schematics/migrations/tabs-signals-and-aria/{data.js → data.cjs} +0 -0
  206. /package/schematics/migrations/tag-list-cleaner/{data.js → data.cjs} +0 -0
  207. /package/schematics/migrations/tags-signals/{data.js → data.cjs} +0 -0
  208. /package/schematics/migrations/textarea-signals/{data.js → data.cjs} +0 -0
  209. /package/schematics/migrations/time-range-title-for/{data.js → data.cjs} +0 -0
  210. /package/schematics/migrations/timepicker-signals/{data.js → data.cjs} +0 -0
  211. /package/schematics/migrations/timezone-grouping-utils/{data.js → data.cjs} +0 -0
  212. /package/schematics/migrations/title-encapsulation/{data.js → data.cjs} +0 -0
  213. /package/schematics/migrations/toast-stack-and-defaults/{data.js → data.cjs} +0 -0
  214. /package/schematics/migrations/tooltip-pointer-events-and-types/{data.js → data.cjs} +0 -0
  215. /package/schematics/migrations/top-bar-container-selectors/{data.js → data.cjs} +0 -0
  216. /package/schematics/migrations/tree-select-signals/{data.js → data.cjs} +0 -0
  217. /package/schematics/migrations/tree-signals/{data.js → data.cjs} +0 -0
  218. /package/schematics/migrations/tree-state-saving-default/{data.js → data.cjs} +0 -0
  219. /package/schematics/migrations/username-pipe-injection/{data.js → data.cjs} +0 -0
  220. /package/schematics/migrations/zoneless-change-detection/{data.js → data.cjs} +0 -0
  221. /package/schematics/utils/{ast.js → ast.cjs} +0 -0
  222. /package/schematics/utils/{messages.js → messages.cjs} +0 -0
@@ -2,7 +2,7 @@ import { FocusMonitor } from '@angular/cdk/a11y';
2
2
  import * as i0 from '@angular/core';
3
3
  import { InjectionToken, inject, SecurityContext, Injectable, DestroyRef, Renderer2, input, booleanAttribute, computed, numberAttribute, signal, ViewEncapsulation, ChangeDetectionStrategy, Component, effect, isDevMode, NgModule } from '@angular/core';
4
4
  import { KbqColorDirective, KbqComponentColors } from '@koobiq/components/core';
5
- import { defer, of, throwError, Subscription } from 'rxjs';
5
+ import { throwError, defer, of, Subscription } from 'rxjs';
6
6
  import { DOCUMENT } from '@angular/common';
7
7
  import { HttpClient } from '@angular/common/http';
8
8
  import { DomSanitizer } from '@angular/platform-browser';
@@ -61,6 +61,18 @@ function kbqIconsDictProvider(dict) {
61
61
  function iconKey(namespace, name) {
62
62
  return namespace ? `${namespace}:${name}` : name;
63
63
  }
64
+ /**
65
+ * Splits "namespace:name" at the first colon; a name without one stays in the given namespace.
66
+ *
67
+ * @internal
68
+ */
69
+ function parseIconName(name, namespace = '') {
70
+ const colonIndex = name.indexOf(':');
71
+ return colonIndex === -1 ? [namespace, name] : [name.slice(0, colonIndex), name.slice(colonIndex + 1)];
72
+ }
73
+ function isSvgMarkup(text) {
74
+ return text.trimStart().startsWith('<');
75
+ }
64
76
  function cloneSvg(svg) {
65
77
  return svg.cloneNode(true);
66
78
  }
@@ -126,18 +138,25 @@ class KbqIconRegistry {
126
138
  * Accepts "namespace:name" syntax.
127
139
  */
128
140
  getNamedSvgIcon(name, namespace = '') {
129
- let resolvedNs = namespace;
130
- let resolvedName = name;
131
- if (resolvedName.trimStart().startsWith('<')) {
141
+ const icon = this.findSvgIcon(name, namespace);
142
+ if (icon)
143
+ return icon;
144
+ const key = iconKey(...parseIconName(name, namespace));
145
+ return throwError(() => Error(`KbqIconRegistry: no icon registered for "${key}".`));
146
+ }
147
+ /**
148
+ * `getNamedSvgIcon` without the error for a miss: `null` when nothing registered can resolve the name. Every font
149
+ * icon is looked up, and an error per miss would cost a stack trace each.
150
+ *
151
+ * @internal
152
+ */
153
+ findSvgIcon(name, namespace = '') {
154
+ if (isSvgMarkup(name)) {
132
155
  // `defer` so that unparsable markup arrives as an error notification: every failure of this
133
156
  // class has to reach the caller through the same channel.
134
- return defer(() => of(this.svgElementFromText(this.sanitizer.sanitize(SecurityContext.HTML, resolvedName) ?? '')));
135
- }
136
- const colonIndex = name.indexOf(':');
137
- if (colonIndex !== -1) {
138
- resolvedNs = name.slice(0, colonIndex);
139
- resolvedName = name.slice(colonIndex + 1);
157
+ return defer(() => of(this.svgElementFromText(this.sanitizer.sanitize(SecurityContext.HTML, name) ?? '')));
140
158
  }
159
+ const [resolvedNs, resolvedName] = parseIconName(name, namespace);
141
160
  const key = iconKey(resolvedNs, resolvedName);
142
161
  const iconConfig = this.iconConfigs.get(key);
143
162
  if (iconConfig) {
@@ -153,7 +172,7 @@ class KbqIconRegistry {
153
172
  svgElement: null,
154
173
  options: undefined
155
174
  };
156
- if (result.trimStart().startsWith('<')) {
175
+ if (isSvgMarkup(result)) {
157
176
  const sanitized = this.sanitizer.sanitize(SecurityContext.HTML, result) ?? '';
158
177
  config.svgText = this.sanitizer.bypassSecurityTrustHtml(sanitized);
159
178
  }
@@ -167,7 +186,7 @@ class KbqIconRegistry {
167
186
  if (sets?.length) {
168
187
  return this.loadIconFromSets(resolvedName, sets);
169
188
  }
170
- return throwError(() => Error(`KbqIconRegistry: no icon registered for "${key}".`));
189
+ return null;
171
190
  }
172
191
  cacheIcon(namespace, name, config) {
173
192
  this.iconConfigs.set(iconKey(namespace, name), config);
@@ -476,9 +495,12 @@ class KbqIcon extends KbqColorDirective {
476
495
  return;
477
496
  }
478
497
  const registry = this.registry;
498
+ // A registry that replaces the lookup, such as a subclass overriding `getNamedSvgIcon` or a test double, is
499
+ // asked through it: only the library's own lookup can report a miss without building an error.
500
+ const ownLookup = registry.getNamedSvgIcon === KbqIconRegistry.prototype.getNamedSvgIcon;
479
501
  // Deferred so that a resolver or a literal that throws falls back to the font class as well, and the
480
502
  // next name is resolved again.
481
- this.svgIconSubscription = defer(() => registry.getNamedSvgIcon(name)).subscribe({
503
+ this.svgIconSubscription = defer(() => (ownLookup ? registry.findSvgIcon(name) : registry.getNamedSvgIcon(name)) ?? of(null)).subscribe({
482
504
  next: (svg) => this.renderSvgIcon(svg),
483
505
  error: () => this.renderSvgIcon(null)
484
506
  });
@@ -523,8 +545,7 @@ class KbqIcon extends KbqColorDirective {
523
545
  return this.iconSize() ?? this.parseIconSize();
524
546
  }
525
547
  parseIconSize() {
526
- const iconName = this.iconName;
527
- const baseName = iconName?.includes(':') ? iconName.split(':')[1] : iconName;
548
+ const baseName = this.iconName && parseIconName(this.iconName)[1];
528
549
  const size = parseInt(baseName?.split('_').pop() ?? '');
529
550
  return Number.isNaN(size) ? undefined : size;
530
551
  }
@@ -752,5 +773,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImpo
752
773
  * Generated bundle index. Do not edit.
753
774
  */
754
775
 
755
- export { KBQ_ICONS_CONFIG, KBQ_ICON_ERROR_STATE_CONTEXT, KBQ_ICON_RESOLVER, KbqIcon, KbqIconButton, KbqIconItem, KbqIconModule, KbqIconRegistry, kbqIconErrorStateContextFactoryProvider, kbqIconsDictProvider, kbqIconsProvider, kbqIconsResolverProvider };
776
+ export { KBQ_ICONS_CONFIG, KBQ_ICON_ERROR_STATE_CONTEXT, KBQ_ICON_RESOLVER, KbqIcon, KbqIconButton, KbqIconItem, KbqIconModule, KbqIconRegistry, kbqIconErrorStateContextFactoryProvider, kbqIconsDictProvider, kbqIconsProvider, kbqIconsResolverProvider, parseIconName };
756
777
  //# sourceMappingURL=koobiq-components-icon.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"koobiq-components-icon.mjs","sources":["../../../packages/components/icon/icon-error-state-context.ts","../../../packages/components/icon/icon-registry-providers.ts","../../../packages/components/icon/icon-registry.ts","../../../packages/components/icon/icon.component.ts","../../../packages/components/icon/icon-button.component.ts","../../../packages/components/icon/icon-item.component.ts","../../../packages/components/icon/icon.module.ts","../../../packages/components/icon/koobiq-components-icon.ts"],"sourcesContent":["import { InjectionToken, Provider, Signal } from '@angular/core';\n\n/**\n * Narrow contract that lets `KbqIcon` react to a host's error state (e.g. `autoColor`) without\n * depending on the host's concrete class.\n *\n * @docs-private\n */\nexport interface KbqIconErrorStateContext {\n /** Whether the host is currently in an error state. */\n readonly errorState: Signal<boolean>;\n}\n\n/**\n * Injection token used by `KbqIcon` to look up its `KbqIconErrorStateContext`.\n *\n * @docs-private\n */\nexport const KBQ_ICON_ERROR_STATE_CONTEXT = new InjectionToken<KbqIconErrorStateContext>('KbqIconErrorStateContext');\n\n/**\n * Utility provider for `KBQ_ICON_ERROR_STATE_CONTEXT`, built from a factory that resolves the current host's `KbqIconErrorStateContext`.\n *\n * @docs-private\n */\nexport const kbqIconErrorStateContextFactoryProvider = (factory: () => KbqIconErrorStateContext): Provider => ({\n provide: KBQ_ICON_ERROR_STATE_CONTEXT,\n useFactory: factory\n});\n","import { InjectionToken, Provider } from '@angular/core';\n\nexport interface KbqIconsConfig {\n /** URL to the SVG sprite file. Must be served as a static asset. */\n spriteUrl: string;\n /** Optional namespace to register the sprite under. */\n namespace?: string;\n}\n\nexport const KBQ_ICONS_CONFIG = new InjectionToken<KbqIconsConfig[]>('KBQ_ICONS_CONFIG');\n\n/**\n * A function that resolves an icon name to either an inline SVG string or a URL string.\n * Return `null` to indicate this resolver does not handle the given name.\n */\nexport type KbqIconResolver = (name: string) => string | null;\n\n/**\n * Multi-valued injection token for icon resolver functions.\n * Resolvers are tried in registration order; the first non-null result wins.\n */\nexport const KBQ_ICON_RESOLVER = new InjectionToken<KbqIconResolver[]>('KBQ_ICON_RESOLVER');\n\n/** Configures the icon registry to load icons from one or more SVG sprite assets. */\nexport function kbqIconsProvider(...sprites: KbqIconsConfig[]): Provider {\n return { provide: KBQ_ICONS_CONFIG, useValue: sprites };\n}\n\n/**\n * Registers a resolver function that maps icon names to SVG strings or URLs.\n * Multiple resolvers can be registered; they are tried in registration order.\n */\nexport function kbqIconsResolverProvider(resolver: KbqIconResolver): Provider {\n return { provide: KBQ_ICON_RESOLVER, useValue: resolver, multi: true };\n}\n\n/**\n * Registers a name→URL dictionary as an icon resolver. Values are fetched at runtime through `HttpClient`.\n *\n * A value starting with `<` is taken as inline markup and passed through Angular's HTML sanitizer,\n * which drops `<svg>` wholesale — register inline icons with\n * `KbqIconRegistry.addSvgIconLiteral(name, sanitizer.bypassSecurityTrustHtml(svg))` instead, where the\n * markup is a `SafeHtml` the application has explicitly vouched for.\n *\n * @example\n * ```ts\n * kbqIconsDictProvider({ 'chevron-down-s_16': '/assets/icons/chevron-down-s_16.svg' })\n * ```\n */\nexport function kbqIconsDictProvider(dict: Record<string, string>): Provider {\n return kbqIconsResolverProvider((name) => dict[name] ?? null);\n}\n","import { DOCUMENT } from '@angular/common';\nimport { HttpClient } from '@angular/common/http';\nimport { inject, Injectable, SecurityContext } from '@angular/core';\nimport { DomSanitizer, SafeHtml, SafeResourceUrl } from '@angular/platform-browser';\nimport { defer, Observable, of, throwError } from 'rxjs';\nimport { catchError, finalize, map, share } from 'rxjs/operators';\nimport { KBQ_ICON_RESOLVER, KBQ_ICONS_CONFIG } from './icon-registry-providers';\n\nexport interface KbqIconOptions {\n viewBox?: string;\n withCredentials?: boolean;\n}\n\ninterface KbqSvgIconConfig {\n svgText: SafeHtml | null;\n url: SafeResourceUrl | null;\n options: KbqIconOptions | undefined;\n /** Cached parsed element (for literal icons or already-fetched URLs). */\n svgElement: SVGElement | null;\n}\n\nfunction iconKey(namespace: string, name: string): string {\n return namespace ? `${namespace}:${name}` : name;\n}\n\nfunction cloneSvg(svg: SVGElement): SVGElement {\n return svg.cloneNode(true) as SVGElement;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class KbqIconRegistry {\n private readonly sanitizer = inject(DomSanitizer);\n private readonly document = inject<Document>(DOCUMENT);\n private readonly httpClient = inject(HttpClient, { optional: true });\n private readonly iconsConfig = inject(KBQ_ICONS_CONFIG, { optional: true });\n private readonly resolvers = inject(KBQ_ICON_RESOLVER, { optional: true }) ?? [];\n\n /** Individual icon configs, keyed by \"namespace:name\". */\n private readonly iconConfigs = new Map<string, KbqSvgIconConfig>();\n\n /** Icon-set configs per namespace. */\n private readonly iconSetConfigs = new Map<string, KbqSvgIconConfig[]>();\n\n /** In-progress URL fetches to dedupe concurrent requests. */\n private readonly inProgressUrlFetches = new Map<string, Observable<string>>();\n\n /** Cached parsed SVG sets, keyed by URL string. */\n private readonly cachedIconSets = new Map<string, SVGElement>();\n\n constructor() {\n this.registerIconSet();\n }\n\n /** Registers an SVG icon by URL in the default namespace. */\n addSvgIcon(name: string, url: SafeResourceUrl, options?: KbqIconOptions): void {\n this.addSvgIconInNamespace('', name, url, options);\n }\n\n /** Registers an SVG icon from an inline HTML string in the default namespace. */\n addSvgIconLiteral(name: string, literal: SafeHtml, options?: KbqIconOptions): void {\n this.addSvgIconLiteralInNamespace('', name, literal, options);\n }\n\n /** Registers an SVG icon by URL under the given namespace. */\n addSvgIconInNamespace(namespace: string, name: string, url: SafeResourceUrl, options?: KbqIconOptions): void {\n this.cacheIcon(namespace, name, { url, svgText: null, options, svgElement: null });\n }\n\n /** Registers an SVG icon from an inline HTML string under the given namespace. */\n addSvgIconLiteralInNamespace(namespace: string, name: string, literal: SafeHtml, options?: KbqIconOptions): void {\n const sanitized = this.sanitizer.sanitize(SecurityContext.HTML, literal);\n\n if (!sanitized) {\n throw Error(`KbqIconRegistry: literal for icon \"${iconKey(namespace, name)}\" sanitized to empty string.`);\n }\n\n this.cacheIcon(namespace, name, {\n url: null,\n svgText: this.sanitizer.bypassSecurityTrustHtml(sanitized),\n options,\n svgElement: null\n });\n }\n\n /** Registers an SVG sprite file in the default namespace. Icons are looked up by their `symbol id`. */\n addSvgIconSet(url: SafeResourceUrl, options?: KbqIconOptions): void {\n this.addSvgIconSetInNamespace('', url, options);\n }\n\n /** Registers an SVG sprite file under the given namespace. Duplicate URLs are silently ignored. */\n addSvgIconSetInNamespace(namespace: string, url: SafeResourceUrl, options?: KbqIconOptions): void {\n const urlStr = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, url) ?? '';\n const sets = this.iconSetConfigs.get(namespace) ?? [];\n const alreadyRegistered = sets.some(\n (set) => this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, set.url!) === urlStr\n );\n\n if (alreadyRegistered) return;\n\n const config: KbqSvgIconConfig = { url, svgText: null, options, svgElement: null };\n\n sets.push(config);\n this.iconSetConfigs.set(namespace, sets);\n }\n\n /**\n * Emits a cloned SVGElement for the given name.\n * Accepts \"namespace:name\" syntax.\n */\n getNamedSvgIcon(name: string, namespace = ''): Observable<SVGElement> {\n let resolvedNs = namespace;\n let resolvedName = name;\n\n if (resolvedName.trimStart().startsWith('<')) {\n // `defer` so that unparsable markup arrives as an error notification: every failure of this\n // class has to reach the caller through the same channel.\n return defer(() =>\n of(this.svgElementFromText(this.sanitizer.sanitize(SecurityContext.HTML, resolvedName) ?? ''))\n );\n }\n\n const colonIndex = name.indexOf(':');\n\n if (colonIndex !== -1) {\n resolvedNs = name.slice(0, colonIndex);\n resolvedName = name.slice(colonIndex + 1);\n }\n\n const key = iconKey(resolvedNs, resolvedName);\n\n const iconConfig = this.iconConfigs.get(key);\n\n if (iconConfig) {\n return this.loadIcon(iconConfig, resolvedName);\n }\n\n for (const resolver of this.resolvers) {\n const result = resolver(resolvedName);\n\n if (result == null) continue;\n\n const config: KbqSvgIconConfig = {\n url: null,\n svgText: null,\n svgElement: null,\n options: undefined\n };\n\n if (result.trimStart().startsWith('<')) {\n const sanitized = this.sanitizer.sanitize(SecurityContext.HTML, result) ?? '';\n\n config.svgText = this.sanitizer.bypassSecurityTrustHtml(sanitized);\n } else {\n config.url = this.sanitizer.bypassSecurityTrustResourceUrl(result);\n }\n\n this.iconConfigs.set(key, config);\n\n return this.loadIcon(config, resolvedName);\n }\n\n const sets = this.iconSetConfigs.get(resolvedNs);\n\n if (sets?.length) {\n return this.loadIconFromSets(resolvedName, sets);\n }\n\n return throwError(() => Error(`KbqIconRegistry: no icon registered for \"${key}\".`));\n }\n\n private cacheIcon(namespace: string, name: string, config: KbqSvgIconConfig): this {\n this.iconConfigs.set(iconKey(namespace, name), config);\n\n return this;\n }\n\n private loadIcon(config: KbqSvgIconConfig, name: string): Observable<SVGElement> {\n if (config.svgElement) {\n return of(cloneSvg(config.svgElement));\n }\n\n if (config.svgText) {\n return defer(() => {\n const svg = this.svgElementFromText(config.svgText as string, config.options);\n\n config.svgElement = svg;\n\n return of(cloneSvg(svg));\n });\n }\n\n if (config.url) {\n return this.fetchUrl(config.url, config.options?.withCredentials).pipe(\n map((text) => {\n const svg = this.svgElementFromText(text, config.options);\n\n config.svgElement = svg;\n\n return cloneSvg(svg);\n })\n );\n }\n\n return throwError(() => Error(`KbqIconRegistry: icon \"${name}\" has neither URL nor literal.`));\n }\n\n private registerIconSet(): void {\n if (!this.iconsConfig) return;\n\n for (const config of this.iconsConfig) {\n const url = this.sanitizer.bypassSecurityTrustResourceUrl(config.spriteUrl);\n\n if (config.namespace) {\n this.addSvgIconSetInNamespace(config.namespace, url);\n } else {\n this.addSvgIconSet(url);\n }\n }\n }\n\n private loadIconFromSets(name: string, sets: KbqSvgIconConfig[]): Observable<SVGElement> {\n const sources = sets\n .slice()\n .reverse()\n .map((set) => this.loadIconSet(set));\n\n const tryNext = (index: number): Observable<SVGElement> => {\n if (index >= sources.length) {\n return throwError(() => Error(`KbqIconRegistry: icon \"${name}\" not found in any registered icon set.`));\n }\n\n return sources[index].pipe(\n map((setElement) => {\n const icon = this.extractIconFromSet(name, setElement);\n\n if (!icon) {\n throw Error(`KbqIconRegistry: icon \"${name}\" not found in set.`);\n }\n\n return icon;\n }),\n catchError(() => tryNext(index + 1))\n );\n };\n\n return tryNext(0);\n }\n\n private loadIconSet(config: KbqSvgIconConfig): Observable<SVGElement> {\n if (config.svgElement) {\n return of(config.svgElement);\n }\n\n if (!config.url) {\n return throwError(() => Error('KbqIconRegistry: icon set has no URL.'));\n }\n\n const urlStr = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, config.url);\n\n if (!urlStr) {\n return throwError(() => Error('KbqIconRegistry: icon set URL failed sanitization.'));\n }\n\n if (this.cachedIconSets.has(urlStr)) {\n config.svgElement = this.cachedIconSets.get(urlStr)!;\n\n return of(config.svgElement);\n }\n\n return this.fetchUrl(config.url, config.options?.withCredentials).pipe(\n map((text) => {\n const svg = this.svgElementFromText(text, config.options);\n\n config.svgElement = svg;\n this.cachedIconSets.set(urlStr, svg);\n\n return svg;\n })\n );\n }\n\n private extractIconFromSet(name: string, setElement: SVGElement): SVGElement | null {\n // Symbol ids come from the consumer's sprite, so they are not guaranteed to be valid CSS\n // identifiers — `3d-view_16` alone would make `#${name}` throw. Matching on the id avoids escaping.\n const symbol = Array.from(setElement.querySelectorAll('symbol')).find((element) => element.id === name);\n\n if (!symbol) return null;\n\n const svg = this.document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n const viewBox = symbol.getAttribute('viewBox') || setElement.getAttribute('viewBox') || '0 0 24 24';\n\n svg.setAttribute('viewBox', viewBox);\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('focusable', 'false');\n\n for (const child of Array.from(symbol.childNodes)) {\n svg.appendChild(child.cloneNode(true));\n }\n\n return svg;\n }\n\n private svgElementFromText(text: string, options?: KbqIconOptions): SVGElement {\n const div = this.document.createElement('div');\n\n div.innerHTML = text;\n\n const svg = div.querySelector('svg') as SVGElement | null;\n\n if (!svg) {\n throw Error('KbqIconRegistry: could not find <svg> element in icon markup.');\n }\n\n if (options?.viewBox) {\n svg.setAttribute('viewBox', options.viewBox);\n }\n\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('focusable', 'false');\n\n return svg;\n }\n\n private fetchUrl(url: SafeResourceUrl, withCredentials = false): Observable<string> {\n // Every other failure in this class is an error notification; a synchronous throw here would\n // escape `getNamedSvgIcon` at the call site, where no `catchError` can reach it.\n if (!this.httpClient) {\n return throwError(() =>\n Error(\n 'KbqIconRegistry: HttpClient is required for loading icons from URLs. ' +\n 'Provide it via provideHttpClient() or HttpClientModule.'\n )\n );\n }\n\n const urlStr = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, url);\n\n if (!urlStr) {\n return throwError(() => Error('KbqIconRegistry: URL failed security sanitization.'));\n }\n\n const inProgress = this.inProgressUrlFetches.get(urlStr);\n\n if (inProgress) return inProgress;\n\n const fetch = this.httpClient.get(urlStr, { responseType: 'text', withCredentials }).pipe(\n share(),\n finalize(() => this.inProgressUrlFetches.delete(urlStr))\n );\n\n this.inProgressUrlFetches.set(urlStr, fetch);\n\n return fetch;\n }\n}\n","import {\n AfterContentInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n inject,\n input,\n numberAttribute,\n OnChanges,\n Renderer2,\n signal,\n SimpleChanges,\n ViewEncapsulation\n} from '@angular/core';\nimport { KbqColorDirective, KbqComponentColors } from '@koobiq/components/core';\nimport { defer, Subscription } from 'rxjs';\nimport { KBQ_ICON_ERROR_STATE_CONTEXT } from './icon-error-state-context';\nimport { KbqIconRegistry } from './icon-registry';\n\n/** Marks an injected `<svg>` with the name it renders, so hydration can recognize and adopt it. */\nconst ICON_NAME_ATTRIBUTE = 'data-kbq-icon-name';\n\n/**\n * Renders an icon on the element it is applied to: a `@koobiq/icons` font glyph by default, or an inline\n * `<svg>` when the name resolves through a configured `KbqIconRegistry`. A name that does not resolve\n * falls back to the font class, and every later name is resolved again.\n *\n * The host is `aria-hidden` by default: an icon carries no text of its own, and in nearly every place the\n * library and its consumers use one it repeats a label that is already there. A meaningful icon opts out\n * with `aria-hidden=\"false\"`, and then has to supply its own `role=\"img\"` and `aria-label`.\n */\n@Component({\n selector: '[kbq-icon]',\n template: '<ng-content />',\n styleUrls: ['icon.scss', 'icon-tokens.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'kbq kbq-icon',\n '[class]': 'svgIcon() ? null : iconName',\n '[class.kbq-error]': 'colorIsError() || hasError || autoColorError',\n '[attr.aria-hidden]': 'resolvedAriaHidden()'\n }\n})\nexport class KbqIcon extends KbqColorDirective implements AfterContentInit, OnChanges {\n /**\n * Host providing error state for `autoColor`, when the icon sits inside one (e.g. a form field).\n *\n * @docs-private\n */\n protected readonly errorStateContext = inject(KBQ_ICON_ERROR_STATE_CONTEXT, { optional: true });\n protected readonly registry = inject(KbqIconRegistry, { optional: true });\n protected readonly destroyRef = inject(DestroyRef);\n protected readonly renderer = inject(Renderer2);\n\n /**\n * Whether the icon is hidden from assistive technology. Left unbound, it falls back to\n * `defaultAriaHidden`, which is `true` for a decorative icon and `false` for an interactive one.\n */\n readonly ariaHidden = input<boolean | undefined, boolean | string | null | undefined>(undefined, {\n alias: 'aria-hidden',\n // `null` is how a template says \"leave it unset\" (`cond ? true : null`), so it means the default\n // rather than `false` — `booleanAttribute(null)` would turn it into an explicit opt-out.\n transform: (value) => (value == null ? undefined : booleanAttribute(value))\n });\n\n /** Whether an icon of this kind is decorative when the caller says nothing. Overridden by subclasses. */\n protected readonly defaultAriaHidden: boolean = true;\n\n /** @docs-private */\n protected readonly resolvedAriaHidden = computed(() => {\n const explicit = this.ariaHidden();\n\n // An explicit value is the caller's, including \"false\" — reflecting it keeps the documented\n // opt-out visible in the DOM. Only an unbound input falls back to the kind's default.\n if (explicit !== undefined) return String(explicit);\n\n return this.defaultAriaHidden ? 'true' : null;\n });\n\n /**\n * Rendered size of the icon in pixels. Left unset, the size is read from the `_<px>` suffix of the\n * icon name (`kbq-plus_16` → 16), which is the `@koobiq/icons` convention; a name without one is\n * rendered at whatever size the surrounding styles give it.\n */\n readonly iconSize = input<number | undefined, number | string | null | undefined>(undefined, {\n transform: (value) => {\n const size = numberAttribute(value);\n\n return Number.isNaN(size) ? undefined : size;\n }\n });\n\n /**\n * Whether the icon follows the error state of the host it sits in (a form field, for one), painting\n * itself red while that host reports an error.\n */\n autoColor = false;\n\n /**\n * Whether the icon takes the error color whatever its `color` is. Set by a host that tints the icons\n * it holds, such as `KbqEmptyState`.\n */\n hasError: boolean = false;\n\n /**\n * Whether `autoColor` takes the error color from the host's error state.\n *\n * @docs-private\n */\n protected get autoColorError(): boolean {\n return this.autoColor && this.hostErrorState();\n }\n\n // The host's error state through a signal of the icon's own: the host's control reads it in its host bindings, in\n // the same reactive consumer as the icon's, where a signal read again after others costs a scan of all it has read\n // so far.\n private readonly hostErrorState = computed(() => !!this.errorStateContext?.errorState());\n\n /**\n * Whether `color` is the error color. A signal of its own because the color class binding already reads\n * `color`: the host bindings of every icon in a view run in that view's reactive consumer, which finds a\n * signal read a second time by scanning all it has read so far, O(N²) per check across N icons.\n *\n * @internal\n */\n protected readonly colorIsError = computed(() => this.color() === KbqComponentColors.Error);\n\n /** Name of an icon within a `@koobiq/icons`. Accepts \"namespace:name\" syntax. */\n iconName: string | undefined;\n\n /** @docs-private */\n readonly autoColorInput = input<boolean | undefined, boolean | string | null | undefined>(undefined, {\n alias: 'autoColor',\n transform: booleanAttribute\n });\n\n /** @docs-private */\n readonly iconNameInput = input<string | undefined>(undefined, { alias: 'kbq-icon' });\n\n /**\n * Whether the host gets an inline `max-height` matching the icon size. Only the bare icon does: the\n * button and the item size themselves through their own padding.\n */\n protected readonly appliesMaxHeight: boolean = true;\n\n /**\n * True when icon is being rendered as inline SVG.\n *\n * @docs-private\n */\n // Starts from the DOM, not `false`: on a hydrated page the svg is already there, and `false`\n // would show the font class until the async resolution catches up.\n protected readonly svgIcon = signal(!!this.findTaggedSvg());\n\n /**\n * Name the inline SVG is resolved for, which is `iconName` however that was set.\n *\n * @docs-private\n */\n protected get svgIconName(): string | undefined {\n return this.iconName;\n }\n\n /** Resolution of the inline SVG, replaced whenever the name changes. */\n private svgIconSubscription = Subscription.EMPTY;\n\n /** The `<svg>` injected for the resolved name — or already on the host, tagged, from SSR. */\n private injectedSvg: SVGElement | null = this.findTaggedSvg();\n\n /** Whether the content is initialized, which is when the inline SVG is first resolved. */\n private contentInitialized = false;\n\n constructor() {\n super();\n\n this.destroyRef.onDestroy(() => this.svgIconSubscription.unsubscribe());\n }\n\n getHostElement() {\n return this.elementRef.nativeElement;\n }\n\n /** An `<svg>` already on the host, tagged with the name it renders — e.g. one SSR left behind. */\n private findTaggedSvg(): SVGElement | null {\n return this.getHostElement().querySelector(`svg[${ICON_NAME_ATTRIBUTE}]`);\n }\n\n /**\n * Sets the icon name from code and resolves its inline SVG again. Before the content is initialized,\n * assigning `iconName` does the same.\n *\n * @docs-private\n */\n protected setIconName(name: string): void {\n this.iconName = name;\n\n if (this.contentInitialized) this.resolveSvgIcon();\n }\n\n /** @docs-private */\n updateMaxHeight() {\n if (!this.appliesMaxHeight) {\n return;\n }\n\n const size = this.resolveIconSize();\n const host = this.getHostElement();\n\n if (size !== undefined) {\n this.renderer.setStyle(host, 'max-height', `${size}px`);\n } else {\n // Without this the ceiling written for the previous name keeps clipping the new glyph.\n this.renderer.removeStyle(host, 'max-height');\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n // A bound input is handed to its member; unbound, it leaves what code wrote.\n // A bound `undefined` is a value as well: auto color turns off and the icon is removed.\n if (changes['autoColorInput']) this.autoColor = this.autoColorInput() ?? false;\n\n // A name change reaches the size through the resolution; an explicit size resolves nothing.\n if (changes['iconSize'] && this.contentInitialized) this.applyIconSize();\n\n if (changes['iconNameInput']) this.setIconName(this.iconNameInput() ?? '');\n }\n\n ngAfterContentInit(): void {\n this.updateMaxHeight();\n\n this.contentInitialized = true;\n this.resolveSvgIcon();\n }\n\n /** Renders `svgIconName` as inline SVG when the registry knows it, dropping a resolution still pending. */\n private resolveSvgIcon(): void {\n const name = this.svgIconName;\n\n this.svgIconSubscription.unsubscribe();\n\n if (!this.registry || !name) {\n this.renderSvgIcon(null);\n\n return;\n }\n\n const registry = this.registry;\n\n // Deferred so that a resolver or a literal that throws falls back to the font class as well, and the\n // next name is resolved again.\n this.svgIconSubscription = defer(() => registry.getNamedSvgIcon(name)).subscribe({\n next: (svg) => this.renderSvgIcon(svg),\n error: () => this.renderSvgIcon(null)\n });\n }\n\n /** Injects the resolved `<svg>`, or drops back to the font class when the name did not resolve. */\n private renderSvgIcon(svg: SVGElement | null): void {\n const host = this.getHostElement();\n const previous = this.injectedSvg;\n\n // A matching svg is already there (SSR's, most likely) — leave it rather than replace it,\n // which would duplicate it if the replacement raced the DOM it's reusing.\n if (previous && svg && previous.getAttribute(ICON_NAME_ATTRIBUTE) === this.iconName) {\n this.svgIcon.set(true);\n this.applyIconSize();\n\n return;\n }\n\n // Only the element injected here (or adopted above): an `<svg>` projected into the host is\n // the consumer's content.\n if (previous) {\n this.renderer.removeChild(host, previous);\n }\n\n this.injectedSvg = svg;\n this.svgIcon.set(!!svg);\n\n if (svg) {\n if (this.iconName) {\n this.renderer.setAttribute(svg, ICON_NAME_ATTRIBUTE, this.iconName);\n }\n\n this.renderer.insertBefore(host, svg, host.firstChild);\n }\n\n this.applyIconSize();\n }\n\n /** Sizes the injected `<svg>` and the host's `max-height` to the resolved icon size. */\n private applyIconSize(): void {\n const size = this.resolveIconSize();\n const svg = this.injectedSvg;\n\n if (svg && size !== undefined) {\n this.renderer.setAttribute(svg, 'width', `${size}`);\n this.renderer.setAttribute(svg, 'height', `${size}`);\n }\n\n this.updateMaxHeight();\n }\n\n private resolveIconSize(): number | undefined {\n return this.iconSize() ?? this.parseIconSize();\n }\n\n private parseIconSize(): number | undefined {\n const iconName = this.iconName;\n const baseName = iconName?.includes(':') ? iconName.split(':')[1] : iconName;\n const size = parseInt(baseName?.split('_').pop() ?? '');\n\n return Number.isNaN(size) ? undefined : size;\n }\n}\n","import { FocusMonitor } from '@angular/cdk/a11y';\nimport {\n AfterViewInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n effect,\n inject,\n input,\n isDevMode,\n numberAttribute,\n OnDestroy,\n signal,\n SimpleChanges,\n ViewEncapsulation\n} from '@angular/core';\nimport { KbqIcon } from './icon.component';\n\n/**\n * Size options for `KbqIconButton`.\n * - `compact`: 16px icon with padding, 24×24px container.\n * - `normal`: 24px icon, no padding.\n */\nexport type KbqIconButtonSize = 'compact' | 'normal';\n\n/** Host elements that are already buttons, or already activated from the keyboard by the browser. */\nconst NATIVELY_ACTIVATED_NODES = ['BUTTON', 'INPUT'];\n\n/**\n * An icon that acts as a button. Applied to a native `<button>` it only adds the styling; applied to any\n * other element — `<i>` is what the library itself mostly uses — it also supplies the semantics the\n * element does not have: `role=\"button\"` and `aria-disabled`. It does not synthesize Enter/Space\n * activation itself — attach a `(keydown.enter)`/`(keydown.space)` listener where it is used.\n *\n * It has no text of its own, so give it an `aria-label` (or an `aria-labelledby`); in dev mode it warns\n * when it has neither.\n *\n * It extends `KbqIcon` for the rendering, but deliberately does not register under that DI token: a\n * `contentChild(KbqIcon)` is looking for a decorative icon to position or tint, and an interactive\n * control is not one. See the note on `KbqIconItem`.\n */\n@Component({\n selector: `[kbq-icon-button]`,\n template: '<ng-content />',\n styleUrls: ['icon-button.scss', 'icon-button-tokens.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'kbq kbq-icon-button',\n\n '[attr.tabindex]': 'tabindex',\n '[attr.disabled]': 'disabled || null',\n '[attr.aria-disabled]': 'disabled || null',\n\n '[class.kbq-disabled]': 'disabled',\n '[class.kbq-icon-button_compact]': \"size() === 'compact'\"\n }\n})\nexport class KbqIconButton extends KbqIcon implements AfterViewInit, OnDestroy {\n /** An icon button is interactive and exposes its own name, so it is not decorative by default. */\n protected override readonly defaultAriaHidden: boolean = false;\n\n protected readonly focusMonitor = inject(FocusMonitor);\n /** Size of the icon button. */\n readonly size = input<KbqIconButtonSize>('normal');\n\n /** @docs-private */\n override readonly iconNameInput = input<string | undefined>(undefined, { alias: 'kbq-icon-button' });\n\n /** Position of the button in the tab order. A disabled button is taken out of it entirely. */\n get tabindex(): number | null {\n return this.disabled ? null : this._tabindex;\n }\n\n set tabindex(value: number | null) {\n this._tabindex = value;\n }\n\n private _tabindex: number | null = 0;\n\n /** Whether the button is disabled. */\n get disabled(): boolean {\n return this.disabledSignal();\n }\n\n set disabled(value: boolean) {\n this.disabledSignal.set(value);\n }\n\n /** @docs-private */\n readonly disabledSignal = signal(false);\n\n /** The button sizes itself through its own padding, so it never gets the bare icon's `max-height`. */\n protected override readonly appliesMaxHeight: boolean = false;\n\n /** @docs-private */\n readonly tabindexInput = input<number | null | undefined, number | string | null | undefined>(undefined, {\n alias: 'tabindex',\n // `numberAttribute` gives NaN for what it cannot parse, and `tabindex=\"NaN\"` is an invalid attribute the\n // browser ignores, so an unparsable value renders no tabindex at all.\n transform: (value) => {\n if (value == null) return undefined;\n\n const tabindex = numberAttribute(value);\n\n return Number.isNaN(tabindex) ? null : tabindex;\n }\n });\n\n /** @docs-private */\n readonly disabledInput = input<boolean | undefined, boolean | string | null | undefined>(undefined, {\n alias: 'disabled',\n transform: booleanAttribute\n });\n\n override ngOnChanges(changes: SimpleChanges): void {\n super.ngOnChanges(changes);\n\n // A bound input is handed to its member; unbound, it leaves what code wrote.\n // A bound `undefined` or `null` restores the default tabindex instead of dropping the button out of the tab order.\n if (changes['tabindexInput']) {\n const tabindex = this.tabindexInput();\n\n this.tabindex = tabindex === undefined ? 0 : tabindex;\n }\n\n if (changes['disabledInput']) {\n const disabled = this.disabledInput();\n\n if (disabled !== undefined) this.disabled = disabled;\n }\n }\n\n constructor() {\n super();\n\n effect(() => (this.disabledSignal() ? this.stopFocusMonitor() : this.runFocusMonitor()));\n }\n\n ngAfterViewInit(): void {\n this.runFocusMonitor();\n this.applyButtonRole();\n this.warnIfMissingAccessibleName();\n }\n\n ngOnDestroy() {\n this.stopFocusMonitor();\n }\n\n /**\n * Whether the host already behaves like a button, so the browser activates it from the keyboard and\n * announces it without help.\n *\n * Read on demand rather than captured in the constructor: `routerLink` and a bound `[attr.href]` both\n * write the attribute during the update pass, so an anchor that navigates carries no `href` at all\n * while directive constructors run.\n */\n private isNativelyActivated(): boolean {\n const host = this.getHostElement();\n\n return NATIVELY_ACTIVATED_NODES.includes(host.nodeName) || (host.nodeName === 'A' && host.hasAttribute('href'));\n }\n\n /**\n * A link that navigates keeps its own role; anything else is a button only because this component\n * says so, and has to be announced as one.\n *\n * Written through the renderer instead of a host binding, because the binding is evaluated in the\n * parent's update pass — before `routerLink` has set its `href` — and on an `OnPush` component it may\n * never be evaluated again to correct itself.\n */\n private applyButtonRole(): void {\n const host = this.getHostElement();\n\n if (this.isNativelyActivated() || host.hasAttribute('role')) return;\n\n this.renderer.setAttribute(host, 'role', 'button');\n }\n\n /**\n * `KbqIcon` renders a decorative glyph, so an icon button carries no text. Without an\n * `aria-label`/`aria-labelledby`/`title` it has no accessible name at all (AXE `button-name`).\n *\n * A host that opted into `aria-hidden=\"true\"` is exempt: assistive technology never reaches it, so it\n * has nothing to be named for. `KbqStepper` and the datepicker toggle are both built that way — a\n * mouse-only affordance beside a control that already carries the keyboard interaction.\n */\n private warnIfMissingAccessibleName(): void {\n if (!isDevMode()) return;\n\n const host = this.getHostElement();\n\n if (host.getAttribute('aria-hidden') === 'true') return;\n\n const hasAccessibleName =\n !!host.textContent?.trim() ||\n host.hasAttribute('aria-label') ||\n host.hasAttribute('aria-labelledby') ||\n host.hasAttribute('title');\n\n if (hasAccessibleName) return;\n\n // eslint-disable-next-line no-console\n console.warn('KbqIconButton has no accessible name. Add [aria-label] or [aria-labelledby] to it.', host);\n }\n\n private runFocusMonitor() {\n this.focusMonitor.monitor(this.getHostElement(), true);\n }\n\n private stopFocusMonitor() {\n this.focusMonitor.stopMonitoring(this.getHostElement());\n }\n}\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\nimport { KbqIcon } from './icon.component';\n\n/**\n * An icon on a filled round background — the status badge of an alert or an empty state. Decorative like\n * `KbqIcon`, and hidden from assistive technology by the same default.\n *\n * Host metadata is inherited from `KbqIcon` through `ɵɵInheritDefinitionFeature`; DI tokens are not, so a\n * `contentChild(KbqIcon)` does not match an icon item. That is deliberate — a host that wants both asks\n * for both, the way `KbqAlert` does, and telling them apart is what lets it report two projected icons.\n */\n@Component({\n selector: `[kbq-icon-item]`,\n template: '<ng-content />',\n styleUrls: ['icon-item.scss', 'icon-item-tokens.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'kbq kbq-icon-item kbq-icon-item_filled',\n '[class.kbq-icon-item_normal]': '!big()',\n '[class.kbq-icon-item_big]': 'big()',\n '[class.kbq-icon-item_fade-off]': '!fade()',\n '[class.kbq-icon-item_fade-on]': 'fade()'\n }\n})\nexport class KbqIconItem extends KbqIcon {\n /** The item sizes itself through its own padding, so it never gets the bare icon's `max-height`. */\n protected override readonly appliesMaxHeight: boolean = false;\n\n /** @docs-private */\n override readonly iconNameInput = input<string | undefined>(undefined, { alias: 'kbq-icon-item' });\n\n /** Whether the background is the translucent \"fade\" variant of the color rather than the solid one. */\n readonly fade = input<boolean>(false);\n /** Whether the item is rendered at the larger of its two sizes. */\n readonly big = input<boolean>(false);\n}\n","import { NgModule } from '@angular/core';\nimport { KbqIconButton } from './icon-button.component';\nimport { KbqIconItem } from './icon-item.component';\nimport { KbqIcon } from './icon.component';\n\nconst COMPONENTS = [\n KbqIcon,\n KbqIconButton,\n KbqIconItem\n];\n\n@NgModule({\n imports: COMPONENTS,\n exports: COMPONENTS\n})\nexport class KbqIconModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"koobiq-components-icon.mjs","sources":["../../../packages/components/icon/icon-error-state-context.ts","../../../packages/components/icon/icon-registry-providers.ts","../../../packages/components/icon/icon-registry.ts","../../../packages/components/icon/icon.component.ts","../../../packages/components/icon/icon-button.component.ts","../../../packages/components/icon/icon-item.component.ts","../../../packages/components/icon/icon.module.ts","../../../packages/components/icon/koobiq-components-icon.ts"],"sourcesContent":["import { InjectionToken, Provider, Signal } from '@angular/core';\n\n/**\n * Narrow contract that lets `KbqIcon` react to a host's error state (e.g. `autoColor`) without\n * depending on the host's concrete class.\n *\n * @docs-private\n */\nexport interface KbqIconErrorStateContext {\n /** Whether the host is currently in an error state. */\n readonly errorState: Signal<boolean>;\n}\n\n/**\n * Injection token used by `KbqIcon` to look up its `KbqIconErrorStateContext`.\n *\n * @docs-private\n */\nexport const KBQ_ICON_ERROR_STATE_CONTEXT = new InjectionToken<KbqIconErrorStateContext>('KbqIconErrorStateContext');\n\n/**\n * Utility provider for `KBQ_ICON_ERROR_STATE_CONTEXT`, built from a factory that resolves the current host's `KbqIconErrorStateContext`.\n *\n * @docs-private\n */\nexport const kbqIconErrorStateContextFactoryProvider = (factory: () => KbqIconErrorStateContext): Provider => ({\n provide: KBQ_ICON_ERROR_STATE_CONTEXT,\n useFactory: factory\n});\n","import { InjectionToken, Provider } from '@angular/core';\n\nexport interface KbqIconsConfig {\n /** URL to the SVG sprite file. Must be served as a static asset. */\n spriteUrl: string;\n /** Optional namespace to register the sprite under. */\n namespace?: string;\n}\n\nexport const KBQ_ICONS_CONFIG = new InjectionToken<KbqIconsConfig[]>('KBQ_ICONS_CONFIG');\n\n/**\n * A function that resolves an icon name to either an inline SVG string or a URL string.\n * Return `null` to indicate this resolver does not handle the given name.\n */\nexport type KbqIconResolver = (name: string) => string | null;\n\n/**\n * Multi-valued injection token for icon resolver functions.\n * Resolvers are tried in registration order; the first non-null result wins.\n */\nexport const KBQ_ICON_RESOLVER = new InjectionToken<KbqIconResolver[]>('KBQ_ICON_RESOLVER');\n\n/** Configures the icon registry to load icons from one or more SVG sprite assets. */\nexport function kbqIconsProvider(...sprites: KbqIconsConfig[]): Provider {\n return { provide: KBQ_ICONS_CONFIG, useValue: sprites };\n}\n\n/**\n * Registers a resolver function that maps icon names to SVG strings or URLs.\n * Multiple resolvers can be registered; they are tried in registration order.\n */\nexport function kbqIconsResolverProvider(resolver: KbqIconResolver): Provider {\n return { provide: KBQ_ICON_RESOLVER, useValue: resolver, multi: true };\n}\n\n/**\n * Registers a name→URL dictionary as an icon resolver. Values are fetched at runtime through `HttpClient`.\n *\n * A value starting with `<` is taken as inline markup and passed through Angular's HTML sanitizer,\n * which drops `<svg>` wholesale — register inline icons with\n * `KbqIconRegistry.addSvgIconLiteral(name, sanitizer.bypassSecurityTrustHtml(svg))` instead, where the\n * markup is a `SafeHtml` the application has explicitly vouched for.\n *\n * @example\n * ```ts\n * kbqIconsDictProvider({ 'chevron-down-s_16': '/assets/icons/chevron-down-s_16.svg' })\n * ```\n */\nexport function kbqIconsDictProvider(dict: Record<string, string>): Provider {\n return kbqIconsResolverProvider((name) => dict[name] ?? null);\n}\n","import { DOCUMENT } from '@angular/common';\nimport { HttpClient } from '@angular/common/http';\nimport { inject, Injectable, SecurityContext } from '@angular/core';\nimport { DomSanitizer, SafeHtml, SafeResourceUrl } from '@angular/platform-browser';\nimport { defer, Observable, of, throwError } from 'rxjs';\nimport { catchError, finalize, map, share } from 'rxjs/operators';\nimport { KBQ_ICON_RESOLVER, KBQ_ICONS_CONFIG } from './icon-registry-providers';\n\nexport interface KbqIconOptions {\n viewBox?: string;\n withCredentials?: boolean;\n}\n\ninterface KbqSvgIconConfig {\n svgText: SafeHtml | null;\n url: SafeResourceUrl | null;\n options: KbqIconOptions | undefined;\n /** Cached parsed element (for literal icons or already-fetched URLs). */\n svgElement: SVGElement | null;\n}\n\nfunction iconKey(namespace: string, name: string): string {\n return namespace ? `${namespace}:${name}` : name;\n}\n\n/**\n * Splits \"namespace:name\" at the first colon; a name without one stays in the given namespace.\n *\n * @internal\n */\nexport function parseIconName(name: string, namespace = ''): [namespace: string, name: string] {\n const colonIndex = name.indexOf(':');\n\n return colonIndex === -1 ? [namespace, name] : [name.slice(0, colonIndex), name.slice(colonIndex + 1)];\n}\n\nfunction isSvgMarkup(text: string): boolean {\n return text.trimStart().startsWith('<');\n}\n\nfunction cloneSvg(svg: SVGElement): SVGElement {\n return svg.cloneNode(true) as SVGElement;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class KbqIconRegistry {\n private readonly sanitizer = inject(DomSanitizer);\n private readonly document = inject<Document>(DOCUMENT);\n private readonly httpClient = inject(HttpClient, { optional: true });\n private readonly iconsConfig = inject(KBQ_ICONS_CONFIG, { optional: true });\n private readonly resolvers = inject(KBQ_ICON_RESOLVER, { optional: true }) ?? [];\n\n /** Individual icon configs, keyed by \"namespace:name\". */\n private readonly iconConfigs = new Map<string, KbqSvgIconConfig>();\n\n /** Icon-set configs per namespace. */\n private readonly iconSetConfigs = new Map<string, KbqSvgIconConfig[]>();\n\n /** In-progress URL fetches to dedupe concurrent requests. */\n private readonly inProgressUrlFetches = new Map<string, Observable<string>>();\n\n /** Cached parsed SVG sets, keyed by URL string. */\n private readonly cachedIconSets = new Map<string, SVGElement>();\n\n constructor() {\n this.registerIconSet();\n }\n\n /** Registers an SVG icon by URL in the default namespace. */\n addSvgIcon(name: string, url: SafeResourceUrl, options?: KbqIconOptions): void {\n this.addSvgIconInNamespace('', name, url, options);\n }\n\n /** Registers an SVG icon from an inline HTML string in the default namespace. */\n addSvgIconLiteral(name: string, literal: SafeHtml, options?: KbqIconOptions): void {\n this.addSvgIconLiteralInNamespace('', name, literal, options);\n }\n\n /** Registers an SVG icon by URL under the given namespace. */\n addSvgIconInNamespace(namespace: string, name: string, url: SafeResourceUrl, options?: KbqIconOptions): void {\n this.cacheIcon(namespace, name, { url, svgText: null, options, svgElement: null });\n }\n\n /** Registers an SVG icon from an inline HTML string under the given namespace. */\n addSvgIconLiteralInNamespace(namespace: string, name: string, literal: SafeHtml, options?: KbqIconOptions): void {\n const sanitized = this.sanitizer.sanitize(SecurityContext.HTML, literal);\n\n if (!sanitized) {\n throw Error(`KbqIconRegistry: literal for icon \"${iconKey(namespace, name)}\" sanitized to empty string.`);\n }\n\n this.cacheIcon(namespace, name, {\n url: null,\n svgText: this.sanitizer.bypassSecurityTrustHtml(sanitized),\n options,\n svgElement: null\n });\n }\n\n /** Registers an SVG sprite file in the default namespace. Icons are looked up by their `symbol id`. */\n addSvgIconSet(url: SafeResourceUrl, options?: KbqIconOptions): void {\n this.addSvgIconSetInNamespace('', url, options);\n }\n\n /** Registers an SVG sprite file under the given namespace. Duplicate URLs are silently ignored. */\n addSvgIconSetInNamespace(namespace: string, url: SafeResourceUrl, options?: KbqIconOptions): void {\n const urlStr = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, url) ?? '';\n const sets = this.iconSetConfigs.get(namespace) ?? [];\n const alreadyRegistered = sets.some(\n (set) => this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, set.url!) === urlStr\n );\n\n if (alreadyRegistered) return;\n\n const config: KbqSvgIconConfig = { url, svgText: null, options, svgElement: null };\n\n sets.push(config);\n this.iconSetConfigs.set(namespace, sets);\n }\n\n /**\n * Emits a cloned SVGElement for the given name.\n * Accepts \"namespace:name\" syntax.\n */\n getNamedSvgIcon(name: string, namespace = ''): Observable<SVGElement> {\n const icon = this.findSvgIcon(name, namespace);\n\n if (icon) return icon;\n\n const key = iconKey(...parseIconName(name, namespace));\n\n return throwError(() => Error(`KbqIconRegistry: no icon registered for \"${key}\".`));\n }\n\n /**\n * `getNamedSvgIcon` without the error for a miss: `null` when nothing registered can resolve the name. Every font\n * icon is looked up, and an error per miss would cost a stack trace each.\n *\n * @internal\n */\n findSvgIcon(name: string, namespace = ''): Observable<SVGElement> | null {\n if (isSvgMarkup(name)) {\n // `defer` so that unparsable markup arrives as an error notification: every failure of this\n // class has to reach the caller through the same channel.\n return defer(() => of(this.svgElementFromText(this.sanitizer.sanitize(SecurityContext.HTML, name) ?? '')));\n }\n\n const [resolvedNs, resolvedName] = parseIconName(name, namespace);\n const key = iconKey(resolvedNs, resolvedName);\n\n const iconConfig = this.iconConfigs.get(key);\n\n if (iconConfig) {\n return this.loadIcon(iconConfig, resolvedName);\n }\n\n for (const resolver of this.resolvers) {\n const result = resolver(resolvedName);\n\n if (result == null) continue;\n\n const config: KbqSvgIconConfig = {\n url: null,\n svgText: null,\n svgElement: null,\n options: undefined\n };\n\n if (isSvgMarkup(result)) {\n const sanitized = this.sanitizer.sanitize(SecurityContext.HTML, result) ?? '';\n\n config.svgText = this.sanitizer.bypassSecurityTrustHtml(sanitized);\n } else {\n config.url = this.sanitizer.bypassSecurityTrustResourceUrl(result);\n }\n\n this.iconConfigs.set(key, config);\n\n return this.loadIcon(config, resolvedName);\n }\n\n const sets = this.iconSetConfigs.get(resolvedNs);\n\n if (sets?.length) {\n return this.loadIconFromSets(resolvedName, sets);\n }\n\n return null;\n }\n\n private cacheIcon(namespace: string, name: string, config: KbqSvgIconConfig): this {\n this.iconConfigs.set(iconKey(namespace, name), config);\n\n return this;\n }\n\n private loadIcon(config: KbqSvgIconConfig, name: string): Observable<SVGElement> {\n if (config.svgElement) {\n return of(cloneSvg(config.svgElement));\n }\n\n if (config.svgText) {\n return defer(() => {\n const svg = this.svgElementFromText(config.svgText as string, config.options);\n\n config.svgElement = svg;\n\n return of(cloneSvg(svg));\n });\n }\n\n if (config.url) {\n return this.fetchUrl(config.url, config.options?.withCredentials).pipe(\n map((text) => {\n const svg = this.svgElementFromText(text, config.options);\n\n config.svgElement = svg;\n\n return cloneSvg(svg);\n })\n );\n }\n\n return throwError(() => Error(`KbqIconRegistry: icon \"${name}\" has neither URL nor literal.`));\n }\n\n private registerIconSet(): void {\n if (!this.iconsConfig) return;\n\n for (const config of this.iconsConfig) {\n const url = this.sanitizer.bypassSecurityTrustResourceUrl(config.spriteUrl);\n\n if (config.namespace) {\n this.addSvgIconSetInNamespace(config.namespace, url);\n } else {\n this.addSvgIconSet(url);\n }\n }\n }\n\n private loadIconFromSets(name: string, sets: KbqSvgIconConfig[]): Observable<SVGElement> {\n const sources = sets\n .slice()\n .reverse()\n .map((set) => this.loadIconSet(set));\n\n const tryNext = (index: number): Observable<SVGElement> => {\n if (index >= sources.length) {\n return throwError(() => Error(`KbqIconRegistry: icon \"${name}\" not found in any registered icon set.`));\n }\n\n return sources[index].pipe(\n map((setElement) => {\n const icon = this.extractIconFromSet(name, setElement);\n\n if (!icon) {\n throw Error(`KbqIconRegistry: icon \"${name}\" not found in set.`);\n }\n\n return icon;\n }),\n catchError(() => tryNext(index + 1))\n );\n };\n\n return tryNext(0);\n }\n\n private loadIconSet(config: KbqSvgIconConfig): Observable<SVGElement> {\n if (config.svgElement) {\n return of(config.svgElement);\n }\n\n if (!config.url) {\n return throwError(() => Error('KbqIconRegistry: icon set has no URL.'));\n }\n\n const urlStr = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, config.url);\n\n if (!urlStr) {\n return throwError(() => Error('KbqIconRegistry: icon set URL failed sanitization.'));\n }\n\n if (this.cachedIconSets.has(urlStr)) {\n config.svgElement = this.cachedIconSets.get(urlStr)!;\n\n return of(config.svgElement);\n }\n\n return this.fetchUrl(config.url, config.options?.withCredentials).pipe(\n map((text) => {\n const svg = this.svgElementFromText(text, config.options);\n\n config.svgElement = svg;\n this.cachedIconSets.set(urlStr, svg);\n\n return svg;\n })\n );\n }\n\n private extractIconFromSet(name: string, setElement: SVGElement): SVGElement | null {\n // Symbol ids come from the consumer's sprite, so they are not guaranteed to be valid CSS\n // identifiers — `3d-view_16` alone would make `#${name}` throw. Matching on the id avoids escaping.\n const symbol = Array.from(setElement.querySelectorAll('symbol')).find((element) => element.id === name);\n\n if (!symbol) return null;\n\n const svg = this.document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n const viewBox = symbol.getAttribute('viewBox') || setElement.getAttribute('viewBox') || '0 0 24 24';\n\n svg.setAttribute('viewBox', viewBox);\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('focusable', 'false');\n\n for (const child of Array.from(symbol.childNodes)) {\n svg.appendChild(child.cloneNode(true));\n }\n\n return svg;\n }\n\n private svgElementFromText(text: string, options?: KbqIconOptions): SVGElement {\n const div = this.document.createElement('div');\n\n div.innerHTML = text;\n\n const svg = div.querySelector('svg') as SVGElement | null;\n\n if (!svg) {\n throw Error('KbqIconRegistry: could not find <svg> element in icon markup.');\n }\n\n if (options?.viewBox) {\n svg.setAttribute('viewBox', options.viewBox);\n }\n\n svg.setAttribute('aria-hidden', 'true');\n svg.setAttribute('focusable', 'false');\n\n return svg;\n }\n\n private fetchUrl(url: SafeResourceUrl, withCredentials = false): Observable<string> {\n // Every other failure in this class is an error notification; a synchronous throw here would\n // escape `getNamedSvgIcon` at the call site, where no `catchError` can reach it.\n if (!this.httpClient) {\n return throwError(() =>\n Error(\n 'KbqIconRegistry: HttpClient is required for loading icons from URLs. ' +\n 'Provide it via provideHttpClient() or HttpClientModule.'\n )\n );\n }\n\n const urlStr = this.sanitizer.sanitize(SecurityContext.RESOURCE_URL, url);\n\n if (!urlStr) {\n return throwError(() => Error('KbqIconRegistry: URL failed security sanitization.'));\n }\n\n const inProgress = this.inProgressUrlFetches.get(urlStr);\n\n if (inProgress) return inProgress;\n\n const fetch = this.httpClient.get(urlStr, { responseType: 'text', withCredentials }).pipe(\n share(),\n finalize(() => this.inProgressUrlFetches.delete(urlStr))\n );\n\n this.inProgressUrlFetches.set(urlStr, fetch);\n\n return fetch;\n }\n}\n","import {\n AfterContentInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n inject,\n input,\n numberAttribute,\n OnChanges,\n Renderer2,\n signal,\n SimpleChanges,\n ViewEncapsulation\n} from '@angular/core';\nimport { KbqColorDirective, KbqComponentColors } from '@koobiq/components/core';\nimport { defer, of, Subscription } from 'rxjs';\nimport { KBQ_ICON_ERROR_STATE_CONTEXT } from './icon-error-state-context';\nimport { KbqIconRegistry, parseIconName } from './icon-registry';\n\n/** Marks an injected `<svg>` with the name it renders, so hydration can recognize and adopt it. */\nconst ICON_NAME_ATTRIBUTE = 'data-kbq-icon-name';\n\n/**\n * Renders an icon on the element it is applied to: a `@koobiq/icons` font glyph by default, or an inline\n * `<svg>` when the name resolves through a configured `KbqIconRegistry`. A name that does not resolve\n * falls back to the font class, and every later name is resolved again.\n *\n * The host is `aria-hidden` by default: an icon carries no text of its own, and in nearly every place the\n * library and its consumers use one it repeats a label that is already there. A meaningful icon opts out\n * with `aria-hidden=\"false\"`, and then has to supply its own `role=\"img\"` and `aria-label`.\n */\n@Component({\n selector: '[kbq-icon]',\n template: '<ng-content />',\n styleUrls: ['icon.scss', 'icon-tokens.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'kbq kbq-icon',\n '[class]': 'svgIcon() ? null : iconName',\n '[class.kbq-error]': 'colorIsError() || hasError || autoColorError',\n '[attr.aria-hidden]': 'resolvedAriaHidden()'\n }\n})\nexport class KbqIcon extends KbqColorDirective implements AfterContentInit, OnChanges {\n /**\n * Host providing error state for `autoColor`, when the icon sits inside one (e.g. a form field).\n *\n * @docs-private\n */\n protected readonly errorStateContext = inject(KBQ_ICON_ERROR_STATE_CONTEXT, { optional: true });\n protected readonly registry = inject(KbqIconRegistry, { optional: true });\n protected readonly destroyRef = inject(DestroyRef);\n protected readonly renderer = inject(Renderer2);\n\n /**\n * Whether the icon is hidden from assistive technology. Left unbound, it falls back to\n * `defaultAriaHidden`, which is `true` for a decorative icon and `false` for an interactive one.\n */\n readonly ariaHidden = input<boolean | undefined, boolean | string | null | undefined>(undefined, {\n alias: 'aria-hidden',\n // `null` is how a template says \"leave it unset\" (`cond ? true : null`), so it means the default\n // rather than `false` — `booleanAttribute(null)` would turn it into an explicit opt-out.\n transform: (value) => (value == null ? undefined : booleanAttribute(value))\n });\n\n /** Whether an icon of this kind is decorative when the caller says nothing. Overridden by subclasses. */\n protected readonly defaultAriaHidden: boolean = true;\n\n /** @docs-private */\n protected readonly resolvedAriaHidden = computed(() => {\n const explicit = this.ariaHidden();\n\n // An explicit value is the caller's, including \"false\" — reflecting it keeps the documented\n // opt-out visible in the DOM. Only an unbound input falls back to the kind's default.\n if (explicit !== undefined) return String(explicit);\n\n return this.defaultAriaHidden ? 'true' : null;\n });\n\n /**\n * Rendered size of the icon in pixels. Left unset, the size is read from the `_<px>` suffix of the\n * icon name (`kbq-plus_16` → 16), which is the `@koobiq/icons` convention; a name without one is\n * rendered at whatever size the surrounding styles give it.\n */\n readonly iconSize = input<number | undefined, number | string | null | undefined>(undefined, {\n transform: (value) => {\n const size = numberAttribute(value);\n\n return Number.isNaN(size) ? undefined : size;\n }\n });\n\n /**\n * Whether the icon follows the error state of the host it sits in (a form field, for one), painting\n * itself red while that host reports an error.\n */\n autoColor = false;\n\n /**\n * Whether the icon takes the error color whatever its `color` is. Set by a host that tints the icons\n * it holds, such as `KbqEmptyState`.\n */\n hasError: boolean = false;\n\n /**\n * Whether `autoColor` takes the error color from the host's error state.\n *\n * @docs-private\n */\n protected get autoColorError(): boolean {\n return this.autoColor && this.hostErrorState();\n }\n\n // The host's error state through a signal of the icon's own: the host's control reads it in its host bindings, in\n // the same reactive consumer as the icon's, where a signal read again after others costs a scan of all it has read\n // so far.\n private readonly hostErrorState = computed(() => !!this.errorStateContext?.errorState());\n\n /**\n * Whether `color` is the error color. A signal of its own because the color class binding already reads\n * `color`: the host bindings of every icon in a view run in that view's reactive consumer, which finds a\n * signal read a second time by scanning all it has read so far, O(N²) per check across N icons.\n *\n * @internal\n */\n protected readonly colorIsError = computed(() => this.color() === KbqComponentColors.Error);\n\n /** Name of an icon within a `@koobiq/icons`. Accepts \"namespace:name\" syntax. */\n iconName: string | undefined;\n\n /** @docs-private */\n readonly autoColorInput = input<boolean | undefined, boolean | string | null | undefined>(undefined, {\n alias: 'autoColor',\n transform: booleanAttribute\n });\n\n /** @docs-private */\n readonly iconNameInput = input<string | undefined>(undefined, { alias: 'kbq-icon' });\n\n /**\n * Whether the host gets an inline `max-height` matching the icon size. Only the bare icon does: the\n * button and the item size themselves through their own padding.\n */\n protected readonly appliesMaxHeight: boolean = true;\n\n /**\n * True when icon is being rendered as inline SVG.\n *\n * @docs-private\n */\n // Starts from the DOM, not `false`: on a hydrated page the svg is already there, and `false`\n // would show the font class until the async resolution catches up.\n protected readonly svgIcon = signal(!!this.findTaggedSvg());\n\n /**\n * Name the inline SVG is resolved for, which is `iconName` however that was set.\n *\n * @docs-private\n */\n protected get svgIconName(): string | undefined {\n return this.iconName;\n }\n\n /** Resolution of the inline SVG, replaced whenever the name changes. */\n private svgIconSubscription = Subscription.EMPTY;\n\n /** The `<svg>` injected for the resolved name — or already on the host, tagged, from SSR. */\n private injectedSvg: SVGElement | null = this.findTaggedSvg();\n\n /** Whether the content is initialized, which is when the inline SVG is first resolved. */\n private contentInitialized = false;\n\n constructor() {\n super();\n\n this.destroyRef.onDestroy(() => this.svgIconSubscription.unsubscribe());\n }\n\n getHostElement() {\n return this.elementRef.nativeElement;\n }\n\n /** An `<svg>` already on the host, tagged with the name it renders — e.g. one SSR left behind. */\n private findTaggedSvg(): SVGElement | null {\n return this.getHostElement().querySelector(`svg[${ICON_NAME_ATTRIBUTE}]`);\n }\n\n /**\n * Sets the icon name from code and resolves its inline SVG again. Before the content is initialized,\n * assigning `iconName` does the same.\n *\n * @docs-private\n */\n protected setIconName(name: string): void {\n this.iconName = name;\n\n if (this.contentInitialized) this.resolveSvgIcon();\n }\n\n /** @docs-private */\n updateMaxHeight() {\n if (!this.appliesMaxHeight) {\n return;\n }\n\n const size = this.resolveIconSize();\n const host = this.getHostElement();\n\n if (size !== undefined) {\n this.renderer.setStyle(host, 'max-height', `${size}px`);\n } else {\n // Without this the ceiling written for the previous name keeps clipping the new glyph.\n this.renderer.removeStyle(host, 'max-height');\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n // A bound input is handed to its member; unbound, it leaves what code wrote.\n // A bound `undefined` is a value as well: auto color turns off and the icon is removed.\n if (changes['autoColorInput']) this.autoColor = this.autoColorInput() ?? false;\n\n // A name change reaches the size through the resolution; an explicit size resolves nothing.\n if (changes['iconSize'] && this.contentInitialized) this.applyIconSize();\n\n if (changes['iconNameInput']) this.setIconName(this.iconNameInput() ?? '');\n }\n\n ngAfterContentInit(): void {\n this.updateMaxHeight();\n\n this.contentInitialized = true;\n this.resolveSvgIcon();\n }\n\n /** Renders `svgIconName` as inline SVG when the registry knows it, dropping a resolution still pending. */\n private resolveSvgIcon(): void {\n const name = this.svgIconName;\n\n this.svgIconSubscription.unsubscribe();\n\n if (!this.registry || !name) {\n this.renderSvgIcon(null);\n\n return;\n }\n\n const registry = this.registry;\n // A registry that replaces the lookup, such as a subclass overriding `getNamedSvgIcon` or a test double, is\n // asked through it: only the library's own lookup can report a miss without building an error.\n const ownLookup = registry.getNamedSvgIcon === KbqIconRegistry.prototype.getNamedSvgIcon;\n\n // Deferred so that a resolver or a literal that throws falls back to the font class as well, and the\n // next name is resolved again.\n this.svgIconSubscription = defer(\n () => (ownLookup ? registry.findSvgIcon(name) : registry.getNamedSvgIcon(name)) ?? of(null)\n ).subscribe({\n next: (svg) => this.renderSvgIcon(svg),\n error: () => this.renderSvgIcon(null)\n });\n }\n\n /** Injects the resolved `<svg>`, or drops back to the font class when the name did not resolve. */\n private renderSvgIcon(svg: SVGElement | null): void {\n const host = this.getHostElement();\n const previous = this.injectedSvg;\n\n // A matching svg is already there (SSR's, most likely) — leave it rather than replace it,\n // which would duplicate it if the replacement raced the DOM it's reusing.\n if (previous && svg && previous.getAttribute(ICON_NAME_ATTRIBUTE) === this.iconName) {\n this.svgIcon.set(true);\n this.applyIconSize();\n\n return;\n }\n\n // Only the element injected here (or adopted above): an `<svg>` projected into the host is\n // the consumer's content.\n if (previous) {\n this.renderer.removeChild(host, previous);\n }\n\n this.injectedSvg = svg;\n this.svgIcon.set(!!svg);\n\n if (svg) {\n if (this.iconName) {\n this.renderer.setAttribute(svg, ICON_NAME_ATTRIBUTE, this.iconName);\n }\n\n this.renderer.insertBefore(host, svg, host.firstChild);\n }\n\n this.applyIconSize();\n }\n\n /** Sizes the injected `<svg>` and the host's `max-height` to the resolved icon size. */\n private applyIconSize(): void {\n const size = this.resolveIconSize();\n const svg = this.injectedSvg;\n\n if (svg && size !== undefined) {\n this.renderer.setAttribute(svg, 'width', `${size}`);\n this.renderer.setAttribute(svg, 'height', `${size}`);\n }\n\n this.updateMaxHeight();\n }\n\n private resolveIconSize(): number | undefined {\n return this.iconSize() ?? this.parseIconSize();\n }\n\n private parseIconSize(): number | undefined {\n const baseName = this.iconName && parseIconName(this.iconName)[1];\n const size = parseInt(baseName?.split('_').pop() ?? '');\n\n return Number.isNaN(size) ? undefined : size;\n }\n}\n","import { FocusMonitor } from '@angular/cdk/a11y';\nimport {\n AfterViewInit,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n effect,\n inject,\n input,\n isDevMode,\n numberAttribute,\n OnDestroy,\n signal,\n SimpleChanges,\n ViewEncapsulation\n} from '@angular/core';\nimport { KbqIcon } from './icon.component';\n\n/**\n * Size options for `KbqIconButton`.\n * - `compact`: 16px icon with padding, 24×24px container.\n * - `normal`: 24px icon, no padding.\n */\nexport type KbqIconButtonSize = 'compact' | 'normal';\n\n/** Host elements that are already buttons, or already activated from the keyboard by the browser. */\nconst NATIVELY_ACTIVATED_NODES = ['BUTTON', 'INPUT'];\n\n/**\n * An icon that acts as a button. Applied to a native `<button>` it only adds the styling; applied to any\n * other element — `<i>` is what the library itself mostly uses — it also supplies the semantics the\n * element does not have: `role=\"button\"` and `aria-disabled`. It does not synthesize Enter/Space\n * activation itself — attach a `(keydown.enter)`/`(keydown.space)` listener where it is used.\n *\n * It has no text of its own, so give it an `aria-label` (or an `aria-labelledby`); in dev mode it warns\n * when it has neither.\n *\n * It extends `KbqIcon` for the rendering, but deliberately does not register under that DI token: a\n * `contentChild(KbqIcon)` is looking for a decorative icon to position or tint, and an interactive\n * control is not one. See the note on `KbqIconItem`.\n */\n@Component({\n selector: `[kbq-icon-button]`,\n template: '<ng-content />',\n styleUrls: ['icon-button.scss', 'icon-button-tokens.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'kbq kbq-icon-button',\n\n '[attr.tabindex]': 'tabindex',\n '[attr.disabled]': 'disabled || null',\n '[attr.aria-disabled]': 'disabled || null',\n\n '[class.kbq-disabled]': 'disabled',\n '[class.kbq-icon-button_compact]': \"size() === 'compact'\"\n }\n})\nexport class KbqIconButton extends KbqIcon implements AfterViewInit, OnDestroy {\n /** An icon button is interactive and exposes its own name, so it is not decorative by default. */\n protected override readonly defaultAriaHidden: boolean = false;\n\n protected readonly focusMonitor = inject(FocusMonitor);\n /** Size of the icon button. */\n readonly size = input<KbqIconButtonSize>('normal');\n\n /** @docs-private */\n override readonly iconNameInput = input<string | undefined>(undefined, { alias: 'kbq-icon-button' });\n\n /** Position of the button in the tab order. A disabled button is taken out of it entirely. */\n get tabindex(): number | null {\n return this.disabled ? null : this._tabindex;\n }\n\n set tabindex(value: number | null) {\n this._tabindex = value;\n }\n\n private _tabindex: number | null = 0;\n\n /** Whether the button is disabled. */\n get disabled(): boolean {\n return this.disabledSignal();\n }\n\n set disabled(value: boolean) {\n this.disabledSignal.set(value);\n }\n\n /** @docs-private */\n readonly disabledSignal = signal(false);\n\n /** The button sizes itself through its own padding, so it never gets the bare icon's `max-height`. */\n protected override readonly appliesMaxHeight: boolean = false;\n\n /** @docs-private */\n readonly tabindexInput = input<number | null | undefined, number | string | null | undefined>(undefined, {\n alias: 'tabindex',\n // `numberAttribute` gives NaN for what it cannot parse, and `tabindex=\"NaN\"` is an invalid attribute the\n // browser ignores, so an unparsable value renders no tabindex at all.\n transform: (value) => {\n if (value == null) return undefined;\n\n const tabindex = numberAttribute(value);\n\n return Number.isNaN(tabindex) ? null : tabindex;\n }\n });\n\n /** @docs-private */\n readonly disabledInput = input<boolean | undefined, boolean | string | null | undefined>(undefined, {\n alias: 'disabled',\n transform: booleanAttribute\n });\n\n override ngOnChanges(changes: SimpleChanges): void {\n super.ngOnChanges(changes);\n\n // A bound input is handed to its member; unbound, it leaves what code wrote.\n // A bound `undefined` or `null` restores the default tabindex instead of dropping the button out of the tab order.\n if (changes['tabindexInput']) {\n const tabindex = this.tabindexInput();\n\n this.tabindex = tabindex === undefined ? 0 : tabindex;\n }\n\n if (changes['disabledInput']) {\n const disabled = this.disabledInput();\n\n if (disabled !== undefined) this.disabled = disabled;\n }\n }\n\n constructor() {\n super();\n\n effect(() => (this.disabledSignal() ? this.stopFocusMonitor() : this.runFocusMonitor()));\n }\n\n ngAfterViewInit(): void {\n this.runFocusMonitor();\n this.applyButtonRole();\n this.warnIfMissingAccessibleName();\n }\n\n ngOnDestroy() {\n this.stopFocusMonitor();\n }\n\n /**\n * Whether the host already behaves like a button, so the browser activates it from the keyboard and\n * announces it without help.\n *\n * Read on demand rather than captured in the constructor: `routerLink` and a bound `[attr.href]` both\n * write the attribute during the update pass, so an anchor that navigates carries no `href` at all\n * while directive constructors run.\n */\n private isNativelyActivated(): boolean {\n const host = this.getHostElement();\n\n return NATIVELY_ACTIVATED_NODES.includes(host.nodeName) || (host.nodeName === 'A' && host.hasAttribute('href'));\n }\n\n /**\n * A link that navigates keeps its own role; anything else is a button only because this component\n * says so, and has to be announced as one.\n *\n * Written through the renderer instead of a host binding, because the binding is evaluated in the\n * parent's update pass — before `routerLink` has set its `href` — and on an `OnPush` component it may\n * never be evaluated again to correct itself.\n */\n private applyButtonRole(): void {\n const host = this.getHostElement();\n\n if (this.isNativelyActivated() || host.hasAttribute('role')) return;\n\n this.renderer.setAttribute(host, 'role', 'button');\n }\n\n /**\n * `KbqIcon` renders a decorative glyph, so an icon button carries no text. Without an\n * `aria-label`/`aria-labelledby`/`title` it has no accessible name at all (AXE `button-name`).\n *\n * A host that opted into `aria-hidden=\"true\"` is exempt: assistive technology never reaches it, so it\n * has nothing to be named for. `KbqStepper` and the datepicker toggle are both built that way — a\n * mouse-only affordance beside a control that already carries the keyboard interaction.\n */\n private warnIfMissingAccessibleName(): void {\n if (!isDevMode()) return;\n\n const host = this.getHostElement();\n\n if (host.getAttribute('aria-hidden') === 'true') return;\n\n const hasAccessibleName =\n !!host.textContent?.trim() ||\n host.hasAttribute('aria-label') ||\n host.hasAttribute('aria-labelledby') ||\n host.hasAttribute('title');\n\n if (hasAccessibleName) return;\n\n // eslint-disable-next-line no-console\n console.warn('KbqIconButton has no accessible name. Add [aria-label] or [aria-labelledby] to it.', host);\n }\n\n private runFocusMonitor() {\n this.focusMonitor.monitor(this.getHostElement(), true);\n }\n\n private stopFocusMonitor() {\n this.focusMonitor.stopMonitoring(this.getHostElement());\n }\n}\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\nimport { KbqIcon } from './icon.component';\n\n/**\n * An icon on a filled round background — the status badge of an alert or an empty state. Decorative like\n * `KbqIcon`, and hidden from assistive technology by the same default.\n *\n * Host metadata is inherited from `KbqIcon` through `ɵɵInheritDefinitionFeature`; DI tokens are not, so a\n * `contentChild(KbqIcon)` does not match an icon item. That is deliberate — a host that wants both asks\n * for both, the way `KbqAlert` does, and telling them apart is what lets it report two projected icons.\n */\n@Component({\n selector: `[kbq-icon-item]`,\n template: '<ng-content />',\n styleUrls: ['icon-item.scss', 'icon-item-tokens.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'kbq kbq-icon-item kbq-icon-item_filled',\n '[class.kbq-icon-item_normal]': '!big()',\n '[class.kbq-icon-item_big]': 'big()',\n '[class.kbq-icon-item_fade-off]': '!fade()',\n '[class.kbq-icon-item_fade-on]': 'fade()'\n }\n})\nexport class KbqIconItem extends KbqIcon {\n /** The item sizes itself through its own padding, so it never gets the bare icon's `max-height`. */\n protected override readonly appliesMaxHeight: boolean = false;\n\n /** @docs-private */\n override readonly iconNameInput = input<string | undefined>(undefined, { alias: 'kbq-icon-item' });\n\n /** Whether the background is the translucent \"fade\" variant of the color rather than the solid one. */\n readonly fade = input<boolean>(false);\n /** Whether the item is rendered at the larger of its two sizes. */\n readonly big = input<boolean>(false);\n}\n","import { NgModule } from '@angular/core';\nimport { KbqIconButton } from './icon-button.component';\nimport { KbqIconItem } from './icon-item.component';\nimport { KbqIcon } from './icon.component';\n\nconst COMPONENTS = [\n KbqIcon,\n KbqIconButton,\n KbqIconItem\n];\n\n@NgModule({\n imports: COMPONENTS,\n exports: COMPONENTS\n})\nexport class KbqIconModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -126,13 +126,25 @@ class KbqTreeSelect extends KbqAbstractSelect {
126
126
  * The tree answers for any node; the option is asked only for its own `[disabled]` input, and a
127
127
  * node inside a collapsed branch has no option to ask.
128
128
  */
129
- isNodeDisabled(node) {
129
+ isNodeDisabled(node, optionsByNode) {
130
130
  const tree = this.tree();
131
131
  if (!tree)
132
132
  return false;
133
133
  if (tree.disabled || tree.treeControl.isDisabled(node))
134
134
  return true;
135
- return tree.renderedOptions.find((option) => option.data === node)?.disabled ?? false;
135
+ const option = optionsByNode
136
+ ? optionsByNode.get(node)
137
+ : tree.renderedOptions.find((option) => option.data === node);
138
+ return option?.disabled ?? false;
139
+ }
140
+ /** The rendered option of each node, for asking `isNodeDisabled` about every selected node at once. */
141
+ renderedOptionsByNode() {
142
+ const optionsByNode = new Map();
143
+ this.tree()?.renderedOptions.forEach((option) => {
144
+ if (!optionsByNode.has(option.data))
145
+ optionsByNode.set(option.data, option);
146
+ });
147
+ return optionsByNode;
136
148
  }
137
149
  /**
138
150
  * Accessible name of the combobox.
@@ -1220,17 +1232,20 @@ class KbqTreeSelect extends KbqAbstractSelect {
1220
1232
  /** Whether the trigger's tags still agree with the selection about which nodes are disabled. */
1221
1233
  hasStaleTriggerValues() {
1222
1234
  const selected = this.selectionModel.selected;
1223
- return (this.triggerValues.length === selected.length &&
1224
- selected.some((node, index) => this.triggerValues[index].disabled !== this.isNodeDisabled(node)));
1235
+ if (this.triggerValues.length !== selected.length)
1236
+ return false;
1237
+ const optionsByNode = this.renderedOptionsByNode();
1238
+ return selected.some((node, index) => this.triggerValues[index].disabled !== this.isNodeDisabled(node, optionsByNode));
1225
1239
  }
1226
1240
  refreshTriggerValues() {
1227
1241
  const treeControl = this.tree().treeControl;
1242
+ const optionsByNode = this.renderedOptionsByNode();
1228
1243
  this.triggerValues = this.selectionModel.selected.map((node) => ({
1229
1244
  value: treeControl.getValue(node),
1230
1245
  viewValue: treeControl.getViewValue(node),
1231
1246
  // `treeControl` alone would miss a node disabled through the option's own input and give it
1232
1247
  // a remove icon — one-by-one removal of exactly what the cleaner keeps.
1233
- disabled: this.isNodeDisabled(node)
1248
+ disabled: this.isNodeDisabled(node, optionsByNode)
1234
1249
  }));
1235
1250
  this.changeDetectorRef.detectChanges();
1236
1251
  }