@testgorilla/tgo-ui 11.22.3 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/fesm2022/testgorilla-tgo-ui-components-accordion.mjs +335 -229
  2. package/fesm2022/testgorilla-tgo-ui-components-accordion.mjs.map +1 -1
  3. package/fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs +547 -465
  4. package/fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs.map +1 -1
  5. package/fesm2022/testgorilla-tgo-ui-components-ai-caveat.mjs +160 -75
  6. package/fesm2022/testgorilla-tgo-ui-components-ai-caveat.mjs.map +1 -1
  7. package/fesm2022/testgorilla-tgo-ui-components-ai-feedback.mjs +678 -278
  8. package/fesm2022/testgorilla-tgo-ui-components-ai-feedback.mjs.map +1 -1
  9. package/fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs +337 -274
  10. package/fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs.map +1 -1
  11. package/fesm2022/testgorilla-tgo-ui-components-audio-waveform.mjs +351 -192
  12. package/fesm2022/testgorilla-tgo-ui-components-audio-waveform.mjs.map +1 -1
  13. package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs +1950 -960
  14. package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs.map +1 -1
  15. package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs +1206 -1044
  16. package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs.map +1 -1
  17. package/fesm2022/testgorilla-tgo-ui-components-avatar.mjs +328 -182
  18. package/fesm2022/testgorilla-tgo-ui-components-avatar.mjs.map +1 -1
  19. package/fesm2022/testgorilla-tgo-ui-components-badge.mjs +383 -203
  20. package/fesm2022/testgorilla-tgo-ui-components-badge.mjs.map +1 -1
  21. package/fesm2022/testgorilla-tgo-ui-components-breadcrumb.mjs +553 -261
  22. package/fesm2022/testgorilla-tgo-ui-components-breadcrumb.mjs.map +1 -1
  23. package/fesm2022/testgorilla-tgo-ui-components-button.mjs +709 -739
  24. package/fesm2022/testgorilla-tgo-ui-components-button.mjs.map +1 -1
  25. package/fesm2022/testgorilla-tgo-ui-components-card.mjs +219 -184
  26. package/fesm2022/testgorilla-tgo-ui-components-card.mjs.map +1 -1
  27. package/fesm2022/testgorilla-tgo-ui-components-checkbox.mjs +515 -458
  28. package/fesm2022/testgorilla-tgo-ui-components-checkbox.mjs.map +1 -1
  29. package/fesm2022/testgorilla-tgo-ui-components-checklist.mjs +423 -162
  30. package/fesm2022/testgorilla-tgo-ui-components-checklist.mjs.map +1 -1
  31. package/fesm2022/testgorilla-tgo-ui-components-core.mjs +10784 -10996
  32. package/fesm2022/testgorilla-tgo-ui-components-core.mjs.map +1 -1
  33. package/fesm2022/testgorilla-tgo-ui-components-datepicker.mjs +810 -533
  34. package/fesm2022/testgorilla-tgo-ui-components-datepicker.mjs.map +1 -1
  35. package/fesm2022/testgorilla-tgo-ui-components-device-control.mjs +473 -116
  36. package/fesm2022/testgorilla-tgo-ui-components-device-control.mjs.map +1 -1
  37. package/fesm2022/testgorilla-tgo-ui-components-dialog.mjs +1149 -540
  38. package/fesm2022/testgorilla-tgo-ui-components-dialog.mjs.map +1 -1
  39. package/fesm2022/testgorilla-tgo-ui-components-divider.mjs +148 -84
  40. package/fesm2022/testgorilla-tgo-ui-components-divider.mjs.map +1 -1
  41. package/fesm2022/testgorilla-tgo-ui-components-donut-chart.mjs +239 -142
  42. package/fesm2022/testgorilla-tgo-ui-components-donut-chart.mjs.map +1 -1
  43. package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs +599 -467
  44. package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs.map +1 -1
  45. package/fesm2022/testgorilla-tgo-ui-components-elevation-shadow.mjs +126 -70
  46. package/fesm2022/testgorilla-tgo-ui-components-elevation-shadow.mjs.map +1 -1
  47. package/fesm2022/testgorilla-tgo-ui-components-empty-state.mjs +324 -329
  48. package/fesm2022/testgorilla-tgo-ui-components-empty-state.mjs.map +1 -1
  49. package/fesm2022/testgorilla-tgo-ui-components-field.mjs +969 -648
  50. package/fesm2022/testgorilla-tgo-ui-components-field.mjs.map +1 -1
  51. package/fesm2022/testgorilla-tgo-ui-components-file-upload.mjs +553 -419
  52. package/fesm2022/testgorilla-tgo-ui-components-file-upload.mjs.map +1 -1
  53. package/fesm2022/testgorilla-tgo-ui-components-filter-button.mjs +847 -452
  54. package/fesm2022/testgorilla-tgo-ui-components-filter-button.mjs.map +1 -1
  55. package/fesm2022/testgorilla-tgo-ui-components-gaussian-chart.mjs +398 -302
  56. package/fesm2022/testgorilla-tgo-ui-components-gaussian-chart.mjs.map +1 -1
  57. package/fesm2022/testgorilla-tgo-ui-components-icon-label.mjs +162 -95
  58. package/fesm2022/testgorilla-tgo-ui-components-icon-label.mjs.map +1 -1
  59. package/fesm2022/testgorilla-tgo-ui-components-icon.mjs +1825 -1795
  60. package/fesm2022/testgorilla-tgo-ui-components-icon.mjs.map +1 -1
  61. package/fesm2022/testgorilla-tgo-ui-components-infinite-scroll-table.mjs +1018 -672
  62. package/fesm2022/testgorilla-tgo-ui-components-infinite-scroll-table.mjs.map +1 -1
  63. package/fesm2022/testgorilla-tgo-ui-components-inline-field.mjs +758 -368
  64. package/fesm2022/testgorilla-tgo-ui-components-inline-field.mjs.map +1 -1
  65. package/fesm2022/testgorilla-tgo-ui-components-logo.mjs +204 -212
  66. package/fesm2022/testgorilla-tgo-ui-components-logo.mjs.map +1 -1
  67. package/fesm2022/testgorilla-tgo-ui-components-media-card.mjs +183 -48
  68. package/fesm2022/testgorilla-tgo-ui-components-media-card.mjs.map +1 -1
  69. package/fesm2022/testgorilla-tgo-ui-components-media-dialog.mjs +243 -79
  70. package/fesm2022/testgorilla-tgo-ui-components-media-dialog.mjs.map +1 -1
  71. package/fesm2022/testgorilla-tgo-ui-components-multi-input.mjs +751 -361
  72. package/fesm2022/testgorilla-tgo-ui-components-multi-input.mjs.map +1 -1
  73. package/fesm2022/testgorilla-tgo-ui-components-navbar.mjs +1122 -385
  74. package/fesm2022/testgorilla-tgo-ui-components-navbar.mjs.map +1 -1
  75. package/fesm2022/testgorilla-tgo-ui-components-overflow-menu.mjs +689 -413
  76. package/fesm2022/testgorilla-tgo-ui-components-overflow-menu.mjs.map +1 -1
  77. package/fesm2022/testgorilla-tgo-ui-components-page-header.mjs +227 -92
  78. package/fesm2022/testgorilla-tgo-ui-components-page-header.mjs.map +1 -1
  79. package/fesm2022/testgorilla-tgo-ui-components-paginator.mjs +174 -113
  80. package/fesm2022/testgorilla-tgo-ui-components-paginator.mjs.map +1 -1
  81. package/fesm2022/testgorilla-tgo-ui-components-password-criteria.mjs +367 -165
  82. package/fesm2022/testgorilla-tgo-ui-components-password-criteria.mjs.map +1 -1
  83. package/fesm2022/testgorilla-tgo-ui-components-password-strength.mjs +253 -118
  84. package/fesm2022/testgorilla-tgo-ui-components-password-strength.mjs.map +1 -1
  85. package/fesm2022/testgorilla-tgo-ui-components-phone-input.mjs +730 -444
  86. package/fesm2022/testgorilla-tgo-ui-components-phone-input.mjs.map +1 -1
  87. package/fesm2022/testgorilla-tgo-ui-components-popover.mjs +533 -221
  88. package/fesm2022/testgorilla-tgo-ui-components-popover.mjs.map +1 -1
  89. package/fesm2022/testgorilla-tgo-ui-components-popup-tip.mjs +274 -76
  90. package/fesm2022/testgorilla-tgo-ui-components-popup-tip.mjs.map +1 -1
  91. package/fesm2022/testgorilla-tgo-ui-components-progress-bar.mjs +184 -124
  92. package/fesm2022/testgorilla-tgo-ui-components-progress-bar.mjs.map +1 -1
  93. package/fesm2022/testgorilla-tgo-ui-components-prompt.mjs +1223 -574
  94. package/fesm2022/testgorilla-tgo-ui-components-prompt.mjs.map +1 -1
  95. package/fesm2022/testgorilla-tgo-ui-components-radial-progress.mjs +249 -160
  96. package/fesm2022/testgorilla-tgo-ui-components-radial-progress.mjs.map +1 -1
  97. package/fesm2022/testgorilla-tgo-ui-components-radio-button.mjs +447 -439
  98. package/fesm2022/testgorilla-tgo-ui-components-radio-button.mjs.map +1 -1
  99. package/fesm2022/testgorilla-tgo-ui-components-rating.mjs +226 -150
  100. package/fesm2022/testgorilla-tgo-ui-components-rating.mjs.map +1 -1
  101. package/fesm2022/testgorilla-tgo-ui-components-scale-table.mjs +255 -67
  102. package/fesm2022/testgorilla-tgo-ui-components-scale-table.mjs.map +1 -1
  103. package/fesm2022/testgorilla-tgo-ui-components-scale.mjs +205 -162
  104. package/fesm2022/testgorilla-tgo-ui-components-scale.mjs.map +1 -1
  105. package/fesm2022/testgorilla-tgo-ui-components-segmented-bar.mjs +245 -153
  106. package/fesm2022/testgorilla-tgo-ui-components-segmented-bar.mjs.map +1 -1
  107. package/fesm2022/testgorilla-tgo-ui-components-segmented-button.mjs +274 -140
  108. package/fesm2022/testgorilla-tgo-ui-components-segmented-button.mjs.map +1 -1
  109. package/fesm2022/testgorilla-tgo-ui-components-segmented-toggle.mjs +319 -147
  110. package/fesm2022/testgorilla-tgo-ui-components-segmented-toggle.mjs.map +1 -1
  111. package/fesm2022/testgorilla-tgo-ui-components-selectable-card.mjs +286 -84
  112. package/fesm2022/testgorilla-tgo-ui-components-selectable-card.mjs.map +1 -1
  113. package/fesm2022/testgorilla-tgo-ui-components-side-navigation.mjs +660 -208
  114. package/fesm2022/testgorilla-tgo-ui-components-side-navigation.mjs.map +1 -1
  115. package/fesm2022/testgorilla-tgo-ui-components-side-panel.mjs +579 -320
  116. package/fesm2022/testgorilla-tgo-ui-components-side-panel.mjs.map +1 -1
  117. package/fesm2022/testgorilla-tgo-ui-components-side-sheet.mjs +419 -200
  118. package/fesm2022/testgorilla-tgo-ui-components-side-sheet.mjs.map +1 -1
  119. package/fesm2022/testgorilla-tgo-ui-components-skeleton.mjs +132 -80
  120. package/fesm2022/testgorilla-tgo-ui-components-skeleton.mjs.map +1 -1
  121. package/fesm2022/testgorilla-tgo-ui-components-slider.mjs +741 -390
  122. package/fesm2022/testgorilla-tgo-ui-components-slider.mjs.map +1 -1
  123. package/fesm2022/testgorilla-tgo-ui-components-snackbar.mjs +455 -329
  124. package/fesm2022/testgorilla-tgo-ui-components-snackbar.mjs.map +1 -1
  125. package/fesm2022/testgorilla-tgo-ui-components-spider-chart.mjs +543 -514
  126. package/fesm2022/testgorilla-tgo-ui-components-spider-chart.mjs.map +1 -1
  127. package/fesm2022/testgorilla-tgo-ui-components-spinner.mjs +193 -104
  128. package/fesm2022/testgorilla-tgo-ui-components-spinner.mjs.map +1 -1
  129. package/fesm2022/testgorilla-tgo-ui-components-stepper.mjs +760 -524
  130. package/fesm2022/testgorilla-tgo-ui-components-stepper.mjs.map +1 -1
  131. package/fesm2022/testgorilla-tgo-ui-components-table.mjs +714 -415
  132. package/fesm2022/testgorilla-tgo-ui-components-table.mjs.map +1 -1
  133. package/fesm2022/testgorilla-tgo-ui-components-tabs.mjs +847 -438
  134. package/fesm2022/testgorilla-tgo-ui-components-tabs.mjs.map +1 -1
  135. package/fesm2022/testgorilla-tgo-ui-components-tag.mjs +535 -275
  136. package/fesm2022/testgorilla-tgo-ui-components-tag.mjs.map +1 -1
  137. package/fesm2022/testgorilla-tgo-ui-components-toggle.mjs +316 -246
  138. package/fesm2022/testgorilla-tgo-ui-components-toggle.mjs.map +1 -1
  139. package/fesm2022/testgorilla-tgo-ui-components-tooltip.mjs +404 -284
  140. package/fesm2022/testgorilla-tgo-ui-components-tooltip.mjs.map +1 -1
  141. package/fesm2022/testgorilla-tgo-ui-components-universal-skills.mjs +664 -383
  142. package/fesm2022/testgorilla-tgo-ui-components-universal-skills.mjs.map +1 -1
  143. package/fesm2022/testgorilla-tgo-ui-components-validation-error.mjs +201 -112
  144. package/fesm2022/testgorilla-tgo-ui-components-validation-error.mjs.map +1 -1
  145. package/fesm2022/testgorilla-tgo-ui-components-write-with-ai.mjs +1014 -458
  146. package/fesm2022/testgorilla-tgo-ui-components-write-with-ai.mjs.map +1 -1
  147. package/fesm2022/testgorilla-tgo-ui.mjs +147 -155
  148. package/fesm2022/testgorilla-tgo-ui.mjs.map +1 -1
  149. package/mcp/catalog.json +1 -1
  150. package/package.json +16 -17
  151. package/projects/tgo-canopy-ui/theme/_palette.scss +23 -18
  152. package/types/testgorilla-tgo-ui-components-accordion.d.ts +214 -158
  153. package/types/testgorilla-tgo-ui-components-ai-audio-circle.d.ts +93 -69
  154. package/types/testgorilla-tgo-ui-components-ai-caveat.d.ts +37 -34
  155. package/types/testgorilla-tgo-ui-components-ai-feedback.d.ts +126 -86
  156. package/types/testgorilla-tgo-ui-components-alert-banner.d.ts +260 -185
  157. package/types/testgorilla-tgo-ui-components-audio-waveform.d.ts +96 -67
  158. package/types/testgorilla-tgo-ui-components-autocomplete-v2.d.ts +455 -256
  159. package/types/testgorilla-tgo-ui-components-autocomplete.d.ts +545 -390
  160. package/types/testgorilla-tgo-ui-components-avatar.d.ts +128 -102
  161. package/types/testgorilla-tgo-ui-components-badge.d.ts +191 -139
  162. package/types/testgorilla-tgo-ui-components-breadcrumb.d.ts +100 -62
  163. package/types/testgorilla-tgo-ui-components-button.d.ts +479 -340
  164. package/types/testgorilla-tgo-ui-components-card.d.ts +153 -114
  165. package/types/testgorilla-tgo-ui-components-checkbox.d.ts +299 -223
  166. package/types/testgorilla-tgo-ui-components-checklist.d.ts +149 -97
  167. package/types/testgorilla-tgo-ui-components-core.d.ts +307 -295
  168. package/types/testgorilla-tgo-ui-components-datepicker.d.ts +404 -299
  169. package/types/testgorilla-tgo-ui-components-device-control.d.ts +151 -81
  170. package/types/testgorilla-tgo-ui-components-dialog.d.ts +442 -329
  171. package/types/testgorilla-tgo-ui-components-divider.d.ts +64 -51
  172. package/types/testgorilla-tgo-ui-components-donut-chart.d.ts +41 -37
  173. package/types/testgorilla-tgo-ui-components-dropdown.d.ts +335 -241
  174. package/types/testgorilla-tgo-ui-components-elevation-shadow.d.ts +48 -43
  175. package/types/testgorilla-tgo-ui-components-empty-state.d.ts +317 -215
  176. package/types/testgorilla-tgo-ui-components-field.d.ts +559 -388
  177. package/types/testgorilla-tgo-ui-components-file-upload.d.ts +230 -168
  178. package/types/testgorilla-tgo-ui-components-filter-button.d.ts +263 -206
  179. package/types/testgorilla-tgo-ui-components-gaussian-chart.d.ts +107 -94
  180. package/types/testgorilla-tgo-ui-components-icon-label.d.ts +84 -61
  181. package/types/testgorilla-tgo-ui-components-icon.d.ts +137 -110
  182. package/types/testgorilla-tgo-ui-components-infinite-scroll-table.d.ts +429 -303
  183. package/types/testgorilla-tgo-ui-components-inline-field.d.ts +338 -254
  184. package/types/testgorilla-tgo-ui-components-logo.d.ts +119 -101
  185. package/types/testgorilla-tgo-ui-components-media-card.d.ts +51 -35
  186. package/types/testgorilla-tgo-ui-components-media-dialog.d.ts +40 -45
  187. package/types/testgorilla-tgo-ui-components-multi-input.d.ts +283 -194
  188. package/types/testgorilla-tgo-ui-components-navbar.d.ts +326 -208
  189. package/types/testgorilla-tgo-ui-components-overflow-menu.d.ts +276 -204
  190. package/types/testgorilla-tgo-ui-components-page-header.d.ts +67 -50
  191. package/types/testgorilla-tgo-ui-components-paginator.d.ts +103 -70
  192. package/types/testgorilla-tgo-ui-components-password-criteria.d.ts +67 -58
  193. package/types/testgorilla-tgo-ui-components-password-strength.d.ts +66 -57
  194. package/types/testgorilla-tgo-ui-components-phone-input.d.ts +217 -175
  195. package/types/testgorilla-tgo-ui-components-popover.d.ts +94 -53
  196. package/types/testgorilla-tgo-ui-components-popup-tip.d.ts +81 -44
  197. package/types/testgorilla-tgo-ui-components-progress-bar.d.ts +115 -84
  198. package/types/testgorilla-tgo-ui-components-prompt.d.ts +315 -219
  199. package/types/testgorilla-tgo-ui-components-radial-progress.d.ts +146 -107
  200. package/types/testgorilla-tgo-ui-components-radio-button.d.ts +296 -219
  201. package/types/testgorilla-tgo-ui-components-rating.d.ts +134 -95
  202. package/types/testgorilla-tgo-ui-components-scale-table.d.ts +67 -47
  203. package/types/testgorilla-tgo-ui-components-scale.d.ts +91 -66
  204. package/types/testgorilla-tgo-ui-components-segmented-bar.d.ts +118 -89
  205. package/types/testgorilla-tgo-ui-components-segmented-button.d.ts +107 -80
  206. package/types/testgorilla-tgo-ui-components-segmented-toggle.d.ts +138 -105
  207. package/types/testgorilla-tgo-ui-components-selectable-card.d.ts +90 -56
  208. package/types/testgorilla-tgo-ui-components-side-navigation.d.ts +183 -107
  209. package/types/testgorilla-tgo-ui-components-side-panel.d.ts +156 -145
  210. package/types/testgorilla-tgo-ui-components-side-sheet.d.ts +98 -89
  211. package/types/testgorilla-tgo-ui-components-skeleton.d.ts +50 -33
  212. package/types/testgorilla-tgo-ui-components-slider.d.ts +278 -198
  213. package/types/testgorilla-tgo-ui-components-snackbar.d.ts +211 -159
  214. package/types/testgorilla-tgo-ui-components-spider-chart.d.ts +140 -121
  215. package/types/testgorilla-tgo-ui-components-spinner.d.ts +93 -72
  216. package/types/testgorilla-tgo-ui-components-stepper.d.ts +480 -338
  217. package/types/testgorilla-tgo-ui-components-table.d.ts +280 -233
  218. package/types/testgorilla-tgo-ui-components-tabs.d.ts +282 -183
  219. package/types/testgorilla-tgo-ui-components-tag.d.ts +266 -193
  220. package/types/testgorilla-tgo-ui-components-toggle.d.ts +180 -132
  221. package/types/testgorilla-tgo-ui-components-tooltip.d.ts +142 -105
  222. package/types/testgorilla-tgo-ui-components-universal-skills.d.ts +165 -144
  223. package/types/testgorilla-tgo-ui-components-validation-error.d.ts +70 -51
  224. package/types/testgorilla-tgo-ui-components-write-with-ai.d.ts +210 -133
  225. package/types/testgorilla-tgo-ui.d.ts +52 -45
