@cdevhub/ngx-tw 0.4.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-dialog-renderer-DoIhoV3d.mjs +198 -0
  47. package/fesm2022/cdevhub-ngx-tw-dialog-dialog-renderer-DoIhoV3d.mjs.map +1 -0
  48. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs +122 -0
  49. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs.map +1 -0
  50. package/fesm2022/cdevhub-ngx-tw-dialog.mjs +199 -220
  51. package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
  52. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +1 -1
  53. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
  54. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs +149 -0
  55. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs.map +1 -0
  56. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +57 -67
  57. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -1
  58. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +42 -24
  59. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
  60. package/fesm2022/cdevhub-ngx-tw-form-field.mjs +114 -21
  61. package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
  62. package/fesm2022/cdevhub-ngx-tw-icon.mjs +16 -6
  63. package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
  64. package/fesm2022/cdevhub-ngx-tw-input.mjs +52 -61
  65. package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
  66. package/fesm2022/cdevhub-ngx-tw-item.mjs +18 -3
  67. package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
  68. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs +168 -0
  69. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs.map +1 -0
  70. package/fesm2022/cdevhub-ngx-tw-menu.mjs +58 -21
  71. package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
  72. package/fesm2022/cdevhub-ngx-tw-number-input.mjs +34 -1
  73. package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -1
  74. package/fesm2022/cdevhub-ngx-tw-paginator.mjs +95 -45
  75. package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
  76. package/fesm2022/cdevhub-ngx-tw-popover.mjs +81 -32
  77. package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
  78. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +1 -1
  79. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
  80. package/fesm2022/cdevhub-ngx-tw-radio.mjs +131 -98
  81. package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
  82. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +207 -42
  83. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
  84. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs +165 -0
  85. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs.map +1 -0
  86. package/fesm2022/cdevhub-ngx-tw-select.mjs +386 -210
  87. package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
  88. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs +256 -0
  89. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs.map +1 -0
  90. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs +129 -0
  91. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs.map +1 -0
  92. package/fesm2022/cdevhub-ngx-tw-sheet.mjs +197 -278
  93. package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
  94. package/fesm2022/cdevhub-ngx-tw-slider.mjs +89 -54
  95. package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
  96. package/fesm2022/cdevhub-ngx-tw-sort.mjs +122 -17
  97. package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
  98. package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -19
  99. package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
  100. package/fesm2022/cdevhub-ngx-tw-stat.mjs +63 -25
  101. package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
  102. package/fesm2022/cdevhub-ngx-tw-stepper.mjs +35 -8
  103. package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
  104. package/fesm2022/cdevhub-ngx-tw-switch.mjs +54 -48
  105. package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
  106. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +12 -15
  107. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
  108. package/fesm2022/cdevhub-ngx-tw-table.mjs +74 -13
  109. package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
  110. package/fesm2022/cdevhub-ngx-tw-tabs.mjs +84 -30
  111. package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
  112. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs +172 -0
  113. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs.map +1 -0
  114. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +107 -71
  115. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -1
  116. package/fesm2022/cdevhub-ngx-tw-textarea.mjs +41 -9
  117. package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
  118. package/fesm2022/cdevhub-ngx-tw-theme.mjs +257 -45
  119. package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
  120. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs +201 -0
  121. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs.map +1 -0
  122. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +184 -77
  123. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
  124. package/fesm2022/cdevhub-ngx-tw-timeline.mjs +110 -27
  125. package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
  126. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs +616 -0
  127. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs.map +1 -0
  128. package/fesm2022/cdevhub-ngx-tw-toast.mjs +556 -945
  129. package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
  130. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +102 -15
  131. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
  132. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs +219 -0
  133. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs.map +1 -0
  134. package/fesm2022/cdevhub-ngx-tw-transfer.mjs +88 -69
  135. package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -1
  136. package/fesm2022/cdevhub-ngx-tw-tree.mjs +68 -19
  137. package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -1
  138. package/index.json +1 -1
  139. package/package.json +63 -2
  140. package/theme/_base.css +13 -0
  141. package/theme/_dark.css +110 -36
  142. package/theme/_high-contrast-dark.css +367 -0
  143. package/theme/_high-contrast.css +13 -2
  144. package/theme/_light.css +276 -0
  145. package/theme/_semantic.css +47 -12
  146. package/theme/_typography.css +17 -0
  147. package/theme/index.css +86 -7
  148. package/types/cdevhub-ngx-tw-accordion.d.ts +12 -4
  149. package/types/cdevhub-ngx-tw-avatar.d.ts +10 -3
  150. package/types/cdevhub-ngx-tw-button.d.ts +1 -0
  151. package/types/cdevhub-ngx-tw-calendar-luxon.d.ts +2 -2
  152. package/types/cdevhub-ngx-tw-calendar-testing.d.ts +1 -1
  153. package/types/cdevhub-ngx-tw-calendar.d.ts +179 -73
  154. package/types/cdevhub-ngx-tw-card.d.ts +11 -3
  155. package/types/cdevhub-ngx-tw-carousel.d.ts +89 -20
  156. package/types/cdevhub-ngx-tw-checkbox.d.ts +40 -12
  157. package/types/cdevhub-ngx-tw-code-block.d.ts +11 -2
  158. package/types/cdevhub-ngx-tw-collapsible.d.ts +32 -5
  159. package/types/cdevhub-ngx-tw-combobox-testing.d.ts +157 -0
  160. package/types/cdevhub-ngx-tw-combobox.d.ts +94 -53
  161. package/types/cdevhub-ngx-tw-command-palette-testing.d.ts +136 -0
  162. package/types/cdevhub-ngx-tw-command-palette.d.ts +33 -5
  163. package/types/cdevhub-ngx-tw-core.d.ts +152 -21
  164. package/types/cdevhub-ngx-tw-date-picker-testing.d.ts +141 -0
  165. package/types/cdevhub-ngx-tw-date-picker.d.ts +37 -29
  166. package/types/cdevhub-ngx-tw-date-range-picker-testing.d.ts +148 -0
  167. package/types/cdevhub-ngx-tw-date-range-picker.d.ts +36 -29
  168. package/types/cdevhub-ngx-tw-dialog-testing.d.ts +98 -0
  169. package/types/cdevhub-ngx-tw-dialog.d.ts +89 -19
  170. package/types/cdevhub-ngx-tw-file-upload-testing.d.ts +120 -0
  171. package/types/cdevhub-ngx-tw-file-upload.d.ts +8 -10
  172. package/types/cdevhub-ngx-tw-flip-card.d.ts +18 -11
  173. package/types/cdevhub-ngx-tw-form-field.d.ts +19 -2
  174. package/types/cdevhub-ngx-tw-icon.d.ts +3 -3
  175. package/types/cdevhub-ngx-tw-input.d.ts +5 -8
  176. package/types/cdevhub-ngx-tw-item.d.ts +2 -0
  177. package/types/cdevhub-ngx-tw-menu-testing.d.ts +131 -0
  178. package/types/cdevhub-ngx-tw-menu.d.ts +2 -2
  179. package/types/cdevhub-ngx-tw-number-input.d.ts +20 -0
  180. package/types/cdevhub-ngx-tw-paginator.d.ts +58 -24
  181. package/types/cdevhub-ngx-tw-popover.d.ts +41 -10
  182. package/types/cdevhub-ngx-tw-progress-bar.d.ts +1 -1
  183. package/types/cdevhub-ngx-tw-radio.d.ts +68 -25
  184. package/types/cdevhub-ngx-tw-segmented-control.d.ts +79 -16
  185. package/types/cdevhub-ngx-tw-select-testing.d.ts +114 -0
  186. package/types/cdevhub-ngx-tw-select.d.ts +104 -33
  187. package/types/cdevhub-ngx-tw-sheet-testing.d.ts +104 -0
  188. package/types/cdevhub-ngx-tw-sheet.d.ts +96 -21
  189. package/types/cdevhub-ngx-tw-slider.d.ts +79 -25
  190. package/types/cdevhub-ngx-tw-sort.d.ts +45 -4
  191. package/types/cdevhub-ngx-tw-split.d.ts +32 -2
  192. package/types/cdevhub-ngx-tw-stat.d.ts +14 -4
  193. package/types/cdevhub-ngx-tw-stepper.d.ts +16 -2
  194. package/types/cdevhub-ngx-tw-switch.d.ts +35 -13
  195. package/types/cdevhub-ngx-tw-tab-nav.d.ts +7 -6
  196. package/types/cdevhub-ngx-tw-table.d.ts +53 -10
  197. package/types/cdevhub-ngx-tw-tabs.d.ts +41 -10
  198. package/types/cdevhub-ngx-tw-tags-input-testing.d.ts +135 -0
  199. package/types/cdevhub-ngx-tw-tags-input.d.ts +26 -11
  200. package/types/cdevhub-ngx-tw-textarea.d.ts +3 -2
  201. package/types/cdevhub-ngx-tw-theme.d.ts +245 -39
  202. package/types/cdevhub-ngx-tw-time-picker-testing.d.ts +129 -0
  203. package/types/cdevhub-ngx-tw-time-picker.d.ts +76 -19
  204. package/types/cdevhub-ngx-tw-timeline.d.ts +36 -12
  205. package/types/cdevhub-ngx-tw-toast.d.ts +61 -12
  206. package/types/cdevhub-ngx-tw-tooltip.d.ts +28 -6
  207. package/types/cdevhub-ngx-tw-transfer-testing.d.ts +152 -0
  208. package/types/cdevhub-ngx-tw-transfer.d.ts +21 -8
  209. package/types/cdevhub-ngx-tw-tree.d.ts +6 -1
