@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
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-transfer.mjs","sources":["../../../projects/ngx-tw/transfer/transfer.ts","../../../projects/ngx-tw/transfer/cdevhub-ngx-tw-transfer.ts"],"sourcesContent":["/*\n * tw-transfer — dual-listbox shuttle. Two panels (source / target) with a column\n * of move buttons between them; the user ticks items in a panel and shuttles the\n * ticked items to the other side. The component's *value* is the set of keys\n * currently on the target side (`targetKeys`), exposed through\n * `ControlValueAccessor` + `FormFieldControl` (mirrors `tags-input` / `select`).\n *\n * Architecture decisions (verified against @angular/cdk 21.2.x source):\n * - Each panel body is one `[cdkListbox]` (multiple) with one `[cdkOption]` per\n * VISIBLE item. CDK owns `role=\"listbox\"`/`\"option\"`, `aria-multiselectable`/\n * `aria-selected`, roving-tabindex Arrow/Home/End, Space/Enter toggle, and\n * typeahead. We do NOT roll a custom listbox or reuse select's overlay.\n * - Option value is the item's KEY `K` (`[cdkOption]=\"row.key\"`), so each panel's\n * `cdkListboxValue` is a `readonly K[]` and `compareWith` is key identity.\n * - TWO selection layers, kept distinct:\n * • `targetKeys` (signal) — persisted membership = the CVA value.\n * • per-panel ephemeral \"checked\" — the CdkListbox value, cleared after moves.\n * - The checked binding is CONTROLLED: `[cdkListboxValue]=\"<panel>Checked()\"`,\n * writing the user's `cdkListboxValueChange` back into that signal. Programmatic\n * writes to `cdkListboxValue` are SILENT in CDK (only user gestures call\n * `valueChange.next` — verified: triggerOption/triggerRange), so the loop never\n * re-enters → no cycle / freeze.\n * - The checked set is a `linkedSignal` whose source is the rendered-key set: on\n * every render change it PRUNES keys whose option is no longer present (a filter\n * hid it, or a move removed it). Two consequences: (1) the bound value is always\n * a subset of the rendered options, so CdkListbox's internal `_invalid` flag —\n * which would otherwise collapse the whole selection to `[]` — never trips; and\n * (2) a key checked then filtered out is dropped permanently (it does NOT\n * re-appear when the filter clears). This matches the requirements doc and side-\n * steps a CDK quirk where a controlled value re-surfacing a just-re-rendered\n * option is not reliably re-selected. Moves always act on the visible subset.\n */\n\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n DestroyRef,\n Directive,\n ElementRef,\n forwardRef,\n inject,\n Injector,\n input,\n isDevMode,\n linkedSignal,\n type OnInit,\n output,\n signal,\n type Signal,\n TemplateRef,\n} from '@angular/core';\nimport {\n type ControlValueAccessor,\n FormGroupDirective,\n NgControl,\n NgForm,\n Validators,\n} from '@angular/forms';\nimport {\n CdkListbox,\n CdkOption,\n type ListboxValueChangeEvent,\n} from '@angular/cdk/listbox';\nimport { FocusMonitor, LiveAnnouncer } from '@angular/cdk/a11y';\nimport { Platform } from '@angular/cdk/platform';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { merge } from 'rxjs';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n TW_ERROR_STATE_MATCHER,\n type TwFormSubmitted,\n type TwSize,\n} from '@cdevhub/ngx-tw/core';\nimport {\n FormFieldControl,\n TW_FORM_FIELD_CONTROL,\n} from '@cdevhub/ngx-tw/form-field';\nimport { CheckboxComponent } from '@cdevhub/ngx-tw/checkbox';\nimport { InputDirective } from '@cdevhub/ngx-tw/input';\n\n// ── Public types ──────────────────────────────────────────────────────\n\n/** Which panel of the transfer an item / event belongs to. */\nexport type TwTransferSide = 'source' | 'target';\n\n/** i18n strings for the transfer. Pass any subset; unset keys fall back to the English defaults. */\nexport interface TwTransferLabels {\n /** Source (left) panel title. Defaults to `'Source'`. */\n sourceTitle?: string;\n /** Target (right) panel title. Defaults to `'Target'`. */\n targetTitle?: string;\n /** Placeholder + accessible name for the per-panel search inputs. Defaults to `'Search'`. */\n searchPlaceholder?: string;\n /** Text shown in a panel body when it has no visible items. Defaults to `'No items'`. */\n emptyText?: string;\n /** Accessible name for the header select-all checkbox. Defaults to `'Select all'`. */\n selectAllLabel?: string;\n /** Accessible name for the → (move-to-target) button. Defaults to `'Move selected to target'`. */\n moveToTargetLabel?: string;\n /** Accessible name for the ← (move-to-source) button. Defaults to `'Move selected to source'`. */\n moveToSourceLabel?: string;\n /** Count template rendered in each panel header. Variables: `{total}`, `{selected}`. Defaults to `'{total} items'`. */\n countFormat?: string;\n /** LiveAnnouncer template announced after a move. Variables: `{count}`, `{target}`. Defaults to `'{count} items moved to {target}'`. */\n moveAnnouncement?: string;\n}\n\n/** Visual configuration for the transfer. Pass any subset; unset keys fall back to the defaults. */\nexport interface TwTransferDisplayConfig {\n /** Row / control density across the design-system ramps. Defaults to `'md'`. */\n size?: TwSize;\n /** Scroll-viewport height of each list, in px (a number) or `'auto'` (flow with content). Defaults to `240`. */\n listHeight?: number | 'auto';\n /** When true, each panel gets a labelled search input above its list. Defaults to `false`. */\n showSearch?: boolean;\n /** When true, each panel header shows a tri-state select-all checkbox. Defaults to `true`. */\n showSelectAll?: boolean;\n}\n\n/** Behavioural configuration for the transfer. Generic over item type `T`. Pass any subset; unset keys fall back to the defaults. */\nexport interface TwTransferBehaviorConfig<T = unknown> {\n /** When true, items only flow source → target; the ← button is not rendered. Defaults to `false`. */\n oneWay?: boolean;\n /** Custom search predicate. Defaults to a case-insensitive substring match of the query against `labelFn(item)`. */\n filterFn?: (item: T, query: string) => boolean;\n /** Per-item disable predicate. A disabled item renders as a disabled option and is excluded from select-all and all moves. Defaults to `() => false`. */\n disabledItem?: (item: T) => boolean;\n}\n\n/** Context surfaced to a `*twTransferItem` template. Generic over the item type `T`. */\nexport interface TwTransferItemContext<T> {\n /** The item data (implicit `let-item`). */\n $implicit: T;\n /** Resolved `labelFn(item)`. */\n label: string;\n /** Ephemeral pending-move checked state of this row's option. */\n checked: boolean;\n /** Whether the item is disabled (via `behavior.disabledItem`). */\n disabled: boolean;\n /** Which panel this row renders in. */\n side: TwTransferSide;\n}\n\n/** Payload emitted by `moved`. Generic over the key type `K`. */\nexport interface TwTransferMovedEvent<K> {\n /** The keys that moved in this interaction. */\n keys: readonly K[];\n /** The direction of the move. */\n direction: 'toTarget' | 'toSource';\n}\n\n// ── Resolved-default constants ────────────────────────────────────────\n\nconst LABELS_DEFAULTS: Required<TwTransferLabels> = {\n sourceTitle: 'Source',\n targetTitle: 'Target',\n searchPlaceholder: 'Search',\n emptyText: 'No items',\n selectAllLabel: 'Select all',\n moveToTargetLabel: 'Move selected to target',\n moveToSourceLabel: 'Move selected to source',\n countFormat: '{total} items',\n moveAnnouncement: '{count} items moved to {target}',\n};\n\nconst DISPLAY_DEFAULTS: Required<TwTransferDisplayConfig> = {\n size: 'md',\n listHeight: 240,\n showSearch: false,\n showSelectAll: true,\n};\n\n/** Replaces `{name}` tokens in a template with values from `vars`. */\nfunction formatLabel(\n template: string,\n vars: Record<string, string | number>,\n): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n key in vars ? String(vars[key]) : match,\n );\n}\n\n// ── tv() config ───────────────────────────────────────────────────────\n//\n// All class strings are literal so the Tailwind v4 JIT scanner picks them up.\n// Semantic + surface/fg/border tokens only. The selected/checked option styling\n// mirrors `tree`'s selected node (`bg-primary-50 text-primary-700`, no `dark:`\n// overrides — slot tokens own structural light/dark contrast).\n\nconst transferVariants = tv(\n {\n slots: {\n // panel · controls · panel. The middle column is auto width; both panels\n // share the remaining space and clamp to `min-w-0` so rows can truncate.\n root: 'grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] gap-3 items-stretch text-fg',\n panel:\n 'flex flex-col min-w-0 rounded-lg border border-border bg-surface overflow-hidden',\n panelHeader:\n 'flex items-center gap-2 border-b border-border bg-surface-muted',\n panelTitle: 'text-sm font-semibold text-fg min-w-0 truncate flex-1',\n panelCount: 'text-xs text-fg-muted shrink-0 tabular-nums',\n search: 'border-b border-border',\n // The cdkListbox scroll viewport. `outline-none` because focus rides the\n // individual options (canonical ring there), not the container.\n list: 'flex flex-col overflow-y-auto outline-none',\n // The cdkOption row.\n option:\n 'flex items-center gap-2 cursor-pointer select-none text-fg transition-colors duration-200 motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n // Presentational check glyph (aria-hidden). Always laid out (for alignment);\n // visibility toggles via opacity off the checked state.\n optionCheck:\n 'shrink-0 transition-opacity duration-200 motion-reduce:transition-none',\n optionLabel: 'min-w-0 truncate flex-1',\n controls: 'flex flex-col justify-center gap-2',\n // Plain square move buttons (icon-only). Square-interactive sub-scale per\n // size; not the [twButton] directive (its size padding would fight a square\n // override across two class bindings).\n moveButton:\n 'inline-flex items-center justify-center shrink-0 rounded-md border border-border bg-surface text-fg-muted cursor-pointer transition-colors duration-200 motion-reduce:transition-none hover:bg-surface-muted hover:text-fg hover:border-border-strong focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500 disabled:opacity-50 disabled:pointer-events-none disabled:cursor-not-allowed',\n moveIcon: 'shrink-0',\n empty:\n 'flex items-center justify-center p-4 text-sm text-fg-subtle text-center',\n },\n variants: {\n size: {\n xs: {\n panelHeader: 'px-2 py-1',\n search: 'px-2 py-1',\n option: 'px-2 py-1 text-xs gap-1.5',\n optionCheck: 'size-4',\n moveButton: 'size-6',\n moveIcon: 'size-4',\n empty: 'text-xs',\n },\n sm: {\n panelHeader: 'px-3 py-1.5',\n search: 'px-3 py-1.5',\n option: 'px-3 py-1.5 text-sm',\n optionCheck: 'size-4',\n moveButton: 'size-7',\n moveIcon: 'size-4',\n },\n md: {\n panelHeader: 'px-4 py-2',\n search: 'px-3 py-2',\n option: 'px-3 py-2 text-sm',\n optionCheck: 'size-5',\n moveButton: 'size-8',\n moveIcon: 'size-5',\n },\n lg: {\n panelHeader: 'px-5 py-2.5',\n search: 'px-4 py-2.5',\n option: 'px-4 py-2.5 text-base',\n optionCheck: 'size-5',\n moveButton: 'size-9',\n moveIcon: 'size-5',\n },\n xl: {\n panelHeader: 'px-6 py-3',\n search: 'px-4 py-3',\n option: 'px-4 py-3 text-base',\n optionCheck: 'size-5',\n moveButton: 'size-9',\n moveIcon: 'size-5',\n },\n },\n checked: {\n true: {\n option: 'bg-primary-50 text-primary-700 hover:bg-primary-50',\n optionCheck: 'opacity-100 text-primary-600',\n },\n false: {\n option: 'hover:bg-surface-muted',\n optionCheck: 'opacity-0',\n },\n },\n optionDisabled: {\n true: { option: 'opacity-50 pointer-events-none' },\n false: {},\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none' },\n false: {},\n },\n },\n defaultVariants: {\n size: 'md',\n checked: false,\n optionDisabled: false,\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\n// ── TransferItemDefDirective ──────────────────────────────────────────\n//\n// Pure TemplateRef carrier for the consumer's per-item template. Mirrors tree's\n// `TreeNodeDefDirective` / table's `CellDefDirective`: a typed context +\n// `ngTemplateContextGuard` so `let-item` / `let-checked=\"checked\"` type-check.\n// Optional — when absent each row renders the default check glyph + label.\n\n/** Structural directive (`*twTransferItem=\"let item\"`) declaring the per-item template. Typed as `TwTransferItemContext<T>`. */\n@Directive({ selector: '[twTransferItem]' })\nexport class TransferItemDefDirective<T = unknown> {\n /** @internal Consumer-projected per-item template. */\n readonly template = inject(TemplateRef<TwTransferItemContext<T>>);\n\n /** @internal */\n static ngTemplateContextGuard<T>(\n _dir: TransferItemDefDirective<T>,\n _ctx: unknown,\n ): _ctx is TwTransferItemContext<T> {\n return true;\n }\n}\n\n// ── Internal view-model types ─────────────────────────────────────────\n\ninterface RowBase<T, K> {\n readonly item: T;\n readonly key: K;\n readonly label: string;\n readonly disabled: boolean;\n}\n\ninterface RowView<T, K> extends RowBase<T, K> {\n readonly checked: boolean;\n readonly optionClass: string;\n readonly checkClass: string;\n readonly context: TwTransferItemContext<T>;\n}\n\ninterface PanelView<T, K> {\n readonly side: TwTransferSide;\n readonly title: string;\n readonly titleId: string;\n readonly countText: string;\n readonly emptyText: string;\n readonly searchPlaceholder: string;\n readonly selectAllLabel: string;\n readonly query: string;\n readonly rows: readonly RowView<T, K>[];\n readonly checkedValue: readonly K[];\n readonly selectAllChecked: boolean;\n readonly selectAllIndeterminate: boolean;\n}\n\nlet nextId = 0;\n\n// ── TransferComponent ─────────────────────────────────────────────────\n\n/**\n * A dual-listbox shuttle: two panels (source / target) with a column of move\n * buttons between them. The user ticks items in a panel and shuttles them across;\n * an optional per-panel search and a tri-state header select-all accelerate bulk\n * moves. The component's value is the set of keys on the target side, exposed\n * through `ControlValueAccessor` + `FormFieldControl` so it works with reactive,\n * template-driven, and signal forms and integrates with `<tw-form-field>`.\n *\n * Each panel composes `@angular/cdk/listbox` (`CdkListbox` / `CdkOption`) for\n * focus-managed, accessible, keyboard-navigable selection. Consumers supply\n * `keyFn` (required) and `labelFn` (defaulted to `String(item)`), and may project\n * a `*twTransferItem` template for rich row content.\n */\n@Component({\n selector: 'tw-transfer',\n exportAs: 'twTransfer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet, CdkListbox, CdkOption, CheckboxComponent, InputDirective],\n providers: [\n {\n provide: TW_FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => TransferComponent),\n },\n ],\n host: {\n role: 'group',\n '[id]': 'id()',\n '[class]': 'rootClasses()',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'resolvedLabelledBy() || null',\n '[attr.aria-describedby]': 'resolvedDescribedBy() || null',\n '[attr.aria-disabled]': 'disabled() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n '[attr.data-focused]': 'focused() || null',\n },\n template: `\n <!-- One panel, instantiated twice (source, then target) around the controls. -->\n <ng-template #panelTpl let-panel>\n <div [class]=\"panelClasses()\">\n <div [class]=\"panelHeaderClasses()\">\n @if (showSelectAll()) {\n <tw-checkbox\n [size]=\"checkboxSize()\"\n [checked]=\"panel.selectAllChecked\"\n [indeterminate]=\"panel.selectAllIndeterminate\"\n [disabled]=\"disabled()\"\n [aria-label]=\"panel.selectAllLabel\"\n (change)=\"onSelectAll(panel.side, $event)\"\n />\n }\n <span [id]=\"panel.titleId\" [class]=\"panelTitleClasses()\">{{ panel.title }}</span>\n <span [class]=\"panelCountClasses()\">{{ panel.countText }}</span>\n </div>\n\n @if (showSearch()) {\n <div [class]=\"searchClasses()\">\n <input\n twInput\n type=\"text\"\n [size]=\"resolvedSize()\"\n [value]=\"panel.query\"\n [disabled]=\"disabled()\"\n [attr.placeholder]=\"panel.searchPlaceholder\"\n [attr.aria-label]=\"panel.searchPlaceholder\"\n (input)=\"onSearch(panel.side, $event)\"\n />\n </div>\n }\n\n <!-- The cdkListbox is rendered only when it has options. An empty\n role=\"listbox\" violates aria-required-children, so an empty panel\n shows a plain message region instead. -->\n @if (panel.rows.length > 0) {\n <div\n cdkListbox\n [cdkListboxMultiple]=\"true\"\n [cdkListboxValue]=\"panel.checkedValue\"\n [cdkListboxDisabled]=\"disabled()\"\n [cdkListboxCompareWith]=\"compareKeys\"\n [class]=\"listClasses()\"\n [style.height.px]=\"listHeightPx()\"\n [attr.aria-labelledby]=\"panel.titleId\"\n (cdkListboxValueChange)=\"onCheckedChange(panel.side, $event)\"\n >\n @for (row of panel.rows; track row.key) {\n <div\n [cdkOption]=\"row.key\"\n [cdkOptionDisabled]=\"row.disabled\"\n [cdkOptionTypeaheadLabel]=\"row.label\"\n [class]=\"row.optionClass\"\n >\n <svg\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n [class]=\"row.checkClass\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M16.704 5.29a1 1 0 0 1 .006 1.414l-7.5 7.6a1 1 0 0 1-1.42.005l-3.5-3.5a1 1 0 1 1 1.414-1.414l2.79 2.79 6.796-6.889a1 1 0 0 1 1.414-.006Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n @if (itemTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"row.context\"\n />\n } @else {\n <span [class]=\"optionLabelClasses()\">{{ row.label }}</span>\n }\n </div>\n }\n </div>\n } @else {\n <div [class]=\"emptyClasses()\" [style.height.px]=\"listHeightPx()\">{{ panel.emptyText }}</div>\n }\n </div>\n </ng-template>\n\n <ng-container\n [ngTemplateOutlet]=\"panelTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: sourcePanel() }\"\n />\n\n <div [class]=\"controlsClasses()\">\n <button\n type=\"button\"\n [class]=\"moveButtonClasses()\"\n [disabled]=\"disabled() || sourceMovableKeys().length === 0\"\n [attr.aria-label]=\"resolvedLabels().moveToTargetLabel\"\n (click)=\"onMoveToTarget()\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\" [class]=\"moveIconClasses()\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 0 1 .02-1.06L11.168 10 7.23 6.29a.75.75 0 1 1 1.04-1.08l4.5 4.25a.75.75 0 0 1 0 1.08l-4.5 4.25a.75.75 0 0 1-1.06-.02Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n\n @if (!oneWay()) {\n <button\n type=\"button\"\n [class]=\"moveButtonClasses()\"\n [disabled]=\"disabled() || targetMovableKeys().length === 0\"\n [attr.aria-label]=\"resolvedLabels().moveToSourceLabel\"\n (click)=\"onMoveToSource()\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\" [class]=\"moveIconClasses()\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 0 1-.02 1.06L8.832 10l3.938 3.71a.75.75 0 1 1-1.04 1.08l-4.5-4.25a.75.75 0 0 1 0-1.08l4.5-4.25a.75.75 0 0 1 1.06.02Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n }\n </div>\n\n <ng-container\n [ngTemplateOutlet]=\"panelTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: targetPanel() }\"\n />\n `,\n})\nexport class TransferComponent<T = unknown, K = unknown>\n extends FormFieldControl<readonly K[]>\n implements ControlValueAccessor, OnInit\n{\n // ── Inputs ──\n\n /** All items across both panels. The source/target split derives from the value, not the reverse. Defaults to `[]`. */\n readonly data = input<readonly T[]>([]);\n\n /** Resolves a stable key for an item — drives membership (the value), checked state, tracking, the cdkOption value, and compareWith. Required. */\n readonly keyFn = input.required<(item: T) => K>();\n\n /** Resolves an item's display label — used for the default row render, search filtering, and listbox typeahead. Defaults to `(item) => String(item)`. */\n readonly labelFn = input<(item: T) => string>((item: T) => String(item));\n\n /** Per-panel text + ARIA labels. Partial; unset keys fall back to the English defaults. */\n readonly labels = input<Partial<TwTransferLabels>>({});\n\n /** Visual configuration — size, list viewport height, search / select-all visibility. Partial; unset keys fall back to the defaults. */\n readonly display = input<Partial<TwTransferDisplayConfig>>({});\n\n /** Behavioural configuration — oneWay, custom filterFn, per-item disabledItem predicate. Partial; unset keys fall back to the defaults. */\n readonly behavior = input<Partial<TwTransferBehaviorConfig<T>>>({});\n\n /** Disables the entire control — panels non-interactive, search + buttons disabled, muted styling. Also driven by Forms `setDisabledState`. Defaults to `false`. */\n readonly disabledInput = input(false, { alias: 'disabled' });\n\n /** Marks the control as required. Mirrored to `aria-required` chrome via the form-field; also inferred from `Validators.required` on a bound control. Defaults to `false`. */\n readonly requiredInput = input(false, { alias: 'required' });\n\n /** Reserved for control identification (e.g. analytics, future native-submission parity). The transfer has no single native value element, so it is not currently reflected to the DOM. Defaults to `undefined`. */\n readonly name = input<string | undefined>(undefined);\n\n /** Id on the host element. Auto-generated as `tw-transfer-N` when unset. Used by the form-field's `<label for>` association. */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /** Accessible name applied to the control when no visible label is wired. Mirrored to `aria-label`. Defaults to `undefined`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the control. Mirrored to `aria-labelledby`. Defaults to `undefined`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the control. The form-field merges its hint / error ids alongside. Defaults to `undefined`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, uses the `TW_ERROR_STATE_MATCHER` token's value. Defaults to `undefined`. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n // ── Outputs ──\n\n /** Fires when items move between panels by user interaction. Payload is the new full target-keys array. Does not fire on `writeValue`. */\n readonly valueChange = output<readonly K[]>();\n\n /** Fires after each directional move, identifying the moved keys and their direction. Does not fire on `writeValue`. */\n readonly moved = output<TwTransferMovedEvent<K>>();\n\n // ── Content query ──\n\n /** @internal Consumer-projected per-item template (`*twTransferItem`). */\n readonly itemTemplate = contentChild(TransferItemDefDirective<T>);\n\n // ── Injected deps ──\n\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n private readonly parentForm = inject(NgForm, { optional: true });\n private readonly parentFormGroup = inject(FormGroupDirective, { optional: true });\n private readonly defaultMatcher = inject(TW_ERROR_STATE_MATCHER);\n private readonly platform = inject(Platform);\n\n // ── Identity ──\n\n private readonly uid = nextId++;\n /** @internal Fallback id used when the consumer does not set `[id]`. */\n readonly hostId = `tw-transfer-${this.uid}`;\n private readonly sourceTitleId = `${this.hostId}-source-title`;\n private readonly targetTitleId = `${this.hostId}-target-title`;\n\n // ── State signals ──\n\n /** @internal The value: keys currently on the target side. Source of truth for membership. */\n private readonly targetKeys = signal<readonly K[]>([]);\n /** @internal Per-panel search queries. */\n private readonly sourceQuery = signal('');\n private readonly targetQuery = signal('');\n\n private readonly cvaDisabled = signal(false);\n private readonly _focused = signal(false);\n private readonly _ngControlRev = signal(0);\n private readonly _formSubmitRev = signal(0);\n private readonly describedByIdsSignal = signal<readonly string[]>([]);\n private readonly labelledByIdsSignal = signal<readonly string[]>([]);\n\n private onChange: (value: readonly K[]) => void = () => {};\n private onTouched: () => void = () => {};\n\n /** @internal Stable comparator for `[cdkListboxCompareWith]`. Keys are identity-comparable. */\n readonly compareKeys = (a: K, b: K): boolean => Object.is(a, b);\n\n // ── Resolved config ──\n\n /** @internal */\n readonly resolvedLabels = computed<Required<TwTransferLabels>>(() => ({\n ...LABELS_DEFAULTS,\n ...this.labels(),\n }));\n\n private readonly resolvedDisplay = computed<Required<TwTransferDisplayConfig>>(() => ({\n ...DISPLAY_DEFAULTS,\n ...this.display(),\n }));\n\n // Behaviour is resolved inline (not via a `Required<>` const) because `filterFn`\n // is legitimately optional and both predicates are generic over `T`.\n private readonly resolvedBehavior = computed(() => {\n const b = this.behavior();\n return {\n oneWay: b.oneWay ?? false,\n filterFn: b.filterFn,\n disabledItem: b.disabledItem ?? ((_item: T) => false),\n };\n });\n\n /** @internal */\n readonly resolvedSize = computed<TwSize>(() => this.resolvedDisplay().size);\n /** @internal Checkbox tops out at `lg` density; map xl → lg. */\n readonly checkboxSize = computed<TwSize>(() => {\n const s = this.resolvedSize();\n return s === 'xl' ? 'lg' : s;\n });\n /** @internal */\n readonly showSearch = computed(() => this.resolvedDisplay().showSearch);\n /** @internal */\n readonly showSelectAll = computed(() => this.resolvedDisplay().showSelectAll);\n /** @internal */\n readonly oneWay = computed(() => this.resolvedBehavior().oneWay);\n /** @internal Fixed list height in px, or `null` when `'auto'`. */\n readonly listHeightPx = computed(() => {\n const h = this.resolvedDisplay().listHeight;\n return h === 'auto' ? null : h;\n });\n\n // ── Derived membership state ──\n\n /** @internal Map from key to item across all data — for orphan-aware target rendering and disabled lookups. */\n private readonly itemByKey = computed(() => {\n const kf = this.keyFn();\n const map = new Map<K, T>();\n for (const item of this.data()) map.set(kf(item), item);\n return map;\n });\n\n private readonly targetKeySet = computed(() => new Set(this.targetKeys()));\n\n /** @internal Items on the source side (in `data` order). */\n private readonly sourceItems = computed<readonly T[]>(() => {\n const inTarget = this.targetKeySet();\n const kf = this.keyFn();\n return this.data().filter((item) => !inTarget.has(kf(item)));\n });\n\n /** @internal Items on the target side (in `targetKeys` order; orphan keys with no item are skipped). */\n private readonly targetItems = computed<readonly T[]>(() => {\n const map = this.itemByKey();\n const out: T[] = [];\n for (const key of this.targetKeys()) {\n const item = map.get(key);\n if (item !== undefined) out.push(item);\n }\n return out;\n });\n\n // ── Per-panel row pipelines (source) ──\n // Stage 1 (base) carries no checked flag → renderedKeys / reconciled derive from\n // it without a cycle. Stage 2 augments with checked state + precomputed classes.\n\n private readonly sourceRowsBase = computed(() =>\n this.toRowsBase(this.filterItems(this.sourceItems(), this.sourceQuery())),\n );\n private readonly sourceRenderedKeys = computed(\n () => new Set(this.sourceRowsBase().map((r) => r.key)),\n );\n /**\n * @internal Ephemeral pending-move checked keys for the source panel — the\n * controlled `[cdkListboxValue]`. A `linkedSignal` over the rendered-key set so\n * it auto-prunes keys whose option a filter / move removed (kept ⊆ rendered → no\n * CdkListbox `_invalid`; dropped keys do not re-surface). Cleared after moves.\n */\n readonly sourceChecked = linkedSignal<ReadonlySet<K>, readonly K[]>({\n source: this.sourceRenderedKeys,\n computation: (rendered, prev) =>\n (prev?.value ?? []).filter((k) => rendered.has(k)),\n });\n private readonly sourceCheckedSet = computed(() => new Set(this.sourceChecked()));\n private readonly sourceRows = computed(() =>\n this.toRows(this.sourceRowsBase(), this.sourceCheckedSet(), 'source'),\n );\n\n // ── Per-panel row pipelines (target) ──\n\n private readonly targetRowsBase = computed(() =>\n this.toRowsBase(this.filterItems(this.targetItems(), this.targetQuery())),\n );\n private readonly targetRenderedKeys = computed(\n () => new Set(this.targetRowsBase().map((r) => r.key)),\n );\n /** @internal Ephemeral pending-move checked keys for the target panel — see {@link sourceChecked}. */\n readonly targetChecked = linkedSignal<ReadonlySet<K>, readonly K[]>({\n source: this.targetRenderedKeys,\n computation: (rendered, prev) =>\n (prev?.value ?? []).filter((k) => rendered.has(k)),\n });\n private readonly targetCheckedSet = computed(() => new Set(this.targetChecked()));\n private readonly targetRows = computed(() =>\n this.toRows(this.targetRowsBase(), this.targetCheckedSet(), 'target'),\n );\n\n // ── Movable + select-all derivations ──\n\n /** @internal Checked, enabled, visible source keys — what the → button moves. */\n readonly sourceMovableKeys = computed<readonly K[]>(() => {\n const checked = this.sourceCheckedSet();\n return this.sourceRowsBase()\n .filter((r) => !r.disabled && checked.has(r.key))\n .map((r) => r.key);\n });\n\n /** @internal Checked, enabled, visible target keys — what the ← button moves. */\n readonly targetMovableKeys = computed<readonly K[]>(() => {\n const checked = this.targetCheckedSet();\n return this.targetRowsBase()\n .filter((r) => !r.disabled && checked.has(r.key))\n .map((r) => r.key);\n });\n\n private readonly sourceSelectAllKeys = computed<readonly K[]>(() =>\n this.sourceRowsBase().filter((r) => !r.disabled).map((r) => r.key),\n );\n private readonly targetSelectAllKeys = computed<readonly K[]>(() =>\n this.targetRowsBase().filter((r) => !r.disabled).map((r) => r.key),\n );\n\n // ── Panel view-models ──\n\n /** @internal */\n readonly sourcePanel = computed<PanelView<T, K>>(() =>\n this.buildPanel(\n 'source',\n this.sourceTitleId,\n this.resolvedLabels().sourceTitle,\n this.sourceRowsBase(),\n this.sourceRows(),\n this.sourceCheckedSet(),\n this.sourceSelectAllKeys(),\n this.sourceChecked(),\n this.sourceQuery(),\n ),\n );\n\n /** @internal */\n readonly targetPanel = computed<PanelView<T, K>>(() =>\n this.buildPanel(\n 'target',\n this.targetTitleId,\n this.resolvedLabels().targetTitle,\n this.targetRowsBase(),\n this.targetRows(),\n this.targetCheckedSet(),\n this.targetSelectAllKeys(),\n this.targetChecked(),\n this.targetQuery(),\n ),\n );\n\n // ── tv() class outputs ──\n\n private readonly variants = computed(() =>\n transferVariants({\n size: this.resolvedSize(),\n disabled: this.disabled(),\n }),\n );\n\n /** @internal */\n readonly rootClasses = computed(() => this.variants().root());\n /** @internal */\n readonly panelClasses = computed(() => this.variants().panel());\n /** @internal */\n readonly panelHeaderClasses = computed(() => this.variants().panelHeader());\n /** @internal */\n readonly panelTitleClasses = computed(() => this.variants().panelTitle());\n /** @internal */\n readonly panelCountClasses = computed(() => this.variants().panelCount());\n /** @internal */\n readonly searchClasses = computed(() => this.variants().search());\n /** @internal */\n readonly listClasses = computed(() => this.variants().list());\n /** @internal */\n readonly optionLabelClasses = computed(() => this.variants().optionLabel());\n /** @internal */\n readonly controlsClasses = computed(() => this.variants().controls());\n /** @internal */\n readonly moveButtonClasses = computed(() => this.variants().moveButton());\n /** @internal */\n readonly moveIconClasses = computed(() => this.variants().moveIcon());\n /** @internal */\n readonly emptyClasses = computed(() => this.variants().empty());\n\n constructor() {\n super();\n // Runtime CVA wiring — register on any host-level NgControl. The component\n // injects `NgControl { self }` for TW_ERROR_STATE_MATCHER, so a static\n // NG_VALUE_ACCESSOR provider would create circular DI on the same instance.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-transfer] The control has no accessible name. Provide `aria-label` / `aria-labelledby`, or wrap it in a <tw-form-field> with a <label twLabel>.',\n );\n }\n });\n }\n\n // ── Public methods ──\n\n /** Moves the given items (by key) to the target side; ignores keys already there or whose item is disabled. Clears the source panel's pending checks, emits `valueChange` + `moved`, calls the CVA onChange, and announces the move. No-op when the control is disabled. */\n moveToTarget(keys: readonly K[]): void {\n if (this.disabled()) return;\n const current = this.targetKeys();\n const existing = new Set(current);\n const disabledFn = this.resolvedBehavior().disabledItem;\n const map = this.itemByKey();\n const moved: K[] = [];\n for (const key of keys) {\n if (existing.has(key)) continue;\n const item = map.get(key);\n if (item !== undefined && disabledFn(item)) continue;\n existing.add(key);\n moved.push(key);\n }\n this.sourceChecked.set([]);\n if (!moved.length) return;\n // Append moved keys to the existing array — orphan keys (in the value, not in\n // `data`) are part of `current` and therefore preserved.\n this.applyValue([...current, ...moved], moved, 'toTarget');\n }\n\n /** Moves the given items (by key) to the source side; ignores keys not on target or whose item is disabled. Clears the target panel's pending checks. No-op when the control is disabled or `behavior.oneWay` is on. Same emissions as {@link moveToTarget}. */\n moveToSource(keys: readonly K[]): void {\n if (this.disabled() || this.resolvedBehavior().oneWay) return;\n const current = this.targetKeys();\n const present = new Set(current);\n const disabledFn = this.resolvedBehavior().disabledItem;\n const map = this.itemByKey();\n const remove = new Set<K>();\n for (const key of keys) {\n if (!present.has(key)) continue;\n const item = map.get(key);\n if (item !== undefined && disabledFn(item)) continue;\n remove.add(key);\n }\n this.targetChecked.set([]);\n if (!remove.size) return;\n // Filter the existing array — unspecified orphan keys are preserved.\n this.applyValue(\n current.filter((k) => !remove.has(k)),\n [...remove],\n 'toSource',\n );\n }\n\n // ── Template event handlers ──\n\n /** @internal */\n onCheckedChange(side: TwTransferSide, event: ListboxValueChangeEvent<K>): void {\n if (side === 'source') this.sourceChecked.set([...event.value]);\n else this.targetChecked.set([...event.value]);\n }\n\n /** @internal Select-all toggles the visible, enabled keys for the panel (replace semantics). */\n onSelectAll(side: TwTransferSide, checked: boolean): void {\n if (side === 'source') {\n this.sourceChecked.set(checked ? [...this.sourceSelectAllKeys()] : []);\n } else {\n this.targetChecked.set(checked ? [...this.targetSelectAllKeys()] : []);\n }\n }\n\n /** @internal */\n onSearch(side: TwTransferSide, event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n if (side === 'source') this.sourceQuery.set(value);\n else this.targetQuery.set(value);\n }\n\n /** @internal */\n onMoveToTarget(): void {\n this.moveToTarget(this.sourceMovableKeys());\n // The clicked → button disables itself once its checked set drains; a focused\n // element that becomes `disabled` drops focus to <body>. Keep the user in the\n // control by moving focus to the destination listbox (non-empty after a move).\n this.focusDestination('target');\n }\n\n /** @internal */\n onMoveToSource(): void {\n this.moveToSource(this.targetMovableKeys());\n this.focusDestination('source');\n }\n\n /**\n * @internal Focuses the destination panel's listbox after the move re-renders.\n * Deferred to the next render (the destination listbox may have just mounted\n * from empty) and matched by its title id rather than DOM order (the *other*\n * panel may have emptied, removing its listbox).\n */\n private focusDestination(side: TwTransferSide): void {\n if (!this.platform.isBrowser) return;\n const titleId = side === 'source' ? this.sourceTitleId : this.targetTitleId;\n afterNextRender(\n () => {\n const listbox = this.elementRef.nativeElement.querySelector(\n `[cdklistbox][aria-labelledby=\"${titleId}\"]`,\n ) as HTMLElement | null;\n listbox?.focus();\n },\n { injector: this.injector },\n );\n }\n\n // ── Internal helpers ──\n\n private applyValue(\n next: readonly K[],\n moved: readonly K[],\n direction: 'toTarget' | 'toSource',\n ): void {\n this.targetKeys.set(next);\n this.onChange(next);\n this.valueChange.emit(next);\n this.moved.emit({ keys: moved, direction });\n const labels = this.resolvedLabels();\n const dest = direction === 'toTarget' ? labels.targetTitle : labels.sourceTitle;\n this.liveAnnouncer.announce(\n formatLabel(labels.moveAnnouncement, { count: moved.length, target: dest }),\n 'polite',\n );\n }\n\n private filterItems(items: readonly T[], query: string): readonly T[] {\n const q = query.trim();\n if (!q) return items;\n const custom = this.resolvedBehavior().filterFn;\n if (custom) return items.filter((item) => custom(item, q));\n const labelFn = this.labelFn();\n const lower = q.toLowerCase();\n return items.filter((item) => labelFn(item).toLowerCase().includes(lower));\n }\n\n private toRowsBase(items: readonly T[]): RowBase<T, K>[] {\n const kf = this.keyFn();\n const labelFn = this.labelFn();\n const disabledFn = this.resolvedBehavior().disabledItem;\n return items.map((item) => ({\n item,\n key: kf(item),\n label: labelFn(item),\n disabled: disabledFn(item),\n }));\n }\n\n private toRows(\n base: readonly RowBase<T, K>[],\n checked: ReadonlySet<K>,\n side: TwTransferSide,\n ): RowView<T, K>[] {\n const size = this.resolvedSize();\n return base.map((b) => {\n const isChecked = checked.has(b.key);\n const v = transferVariants({\n size,\n checked: isChecked,\n optionDisabled: b.disabled,\n });\n return {\n ...b,\n checked: isChecked,\n optionClass: v.option(),\n checkClass: v.optionCheck(),\n context: {\n $implicit: b.item,\n label: b.label,\n checked: isChecked,\n disabled: b.disabled,\n side,\n },\n };\n });\n }\n\n private buildPanel(\n side: TwTransferSide,\n titleId: string,\n title: string,\n base: readonly RowBase<T, K>[],\n rows: readonly RowView<T, K>[],\n checked: ReadonlySet<K>,\n selectAllKeys: readonly K[],\n checkedValue: readonly K[],\n query: string,\n ): PanelView<T, K> {\n const labels = this.resolvedLabels();\n const selectedCount = rows.reduce((n, r) => (r.checked ? n + 1 : n), 0);\n const state = this.selectAllState(selectAllKeys, checked);\n return {\n side,\n title,\n titleId,\n countText: formatLabel(labels.countFormat, {\n total: base.length,\n selected: selectedCount,\n }),\n emptyText: labels.emptyText,\n searchPlaceholder: labels.searchPlaceholder,\n selectAllLabel: labels.selectAllLabel,\n query,\n rows,\n checkedValue,\n selectAllChecked: state === 'checked',\n selectAllIndeterminate: state === 'indeterminate',\n };\n }\n\n private selectAllState(\n enabledKeys: readonly K[],\n checked: ReadonlySet<K>,\n ): 'checked' | 'indeterminate' | 'unchecked' {\n if (enabledKeys.length === 0) return 'unchecked';\n let n = 0;\n for (const key of enabledKeys) if (checked.has(key)) n++;\n if (n === 0) return 'unchecked';\n if (n === enabledKeys.length) return 'checked';\n return 'indeterminate';\n }\n\n private hasAccessibleNameHint(): boolean {\n return (\n !!this.ariaLabel() ||\n !!this.ariaLabelledby() ||\n this.labelledByIdsSignal().length > 0\n );\n }\n\n // ── FormFieldControl signals ──\n\n /** @internal */\n readonly id: Signal<string> = computed(() => this.idInput() ?? this.hostId);\n\n /** The current target-keys array. Doubles as the `FormFieldControl` value member. */\n readonly value: Signal<readonly K[]> = this.targetKeys.asReadonly();\n\n /** @internal */\n readonly focused: Signal<boolean> = this._focused.asReadonly();\n\n /** @internal Empty when nothing is on the target side — drives the form-field floating label. */\n readonly empty: Signal<boolean> = computed(() => this.targetKeys().length === 0);\n\n /** @internal */\n readonly disabled: Signal<boolean> = computed(\n () => this.disabledInput() || this.cvaDisabled(),\n );\n\n /** @internal */\n readonly required: Signal<boolean> = computed(() => {\n this._ngControlRev();\n if (this.requiredInput()) return true;\n return !!this.ngControl?.control?.hasValidator(Validators.required);\n });\n\n /** @internal */\n readonly errorState: Signal<boolean> = computed(() => {\n this._ngControlRev();\n this._formSubmitRev();\n this._focused();\n const matcher = this.errorStateMatcher() ?? this.defaultMatcher;\n const form: TwFormSubmitted | null =\n (this.parentFormGroup as TwFormSubmitted | null) ??\n (this.parentForm as TwFormSubmitted | null);\n return matcher.isErrorState(this.ngControl?.control ?? null, form);\n });\n\n /** @internal Active validation errors from the bound control, for `[twError match=\"…\"]` filtering. */\n override readonly errors = computed<Record<string, unknown> | null>(() => {\n this._ngControlRev();\n return (this.ngControl?.control?.errors as Record<string, unknown> | null) ?? null;\n });\n\n /** @internal */\n readonly controlType = 'transfer';\n\n /** @internal */\n readonly userAriaDescribedBy: Signal<string | undefined> = computed(() =>\n this.ariaDescribedby(),\n );\n\n /** @internal */\n override readonly userAriaLabelledby: Signal<string | undefined> = computed(() =>\n this.ariaLabelledby(),\n );\n\n /** @internal Merged `aria-describedby` (form-field hint/error ids + consumer-supplied). */\n readonly resolvedDescribedBy = computed(() => {\n const pushed = this.describedByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n const user = this.ariaDescribedby();\n if (user) return user.split(/\\s+/).filter(Boolean).join(' ');\n return '';\n });\n\n /** @internal Merged `aria-labelledby` (form-field label id + consumer-supplied). */\n readonly resolvedLabelledBy = computed(() => {\n const pushed = this.labelledByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n const user = this.ariaLabelledby();\n if (user) return user.split(/\\s+/).filter(Boolean).join(' ');\n return '';\n });\n\n // ── ControlValueAccessor ──\n\n writeValue(value: readonly K[] | null | undefined): void {\n // Orphan keys (present here but absent from `data`) are preserved — they render\n // nothing but survive the round-trip, so a form value outlives a lagging `data`.\n this.targetKeys.set(Array.isArray(value) ? [...value] : []);\n this.sourceChecked.set([]);\n this.targetChecked.set([]);\n }\n\n registerOnChange(fn: (value: readonly K[]) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // ── FormFieldControl methods ──\n\n /** @internal */\n setDescribedByIds(ids: string[]): void {\n this.describedByIdsSignal.set([...ids]);\n }\n\n /** @internal */\n override setLabelledByIds(ids: string[]): void {\n this.labelledByIdsSignal.set([...ids]);\n }\n\n /** @internal Clicking the form-field surface focuses the first listbox. */\n onContainerClick(event: MouseEvent): void {\n if (this.disabled() || event.defaultPrevented) return;\n const host = this.elementRef.nativeElement;\n if (event.target !== host && host.contains(event.target as Node)) return;\n const listbox = host.querySelector('[cdklistbox]') as HTMLElement | null;\n listbox?.focus();\n }\n\n // ── Lifecycle ──\n\n ngOnInit(): void {\n // Host-level focus monitor (checkChildren: true): internal focus moves between\n // the two listboxes / buttons / search stay \"focused\"; origin === null fires\n // only when focus leaves the WHOLE control — the single source for onTouched.\n this.focusMonitor\n .monitor(this.elementRef, true)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((origin) => {\n const wasFocused = this._focused();\n this._focused.set(!!origin);\n if (wasFocused && !origin) {\n this.onTouched();\n this._ngControlRev.update((n) => n + 1);\n }\n });\n this.destroyRef.onDestroy(() => this.focusMonitor.stopMonitoring(this.elementRef));\n\n // React to status/value changes on the bound control so errorState recomputes.\n const ctrl = this.ngControl?.control;\n if (ctrl) {\n const streams = [ctrl.statusChanges, ctrl.valueChanges].filter(\n (s): s is NonNullable<typeof s> => !!s,\n );\n if (streams.length) {\n merge(...streams)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._ngControlRev.update((n) => n + 1));\n }\n }\n\n const submit = this.parentFormGroup?.ngSubmit ?? this.parentForm?.ngSubmit;\n if (submit) {\n submit\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this._formSubmitRev.update((n) => n + 1));\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-transfer.mjs","sources":["../../../projects/ngx-tw/transfer/transfer.ts","../../../projects/ngx-tw/transfer/cdevhub-ngx-tw-transfer.ts"],"sourcesContent":["/*\n * tw-transfer — dual-listbox shuttle. Two panels (source / target) with a column\n * of move buttons between them; the user ticks items in a panel and shuttles the\n * ticked items to the other side. The component's *value* is the set of keys\n * currently on the target side (`targetKeys`), exposed through\n * `ControlValueAccessor` + `FormFieldControl` (mirrors `tags-input` / `select`).\n *\n * Architecture decisions (verified against @angular/cdk 21.2.x source):\n * - Each panel body is one `[cdkListbox]` (multiple) with one `[cdkOption]` per\n * VISIBLE item. CDK owns `role=\"listbox\"`/`\"option\"`, `aria-multiselectable`/\n * `aria-selected`, roving-tabindex Arrow/Home/End, Space/Enter toggle, and\n * typeahead. We do NOT roll a custom listbox or reuse select's overlay.\n * - Option value is the item's KEY `K` (`[cdkOption]=\"row.key\"`), so each panel's\n * `cdkListboxValue` is a `readonly K[]` and `compareWith` is key identity.\n * - TWO selection layers, kept distinct:\n * • `targetKeys` (signal) — persisted membership = the CVA value.\n * • per-panel ephemeral \"checked\" — the CdkListbox value, cleared after moves.\n * - The checked binding is CONTROLLED: `[cdkListboxValue]=\"<panel>Checked()\"`,\n * writing the user's `cdkListboxValueChange` back into that signal. Programmatic\n * writes to `cdkListboxValue` are SILENT in CDK (only user gestures call\n * `valueChange.next` — verified: triggerOption/triggerRange), so the loop never\n * re-enters → no cycle / freeze.\n * - The checked set is a `linkedSignal` whose source is the rendered-key set: on\n * every render change it PRUNES keys whose option is no longer present (a filter\n * hid it, or a move removed it). Two consequences: (1) the bound value is always\n * a subset of the rendered options, so CdkListbox's internal `_invalid` flag —\n * which would otherwise collapse the whole selection to `[]` — never trips; and\n * (2) a key checked then filtered out is dropped permanently (it does NOT\n * re-appear when the filter clears). This matches the requirements doc and side-\n * steps a CDK quirk where a controlled value re-surfacing a just-re-rendered\n * option is not reliably re-selected. Moves always act on the visible subset.\n */\n\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n DestroyRef,\n Directive,\n ElementRef,\n forwardRef,\n inject,\n Injector,\n input,\n isDevMode,\n linkedSignal,\n type OnInit,\n output,\n signal,\n type Signal,\n TemplateRef,\n} from '@angular/core';\nimport { type ControlValueAccessor, NgControl } from '@angular/forms';\nimport {\n CdkListbox,\n CdkOption,\n type ListboxValueChangeEvent,\n} from '@angular/cdk/listbox';\nimport { FocusMonitor, LiveAnnouncer } from '@angular/cdk/a11y';\nimport { Platform } from '@angular/cdk/platform';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n type TwSize,\n wireErrorState,\n} from '@cdevhub/ngx-tw/core';\nimport {\n FormFieldControl,\n TW_FORM_FIELD_CONTROL,\n} from '@cdevhub/ngx-tw/form-field';\nimport { CheckboxComponent } from '@cdevhub/ngx-tw/checkbox';\nimport { InputDirective } from '@cdevhub/ngx-tw/input';\n\n// ── Public types ──────────────────────────────────────────────────────\n\n/** Which panel of the transfer an item / event belongs to. */\nexport type TwTransferSide = 'source' | 'target';\n\n/** i18n strings for the transfer. Pass any subset; unset keys fall back to the English defaults. */\nexport interface TwTransferLabels {\n /** Source (left) panel title. Defaults to `'Source'`. */\n sourceTitle?: string;\n /** Target (right) panel title. Defaults to `'Target'`. */\n targetTitle?: string;\n /** Placeholder + accessible name for the per-panel search inputs. Defaults to `'Search'`. */\n searchPlaceholder?: string;\n /** Text shown in a panel body when it has no visible items. Defaults to `'No items'`. */\n emptyText?: string;\n /** Accessible name for the header select-all checkbox. Defaults to `'Select all'`. */\n selectAllLabel?: string;\n /** Accessible name for the → (move-to-target) button. Defaults to `'Move selected to target'`. */\n moveToTargetLabel?: string;\n /** Accessible name for the ← (move-to-source) button. Defaults to `'Move selected to source'`. */\n moveToSourceLabel?: string;\n /** Count template rendered in each panel header. Variables: `{total}`, `{selected}`. Defaults to `'{total} items'`. */\n countFormat?: string;\n /** LiveAnnouncer template announced after a move. Variables: `{count}`, `{target}`. Defaults to `'{count} items moved to {target}'`. */\n moveAnnouncement?: string;\n}\n\n/** Visual configuration for the transfer. Pass any subset; unset keys fall back to the defaults. */\nexport interface TwTransferDisplayConfig {\n /** Row / control density across the design-system ramps. Defaults to `'md'`. */\n size?: TwSize;\n /** Scroll-viewport height of each list, in px (a number) or `'auto'` (flow with content). Defaults to `240`. */\n listHeight?: number | 'auto';\n /** When true, each panel gets a labelled search input above its list. Defaults to `false`. */\n showSearch?: boolean;\n /** When true, each panel header shows a tri-state select-all checkbox. Defaults to `true`. */\n showSelectAll?: boolean;\n}\n\n/** Behavioural configuration for the transfer. Generic over item type `T`. Pass any subset; unset keys fall back to the defaults. */\nexport interface TwTransferBehaviorConfig<T = unknown> {\n /** When true, items only flow source → target; the ← button is not rendered. Defaults to `false`. */\n oneWay?: boolean;\n /** Custom search predicate. Defaults to a case-insensitive substring match of the query against `labelFn(item)`. */\n filterFn?: (item: T, query: string) => boolean;\n /** Per-item disable predicate. A disabled item renders as a disabled option and is excluded from select-all and all moves. Defaults to `() => false`. */\n disabledItem?: (item: T) => boolean;\n}\n\n/** Context surfaced to a `*twTransferItem` template. Generic over the item type `T`. */\nexport interface TwTransferItemContext<T> {\n /** The item data (implicit `let-item`). */\n $implicit: T;\n /** Resolved `labelFn(item)`. */\n label: string;\n /** Ephemeral pending-move checked state of this row's option. */\n checked: boolean;\n /** Whether the item is disabled (via `behavior.disabledItem`). */\n disabled: boolean;\n /** Which panel this row renders in. */\n side: TwTransferSide;\n}\n\n/** Payload emitted by `moved`. Generic over the key type `K`. */\nexport interface TwTransferMovedEvent<K> {\n /** The keys that moved in this interaction. */\n keys: readonly K[];\n /** The direction of the move. */\n direction: 'toTarget' | 'toSource';\n}\n\n// ── Resolved-default constants ────────────────────────────────────────\n\nconst LABELS_DEFAULTS: Required<TwTransferLabels> = {\n sourceTitle: 'Source',\n targetTitle: 'Target',\n searchPlaceholder: 'Search',\n emptyText: 'No items',\n selectAllLabel: 'Select all',\n moveToTargetLabel: 'Move selected to target',\n moveToSourceLabel: 'Move selected to source',\n countFormat: '{total} items',\n moveAnnouncement: '{count} items moved to {target}',\n};\n\nconst DISPLAY_DEFAULTS: Required<TwTransferDisplayConfig> = {\n size: 'md',\n listHeight: 240,\n showSearch: false,\n showSelectAll: true,\n};\n\n/** Replaces `{name}` tokens in a template with values from `vars`. */\nfunction formatLabel(\n template: string,\n vars: Record<string, string | number>,\n): string {\n // Defence in depth. `resolvedLabels()` already filters explicitly-undefined\n // consumer keys, so a non-string cannot reach here through the public\n // `labels` input today. The guard exists so a future regression in that\n // merge degrades to a missing label instead of throwing.\n if (typeof template !== 'string') return '';\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n key in vars ? String(vars[key]) : match,\n );\n}\n\n// ── tv() config ───────────────────────────────────────────────────────\n//\n// All class strings are literal so the Tailwind v4 JIT scanner picks them up.\n// Semantic + surface/fg/border tokens only. The selected/checked option styling\n// mirrors `tree`'s selected node (`bg-primary-50 text-primary-700`, no `dark:`\n// overrides — slot tokens own structural light/dark contrast).\n\nconst transferVariants = tv(\n {\n slots: {\n // panel · controls · panel. The middle column is auto width; both panels\n // share the remaining space and clamp to `min-w-0` so rows can truncate.\n root: 'grid grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] gap-3 items-stretch text-fg',\n panel:\n 'flex flex-col min-w-0 rounded-lg border border-border bg-surface overflow-hidden',\n panelHeader:\n 'flex items-center gap-2 border-b border-border bg-surface-muted',\n panelTitle: 'text-sm font-semibold text-fg min-w-0 truncate flex-1',\n panelCount: 'text-xs text-fg-muted shrink-0 tabular-nums',\n search: 'border-b border-border',\n // The cdkListbox scroll viewport. `outline-none` because focus rides the\n // individual options (canonical ring there), not the container.\n list: 'flex flex-col overflow-y-auto outline-none',\n // The cdkOption row.\n option:\n 'flex items-center gap-2 cursor-pointer select-none text-fg transition-colors duration-200 motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n // Presentational check glyph (aria-hidden). Always laid out (for alignment);\n // visibility toggles via opacity off the checked state.\n optionCheck:\n 'shrink-0 transition-opacity duration-200 motion-reduce:transition-none',\n optionLabel: 'min-w-0 truncate flex-1',\n controls: 'flex flex-col justify-center gap-2',\n // Plain square move buttons (icon-only). Square-interactive sub-scale per\n // size; not the [twButton] directive (its size padding would fight a square\n // override across two class bindings).\n moveButton:\n 'inline-flex items-center justify-center shrink-0 rounded-md border border-border bg-surface text-fg-muted cursor-pointer transition-colors duration-200 motion-reduce:transition-none hover:bg-surface-muted hover:text-fg hover:border-border-strong focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500 disabled:opacity-50 disabled:pointer-events-none disabled:cursor-not-allowed',\n // Glyph inside the square move button. Glyph sub-scale saturating at\n // `lg`: 3 / 4 / 5 / 6 / 6, matching `optionCheck`. Previously 4/4/5/5/5,\n // which left three of the five advertised steps dead. `xl` stops at\n // 24px rather than the scale's 32px because the glyph lives inside a\n // 36px `moveButton` (the square-interactive scale saturates at `lg`\n // too, per CLAUDE.md) — a 32px glyph in a 36px target leaves no optical\n // padding. Raising one means raising the other.\n moveIcon: 'shrink-0',\n empty:\n 'flex items-center justify-center p-4 text-sm text-fg-subtle text-center',\n },\n variants: {\n size: {\n xs: {\n panelHeader: 'px-2 py-1',\n search: 'px-2 py-1',\n option: 'px-2 py-1 text-xs gap-1.5',\n optionCheck: 'size-3',\n moveButton: 'size-6',\n moveIcon: 'size-3',\n empty: 'text-xs',\n },\n sm: {\n panelHeader: 'px-3 py-1.5',\n search: 'px-3 py-1.5',\n option: 'px-3 py-1.5 text-sm',\n optionCheck: 'size-4',\n moveButton: 'size-7',\n moveIcon: 'size-4',\n },\n md: {\n panelHeader: 'px-4 py-2',\n search: 'px-3 py-2',\n option: 'px-3 py-2 text-sm',\n optionCheck: 'size-5',\n moveButton: 'size-8',\n moveIcon: 'size-5',\n },\n lg: {\n panelHeader: 'px-5 py-2.5',\n search: 'px-4 py-2.5',\n option: 'px-4 py-2.5 text-base',\n optionCheck: 'size-6',\n moveButton: 'size-9',\n moveIcon: 'size-6',\n },\n xl: {\n panelHeader: 'px-6 py-3',\n search: 'px-4 py-3',\n option: 'px-4 py-3 text-base',\n optionCheck: 'size-6',\n moveButton: 'size-9',\n moveIcon: 'size-6',\n },\n },\n checked: {\n true: {\n option: 'bg-primary-50 text-primary-700 hover:bg-primary-50',\n optionCheck: 'opacity-100 text-primary-600',\n },\n false: {\n option: 'hover:bg-surface-muted',\n optionCheck: 'opacity-0',\n },\n },\n optionDisabled: {\n true: { option: 'opacity-50 pointer-events-none' },\n false: {},\n },\n disabled: {\n true: { root: 'opacity-50 pointer-events-none' },\n false: {},\n },\n },\n defaultVariants: {\n size: 'md',\n checked: false,\n optionDisabled: false,\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\n// ── TransferItemDefDirective ──────────────────────────────────────────\n//\n// Pure TemplateRef carrier for the consumer's per-item template. Mirrors tree's\n// `TreeNodeDefDirective` / table's `CellDefDirective`: a typed context +\n// `ngTemplateContextGuard` so `let-item` / `let-checked=\"checked\"` type-check.\n// Optional — when absent each row renders the default check glyph + label.\n\n/** Structural directive (`*twTransferItem=\"let item\"`) declaring the per-item template. Typed as `TwTransferItemContext<T>`. */\n@Directive({ selector: '[twTransferItem]' })\nexport class TransferItemDefDirective<T = unknown> {\n /** @internal Consumer-projected per-item template. */\n readonly template = inject(TemplateRef<TwTransferItemContext<T>>);\n\n /** @internal */\n static ngTemplateContextGuard<T>(\n _dir: TransferItemDefDirective<T>,\n _ctx: unknown,\n ): _ctx is TwTransferItemContext<T> {\n return true;\n }\n}\n\n// ── Internal view-model types ─────────────────────────────────────────\n\ninterface RowBase<T, K> {\n readonly item: T;\n readonly key: K;\n readonly label: string;\n readonly disabled: boolean;\n}\n\ninterface RowView<T, K> extends RowBase<T, K> {\n readonly checked: boolean;\n readonly optionClass: string;\n readonly checkClass: string;\n readonly context: TwTransferItemContext<T>;\n}\n\ninterface PanelView<T, K> {\n readonly side: TwTransferSide;\n readonly title: string;\n readonly titleId: string;\n readonly countText: string;\n readonly emptyText: string;\n readonly searchPlaceholder: string;\n readonly selectAllLabel: string;\n readonly query: string;\n readonly rows: readonly RowView<T, K>[];\n readonly checkedValue: readonly K[];\n readonly selectAllChecked: boolean;\n readonly selectAllIndeterminate: boolean;\n}\n\nlet nextId = 0;\n\n// ── TransferComponent ─────────────────────────────────────────────────\n\n/**\n * A dual-listbox shuttle: two panels (source / target) with a column of move\n * buttons between them. The user ticks items in a panel and shuttles them across;\n * an optional per-panel search and a tri-state header select-all accelerate bulk\n * moves. The component's value is the set of keys on the target side, exposed\n * through `ControlValueAccessor` + `FormFieldControl` so it works with reactive,\n * template-driven, and signal forms and integrates with `<tw-form-field>`.\n *\n * Each panel composes `@angular/cdk/listbox` (`CdkListbox` / `CdkOption`) for\n * focus-managed, accessible, keyboard-navigable selection. Consumers supply\n * `keyFn` (required) and `labelFn` (defaulted to `String(item)`), and may project\n * a `*twTransferItem` template for rich row content.\n */\n@Component({\n selector: 'tw-transfer',\n exportAs: 'twTransfer',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet, CdkListbox, CdkOption, CheckboxComponent, InputDirective],\n providers: [\n {\n provide: TW_FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => TransferComponent),\n },\n ],\n host: {\n role: 'group',\n '[id]': 'id()',\n '[class]': 'rootClasses()',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'resolvedLabelledBy() || null',\n '[attr.aria-describedby]': 'resolvedDescribedBy() || null',\n '[attr.aria-disabled]': 'disabled() || null',\n // NOTE: no `aria-invalid` here. ARIA 1.2 does not allow it on `role=\"group\"`\n // (axe: critical `aria-allowed-attr`). It is carried by the target panel's\n // content region instead — `value` is `targetKeys`, so that panel is the one\n // holding the value. `tags-input` and `file-upload` were corrected the same\n // way in an earlier pass; this component was missed.\n '[attr.data-focused]': 'focused() || null',\n },\n template: `\n <!-- One panel, instantiated twice (source, then target) around the controls. -->\n <ng-template #panelTpl let-panel>\n <div [class]=\"panelClasses()\">\n <div [class]=\"panelHeaderClasses()\">\n @if (showSelectAll()) {\n <tw-checkbox\n [size]=\"checkboxSize()\"\n [checked]=\"panel.selectAllChecked\"\n [indeterminate]=\"panel.selectAllIndeterminate\"\n [disabled]=\"disabled()\"\n [aria-label]=\"panel.selectAllLabel\"\n (change)=\"onSelectAll(panel.side, $event)\"\n />\n }\n <span [id]=\"panel.titleId\" [class]=\"panelTitleClasses()\">{{ panel.title }}</span>\n <span [class]=\"panelCountClasses()\">{{ panel.countText }}</span>\n </div>\n\n @if (showSearch()) {\n <div [class]=\"searchClasses()\">\n <input\n twInput\n type=\"text\"\n [size]=\"resolvedSize()\"\n [value]=\"panel.query\"\n [disabled]=\"disabled()\"\n [attr.placeholder]=\"panel.searchPlaceholder\"\n [attr.aria-label]=\"panel.searchPlaceholder\"\n (input)=\"onSearch(panel.side, $event)\"\n />\n </div>\n }\n\n <!-- The cdkListbox is rendered only when it has options. An empty\n role=\"listbox\" violates aria-required-children, so an empty panel\n shows a plain message region instead. -->\n @if (panel.rows.length > 0) {\n <div\n cdkListbox\n [cdkListboxMultiple]=\"true\"\n [cdkListboxValue]=\"panel.checkedValue\"\n [cdkListboxDisabled]=\"disabled()\"\n [cdkListboxCompareWith]=\"compareKeys\"\n [class]=\"listClasses()\"\n [style.height.px]=\"listHeightPx()\"\n [attr.aria-labelledby]=\"panel.titleId\"\n [attr.aria-invalid]=\"panel.side === 'target' && errorState() ? 'true' : null\"\n (cdkListboxValueChange)=\"onCheckedChange(panel.side, $event)\"\n >\n @for (row of panel.rows; track row.key) {\n <div\n [cdkOption]=\"row.key\"\n [cdkOptionDisabled]=\"row.disabled\"\n [cdkOptionTypeaheadLabel]=\"row.label\"\n [class]=\"row.optionClass\"\n >\n <svg\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-hidden=\"true\"\n [class]=\"row.checkClass\"\n >\n <path\n fill-rule=\"evenodd\"\n d=\"M16.704 5.29a1 1 0 0 1 .006 1.414l-7.5 7.6a1 1 0 0 1-1.42.005l-3.5-3.5a1 1 0 1 1 1.414-1.414l2.79 2.79 6.796-6.889a1 1 0 0 1 1.414-.006Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n @if (itemTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"row.context\"\n />\n } @else {\n <span [class]=\"optionLabelClasses()\">{{ row.label }}</span>\n }\n </div>\n }\n </div>\n } @else {\n <!--\n Also carries aria-invalid: an empty target is exactly when a required\n transfer is invalid, and the listbox above does not exist to carry it\n (an empty role=listbox would violate aria-required-children).\n -->\n <div\n [class]=\"emptyClasses()\"\n [style.height.px]=\"listHeightPx()\"\n [attr.aria-invalid]=\"panel.side === 'target' && errorState() ? 'true' : null\"\n >{{ panel.emptyText }}</div>\n }\n </div>\n </ng-template>\n\n <ng-container\n [ngTemplateOutlet]=\"panelTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: sourcePanel() }\"\n />\n\n <div [class]=\"controlsClasses()\">\n <button\n type=\"button\"\n [class]=\"moveButtonClasses()\"\n [disabled]=\"disabled() || sourceMovableKeys().length === 0\"\n [attr.aria-label]=\"resolvedLabels().moveToTargetLabel\"\n (click)=\"onMoveToTarget()\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\" [class]=\"moveIconClasses()\">\n <path\n fill-rule=\"evenodd\"\n d=\"M7.21 14.77a.75.75 0 0 1 .02-1.06L11.168 10 7.23 6.29a.75.75 0 1 1 1.04-1.08l4.5 4.25a.75.75 0 0 1 0 1.08l-4.5 4.25a.75.75 0 0 1-1.06-.02Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n\n @if (!oneWay()) {\n <button\n type=\"button\"\n [class]=\"moveButtonClasses()\"\n [disabled]=\"disabled() || targetMovableKeys().length === 0\"\n [attr.aria-label]=\"resolvedLabels().moveToSourceLabel\"\n (click)=\"onMoveToSource()\"\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\" [class]=\"moveIconClasses()\">\n <path\n fill-rule=\"evenodd\"\n d=\"M12.79 5.23a.75.75 0 0 1-.02 1.06L8.832 10l3.938 3.71a.75.75 0 1 1-1.04 1.08l-4.5-4.25a.75.75 0 0 1 0-1.08l4.5-4.25a.75.75 0 0 1 1.06.02Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </button>\n }\n </div>\n\n <ng-container\n [ngTemplateOutlet]=\"panelTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: targetPanel() }\"\n />\n `,\n})\nexport class TransferComponent<T = unknown, K = unknown>\n extends FormFieldControl<readonly K[]>\n implements ControlValueAccessor, OnInit\n{\n // ── Inputs ──\n\n /** All items across both panels. The source/target split derives from the value, not the reverse. Defaults to `[]`. */\n readonly data = input<readonly T[]>([]);\n\n /** Resolves a stable key for an item — drives membership (the value), checked state, tracking, the cdkOption value, and compareWith. Required. */\n readonly keyFn = input.required<(item: T) => K>();\n\n /** Resolves an item's display label — used for the default row render, search filtering, and listbox typeahead. Defaults to `(item) => String(item)`. */\n readonly labelFn = input<(item: T) => string>((item: T) => String(item));\n\n /** Per-panel text + ARIA labels. Partial; unset keys fall back to the English defaults. */\n readonly labels = input<Partial<TwTransferLabels>>({});\n\n /** Visual configuration — size, list viewport height, search / select-all visibility. Partial; unset keys fall back to the defaults. */\n readonly display = input<Partial<TwTransferDisplayConfig>>({});\n\n /** Behavioural configuration — oneWay, custom filterFn, per-item disabledItem predicate. Partial; unset keys fall back to the defaults. */\n readonly behavior = input<Partial<TwTransferBehaviorConfig<T>>>({});\n\n /** Disables the entire control — panels non-interactive, search + buttons disabled, muted styling. Also driven by Forms `setDisabledState`. Defaults to `false`. */\n readonly disabledInput = input(false, { alias: 'disabled' });\n\n /** Marks the control as required. Mirrored to `aria-required` chrome via the form-field; also inferred from `Validators.required` on a bound control. Defaults to `false`. */\n readonly requiredInput = input(false, { alias: 'required' });\n\n /** Reserved for control identification (e.g. analytics, future native-submission parity). The transfer has no single native value element, so it is not currently reflected to the DOM. Defaults to `undefined`. */\n readonly name = input<string | undefined>(undefined);\n\n /** Id on the host element. Auto-generated as `tw-transfer-N` when unset. Used by the form-field's `<label for>` association. Alias: `id`. */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /** Accessible name applied to the control when no visible label is wired. Mirrored to `aria-label`. Defaults to `undefined`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID of an external element that labels the control. Mirrored to `aria-labelledby`. Defaults to `undefined`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n /** ID of an external element that describes the control. The form-field merges its hint / error ids alongside. Defaults to `undefined`. Alias: `aria-describedby`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, { alias: 'aria-describedby' });\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, uses the `TW_ERROR_STATE_MATCHER` token's value. Defaults to `undefined`. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n // ── Outputs ──\n\n /** Fires when items move between panels by user interaction. Payload is the new full target-keys array. Does not fire on `writeValue`. */\n readonly valueChange = output<readonly K[]>();\n\n /** Fires after each directional move, identifying the moved keys and their direction. Does not fire on `writeValue`. */\n readonly moved = output<TwTransferMovedEvent<K>>();\n\n // ── Content query ──\n\n /** @internal Consumer-projected per-item template (`*twTransferItem`). */\n readonly itemTemplate = contentChild(TransferItemDefDirective<T>);\n\n // ── Injected deps ──\n\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n private readonly platform = inject(Platform);\n\n // ── Identity ──\n\n private readonly uid = nextId++;\n /** @internal Fallback id used when the consumer does not set `[id]`. */\n readonly hostId = `tw-transfer-${this.uid}`;\n private readonly sourceTitleId = `${this.hostId}-source-title`;\n private readonly targetTitleId = `${this.hostId}-target-title`;\n\n // ── State signals ──\n\n /** @internal The value: keys currently on the target side. Source of truth for membership. */\n private readonly targetKeys = signal<readonly K[]>([]);\n /** @internal Per-panel search queries. */\n private readonly sourceQuery = signal('');\n private readonly targetQuery = signal('');\n\n private readonly cvaDisabled = signal(false);\n private readonly _focused = signal(false);\n\n /** @internal Shared `errorState` / `required` / `errors` derivation — see `wireErrorState`. */\n private readonly errorWiring = wireErrorState({\n ngControl: () => this.ngControl,\n matcher: () => this.errorStateMatcher(),\n required: () => this.requiredInput(),\n track: [() => this._focused()],\n });\n private readonly describedByIdsSignal = signal<readonly string[]>([]);\n private readonly labelledByIdsSignal = signal<readonly string[]>([]);\n\n private onChange: (value: readonly K[]) => void = () => {};\n private onTouched: () => void = () => {};\n\n /** @internal Stable comparator for `[cdkListboxCompareWith]`. Keys are identity-comparable. */\n readonly compareKeys = (a: K, b: K): boolean => Object.is(a, b);\n\n // ── Resolved config ──\n\n /**\n * @internal Resolved label record.\n *\n * Explicitly-undefined keys are dropped before merging. Root `tsconfig.json`\n * does not set `exactOptionalPropertyTypes`, so\n * `[labels]=\"{ moveAnnouncement: i18n.moved }\"` type-checks even when the\n * i18n bundle has no such key — and a plain spread would then overwrite the\n * default with `undefined`, which reaches `formatLabel()` and throws\n * `Cannot read properties of undefined (reading 'replace')`. Same filter\n * `table.ts` and `timeline.ts` already use; the `Required<>` annotation only\n * tells the truth once the filter is in place.\n */\n readonly resolvedLabels = computed<Required<TwTransferLabels>>(() => {\n const overrides = Object.fromEntries(\n Object.entries(this.labels() ?? {}).filter(([, value]) => value !== undefined),\n );\n return { ...LABELS_DEFAULTS, ...overrides } as Required<TwTransferLabels>;\n });\n\n /**\n * @internal Resolved display config. Same explicitly-undefined filter as\n * `resolvedLabels` — a plain spread let `[display]=\"{ listHeight: undefined }\"`\n * reach the list's inline `height` as `undefined`, collapsing the panes.\n */\n private readonly resolvedDisplay = computed<Required<TwTransferDisplayConfig>>(() => {\n const overrides = Object.fromEntries(\n Object.entries(this.display() ?? {}).filter(([, value]) => value !== undefined),\n );\n return { ...DISPLAY_DEFAULTS, ...overrides } as Required<TwTransferDisplayConfig>;\n });\n\n // Behaviour is resolved inline (not via a `Required<>` const) because `filterFn`\n // is legitimately optional and both predicates are generic over `T`.\n private readonly resolvedBehavior = computed(() => {\n const b = this.behavior();\n return {\n oneWay: b.oneWay ?? false,\n filterFn: b.filterFn,\n disabledItem: b.disabledItem ?? ((_item: T) => false),\n };\n });\n\n /** @internal */\n readonly resolvedSize = computed<TwSize>(() => this.resolvedDisplay().size);\n /** @internal Checkbox tops out at `lg` density; map xl → lg. */\n readonly checkboxSize = computed<TwSize>(() => {\n const s = this.resolvedSize();\n return s === 'xl' ? 'lg' : s;\n });\n /** @internal */\n readonly showSearch = computed(() => this.resolvedDisplay().showSearch);\n /** @internal */\n readonly showSelectAll = computed(() => this.resolvedDisplay().showSelectAll);\n /** @internal */\n readonly oneWay = computed(() => this.resolvedBehavior().oneWay);\n /** @internal Fixed list height in px, or `null` when `'auto'`. */\n readonly listHeightPx = computed(() => {\n const h = this.resolvedDisplay().listHeight;\n return h === 'auto' ? null : h;\n });\n\n // ── Derived membership state ──\n\n /** @internal Map from key to item across all data — for orphan-aware target rendering and disabled lookups. */\n private readonly itemByKey = computed(() => {\n const kf = this.keyFn();\n const map = new Map<K, T>();\n for (const item of this.data()) map.set(kf(item), item);\n return map;\n });\n\n private readonly targetKeySet = computed(() => new Set(this.targetKeys()));\n\n /** @internal Items on the source side (in `data` order). */\n private readonly sourceItems = computed<readonly T[]>(() => {\n const inTarget = this.targetKeySet();\n const kf = this.keyFn();\n return this.data().filter((item) => !inTarget.has(kf(item)));\n });\n\n /** @internal Items on the target side (in `targetKeys` order; orphan keys with no item are skipped). */\n private readonly targetItems = computed<readonly T[]>(() => {\n const map = this.itemByKey();\n const out: T[] = [];\n for (const key of this.targetKeys()) {\n const item = map.get(key);\n if (item !== undefined) out.push(item);\n }\n return out;\n });\n\n // ── Per-panel row pipelines (source) ──\n // Stage 1 (base) carries no checked flag → renderedKeys / reconciled derive from\n // it without a cycle. Stage 2 augments with checked state + precomputed classes.\n\n private readonly sourceRowsBase = computed(() =>\n this.toRowsBase(this.filterItems(this.sourceItems(), this.sourceQuery())),\n );\n private readonly sourceRenderedKeys = computed(\n () => new Set(this.sourceRowsBase().map((r) => r.key)),\n );\n /**\n * @internal Ephemeral pending-move checked keys for the source panel — the\n * controlled `[cdkListboxValue]`. A `linkedSignal` over the rendered-key set so\n * it auto-prunes keys whose option a filter / move removed (kept ⊆ rendered → no\n * CdkListbox `_invalid`; dropped keys do not re-surface). Cleared after moves.\n */\n readonly sourceChecked = linkedSignal<ReadonlySet<K>, readonly K[]>({\n source: this.sourceRenderedKeys,\n computation: (rendered, prev) =>\n (prev?.value ?? []).filter((k) => rendered.has(k)),\n });\n private readonly sourceCheckedSet = computed(() => new Set(this.sourceChecked()));\n private readonly sourceRows = computed(() =>\n this.toRows(this.sourceRowsBase(), this.sourceCheckedSet(), 'source'),\n );\n\n // ── Per-panel row pipelines (target) ──\n\n private readonly targetRowsBase = computed(() =>\n this.toRowsBase(this.filterItems(this.targetItems(), this.targetQuery())),\n );\n private readonly targetRenderedKeys = computed(\n () => new Set(this.targetRowsBase().map((r) => r.key)),\n );\n /** @internal Ephemeral pending-move checked keys for the target panel — see {@link sourceChecked}. */\n readonly targetChecked = linkedSignal<ReadonlySet<K>, readonly K[]>({\n source: this.targetRenderedKeys,\n computation: (rendered, prev) =>\n (prev?.value ?? []).filter((k) => rendered.has(k)),\n });\n private readonly targetCheckedSet = computed(() => new Set(this.targetChecked()));\n private readonly targetRows = computed(() =>\n this.toRows(this.targetRowsBase(), this.targetCheckedSet(), 'target'),\n );\n\n // ── Movable + select-all derivations ──\n\n /** @internal Checked, enabled, visible source keys — what the → button moves. */\n readonly sourceMovableKeys = computed<readonly K[]>(() => {\n const checked = this.sourceCheckedSet();\n return this.sourceRowsBase()\n .filter((r) => !r.disabled && checked.has(r.key))\n .map((r) => r.key);\n });\n\n /** @internal Checked, enabled, visible target keys — what the ← button moves. */\n readonly targetMovableKeys = computed<readonly K[]>(() => {\n const checked = this.targetCheckedSet();\n return this.targetRowsBase()\n .filter((r) => !r.disabled && checked.has(r.key))\n .map((r) => r.key);\n });\n\n private readonly sourceSelectAllKeys = computed<readonly K[]>(() =>\n this.sourceRowsBase().filter((r) => !r.disabled).map((r) => r.key),\n );\n private readonly targetSelectAllKeys = computed<readonly K[]>(() =>\n this.targetRowsBase().filter((r) => !r.disabled).map((r) => r.key),\n );\n\n // ── Panel view-models ──\n\n /** @internal */\n readonly sourcePanel = computed<PanelView<T, K>>(() =>\n this.buildPanel(\n 'source',\n this.sourceTitleId,\n this.resolvedLabels().sourceTitle,\n this.sourceRowsBase(),\n this.sourceRows(),\n this.sourceCheckedSet(),\n this.sourceSelectAllKeys(),\n this.sourceChecked(),\n this.sourceQuery(),\n ),\n );\n\n /** @internal */\n readonly targetPanel = computed<PanelView<T, K>>(() =>\n this.buildPanel(\n 'target',\n this.targetTitleId,\n this.resolvedLabels().targetTitle,\n this.targetRowsBase(),\n this.targetRows(),\n this.targetCheckedSet(),\n this.targetSelectAllKeys(),\n this.targetChecked(),\n this.targetQuery(),\n ),\n );\n\n // ── tv() class outputs ──\n\n private readonly variants = computed(() =>\n transferVariants({\n size: this.resolvedSize(),\n disabled: this.disabled(),\n }),\n );\n\n /** @internal */\n readonly rootClasses = computed(() => this.variants().root());\n /** @internal */\n readonly panelClasses = computed(() => this.variants().panel());\n /** @internal */\n readonly panelHeaderClasses = computed(() => this.variants().panelHeader());\n /** @internal */\n readonly panelTitleClasses = computed(() => this.variants().panelTitle());\n /** @internal */\n readonly panelCountClasses = computed(() => this.variants().panelCount());\n /** @internal */\n readonly searchClasses = computed(() => this.variants().search());\n /** @internal */\n readonly listClasses = computed(() => this.variants().list());\n /** @internal */\n readonly optionLabelClasses = computed(() => this.variants().optionLabel());\n /** @internal */\n readonly controlsClasses = computed(() => this.variants().controls());\n /** @internal */\n readonly moveButtonClasses = computed(() => this.variants().moveButton());\n /** @internal */\n readonly moveIconClasses = computed(() => this.variants().moveIcon());\n /** @internal */\n readonly emptyClasses = computed(() => this.variants().empty());\n\n constructor() {\n super();\n // Runtime CVA wiring — register on any host-level NgControl. The component\n // injects `NgControl { self }` for TW_ERROR_STATE_MATCHER, so a static\n // NG_VALUE_ACCESSOR provider would create circular DI on the same instance.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-transfer] The control has no accessible name. Provide `aria-label` / `aria-labelledby`, or wrap it in a <tw-form-field> with a <label twLabel>.',\n );\n }\n });\n }\n\n // ── Public methods ──\n\n /** Moves the given items (by key) to the target side; ignores keys already there or whose item is disabled. Clears the source panel's pending checks, emits `valueChange` + `moved`, calls the CVA onChange, and announces the move. No-op when the control is disabled. */\n moveToTarget(keys: readonly K[]): void {\n if (this.disabled()) return;\n const current = this.targetKeys();\n const existing = new Set(current);\n const disabledFn = this.resolvedBehavior().disabledItem;\n const map = this.itemByKey();\n const moved: K[] = [];\n for (const key of keys) {\n if (existing.has(key)) continue;\n const item = map.get(key);\n if (item !== undefined && disabledFn(item)) continue;\n existing.add(key);\n moved.push(key);\n }\n this.sourceChecked.set([]);\n if (!moved.length) return;\n // Append moved keys to the existing array — orphan keys (in the value, not in\n // `data`) are part of `current` and therefore preserved.\n this.applyValue([...current, ...moved], moved, 'toTarget');\n }\n\n /** Moves the given items (by key) to the source side; ignores keys not on target or whose item is disabled. Clears the target panel's pending checks. No-op when the control is disabled or `behavior.oneWay` is on. Same emissions as {@link moveToTarget}. */\n moveToSource(keys: readonly K[]): void {\n if (this.disabled() || this.resolvedBehavior().oneWay) return;\n const current = this.targetKeys();\n const present = new Set(current);\n const disabledFn = this.resolvedBehavior().disabledItem;\n const map = this.itemByKey();\n const remove = new Set<K>();\n for (const key of keys) {\n if (!present.has(key)) continue;\n const item = map.get(key);\n if (item !== undefined && disabledFn(item)) continue;\n remove.add(key);\n }\n this.targetChecked.set([]);\n if (!remove.size) return;\n // Filter the existing array — unspecified orphan keys are preserved.\n this.applyValue(\n current.filter((k) => !remove.has(k)),\n [...remove],\n 'toSource',\n );\n }\n\n // ── Template event handlers ──\n\n /** @internal */\n onCheckedChange(side: TwTransferSide, event: ListboxValueChangeEvent<K>): void {\n if (side === 'source') this.sourceChecked.set([...event.value]);\n else this.targetChecked.set([...event.value]);\n }\n\n /** @internal Select-all toggles the visible, enabled keys for the panel (replace semantics). */\n onSelectAll(side: TwTransferSide, checked: boolean): void {\n if (side === 'source') {\n this.sourceChecked.set(checked ? [...this.sourceSelectAllKeys()] : []);\n } else {\n this.targetChecked.set(checked ? [...this.targetSelectAllKeys()] : []);\n }\n }\n\n /** @internal */\n onSearch(side: TwTransferSide, event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n if (side === 'source') this.sourceQuery.set(value);\n else this.targetQuery.set(value);\n }\n\n /** @internal */\n onMoveToTarget(): void {\n this.moveToTarget(this.sourceMovableKeys());\n // The clicked → button disables itself once its checked set drains; a focused\n // element that becomes `disabled` drops focus to <body>. Keep the user in the\n // control by moving focus to the destination listbox (non-empty after a move).\n this.focusDestination('target');\n }\n\n /** @internal */\n onMoveToSource(): void {\n this.moveToSource(this.targetMovableKeys());\n this.focusDestination('source');\n }\n\n /**\n * @internal Focuses the destination panel's listbox after the move re-renders.\n * Deferred to the next render (the destination listbox may have just mounted\n * from empty) and matched by its title id rather than DOM order (the *other*\n * panel may have emptied, removing its listbox).\n */\n private focusDestination(side: TwTransferSide): void {\n if (!this.platform.isBrowser) return;\n const titleId = side === 'source' ? this.sourceTitleId : this.targetTitleId;\n afterNextRender(\n () => {\n const listbox = this.elementRef.nativeElement.querySelector(\n `[cdklistbox][aria-labelledby=\"${titleId}\"]`,\n ) as HTMLElement | null;\n listbox?.focus();\n },\n { injector: this.injector },\n );\n }\n\n // ── Internal helpers ──\n\n private applyValue(\n next: readonly K[],\n moved: readonly K[],\n direction: 'toTarget' | 'toSource',\n ): void {\n this.targetKeys.set(next);\n this.onChange(next);\n this.valueChange.emit(next);\n this.moved.emit({ keys: moved, direction });\n const labels = this.resolvedLabels();\n const dest = direction === 'toTarget' ? labels.targetTitle : labels.sourceTitle;\n this.liveAnnouncer.announce(\n formatLabel(labels.moveAnnouncement, { count: moved.length, target: dest }),\n 'polite',\n );\n }\n\n private filterItems(items: readonly T[], query: string): readonly T[] {\n const q = query.trim();\n if (!q) return items;\n const custom = this.resolvedBehavior().filterFn;\n if (custom) return items.filter((item) => custom(item, q));\n const labelFn = this.labelFn();\n const lower = q.toLowerCase();\n return items.filter((item) => labelFn(item).toLowerCase().includes(lower));\n }\n\n private toRowsBase(items: readonly T[]): RowBase<T, K>[] {\n const kf = this.keyFn();\n const labelFn = this.labelFn();\n const disabledFn = this.resolvedBehavior().disabledItem;\n return items.map((item) => ({\n item,\n key: kf(item),\n label: labelFn(item),\n disabled: disabledFn(item),\n }));\n }\n\n private toRows(\n base: readonly RowBase<T, K>[],\n checked: ReadonlySet<K>,\n side: TwTransferSide,\n ): RowView<T, K>[] {\n const size = this.resolvedSize();\n return base.map((b) => {\n const isChecked = checked.has(b.key);\n const v = transferVariants({\n size,\n checked: isChecked,\n optionDisabled: b.disabled,\n });\n return {\n ...b,\n checked: isChecked,\n optionClass: v.option(),\n checkClass: v.optionCheck(),\n context: {\n $implicit: b.item,\n label: b.label,\n checked: isChecked,\n disabled: b.disabled,\n side,\n },\n };\n });\n }\n\n private buildPanel(\n side: TwTransferSide,\n titleId: string,\n title: string,\n base: readonly RowBase<T, K>[],\n rows: readonly RowView<T, K>[],\n checked: ReadonlySet<K>,\n selectAllKeys: readonly K[],\n checkedValue: readonly K[],\n query: string,\n ): PanelView<T, K> {\n const labels = this.resolvedLabels();\n const selectedCount = rows.reduce((n, r) => (r.checked ? n + 1 : n), 0);\n const state = this.selectAllState(selectAllKeys, checked);\n return {\n side,\n title,\n titleId,\n countText: formatLabel(labels.countFormat, {\n total: base.length,\n selected: selectedCount,\n }),\n emptyText: labels.emptyText,\n searchPlaceholder: labels.searchPlaceholder,\n selectAllLabel: labels.selectAllLabel,\n query,\n rows,\n checkedValue,\n selectAllChecked: state === 'checked',\n selectAllIndeterminate: state === 'indeterminate',\n };\n }\n\n private selectAllState(\n enabledKeys: readonly K[],\n checked: ReadonlySet<K>,\n ): 'checked' | 'indeterminate' | 'unchecked' {\n if (enabledKeys.length === 0) return 'unchecked';\n let n = 0;\n for (const key of enabledKeys) if (checked.has(key)) n++;\n if (n === 0) return 'unchecked';\n if (n === enabledKeys.length) return 'checked';\n return 'indeterminate';\n }\n\n private hasAccessibleNameHint(): boolean {\n return (\n !!this.ariaLabel() ||\n !!this.ariaLabelledby() ||\n this.labelledByIdsSignal().length > 0\n );\n }\n\n // ── FormFieldControl signals ──\n\n /** @internal */\n readonly id: Signal<string> = computed(() => this.idInput() ?? this.hostId);\n\n /** The current target-keys array. Doubles as the `FormFieldControl` value member. */\n readonly value: Signal<readonly K[]> = this.targetKeys.asReadonly();\n\n /** @internal */\n readonly focused: Signal<boolean> = this._focused.asReadonly();\n\n /** @internal Empty when nothing is on the target side — drives the form-field floating label. */\n readonly empty: Signal<boolean> = computed(() => this.targetKeys().length === 0);\n\n /** @internal */\n readonly disabled: Signal<boolean> = computed(\n () => this.disabledInput() || this.cvaDisabled(),\n );\n\n /** @internal */\n readonly required: Signal<boolean> = this.errorWiring.required;\n\n /** @internal */\n readonly errorState: Signal<boolean> = this.errorWiring.errorState;\n\n /** @internal Active validation errors from the bound control, for `[twError match=\"…\"]` filtering. */\n override readonly errors = this.errorWiring.errors;\n\n /** @internal */\n readonly controlType = 'transfer';\n\n /** @internal */\n readonly userAriaDescribedBy: Signal<string | undefined> = computed(() =>\n this.ariaDescribedby(),\n );\n\n /** @internal */\n override readonly userAriaLabelledby: Signal<string | undefined> = computed(() =>\n this.ariaLabelledby(),\n );\n\n /** @internal Merged `aria-describedby` (form-field hint/error ids + consumer-supplied). */\n readonly resolvedDescribedBy = computed(() => {\n const pushed = this.describedByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n const user = this.ariaDescribedby();\n if (user) return user.split(/\\s+/).filter(Boolean).join(' ');\n return '';\n });\n\n /** @internal Merged `aria-labelledby` (form-field label id + consumer-supplied). */\n readonly resolvedLabelledBy = computed(() => {\n const pushed = this.labelledByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n const user = this.ariaLabelledby();\n if (user) return user.split(/\\s+/).filter(Boolean).join(' ');\n return '';\n });\n\n // ── ControlValueAccessor ──\n\n writeValue(value: readonly K[] | null | undefined): void {\n // Orphan keys (present here but absent from `data`) are preserved — they render\n // nothing but survive the round-trip, so a form value outlives a lagging `data`.\n this.targetKeys.set(Array.isArray(value) ? [...value] : []);\n this.sourceChecked.set([]);\n this.targetChecked.set([]);\n }\n\n registerOnChange(fn: (value: readonly K[]) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.cvaDisabled.set(isDisabled);\n }\n\n // ── FormFieldControl methods ──\n\n /** @internal */\n setDescribedByIds(ids: string[]): void {\n this.describedByIdsSignal.set([...ids]);\n }\n\n /** @internal */\n override setLabelledByIds(ids: string[]): void {\n this.labelledByIdsSignal.set([...ids]);\n }\n\n /** @internal Clicking the form-field surface focuses the first listbox. */\n onContainerClick(event: MouseEvent): void {\n if (this.disabled() || event.defaultPrevented) return;\n const host = this.elementRef.nativeElement;\n if (event.target !== host && host.contains(event.target as Node)) return;\n const listbox = host.querySelector('[cdklistbox]') as HTMLElement | null;\n listbox?.focus();\n }\n\n // ── Lifecycle ──\n\n ngOnInit(): void {\n // Host-level focus monitor (checkChildren: true): internal focus moves between\n // the two listboxes / buttons / search stay \"focused\"; origin === null fires\n // only when focus leaves the WHOLE control — the single source for onTouched.\n this.focusMonitor\n .monitor(this.elementRef, true)\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((origin) => {\n const wasFocused = this._focused();\n this._focused.set(!!origin);\n if (wasFocused && !origin) {\n this.onTouched();\n this.errorWiring.bump();\n }\n });\n this.destroyRef.onDestroy(() => this.focusMonitor.stopMonitoring(this.elementRef));\n\n // React to status/value changes on the bound control so errorState recomputes.\n this.errorWiring.connect();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { inject, TemplateRef, Directive, input, model, output, contentChild, viewChild, signal, computed, effect, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { inject, TemplateRef, Directive, input, model, output, contentChild, viewChild, signal, computed, effect, untracked, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
4
4
  import * as i1 from '@angular/cdk/tree';
