@cdevhub/ngx-tw 0.5.0 → 0.6.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 (209) hide show
  1. package/README.md +78 -15
  2. package/fesm2022/cdevhub-ngx-tw-accordion.mjs +16 -5
  3. package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
  4. package/fesm2022/cdevhub-ngx-tw-avatar.mjs +26 -15
  5. package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
  6. package/fesm2022/cdevhub-ngx-tw-badge.mjs +17 -5
  7. package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
  8. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +27 -6
  9. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
  10. package/fesm2022/cdevhub-ngx-tw-button.mjs +23 -11
  11. package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
  12. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +5 -5
  13. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
  14. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs +3 -3
  15. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs.map +1 -1
  16. package/fesm2022/cdevhub-ngx-tw-calendar.mjs +427 -122
  17. package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
  18. package/fesm2022/cdevhub-ngx-tw-card.mjs +21 -11
  19. package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
  20. package/fesm2022/cdevhub-ngx-tw-carousel.mjs +215 -96
  21. package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
  22. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +108 -64
  23. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
  24. package/fesm2022/cdevhub-ngx-tw-code-block.mjs +18 -6
  25. package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
  26. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +55 -30
  27. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
  28. package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs +218 -0
  29. package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs.map +1 -0
  30. package/fesm2022/cdevhub-ngx-tw-combobox.mjs +236 -211
  31. package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
  32. package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs +200 -0
  33. package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs.map +1 -0
  34. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +34 -7
  35. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
  36. package/fesm2022/cdevhub-ngx-tw-core.mjs +135 -15
  37. package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
  38. package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs +203 -0
  39. package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs.map +1 -0
  40. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +160 -102
  41. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
  42. package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs +209 -0
  43. package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs.map +1 -0
  44. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +182 -107
  45. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
  46. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs +122 -0
  47. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs.map +1 -0
  48. package/fesm2022/cdevhub-ngx-tw-dialog.mjs +11 -2
  49. package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
  50. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +1 -1
  51. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
  52. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs +149 -0
  53. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs.map +1 -0
  54. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +57 -67
  55. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -1
  56. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +42 -24
  57. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
  58. package/fesm2022/cdevhub-ngx-tw-form-field.mjs +114 -21
  59. package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
  60. package/fesm2022/cdevhub-ngx-tw-icon.mjs +16 -6
  61. package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
  62. package/fesm2022/cdevhub-ngx-tw-input.mjs +52 -61
  63. package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
  64. package/fesm2022/cdevhub-ngx-tw-item.mjs +28 -4
  65. package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
  66. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs +168 -0
  67. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs.map +1 -0
  68. package/fesm2022/cdevhub-ngx-tw-menu.mjs +58 -21
  69. package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
  70. package/fesm2022/cdevhub-ngx-tw-number-input.mjs +34 -1
  71. package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -1
  72. package/fesm2022/cdevhub-ngx-tw-paginator.mjs +95 -45
  73. package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
  74. package/fesm2022/cdevhub-ngx-tw-popover.mjs +81 -32
  75. package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
  76. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +1 -1
  77. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
  78. package/fesm2022/cdevhub-ngx-tw-radio.mjs +131 -98
  79. package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
  80. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +207 -42
  81. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
  82. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs +165 -0
  83. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs.map +1 -0
  84. package/fesm2022/cdevhub-ngx-tw-select.mjs +386 -210
  85. package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
  86. package/fesm2022/{cdevhub-ngx-tw-sheet-sheet-renderer-ByyNluUd.mjs → cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs} +3 -3
  87. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs.map +1 -0
  88. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs +129 -0
  89. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs.map +1 -0
  90. package/fesm2022/cdevhub-ngx-tw-sheet.mjs +23 -7
  91. package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
  92. package/fesm2022/cdevhub-ngx-tw-slider.mjs +89 -54
  93. package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
  94. package/fesm2022/cdevhub-ngx-tw-sort.mjs +122 -17
  95. package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
  96. package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -19
  97. package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
  98. package/fesm2022/cdevhub-ngx-tw-stat.mjs +63 -25
  99. package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
  100. package/fesm2022/cdevhub-ngx-tw-stepper.mjs +35 -8
  101. package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
  102. package/fesm2022/cdevhub-ngx-tw-switch.mjs +54 -48
  103. package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
  104. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +12 -15
  105. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
  106. package/fesm2022/cdevhub-ngx-tw-table.mjs +74 -13
  107. package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
  108. package/fesm2022/cdevhub-ngx-tw-tabs.mjs +84 -30
  109. package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
  110. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs +172 -0
  111. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs.map +1 -0
  112. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +107 -71
  113. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -1
  114. package/fesm2022/cdevhub-ngx-tw-textarea.mjs +41 -9
  115. package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
  116. package/fesm2022/cdevhub-ngx-tw-theme.mjs +257 -45
  117. package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
  118. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs +201 -0
  119. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs.map +1 -0
  120. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +184 -77
  121. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
  122. package/fesm2022/cdevhub-ngx-tw-timeline.mjs +110 -27
  123. package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
  124. package/fesm2022/{cdevhub-ngx-tw-toast-toast-renderer-DSu4YoTy.mjs → cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs} +107 -19
  125. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs.map +1 -0
  126. package/fesm2022/cdevhub-ngx-tw-toast.mjs +21 -13
  127. package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
  128. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +102 -15
  129. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
  130. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs +219 -0
  131. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs.map +1 -0
  132. package/fesm2022/cdevhub-ngx-tw-transfer.mjs +88 -69
  133. package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -1
  134. package/fesm2022/cdevhub-ngx-tw-tree.mjs +68 -19
  135. package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -1
  136. package/index.json +1 -1
  137. package/package.json +63 -2
  138. package/theme/_base.css +13 -0
  139. package/theme/_dark.css +111 -36
  140. package/theme/_high-contrast-dark.css +367 -0
  141. package/theme/_high-contrast.css +13 -2
  142. package/theme/_light.css +332 -0
  143. package/theme/_semantic.css +60 -26
  144. package/theme/_typography.css +17 -0
  145. package/theme/index.css +86 -7
  146. package/types/cdevhub-ngx-tw-accordion.d.ts +12 -4
  147. package/types/cdevhub-ngx-tw-avatar.d.ts +10 -3
  148. package/types/cdevhub-ngx-tw-button.d.ts +1 -0
  149. package/types/cdevhub-ngx-tw-calendar-luxon.d.ts +2 -2
  150. package/types/cdevhub-ngx-tw-calendar-testing.d.ts +1 -1
  151. package/types/cdevhub-ngx-tw-calendar.d.ts +179 -73
  152. package/types/cdevhub-ngx-tw-card.d.ts +11 -3
  153. package/types/cdevhub-ngx-tw-carousel.d.ts +89 -20
  154. package/types/cdevhub-ngx-tw-checkbox.d.ts +40 -12
  155. package/types/cdevhub-ngx-tw-code-block.d.ts +11 -2
  156. package/types/cdevhub-ngx-tw-collapsible.d.ts +32 -5
  157. package/types/cdevhub-ngx-tw-combobox-testing.d.ts +157 -0
  158. package/types/cdevhub-ngx-tw-combobox.d.ts +94 -53
  159. package/types/cdevhub-ngx-tw-command-palette-testing.d.ts +136 -0
  160. package/types/cdevhub-ngx-tw-command-palette.d.ts +33 -5
  161. package/types/cdevhub-ngx-tw-core.d.ts +152 -21
  162. package/types/cdevhub-ngx-tw-date-picker-testing.d.ts +141 -0
  163. package/types/cdevhub-ngx-tw-date-picker.d.ts +37 -29
  164. package/types/cdevhub-ngx-tw-date-range-picker-testing.d.ts +148 -0
  165. package/types/cdevhub-ngx-tw-date-range-picker.d.ts +36 -29
  166. package/types/cdevhub-ngx-tw-dialog-testing.d.ts +98 -0
  167. package/types/cdevhub-ngx-tw-dialog.d.ts +12 -3
  168. package/types/cdevhub-ngx-tw-file-upload-testing.d.ts +120 -0
  169. package/types/cdevhub-ngx-tw-file-upload.d.ts +8 -10
  170. package/types/cdevhub-ngx-tw-flip-card.d.ts +18 -11
  171. package/types/cdevhub-ngx-tw-form-field.d.ts +19 -2
  172. package/types/cdevhub-ngx-tw-icon.d.ts +3 -3
  173. package/types/cdevhub-ngx-tw-input.d.ts +5 -8
  174. package/types/cdevhub-ngx-tw-item.d.ts +2 -0
  175. package/types/cdevhub-ngx-tw-menu-testing.d.ts +131 -0
  176. package/types/cdevhub-ngx-tw-menu.d.ts +2 -2
  177. package/types/cdevhub-ngx-tw-number-input.d.ts +20 -0
  178. package/types/cdevhub-ngx-tw-paginator.d.ts +58 -24
  179. package/types/cdevhub-ngx-tw-popover.d.ts +41 -10
  180. package/types/cdevhub-ngx-tw-progress-bar.d.ts +1 -1
  181. package/types/cdevhub-ngx-tw-radio.d.ts +68 -25
  182. package/types/cdevhub-ngx-tw-segmented-control.d.ts +79 -16
  183. package/types/cdevhub-ngx-tw-select-testing.d.ts +114 -0
  184. package/types/cdevhub-ngx-tw-select.d.ts +104 -33
  185. package/types/cdevhub-ngx-tw-sheet-testing.d.ts +104 -0
  186. package/types/cdevhub-ngx-tw-sheet.d.ts +19 -3
  187. package/types/cdevhub-ngx-tw-slider.d.ts +79 -25
  188. package/types/cdevhub-ngx-tw-sort.d.ts +45 -4
  189. package/types/cdevhub-ngx-tw-split.d.ts +32 -2
  190. package/types/cdevhub-ngx-tw-stat.d.ts +14 -4
  191. package/types/cdevhub-ngx-tw-stepper.d.ts +16 -2
  192. package/types/cdevhub-ngx-tw-switch.d.ts +35 -13
  193. package/types/cdevhub-ngx-tw-tab-nav.d.ts +7 -6
  194. package/types/cdevhub-ngx-tw-table.d.ts +53 -10
  195. package/types/cdevhub-ngx-tw-tabs.d.ts +41 -10
  196. package/types/cdevhub-ngx-tw-tags-input-testing.d.ts +135 -0
  197. package/types/cdevhub-ngx-tw-tags-input.d.ts +26 -11
  198. package/types/cdevhub-ngx-tw-textarea.d.ts +3 -2
  199. package/types/cdevhub-ngx-tw-theme.d.ts +245 -39
  200. package/types/cdevhub-ngx-tw-time-picker-testing.d.ts +129 -0
  201. package/types/cdevhub-ngx-tw-time-picker.d.ts +76 -19
  202. package/types/cdevhub-ngx-tw-timeline.d.ts +36 -12
  203. package/types/cdevhub-ngx-tw-toast.d.ts +20 -6
  204. package/types/cdevhub-ngx-tw-tooltip.d.ts +28 -6
  205. package/types/cdevhub-ngx-tw-transfer-testing.d.ts +152 -0
  206. package/types/cdevhub-ngx-tw-transfer.d.ts +21 -8
  207. package/types/cdevhub-ngx-tw-tree.d.ts +6 -1
  208. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-ByyNluUd.mjs.map +0 -1
  209. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-DSu4YoTy.mjs.map +0 -1