@@ -4,6 +4,17 @@ import * as _angular_core from '@angular/core';
4
4
  import { Signal, ElementRef } from '@angular/core';
5
5
  import { TwOrientation, TwSize, TwColor } from '@cdevhub/ngx-tw/core';
6
6
 
7
+ /**
8
+ * Carousel public types.
9
+ *
10
+ * This file is the leaf of the carousel entry point's import graph: it holds
11
+ * only type declarations and imports nothing, so every other file in the
12
+ * directory can read from it without creating a cycle. Concretely,
13
+ * `carousel-labels.ts` needs `TwCarouselLabels` while `carousel.ts` needs
14
+ * `DEFAULT_CAROUSEL_LABELS` back from it — with both declared in `carousel.ts`
15
+ * that pair is a genuine import cycle. Mirrors the `calendar/calendar.types.ts`
16
+ * precedent.
17
+ */
7
18
  /** Visual style of the indicators row rendered by `<tw-carousel-indicators>`. */
8
19
  type TwCarouselIndicatorVariant = 'dots' | 'lines' | 'numbers';
9
20
  /** Where the indicators sit relative to the carousel viewport. */
@@ -21,25 +32,32 @@ interface TwCarouselSlideChangeEvent {
21
32
  }
22
33
  /** Reason emitted when autoplay transitions running → paused. */
23
34
  type TwCarouselAutoplayReason = 'hover' | 'focus' | 'interaction' | 'visibility' | 'manual';