@@ -1,148 +1,320 @@
1
- import * as i0 from '@angular/core';
2
- import { inject, ElementRef, DestroyRef, input, model, booleanAttribute, computed, viewChildren, signal, afterRenderEffect, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { MatTooltip } from '@angular/material/tooltip';
4
- import * as i1 from '@testgorilla/tgo-ui/components/icon';
5
- import { IconComponentModule } from '@testgorilla/tgo-ui/components/icon';
6
- import { SkeletonComponent } from '@testgorilla/tgo-ui/components/skeleton';
7
- import { TooltipPositionType } from '@testgorilla/tgo-ui/components/tooltip';
8
-
9
- class SegmentedToggleComponent {
10
- constructor() {
11
- this.hostRef = inject(ElementRef);
12
- this.destroyRef = inject(DestroyRef);
13
- this.options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
14
- this.value = model(...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
15
- this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
16
- /**
17
- * Shows a small skeleton to the right of each option's content, in place of
18
- * its `count`, while the quantities are being fetched. Segments stay selectable.
19
- */
20
- this.loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
21
- this.ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
22
- this.testId = input(null, ...(ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []));
23
- this.applicationTheme = input(undefined, ...(ngDevMode ? [{ debugName: "applicationTheme" }] : /* istanbul ignore next */ []));
24
- this.defaultAppTheme = inject('CANOPYUI_DEFAULT_APPLICATION_THEME', {
25
- optional: true,
26
- });
27
- this.theme = computed(() => this.applicationTheme() ?? this.defaultAppTheme ?? 'light', ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
28
- /**
29
- * Pill-shaped placeholder sized to a short count next to a 16px icon/label.
30
- * Tinted from the segment's text colour so it follows every state (unselected,
31
- * selected, brand, disabled); the library's fixed light grey vanishes on white
32
- * and glares on the black pill.
33
- */
34
- this.skeletonTheme = {
35
- 'background-color': 'color-mix(in srgb, currentColor 20%, transparent)',
36
- width: '16px',
37
- height: '12px',
38
- margin: '0',
39
- 'border-radius': '999px',
40
- 'vertical-align': 'middle',
41
- };
42
- /** One ElementRef per segment button; used to measure the active pill geometry. */
43
- this.optionButtons = viewChildren('optionButton', ...(ngDevMode ? [{ debugName: "optionButtons" }] : /* istanbul ignore next */ []));
44
- /** Index of the selected option; -1 when value() matches no option. */
45
- this.selectedIndex = computed(() => this.options().findIndex(option => option.value === this.value()), ...(ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []));
46
- /** True when the currently-selected option is flagged `brand: true`. */
47
- this.selectedOptionIsBrand = computed(() => this.options()[this.selectedIndex()]?.brand === true, ...(ngDevMode ? [{ debugName: "selectedOptionIsBrand" }] : /* istanbul ignore next */ []));
48
- /** Measured pixel geometry of the active button, driving the sliding indicator. */
49
- this.indicatorOffset = signal(0, ...(ngDevMode ? [{ debugName: "indicatorOffset" }] : /* istanbul ignore next */ []));
50
- this.indicatorTop = signal(0, ...(ngDevMode ? [{ debugName: "indicatorTop" }] : /* istanbul ignore next */ []));
51
- this.indicatorWidth = signal(0, ...(ngDevMode ? [{ debugName: "indicatorWidth" }] : /* istanbul ignore next */ []));
52
- this.indicatorHeight = signal(0, ...(ngDevMode ? [{ debugName: "indicatorHeight" }] : /* istanbul ignore next */ []));
53
- /** Enables the slide transition only after the initial position is painted. */
54
- this.animated = signal(false, ...(ngDevMode ? [{ debugName: "animated" }] : /* istanbul ignore next */ []));
55
- // Re-measure after every render that follows a selection or options change.
56
- afterRenderEffect(() => {
57
- // Read these so the effect re-runs (post-render) whenever selection changes.
58
- this.value();
59
- this.options();
60
- this.measureIndicator();
61
- });
62
- // Re-measure on container resize (width changes don't touch any signal).
63
- afterNextRender(() => {
64
- // Position the indicator for the initial selection without animating, then
65
- // enable the slide on the next frame so only user-driven changes animate.
66
- this.measureIndicator();
67
- requestAnimationFrame(() => this.animated.set(true));
68
- if (typeof ResizeObserver === 'undefined') {
69
- return;
70
- }
71
- const observer = new ResizeObserver(() => this.measureIndicator());
72
- observer.observe(this.hostRef.nativeElement);
73
- this.destroyRef.onDestroy(() => observer.disconnect());
74
- });
75
- }
76
- select(optionValue) {
77
- if (this.disabled()) {
78
- return;
79
- }
80
- this.value.set(optionValue);
81
- }
82
- isSelected(optionValue) {
83
- return optionValue === this.value();
84
- }
85
- /**
86
- * Last-resort accessible name for a segment. Used only for an icon-only option
87
- * that provides neither a visible `label` nor an `iconAriaLabel`, so the button
88
- * is never a nameless control. When a label or icon label is present those name
89
- * the button and this returns `null` (no `aria-label` attribute). The `aria-label`
90
- * replaces the button's content as its name, so a visible `count` is appended
91
- * here or it would never be announced.
92
- */
93
- fallbackAriaLabel(option) {
94
- if (option.label || option.iconAriaLabel) {
95
- return null;
96
- }
97
- const name = String(option.value);
98
- return option.count !== undefined && !this.loading() ? `${name} ${option.count}` : name;
99
- }
100
- optionTestId(option) {
101
- if (option.testId) {
102
- return option.testId;
103
- }
104
- const testId = this.testId();
105
- return testId ? `${testId}-${String(option.value)}` : null;
106
- }
107
- /** Maps the option's Canopy tooltip position (default TOP) to the MatTooltip position. */
108
- tooltipPosition(option) {
109
- switch (option.tooltipPosition ?? TooltipPositionType.TOP) {
110
- case TooltipPositionType.BOTTOM:
111
- return 'below';
112
- case TooltipPositionType.LEFT:
113
- return 'left';
114
- case TooltipPositionType.RIGHT:
115
- return 'right';
116
- case TooltipPositionType.TOP:
117
- return 'above';
118
- }
119
- }
120
- /** Reads the active button's box and writes it to the indicator signals. */
121
- measureIndicator() {
122
- const button = this.optionButtons()[this.selectedIndex()]?.nativeElement;
123
- if (!button) {
124
- return;
125
- }
126
- this.indicatorOffset.set(button.offsetLeft);
127
- this.indicatorTop.set(button.offsetTop);
128
- this.indicatorWidth.set(button.offsetWidth);
129
- this.indicatorHeight.set(button.offsetHeight);
130
- }
131
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: SegmentedToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
132
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: SegmentedToggleComponent, isStandalone: true, selector: "ui-segmented-toggle", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null }, applicationTheme: { classPropertyName: "applicationTheme", publicName: "applicationTheme", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { properties: { "attr.theme": "theme()", "class.ui-segmented-toggle--brand-active": "selectedOptionIsBrand()", "class.ui-segmented-toggle--disabled": "disabled()" } }, viewQueries: [{ propertyName: "optionButtons", predicate: ["optionButton"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"ui-segmented-toggle__group\"\n role=\"group\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <span\n class=\"ui-segmented-toggle__indicator\"\n [class.ui-segmented-toggle__indicator--hidden]=\"selectedIndex() < 0\"\n [class.ui-segmented-toggle__indicator--animated]=\"animated()\"\n aria-hidden=\"true\"\n [style.transform]=\"'translateX(' + indicatorOffset() + 'px) translateY(' + indicatorTop() + 'px)'\"\n [style.width.px]=\"indicatorWidth()\"\n [style.height.px]=\"indicatorHeight()\"\n ></span>\n\n @for (option of options(); track option.value) {\n <button\n #optionButton\n type=\"button\"\n class=\"ui-segmented-toggle__option\"\n [attr.aria-pressed]=\"isSelected(option.value)\"\n [attr.aria-label]=\"fallbackAriaLabel(option)\"\n [disabled]=\"disabled()\"\n [matTooltip]=\"option.tooltip ?? ''\"\n [matTooltipPosition]=\"tooltipPosition(option)\"\n [matTooltipClass]=\"theme()\"\n [attr.data-testid]=\"optionTestId(option)\"\n (click)=\"select(option.value)\"\n >\n @if (option.icon) {\n <ui-icon\n class=\"ui-segmented-toggle__icon\"\n [name]=\"option.icon\"\n size=\"16\"\n [attr.aria-hidden]=\"option.iconAriaLabel ? null : 'true'\"\n ></ui-icon>\n @if (option.iconAriaLabel) {\n <span class=\"ui-segmented-toggle__sr-only\">{{ option.iconAriaLabel }}</span>\n }\n }\n @if (option.label) {\n <span class=\"ui-segmented-toggle__label\">{{ option.label }}</span>\n }\n @if (loading()) {\n <span class=\"ui-segmented-toggle__skeleton\" aria-hidden=\"true\">\n <ui-skeleton [theme]=\"skeletonTheme\" [applicationTheme]=\"theme()\"></ui-skeleton>\n </span>\n } @else if (option.count !== undefined) {\n <span class=\"ui-segmented-toggle__count\">{{ option.count }}</span>\n }\n </button>\n }\n</div>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{display:inline-flex}.ui-segmented-toggle__group{position:relative;display:flex;align-items:center;gap:0;padding:4px;box-shadow:inset 0 0 0 1px #242424;border-radius:999px;background:#fff}.ui-segmented-toggle__indicator{position:absolute;top:0;left:0;z-index:0;border-radius:999px;background:#242424}.ui-segmented-toggle__indicator--hidden{opacity:0}.ui-segmented-toggle__indicator--animated{transition:transform .2s ease,width .2s ease,opacity .2s ease}.ui-segmented-toggle__option{--cnp-icon-color: #242424;position:relative;z-index:1;display:inline-flex;flex:0 0 auto;gap:4px;align-items:center;justify-content:center;margin:0;padding:3px 16px;border:0;border-radius:999px;background:transparent;color:#242424;font:inherit;white-space:nowrap;cursor:pointer;transition:transform .1s ease}.ui-segmented-toggle__option:hover:not(:disabled,[aria-pressed=true]){background:#f4f4f4}.ui-segmented-toggle__option:active:not(:disabled,[aria-pressed=true]){transform:scale(.97)}.ui-segmented-toggle__option:focus-visible{outline:2px solid #242424;outline-offset:-2px}.ui-segmented-toggle__option[aria-pressed=true]:focus-visible{outline-color:#919191}.ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #ffffff;color:#fff}.ui-segmented-toggle__option[aria-pressed=true] .ui-segmented-toggle__label{font-weight:700}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__indicator{background:#d410aa}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__option[aria-pressed=true]:focus-visible{outline-color:#fff}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #ffe6fa;color:#ffe6fa}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__group{box-shadow:inset 0 0 0 1px #919191}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__indicator{background:#e9e9e9}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__option,:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #919191;color:#919191;cursor:not-allowed}.ui-segmented-toggle__skeleton{display:inline-flex;align-items:center;line-height:0}.ui-segmented-toggle__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(prefers-reduced-motion:reduce){.ui-segmented-toggle__indicator--animated,.ui-segmented-toggle__option{transition:none}.ui-segmented-toggle__option:active:not(:disabled,[aria-pressed=true]){transform:none}}\n"], dependencies: [{ kind: "ngmodule", type: IconComponentModule }, { kind: "component", type: i1.IconComponent, selector: "ui-icon", inputs: ["size", "cssClass", "name", "color", "filled", "toggleIconStyle", "applicationTheme", "useFullIconName"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: SkeletonComponent, selector: "ui-skeleton", inputs: ["count", "theme", "appearance", "isAiTheme", "applicationTheme"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
133
- }
134
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: SegmentedToggleComponent, decorators: [{
135
- type: Component,
136
- args: [{ selector: 'ui-segmented-toggle', standalone: true, imports: [IconComponentModule, MatTooltip, SkeletonComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
137
- '[attr.theme]': 'theme()',
138
- '[class.ui-segmented-toggle--brand-active]': 'selectedOptionIsBrand()',
139
- '[class.ui-segmented-toggle--disabled]': 'disabled()',
140
- }, template: "<div\n class=\"ui-segmented-toggle__group\"\n role=\"group\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <span\n class=\"ui-segmented-toggle__indicator\"\n [class.ui-segmented-toggle__indicator--hidden]=\"selectedIndex() < 0\"\n [class.ui-segmented-toggle__indicator--animated]=\"animated()\"\n aria-hidden=\"true\"\n [style.transform]=\"'translateX(' + indicatorOffset() + 'px) translateY(' + indicatorTop() + 'px)'\"\n [style.width.px]=\"indicatorWidth()\"\n [style.height.px]=\"indicatorHeight()\"\n ></span>\n\n @for (option of options(); track option.value) {\n <button\n #optionButton\n type=\"button\"\n class=\"ui-segmented-toggle__option\"\n [attr.aria-pressed]=\"isSelected(option.value)\"\n [attr.aria-label]=\"fallbackAriaLabel(option)\"\n [disabled]=\"disabled()\"\n [matTooltip]=\"option.tooltip ?? ''\"\n [matTooltipPosition]=\"tooltipPosition(option)\"\n [matTooltipClass]=\"theme()\"\n [attr.data-testid]=\"optionTestId(option)\"\n (click)=\"select(option.value)\"\n >\n @if (option.icon) {\n <ui-icon\n class=\"ui-segmented-toggle__icon\"\n [name]=\"option.icon\"\n size=\"16\"\n [attr.aria-hidden]=\"option.iconAriaLabel ? null : 'true'\"\n ></ui-icon>\n @if (option.iconAriaLabel) {\n <span class=\"ui-segmented-toggle__sr-only\">{{ option.iconAriaLabel }}</span>\n }\n }\n @if (option.label) {\n <span class=\"ui-segmented-toggle__label\">{{ option.label }}</span>\n }\n @if (loading()) {\n <span class=\"ui-segmented-toggle__skeleton\" aria-hidden=\"true\">\n <ui-skeleton [theme]=\"skeletonTheme\" [applicationTheme]=\"theme()\"></ui-skeleton>\n </span>\n } @else if (option.count !== undefined) {\n <span class=\"ui-segmented-toggle__count\">{{ option.count }}</span>\n }\n </button>\n }\n</div>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{display:inline-flex}.ui-segmented-toggle__group{position:relative;display:flex;align-items:center;gap:0;padding:4px;box-shadow:inset 0 0 0 1px #242424;border-radius:999px;background:#fff}.ui-segmented-toggle__indicator{position:absolute;top:0;left:0;z-index:0;border-radius:999px;background:#242424}.ui-segmented-toggle__indicator--hidden{opacity:0}.ui-segmented-toggle__indicator--animated{transition:transform .2s ease,width .2s ease,opacity .2s ease}.ui-segmented-toggle__option{--cnp-icon-color: #242424;position:relative;z-index:1;display:inline-flex;flex:0 0 auto;gap:4px;align-items:center;justify-content:center;margin:0;padding:3px 16px;border:0;border-radius:999px;background:transparent;color:#242424;font:inherit;white-space:nowrap;cursor:pointer;transition:transform .1s ease}.ui-segmented-toggle__option:hover:not(:disabled,[aria-pressed=true]){background:#f4f4f4}.ui-segmented-toggle__option:active:not(:disabled,[aria-pressed=true]){transform:scale(.97)}.ui-segmented-toggle__option:focus-visible{outline:2px solid #242424;outline-offset:-2px}.ui-segmented-toggle__option[aria-pressed=true]:focus-visible{outline-color:#919191}.ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #ffffff;color:#fff}.ui-segmented-toggle__option[aria-pressed=true] .ui-segmented-toggle__label{font-weight:700}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__indicator{background:#d410aa}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__option[aria-pressed=true]:focus-visible{outline-color:#fff}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #ffe6fa;color:#ffe6fa}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__group{box-shadow:inset 0 0 0 1px #919191}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__indicator{background:#e9e9e9}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__option,:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #919191;color:#919191;cursor:not-allowed}.ui-segmented-toggle__skeleton{display:inline-flex;align-items:center;line-height:0}.ui-segmented-toggle__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(prefers-reduced-motion:reduce){.ui-segmented-toggle__indicator--animated,.ui-segmented-toggle__option{transition:none}.ui-segmented-toggle__option:active:not(:disabled,[aria-pressed=true]){transform:none}}\n"] }]
141
- }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }], applicationTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "applicationTheme", required: false }] }], optionButtons: [{ type: i0.ViewChildren, args: ['optionButton', { isSignal: true }] }] } });
142
-
143
- /**
144
- * Generated bundle index. Do not edit.
145
- */
146
-
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, afterNextRender, afterRenderEffect, booleanAttribute, computed, inject, input, model, signal, viewChildren } from "@angular/core";
3
+ import { MatTooltip } from "@angular/material/tooltip";
4
+ import * as i1 from "@testgorilla/tgo-ui/components/icon";
5
+ import { IconComponentModule } from "@testgorilla/tgo-ui/components/icon";
6
+ import { SkeletonComponent } from "@testgorilla/tgo-ui/components/skeleton";
7
+ import { TooltipPositionType } from "@testgorilla/tgo-ui/components/tooltip";
8
+ var SegmentedToggleComponent = class SegmentedToggleComponent {
9
+ constructor() {
10
+ this.hostRef = inject(ElementRef);
11
+ this.destroyRef = inject(DestroyRef);
12
+ this.options = input.required(...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
13
+ this.value = model(...ngDevMode ? [void 0, { debugName: "value" }] : /* istanbul ignore next */ []);
14
+ this.disabled = input(false, {
15
+ ...ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {},
16
+ transform: booleanAttribute
17
+ });
18
+ this.loading = input(false, {
19
+ ...ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {},
20
+ transform: booleanAttribute
21
+ });
22
+ this.ariaLabel = input(...ngDevMode ? [void 0, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
23
+ this.testId = input(null, ...ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []);
24
+ this.applicationTheme = input(void 0, ...ngDevMode ? [{ debugName: "applicationTheme" }] : /* istanbul ignore next */ []);
25
+ this.defaultAppTheme = inject("CANOPYUI_DEFAULT_APPLICATION_THEME", { optional: true });
26
+ this.theme = computed(() => this.applicationTheme() ?? this.defaultAppTheme ?? "light", ...ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []);
27
+ this.skeletonTheme = {
28
+ "background-color": "color-mix(in srgb, currentColor 20%, transparent)",
29
+ width: "16px",
30
+ height: "12px",
31
+ margin: "0",
32
+ "border-radius": "999px",
33
+ "vertical-align": "middle"
34
+ };
35
+ this.optionButtons = viewChildren("optionButton", ...ngDevMode ? [{ debugName: "optionButtons" }] : /* istanbul ignore next */ []);
36
+ this.selectedIndex = computed(() => this.options().findIndex((option) => option.value === this.value()), ...ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []);
37
+ this.selectedOptionIsBrand = computed(() => this.options()[this.selectedIndex()]?.brand === true, ...ngDevMode ? [{ debugName: "selectedOptionIsBrand" }] : /* istanbul ignore next */ []);
38
+ this.indicatorOffset = signal(0, ...ngDevMode ? [{ debugName: "indicatorOffset" }] : /* istanbul ignore next */ []);
39
+ this.indicatorTop = signal(0, ...ngDevMode ? [{ debugName: "indicatorTop" }] : /* istanbul ignore next */ []);
40
+ this.indicatorWidth = signal(0, ...ngDevMode ? [{ debugName: "indicatorWidth" }] : /* istanbul ignore next */ []);
41
+ this.indicatorHeight = signal(0, ...ngDevMode ? [{ debugName: "indicatorHeight" }] : /* istanbul ignore next */ []);
42
+ this.animated = signal(false, ...ngDevMode ? [{ debugName: "animated" }] : /* istanbul ignore next */ []);
43
+ afterRenderEffect(() => {
44
+ this.value();
45
+ this.options();
46
+ this.measureIndicator();
47
+ });
48
+ afterNextRender(() => {
49
+ this.measureIndicator();
50
+ requestAnimationFrame(() => this.animated.set(true));
51
+ if (typeof ResizeObserver === "undefined") return;
52
+ const observer = new ResizeObserver(() => this.measureIndicator());
53
+ observer.observe(this.hostRef.nativeElement);
54
+ this.destroyRef.onDestroy(() => observer.disconnect());
55
+ });
56
+ }
57
+ select(optionValue) {
58
+ if (this.disabled()) return;
59
+ this.value.set(optionValue);
60
+ }
61
+ isSelected(optionValue) {
62
+ return optionValue === this.value();
63
+ }
64
+ fallbackAriaLabel(option) {
65
+ if (option.label || option.iconAriaLabel) return null;
66
+ const name = String(option.value);
67
+ return option.count !== void 0 && !this.loading() ? `${name} ${option.count}` : name;
68
+ }
69
+ optionTestId(option) {
70
+ if (option.testId) return option.testId;
71
+ const testId = this.testId();
72
+ return testId ? `${testId}-${String(option.value)}` : null;
73
+ }
74
+ tooltipPosition(option) {
75
+ switch (option.tooltipPosition ?? TooltipPositionType.TOP) {
76
+ case TooltipPositionType.BOTTOM: return "below";
77
+ case TooltipPositionType.LEFT: return "left";
78
+ case TooltipPositionType.RIGHT: return "right";
79
+ case TooltipPositionType.TOP: return "above";
80
+ }
81
+ }
82
+ measureIndicator() {
83
+ const button = this.optionButtons()[this.selectedIndex()]?.nativeElement;
84
+ if (!button) return;
85
+ this.indicatorOffset.set(button.offsetLeft);
86
+ this.indicatorTop.set(button.offsetTop);
87
+ this.indicatorWidth.set(button.offsetWidth);
88
+ this.indicatorHeight.set(button.offsetHeight);
89
+ }
90
+ static {
91
+ this.ɵfac = i0.ɵɵngDeclareFactory({
92
+ minVersion: "12.0.0",
93
+ version: "22.2.4",
94
+ ngImport: i0,
95
+ type: SegmentedToggleComponent,
96
+ deps: [],
97
+ target: i0.ɵɵFactoryTarget.Component
98
+ });
99
+ }
100
+ static {
101
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
102
+ minVersion: "17.0.0",
103
+ version: "22.2.4",
104
+ type: SegmentedToggleComponent,
105
+ isStandalone: true,
106
+ selector: "ui-segmented-toggle",
107
+ inputs: {
108
+ options: {
109
+ classPropertyName: "options",
110
+ publicName: "options",
111
+ isSignal: true,
112
+ isRequired: true,
113
+ transformFunction: null
114
+ },
115
+ value: {
116
+ classPropertyName: "value",
117
+ publicName: "value",
118
+ isSignal: true,
119
+ isRequired: false,
120
+ transformFunction: null
121
+ },
122
+ disabled: {
123
+ classPropertyName: "disabled",
124
+ publicName: "disabled",
125
+ isSignal: true,
126
+ isRequired: false,
127
+ transformFunction: null
128
+ },
129
+ loading: {
130
+ classPropertyName: "loading",
131
+ publicName: "loading",
132
+ isSignal: true,
133
+ isRequired: false,
134
+ transformFunction: null
135
+ },
136
+ ariaLabel: {
137
+ classPropertyName: "ariaLabel",
138
+ publicName: "ariaLabel",
139
+ isSignal: true,
140
+ isRequired: false,
141
+ transformFunction: null
142
+ },
143
+ testId: {
144
+ classPropertyName: "testId",
145
+ publicName: "testId",
146
+ isSignal: true,
147
+ isRequired: false,
148
+ transformFunction: null
149
+ },
150
+ applicationTheme: {
151
+ classPropertyName: "applicationTheme",
152
+ publicName: "applicationTheme",
153
+ isSignal: true,
154
+ isRequired: false,
155
+ transformFunction: null
156
+ }
157
+ },
158
+ outputs: { value: "valueChange" },
159
+ host: { properties: {
160
+ "attr.theme": "theme()",
161
+ "class.ui-segmented-toggle--brand-active": "selectedOptionIsBrand()",
162
+ "class.ui-segmented-toggle--disabled": "disabled()"
163
+ } },
164
+ viewQueries: [{
165
+ propertyName: "optionButtons",
166
+ predicate: ["optionButton"],
167
+ descendants: true,
168
+ isSignal: true
169
+ }],
170
+ ngImport: i0,
171
+ template: "<div\n class=\"ui-segmented-toggle__group\"\n role=\"group\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <span\n class=\"ui-segmented-toggle__indicator\"\n [class.ui-segmented-toggle__indicator--hidden]=\"selectedIndex() < 0\"\n [class.ui-segmented-toggle__indicator--animated]=\"animated()\"\n aria-hidden=\"true\"\n [style.transform]=\"'translateX(' + indicatorOffset() + 'px) translateY(' + indicatorTop() + 'px)'\"\n [style.width.px]=\"indicatorWidth()\"\n [style.height.px]=\"indicatorHeight()\"\n ></span>\n\n @for (option of options(); track option.value) {\n <button\n #optionButton\n type=\"button\"\n class=\"ui-segmented-toggle__option\"\n [attr.aria-pressed]=\"isSelected(option.value)\"\n [attr.aria-label]=\"fallbackAriaLabel(option)\"\n [disabled]=\"disabled()\"\n [matTooltip]=\"option.tooltip ?? ''\"\n [matTooltipPosition]=\"tooltipPosition(option)\"\n [matTooltipClass]=\"theme()\"\n [attr.data-testid]=\"optionTestId(option)\"\n (click)=\"select(option.value)\"\n >\n @if (option.icon) {\n <ui-icon\n class=\"ui-segmented-toggle__icon\"\n [name]=\"option.icon\"\n size=\"16\"\n [attr.aria-hidden]=\"option.iconAriaLabel ? null : 'true'\"\n ></ui-icon>\n @if (option.iconAriaLabel) {\n <span class=\"ui-segmented-toggle__sr-only\">{{ option.iconAriaLabel }}</span>\n }\n }\n @if (option.label) {\n <span class=\"ui-segmented-toggle__label\">{{ option.label }}</span>\n }\n @if (loading()) {\n <span class=\"ui-segmented-toggle__skeleton\" aria-hidden=\"true\">\n <ui-skeleton [theme]=\"skeletonTheme\" [applicationTheme]=\"theme()\"></ui-skeleton>\n </span>\n } @else if (option.count !== undefined) {\n <span class=\"ui-segmented-toggle__count\">{{ option.count }}</span>\n }\n </button>\n }\n</div>\n",
172
+ styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{display:inline-flex}.ui-segmented-toggle__group{position:relative;display:flex;align-items:center;gap:0;padding:4px;box-shadow:inset 0 0 0 1px #242424;border-radius:999px;background:#fff}.ui-segmented-toggle__indicator{position:absolute;top:0;left:0;z-index:0;border-radius:999px;background:#242424}.ui-segmented-toggle__indicator--hidden{opacity:0}.ui-segmented-toggle__indicator--animated{transition:transform .2s ease,width .2s ease,opacity .2s ease}.ui-segmented-toggle__option{--cnp-icon-color: #242424;position:relative;z-index:1;display:inline-flex;flex:0 0 auto;gap:4px;align-items:center;justify-content:center;margin:0;padding:3px 16px;border:0;border-radius:999px;background:transparent;color:#242424;font:inherit;white-space:nowrap;cursor:pointer;transition:transform .1s ease}.ui-segmented-toggle__option:hover:not(:disabled,[aria-pressed=true]){background:#f4f4f4}.ui-segmented-toggle__option:active:not(:disabled,[aria-pressed=true]){transform:scale(.97)}.ui-segmented-toggle__option:focus-visible{outline:2px solid #242424;outline-offset:-2px}.ui-segmented-toggle__option[aria-pressed=true]:focus-visible{outline-color:#919191}.ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #ffffff;color:#fff}.ui-segmented-toggle__option[aria-pressed=true] .ui-segmented-toggle__label{font-weight:700}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__indicator{background:#d410aa}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__option[aria-pressed=true]:focus-visible{outline-color:#fff}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #ffe6fa;color:#ffe6fa}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__group{box-shadow:inset 0 0 0 1px #919191}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__indicator{background:#e9e9e9}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__option,:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #919191;color:#919191;cursor:not-allowed}.ui-segmented-toggle__skeleton{display:inline-flex;align-items:center;line-height:0}.ui-segmented-toggle__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(prefers-reduced-motion:reduce){.ui-segmented-toggle__indicator--animated,.ui-segmented-toggle__option{transition:none}.ui-segmented-toggle__option:active:not(:disabled,[aria-pressed=true]){transform:none}}\n"],
173
+ dependencies: [
174
+ {
175
+ kind: "ngmodule",
176
+ type: IconComponentModule
177
+ },
178
+ {
179
+ kind: "component",
180
+ type: i1.IconComponent,
181
+ selector: "ui-icon",
182
+ inputs: [
183
+ "size",
184
+ "cssClass",
185
+ "name",
186
+ "color",
187
+ "filled",
188
+ "toggleIconStyle",
189
+ "applicationTheme",
190
+ "useFullIconName"
191
+ ]
192
+ },
193
+ {
194
+ kind: "directive",
195
+ type: MatTooltip,
196
+ selector: "[matTooltip]",
197
+ inputs: [
198
+ "matTooltipPosition",
199
+ "matTooltipPositionAtOrigin",
200
+ "matTooltipDisabled",
201
+ "matTooltipShowDelay",
202
+ "matTooltipHideDelay",
203
+ "matTooltipTouchGestures",
204
+ "matTooltip",
205
+ "matTooltipClass"
206
+ ],
207
+ exportAs: ["matTooltip"]
208
+ },
209
+ {
210
+ kind: "component",
211
+ type: SkeletonComponent,
212
+ selector: "ui-skeleton",
213
+ inputs: [
214
+ "count",
215
+ "theme",
216
+ "appearance",
217
+ "isAiTheme",
218
+ "applicationTheme"
219
+ ]
220
+ }
221
+ ],
222
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
223
+ });
224
+ }
225
+ };
226
+ i0.ɵɵngDeclareClassMetadata({
227
+ minVersion: "12.0.0",
228
+ version: "22.2.4",
229
+ ngImport: i0,
230
+ type: SegmentedToggleComponent,
231
+ decorators: [{
232
+ type: Component,
233
+ args: [{
234
+ selector: "ui-segmented-toggle",
235
+ standalone: true,
236
+ imports: [
237
+ IconComponentModule,
238
+ MatTooltip,
239
+ SkeletonComponent
240
+ ],
241
+ changeDetection: ChangeDetectionStrategy.OnPush,
242
+ host: {
243
+ "[attr.theme]": "theme()",
244
+ "[class.ui-segmented-toggle--brand-active]": "selectedOptionIsBrand()",
245
+ "[class.ui-segmented-toggle--disabled]": "disabled()"
246
+ },
247
+ template: "<div\n class=\"ui-segmented-toggle__group\"\n role=\"group\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <span\n class=\"ui-segmented-toggle__indicator\"\n [class.ui-segmented-toggle__indicator--hidden]=\"selectedIndex() < 0\"\n [class.ui-segmented-toggle__indicator--animated]=\"animated()\"\n aria-hidden=\"true\"\n [style.transform]=\"'translateX(' + indicatorOffset() + 'px) translateY(' + indicatorTop() + 'px)'\"\n [style.width.px]=\"indicatorWidth()\"\n [style.height.px]=\"indicatorHeight()\"\n ></span>\n\n @for (option of options(); track option.value) {\n <button\n #optionButton\n type=\"button\"\n class=\"ui-segmented-toggle__option\"\n [attr.aria-pressed]=\"isSelected(option.value)\"\n [attr.aria-label]=\"fallbackAriaLabel(option)\"\n [disabled]=\"disabled()\"\n [matTooltip]=\"option.tooltip ?? ''\"\n [matTooltipPosition]=\"tooltipPosition(option)\"\n [matTooltipClass]=\"theme()\"\n [attr.data-testid]=\"optionTestId(option)\"\n (click)=\"select(option.value)\"\n >\n @if (option.icon) {\n <ui-icon\n class=\"ui-segmented-toggle__icon\"\n [name]=\"option.icon\"\n size=\"16\"\n [attr.aria-hidden]=\"option.iconAriaLabel ? null : 'true'\"\n ></ui-icon>\n @if (option.iconAriaLabel) {\n <span class=\"ui-segmented-toggle__sr-only\">{{ option.iconAriaLabel }}</span>\n }\n }\n @if (option.label) {\n <span class=\"ui-segmented-toggle__label\">{{ option.label }}</span>\n }\n @if (loading()) {\n <span class=\"ui-segmented-toggle__skeleton\" aria-hidden=\"true\">\n <ui-skeleton [theme]=\"skeletonTheme\" [applicationTheme]=\"theme()\"></ui-skeleton>\n </span>\n } @else if (option.count !== undefined) {\n <span class=\"ui-segmented-toggle__count\">{{ option.count }}</span>\n }\n </button>\n }\n</div>\n",
248
+ styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{display:inline-flex}.ui-segmented-toggle__group{position:relative;display:flex;align-items:center;gap:0;padding:4px;box-shadow:inset 0 0 0 1px #242424;border-radius:999px;background:#fff}.ui-segmented-toggle__indicator{position:absolute;top:0;left:0;z-index:0;border-radius:999px;background:#242424}.ui-segmented-toggle__indicator--hidden{opacity:0}.ui-segmented-toggle__indicator--animated{transition:transform .2s ease,width .2s ease,opacity .2s ease}.ui-segmented-toggle__option{--cnp-icon-color: #242424;position:relative;z-index:1;display:inline-flex;flex:0 0 auto;gap:4px;align-items:center;justify-content:center;margin:0;padding:3px 16px;border:0;border-radius:999px;background:transparent;color:#242424;font:inherit;white-space:nowrap;cursor:pointer;transition:transform .1s ease}.ui-segmented-toggle__option:hover:not(:disabled,[aria-pressed=true]){background:#f4f4f4}.ui-segmented-toggle__option:active:not(:disabled,[aria-pressed=true]){transform:scale(.97)}.ui-segmented-toggle__option:focus-visible{outline:2px solid #242424;outline-offset:-2px}.ui-segmented-toggle__option[aria-pressed=true]:focus-visible{outline-color:#919191}.ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #ffffff;color:#fff}.ui-segmented-toggle__option[aria-pressed=true] .ui-segmented-toggle__label{font-weight:700}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__indicator{background:#d410aa}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__option[aria-pressed=true]:focus-visible{outline-color:#fff}:host(.ui-segmented-toggle--brand-active) .ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #ffe6fa;color:#ffe6fa}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__group{box-shadow:inset 0 0 0 1px #919191}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__indicator{background:#e9e9e9}:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__option,:host(.ui-segmented-toggle--disabled) .ui-segmented-toggle__option[aria-pressed=true]{--cnp-icon-color: #919191;color:#919191;cursor:not-allowed}.ui-segmented-toggle__skeleton{display:inline-flex;align-items:center;line-height:0}.ui-segmented-toggle__sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}@media(prefers-reduced-motion:reduce){.ui-segmented-toggle__indicator--animated,.ui-segmented-toggle__option{transition:none}.ui-segmented-toggle__option:active:not(:disabled,[aria-pressed=true]){transform:none}}\n"]
249
+ }]
250
+ }],
251
+ ctorParameters: () => [],
252
+ propDecorators: {
253
+ options: [{
254
+ type: i0.Input,
255
+ args: [{
256
+ isSignal: true,
257
+ alias: "options",
258
+ required: true
259
+ }]
260
+ }],
261
+ value: [{
262
+ type: i0.Input,
263
+ args: [{
264
+ isSignal: true,
265
+ alias: "value",
266
+ required: false
267
+ }]
268
+ }, {
269
+ type: i0.Output,
270
+ args: ["valueChange"]
271
+ }],
272
+ disabled: [{
273
+ type: i0.Input,
274
+ args: [{
275
+ isSignal: true,
276
+ alias: "disabled",
277
+ required: false
278
+ }]
279
+ }],
280
+ loading: [{
281
+ type: i0.Input,
282
+ args: [{
283
+ isSignal: true,
284
+ alias: "loading",
285
+ required: false
286
+ }]
287
+ }],
288
+ ariaLabel: [{
289
+ type: i0.Input,
290
+ args: [{
291
+ isSignal: true,
292
+ alias: "ariaLabel",
293
+ required: false
294
+ }]
295
+ }],
296
+ testId: [{
297
+ type: i0.Input,
298
+ args: [{
299
+ isSignal: true,
300
+ alias: "testId",
301
+ required: false
302
+ }]
303
+ }],
304
+ applicationTheme: [{
305
+ type: i0.Input,
306
+ args: [{
307
+ isSignal: true,
308
+ alias: "applicationTheme",
309
+ required: false
310
+ }]
311
+ }],
312
+ optionButtons: [{
313
+ type: i0.ViewChildren,
314
+ args: ["optionButton", { isSignal: true }]
315
+ }]
316
+ }
317
+ });
147
318
  export { SegmentedToggleComponent };
148
- //# sourceMappingURL=testgorilla-tgo-ui-components-segmented-toggle.mjs.map
319
+
320
+ //# sourceMappingURL=testgorilla-tgo-ui-components-segmented-toggle.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"testgorilla-tgo-ui-components-segmented-toggle.mjs","sources":["../../../components/segmented-toggle/segmented-toggle.component.ts","../../../components/segmented-toggle/segmented-toggle.component.html","../../../components/segmented-toggle/testgorilla-tgo-ui-components-segmented-toggle.ts"],"sourcesContent":["import {\n afterNextRender,\n afterRenderEffect,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n model,\n signal,\n viewChildren,\n} from '@angular/core';\nimport { MatTooltip, TooltipPosition } from '@angular/material/tooltip';\n\nimport { ApplicationTheme } from '@testgorilla/tgo-ui/components/core';\nimport { IconComponentModule } from '@testgorilla/tgo-ui/components/icon';\nimport { SkeletonComponent } from '@testgorilla/tgo-ui/components/skeleton';\nimport { TooltipPositionType } from '@testgorilla/tgo-ui/components/tooltip';\n\nimport { SegmentedToggleOption } from './segmented-toggle.model';\n\n@Component({\n selector: 'ui-segmented-toggle',\n standalone: true,\n imports: [IconComponentModule, MatTooltip, SkeletonComponent],\n templateUrl: './segmented-toggle.component.html',\n styleUrls: ['./segmented-toggle.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.theme]': 'theme()',\n '[class.ui-segmented-toggle--brand-active]': 'selectedOptionIsBrand()',\n '[class.ui-segmented-toggle--disabled]': 'disabled()',\n },\n})\nexport class SegmentedToggleComponent<T> {\n private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n\n readonly options = input.required<SegmentedToggleOption<T>[]>();\n readonly value = model<T>();\n readonly disabled = input(false, { transform: booleanAttribute });\n /**\n * Shows a small skeleton to the right of each option's content, in place of\n * its `count`, while the quantities are being fetched. Segments stay selectable.\n */\n readonly loading = input(false, { transform: booleanAttribute });\n readonly ariaLabel = input<string>();\n\n readonly testId = input<string | null>(null);\n readonly applicationTheme = input<ApplicationTheme | undefined>(undefined);\n private readonly defaultAppTheme = inject<ApplicationTheme>('CANOPYUI_DEFAULT_APPLICATION_THEME' as never, {\n optional: true,\n });\n readonly theme = computed<ApplicationTheme>(() => this.applicationTheme() ?? this.defaultAppTheme ?? 'light');\n\n /**\n * Pill-shaped placeholder sized to a short count next to a 16px icon/label.\n * Tinted from the segment's text colour so it follows every state (unselected,\n * selected, brand, disabled); the library's fixed light grey vanishes on white\n * and glares on the black pill.\n */\n protected readonly skeletonTheme = {\n 'background-color': 'color-mix(in srgb, currentColor 20%, transparent)',\n width: '16px',\n height: '12px',\n margin: '0',\n 'border-radius': '999px',\n 'vertical-align': 'middle',\n };\n\n /** One ElementRef per segment button; used to measure the active pill geometry. */\n private readonly optionButtons = viewChildren<ElementRef<HTMLButtonElement>>('optionButton');\n\n /** Index of the selected option; -1 when value() matches no option. */\n protected readonly selectedIndex = computed(() => this.options().findIndex(option => option.value === this.value()));\n\n /** True when the currently-selected option is flagged `brand: true`. */\n protected readonly selectedOptionIsBrand = computed(() => this.options()[this.selectedIndex()]?.brand === true);\n\n /** Measured pixel geometry of the active button, driving the sliding indicator. */\n protected readonly indicatorOffset = signal(0);\n protected readonly indicatorTop = signal(0);\n protected readonly indicatorWidth = signal(0);\n protected readonly indicatorHeight = signal(0);\n\n /** Enables the slide transition only after the initial position is painted. */\n protected readonly animated = signal(false);\n\n constructor() {\n // Re-measure after every render that follows a selection or options change.\n afterRenderEffect(() => {\n // Read these so the effect re-runs (post-render) whenever selection changes.\n this.value();\n this.options();\n this.measureIndicator();\n });\n\n // Re-measure on container resize (width changes don't touch any signal).\n afterNextRender(() => {\n // Position the indicator for the initial selection without animating, then\n // enable the slide on the next frame so only user-driven changes animate.\n this.measureIndicator();\n requestAnimationFrame(() => this.animated.set(true));\n\n if (typeof ResizeObserver === 'undefined') {\n return;\n }\n const observer = new ResizeObserver(() => this.measureIndicator());\n observer.observe(this.hostRef.nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n protected select(optionValue: T): void {\n if (this.disabled()) {\n return;\n }\n this.value.set(optionValue);\n }\n\n protected isSelected(optionValue: T): boolean {\n return optionValue === this.value();\n }\n\n /**\n * Last-resort accessible name for a segment. Used only for an icon-only option\n * that provides neither a visible `label` nor an `iconAriaLabel`, so the button\n * is never a nameless control. When a label or icon label is present those name\n * the button and this returns `null` (no `aria-label` attribute). The `aria-label`\n * replaces the button's content as its name, so a visible `count` is appended\n * here or it would never be announced.\n */\n protected fallbackAriaLabel(option: SegmentedToggleOption<T>): string | null {\n if (option.label || option.iconAriaLabel) {\n return null;\n }\n const name = String(option.value);\n return option.count !== undefined && !this.loading() ? `${name} ${option.count}` : name;\n }\n\n protected optionTestId(option: SegmentedToggleOption<T>): string | null {\n if (option.testId) {\n return option.testId;\n }\n const testId = this.testId();\n return testId ? `${testId}-${String(option.value)}` : null;\n }\n\n /** Maps the option's Canopy tooltip position (default TOP) to the MatTooltip position. */\n protected tooltipPosition(option: SegmentedToggleOption<T>): TooltipPosition {\n switch (option.tooltipPosition ?? TooltipPositionType.TOP) {\n case TooltipPositionType.BOTTOM:\n return 'below';\n case TooltipPositionType.LEFT:\n return 'left';\n case TooltipPositionType.RIGHT:\n return 'right';\n case TooltipPositionType.TOP:\n return 'above';\n }\n }\n\n /** Reads the active button's box and writes it to the indicator signals. */\n private measureIndicator(): void {\n const button = this.optionButtons()[this.selectedIndex()]?.nativeElement;\n if (!button) {\n return;\n }\n this.indicatorOffset.set(button.offsetLeft);\n this.indicatorTop.set(button.offsetTop);\n this.indicatorWidth.set(button.offsetWidth);\n this.indicatorHeight.set(button.offsetHeight);\n }\n}\n","<div\n class=\"ui-segmented-toggle__group\"\n role=\"group\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <span\n class=\"ui-segmented-toggle__indicator\"\n [class.ui-segmented-toggle__indicator--hidden]=\"selectedIndex() < 0\"\n [class.ui-segmented-toggle__indicator--animated]=\"animated()\"\n aria-hidden=\"true\"\n [style.transform]=\"'translateX(' + indicatorOffset() + 'px) translateY(' + indicatorTop() + 'px)'\"\n [style.width.px]=\"indicatorWidth()\"\n [style.height.px]=\"indicatorHeight()\"\n ></span>\n\n @for (option of options(); track option.value) {\n <button\n #optionButton\n type=\"button\"\n class=\"ui-segmented-toggle__option\"\n [attr.aria-pressed]=\"isSelected(option.value)\"\n [attr.aria-label]=\"fallbackAriaLabel(option)\"\n [disabled]=\"disabled()\"\n [matTooltip]=\"option.tooltip ?? ''\"\n [matTooltipPosition]=\"tooltipPosition(option)\"\n [matTooltipClass]=\"theme()\"\n [attr.data-testid]=\"optionTestId(option)\"\n (click)=\"select(option.value)\"\n >\n @if (option.icon) {\n <ui-icon\n class=\"ui-segmented-toggle__icon\"\n [name]=\"option.icon\"\n size=\"16\"\n [attr.aria-hidden]=\"option.iconAriaLabel ? null : 'true'\"\n ></ui-icon>\n @if (option.iconAriaLabel) {\n <span class=\"ui-segmented-toggle__sr-only\">{{ option.iconAriaLabel }}</span>\n }\n }\n @if (option.label) {\n <span class=\"ui-segmented-toggle__label\">{{ option.label }}</span>\n }\n @if (loading()) {\n <span class=\"ui-segmented-toggle__skeleton\" aria-hidden=\"true\">\n <ui-skeleton [theme]=\"skeletonTheme\" [applicationTheme]=\"theme()\"></ui-skeleton>\n </span>\n } @else if (option.count !== undefined) {\n <span class=\"ui-segmented-toggle__count\">{{ option.count }}</span>\n }\n </button>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testgorilla-tgo-ui-components-segmented-toggle.mjs","names":[],"sources":["../../../components/segmented-toggle/segmented-toggle.component.ts","../../../components/segmented-toggle/segmented-toggle.component.html"],"sourcesContent":["import {\n afterNextRender,\n afterRenderEffect,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n model,\n signal,\n viewChildren,\n} from '@angular/core';\nimport { MatTooltip, TooltipPosition } from '@angular/material/tooltip';\n\nimport { ApplicationTheme } from '@testgorilla/tgo-ui/components/core';\nimport { IconComponentModule } from '@testgorilla/tgo-ui/components/icon';\nimport { SkeletonComponent } from '@testgorilla/tgo-ui/components/skeleton';\nimport { TooltipPositionType } from '@testgorilla/tgo-ui/components/tooltip';\n\nimport { SegmentedToggleOption } from './segmented-toggle.model';\n\n@Component({\n selector: 'ui-segmented-toggle',\n standalone: true,\n imports: [IconComponentModule, MatTooltip, SkeletonComponent],\n templateUrl: './segmented-toggle.component.html',\n styleUrls: ['./segmented-toggle.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.theme]': 'theme()',\n '[class.ui-segmented-toggle--brand-active]': 'selectedOptionIsBrand()',\n '[class.ui-segmented-toggle--disabled]': 'disabled()',\n },\n})\nexport class SegmentedToggleComponent<T> {\n private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n\n readonly options = input.required<SegmentedToggleOption<T>[]>();\n readonly value = model<T>();\n readonly disabled = input(false, { transform: booleanAttribute });\n /**\n * Shows a small skeleton to the right of each option's content, in place of\n * its `count`, while the quantities are being fetched. Segments stay selectable.\n */\n readonly loading = input(false, { transform: booleanAttribute });\n readonly ariaLabel = input<string>();\n\n readonly testId = input<string | null>(null);\n readonly applicationTheme = input<ApplicationTheme | undefined>(undefined);\n private readonly defaultAppTheme = inject<ApplicationTheme>('CANOPYUI_DEFAULT_APPLICATION_THEME' as never, {\n optional: true,\n });\n readonly theme = computed<ApplicationTheme>(() => this.applicationTheme() ?? this.defaultAppTheme ?? 'light');\n\n /**\n * Pill-shaped placeholder sized to a short count next to a 16px icon/label.\n * Tinted from the segment's text colour so it follows every state (unselected,\n * selected, brand, disabled); the library's fixed light grey vanishes on white\n * and glares on the black pill.\n */\n protected readonly skeletonTheme = {\n 'background-color': 'color-mix(in srgb, currentColor 20%, transparent)',\n width: '16px',\n height: '12px',\n margin: '0',\n 'border-radius': '999px',\n 'vertical-align': 'middle',\n };\n\n /** One ElementRef per segment button; used to measure the active pill geometry. */\n private readonly optionButtons = viewChildren<ElementRef<HTMLButtonElement>>('optionButton');\n\n /** Index of the selected option; -1 when value() matches no option. */\n protected readonly selectedIndex = computed(() => this.options().findIndex(option => option.value === this.value()));\n\n /** True when the currently-selected option is flagged `brand: true`. */\n protected readonly selectedOptionIsBrand = computed(() => this.options()[this.selectedIndex()]?.brand === true);\n\n /** Measured pixel geometry of the active button, driving the sliding indicator. */\n protected readonly indicatorOffset = signal(0);\n protected readonly indicatorTop = signal(0);\n protected readonly indicatorWidth = signal(0);\n protected readonly indicatorHeight = signal(0);\n\n /** Enables the slide transition only after the initial position is painted. */\n protected readonly animated = signal(false);\n\n constructor() {\n // Re-measure after every render that follows a selection or options change.\n afterRenderEffect(() => {\n // Read these so the effect re-runs (post-render) whenever selection changes.\n this.value();\n this.options();\n this.measureIndicator();\n });\n\n // Re-measure on container resize (width changes don't touch any signal).\n afterNextRender(() => {\n // Position the indicator for the initial selection without animating, then\n // enable the slide on the next frame so only user-driven changes animate.\n this.measureIndicator();\n requestAnimationFrame(() => this.animated.set(true));\n\n if (typeof ResizeObserver === 'undefined') {\n return;\n }\n const observer = new ResizeObserver(() => this.measureIndicator());\n observer.observe(this.hostRef.nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n protected select(optionValue: T): void {\n if (this.disabled()) {\n return;\n }\n this.value.set(optionValue);\n }\n\n protected isSelected(optionValue: T): boolean {\n return optionValue === this.value();\n }\n\n /**\n * Last-resort accessible name for a segment. Used only for an icon-only option\n * that provides neither a visible `label` nor an `iconAriaLabel`, so the button\n * is never a nameless control. When a label or icon label is present those name\n * the button and this returns `null` (no `aria-label` attribute). The `aria-label`\n * replaces the button's content as its name, so a visible `count` is appended\n * here or it would never be announced.\n */\n protected fallbackAriaLabel(option: SegmentedToggleOption<T>): string | null {\n if (option.label || option.iconAriaLabel) {\n return null;\n }\n const name = String(option.value);\n return option.count !== undefined && !this.loading() ? `${name} ${option.count}` : name;\n }\n\n protected optionTestId(option: SegmentedToggleOption<T>): string | null {\n if (option.testId) {\n return option.testId;\n }\n const testId = this.testId();\n return testId ? `${testId}-${String(option.value)}` : null;\n }\n\n /** Maps the option's Canopy tooltip position (default TOP) to the MatTooltip position. */\n protected tooltipPosition(option: SegmentedToggleOption<T>): TooltipPosition {\n switch (option.tooltipPosition ?? TooltipPositionType.TOP) {\n case TooltipPositionType.BOTTOM:\n return 'below';\n case TooltipPositionType.LEFT:\n return 'left';\n case TooltipPositionType.RIGHT:\n return 'right';\n case TooltipPositionType.TOP:\n return 'above';\n }\n }\n\n /** Reads the active button's box and writes it to the indicator signals. */\n private measureIndicator(): void {\n const button = this.optionButtons()[this.selectedIndex()]?.nativeElement;\n if (!button) {\n return;\n }\n this.indicatorOffset.set(button.offsetLeft);\n this.indicatorTop.set(button.offsetTop);\n this.indicatorWidth.set(button.offsetWidth);\n this.indicatorHeight.set(button.offsetHeight);\n }\n}\n","<div\n class=\"ui-segmented-toggle__group\"\n role=\"group\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-busy]=\"loading() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <span\n class=\"ui-segmented-toggle__indicator\"\n [class.ui-segmented-toggle__indicator--hidden]=\"selectedIndex() < 0\"\n [class.ui-segmented-toggle__indicator--animated]=\"animated()\"\n aria-hidden=\"true\"\n [style.transform]=\"'translateX(' + indicatorOffset() + 'px) translateY(' + indicatorTop() + 'px)'\"\n [style.width.px]=\"indicatorWidth()\"\n [style.height.px]=\"indicatorHeight()\"\n ></span>\n\n @for (option of options(); track option.value) {\n <button\n #optionButton\n type=\"button\"\n class=\"ui-segmented-toggle__option\"\n [attr.aria-pressed]=\"isSelected(option.value)\"\n [attr.aria-label]=\"fallbackAriaLabel(option)\"\n [disabled]=\"disabled()\"\n [matTooltip]=\"option.tooltip ?? ''\"\n [matTooltipPosition]=\"tooltipPosition(option)\"\n [matTooltipClass]=\"theme()\"\n [attr.data-testid]=\"optionTestId(option)\"\n (click)=\"select(option.value)\"\n >\n @if (option.icon) {\n <ui-icon\n class=\"ui-segmented-toggle__icon\"\n [name]=\"option.icon\"\n size=\"16\"\n [attr.aria-hidden]=\"option.iconAriaLabel ? null : 'true'\"\n ></ui-icon>\n @if (option.iconAriaLabel) {\n <span class=\"ui-segmented-toggle__sr-only\">{{ option.iconAriaLabel }}</span>\n }\n }\n @if (option.label) {\n <span class=\"ui-segmented-toggle__label\">{{ option.label }}</span>\n }\n @if (loading()) {\n <span class=\"ui-segmented-toggle__skeleton\" aria-hidden=\"true\">\n <ui-skeleton [theme]=\"skeletonTheme\" [applicationTheme]=\"theme()\"></ui-skeleton>\n </span>\n } @else if (option.count !== undefined) {\n <span class=\"ui-segmented-toggle__count\">{{ option.count }}</span>\n }\n </button>\n }\n</div>\n"],"mappings":"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"}