@@ -1,8 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { input, inject, ElementRef, forwardRef, isDevMode, computed, ChangeDetectionStrategy, Component, model, contentChildren, signal, linkedSignal } from '@angular/core';
3
- import { NG_VALUE_ACCESSOR } from '@angular/forms';
3
+ import { NgControl } from '@angular/forms';
4
+ import { Directionality } from '@angular/cdk/bidi';
4
5
  import { tv } from 'tailwind-variants';
6
+ import { wireErrorState } from '@cdevhub/ngx-tw/core';
5
7
 
8
+ /** Maps every legacy spelling onto its canonical replacement. */
9
+ const VARIANT_ALIASES = {
10
+ filled: 'solid',
11
+ };
6
12
  // ── tv() config ──
7
13
  // All slot styling — base, size, orientation, rounded, variant × color × active,
8
14
  // disabled — flows through this single config. Static literal class strings are
@@ -15,12 +21,16 @@ const segmentedControlVariants = tv({
15
21
  option: 'inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap cursor-pointer transition-colors duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',
16
22
  },
17
23
  variants: {
24
+ // Pinned control heights — see `docs/vertical-rhythm.md`. The option carries
25
+ // horizontal padding and font size only; the height itself is pinned in the
26
+ // orientation-keyed compound variants below, because *which box* owns the
27
+ // pin depends on the axis (root when horizontal, option when vertical).
18
28
  size: {
19
- xs: { option: 'px-2 py-1 text-xs' },
20
- sm: { option: 'px-3 py-1.5 text-sm' },
21
- md: { option: 'px-4 py-2 text-sm' },
22
- lg: { option: 'px-5 py-2.5 text-base' },
23
- xl: { option: 'px-6 py-3 text-base' },
29
+ xs: { option: 'px-2 text-xs' },
30
+ sm: { option: 'px-3 text-sm' },
31
+ md: { option: 'px-4 text-sm' },
32
+ lg: { option: 'px-5 text-base' },
33
+ xl: { option: 'px-6 text-base' },
24
34
  },
25
35
  orientation: {
26
36
  horizontal: { root: 'flex-row gap-1' },
@@ -36,7 +46,7 @@ const segmentedControlVariants = tv({
36
46
  // all active styling without per-axis defaults bleeding through.
37
47
  variant: {
38
48
  surface: {},
39
- filled: {},
49
+ solid: {},
40
50
  outline: {},
41
51
  },
42
52
  color: {
@@ -59,6 +69,36 @@ const segmentedControlVariants = tv({
59
69
  },
60
70
  },
61
71
  compoundVariants: [
72
+ // ── Pinned heights (docs/vertical-rhythm.md) ──
73
+ // Horizontal: the *root* is the single-line control, so the pin lives there.
74
+ // The `p-1` recessed track stays (it is the component's visual identity) and
75
+ // is absorbed by the pinned box under `box-sizing: border-box`; the root is
76
+ // `inline-flex` with the default `align-items: stretch`, so each option fills
77
+ // the remaining height without a pin of its own.
78
+ //
79
+ // `xs` is the exception, and it is an accessibility floor rather than a
80
+ // style choice. The option — not the root — carries `role="radio"`, the
81
+ // tabindex and the click handler, so the option IS the target. A 24px root
82
+ // minus a 4px inset per side leaves a 16px target, under the WCAG 2.2
83
+ // SC 2.5.8 (AA) 24px minimum. An inset track and a 24px target cannot both
84
+ // fit inside 24px, so at `xs` the inset is dropped: the option fills the
85
+ // full 24px and `gap-1` alone carries the track read. Widening the root to
86
+ // 32px instead would restore the inset but break the shared control height
87
+ // that lets a segmented control sit flush beside a button or input.
88
+ { orientation: 'horizontal', size: 'xs', class: { root: 'h-6 p-0' } },
89
+ { orientation: 'horizontal', size: 'sm', class: { root: 'h-8' } },
90
+ { orientation: 'horizontal', size: 'md', class: { root: 'h-9' } },
91
+ { orientation: 'horizontal', size: 'lg', class: { root: 'h-11' } },
92
+ { orientation: 'horizontal', size: 'xl', class: { root: 'h-12' } },
93
+ // Vertical: the root grows with the option count, so pinning it would crush
94
+ // the stack. Each option is its own single-line control row instead, which
95
+ // reproduces the pre-migration vertical height exactly (padding-derived
96
+ // before, declared now).
97
+ { orientation: 'vertical', size: 'xs', class: { option: 'h-6' } },
98
+ { orientation: 'vertical', size: 'sm', class: { option: 'h-8' } },
99
+ { orientation: 'vertical', size: 'md', class: { option: 'h-9' } },
100
+ { orientation: 'vertical', size: 'lg', class: { option: 'h-11' } },
101
+ { orientation: 'vertical', size: 'xl', class: { option: 'h-12' } },
62
102
  // surface × color × active=true
63
103
  { variant: 'surface', color: 'primary', active: true, class: { option: 'bg-surface shadow-sm text-primary-fg' } },
64
104
  { variant: 'surface', color: 'secondary', active: true, class: { option: 'bg-surface shadow-sm text-secondary-fg' } },
@@ -68,15 +108,15 @@ const segmentedControlVariants = tv({
68
108
  { variant: 'surface', color: 'success', active: true, class: { option: 'bg-surface shadow-sm text-success-fg' } },
69
109
  { variant: 'surface', color: 'warning', active: true, class: { option: 'bg-surface shadow-sm text-warning-fg' } },
70
110
  { variant: 'surface', color: 'error', active: true, class: { option: 'bg-surface shadow-sm text-error-fg' } },
71
- // filled × color × active=true
72
- { variant: 'filled', color: 'primary', active: true, class: { option: 'bg-primary-solid text-primary-solid-fg shadow-sm' } },
73
- { variant: 'filled', color: 'secondary', active: true, class: { option: 'bg-secondary-solid text-secondary-solid-fg shadow-sm' } },
74
- { variant: 'filled', color: 'accent', active: true, class: { option: 'bg-accent-solid text-accent-solid-fg shadow-sm' } },
75
- { variant: 'filled', color: 'neutral', active: true, class: { option: 'bg-neutral-solid text-neutral-solid-fg shadow-sm' } },
76
- { variant: 'filled', color: 'info', active: true, class: { option: 'bg-info-solid text-info-solid-fg shadow-sm' } },
77
- { variant: 'filled', color: 'success', active: true, class: { option: 'bg-success-solid text-success-solid-fg shadow-sm' } },
78
- { variant: 'filled', color: 'warning', active: true, class: { option: 'bg-warning-solid text-warning-solid-fg shadow-sm' } },
79
- { variant: 'filled', color: 'error', active: true, class: { option: 'bg-error-solid text-error-solid-fg shadow-sm' } },
111
+ // solid × color × active=true
112
+ { variant: 'solid', color: 'primary', active: true, class: { option: 'bg-primary-solid text-primary-solid-fg shadow-sm' } },
113
+ { variant: 'solid', color: 'secondary', active: true, class: { option: 'bg-secondary-solid text-secondary-solid-fg shadow-sm' } },
114
+ { variant: 'solid', color: 'accent', active: true, class: { option: 'bg-accent-solid text-accent-solid-fg shadow-sm' } },
115
+ { variant: 'solid', color: 'neutral', active: true, class: { option: 'bg-neutral-solid text-neutral-solid-fg shadow-sm' } },
116
+ { variant: 'solid', color: 'info', active: true, class: { option: 'bg-info-solid text-info-solid-fg shadow-sm' } },
117
+ { variant: 'solid', color: 'success', active: true, class: { option: 'bg-success-solid text-success-solid-fg shadow-sm' } },
118
+ { variant: 'solid', color: 'warning', active: true, class: { option: 'bg-warning-solid text-warning-solid-fg shadow-sm' } },
119
+ { variant: 'solid', color: 'error', active: true, class: { option: 'bg-error-solid text-error-solid-fg shadow-sm' } },
80
120
  // outline × color × active=true
81
121
  { variant: 'outline', color: 'primary', active: true, class: { option: 'ring-2 ring-primary-border-strong text-primary-fg' } },
82
122
  { variant: 'outline', color: 'secondary', active: true, class: { option: 'ring-2 ring-secondary-border-strong text-secondary-fg' } },
@@ -128,13 +168,17 @@ class SegmentedControlOptionComponent {
128
168
  return false;
129
169
  if (this.isActive())
130
170
  return true;
131
- // If no option is active, first non-disabled option gets focus
132
- if (this.parent?.activeValue() === null) {
133
- const opts = this.parent.options();
134
- const first = opts.find((o) => !o.isDisabled());
135
- return first?.value() === this.value();
136
- }
137
- return false;
171
+ // Roving-tabindex recovery. The fallback used to be gated on
172
+ // `activeValue() === null`, which is a strict check: `undefined`, `''`, a
173
+ // stale id, or an active option that is itself disabled all left NO
174
+ // option tabbable and dropped the whole control out of the tab order
175
+ // (WCAG SC 2.1.1). The real condition is "no enabled option is active".
176
+ const opts = this.parent?.options() ?? [];
177
+ const hasTabbableActive = opts.some((o) => o.isActive() && !o.isDisabled());
178
+ if (hasTabbableActive)
179
+ return false;
180
+ const first = opts.find((o) => !o.isDisabled());
181
+ return first?.value() === this.value();
138
182
  }, /* @ts-ignore */
139
183
  ...(ngDevMode ? [{ debugName: "isFocusable" }] : /* istanbul ignore next */ []));
140
184
  classes = computed(() => {
@@ -142,7 +186,7 @@ class SegmentedControlOptionComponent {
142
186
  size: this.parent?.size() ?? 'md',
143
187
  orientation: this.parent?.orientation() ?? 'horizontal',
144
188
  rounded: this.parent?.effectiveRounded() ?? 'pill',
145
- variant: this.parent?.variant() ?? 'surface',
189
+ variant: this.parent?.resolvedVariant() ?? 'surface',
146
190
  color: this.parent?.color() ?? 'primary',
147
191
  active: this.isActive(),
148
192
  disabled: this.isDisabled(),
@@ -150,11 +194,13 @@ class SegmentedControlOptionComponent {
150
194
  return result.option();
151
195
  }, /* @ts-ignore */
152
196
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
197
+ /** Selects this option in the parent segmented control. No-op when the option is disabled. */
153
198
  select() {
154
199
  if (this.isDisabled())
155
200
  return;
156
201
  this.parent?.selectOption(this.value());
157
202
  }
203
+ /** Moves DOM focus to this option's element. Called by the parent group's arrow-key handler, which moves focus and selection together (selection-follows-focus, as WAI-ARIA APG specifies for a radiogroup). */
158
204
  focus() {
159
205
  this.elementRef.nativeElement.focus();
160
206
  }
@@ -180,7 +226,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
180
226
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
181
227
  // ── SegmentedControlComponent ──
182
228
  class SegmentedControlComponent {
183
- /** Controls the active indicator style. `'surface'` shows a raised white pill; `'filled'` shows a solid colored background; `'outline'` shows a colored ring border. Defaults to `'surface'`. */
229
+ /** Controls the active indicator style. `'surface'` shows a raised white pill; `'solid'` shows a solid colored background; `'outline'` shows a colored ring border. Defaults to `'surface'`. `'filled'` is a deprecated alias for `'solid'`. */
184
230
  variant = input('surface', /* @ts-ignore */
185
231
  ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
186
232
  /** Sets the semantic color for the active option indicator. Defaults to `'primary'`. */
@@ -198,23 +244,86 @@ class SegmentedControlComponent {
198
244
  /** When true, prevents all interaction and applies muted styling. Defaults to `false`. */
199
245
  disabled = input(false, /* @ts-ignore */
200
246
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
201
- /** The value of the currently selected option. Two-way bound. Updates on user selection. */
247
+ /** When true, sets `aria-required="true"` on the radiogroup so assistive tech announces a choice is mandatory. Also inferred from `Validators.required` on a bound control, so a reactive/template-driven form does not have to state it twice. Defaults to `false`. */
248
+ requiredInput = input(false, { ...(ngDevMode ? { debugName: "requiredInput" } : /* istanbul ignore next */ {}), alias: 'required' });
249
+ /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the control uses the `TW_ERROR_STATE_MATCHER` token's value. */
250
+ errorStateMatcher = input(undefined, /* @ts-ignore */
251
+ ...(ngDevMode ? [{ debugName: "errorStateMatcher" }] : /* istanbul ignore next */ []));
252
+ /**
253
+ * The value of the currently selected option. Two-way bound. Defaults to
254
+ * `null`.
255
+ *
256
+ * The two-way binding mints a `valueChange` output, and it is the
257
+ * *any-change* channel: it fires on user selection **and** on a programmatic
258
+ * write from a bound form (`FormControl.setValue`, `ngModel`, `writeValue`).
259
+ * Unlike `tw-checkbox` / `tw-switch` / `tw-radio-group`, this control ships no
260
+ * separate gesture-only `change` output, so writing back into the same form
261
+ * from a `(valueChange)` handler will echo. To act on user selection alone,
262
+ * compare against the value you last wrote, or listen on the form control.
263
+ */
202
264
  value = model(null, /* @ts-ignore */
203
265
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
204
266
  /** @internal */
205
267
  options = contentChildren(SegmentedControlOptionComponent, /* @ts-ignore */
206
268
  ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
269
+ elementRef = inject((ElementRef));
270
+ ngControl = inject(NgControl, { optional: true, self: true });
271
+ /**
272
+ * Optional so a consumer that never imports `BidiModule` still gets a working
273
+ * control — arrow navigation falls back to LTR when the token is absent. Read
274
+ * imperatively inside the keydown handler; nothing here needs to re-render on
275
+ * a direction change.
276
+ */
277
+ directionality = inject(Directionality, { optional: true });
207
278
  onChange = () => { };
208
279
  onTouched = () => { };
209
280
  cvaDisabled = signal(false, /* @ts-ignore */
210
281
  ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
282
+ /** @internal Shared `errorState` / `required` / `errors` derivation — see `wireErrorState`. */
283
+ errorWiring = wireErrorState({
284
+ ngControl: () => this.ngControl,
285
+ matcher: () => this.errorStateMatcher(),
286
+ required: () => this.requiredInput(),
287
+ });
288
+ constructor() {
289
+ // Material-style CVA wiring: declare ourselves as the value accessor on any
290
+ // host-level `NgControl` (FormControlDirective, NgModel, etc.). This avoids
291
+ // the circular-DI that a static `NG_VALUE_ACCESSOR` provider would create
292
+ // because `NgControl` is injected with `self: true` on the same element.
293
+ //
294
+ // The assignment MUST stay in the constructor. This component exposes a
295
+ // `value` model(), so Angular v22 would otherwise compile it as a
296
+ // signal-forms *custom control* and skip `setUpValidators` entirely — a
297
+ // silent validator drop that no value/disabled test can catch.
298
+ if (this.ngControl) {
299
+ this.ngControl.valueAccessor = this;
300
+ }
301
+ }
211
302
  isDisabled = computed(() => this.disabled() || this.cvaDisabled(), /* @ts-ignore */
212
303
  ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
304
+ /**
305
+ * @internal Resolved required state: the `required` input OR'd with
306
+ * `Validators.required` on a bound `NgControl`. The OR (rather than a
307
+ * validator-only read) is what keeps signal forms working — `cvaControlCreate`
308
+ * writes the `required` *input* directly from the field state and never
309
+ * consults validators, so the input arm carries that branch while the
310
+ * validator arm carries reactive/template-driven forms.
311
+ */
312
+ required = this.errorWiring.required;
313
+ /** @internal Whether the control is in an error state per the configured `ErrorStateMatcher`. Reads the bound `NgControl.invalid` through the matcher and drives `aria-invalid` on the radiogroup host. */
314
+ errorState = this.errorWiring.errorState;
213
315
  activeValue = linkedSignal(() => this.value(), /* @ts-ignore */
214
316
  ...(ngDevMode ? [{ debugName: "activeValue" }] : /* istanbul ignore next */ []));
215
317
  /** @internal Read by `SegmentedControlOptionComponent.classes` to resolve the option's tv() bucket. Vertical orientation forces `'md'` regardless of input. */
216
318
  effectiveRounded = computed(() => this.orientation() === 'vertical' ? 'md' : this.rounded(), /* @ts-ignore */
217
319
  ...(ngDevMode ? [{ debugName: "effectiveRounded" }] : /* istanbul ignore next */ []));
320
+ /** @internal Canonical variant with legacy spellings folded in. Read by `SegmentedControlOptionComponent.classes` to resolve the option's tv() bucket. */
321
+ resolvedVariant = computed(() => {
322
+ const v = this.variant();
323
+ return (VARIANT_ALIASES[v] ??
324
+ v);
325
+ }, /* @ts-ignore */
326
+ ...(ngDevMode ? [{ debugName: "resolvedVariant" }] : /* istanbul ignore next */ []));
218
327
  variantResult = computed(() => segmentedControlVariants({
219
328
  size: this.size(),
220
329
  orientation: this.orientation(),
@@ -229,28 +338,81 @@ class SegmentedControlComponent {
229
338
  }, /* @ts-ignore */
230
339
  ...(ngDevMode ? [{ debugName: "rootClasses" }] : /* istanbul ignore next */ []));
231
340
  // ── Selection ──
341
+ /** Selects the option with the given value, updating the two-way bound `value` and notifying the registered `ControlValueAccessor` callbacks. No-op when the control is disabled. */
232
342
  selectOption(val) {
233
343
  if (this.isDisabled())
234
344
  return;
235
345
  this.activeValue.set(val);
236
346
  this.value.set(val);
237
347
  this.onChange(val);
348
+ // Deliberately NOT `onTouched()`. Angular's CVA contract registers
349
+ // `onTouched` as the BLUR notification; calling it on selection flipped
350
+ // `touched` with no blur, so a consumer staging error display on `touched`
351
+ // got different behaviour from `tw-segmented-control` than from
352
+ // `tw-slider` / `tw-input`. `onFocusOut()` below is the only place that
353
+ // fires it. The control's own `valueChanges`/`statusChanges` subscription
354
+ // (see `ngOnInit`) is what refreshes `errorState` after this write.
355
+ }
356
+ /**
357
+ * @internal Blur notification for the CVA contract. Fires `onTouched` only
358
+ * when focus leaves the radiogroup entirely — roving focus moves between
359
+ * option elements inside the group, and each of those hops raises `focusout`
360
+ * on the host too. Without this the control is only ever marked `touched` by
361
+ * a selection, so a user who tabs through without choosing never surfaces the
362
+ * `required` error.
363
+ */
364
+ onFocusOut(event) {
365
+ const next = event.relatedTarget;
366
+ if (next && this.elementRef.nativeElement.contains(next))
367
+ return;
238
368
  this.onTouched();
369
+ this.errorWiring.bump();
239
370
  }
240
371
  // ── Keyboard navigation ──
372
+ /** @internal Handles roving-focus keyboard navigation (Arrow keys, Home, End) and Space / Enter activation across the option group. */
241
373
  onKeydown(event) {
242
374
  const opts = this.options();
243
375
  if (opts.length === 0)
244
376
  return;
377
+ // Space activates the focused option, as WAI-ARIA requires of every
378
+ // `role="radio"`. The option host is a custom element, not a native
379
+ // control, so no click event is synthesised for us — without this branch
380
+ // selection is pointer-only (WCAG SC 2.1.1). Enter is accepted too: it
381
+ // costs nothing and matches what users expect from a button-like control.
382
+ if (event.key === ' ' || event.key === 'Spacebar' || event.key === 'Enter') {
383
+ const target = event.target;
384
+ const focused = target
385
+ ? opts.find(o => o.elementRef.nativeElement.contains(target))
386
+ : undefined;
387
+ if (focused && !focused.isDisabled()) {
388
+ // Space would otherwise scroll the page.
389
+ event.preventDefault();
390
+ this.selectOption(focused.value());
391
+ }
392
+ return;
393
+ }
245
394
  let targetIndex = -1;
246
395
  const currentIdx = opts.findIndex(o => o.value() === this.activeValue());
247
396
  const startIdx = currentIdx >= 0 ? currentIdx : 0;
397
+ // Horizontal arrows follow the layout direction. The option host is a
398
+ // custom element carrying `role="radio"`, not a native `<input>`, so the
399
+ // browser's RTL arrow flipping is unavailable — without this the arrows
400
+ // step backwards in DOM order but forwards visually in an RTL locale.
401
+ // Vertical arrows are direction-independent (CDK's ListKeyManager draws the
402
+ // same line), and the flip applies regardless of `orientation()` because a
403
+ // radiogroup accepts both arrow pairs in either layout, per WAI-ARIA APG.
404
+ const forward = this.directionality?.value === 'rtl' ? -1 : 1;
405
+ const backward = forward === 1 ? -1 : 1;
248
406
  switch (event.key) {
249
407
  case 'ArrowRight':
408
+ targetIndex = this.findNextEnabledIndex(opts, startIdx, forward);
409
+ break;
410
+ case 'ArrowLeft':
411
+ targetIndex = this.findNextEnabledIndex(opts, startIdx, backward);
412
+ break;
250
413
  case 'ArrowDown':
251
414
  targetIndex = this.findNextEnabledIndex(opts, startIdx, 1);
252
415
  break;
253
- case 'ArrowLeft':
254
416
  case 'ArrowUp':
255
417
  targetIndex = this.findNextEnabledIndex(opts, startIdx, -1);
256
418
  break;
@@ -299,14 +461,15 @@ class SegmentedControlComponent {
299
461
  setDisabledState(isDisabled) {
300
462
  this.cvaDisabled.set(isDisabled);
301
463
  }
464
+ // ── Lifecycle ──
465
+ ngOnInit() {
466
+ // NgControl's `control` is set by the parent FormControl* directive before
467
+ // children's `ngOnInit`. Subscribe here so `errorState` reacts to
468
+ // status/value changes on the bound control.
469
+ this.errorWiring.connect();
470
+ }
302
471
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SegmentedControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
303
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.7", type: SegmentedControlComponent, isStandalone: true, selector: "tw-segmented-control", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { attributes: { "role": "radiogroup" }, listeners: { "keydown": "onKeydown($event)" }, properties: { "class": "rootClasses()", "attr.aria-orientation": "orientation()", "attr.aria-disabled": "isDisabled() || null" } }, providers: [
304
- {
305
- provide: NG_VALUE_ACCESSOR,
306
- useExisting: forwardRef(() => SegmentedControlComponent),
307
- multi: true,
308
- },
309
- ], queries: [{ propertyName: "options", predicate: SegmentedControlOptionComponent, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
472
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.7", type: SegmentedControlComponent, isStandalone: true, selector: "tw-segmented-control", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, requiredInput: { classPropertyName: "requiredInput", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { attributes: { "role": "radiogroup" }, listeners: { "keydown": "onKeydown($event)", "focusout": "onFocusOut($event)" }, properties: { "class": "rootClasses()", "attr.aria-orientation": "orientation()", "attr.aria-disabled": "isDisabled() || null", "attr.aria-invalid": "errorState() || null", "attr.aria-required": "required() || null" } }, queries: [{ propertyName: "options", predicate: SegmentedControlOptionComponent, isSignal: true }], ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
310
473
  }
311
474
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: SegmentedControlComponent, decorators: [{
312
475
  type: Component,
@@ -314,22 +477,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
314
477
  selector: 'tw-segmented-control',
315
478
  changeDetection: ChangeDetectionStrategy.OnPush,
316
479
  template: `<ng-content />`,
317
- providers: [
318
- {
319
- provide: NG_VALUE_ACCESSOR,
320
- useExisting: forwardRef(() => SegmentedControlComponent),
321
- multi: true,
322
- },
323
- ],
480
+ // No static `NG_VALUE_ACCESSOR` provider: this control injects
481
+ // `NgControl` with `{ self: true }` for `TW_ERROR_STATE_MATCHER`
482
+ // integration, and a static provider on the same element creates circular
483
+ // DI against it. The accessor is registered by runtime assignment in the
484
+ // constructor instead — see the constructor comment for why that must be
485
+ // the constructor and not `ngOnInit`.
324
486
  host: {
325
487
  'role': 'radiogroup',
326
488
  '[class]': 'rootClasses()',
327
489
  '[attr.aria-orientation]': 'orientation()',
328
490
  '[attr.aria-disabled]': 'isDisabled() || null',
491
+ '[attr.aria-invalid]': 'errorState() || null',
492
+ '[attr.aria-required]': 'required() || null',
329
493
  '(keydown)': 'onKeydown($event)',
494
+ '(focusout)': 'onFocusOut($event)',
330
495
  },
331
496
  }]
332
- }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SegmentedControlOptionComponent), { isSignal: true }] }] } });
497
+ }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], requiredInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], options: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => SegmentedControlOptionComponent), { isSignal: true }] }] } });
333
498
 
334
499
  /**
335
500
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-segmented-control.mjs","sources":["../../../projects/ngx-tw/segmented-control/segmented-control.ts","../../../projects/ngx-tw/segmented-control/cdevhub-ngx-tw-segmented-control.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChildren,\n ElementRef,\n forwardRef,\n inject,\n input,\n isDevMode,\n linkedSignal,\n model,\n signal,\n} from '@angular/core';\nimport { type ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor, TwOrientation, TwSize } from '@cdevhub/ngx-tw/core';\n\n/** Visual style of the active indicator. */\nexport type SegmentedControlVariant = 'surface' | 'filled' | 'outline';\n\n/** Border-radius shape of the container and options. */\nexport type SegmentedControlRounded = 'pill' | 'md';\n\n// ── tv() config ──\n// All slot styling — base, size, orientation, rounded, variant × color × active,\n// disabled — flows through this single config. Static literal class strings are\n// required so the Tailwind v4 JIT scanner picks them up; new\n// `{role}-{solid,fg,border-strong}` combinations need a matching entry in\n// `theme/index.css`'s `@source inline(...)` safelist.\n\nconst segmentedControlVariants = tv({\n slots: {\n root: 'inline-flex bg-surface-muted p-1',\n option:\n 'inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap cursor-pointer transition-colors duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n },\n variants: {\n size: {\n xs: { option: 'px-2 py-1 text-xs' },\n sm: { option: 'px-3 py-1.5 text-sm' },\n md: { option: 'px-4 py-2 text-sm' },\n lg: { option: 'px-5 py-2.5 text-base' },\n xl: { option: 'px-6 py-3 text-base' },\n },\n orientation: {\n horizontal: { root: 'flex-row gap-1' },\n vertical: { root: 'flex-col gap-1' },\n },\n rounded: {\n pill: { root: 'rounded-full', option: 'rounded-full' },\n md: { root: 'rounded-md', option: 'rounded-md' },\n },\n // `variant` and `color` participate only via `compoundVariants` below —\n // their per-axis entries are intentionally empty so the cartesian product\n // (3 variants × 8 colors × 2 active states = 48 compound entries) owns\n // all active styling without per-axis defaults bleeding through.\n variant: {\n surface: {},\n filled: {},\n outline: {},\n },\n color: {\n primary: {},\n secondary: {},\n accent: {},\n neutral: {},\n info: {},\n success: {},\n warning: {},\n error: {},\n },\n active: {\n true: {},\n false: { option: 'text-fg-muted hover:text-fg' },\n },\n disabled: {\n true: { option: 'opacity-50 pointer-events-none cursor-default' },\n false: {},\n },\n },\n compoundVariants: [\n // surface × color × active=true\n { variant: 'surface', color: 'primary', active: true, class: { option: 'bg-surface shadow-sm text-primary-fg' } },\n { variant: 'surface', color: 'secondary', active: true, class: { option: 'bg-surface shadow-sm text-secondary-fg' } },\n { variant: 'surface', color: 'accent', active: true, class: { option: 'bg-surface shadow-sm text-accent-fg' } },\n { variant: 'surface', color: 'neutral', active: true, class: { option: 'bg-surface shadow-sm text-fg' } },\n { variant: 'surface', color: 'info', active: true, class: { option: 'bg-surface shadow-sm text-info-fg' } },\n { variant: 'surface', color: 'success', active: true, class: { option: 'bg-surface shadow-sm text-success-fg' } },\n { variant: 'surface', color: 'warning', active: true, class: { option: 'bg-surface shadow-sm text-warning-fg' } },\n { variant: 'surface', color: 'error', active: true, class: { option: 'bg-surface shadow-sm text-error-fg' } },\n // filled × color × active=true\n { variant: 'filled', color: 'primary', active: true, class: { option: 'bg-primary-solid text-primary-solid-fg shadow-sm' } },\n { variant: 'filled', color: 'secondary', active: true, class: { option: 'bg-secondary-solid text-secondary-solid-fg shadow-sm' } },\n { variant: 'filled', color: 'accent', active: true, class: { option: 'bg-accent-solid text-accent-solid-fg shadow-sm' } },\n { variant: 'filled', color: 'neutral', active: true, class: { option: 'bg-neutral-solid text-neutral-solid-fg shadow-sm' } },\n { variant: 'filled', color: 'info', active: true, class: { option: 'bg-info-solid text-info-solid-fg shadow-sm' } },\n { variant: 'filled', color: 'success', active: true, class: { option: 'bg-success-solid text-success-solid-fg shadow-sm' } },\n { variant: 'filled', color: 'warning', active: true, class: { option: 'bg-warning-solid text-warning-solid-fg shadow-sm' } },\n { variant: 'filled', color: 'error', active: true, class: { option: 'bg-error-solid text-error-solid-fg shadow-sm' } },\n // outline × color × active=true\n { variant: 'outline', color: 'primary', active: true, class: { option: 'ring-2 ring-primary-border-strong text-primary-fg' } },\n { variant: 'outline', color: 'secondary', active: true, class: { option: 'ring-2 ring-secondary-border-strong text-secondary-fg' } },\n { variant: 'outline', color: 'accent', active: true, class: { option: 'ring-2 ring-accent-border-strong text-accent-fg' } },\n { variant: 'outline', color: 'neutral', active: true, class: { option: 'ring-2 ring-border-strong text-fg' } },\n { variant: 'outline', color: 'info', active: true, class: { option: 'ring-2 ring-info-border-strong text-info-fg' } },\n { variant: 'outline', color: 'success', active: true, class: { option: 'ring-2 ring-success-border-strong text-success-fg' } },\n { variant: 'outline', color: 'warning', active: true, class: { option: 'ring-2 ring-warning-border-strong text-warning-fg' } },\n { variant: 'outline', color: 'error', active: true, class: { option: 'ring-2 ring-error-border-strong text-error-fg' } },\n ],\n defaultVariants: {\n size: 'md',\n orientation: 'horizontal',\n rounded: 'pill',\n variant: 'surface',\n color: 'primary',\n active: false,\n disabled: false,\n },\n}, { twMerge: true });\n\n// ── SegmentedControlOptionComponent ──\n\nlet nextId = 0;\n\n@Component({\n selector: 'tw-segmented-option',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<ng-content />`,\n host: {\n 'role': 'radio',\n '[id]': 'id',\n '[class]': 'classes()',\n '[attr.aria-checked]': 'isActive()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.tabindex]': 'isFocusable() ? 0 : -1',\n '(click)': 'select()',\n },\n})\nexport class SegmentedControlOptionComponent {\n /** Unique value identifying this option. Required. */\n readonly value = input.required<string>();\n\n /** When true, this option cannot be selected and is skipped by keyboard navigation. Defaults to `false`. */\n readonly disabled = input(false);\n\n readonly elementRef = inject(ElementRef<HTMLElement>);\n // `{ optional: true }` so the dev-mode guard below can fire a clearer\n // error than a raw DI failure when the option is rendered outside a\n // `<tw-segmented-control>`. All downstream reads use `this.parent?.` so\n // production misconfiguration degrades cleanly to a non-interactive option\n // (the dev `console.error` makes the cause obvious during development).\n private readonly parent: SegmentedControlComponent | null = inject(\n forwardRef(() => SegmentedControlComponent),\n { optional: true },\n );\n\n readonly id = `tw-segmented-option-${nextId++}`;\n\n constructor() {\n if (isDevMode() && !this.parent) {\n console.error(\n '<tw-segmented-option> must be a child of <tw-segmented-control>.',\n );\n }\n }\n\n readonly isActive = computed(() => this.parent?.activeValue() === this.value());\n\n readonly isDisabled = computed(() => this.disabled() || (this.parent?.isDisabled() ?? false));\n\n readonly isFocusable = computed(() => {\n if (this.isDisabled()) return false;\n if (this.isActive()) return true;\n // If no option is active, first non-disabled option gets focus\n if (this.parent?.activeValue() === null) {\n const opts = this.parent.options();\n const first = opts.find((o: SegmentedControlOptionComponent) => !o.isDisabled());\n return first?.value() === this.value();\n }\n return false;\n });\n\n readonly classes = computed(() => {\n const result = segmentedControlVariants({\n size: this.parent?.size() ?? 'md',\n orientation: this.parent?.orientation() ?? 'horizontal',\n rounded: this.parent?.effectiveRounded() ?? 'pill',\n variant: this.parent?.variant() ?? 'surface',\n color: this.parent?.color() ?? 'primary',\n active: this.isActive(),\n disabled: this.isDisabled(),\n });\n return result.option();\n });\n\n select(): void {\n if (this.isDisabled()) return;\n this.parent?.selectOption(this.value());\n }\n\n focus(): void {\n this.elementRef.nativeElement.focus();\n }\n}\n\n// ── SegmentedControlComponent ──\n\n@Component({\n selector: 'tw-segmented-control',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<ng-content />`,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => SegmentedControlComponent),\n multi: true,\n },\n ],\n host: {\n 'role': 'radiogroup',\n '[class]': 'rootClasses()',\n '[attr.aria-orientation]': 'orientation()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class SegmentedControlComponent implements ControlValueAccessor {\n /** Controls the active indicator style. `'surface'` shows a raised white pill; `'filled'` shows a solid colored background; `'outline'` shows a colored ring border. Defaults to `'surface'`. */\n readonly variant = input<SegmentedControlVariant>('surface');\n\n /** Sets the semantic color for the active option indicator. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls padding, font size, and gap of options. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Layout direction of the control. Defaults to `'horizontal'`. */\n readonly orientation = input<TwOrientation>('horizontal');\n\n /** Controls the border-radius shape of the container and options. `'pill'` uses fully rounded corners; `'md'` uses standard radius. Vertical orientation forces `'md'`. Defaults to `'pill'`. */\n readonly rounded = input<SegmentedControlRounded>('pill');\n\n /** When true, prevents all interaction and applies muted styling. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** The value of the currently selected option. Two-way bound. Updates on user selection. */\n readonly value = model<string | null>(null);\n\n /** @internal */\n readonly options = contentChildren(SegmentedControlOptionComponent);\n\n private onChange: (value: string | null) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n\n readonly activeValue = linkedSignal(() => this.value());\n\n /** @internal Read by `SegmentedControlOptionComponent.classes` to resolve the option's tv() bucket. Vertical orientation forces `'md'` regardless of input. */\n readonly effectiveRounded = computed<SegmentedControlRounded>(() =>\n this.orientation() === 'vertical' ? 'md' : this.rounded(),\n );\n\n private readonly variantResult = computed(() =>\n segmentedControlVariants({\n size: this.size(),\n orientation: this.orientation(),\n rounded: this.effectiveRounded(),\n }),\n );\n\n readonly rootClasses = computed(() => {\n const base = this.variantResult().root();\n return this.isDisabled()\n ? `${base} opacity-50 pointer-events-none`\n : base;\n });\n\n // ── Selection ──\n\n selectOption(val: string): void {\n if (this.isDisabled()) return;\n this.activeValue.set(val);\n this.value.set(val);\n this.onChange(val);\n this.onTouched();\n }\n\n // ── Keyboard navigation ──\n\n onKeydown(event: KeyboardEvent): void {\n const opts = this.options();\n if (opts.length === 0) return;\n\n let targetIndex = -1;\n const currentIdx = opts.findIndex(o => o.value() === this.activeValue());\n const startIdx = currentIdx >= 0 ? currentIdx : 0;\n\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n targetIndex = this.findNextEnabledIndex(opts, startIdx, 1);\n break;\n case 'ArrowLeft':\n case 'ArrowUp':\n targetIndex = this.findNextEnabledIndex(opts, startIdx, -1);\n break;\n case 'Home':\n targetIndex = opts.findIndex(o => !o.isDisabled());\n break;\n case 'End':\n for (let i = opts.length - 1; i >= 0; i--) {\n if (!opts[i].isDisabled()) { targetIndex = i; break; }\n }\n break;\n default:\n return;\n }\n\n if (targetIndex >= 0) {\n event.preventDefault();\n const opt = opts[targetIndex];\n this.selectOption(opt.value());\n opt.focus();\n }\n }\n\n private findNextEnabledIndex(\n opts: readonly SegmentedControlOptionComponent[],\n from: number,\n direction: 1 | -1,\n ): number {\n const len = opts.length;\n let idx = from;\n for (let i = 0; i < len; i++) {\n idx = (idx + direction + len) % len;\n if (!opts[idx].isDisabled()) return idx;\n }\n return -1;\n }\n\n // ── ControlValueAccessor ──\n\n writeValue(val: string | null): void {\n this.activeValue.set(val);\n this.value.set(val ?? null);\n }\n\n registerOnChange(fn: (value: string | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-segmented-control.mjs","sources":["../../../projects/ngx-tw/segmented-control/segmented-control.ts","../../../projects/ngx-tw/segmented-control/cdevhub-ngx-tw-segmented-control.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChildren,\n ElementRef,\n forwardRef,\n inject,\n input,\n isDevMode,\n linkedSignal,\n model,\n type OnInit,\n signal,\n type Signal,\n} from '@angular/core';\nimport { type ControlValueAccessor, NgControl } from '@angular/forms';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n type TwColor,\n type TwOrientation,\n type TwSize,\n wireErrorState,\n} from '@cdevhub/ngx-tw/core';\n\n/** Visual style of the active indicator. */\nexport type SegmentedControlVariant =\n | 'surface'\n | 'solid'\n | 'outline'\n | SegmentedControlVariantLegacy;\n\n/**\n * Legacy `variant` spellings, kept so existing templates keep compiling.\n *\n * @deprecated `'filled'` is an alias for `'solid'`; it will be removed in the next\n * major. Prefer `'solid'`.\n */\nexport type SegmentedControlVariantLegacy = 'filled';\n\n/** Canonical `variant` spellings — the set `tv()` actually keys on. */\ntype SegmentedControlVariantCanonical = Exclude<\n SegmentedControlVariant,\n SegmentedControlVariantLegacy\n>;\n\n/** Maps every legacy spelling onto its canonical replacement. */\nconst VARIANT_ALIASES: Readonly<\n Record<SegmentedControlVariantLegacy, SegmentedControlVariantCanonical>\n> = {\n filled: 'solid',\n};\n\n/** Border-radius shape of the container and options. */\nexport type SegmentedControlRounded = 'pill' | 'md';\n\n// ── tv() config ──\n// All slot styling — base, size, orientation, rounded, variant × color × active,\n// disabled — flows through this single config. Static literal class strings are\n// required so the Tailwind v4 JIT scanner picks them up; new\n// `{role}-{solid,fg,border-strong}` combinations need a matching entry in\n// `theme/index.css`'s `@source inline(...)` safelist.\n\nconst segmentedControlVariants = tv({\n slots: {\n root: 'inline-flex bg-surface-muted p-1',\n option:\n 'inline-flex items-center justify-center gap-1.5 font-medium whitespace-nowrap cursor-pointer transition-colors duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n },\n variants: {\n // Pinned control heights — see `docs/vertical-rhythm.md`. The option carries\n // horizontal padding and font size only; the height itself is pinned in the\n // orientation-keyed compound variants below, because *which box* owns the\n // pin depends on the axis (root when horizontal, option when vertical).\n size: {\n xs: { option: 'px-2 text-xs' },\n sm: { option: 'px-3 text-sm' },\n md: { option: 'px-4 text-sm' },\n lg: { option: 'px-5 text-base' },\n xl: { option: 'px-6 text-base' },\n },\n orientation: {\n horizontal: { root: 'flex-row gap-1' },\n vertical: { root: 'flex-col gap-1' },\n },\n rounded: {\n pill: { root: 'rounded-full', option: 'rounded-full' },\n md: { root: 'rounded-md', option: 'rounded-md' },\n },\n // `variant` and `color` participate only via `compoundVariants` below —\n // their per-axis entries are intentionally empty so the cartesian product\n // (3 variants × 8 colors × 2 active states = 48 compound entries) owns\n // all active styling without per-axis defaults bleeding through.\n variant: {\n surface: {},\n solid: {},\n outline: {},\n },\n color: {\n primary: {},\n secondary: {},\n accent: {},\n neutral: {},\n info: {},\n success: {},\n warning: {},\n error: {},\n },\n active: {\n true: {},\n false: { option: 'text-fg-muted hover:text-fg' },\n },\n disabled: {\n true: { option: 'opacity-50 pointer-events-none cursor-default' },\n false: {},\n },\n },\n compoundVariants: [\n // ── Pinned heights (docs/vertical-rhythm.md) ──\n // Horizontal: the *root* is the single-line control, so the pin lives there.\n // The `p-1` recessed track stays (it is the component's visual identity) and\n // is absorbed by the pinned box under `box-sizing: border-box`; the root is\n // `inline-flex` with the default `align-items: stretch`, so each option fills\n // the remaining height without a pin of its own.\n //\n // `xs` is the exception, and it is an accessibility floor rather than a\n // style choice. The option — not the root — carries `role=\"radio\"`, the\n // tabindex and the click handler, so the option IS the target. A 24px root\n // minus a 4px inset per side leaves a 16px target, under the WCAG 2.2\n // SC 2.5.8 (AA) 24px minimum. An inset track and a 24px target cannot both\n // fit inside 24px, so at `xs` the inset is dropped: the option fills the\n // full 24px and `gap-1` alone carries the track read. Widening the root to\n // 32px instead would restore the inset but break the shared control height\n // that lets a segmented control sit flush beside a button or input.\n { orientation: 'horizontal', size: 'xs', class: { root: 'h-6 p-0' } },\n { orientation: 'horizontal', size: 'sm', class: { root: 'h-8' } },\n { orientation: 'horizontal', size: 'md', class: { root: 'h-9' } },\n { orientation: 'horizontal', size: 'lg', class: { root: 'h-11' } },\n { orientation: 'horizontal', size: 'xl', class: { root: 'h-12' } },\n // Vertical: the root grows with the option count, so pinning it would crush\n // the stack. Each option is its own single-line control row instead, which\n // reproduces the pre-migration vertical height exactly (padding-derived\n // before, declared now).\n { orientation: 'vertical', size: 'xs', class: { option: 'h-6' } },\n { orientation: 'vertical', size: 'sm', class: { option: 'h-8' } },\n { orientation: 'vertical', size: 'md', class: { option: 'h-9' } },\n { orientation: 'vertical', size: 'lg', class: { option: 'h-11' } },\n { orientation: 'vertical', size: 'xl', class: { option: 'h-12' } },\n // surface × color × active=true\n { variant: 'surface', color: 'primary', active: true, class: { option: 'bg-surface shadow-sm text-primary-fg' } },\n { variant: 'surface', color: 'secondary', active: true, class: { option: 'bg-surface shadow-sm text-secondary-fg' } },\n { variant: 'surface', color: 'accent', active: true, class: { option: 'bg-surface shadow-sm text-accent-fg' } },\n { variant: 'surface', color: 'neutral', active: true, class: { option: 'bg-surface shadow-sm text-fg' } },\n { variant: 'surface', color: 'info', active: true, class: { option: 'bg-surface shadow-sm text-info-fg' } },\n { variant: 'surface', color: 'success', active: true, class: { option: 'bg-surface shadow-sm text-success-fg' } },\n { variant: 'surface', color: 'warning', active: true, class: { option: 'bg-surface shadow-sm text-warning-fg' } },\n { variant: 'surface', color: 'error', active: true, class: { option: 'bg-surface shadow-sm text-error-fg' } },\n // solid × color × active=true\n { variant: 'solid', color: 'primary', active: true, class: { option: 'bg-primary-solid text-primary-solid-fg shadow-sm' } },\n { variant: 'solid', color: 'secondary', active: true, class: { option: 'bg-secondary-solid text-secondary-solid-fg shadow-sm' } },\n { variant: 'solid', color: 'accent', active: true, class: { option: 'bg-accent-solid text-accent-solid-fg shadow-sm' } },\n { variant: 'solid', color: 'neutral', active: true, class: { option: 'bg-neutral-solid text-neutral-solid-fg shadow-sm' } },\n { variant: 'solid', color: 'info', active: true, class: { option: 'bg-info-solid text-info-solid-fg shadow-sm' } },\n { variant: 'solid', color: 'success', active: true, class: { option: 'bg-success-solid text-success-solid-fg shadow-sm' } },\n { variant: 'solid', color: 'warning', active: true, class: { option: 'bg-warning-solid text-warning-solid-fg shadow-sm' } },\n { variant: 'solid', color: 'error', active: true, class: { option: 'bg-error-solid text-error-solid-fg shadow-sm' } },\n // outline × color × active=true\n { variant: 'outline', color: 'primary', active: true, class: { option: 'ring-2 ring-primary-border-strong text-primary-fg' } },\n { variant: 'outline', color: 'secondary', active: true, class: { option: 'ring-2 ring-secondary-border-strong text-secondary-fg' } },\n { variant: 'outline', color: 'accent', active: true, class: { option: 'ring-2 ring-accent-border-strong text-accent-fg' } },\n { variant: 'outline', color: 'neutral', active: true, class: { option: 'ring-2 ring-border-strong text-fg' } },\n { variant: 'outline', color: 'info', active: true, class: { option: 'ring-2 ring-info-border-strong text-info-fg' } },\n { variant: 'outline', color: 'success', active: true, class: { option: 'ring-2 ring-success-border-strong text-success-fg' } },\n { variant: 'outline', color: 'warning', active: true, class: { option: 'ring-2 ring-warning-border-strong text-warning-fg' } },\n { variant: 'outline', color: 'error', active: true, class: { option: 'ring-2 ring-error-border-strong text-error-fg' } },\n ],\n defaultVariants: {\n size: 'md',\n orientation: 'horizontal',\n rounded: 'pill',\n variant: 'surface',\n color: 'primary',\n active: false,\n disabled: false,\n },\n}, { twMerge: true });\n\n// ── SegmentedControlOptionComponent ──\n\nlet nextId = 0;\n\n@Component({\n selector: 'tw-segmented-option',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<ng-content />`,\n host: {\n 'role': 'radio',\n '[id]': 'id',\n '[class]': 'classes()',\n '[attr.aria-checked]': 'isActive()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.tabindex]': 'isFocusable() ? 0 : -1',\n '(click)': 'select()',\n },\n})\nexport class SegmentedControlOptionComponent {\n /** Unique value identifying this option. Required. */\n readonly value = input.required<string>();\n\n /** When true, this option cannot be selected and is skipped by keyboard navigation. Defaults to `false`. */\n readonly disabled = input(false);\n\n readonly elementRef = inject(ElementRef<HTMLElement>);\n // `{ optional: true }` so the dev-mode guard below can fire a clearer\n // error than a raw DI failure when the option is rendered outside a\n // `<tw-segmented-control>`. All downstream reads use `this.parent?.` so\n // production misconfiguration degrades cleanly to a non-interactive option\n // (the dev `console.error` makes the cause obvious during development).\n private readonly parent: SegmentedControlComponent | null = inject(\n forwardRef(() => SegmentedControlComponent),\n { optional: true },\n );\n\n readonly id = `tw-segmented-option-${nextId++}`;\n\n constructor() {\n if (isDevMode() && !this.parent) {\n console.error(\n '<tw-segmented-option> must be a child of <tw-segmented-control>.',\n );\n }\n }\n\n readonly isActive = computed(() => this.parent?.activeValue() === this.value());\n\n readonly isDisabled = computed(() => this.disabled() || (this.parent?.isDisabled() ?? false));\n\n readonly isFocusable = computed(() => {\n if (this.isDisabled()) return false;\n if (this.isActive()) return true;\n // Roving-tabindex recovery. The fallback used to be gated on\n // `activeValue() === null`, which is a strict check: `undefined`, `''`, a\n // stale id, or an active option that is itself disabled all left NO\n // option tabbable and dropped the whole control out of the tab order\n // (WCAG SC 2.1.1). The real condition is \"no enabled option is active\".\n const opts = this.parent?.options() ?? [];\n const hasTabbableActive = opts.some(\n (o: SegmentedControlOptionComponent) => o.isActive() && !o.isDisabled(),\n );\n if (hasTabbableActive) return false;\n const first = opts.find((o: SegmentedControlOptionComponent) => !o.isDisabled());\n return first?.value() === this.value();\n });\n\n readonly classes = computed(() => {\n const result = segmentedControlVariants({\n size: this.parent?.size() ?? 'md',\n orientation: this.parent?.orientation() ?? 'horizontal',\n rounded: this.parent?.effectiveRounded() ?? 'pill',\n variant: this.parent?.resolvedVariant() ?? 'surface',\n color: this.parent?.color() ?? 'primary',\n active: this.isActive(),\n disabled: this.isDisabled(),\n });\n return result.option();\n });\n\n /** Selects this option in the parent segmented control. No-op when the option is disabled. */\n select(): void {\n if (this.isDisabled()) return;\n this.parent?.selectOption(this.value());\n }\n\n /** Moves DOM focus to this option's element. Called by the parent group's arrow-key handler, which moves focus and selection together (selection-follows-focus, as WAI-ARIA APG specifies for a radiogroup). */\n focus(): void {\n this.elementRef.nativeElement.focus();\n }\n}\n\n// ── SegmentedControlComponent ──\n\n@Component({\n selector: 'tw-segmented-control',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `<ng-content />`,\n // No static `NG_VALUE_ACCESSOR` provider: this control injects\n // `NgControl` with `{ self: true }` for `TW_ERROR_STATE_MATCHER`\n // integration, and a static provider on the same element creates circular\n // DI against it. The accessor is registered by runtime assignment in the\n // constructor instead — see the constructor comment for why that must be\n // the constructor and not `ngOnInit`.\n host: {\n 'role': 'radiogroup',\n '[class]': 'rootClasses()',\n '[attr.aria-orientation]': 'orientation()',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.aria-required]': 'required() || null',\n '(keydown)': 'onKeydown($event)',\n '(focusout)': 'onFocusOut($event)',\n },\n})\nexport class SegmentedControlComponent implements ControlValueAccessor, OnInit {\n /** Controls the active indicator style. `'surface'` shows a raised white pill; `'solid'` shows a solid colored background; `'outline'` shows a colored ring border. Defaults to `'surface'`. `'filled'` is a deprecated alias for `'solid'`. */\n readonly variant = input<SegmentedControlVariant>('surface');\n\n /** Sets the semantic color for the active option indicator. Defaults to `'primary'`. */\n readonly color = input<TwColor>('primary');\n\n /** Controls padding, font size, and gap of options. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Layout direction of the control. Defaults to `'horizontal'`. */\n readonly orientation = input<TwOrientation>('horizontal');\n\n /** Controls the border-radius shape of the container and options. `'pill'` uses fully rounded corners; `'md'` uses standard radius. Vertical orientation forces `'md'`. Defaults to `'pill'`. */\n readonly rounded = input<SegmentedControlRounded>('pill');\n\n /** When true, prevents all interaction and applies muted styling. Defaults to `false`. */\n readonly disabled = input(false);\n\n /** When true, sets `aria-required=\"true\"` on the radiogroup so assistive tech announces a choice is mandatory. Also inferred from `Validators.required` on a bound control, so a reactive/template-driven form does not have to state it twice. Defaults to `false`. */\n readonly requiredInput = input(false, { alias: 'required' });\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the control uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n /**\n * The value of the currently selected option. Two-way bound. Defaults to\n * `null`.\n *\n * The two-way binding mints a `valueChange` output, and it is the\n * *any-change* channel: it fires on user selection **and** on a programmatic\n * write from a bound form (`FormControl.setValue`, `ngModel`, `writeValue`).\n * Unlike `tw-checkbox` / `tw-switch` / `tw-radio-group`, this control ships no\n * separate gesture-only `change` output, so writing back into the same form\n * from a `(valueChange)` handler will echo. To act on user selection alone,\n * compare against the value you last wrote, or listen on the form control.\n */\n readonly value = model<string | null>(null);\n\n /** @internal */\n readonly options = contentChildren(SegmentedControlOptionComponent);\n\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n /**\n * Optional so a consumer that never imports `BidiModule` still gets a working\n * control — arrow navigation falls back to LTR when the token is absent. Read\n * imperatively inside the keydown handler; nothing here needs to re-render on\n * a direction change.\n */\n private readonly directionality = inject(Directionality, { optional: true });\n\n private onChange: (value: string | null) => void = () => {};\n private onTouched: () => void = () => {};\n private readonly cvaDisabled = signal(false);\n\n /** @internal Shared `errorState` / `required` / `errors` derivation — see `wireErrorState`. */\n private readonly errorWiring = wireErrorState({\n ngControl: () => this.ngControl,\n matcher: () => this.errorStateMatcher(),\n required: () => this.requiredInput(),\n });\n\n constructor() {\n // Material-style CVA wiring: declare ourselves as the value accessor on any\n // host-level `NgControl` (FormControlDirective, NgModel, etc.). This avoids\n // the circular-DI that a static `NG_VALUE_ACCESSOR` provider would create\n // because `NgControl` is injected with `self: true` on the same element.\n //\n // The assignment MUST stay in the constructor. This component exposes a\n // `value` model(), so Angular v22 would otherwise compile it as a\n // signal-forms *custom control* and skip `setUpValidators` entirely — a\n // silent validator drop that no value/disabled test can catch.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n readonly isDisabled = computed(() => this.disabled() || this.cvaDisabled());\n\n /**\n * @internal Resolved required state: the `required` input OR'd with\n * `Validators.required` on a bound `NgControl`. The OR (rather than a\n * validator-only read) is what keeps signal forms working — `cvaControlCreate`\n * writes the `required` *input* directly from the field state and never\n * consults validators, so the input arm carries that branch while the\n * validator arm carries reactive/template-driven forms.\n */\n readonly required: Signal<boolean> = this.errorWiring.required;\n\n /** @internal Whether the control is in an error state per the configured `ErrorStateMatcher`. Reads the bound `NgControl.invalid` through the matcher and drives `aria-invalid` on the radiogroup host. */\n readonly errorState: Signal<boolean> = this.errorWiring.errorState;\n\n readonly activeValue = linkedSignal(() => this.value());\n\n /** @internal Read by `SegmentedControlOptionComponent.classes` to resolve the option's tv() bucket. Vertical orientation forces `'md'` regardless of input. */\n readonly effectiveRounded = computed<SegmentedControlRounded>(() =>\n this.orientation() === 'vertical' ? 'md' : this.rounded(),\n );\n\n /** @internal Canonical variant with legacy spellings folded in. Read by `SegmentedControlOptionComponent.classes` to resolve the option's tv() bucket. */\n readonly resolvedVariant = computed<SegmentedControlVariantCanonical>(() => {\n const v = this.variant();\n return (\n (VARIANT_ALIASES as Record<string, SegmentedControlVariantCanonical | undefined>)[v] ??\n (v as SegmentedControlVariantCanonical)\n );\n });\n\n private readonly variantResult = computed(() =>\n segmentedControlVariants({\n size: this.size(),\n orientation: this.orientation(),\n rounded: this.effectiveRounded(),\n }),\n );\n\n readonly rootClasses = computed(() => {\n const base = this.variantResult().root();\n return this.isDisabled()\n ? `${base} opacity-50 pointer-events-none`\n : base;\n });\n\n // ── Selection ──\n\n /** Selects the option with the given value, updating the two-way bound `value` and notifying the registered `ControlValueAccessor` callbacks. No-op when the control is disabled. */\n selectOption(val: string): void {\n if (this.isDisabled()) return;\n this.activeValue.set(val);\n this.value.set(val);\n this.onChange(val);\n // Deliberately NOT `onTouched()`. Angular's CVA contract registers\n // `onTouched` as the BLUR notification; calling it on selection flipped\n // `touched` with no blur, so a consumer staging error display on `touched`\n // got different behaviour from `tw-segmented-control` than from\n // `tw-slider` / `tw-input`. `onFocusOut()` below is the only place that\n // fires it. The control's own `valueChanges`/`statusChanges` subscription\n // (see `ngOnInit`) is what refreshes `errorState` after this write.\n }\n\n /**\n * @internal Blur notification for the CVA contract. Fires `onTouched` only\n * when focus leaves the radiogroup entirely — roving focus moves between\n * option elements inside the group, and each of those hops raises `focusout`\n * on the host too. Without this the control is only ever marked `touched` by\n * a selection, so a user who tabs through without choosing never surfaces the\n * `required` error.\n */\n onFocusOut(event: FocusEvent): void {\n const next = event.relatedTarget as Node | null;\n if (next && this.elementRef.nativeElement.contains(next)) return;\n this.onTouched();\n this.errorWiring.bump();\n }\n\n // ── Keyboard navigation ──\n\n /** @internal Handles roving-focus keyboard navigation (Arrow keys, Home, End) and Space / Enter activation across the option group. */\n onKeydown(event: KeyboardEvent): void {\n const opts = this.options();\n if (opts.length === 0) return;\n\n // Space activates the focused option, as WAI-ARIA requires of every\n // `role=\"radio\"`. The option host is a custom element, not a native\n // control, so no click event is synthesised for us — without this branch\n // selection is pointer-only (WCAG SC 2.1.1). Enter is accepted too: it\n // costs nothing and matches what users expect from a button-like control.\n if (event.key === ' ' || event.key === 'Spacebar' || event.key === 'Enter') {\n const target = event.target as Node | null;\n const focused = target\n ? opts.find(o => o.elementRef.nativeElement.contains(target))\n : undefined;\n if (focused && !focused.isDisabled()) {\n // Space would otherwise scroll the page.\n event.preventDefault();\n this.selectOption(focused.value());\n }\n return;\n }\n\n let targetIndex = -1;\n const currentIdx = opts.findIndex(o => o.value() === this.activeValue());\n const startIdx = currentIdx >= 0 ? currentIdx : 0;\n\n // Horizontal arrows follow the layout direction. The option host is a\n // custom element carrying `role=\"radio\"`, not a native `<input>`, so the\n // browser's RTL arrow flipping is unavailable — without this the arrows\n // step backwards in DOM order but forwards visually in an RTL locale.\n // Vertical arrows are direction-independent (CDK's ListKeyManager draws the\n // same line), and the flip applies regardless of `orientation()` because a\n // radiogroup accepts both arrow pairs in either layout, per WAI-ARIA APG.\n const forward: 1 | -1 = this.directionality?.value === 'rtl' ? -1 : 1;\n const backward: 1 | -1 = forward === 1 ? -1 : 1;\n\n switch (event.key) {\n case 'ArrowRight':\n targetIndex = this.findNextEnabledIndex(opts, startIdx, forward);\n break;\n case 'ArrowLeft':\n targetIndex = this.findNextEnabledIndex(opts, startIdx, backward);\n break;\n case 'ArrowDown':\n targetIndex = this.findNextEnabledIndex(opts, startIdx, 1);\n break;\n case 'ArrowUp':\n targetIndex = this.findNextEnabledIndex(opts, startIdx, -1);\n break;\n case 'Home':\n targetIndex = opts.findIndex(o => !o.isDisabled());\n break;\n case 'End':\n for (let i = opts.length - 1; i >= 0; i--) {\n if (!opts[i].isDisabled()) { targetIndex = i; break; }\n }\n break;\n default:\n return;\n }\n\n if (targetIndex >= 0) {\n event.preventDefault();\n const opt = opts[targetIndex];\n this.selectOption(opt.value());\n opt.focus();\n }\n }\n\n private findNextEnabledIndex(\n opts: readonly SegmentedControlOptionComponent[],\n from: number,\n direction: 1 | -1,\n ): number {\n const len = opts.length;\n let idx = from;\n for (let i = 0; i < len; i++) {\n idx = (idx + direction + len) % len;\n if (!opts[idx].isDisabled()) return idx;\n }\n return -1;\n }\n\n // ── ControlValueAccessor ──\n\n writeValue(val: string | null): void {\n this.activeValue.set(val);\n this.value.set(val ?? null);\n }\n\n registerOnChange(fn: (value: string | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // ── Lifecycle ──\n\n ngOnInit(): void {\n // NgControl's `control` is set by the parent FormControl* directive before\n // children's `ngOnInit`. Subscribe here so `errorState` reacts to\n // status/value changes on the bound control.\n this.errorWiring.connect();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}