5
5
  import { CdkTreeModule } from '@angular/cdk/tree';
6
6
  import { tv } from 'tailwind-variants';
@@ -30,8 +30,11 @@ import { tv } from 'tailwind-variants';
30
30
  * bridging an RxJS `changed` stream. NOT a form control (no CVA).
31
31
  * - Expansion is bidirectionally synced with the `expandedKeys` model:
32
32
  * model→CDK via a guarded `effect()` (CDK's `select`/`deselect` are
33
- * idempotent → settles in one tick); CDK→model via each node's
34
- * `(expandedChange)` output with compare-before-write (no signal cycle).
33
+ * idempotent → settles in one tick), plus a one-shot `afterNextRender()`
34
+ * replay because CDK's expansion model does not exist yet on the effect's
35
+ * first run and `CdkTree.expand()` no-ops silently until it does; CDK→model
36
+ * via each node's `(expandedChange)` output with compare-before-write (no
37
+ * signal cycle).
35
38
  */
36
39
  // ── Resolved-default constants ───────────────────────────────────────
37
40
  const SELECTION_DEFAULTS = {
@@ -61,12 +64,31 @@ const treeVariants = tv({
61
64
  content: 'flex items-center gap-1.5 min-w-0 flex-1',
62
65
  },
63
66
  variants: {
67
+ // Tree nodes are on the `min-h-*` list (docs/vertical-rhythm.md §2), not
68
+ // the pinned one: a consumer's node template may wrap onto a second line,
69
+ // so the row must stay free to grow. The floor lands on the control scale
70
+ // (24 / 32 / 36 / 44 / 48) exactly as `menu`'s rows do, and `py-*` is kept
71
+ // as it was — it sets the breathing room around a wrapped row, where the
72
+ // floor no longer binds.
73
+ //
74
+ // The row is also the pointer target: it carries `(activation)` and the
75
+ // `treeitem` role, and it was the *only* member of that cohort shipping no
76
+ // floor at all, so at `xs` it measured one `text-sm` line box — 20px,
77
+ // under the WCAG 2.2 SC 2.5.8 24px minimum. The floor fixes the rhythm
78
+ // gap and the target-size defect with one value.
79
+ //
80
+ // Resting heights the floor binds against (text-sm line box = 20px):
81
+ // xs → py-0 (0) + 20 = 20 → 24 (`min-h-6`)
82
+ // sm → py-0.5 (4) + 20 = 24 → 32 (`min-h-8`)
83
+ // md → py-1 (8) + 20 = 28 → 36 (`min-h-9`)
84
+ // lg → py-1.5 (12) + 20 = 32 → 44 (`min-h-11`)
85
+ // xl → py-2 (16) + 20 = 36 → 48 (`min-h-12`)
64
86
  size: {
65
- xs: { content: 'py-0' },
66
- sm: { content: 'py-0.5' },
67
- md: { content: 'py-1' },
68
- lg: { content: 'py-1.5' },
69
- xl: { content: 'py-2' },
87
+ xs: { node: 'min-h-6', content: 'py-0' },
88
+ sm: { node: 'min-h-8', content: 'py-0.5' },
89
+ md: { node: 'min-h-9', content: 'py-1' },
90
+ lg: { node: 'min-h-11', content: 'py-1.5' },
91
+ xl: { node: 'min-h-12', content: 'py-2' },
70
92
  },
71
93
  selected: {
72
94
  true: { node: 'bg-primary-50 text-primary-700 hover:bg-primary-50' },
@@ -209,17 +231,44 @@ class TreeComponent {
209
231
  const all = this.flattenAll();
210
232
  if (!tree)
211
233
  return;
212
- untracked(() => {
213
- for (const node of all) {
214
- const key = this.keyOf(node);
215
- const isOpen = tree.isExpanded(node);
216
- if (wanted.has(key) && !isOpen)
217
- tree.expand(node);
218
- else if (!wanted.has(key) && isOpen)
219
- tree.collapse(node);
220
- }
221
- });
234
+ untracked(() => this.applyExpansion(tree, wanted, all));
222
235
  });
236
+ // The effect above runs for the first time BEFORE `cdk-tree`'s `dataSource`
237
+ // binding is applied — and CDK creates its expansion model lazily, at that
238
+ // binding. Until the model exists, `CdkTree.expand()` falls through both of
239
+ // its branches (`if (this.treeControl) … else if (this._expansionModel) …`)
240
+ // and does nothing, with no error. So an `expandedKeys` value that was
241
+ // already populated at mount was dropped on the floor, and the effect never
242
+ // re-ran to correct it because none of its inputs had changed: the tree
243
+ // rendered fully collapsed for the rest of its life. Re-apply once the first
244
+ // render has happened, by which point the model exists.
245
+ //
246
+ // `applyExpansion` is idempotent (it compares against `tree.isExpanded`), so
247
+ // this is a no-op in every case where the effect already succeeded, and
248
+ // `onCdkExpandedChange` compares before writing, so no spurious
249
+ // `expandedChange` is emitted.
250
+ // No `if (!tree)` guard here, deliberately: `cdkTree` is a `viewChild.required`,
251
+ // which throws rather than returning undefined, and this hook only runs after a
252
+ // render — so the query is always resolved. Angular disposes render hooks with
253
+ // the component's injector, so a tree destroyed before its first render never
254
+ // reaches this at all (both cases are asserted in `tree.spec.ts`).
255
+ afterNextRender(() => {
256
+ this.applyExpansion(this.cdkTree(), new Set(this.expandedKeys()), this.flattenAll());
257
+ });
258
+ }
259
+ /**
260
+ * @internal Drives CDK's expansion model to match `wanted`. Idempotent — every
261
+ * node is compared against `tree.isExpanded` before being touched.
262
+ */
263
+ applyExpansion(tree, wanted, all) {
264
+ for (const node of all) {
265
+ const key = this.keyOf(node);
266
+ const isOpen = tree.isExpanded(node);
267
+ if (wanted.has(key) && !isOpen)
268
+ tree.expand(node);
269
+ else if (!wanted.has(key) && isOpen)
270
+ tree.collapse(node);
271
+ }
223
272
  }
224
273
  // ── Key + traversal helpers ──
225
274
  /** @internal Resolves a node's identity key via `trackBy`, falling back to the node itself. */
@@ -526,7 +575,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
526
575
  /** Attribute directive (`[twTreeNodeToggle]="node"`) that toggles the given node's expansion on click. */
527
576
  class TreeNodeToggleDirective {
528
577
  tree = inject((TreeComponent));
529
- /** The node whose expansion this control toggles. */
578
+ /** The node whose expansion this control toggles. Alias: `twTreeNodeToggle`. */
530
579
  node = input.required({ ...(ngDevMode ? { debugName: "node" } : /* istanbul ignore next */ {}), alias: 'twTreeNodeToggle' });
531
580
  /** @internal Toggles the node and stops the click from bubbling to row activation. */
532
581
  onClick(event) {