@cdevhub/ngx-tw 0.5.0 → 0.6.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 (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 +18 -3
  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 +110 -36
  140. package/theme/_high-contrast-dark.css +367 -0
  141. package/theme/_high-contrast.css +13 -2
  142. package/theme/_light.css +276 -0
  143. package/theme/_semantic.css +47 -12
  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
@@ -42,7 +42,7 @@ interface ProgressBarOptions {
42
42
  * ```
43
43
  */
44
44
  declare class ProgressBarComponent {
45
- /** Current progress value. When null or undefined, the bar renders indeterminate. Values outside `[options.min, options.max]` are clamped. */
45
+ /** Current progress value. When null or undefined, the bar renders indeterminate. Values outside `[options.min, options.max]` are clamped. Defaults to `null`. */
46
46
  readonly value: _angular_core.InputSignal<number | null | undefined>;
47
47
  /** Visual style of the bar. `'linear'` renders a single fill; `'segmented'` splits the rail into discrete steps. Defaults to `'linear'`. */
48
48
  readonly variant: _angular_core.InputSignal<ProgressBarVariant>;
@@ -10,7 +10,7 @@ type RadioOrientation = 'horizontal' | 'vertical';
10
10
  /** Position of the label relative to the radio control. */
11
11
  type RadioLabelPosition = 'before' | 'after';
12
12
  declare class RadioComponent implements ControlValueAccessor, OnInit {
13
- /** The value this radio contributes when selected inside a `tw-radio-group`. Required when nested in a group; ignored when used standalone. */
13
+ /** The value this radio contributes when selected inside a `tw-radio-group`. Required when nested in a group; ignored when used standalone. Defaults to `undefined`. */
14
14
  readonly value: _angular_core.InputSignal<unknown>;
15
15
  /** Overrides the parent group's color for this radio. When undefined, inherits from the group (or defaults to `'primary'` standalone). */
16
16
  readonly color: _angular_core.InputSignal<TwColor | undefined>;
@@ -28,31 +28,51 @@ declare class RadioComponent implements ControlValueAccessor, OnInit {
28
28
  readonly labelPosition: _angular_core.InputSignal<RadioLabelPosition>;
29
29
  /** Optional name attribute for standalone use. Ignored when the parent group provides a name. */
30
30
  readonly name: _angular_core.InputSignal<string | undefined>;
31
- /** Accessible name when no visible label is provided. Mirrored to `aria-label`. */
31
+ /** Accessible name when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */
32
32
  readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
33
- /** ID of an external element that labels the radio. Mirrored to `aria-labelledby`. */
33
+ /** ID of an external element that labels the radio. Mirrored to `aria-labelledby`. Defaults to `undefined`. */
34
34
  readonly ariaLabelledby: _angular_core.InputSignal<string | undefined>;
35
- /** ID of an external element that describes the radio. Mirrored to `aria-describedby`. */
35
+ /** ID of an external element that describes the radio. Mirrored to `aria-describedby`. Defaults to `undefined`. */
36
36
  readonly ariaDescribedby: _angular_core.InputSignal<string | undefined>;
37
- /** Two-way bound checked state. Authoritative only in standalone mode; when inside a `tw-radio-group`, this model reflects group selection but does NOT drive it. */
37
+ /**
38
+ * Two-way bound checked state. Authoritative only in standalone mode.
39
+ * Defaults to `false`.
40
+ *
41
+ * Standalone, the minted `checkedChange` output is the *any-change* channel:
42
+ * it fires both when the user selects this radio and when a bound form writes
43
+ * into it (`FormControl.setValue`, `ngModel`, `writeValue`). `(change)` is the
44
+ * *user-gesture-only* channel — bind that one for analytics or a confirmation
45
+ * prompt, where a programmatic write must not count as a click.
46
+ *
47
+ * Inside a `tw-radio-group` this model is inert: the group owns selection,
48
+ * the rendered state comes from the group's `value`, and the component never
49
+ * writes `checked` — so `(checkedChange)` never fires on a grouped radio.
50
+ * `(change)` still fires when this radio becomes the selected one. Bind the
51
+ * group's `[(value)]` / `(change)` instead.
52
+ */
38
53
  readonly checked: _angular_core.ModelSignal<boolean>;
39
54
  /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the radio uses the `TW_ERROR_STATE_MATCHER` token's value. */
40
55
  readonly errorStateMatcher: _angular_core.InputSignal<ErrorStateMatcher | undefined>;
41
- /** Fires after the checked state changes from a user interaction on this radio. In grouped mode only fires when this radio becomes the selected one. Does not fire when selection is updated programmatically. */
56
+ /**
57
+ * Fires after the checked state changes from a user interaction on this
58
+ * radio. In grouped mode only fires when this radio becomes the selected one.
59
+ * Does **not** fire when selection is updated programmatically via
60
+ * `writeValue` / `FormControl.setValue` / `ngModel` — standalone, bind the
61
+ * two-way binding's `(checkedChange)` for that, which fires on any change.
62
+ * (Grouped, `(checkedChange)` never fires at all; use the group's
63
+ * `[(value)]`.)
64
+ */
42
65
  readonly change: _angular_core.OutputEmitterRef<boolean>;
43
66
  private readonly focusMonitor;
44
67
  readonly elementRef: ElementRef<any>;
45
68
  private readonly destroyRef;
46
69
  private readonly parent;
47
70
  private readonly ngControl;
48
- private readonly parentForm;
49
- private readonly parentFormGroup;
50
- private readonly defaultMatcher;
51
71
  private onChange;
52
72
  private onTouched;
53
73
  private readonly cvaDisabled;
54
- private readonly _ngControlRev;
55
- private readonly _formSubmitRev;
74
+ /** @internal Shared `errorState` derivation — see `wireErrorState`. */
75
+ private readonly errorWiring;
56
76
  private readonly uid;
57
77
  readonly hostId: string;
58
78
  readonly labelId: string;
@@ -110,25 +130,52 @@ declare class RadioGroupComponent<T = unknown> implements ControlValueAccessor,
110
130
  readonly size: _angular_core.InputSignal<TwSize>;
111
131
  /** Visual style of the selected indicator. `'solid'` fills the dot with the color against a colored ring; `'outline'` keeps a transparent fill with a colored ring and colored dot. Propagated to children unless a child overrides it. Defaults to `'solid'`. */
112
132
  readonly variant: _angular_core.InputSignal<RadioVariant>;
113
- /** Layout direction of the group. Drives `aria-orientation` and the arrow-key model. Defaults to `'vertical'`. */
133
+ /** Layout direction of the group. Sets `aria-orientation` and the visual axis; both arrow-key pairs navigate in either orientation, per WAI-ARIA APG. Defaults to `'vertical'`. */
114
134
  readonly orientation: _angular_core.InputSignal<RadioOrientation>;
115
135
  /** When true, disables every radio in the group and blocks keyboard interaction. Defaults to `false`. */
116
136
  readonly disabled: _angular_core.InputSignal<boolean>;
117
- /** When true, sets `aria-required="true"` on the group for assistive tech. Defaults to `false`. */
118
- readonly required: _angular_core.InputSignal<boolean>;
137
+ /** When true, sets `aria-required="true"` on the group for assistive tech. 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`. */
138
+ readonly requiredInput: _angular_core.InputSignal<boolean>;
139
+ /**
140
+ * @internal Shared `errorState` / `required` / `errors` derivation — see
141
+ * `wireErrorState`. Declared here, above `required`, because class field
142
+ * initializers run in declaration order.
143
+ */
144
+ private readonly errorWiring;
145
+ /**
146
+ * @internal Resolved required state: the `required` input OR'd with
147
+ * `Validators.required` on a bound `NgControl`.
148
+ */
149
+ readonly required: Signal<boolean>;
119
150
  /** Optional form-association name. Propagated to each child radio's host `name` attribute so standard HTML form semantics still apply. */
120
151
  readonly name: _angular_core.InputSignal<string | undefined>;
121
- /** Accessible name for the group when no visible label is provided. Mirrored to `aria-label`. */
152
+ /** Accessible name for the group when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */
122
153
  readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
123
- /** ID of an external element that labels the group. Mirrored to `aria-labelledby`. */
154
+ /** ID of an external element that labels the group. Mirrored to `aria-labelledby`. Defaults to `undefined`. */
124
155
  readonly ariaLabelledby: _angular_core.InputSignal<string | undefined>;
125
- /** ID of an external element that describes the group. Mirrored to `aria-describedby`. */
156
+ /** ID of an external element that describes the group. Mirrored to `aria-describedby`. Defaults to `undefined`. */
126
157
  readonly ariaDescribedby: _angular_core.InputSignal<string | undefined>;
127
- /** Two-way bound selected value. Updates when the user picks a radio; fires `valueChange`. `null` means no selection. */
158
+ /**
159
+ * Two-way bound selected value. `null` means no selection. Defaults to
160
+ * `null`.
161
+ *
162
+ * The two-way binding mints a `valueChange` output. That output is the
163
+ * *any-change* channel: it fires when the user picks a radio **and** when a
164
+ * bound form writes into the group (`FormControl.setValue`, `ngModel`,
165
+ * `writeValue`). `(change)` is the *user-gesture-only* channel — bind that
166
+ * one for analytics or a confirmation prompt, where a programmatic write must
167
+ * not count as a click. Writing back into the same form from a
168
+ * `(valueChange)` handler will echo.
169
+ */
128
170
  readonly value: _angular_core.ModelSignal<T | null>;
129
171
  /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the group uses the `TW_ERROR_STATE_MATCHER` token's value. */
130
172
  readonly errorStateMatcher: _angular_core.InputSignal<ErrorStateMatcher | undefined>;
131
- /** Fires after the selected value changes from a user interaction. Does not fire when the value is updated programmatically via `writeValue`. */
173
+ /**
174
+ * Fires after the selected value changes from a user interaction. Does
175
+ * **not** fire when the value is updated programmatically via `writeValue` /
176
+ * `FormControl.setValue` / `ngModel` — for those, bind the two-way binding's
177
+ * `(valueChange)` instead, which fires on any change.
178
+ */
132
179
  readonly change: _angular_core.OutputEmitterRef<T | null>;
133
180
  /** @internal Child radios discovered via content projection. */
134
181
  readonly radios: Signal<readonly RadioComponent[]>;
@@ -136,15 +183,10 @@ declare class RadioGroupComponent<T = unknown> implements ControlValueAccessor,
136
183
  private readonly elementRef;
137
184
  private readonly destroyRef;
138
185
  private readonly ngControl;
139
- private readonly parentForm;
140
- private readonly parentFormGroup;
141
- private readonly defaultMatcher;
142
186
  readonly hostId: string;
143
187
  private onChange;
144
188
  private onTouched;
145
189
  private readonly cvaDisabled;
146
- private readonly _ngControlRev;
147
- private readonly _formSubmitRev;
148
190
  /** Effective disabled state — input OR CVA disabled. */
149
191
  readonly isDisabled: Signal<boolean>;
150
192
  /** Group-level error state per the configured `ErrorStateMatcher`. Reads the bound `NgControl.invalid` through the matcher; child radios inherit from this when wrapped in the group. */
@@ -157,6 +199,7 @@ declare class RadioGroupComponent<T = unknown> implements ControlValueAccessor,
157
199
  selectValue(next: unknown): void;
158
200
  /** @internal Called by child radios on blur — propagates to CVA onTouched and bumps the errorState revision so a blur on a child radio refreshes the group's `aria-invalid`. */
159
201
  notifyTouched(): void;
202
+ /** @internal Handles roving-focus keyboard navigation (Arrow keys, Space) across the radios in the group. */
160
203
  onKeydown(event: KeyboardEvent): void;
161
204
  private findNextEnabledIndex;
162
205
  private firstEnabledIndex;
@@ -167,7 +210,7 @@ declare class RadioGroupComponent<T = unknown> implements ControlValueAccessor,
167
210
  setDisabledState(isDisabled: boolean): void;
168
211
  ngOnInit(): void;
169
212
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RadioGroupComponent<any>, never>;
170
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<RadioGroupComponent<any>, "tw-radio-group", never, { "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "ariaDescribedby": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "change": "change"; }, ["radios"], ["*"], true, never>;
213
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<RadioGroupComponent<any>, "tw-radio-group", never, { "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "requiredInput": { "alias": "required"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "ariaDescribedby": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "change": "change"; }, ["radios"], ["*"], true, never>;
171
214
  }
172
215
 
173
216
  export { RadioComponent, RadioGroupComponent };
@@ -1,10 +1,19 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { ElementRef } from '@angular/core';
2
+ import { OnInit, Signal, ElementRef } from '@angular/core';
3
3
  import { ControlValueAccessor } from '@angular/forms';
4
- import { TwColor, TwSize, TwOrientation } from '@cdevhub/ngx-tw/core';
4
+ import { TwColor, TwSize, TwOrientation, ErrorStateMatcher } from '@cdevhub/ngx-tw/core';
5
5
 
6
6
  /** Visual style of the active indicator. */
7
- type SegmentedControlVariant = 'surface' | 'filled' | 'outline';
7
+ type SegmentedControlVariant = 'surface' | 'solid' | 'outline' | SegmentedControlVariantLegacy;
8
+ /**
9
+ * Legacy `variant` spellings, kept so existing templates keep compiling.
10
+ *
11
+ * @deprecated `'filled'` is an alias for `'solid'`; it will be removed in the next
12
+ * major. Prefer `'solid'`.
13
+ */
14
+ type SegmentedControlVariantLegacy = 'filled';
15
+ /** Canonical `variant` spellings — the set `tv()` actually keys on. */
16
+ type SegmentedControlVariantCanonical = Exclude<SegmentedControlVariant, SegmentedControlVariantLegacy>;
8
17
  /** Border-radius shape of the container and options. */
9
18
  type SegmentedControlRounded = 'pill' | 'md';
10
19
  declare class SegmentedControlOptionComponent {
@@ -16,17 +25,19 @@ declare class SegmentedControlOptionComponent {
16
25
  private readonly parent;
17
26
  readonly id: string;
18
27
  constructor();
19
- readonly isActive: _angular_core.Signal<boolean>;
20
- readonly isDisabled: _angular_core.Signal<boolean>;
21
- readonly isFocusable: _angular_core.Signal<boolean>;
22
- readonly classes: _angular_core.Signal<string>;
28
+ readonly isActive: Signal<boolean>;
29
+ readonly isDisabled: Signal<boolean>;
30
+ readonly isFocusable: Signal<boolean>;
31
+ readonly classes: Signal<string>;
32
+ /** Selects this option in the parent segmented control. No-op when the option is disabled. */
23
33
  select(): void;
34
+ /** 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). */
24
35
  focus(): void;
25
36
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SegmentedControlOptionComponent, never>;
26
37
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<SegmentedControlOptionComponent, "tw-segmented-option", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
27
38
  }
28
- declare class SegmentedControlComponent implements ControlValueAccessor {
29
- /** 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'`. */
39
+ declare class SegmentedControlComponent implements ControlValueAccessor, OnInit {
40
+ /** 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'`. */
30
41
  readonly variant: _angular_core.InputSignal<SegmentedControlVariant>;
31
42
  /** Sets the semantic color for the active option indicator. Defaults to `'primary'`. */
32
43
  readonly color: _angular_core.InputSignal<TwColor>;
@@ -38,29 +49,81 @@ declare class SegmentedControlComponent implements ControlValueAccessor {
38
49
  readonly rounded: _angular_core.InputSignal<SegmentedControlRounded>;
39
50
  /** When true, prevents all interaction and applies muted styling. Defaults to `false`. */
40
51
  readonly disabled: _angular_core.InputSignal<boolean>;
41
- /** The value of the currently selected option. Two-way bound. Updates on user selection. */
52
+ /** 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`. */
53
+ readonly requiredInput: _angular_core.InputSignal<boolean>;
54
+ /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the control uses the `TW_ERROR_STATE_MATCHER` token's value. */
55
+ readonly errorStateMatcher: _angular_core.InputSignal<ErrorStateMatcher | undefined>;
56
+ /**
57
+ * The value of the currently selected option. Two-way bound. Defaults to
58
+ * `null`.
59
+ *
60
+ * The two-way binding mints a `valueChange` output, and it is the
61
+ * *any-change* channel: it fires on user selection **and** on a programmatic
62
+ * write from a bound form (`FormControl.setValue`, `ngModel`, `writeValue`).
63
+ * Unlike `tw-checkbox` / `tw-switch` / `tw-radio-group`, this control ships no
64
+ * separate gesture-only `change` output, so writing back into the same form
65
+ * from a `(valueChange)` handler will echo. To act on user selection alone,
66
+ * compare against the value you last wrote, or listen on the form control.
67
+ */
42
68
  readonly value: _angular_core.ModelSignal<string | null>;
43
69
  /** @internal */
44
- readonly options: _angular_core.Signal<readonly SegmentedControlOptionComponent[]>;
70
+ readonly options: Signal<readonly SegmentedControlOptionComponent[]>;
71
+ private readonly elementRef;
72
+ private readonly ngControl;
73
+ /**
74
+ * Optional so a consumer that never imports `BidiModule` still gets a working
75
+ * control — arrow navigation falls back to LTR when the token is absent. Read
76
+ * imperatively inside the keydown handler; nothing here needs to re-render on
77
+ * a direction change.
78
+ */
79
+ private readonly directionality;
45
80
  private onChange;
46
81
  private onTouched;
47
82
  private readonly cvaDisabled;
48
- readonly isDisabled: _angular_core.Signal<boolean>;
83
+ /** @internal Shared `errorState` / `required` / `errors` derivation — see `wireErrorState`. */
84
+ private readonly errorWiring;
85
+ constructor();
86
+ readonly isDisabled: Signal<boolean>;
87
+ /**
88
+ * @internal Resolved required state: the `required` input OR'd with
89
+ * `Validators.required` on a bound `NgControl`. The OR (rather than a
90
+ * validator-only read) is what keeps signal forms working — `cvaControlCreate`
91
+ * writes the `required` *input* directly from the field state and never
92
+ * consults validators, so the input arm carries that branch while the
93
+ * validator arm carries reactive/template-driven forms.
94
+ */
95
+ readonly required: Signal<boolean>;
96
+ /** @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. */
97
+ readonly errorState: Signal<boolean>;
49
98
  readonly activeValue: _angular_core.WritableSignal<string | null>;
50
99
  /** @internal Read by `SegmentedControlOptionComponent.classes` to resolve the option's tv() bucket. Vertical orientation forces `'md'` regardless of input. */
51
- readonly effectiveRounded: _angular_core.Signal<SegmentedControlRounded>;
100
+ readonly effectiveRounded: Signal<SegmentedControlRounded>;
101
+ /** @internal Canonical variant with legacy spellings folded in. Read by `SegmentedControlOptionComponent.classes` to resolve the option's tv() bucket. */
102
+ readonly resolvedVariant: Signal<SegmentedControlVariantCanonical>;
52
103
  private readonly variantResult;
53
- readonly rootClasses: _angular_core.Signal<string>;
104
+ readonly rootClasses: Signal<string>;
105
+ /** 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. */
54
106
  selectOption(val: string): void;
107
+ /**
108
+ * @internal Blur notification for the CVA contract. Fires `onTouched` only
109
+ * when focus leaves the radiogroup entirely — roving focus moves between
110
+ * option elements inside the group, and each of those hops raises `focusout`
111
+ * on the host too. Without this the control is only ever marked `touched` by
112
+ * a selection, so a user who tabs through without choosing never surfaces the
113
+ * `required` error.
114
+ */
115
+ onFocusOut(event: FocusEvent): void;
116
+ /** @internal Handles roving-focus keyboard navigation (Arrow keys, Home, End) and Space / Enter activation across the option group. */
55
117
  onKeydown(event: KeyboardEvent): void;
56
118
  private findNextEnabledIndex;
57
119
  writeValue(val: string | null): void;
58
120
  registerOnChange(fn: (value: string | null) => void): void;
59
121
  registerOnTouched(fn: () => void): void;
60
122
  setDisabledState(isDisabled: boolean): void;
123
+ ngOnInit(): void;
61
124
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SegmentedControlComponent, never>;
62
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SegmentedControlComponent, "tw-segmented-control", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, ["options"], ["*"], true, never>;
125
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SegmentedControlComponent, "tw-segmented-control", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "requiredInput": { "alias": "required"; "required": false; "isSignal": true; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, ["options"], ["*"], true, never>;
63
126
  }
64
127
 
65
128
  export { SegmentedControlComponent, SegmentedControlOptionComponent };
66
- export type { SegmentedControlRounded, SegmentedControlVariant };
129
+ export type { SegmentedControlRounded, SegmentedControlVariant, SegmentedControlVariantLegacy };
@@ -0,0 +1,114 @@
1
+ import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
2
+
3
+ /** Filters accepted by `SelectOptionHarness.with`. */
4
+ interface SelectOptionHarnessFilters extends BaseHarnessFilters {
5
+ /** Match by the option's visible text. */
6
+ text?: string | RegExp;
7
+ /** Match selected / unselected options. */
8
+ selected?: boolean;
9
+ /** Match disabled / enabled options. */
10
+ disabled?: boolean;
11
+ }
12
+ /**
13
+ * Harness for a single option inside an open `tw-select` panel.
14
+ *
15
+ * Options render into the CDK overlay, not inside `tw-select`, so they are
16
+ * reached through {@link SelectHarness} rather than located directly against a
17
+ * fixture.
18
+ */
19
+ declare class SelectOptionHarness extends ComponentHarness {
20
+ static hostSelector: string;
21
+ /** Predicate for `locatorFor` / `locatorForAll`. */
22
+ static with(options?: SelectOptionHarnessFilters): HarnessPredicate<SelectOptionHarness>;
23
+ /** The option's rendered text, trimmed. */
24
+ getText(): Promise<string>;
25
+ /** Whether the option reports `aria-selected="true"`. */
26
+ isSelected(): Promise<boolean>;
27
+ /** Whether the option reports `aria-disabled="true"`. */
28
+ isDisabled(): Promise<boolean>;
29
+ /** Clicks the option. A disabled option ignores the click, as in the browser. */
30
+ click(): Promise<void>;
31
+ }
32
+
33
+ /** Filters accepted by `SelectHarness.with`. */
34
+ interface SelectHarnessFilters extends BaseHarnessFilters {
35
+ /** Match by the trigger's accessible name. */
36
+ label?: string | RegExp;
37
+ /** Match by the text currently displayed in the trigger. */
38
+ triggerText?: string | RegExp;
39
+ /** Match disabled / enabled selects. */
40
+ disabled?: boolean;
41
+ }
42
+ /**
43
+ * Harness for `tw-select`.
44
+ *
45
+ * The options panel renders into the CDK overlay container, outside the
46
+ * `tw-select` host, so this harness resolves it through
47
+ * `documentRootLocatorFactory()`. A consumer can therefore load this harness
48
+ * from the ordinary fixture loader and still reach the options — no
49
+ * `documentRootLoader` ceremony required.
50
+ *
51
+ * The panel is *disposed* on close rather than merely detached, so option
52
+ * harnesses must be re-read after each `open()`. Do not cache them across a
53
+ * close.
54
+ */
55
+ declare class SelectHarness extends ComponentHarness {
56
+ static hostSelector: string;
57
+ private readonly trigger;
58
+ private readonly clearButton;
59
+ /** Resolves the overlay panel, which lives outside this harness's host. */
60
+ private readonly panel;
61
+ /** Predicate for `locatorFor` / `locatorForAll`. */
62
+ static with(options?: SelectHarnessFilters): HarnessPredicate<SelectHarness>;
63
+ /** The trigger's accessible name, from `aria-label` when one is set. */
64
+ getLabel(): Promise<string | null>;
65
+ /**
66
+ * The text currently rendered in the trigger, trimmed. This is the
67
+ * placeholder when the select holds no value.
68
+ */
69
+ getTriggerText(): Promise<string>;
70
+ /** Whether the panel is open, read from the trigger's `aria-expanded`. */
71
+ isOpen(): Promise<boolean>;
72
+ /** Whether the trigger reports `aria-disabled="true"`. */
73
+ isDisabled(): Promise<boolean>;
74
+ /** Whether the trigger reports `aria-invalid="true"`. */
75
+ isInvalid(): Promise<boolean>;
76
+ /** Whether the trigger reports `aria-required="true"`. */
77
+ isRequired(): Promise<boolean>;
78
+ /** Opens the panel. No-op when already open. */
79
+ open(): Promise<void>;
80
+ /** Closes the panel with Escape. No-op when already closed. */
81
+ close(): Promise<void>;
82
+ /**
83
+ * Every option in the open panel. Returns an empty array when the panel is
84
+ * closed, because the overlay is disposed rather than hidden.
85
+ */
86
+ getOptions(filters?: SelectOptionHarnessFilters): Promise<SelectOptionHarness[]>;
87
+ /**
88
+ * Opens the panel if needed and clicks the first option whose text matches.
89
+ * Throws when nothing matches, rather than failing silently.
90
+ */
91
+ selectOption(text: string | RegExp): Promise<void>;
92
+ /**
93
+ * The text of every currently selected option. Opens the panel if needed,
94
+ * because selection state is exposed on the options, which only exist while
95
+ * the panel is attached.
96
+ */
97
+ getSelectedOptionTexts(): Promise<string[]>;
98
+ /**
99
+ * Whether a clear control is rendered. `tw-select` has no `clearable` input —
100
+ * the control appears whenever the select is enabled and holds a value.
101
+ */
102
+ hasClearButton(): Promise<boolean>;
103
+ /**
104
+ * Clicks the clear control. Throws when none is rendered.
105
+ *
106
+ * The control is a native `<button>` and a *sibling* of the trigger, not a
107
+ * descendant — HTML's content model forbids interactive content inside a
108
+ * `<button>`.
109
+ */
110
+ clear(): Promise<void>;
111
+ }
112
+
113
+ export { SelectHarness, SelectOptionHarness };
114
+ export type { SelectHarnessFilters, SelectOptionHarnessFilters };