24
- /** Localizable strings for the carousel. */
35
+ /**
36
+ * Localizable strings for the carousel.
37
+ *
38
+ * Every member is optional. This interface only ever reaches consumers through
39
+ * `input<Partial<TwCarouselLabels>>`, and unset keys fall back to
40
+ * {@link DEFAULT_CAROUSEL_LABELS} — so a consumer holding an i18n bundle typed
41
+ * as `TwCarouselLabels` must not be forced to restate every key, and adding a
42
+ * label in a future minor must not break them on a non-major release.
43
+ */
25
44
  interface TwCarouselLabels {
26
45
  /** Accessible label for the Previous-slide directive host. Default: `'Previous slide'`. */
27
- previous: string;
46
+ previous?: string;
28
47
  /** Accessible label for the Next-slide directive host. Default: `'Next slide'`. */
29
- next: string;
48
+ next?: string;
30
49
  /** Accessible label for the autoplay pause control. Default: `'Pause autoplay'`. */
31
- pauseAutoplay: string;
50
+ pauseAutoplay?: string;
32
51
  /** Accessible label for the autoplay resume control. Default: `'Resume autoplay'`. */
33
- resumeAutoplay: string;
52
+ resumeAutoplay?: string;
34
53
  /** Template for indicator-button accessible names. Variable: `{page}` (1-based). Default: `'Go to slide {page}'`. */
35
- indicator: string;
54
+ indicator?: string;
36
55
  /** Template for per-slide accessible names with a custom label. Variables: `{index}` (1-based), `{total}`, `{label}`. Default: `'{index} of {total}: {label}'`. */
37
- slideOfWithLabel: string;
56
+ slideOfWithLabel?: string;
38
57
  /** Template for per-slide accessible names without a custom label. Variables: `{index}` (1-based), `{total}`. Default: `'{index} of {total}'`. */
39
- slideOf: string;
58
+ slideOf?: string;
40
59
  }
41
- /** Default English labels used when consumers do not override via the `labels` input. */
42
- declare const DEFAULT_CAROUSEL_LABELS: Readonly<TwCarouselLabels>;
60
+
43
61
  /**
44
62
  * A single slide inside a `<tw-carousel>`. Projects arbitrary content via its
45
63
  * default slot. Reports its visibility back to the carousel container via a
@@ -105,9 +123,9 @@ declare class CarouselComponent {
105
123
  readonly snapAlign: _angular_core.InputSignal<"start" | "center" | "end">;
106
124
  /** Two-way bound 0-based index of the first visible slide in the current page. Setting from the parent scrolls the viewport smoothly to align that slide; reading reflects user-driven scroll position after `scrollend`. Defaults to `0`. */
107
125
  readonly activeIndex: _angular_core.ModelSignal<number>;
108
- /** Accessible name for the carousel region. If both this and `ariaLabelledBy` are `null`, a one-time dev-mode `console.warn` is logged (production builds never log). Defaults to `null`. */
126
+ /** Accessible name for the carousel region. Mirrored to `aria-label`. If both this and `aria-labelledby` are `null`, a one-time dev-mode `console.warn` is logged (production builds never log). Defaults to `null`. */
109
127
  readonly ariaLabel: _angular_core.InputSignal<string | null>;
110
- /** ID of an element labeling the carousel. Either `ariaLabel` or `ariaLabelledBy` SHOULD be provided. Defaults to `null`. */
128
+ /** ID of an element labeling the carousel. Mirrored to `aria-labelledby`. Either `aria-label` or `aria-labelledby` SHOULD be provided. Defaults to `null`. */
111
129
  readonly ariaLabelledBy: _angular_core.InputSignal<string | null>;
112
130
  /** Localizable strings for prev/next/pause/resume/indicator/slide-of templates. Unset keys fall back to the English defaults in `DEFAULT_CAROUSEL_LABELS`. Defaults to `{}`. */
113
131
  readonly labels: _angular_core.InputSignal<Partial<TwCarouselLabels>>;
@@ -122,8 +140,19 @@ declare class CarouselComponent {
122
140
  readonly _viewportRef: Signal<ElementRef<HTMLDivElement>>;
123
141
  /** @internal Projected slides in DOM order. */
124
142
  readonly slides: Signal<readonly CarouselSlideComponent[]>;
125
- /** @internal Resolved label record with English defaults filled in. */
126
- readonly resolvedLabels: Signal<TwCarouselLabels>;
143
+ /**
144
+ * @internal Resolved label record with English defaults filled in.
145
+ *
146
+ * Explicitly-undefined keys are dropped before merging. Root `tsconfig.json`
147
+ * does not set `exactOptionalPropertyTypes`, so `[labels]="{ indicator:
148
+ * t('carousel.indicator') }"` type-checks even when `t()` returns
149
+ * `string | undefined` — and a plain spread would then overwrite the default
150
+ * with `undefined`, which reaches `formatLabel()` and throws
151
+ * `Cannot read properties of undefined (reading 'replace')` inside a
152
+ * `computed`, taking the whole render down. Same filter `table.ts` and
153
+ * `timeline.ts` already use; `Required<>` then guarantees a string per key.
154
+ */
155
+ readonly resolvedLabels: Signal<Required<TwCarouselLabels>>;
127
156
  /** @internal Effective `slidesPerView` clamped to `[0.5, slideCount]`. */
128
157
  readonly _effectiveSlidesPerView: Signal<number>;
129
158
  /** @internal Effective `slidesToScroll` floored to a positive integer. Read by child indicators directive (`CarouselIndicatorsComponent._onClick`) as a signal. */
@@ -185,6 +214,14 @@ declare class CarouselComponent {
185
214
  gap?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
186
215
  snapAlign?: "start" | "center" | "end" | undefined;
187
216
  } & tailwind_variants.ClassProp<tailwind_merge.ClassNameValue>) | undefined) => string;
217
+ indicatorTarget: (slotProps?: ({
218
+ variant?: "dots" | "lines" | "numbers" | undefined;
219
+ size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
220
+ orientation?: "horizontal" | "vertical" | undefined;
221
+ position?: "overlay" | "below" | undefined;
222
+ gap?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
223
+ snapAlign?: "start" | "center" | "end" | undefined;
224
+ } & tailwind_variants.ClassProp<tailwind_merge.ClassNameValue>) | undefined) => string;
188
225
  indicator: (slotProps?: ({
189
226
  variant?: "dots" | "lines" | "numbers" | undefined;
190
227
  size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
@@ -234,6 +271,14 @@ declare class CarouselComponent {
234
271
  gap?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
235
272
  snapAlign?: "start" | "center" | "end" | undefined;
236
273
  } & tailwind_variants.ClassProp<tailwind_merge.ClassNameValue>) | undefined) => string;
274
+ indicatorTarget: (slotProps?: ({
275
+ variant?: "dots" | "lines" | "numbers" | undefined;
276
+ size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
277
+ orientation?: "horizontal" | "vertical" | undefined;
278
+ position?: "overlay" | "below" | undefined;
279
+ gap?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
280
+ snapAlign?: "start" | "center" | "end" | undefined;
281
+ } & tailwind_variants.ClassProp<tailwind_merge.ClassNameValue>) | undefined) => string;
237
282
  indicator: (slotProps?: ({
238
283
  variant?: "dots" | "lines" | "numbers" | undefined;
239
284
  size?: "xs" | "sm" | "md" | "lg" | "xl" | undefined;
@@ -276,6 +321,8 @@ declare class CarouselComponent {
276
321
  private _onScrollEndBound;
277
322
  private _onScrollDebouncedBound;
278
323
  private _scrollDebounceTimer;
324
+ /** Handle for the post-interaction autoplay-pause expiry (see `_onPointerUp`). */
325
+ private _postInteractionPauseTimer;
279
326
  private _onVisibilityChangeBound;
280
327
  private _setupViewport;
281
328
  private _teardownViewport;
@@ -321,8 +368,9 @@ declare class CarouselComponent {
321
368
  _onKeydown(event: KeyboardEvent): void;
322
369
  _togglePauseControl(): void;
323
370
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<CarouselComponent, never>;
324
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<CarouselComponent, "tw-carousel", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "slidesPerView": { "alias": "slidesPerView"; "required": false; "isSignal": true; }; "slidesToScroll": { "alias": "slidesToScroll"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; "loop": { "alias": "loop"; "required": false; "isSignal": true; }; "autoplay": { "alias": "autoplay"; "required": false; "isSignal": true; }; "autoplayInterval": { "alias": "autoplayInterval"; "required": false; "isSignal": true; }; "pauseOnHover": { "alias": "pauseOnHover"; "required": false; "isSignal": true; }; "pauseOnFocusIn": { "alias": "pauseOnFocusIn"; "required": false; "isSignal": true; }; "draggable": { "alias": "draggable"; "required": false; "isSignal": true; }; "keyboard": { "alias": "keyboard"; "required": false; "isSignal": true; }; "snapAlign": { "alias": "snapAlign"; "required": false; "isSignal": true; }; "activeIndex": { "alias": "activeIndex"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "ariaLabelledBy"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "activeIndex": "activeIndexChange"; "slideChange": "slideChange"; "autoplayPaused": "autoplayPaused"; "autoplayResumed": "autoplayResumed"; }, ["slides"], ["tw-carousel-slide", "[twCarouselPrev], [twCarouselNext], tw-carousel-indicators", "*"], true, never>;
371
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<CarouselComponent, "tw-carousel", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "slidesPerView": { "alias": "slidesPerView"; "required": false; "isSignal": true; }; "slidesToScroll": { "alias": "slidesToScroll"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; "loop": { "alias": "loop"; "required": false; "isSignal": true; }; "autoplay": { "alias": "autoplay"; "required": false; "isSignal": true; }; "autoplayInterval": { "alias": "autoplayInterval"; "required": false; "isSignal": true; }; "pauseOnHover": { "alias": "pauseOnHover"; "required": false; "isSignal": true; }; "pauseOnFocusIn": { "alias": "pauseOnFocusIn"; "required": false; "isSignal": true; }; "draggable": { "alias": "draggable"; "required": false; "isSignal": true; }; "keyboard": { "alias": "keyboard"; "required": false; "isSignal": true; }; "snapAlign": { "alias": "snapAlign"; "required": false; "isSignal": true; }; "activeIndex": { "alias": "activeIndex"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "activeIndex": "activeIndexChange"; "slideChange": "slideChange"; "autoplayPaused": "autoplayPaused"; "autoplayResumed": "autoplayResumed"; }, ["slides"], ["tw-carousel-slide", "[twCarouselPrev], [twCarouselNext], tw-carousel-indicators", "*"], true, never>;
325
372
  }
373
+
326
374
  /**
327
375
  * Renders one button per **page** (not per slide) inside a `<tw-carousel>`.
328
376
  * The active button is marked with `aria-current="true"` and a distinguishing
@@ -340,7 +388,7 @@ declare class CarouselIndicatorsComponent {
340
388
  /** @internal Direct parent carousel. */
341
389
  readonly carousel: CarouselComponent;
342
390
  private readonly _variantResult;
343
- readonly rootClasses: Signal<string>;
391
+ readonly rootClasses: _angular_core.Signal<string>;
344
392
  /**
345
393
  * @internal Sequence of page indices to render. Returns `[]` when the
346
394
  * parent carousel's `slidesPerView` is not `1` — a single dot can never
@@ -350,14 +398,18 @@ declare class CarouselIndicatorsComponent {
350
398
  * `slidesPerView` back to `1` — the buttons reappear at that point without
351
399
  * a remount.
352
400
  */
353
- readonly _pages: Signal<number[]>;
401
+ readonly _pages: _angular_core.Signal<number[]>;
354
402
  constructor();
355
- _buttonClasses(page: number): string;
403
+ /** @internal Classes for the indicator `<button>` — the 24x24-floored hit target (SC 2.5.8). Identical for every page, so it is a computed rather than a per-page call. */
404
+ readonly _buttonClasses: _angular_core.Signal<string>;
405
+ /** @internal Classes for the painted mark inside the target: geometry from the `variant` × `size` compound variants, fill from the active/inactive lookup. */
406
+ _indicatorClasses(page: number): string;
356
407
  _buttonLabel(page: number): string;
357
408
  _onClick(page: number): void;
358
409
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<CarouselIndicatorsComponent, never>;
359
410
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<CarouselIndicatorsComponent, "tw-carousel-indicators", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
360
411
  }
412
+
361
413
  /**
362
414
  * Apply to any focusable element (typically `<button>`) inside a `<tw-carousel>`
363
415
  * to navigate to the previous page. Auto-disables at the first slide when the
@@ -372,7 +424,7 @@ declare class CarouselPrevDirective {
372
424
  private readonly _hasLabelledBy;
373
425
  private readonly _isButton;
374
426
  /** @internal True when prev is unavailable (at start and !loop). */
375
- readonly _isDisabled: Signal<boolean>;
427
+ readonly _isDisabled: _angular_core.Signal<boolean>;
376
428
  _ariaLabel(): string | null;
377
429
  _isButtonDisabled(): string | null;
378
430
  _isTabindex(): string | null;
@@ -393,7 +445,7 @@ declare class CarouselNextDirective {
393
445
  private readonly _consumerLabel;
394
446
  private readonly _hasLabelledBy;
395
447
  private readonly _isButton;
396
- readonly _isDisabled: Signal<boolean>;
448
+ readonly _isDisabled: _angular_core.Signal<boolean>;
397
449
  _ariaLabel(): string | null;
398
450
  _isButtonDisabled(): string | null;
399
451
  _isTabindex(): string | null;
@@ -402,5 +454,22 @@ declare class CarouselNextDirective {
402
454
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<CarouselNextDirective, "[twCarouselNext]", never, {}, {}, never, never, true, never>;
403
455
  }
404
456
 
457
+ /**
458
+ * Carousel label resolution — the English defaults and the `{placeholder}`
459
+ * interpolation both `CarouselSlideComponent` (per-slide `aria-label`) and
460
+ * `CarouselIndicatorsComponent` (per-page `aria-label`) read.
461
+ *
462
+ * `formatLabel` is exported so those two files can share one implementation;
463
+ * it is deliberately **not** re-exported from `index.ts` and carries no
464
+ * compatibility promise.
465
+ */
466
+
467
+ /**
468
+ * Default English labels used when consumers do not override via the `labels`
469
+ * input. Typed `Required<TwCarouselLabels>` so readers keep a non-optional
470
+ * `string` for every key even though the interface itself is all-optional.
471
+ */
472
+ declare const DEFAULT_CAROUSEL_LABELS: Readonly<Required<TwCarouselLabels>>;
473
+
405
474
  export { CarouselComponent, CarouselIndicatorsComponent, CarouselNextDirective, CarouselPrevDirective, CarouselSlideComponent, DEFAULT_CAROUSEL_LABELS };
406
475
  export type { TwCarouselAutoplayReason, TwCarouselIndicatorPosition, TwCarouselIndicatorVariant, TwCarouselLabels, TwCarouselSlideChangeEvent, TwCarouselSlideChangeTrigger };
@@ -27,36 +27,58 @@ declare class CheckboxComponent extends FormFieldControl<boolean> implements Con
27
27
  readonly labelPosition: _angular_core.InputSignal<CheckboxLabelPosition>;
28
28
  /** Optional name attribute, applied to the hidden native `<input type="checkbox">` so native form submission includes the control. */
29
29
  readonly name: _angular_core.InputSignal<string | undefined>;
30
- /** Id on the host element. Auto-generated as `tw-checkbox-N` when not provided. Used by the form-field's `<label for>` attribute. */
30
+ /** Id on the host element. Auto-generated as `tw-checkbox-N` when not provided. Anchors the derived label/description ids; the accessible name inside a `<tw-form-field>` comes from `aria-labelledby`, not from the field's `<label for>` (the host is a custom element, which `for` cannot target). */
31
31
  readonly idInput: _angular_core.InputSignal<string | undefined>;
32
- /** Accessible name when no visible label is provided. Mirrored to `aria-label`. */
32
+ /** Accessible name when no visible label is provided. Mirrored to `aria-label`. Defaults to `undefined`. */
33
33
  readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
34
- /** ID of an external element that labels the checkbox. Mirrored to `aria-labelledby`. */
34
+ /** ID of an external element that labels the checkbox. Mirrored to `aria-labelledby`. Defaults to `undefined`. */
35
35
  readonly ariaLabelledby: _angular_core.InputSignal<string | undefined>;
36
- /** ID of an external element that describes the checkbox. Mirrored to `aria-describedby`. Form-field merges its hint/error ids alongside. */
36
+ /** ID of an external element that describes the checkbox. Mirrored to `aria-describedby`. Form-field merges its hint/error ids alongside. Defaults to `undefined`. */
37
37
  readonly ariaDescribedby: _angular_core.InputSignal<string | undefined>;
38
38
  /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the directive uses the `TW_ERROR_STATE_MATCHER` token's value. */
39
39
  readonly errorStateMatcher: _angular_core.InputSignal<ErrorStateMatcher | undefined>;
40
- /** Two-way bound checked state. Updates when the user toggles via click or Space. */
40
+ /**
41
+ * Two-way bound checked state. Updates when the user toggles via click or
42
+ * Space, **and** when a bound form writes into the control
43
+ * (`FormControl.setValue`, `ngModel`, `writeValue`). Defaults to `false`.
44
+ *
45
+ * The two-way binding mints a `checkedChange` output. That output is the
46
+ * *any-change* channel: it fires on programmatic writes as well as user
47
+ * gestures. `(change)` is the *user-gesture-only* channel. Bind
48
+ * `(checkedChange)` to mirror state; bind `(change)` for analytics or a
49
+ * confirmation prompt, where a programmatic write must not count as a click.
50
+ * Writing back into the same form from a `(checkedChange)` handler will echo.
51
+ */
41
52
  readonly checked: _angular_core.ModelSignal<boolean>;
42
- /** Two-way bound indeterminate state. When true, the box shows a dash and the host exposes `aria-checked="mixed"`. Any user toggle clears indeterminate and sets `checked` to `true`. */
53
+ /**
54
+ * Two-way bound indeterminate state. When true, the box shows a dash and the
55
+ * host exposes `aria-checked="mixed"`. Any user toggle clears indeterminate
56
+ * and sets `checked` to `true`. Defaults to `false`.
57
+ *
58
+ * Its minted `indeterminateChange` output follows the same rule as
59
+ * `checkedChange`: it also fires when `writeValue` clears the state, so it is
60
+ * an any-change channel, not a gesture channel.
61
+ */
43
62
  readonly indeterminate: _angular_core.ModelSignal<boolean>;
44
- /** Fires after the checked state changes from a user interaction. Does not fire when the value is updated programmatically via `writeValue`. */
63
+ /**
64
+ * Fires after the checked state changes from a user interaction (click or
65
+ * Space). Does **not** fire when the value is updated programmatically via
66
+ * `writeValue` / `FormControl.setValue` / `ngModel` — for those, bind the
67
+ * two-way binding's `(checkedChange)` instead, which fires on any change.
68
+ */
45
69
  readonly change: _angular_core.OutputEmitterRef<boolean>;
46
70
  private readonly focusMonitor;
47
71
  private readonly elementRef;
48
72
  private readonly destroyRef;
49
73
  private readonly ngControl;
50
- private readonly parentForm;
51
- private readonly parentFormGroup;
52
- private readonly defaultMatcher;
53
74
  private onChange;
54
75
  private onTouched;
55
76
  private readonly cvaDisabled;
56
77
  private readonly _focused;
57
- private readonly _ngControlRev;
58
- private readonly _formSubmitRev;
78
+ /** @internal Shared `errorState` / `required` / `errors` derivation — see `wireErrorState`. */
79
+ private readonly errorWiring;
59
80
  private readonly describedByIdsSignal;
81
+ private readonly labelledByIdsSignal;
60
82
  private readonly uid;
61
83
  /** @internal Fallback id used when the consumer does not set `[id]`. */
62
84
  readonly hostId: string;
@@ -99,10 +121,14 @@ declare class CheckboxComponent extends FormFieldControl<boolean> implements Con
99
121
  readonly required: Signal<boolean>;
100
122
  /** @internal */
101
123
  readonly errorState: Signal<boolean>;
124
+ /** @internal Active validation errors map from the bound `NgControl`. Drives `[twError match="…"]` inside a wrapping `tw-form-field`; without it the form-field's key set is permanently empty and every `match`ed error stays hidden. */
125
+ readonly errors: Signal<Record<string, unknown> | null>;
102
126
  /** @internal */
103
127
  readonly controlType = "checkbox";
104
128
  /** @internal */
105
129
  readonly userAriaDescribedBy: Signal<string | undefined>;
130
+ /** @internal Consumer-supplied `aria-labelledby`, surfaced so the wrapping form-field merges it into the ids it pushes back rather than replacing it. */
131
+ readonly userAriaLabelledby: Signal<string | undefined>;
106
132
  private readonly variantResult;
107
133
  readonly rootClasses: Signal<string>;
108
134
  readonly boxWrapClasses: Signal<string>;
@@ -124,6 +150,8 @@ declare class CheckboxComponent extends FormFieldControl<boolean> implements Con
124
150
  setDisabledState(isDisabled: boolean): void;
125
151
  /** @internal Called by the form-field once it has computed the merged describedby ids. */
126
152
  setDescribedByIds(ids: string[]): void;
153
+ /** @internal Receives the merged `aria-labelledby` ids from the wrapping form-field. Required because the host is a custom element rather than a labelable control, so the field's `<label for>` never reaches it. */
154
+ setLabelledByIds(ids: string[]): void;
127
155
  /** @internal Called when the form-field container is clicked — focus the host without toggling. */
128
156
  onContainerClick(event: MouseEvent): void;
129
157
  ngOnInit(): void;
@@ -1,7 +1,14 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
 
3
3
  /** Visual style of the code block container. */
4
- type CodeBlockVariant = 'filled' | 'outlined';
4
+ type CodeBlockVariant = 'solid' | 'outline' | CodeBlockVariantLegacy;
5
+ /**
6
+ * Legacy `variant` spellings, kept so existing templates keep compiling.
7
+ * @deprecated `'filled'` is an alias for `'solid'` and `'outlined'` an alias
8
+ * for `'outline'`; both render identically to their replacements and will be
9
+ * removed in the next major. Prefer `'solid'` / `'outline'`.
10
+ */
11
+ type CodeBlockVariantLegacy = 'filled' | 'outlined';
5
12
  /**
6
13
  * Localizable strings used by the code block. Provide a partial override —
7
14
  * any missing fields fall back to English defaults.
@@ -51,7 +58,7 @@ declare class CodeBlockComponent {
51
58
  readonly code: _angular_core.InputSignal<string>;
52
59
  /** Optional language label displayed in the header (e.g. `'TypeScript'`, `'HTML'`). */
53
60
  readonly language: _angular_core.InputSignal<string | undefined>;
54
- /** Visual style of the container. Defaults to `'filled'`. */
61
+ /** Visual style of the container. Defaults to `'solid'`. `'filled'` and `'outlined'` are deprecated aliases for `'solid'` and `'outline'` and render identically. */
55
62
  readonly variant: _angular_core.InputSignal<CodeBlockVariant>;
56
63
  /** When true, wraps long lines instead of horizontal scrolling. Defaults to `false`. */
57
64
  readonly wrap: _angular_core.InputSignalWithTransform<boolean, unknown>;
@@ -76,6 +83,8 @@ declare class CodeBlockComponent {
76
83
  copied: string;
77
84
  announcement: string;
78
85
  }>;
86
+ /** @internal Canonical variant with legacy spellings folded in. */
87
+ private readonly resolvedVariant;
79
88
  private readonly variantResult;
80
89
  protected readonly rootClasses: _angular_core.Signal<string>;
81
90
  protected readonly headerClasses: _angular_core.Signal<string>;
@@ -4,16 +4,34 @@ import { FocusableOption } from '@angular/cdk/a11y';
4
4
  import { TwColor, TwSize } from '@cdevhub/ngx-tw/core';
5
5
 
6
6
  /** Visual style of the collapsible container. */
7
- type CollapsibleVariant = 'default' | 'bordered' | 'ghost' | 'filled';
7
+ type CollapsibleVariant = 'default' | 'outline' | 'ghost' | 'solid' | CollapsibleVariantLegacy;
8
+ /**
9
+ * Legacy `variant` spellings, kept so existing templates keep compiling.
10
+ * @deprecated `'bordered'` aliases `'outline'` and `'filled'` aliases
11
+ * `'solid'`. Both render identically to their replacements and will be
12
+ * removed in the next major.
13
+ */
14
+ type CollapsibleVariantLegacy = 'bordered' | 'filled';
15
+ /** Canonical `variant` spellings — the set `tv()` actually keys on. */
16
+ type CollapsibleVariantCanonical = Exclude<CollapsibleVariant, CollapsibleVariantLegacy>;
8
17
  /** Decorative axes bundled into a single collapsible input. */
9
18
  interface CollapsibleDisplay {
10
19
  /** Visual style of the panel container. Defaults to `'default'`. */
11
20
  variant?: CollapsibleVariant;
12
- /** Semantic color; applies to the `bordered` and `filled` variants. Defaults to `'neutral'`. */
21
+ /** Semantic color; applies to the `outline` and `solid` variants. Defaults to `'neutral'`. */
13
22
  color?: TwColor;
14
23
  /** Padding scale for the trigger and content sections. Defaults to `'md'`. */
15
24
  size?: TwSize;
16
25
  }
26
+ /**
27
+ * `CollapsibleDisplay` after defaults are filled in and legacy `variant`
28
+ * spellings are normalised. Module-private on purpose: narrowing `variant`
29
+ * to the canonical set is what makes the compiler prove the normalisation
30
+ * happened before `tv()` is called, and it is not consumer API.
31
+ */
32
+ type ResolvedCollapsibleDisplay = Required<Omit<CollapsibleDisplay, 'variant'>> & {
33
+ variant: CollapsibleVariantCanonical;
34
+ };
17
35
  declare class CollapsibleIconDirective {
18
36
  private readonly collapsible;
19
37
  /** @internal */
@@ -34,8 +52,11 @@ declare class CollapsibleTriggerDirective implements FocusableOption {
34
52
  readonly classes: _angular_core.Signal<string>;
35
53
  /** @internal */
36
54
  readonly iconClasses: _angular_core.Signal<string>;
55
+ /** @internal Toggles the parent collapsible when the trigger is clicked. */
37
56
  onClick(): void;
57
+ /** @internal Toggles on Enter/Space and delegates arrow-key navigation to the enclosing group. */
38
58
  onKeydown(event: KeyboardEvent): void;
59
+ /** Moves DOM focus to the trigger element. Called by `FocusKeyManager` during arrow-key navigation. */
39
60
  focus(): void;
40
61
  /** @internal FocusableOption: lets FocusKeyManager skip disabled triggers. */
41
62
  get disabled(): boolean;
@@ -45,7 +66,7 @@ declare class CollapsibleTriggerDirective implements FocusableOption {
45
66
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<CollapsibleTriggerDirective, "[twCollapsibleTrigger]", never, {}, {}, never, ["*"], true, never>;
46
67
  }
47
68
  declare class CollapsibleComponent {
48
- /** Unique identifier for this panel. Required when used inside a group. */
69
+ /** Unique identifier for this panel. Required when used inside a group. Defaults to an empty string. */
49
70
  readonly value: _angular_core.InputSignal<string>;
50
71
  /** Bundles decorative axes: `variant`, `color`, `size`. Accepts a partial; unset keys fall back to the defaults (`{ variant: 'default', color: 'neutral', size: 'md' }`). */
51
72
  readonly display: _angular_core.InputSignal<CollapsibleDisplay>;
@@ -73,8 +94,14 @@ declare class CollapsibleComponent {
73
94
  * lives next to the source — `activated()` reads cleanly as "derived from open".
74
95
  */
75
96
  readonly activated: _angular_core.WritableSignal<boolean>;
76
- /** @internal Resolved decorative configuration. */
77
- readonly resolvedDisplay: _angular_core.Signal<Required<CollapsibleDisplay>>;
97
+ /**
98
+ * @internal Resolved decorative configuration: defaults filled in, then
99
+ * legacy `variant` spellings folded onto their canonical replacements. The
100
+ * narrowed return type is the guard — `tv()` silently returns *base classes
101
+ * only* for a variant value it does not know, so an un-normalised legacy
102
+ * string would render an unstyled panel with no error anywhere.
103
+ */
104
+ readonly resolvedDisplay: _angular_core.Signal<ResolvedCollapsibleDisplay>;
78
105
  private readonly variantResult;
79
106
  readonly rootClasses: _angular_core.Signal<string>;
80
107
  readonly triggerClasses: _angular_core.Signal<string>;
@@ -0,0 +1,157 @@
1
+ import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
2
+
3
+ /** Filters accepted by `ComboboxOptionHarness.with`. */
4
+ interface ComboboxOptionHarnessFilters 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-combobox` panel.
14
+ *
15
+ * Options render into the CDK overlay, not inside `tw-combobox`, so they are
16
+ * reached through {@link ComboboxHarness} rather than located directly against
17
+ * a fixture.
18
+ *
19
+ * `tw-combobox` is an `aria-activedescendant` listbox: DOM focus never leaves
20
+ * the input, so an option is never the active element. Keyboard highlight is
21
+ * expressed on the input's `aria-activedescendant`, not on the option, and is
22
+ * therefore not exposed here.
23
+ */
24
+ declare class ComboboxOptionHarness extends ComponentHarness {
25
+ static hostSelector: string;
26
+ /** Predicate for `locatorFor` / `locatorForAll`. */
27
+ static with(options?: ComboboxOptionHarnessFilters): HarnessPredicate<ComboboxOptionHarness>;
28
+ /**
29
+ * The option's rendered text, trimmed. An option carrying a `description`
30
+ * renders label and description as sibling block spans, so this returns both
31
+ * concatenated with no separator.
32
+ */
33
+ getText(): Promise<string>;
34
+ /** Whether the option reports `aria-selected="true"`. */
35
+ isSelected(): Promise<boolean>;
36
+ /** Whether the option reports `aria-disabled="true"`. */
37
+ isDisabled(): Promise<boolean>;
38
+ /** Clicks the option. A disabled option ignores the click, as in the browser. */
39
+ click(): Promise<void>;
40
+ }
41
+
42
+ /** Filters accepted by `ComboboxHarness.with`. */
43
+ interface ComboboxHarnessFilters extends BaseHarnessFilters {
44
+ /** Match by the input's accessible name. */
45
+ label?: string | RegExp;
46
+ /** Match by the text currently typed into (or displayed in) the input. */
47
+ inputValue?: string | RegExp;
48
+ /** Match disabled / enabled comboboxes. */
49
+ disabled?: boolean;
50
+ }
51
+ /**
52
+ * Harness for `tw-combobox`.
53
+ *
54
+ * The options panel renders into the CDK overlay container, outside the
55
+ * `tw-combobox` host, so this harness resolves it through
56
+ * `documentRootLocatorFactory()`. A consumer can therefore load this harness
57
+ * from the ordinary fixture loader and still reach the options — no
58
+ * `documentRootLoader` ceremony required.
59
+ *
60
+ * The panel is *disposed* on close rather than merely detached, so option
61
+ * harnesses must be re-read after each `open()`. Do not cache them across a
62
+ * close.
63
+ */
64
+ declare class ComboboxHarness extends ComponentHarness {
65
+ static hostSelector: string;
66
+ private readonly input;
67
+ /**
68
+ * The inline clear (×) control. Its `aria-label` is a template literal in
69
+ * `combobox.ts` — not a consumer input — so matching on it is stable.
70
+ */
71
+ private readonly clearButton;
72
+ /** Resolves the overlay panel, which lives outside this harness's host. */
73
+ private readonly panel;
74
+ /** Predicate for `locatorFor` / `locatorForAll`. */
75
+ static with(options?: ComboboxHarnessFilters): HarnessPredicate<ComboboxHarness>;
76
+ /** The input's accessible name, from `aria-label` when one is set. */
77
+ getLabel(): Promise<string | null>;
78
+ /**
79
+ * The text currently in the input — the typed query while the user is
80
+ * filtering, the committed option's label afterwards. Empty string when the
81
+ * combobox holds nothing (the placeholder is not part of the value).
82
+ */
83
+ getInputValue(): Promise<string>;
84
+ /** The input's `placeholder`, or `null` when none is set. */
85
+ getPlaceholder(): Promise<string | null>;
86
+ /**
87
+ * Replaces the input text and lets the component filter against it — the
88
+ * harness equivalent of selecting all and typing a query.
89
+ *
90
+ * Does NOT commit a value: `tw-combobox` commits on option pick, Enter, blur
91
+ * or Tab. Follow with `selectOption(...)` to pick from the filtered list.
92
+ */
93
+ setInputValue(value: string): Promise<void>;
94
+ /** Whether the panel is open, read from the input's `aria-expanded`. */
95
+ isOpen(): Promise<boolean>;
96
+ /** Whether the input reports `aria-disabled="true"`. */
97
+ isDisabled(): Promise<boolean>;
98
+ /** Whether the input reports `aria-invalid="true"`. */
99
+ isInvalid(): Promise<boolean>;
100
+ /**
101
+ * Whether the input reports `aria-required="true"`. Reflects the `required`
102
+ * input *and* a `Validators.required` on a bound control.
103
+ */
104
+ isRequired(): Promise<boolean>;
105
+ /**
106
+ * Opens the panel with `Alt+ArrowDown`. No-op when already open.
107
+ *
108
+ * Deliberately not a click: `openOnFocus` defaults to `true` but can be
109
+ * turned off, whereas `Alt+ArrowDown` is the APG force-open gesture and works
110
+ * either way. A disabled combobox ignores it, as it does in the browser.
111
+ */
112
+ open(): Promise<void>;
113
+ /**
114
+ * Closes the panel with `Alt+ArrowUp`. No-op when already closed.
115
+ *
116
+ * Deliberately not Escape: Escape *also* reverts the input text to the last
117
+ * committed label, which would make `close()` silently destroy a typed query.
118
+ *
119
+ * The overlay runs a leave animation before it detaches, so `isOpen()` flips
120
+ * to `false` immediately while the panel element lingers for a few more
121
+ * frames. Two consequences worth knowing:
122
+ *
123
+ * - Do not assert `getOptions()` is empty on the tick after a close; the
124
+ * old panel is still mounted.
125
+ * - An `open()` inside that window does **not** attach a fresh panel — the
126
+ * component sees an overlay ref it has not disposed yet and silently
127
+ * keeps the outgoing one. Let the animation finish before reopening.
128
+ */
129
+ close(): Promise<void>;
130
+ /**
131
+ * Every option in the open panel, in render order and already filtered by
132
+ * whatever query the input holds. Returns an empty array when the panel has
133
+ * never been opened, because the overlay is disposed rather than hidden.
134
+ */
135
+ getOptions(filters?: ComboboxOptionHarnessFilters): Promise<ComboboxOptionHarness[]>;
136
+ /**
137
+ * The text of every option currently rendered in the open panel. Opens the
138
+ * panel if needed — this is how a consumer reads the result of a filter
139
+ * query.
140
+ */
141
+ getOptionTexts(): Promise<string[]>;
142
+ /**
143
+ * Opens the panel if needed and clicks the first option whose text matches.
144
+ * Throws when nothing matches, rather than failing silently.
145
+ */
146
+ selectOption(text: string | RegExp): Promise<void>;
147
+ /**
148
+ * Whether the inline clear control is rendered. It appears only while
149
+ * `clearable` is on, the combobox is enabled, and the input is non-empty.
150
+ */
151
+ hasClearButton(): Promise<boolean>;
152
+ /** Clicks the clear control. Throws when none is rendered. */
153
+ clear(): Promise<void>;
154
+ }
155
+
156
+ export { ComboboxHarness, ComboboxOptionHarness };
157
+ export type { ComboboxHarnessFilters, ComboboxOptionHarnessFilters };