@cdevhub/ngx-tw 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/README.md +78 -15
  2. package/fesm2022/cdevhub-ngx-tw-accordion.mjs +16 -5
  3. package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
  4. package/fesm2022/cdevhub-ngx-tw-avatar.mjs +26 -15
  5. package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
  6. package/fesm2022/cdevhub-ngx-tw-badge.mjs +17 -5
  7. package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
  8. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +27 -6
  9. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
  10. package/fesm2022/cdevhub-ngx-tw-button.mjs +23 -11
  11. package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
  12. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +5 -5
  13. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
  14. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs +3 -3
  15. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs.map +1 -1
  16. package/fesm2022/cdevhub-ngx-tw-calendar.mjs +427 -122
  17. package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
  18. package/fesm2022/cdevhub-ngx-tw-card.mjs +21 -11
  19. package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
  20. package/fesm2022/cdevhub-ngx-tw-carousel.mjs +215 -96
  21. package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
  22. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +108 -64
  23. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
  24. package/fesm2022/cdevhub-ngx-tw-code-block.mjs +18 -6
  25. package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
  26. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +55 -30
  27. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
  28. package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs +218 -0
  29. package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs.map +1 -0
  30. package/fesm2022/cdevhub-ngx-tw-combobox.mjs +236 -211
  31. package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
  32. package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs +200 -0
  33. package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs.map +1 -0
  34. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +34 -7
  35. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
  36. package/fesm2022/cdevhub-ngx-tw-core.mjs +135 -15
  37. package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
  38. package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs +203 -0
  39. package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs.map +1 -0
  40. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +160 -102
  41. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
  42. package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs +209 -0
  43. package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs.map +1 -0
  44. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +182 -107
  45. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
  46. package/fesm2022/cdevhub-ngx-tw-dialog-dialog-renderer-DoIhoV3d.mjs +198 -0
  47. package/fesm2022/cdevhub-ngx-tw-dialog-dialog-renderer-DoIhoV3d.mjs.map +1 -0
  48. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs +122 -0
  49. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs.map +1 -0
  50. package/fesm2022/cdevhub-ngx-tw-dialog.mjs +199 -220
  51. package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
  52. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +1 -1
  53. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
  54. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs +149 -0
  55. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs.map +1 -0
  56. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +57 -67
  57. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -1
  58. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +42 -24
  59. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
  60. package/fesm2022/cdevhub-ngx-tw-form-field.mjs +114 -21
  61. package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
  62. package/fesm2022/cdevhub-ngx-tw-icon.mjs +16 -6
  63. package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
  64. package/fesm2022/cdevhub-ngx-tw-input.mjs +52 -61
  65. package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
  66. package/fesm2022/cdevhub-ngx-tw-item.mjs +18 -3
  67. package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
  68. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs +168 -0
  69. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs.map +1 -0
  70. package/fesm2022/cdevhub-ngx-tw-menu.mjs +58 -21
  71. package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
  72. package/fesm2022/cdevhub-ngx-tw-number-input.mjs +34 -1
  73. package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -1
  74. package/fesm2022/cdevhub-ngx-tw-paginator.mjs +95 -45
  75. package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
  76. package/fesm2022/cdevhub-ngx-tw-popover.mjs +81 -32
  77. package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
  78. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +1 -1
  79. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
  80. package/fesm2022/cdevhub-ngx-tw-radio.mjs +131 -98
  81. package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
  82. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +207 -42
  83. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
  84. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs +165 -0
  85. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs.map +1 -0
  86. package/fesm2022/cdevhub-ngx-tw-select.mjs +386 -210
  87. package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
  88. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs +256 -0
  89. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs.map +1 -0
  90. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs +129 -0
  91. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs.map +1 -0
  92. package/fesm2022/cdevhub-ngx-tw-sheet.mjs +197 -278
  93. package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
  94. package/fesm2022/cdevhub-ngx-tw-slider.mjs +89 -54
  95. package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
  96. package/fesm2022/cdevhub-ngx-tw-sort.mjs +122 -17
  97. package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
  98. package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -19
  99. package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
  100. package/fesm2022/cdevhub-ngx-tw-stat.mjs +63 -25
  101. package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
  102. package/fesm2022/cdevhub-ngx-tw-stepper.mjs +35 -8
  103. package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
  104. package/fesm2022/cdevhub-ngx-tw-switch.mjs +54 -48
  105. package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
  106. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +12 -15
  107. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
  108. package/fesm2022/cdevhub-ngx-tw-table.mjs +74 -13
  109. package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
  110. package/fesm2022/cdevhub-ngx-tw-tabs.mjs +84 -30
  111. package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
  112. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs +172 -0
  113. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs.map +1 -0
  114. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +107 -71
  115. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -1
  116. package/fesm2022/cdevhub-ngx-tw-textarea.mjs +41 -9
  117. package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
  118. package/fesm2022/cdevhub-ngx-tw-theme.mjs +257 -45
  119. package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
  120. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs +201 -0
  121. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs.map +1 -0
  122. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +184 -77
  123. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
  124. package/fesm2022/cdevhub-ngx-tw-timeline.mjs +110 -27
  125. package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
  126. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs +616 -0
  127. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs.map +1 -0
  128. package/fesm2022/cdevhub-ngx-tw-toast.mjs +556 -945
  129. package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
  130. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +102 -15
  131. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
  132. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs +219 -0
  133. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs.map +1 -0
  134. package/fesm2022/cdevhub-ngx-tw-transfer.mjs +88 -69
  135. package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -1
  136. package/fesm2022/cdevhub-ngx-tw-tree.mjs +68 -19
  137. package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -1
  138. package/index.json +1 -1
  139. package/package.json +63 -2
  140. package/theme/_base.css +13 -0
  141. package/theme/_dark.css +110 -36
  142. package/theme/_high-contrast-dark.css +367 -0
  143. package/theme/_high-contrast.css +13 -2
  144. package/theme/_light.css +276 -0
  145. package/theme/_semantic.css +47 -12
  146. package/theme/_typography.css +17 -0
  147. package/theme/index.css +86 -7
  148. package/types/cdevhub-ngx-tw-accordion.d.ts +12 -4
  149. package/types/cdevhub-ngx-tw-avatar.d.ts +10 -3
  150. package/types/cdevhub-ngx-tw-button.d.ts +1 -0
  151. package/types/cdevhub-ngx-tw-calendar-luxon.d.ts +2 -2
  152. package/types/cdevhub-ngx-tw-calendar-testing.d.ts +1 -1
  153. package/types/cdevhub-ngx-tw-calendar.d.ts +179 -73
  154. package/types/cdevhub-ngx-tw-card.d.ts +11 -3
  155. package/types/cdevhub-ngx-tw-carousel.d.ts +89 -20
  156. package/types/cdevhub-ngx-tw-checkbox.d.ts +40 -12
  157. package/types/cdevhub-ngx-tw-code-block.d.ts +11 -2
  158. package/types/cdevhub-ngx-tw-collapsible.d.ts +32 -5
  159. package/types/cdevhub-ngx-tw-combobox-testing.d.ts +157 -0
  160. package/types/cdevhub-ngx-tw-combobox.d.ts +94 -53
  161. package/types/cdevhub-ngx-tw-command-palette-testing.d.ts +136 -0
  162. package/types/cdevhub-ngx-tw-command-palette.d.ts +33 -5
  163. package/types/cdevhub-ngx-tw-core.d.ts +152 -21
  164. package/types/cdevhub-ngx-tw-date-picker-testing.d.ts +141 -0
  165. package/types/cdevhub-ngx-tw-date-picker.d.ts +37 -29
  166. package/types/cdevhub-ngx-tw-date-range-picker-testing.d.ts +148 -0
  167. package/types/cdevhub-ngx-tw-date-range-picker.d.ts +36 -29
  168. package/types/cdevhub-ngx-tw-dialog-testing.d.ts +98 -0
  169. package/types/cdevhub-ngx-tw-dialog.d.ts +89 -19
  170. package/types/cdevhub-ngx-tw-file-upload-testing.d.ts +120 -0
  171. package/types/cdevhub-ngx-tw-file-upload.d.ts +8 -10
  172. package/types/cdevhub-ngx-tw-flip-card.d.ts +18 -11
  173. package/types/cdevhub-ngx-tw-form-field.d.ts +19 -2
  174. package/types/cdevhub-ngx-tw-icon.d.ts +3 -3
  175. package/types/cdevhub-ngx-tw-input.d.ts +5 -8
  176. package/types/cdevhub-ngx-tw-item.d.ts +2 -0
  177. package/types/cdevhub-ngx-tw-menu-testing.d.ts +131 -0
  178. package/types/cdevhub-ngx-tw-menu.d.ts +2 -2
  179. package/types/cdevhub-ngx-tw-number-input.d.ts +20 -0
  180. package/types/cdevhub-ngx-tw-paginator.d.ts +58 -24
  181. package/types/cdevhub-ngx-tw-popover.d.ts +41 -10
  182. package/types/cdevhub-ngx-tw-progress-bar.d.ts +1 -1
  183. package/types/cdevhub-ngx-tw-radio.d.ts +68 -25
  184. package/types/cdevhub-ngx-tw-segmented-control.d.ts +79 -16
  185. package/types/cdevhub-ngx-tw-select-testing.d.ts +114 -0
  186. package/types/cdevhub-ngx-tw-select.d.ts +104 -33
  187. package/types/cdevhub-ngx-tw-sheet-testing.d.ts +104 -0
  188. package/types/cdevhub-ngx-tw-sheet.d.ts +96 -21
  189. package/types/cdevhub-ngx-tw-slider.d.ts +79 -25
  190. package/types/cdevhub-ngx-tw-sort.d.ts +45 -4
  191. package/types/cdevhub-ngx-tw-split.d.ts +32 -2
  192. package/types/cdevhub-ngx-tw-stat.d.ts +14 -4
  193. package/types/cdevhub-ngx-tw-stepper.d.ts +16 -2
  194. package/types/cdevhub-ngx-tw-switch.d.ts +35 -13
  195. package/types/cdevhub-ngx-tw-tab-nav.d.ts +7 -6
  196. package/types/cdevhub-ngx-tw-table.d.ts +53 -10
  197. package/types/cdevhub-ngx-tw-tabs.d.ts +41 -10
  198. package/types/cdevhub-ngx-tw-tags-input-testing.d.ts +135 -0
  199. package/types/cdevhub-ngx-tw-tags-input.d.ts +26 -11
  200. package/types/cdevhub-ngx-tw-textarea.d.ts +3 -2
  201. package/types/cdevhub-ngx-tw-theme.d.ts +245 -39
  202. package/types/cdevhub-ngx-tw-time-picker-testing.d.ts +129 -0
  203. package/types/cdevhub-ngx-tw-time-picker.d.ts +76 -19
  204. package/types/cdevhub-ngx-tw-timeline.d.ts +36 -12
  205. package/types/cdevhub-ngx-tw-toast.d.ts +61 -12
  206. package/types/cdevhub-ngx-tw-tooltip.d.ts +28 -6
  207. package/types/cdevhub-ngx-tw-transfer-testing.d.ts +152 -0
  208. package/types/cdevhub-ngx-tw-transfer.d.ts +21 -8
  209. package/types/cdevhub-ngx-tw-tree.d.ts +6 -1
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-file-upload.mjs","sources":["../../../projects/ngx-tw/file-upload/file-upload.ts","../../../projects/ngx-tw/file-upload/file-upload.html","../../../projects/ngx-tw/file-upload/cdevhub-ngx-tw-file-upload.ts"],"sourcesContent":["/**\n * `tw-file-upload` — selects one or more files via button / click / drag-and-drop.\n *\n * Surfaces the selected files as a `File[]` value through `ControlValueAccessor`\n * so the component works identically with template-driven `ngModel`, reactive\n * `[formControl]`, and signal-based `[formField]` strategies. Integrates with\n * `<tw-form-field>` for label / hint / error chrome.\n *\n * Built-in validation (`accept`, `maxSize`, `maxFiles`) rejects files at the\n * UI layer and surfaces them via the `fileRejected` output and `LiveAnnouncer`.\n * These rejections do NOT flow through `NgControl.errors`, so they cannot be\n * matched with `[twError match=\"size\"]`. Use Angular `Validator`s on the bound\n * `NgControl` for error-key-driven UI (cross-field or async validation).\n *\n * The component does NOT issue HTTP requests. Consumers own the upload pipeline\n * and push progress / status back into the component via `setItemProgress` and\n * `setItemStatus`.\n */\nimport {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n DestroyRef,\n Directive,\n ElementRef,\n forwardRef,\n inject,\n input,\n isDevMode,\n type OnInit,\n output,\n signal,\n type Signal,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n type ControlValueAccessor,\n FormGroupDirective,\n NgControl,\n NgForm,\n Validators,\n} from '@angular/forms';\nimport { FocusMonitor, LiveAnnouncer } from '@angular/cdk/a11y';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { isObservable, 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 { FormFieldControl, TW_FORM_FIELD_CONTROL } from '@cdevhub/ngx-tw/form-field';\nimport { ButtonDirective } from '@cdevhub/ngx-tw/button';\nimport { IconComponent } from '@cdevhub/ngx-tw/icon';\nimport { ProgressBarComponent } from '@cdevhub/ngx-tw/progress-bar';\n\n/** Lifecycle status of a single selected file. */\nexport type FileUploadStatus = 'pending' | 'uploading' | 'success' | 'error';\n\n/** Visual variant of the drop zone container. */\nexport type FileUploadVariant = 'outline' | 'soft';\n\n/** Reason a file was rejected during validation. */\nexport type FileUploadRejectionReason = 'accept' | 'size' | 'count';\n\n/** A single tracked entry in the file-upload's internal state. */\nexport interface FileUploadItem {\n /** Stable opaque id for this entry. Generated by the component on add. Use as the key when calling `setItemProgress` / `setItemStatus`. */\n readonly id: string;\n /** The underlying `File` object as provided by the browser (or by `writeValue`). */\n readonly file: File;\n /** Current upload progress, integer 0–100. `0` when no progress has been reported. */\n readonly progress: number;\n /** Current lifecycle status. Defaults to `'pending'`. */\n readonly status: FileUploadStatus;\n /** Optional error message attached when `status === 'error'`. Displayed in the file row and announced via `LiveAnnouncer`. */\n readonly error?: string;\n}\n\n/** Payload emitted on `fileRejected`. */\nexport interface FileUploadRejection {\n /** The browser-supplied `File` that was rejected. */\n readonly file: File;\n /** Why the file was rejected. */\n readonly reason: FileUploadRejectionReason;\n /** Human-readable message suitable for assistive-tech announcement and inline display. */\n readonly message: string;\n}\n\n// ── Structural slot directive ────────────────────────────────────\n\n/**\n * Structural directive that captures a template used to render each item row.\n * Apply with `*twFileUploadItem=\"let item\"` to override the default row layout.\n *\n * The template context exposes the current `FileUploadItem` as both `$implicit`\n * and `item`, so both `let-item` and `let-item=\"item\"` work.\n */\n@Directive({ selector: 'ng-template[twFileUploadItem]' })\nexport class FileUploadItemDirective {\n /** @internal Reference to the captured template — read by the host component. */\n readonly templateRef = inject<TemplateRef<{ $implicit: FileUploadItem; item: FileUploadItem }>>(\n TemplateRef,\n );\n}\n\n// ── tv() config ──────────────────────────────────────────────────\n\nconst fileUploadVariants = tv(\n {\n slots: {\n // `relative` scopes the hidden `<input type=\"file\" class=\"sr-only\">` —\n // its `position: absolute` + `margin: -1px` would otherwise resolve\n // against the nearest positioned ancestor (often `<body>`), extending\n // the document and producing runaway horizontal/vertical scroll.\n root: 'relative flex flex-col gap-3 w-full',\n // 2px dashed border on the outline variant is the dropzone's defining\n // affordance — codified deviation from CLAUDE.md's \"2px = active state\n // indicator only\" rule. The empty dropzone IS an awaiting-input affordance.\n dropzone:\n 'relative rounded-lg transition-[border-color,background-color,transform] duration-200 motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500 cursor-pointer',\n dropzoneInner: 'flex flex-col items-center justify-center text-center gap-3',\n illustration: 'text-fg-subtle shrink-0',\n headline: 'font-semibold text-fg empty:hidden',\n description: 'text-fg-muted empty:hidden',\n list: 'flex flex-col gap-1 m-0 p-0 list-none empty:hidden',\n item: 'flex items-start gap-3 px-3 py-2 rounded-md hover:bg-surface-muted transition-colors duration-200 motion-reduce:transition-none',\n itemIcon: 'shrink-0 text-fg-muted mt-0.5',\n itemBody: 'flex-1 min-w-0 flex flex-col gap-1',\n itemName: 'text-sm font-medium text-fg truncate',\n itemMeta: 'text-xs text-fg-muted',\n itemProgress: 'mt-1',\n itemActions: 'flex items-center gap-1 shrink-0',\n },\n variants: {\n variant: {\n outline: { dropzone: 'border-2 border-dashed border-border bg-transparent' },\n soft: { dropzone: 'border border-border bg-surface-muted' },\n },\n size: {\n xs: { dropzone: 'p-2', headline: 'text-xs', description: 'text-2xs' },\n sm: { dropzone: 'p-3', headline: 'text-sm', description: 'text-xs' },\n md: { dropzone: 'p-4', headline: 'text-sm', description: 'text-xs' },\n lg: { dropzone: 'p-6', headline: 'text-sm', description: 'text-xs' },\n xl: { dropzone: 'p-8', headline: 'text-sm', description: 'text-xs' },\n },\n state: {\n idle: {},\n // 1% scale-up — below Tailwind's smallest `scale-95` step but visually\n // correct for a subtle drag-over lift; the alternative is no lift.\n draggingValid: {\n dropzone:\n 'border-primary-500 bg-primary-50 dark:bg-primary-900/20 scale-[1.01]',\n },\n draggingInvalid: {\n dropzone: 'border-error-500 bg-error-50 dark:bg-error-900/20',\n },\n error: { dropzone: 'border-error-500' },\n },\n disabled: {\n true: { dropzone: 'opacity-50 pointer-events-none cursor-not-allowed' },\n false: {},\n },\n },\n defaultVariants: {\n variant: 'outline',\n size: 'md',\n state: 'idle',\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\n// ── Module-level counters & helpers ─────────────────────────────\n\nlet nextHostId = 0;\nlet nextItemSeq = 0;\n\nconst BYTE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\n\nfunction formatBytes(n: number): string {\n if (!Number.isFinite(n) || n < 0) return '0 B';\n if (n < 1024) return `${n} B`;\n let v = n;\n let i = 0;\n while (v >= 1024 && i < BYTE_UNITS.length - 1) {\n v /= 1024;\n i += 1;\n }\n return `${v < 10 ? v.toFixed(1) : Math.round(v)} ${BYTE_UNITS[i]}`;\n}\n\nfunction parseAcceptList(accept: string | undefined): string[] {\n if (!accept) return [];\n return accept\n .split(',')\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean);\n}\n\nfunction matchesAccept(file: File, patterns: readonly string[]): boolean {\n if (patterns.length === 0) return true;\n const type = file.type.toLowerCase();\n const name = file.name.toLowerCase();\n for (const pattern of patterns) {\n if (pattern.startsWith('.')) {\n if (name.endsWith(pattern)) return true;\n } else if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (type.startsWith(prefix)) return true;\n } else if (type === pattern) {\n return true;\n }\n }\n return false;\n}\n\nfunction iconNameFor(file: File): string {\n const type = file.type.toLowerCase();\n if (type.startsWith('image/')) return 'image';\n if (type === 'application/pdf') return 'file-text';\n if (type.startsWith('text/')) return 'file-text';\n return 'file';\n}\n\nfunction clampPercent(n: number): number {\n if (!Number.isFinite(n)) return 0;\n if (n < 0) return 0;\n if (n > 100) return 100;\n return Math.round(n);\n}\n\n// ── FileUploadComponent ─────────────────────────────────────────\n\n@Component({\n selector: 'tw-file-upload',\n exportAs: 'twFileUpload',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet, ButtonDirective, IconComponent, ProgressBarComponent],\n providers: [\n {\n provide: TW_FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => FileUploadComponent),\n },\n ],\n templateUrl: './file-upload.html',\n host: {\n 'role': 'group',\n '[id]': 'id()',\n '[class]': 'rootClasses()',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'effectiveAriaLabelledby() || null',\n '[attr.aria-describedby]': 'effectiveAriaDescribedby() || null',\n '[attr.aria-disabled]': 'disabled() || null',\n '[attr.aria-required]': 'required() || null',\n '[attr.aria-invalid]': 'errorState() || null',\n },\n})\nexport class FileUploadComponent\n extends FormFieldControl<File[]>\n implements ControlValueAccessor, OnInit\n{\n // ── Inputs ──\n\n /** When true, the user can select more than one file. Mirrors to the hidden `<input multiple>` attribute. Defaults to `false`. */\n readonly multiple = input<boolean, unknown>(false, { transform: booleanAttribute });\n\n /** Comma-separated list of accepted file types using the native `<input accept>` syntax (e.g., `'image/*,.pdf'`). Forwarded to the hidden input and used to reject dropped files that do not match. Defaults to `undefined` (accept any). */\n readonly accept = input<string | undefined>(undefined);\n\n /** Maximum size per file, in bytes. Files exceeding this are rejected with reason `'size'` and never reach `value`. Defaults to `undefined` (no limit). */\n readonly maxSize = input<number | undefined>(undefined);\n\n /** Maximum total file count. Drops that would push the count over this limit are rejected with reason `'count'`. Ignored when `multiple` is `false` (the limit is always 1). Defaults to `undefined` (no limit). */\n readonly maxFiles = input<number | undefined>(undefined);\n\n /** Visual style of the drop zone. `'outline'` renders a dashed-bordered transparent region; `'soft'` renders a filled muted background. Defaults to `'outline'`. */\n readonly variant = input<FileUploadVariant>('outline');\n\n /** Controls overall density: drop-zone padding, icon scale, headline typography. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, blocks file selection (button, click, drop, keyboard) and applies muted styling. Reactive forms also propagate `disabled` via `setDisabledState`. Defaults to `false`. */\n readonly disabledInput = input<boolean, unknown>(false, {\n alias: 'disabled',\n transform: booleanAttribute,\n });\n\n /** Marks the control as required. Mirrors to `aria-required`. Also inferred from `Validators.required` on a bound `NgControl`. Defaults to `false`. */\n readonly requiredInput = input<boolean, unknown>(false, {\n alias: 'required',\n transform: booleanAttribute,\n });\n\n /** Headline text rendered inside the drop zone (e.g., `'Drag files here'`). Projected `[twFileUploadHeadline]` content takes precedence over this input. */\n readonly label = input<string | undefined>(undefined);\n\n /** Secondary text rendered under the label (e.g., `'PDF up to 10MB'`). Projected `[twFileUploadDescription]` content takes precedence. */\n readonly description = input<string | undefined>(undefined);\n\n /** Label rendered inside the trigger button. Defaults to `'Choose files'`. Use `'Choose file'` when `multiple` is `false` (consumer responsibility). */\n readonly triggerLabel = input<string>('Choose files');\n\n /** Accessible name applied to the host when no visible label is projected. Mirrored to `aria-label`. */\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`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, {\n alias: 'aria-labelledby',\n });\n\n /** ID of an external element that describes the control. Form-field merges its hint/error ids alongside. */\n readonly ariaDescribedby = input<string | undefined>(undefined, {\n alias: 'aria-describedby',\n });\n\n /** Optional `name` attribute on the hidden `<input type=\"file\">` for native form submissions. */\n readonly name = input<string | undefined>(undefined);\n\n /** Id on the host element. Auto-generated as `tw-file-upload-N` when not provided. Used by the form-field's `<label for>` attribute. */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the component uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n // ── Outputs ──\n\n /** Fires once per add operation with the items that were accepted and appended. Does not fire for rejected files (see `fileRejected`). Does not fire on `writeValue`. */\n readonly filesAdded = output<FileUploadItem[]>();\n\n /** Fires when a file is removed via the remove button or programmatic `remove()`. Does not fire on `writeValue`. */\n readonly fileRemoved = output<FileUploadItem>();\n\n /** Fires for each file that failed validation during add. Payload includes a human-readable message suitable for assistive-tech announcement. */\n readonly fileRejected = output<FileUploadRejection>();\n\n /** Fires when all files are cleared at once via programmatic `clear()`. Does not fire on `writeValue`, even when the new value is empty. */\n readonly cleared = output<void>();\n\n // ── Injections ──\n\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly destroyRef = inject(DestroyRef);\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\n // ── Internal mutable state ──\n\n private readonly itemsSignal = signal<readonly FileUploadItem[]>([]);\n private readonly cvaDisabled = signal(false);\n private readonly isDraggingSignal = signal(false);\n private readonly dragHasInvalidFilesSignal = 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 dragCounter = 0;\n\n private onChange: (value: File[]) => void = () => {};\n private onTouched: () => void = () => {};\n\n // ── Template refs ──\n\n /** @internal Captured custom-item template (from `*twFileUploadItem`). When absent, the default row template renders. */\n readonly itemSlot = contentChild(FileUploadItemDirective);\n\n /** @internal Dropzone wrapper — used to scope the form-field container-click guard. */\n private readonly dropzoneRef = viewChild<ElementRef<HTMLElement>>('dropzone');\n\n /** @internal The visible trigger button — the keyboard-operable control that receives focus on container click and after the last item is removed. */\n private readonly triggerRef = viewChild<ElementRef<HTMLButtonElement>>('trigger');\n\n /** @internal Hidden native input — used as the OS picker trigger. */\n private readonly hiddenInputRef = viewChild<ElementRef<HTMLInputElement>>('hiddenInput');\n\n // ── Ids ──\n\n private readonly uid = nextHostId++;\n /** @internal Auto-generated host id used when `[id]` is not supplied. */\n readonly hostId = `tw-file-upload-${this.uid}`;\n /** @internal */\n readonly headlineId = `${this.hostId}-headline`;\n /** @internal */\n readonly descriptionId = `${this.hostId}-description`;\n /** @internal */\n readonly hiddenInputId = `${this.hostId}-input`;\n\n // ── Public readonly signals ──\n\n /** Current items with their progress and status. Snapshot of internal state. */\n readonly items: Signal<readonly FileUploadItem[]> = this.itemsSignal.asReadonly();\n\n /** True while a valid file drag is over the drop zone. */\n readonly isDragging: Signal<boolean> = this.isDraggingSignal.asReadonly();\n\n /** Convenience alias for `items().length`. Useful for counter hints. */\n readonly valueLength: Signal<number> = computed(() => this.itemsSignal().length);\n\n // ── FormFieldControl signals ──\n\n /** @internal */\n readonly id: Signal<string> = computed(() => this.idInput() ?? this.hostId);\n\n /** @internal */\n readonly value: Signal<File[] | null> = computed(() => {\n const list = this.itemsSignal();\n return list.length ? list.map((i) => i.file) : null;\n });\n\n /** @internal */\n readonly focused: Signal<boolean> = this._focused.asReadonly();\n\n /** @internal */\n readonly empty: Signal<boolean> = computed(() => this.itemsSignal().length === 0);\n\n /** @internal */\n readonly disabled: Signal<boolean> = computed(() => {\n this._ngControlRev();\n return this.disabledInput() || this.cvaDisabled() || !!this.ngControl?.disabled;\n });\n\n /** @internal */\n readonly required: Signal<boolean> = computed(() => {\n this._ngControlRev();\n if (this.requiredInput()) return true;\n const ctrl = this.ngControl?.control;\n return !!ctrl?.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 Validation errors map from the bound `NgControl`. */\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 = 'file-upload';\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 // ── Effective ARIA ──\n //\n // When wrapped by `<tw-form-field>`, the form-field calls `setDescribedByIds`\n // / `setLabelledByIds` with the FULLY MERGED id list (hint/error/label + the\n // consumer's `aria-*by` ids). In that case the pushed ids alone are the\n // source of truth. When standalone, fall back to the consumer-supplied\n // `aria-*by` input and the internal description id.\n\n /** @internal */\n readonly effectiveAriaLabelledby = computed(() => {\n const pushed = this.labelledByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n return this.ariaLabelledby() || undefined;\n });\n\n /** @internal */\n readonly effectiveAriaDescribedby = computed(() => {\n const pushed = this.describedByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n const merged: string[] = [];\n const external = this.ariaDescribedby();\n if (external) {\n for (const id of external.split(/\\s+/).filter(Boolean)) merged.push(id);\n }\n if (this.description()) merged.push(this.descriptionId);\n return merged.length ? merged.join(' ') : undefined;\n });\n\n // ── Variant computeds ──\n\n private readonly stateVariant = computed<'idle' | 'draggingValid' | 'draggingInvalid' | 'error'>(\n () => {\n if (this.disabled()) return 'idle';\n if (this.isDraggingSignal()) {\n return this.dragHasInvalidFilesSignal() ? 'draggingInvalid' : 'draggingValid';\n }\n if (this.errorState()) return 'error';\n return 'idle';\n },\n );\n\n private readonly variantResult = computed(() =>\n fileUploadVariants({\n variant: this.variant(),\n size: this.size(),\n state: this.stateVariant(),\n disabled: this.disabled(),\n }),\n );\n\n /** @internal */\n readonly rootClasses = computed(() => this.variantResult().root());\n /** @internal */\n readonly dropzoneClasses = computed(() => this.variantResult().dropzone());\n /** @internal */\n readonly dropzoneInnerClasses = computed(() => this.variantResult().dropzoneInner());\n /** @internal */\n readonly illustrationClasses = computed(() => this.variantResult().illustration());\n /** @internal */\n readonly headlineClasses = computed(() => this.variantResult().headline());\n /** @internal */\n readonly descriptionClasses = computed(() => this.variantResult().description());\n /** @internal */\n readonly listClasses = computed(() => this.variantResult().list());\n /** @internal */\n readonly itemClasses = computed(() => this.variantResult().item());\n /** @internal */\n readonly itemIconClasses = computed(() => this.variantResult().itemIcon());\n /** @internal */\n readonly itemBodyClasses = computed(() => this.variantResult().itemBody());\n /** @internal */\n readonly itemNameClasses = computed(() => this.variantResult().itemName());\n /** @internal */\n readonly itemMetaClasses = computed(() => this.variantResult().itemMeta());\n /** @internal */\n readonly itemProgressClasses = computed(() => this.variantResult().itemProgress());\n /** @internal */\n readonly itemActionsClasses = computed(() => this.variantResult().itemActions());\n\n /** @internal Mapping component size → icon size for the illustration. */\n readonly iconSize = computed<TwSize>(() => {\n const s = this.size();\n if (s === 'xs') return 'sm';\n if (s === 'sm') return 'md';\n if (s === 'md') return 'lg';\n return 'xl';\n });\n\n // ── Construction ──\n\n constructor() {\n super();\n // Runtime CVA wiring — incompatible with a static NG_VALUE_ACCESSOR provider\n // because `inject(NgControl, { self: true })` for matcher integration would\n // create a circular DI on the same element.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-file-upload] The file-upload has no accessible name. Provide a `label`, project label content, or set `aria-label` / `aria-labelledby`.',\n );\n }\n });\n }\n\n // ── Public API ──\n\n /** Programmatically opens the OS file picker. No-op when disabled. */\n open(): void {\n if (this.disabled()) return;\n const input = this.hiddenInputRef()?.nativeElement;\n if (input) input.click();\n }\n\n /** Removes the item with the given id. Emits `fileRemoved`. No-op when the id is unknown or the component is disabled. */\n remove(id: string): void {\n if (this.disabled()) return;\n const current = this.itemsSignal();\n const idx = current.findIndex((i) => i.id === id);\n if (idx === -1) return;\n const removed = current[idx];\n const next = current.slice(0, idx).concat(current.slice(idx + 1));\n this.itemsSignal.set(next);\n this.emitChange();\n this.fileRemoved.emit(removed);\n this.liveAnnouncer.announce(`${removed.file.name} removed.`, 'polite');\n // Move focus to the next remove button, or to the trigger button when none remain.\n queueMicrotask(() => {\n const host = this.elementRef.nativeElement as HTMLElement;\n const nextButtons = host.querySelectorAll('[data-tw-file-upload-remove]');\n if (nextButtons.length === 0) {\n this.triggerRef()?.nativeElement.focus();\n } else {\n const fallback = nextButtons[Math.min(idx, nextButtons.length - 1)] as\n | HTMLButtonElement\n | undefined;\n fallback?.focus();\n }\n });\n }\n\n /** Removes all items. Emits `cleared` and calls `onChange([])`. No-op when already empty or disabled. */\n clear(): void {\n if (this.disabled()) return;\n if (this.itemsSignal().length === 0) return;\n this.itemsSignal.set([]);\n this.emitChange();\n this.cleared.emit();\n this.liveAnnouncer.announce('All files removed.', 'polite');\n }\n\n /** Updates the per-item progress (0–100, clamped). Does not change status. No-op when the id is unknown. */\n setItemProgress(id: string, percent: number): void {\n const clamped = clampPercent(percent);\n let found = false;\n const next = this.itemsSignal().map((item) => {\n if (item.id !== id) return item;\n found = true;\n if (item.progress === clamped) return item;\n return { ...item, progress: clamped };\n });\n if (found) this.itemsSignal.set(next);\n }\n\n /** Updates the per-item status and (optionally) the error message. Announces status transitions via `LiveAnnouncer`. No-op when the id is unknown. */\n setItemStatus(id: string, status: FileUploadStatus, error?: string): void {\n let target: FileUploadItem | undefined;\n let changed = false;\n const next = this.itemsSignal().map((item) => {\n if (item.id !== id) return item;\n target = item;\n const nextError = error !== undefined ? error : item.error;\n if (item.status === status && item.error === nextError) return item;\n changed = true;\n return { ...item, status, error: nextError };\n });\n if (!target) return;\n if (changed) this.itemsSignal.set(next);\n const name = target.file.name;\n if (status === 'success') {\n this.liveAnnouncer.announce(`${name} upload complete.`, 'polite');\n } else if (status === 'error') {\n this.liveAnnouncer.announce(\n error ? `${name} upload failed: ${error}.` : `${name} upload failed.`,\n 'polite',\n );\n } else if (status === 'uploading') {\n this.liveAnnouncer.announce(`${name} uploading.`, 'polite');\n }\n }\n\n // ── Drag-drop handlers ──\n\n /** @internal */\n onDragEnter(event: DragEvent): void {\n if (this.disabled()) return;\n if (!this.isFileDrag(event)) return;\n event.preventDefault();\n this.dragCounter += 1;\n if (this.dragCounter === 1) {\n this.dragHasInvalidFilesSignal.set(this.computeDragInvalid(event));\n this.isDraggingSignal.set(true);\n }\n }\n\n /** @internal */\n onDragOver(event: DragEvent): void {\n if (this.disabled()) return;\n if (!this.isFileDrag(event)) return;\n // Required to enable `drop` — browsers reject drops by default.\n event.preventDefault();\n }\n\n /** @internal */\n onDragLeave(event: DragEvent): void {\n if (this.disabled()) return;\n if (!this.isFileDrag(event)) return;\n if (this.dragCounter > 0) this.dragCounter -= 1;\n if (this.dragCounter === 0) {\n this.isDraggingSignal.set(false);\n this.dragHasInvalidFilesSignal.set(false);\n }\n }\n\n /** @internal */\n onDrop(event: DragEvent): void {\n if (this.disabled()) return;\n event.preventDefault();\n this.dragCounter = 0;\n this.isDraggingSignal.set(false);\n this.dragHasInvalidFilesSignal.set(false);\n const files = event.dataTransfer?.files;\n if (files && files.length) {\n this.addFiles(files);\n }\n }\n\n /** @internal */\n onTriggerClick(event: MouseEvent): void {\n event.stopPropagation();\n this.open();\n }\n\n /** @internal Called by the hidden `<input type=\"file\">` `change` event. */\n onNativeChange(event: Event): void {\n const target = event.target as HTMLInputElement;\n const files = target.files;\n if (files && files.length) this.addFiles(files);\n // Reset so re-selecting the same file re-fires `change`.\n target.value = '';\n }\n\n // ── Add files (validation + commit) ──\n\n private addFiles(files: FileList | readonly File[]): void {\n if (this.disabled()) return;\n const incoming: File[] = Array.from(files);\n if (incoming.length === 0) return;\n\n // Single-file mode: replace existing entry with the latest file dropped/selected.\n if (!this.multiple()) {\n const file = incoming[0];\n if (!file) return;\n const patterns = parseAcceptList(this.accept());\n if (!matchesAccept(file, patterns)) {\n this.reject(file, 'accept');\n return;\n }\n const maxSize = this.maxSize();\n if (maxSize !== undefined && file.size > maxSize) {\n this.reject(file, 'size');\n return;\n }\n const newItem = this.wrapFile(file);\n this.itemsSignal.set([newItem]);\n this.emitChange();\n this.filesAdded.emit([newItem]);\n this.liveAnnouncer.announce('1 file added.', 'polite');\n return;\n }\n\n const patterns = parseAcceptList(this.accept());\n const maxSize = this.maxSize();\n const maxFiles = this.maxFiles();\n const accepted: FileUploadItem[] = [];\n const currentCount = this.itemsSignal().length;\n\n for (const file of incoming) {\n if (!matchesAccept(file, patterns)) {\n this.reject(file, 'accept');\n continue;\n }\n if (maxSize !== undefined && file.size > maxSize) {\n this.reject(file, 'size');\n continue;\n }\n if (maxFiles !== undefined && currentCount + accepted.length >= maxFiles) {\n this.reject(file, 'count');\n continue;\n }\n accepted.push(this.wrapFile(file));\n }\n\n if (accepted.length === 0) return;\n\n this.itemsSignal.set([...this.itemsSignal(), ...accepted]);\n this.emitChange();\n this.filesAdded.emit(accepted);\n this.liveAnnouncer.announce(\n `${accepted.length} file${accepted.length === 1 ? '' : 's'} added.`,\n 'polite',\n );\n }\n\n private wrapFile(file: File): FileUploadItem {\n return {\n id: `tw-file-upload-item-${nextItemSeq++}`,\n file,\n progress: 0,\n status: 'pending',\n };\n }\n\n private reject(file: File, reason: FileUploadRejectionReason): void {\n const message = this.rejectionMessage(file, reason);\n // Sequence per-file announcements so a batch of rejections is announced cleanly.\n setTimeout(() => this.liveAnnouncer.announce(message, 'polite'));\n this.fileRejected.emit({ file, reason, message });\n }\n\n private rejectionMessage(file: File, reason: FileUploadRejectionReason): string {\n if (reason === 'accept') return `${file.name} was rejected: file type not allowed.`;\n if (reason === 'size') {\n const max = this.maxSize();\n const limit = max !== undefined ? formatBytes(max) : 'allowed size';\n return `${file.name} was rejected: exceeds ${limit}.`;\n }\n return `${file.name} was rejected: maximum file count reached.`;\n }\n\n // ── Drag inspection ──\n\n private isFileDrag(event: DragEvent): boolean {\n const dt = event.dataTransfer;\n if (!dt) return false;\n // `types` includes 'Files' when files are being dragged from the OS.\n return Array.from(dt.types).includes('Files');\n }\n\n private computeDragInvalid(event: DragEvent): boolean {\n const patterns = parseAcceptList(this.accept());\n if (patterns.length === 0) return false;\n const items = event.dataTransfer?.items;\n if (!items || items.length === 0) return false;\n // During drag, filenames are not exposed — only MIME types via `items[i].type`.\n // Extension-only patterns (`.pdf`) can't be confirmed mid-drag, so we treat\n // the drag as potentially valid if ANY item could match by MIME or if the\n // accept list contains any extension-only pattern.\n const hasExtensionPattern = patterns.some((p) => p.startsWith('.'));\n if (hasExtensionPattern) return false;\n for (const item of Array.from(items)) {\n if (item.kind !== 'file') continue;\n const type = item.type.toLowerCase();\n for (const pattern of patterns) {\n if (pattern.endsWith('/*')) {\n if (type.startsWith(pattern.slice(0, -1))) return false;\n } else if (type === pattern) {\n return false;\n }\n }\n }\n return true;\n }\n\n // ── ControlValueAccessor ──\n\n writeValue(value: File[] | File | null | undefined): void {\n if (value === null || value === undefined) {\n if (this.itemsSignal().length === 0) return;\n this.itemsSignal.set([]);\n return;\n }\n const list: File[] = Array.isArray(value) ? value : [value];\n if (list.length === 0) {\n if (this.itemsSignal().length === 0) return;\n this.itemsSignal.set([]);\n return;\n }\n const current = this.itemsSignal();\n if (\n current.length === list.length &&\n current.every((item, idx) => item.file === list[idx])\n ) {\n return;\n }\n this.itemsSignal.set(list.map((file) => this.wrapFile(file)));\n }\n\n registerOnChange(fn: (value: File[]) => 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 private emitChange(): void {\n const files = this.itemsSignal().map((i) => i.file);\n this.onChange(files);\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 */\n onContainerClick(event: MouseEvent): void {\n if (this.disabled()) return;\n if (event.defaultPrevented) return;\n const dropzone = this.dropzoneRef()?.nativeElement;\n if (!dropzone) return;\n const target = event.target as Node | null;\n if (target && dropzone.contains(target)) return;\n this.triggerRef()?.nativeElement.focus();\n }\n\n // ── Rendering helpers ──\n\n /** @internal */\n iconNameFor(item: FileUploadItem): string {\n return iconNameFor(item.file);\n }\n\n /** @internal */\n shouldShowProgress(item: FileUploadItem): boolean {\n if (item.status === 'pending' && item.progress === 0) return false;\n return true;\n }\n\n /** @internal */\n progressColorFor(item: FileUploadItem): 'primary' | 'success' | 'error' {\n if (item.status === 'error') return 'error';\n if (item.status === 'success' || item.progress >= 100) return 'success';\n return 'primary';\n }\n\n /** @internal */\n metaTextFor(item: FileUploadItem): string {\n const size = formatBytes(item.file.size);\n if (item.status === 'pending') return size;\n if (item.status === 'uploading') return `${size} · Uploading`;\n if (item.status === 'success') return `${size} · Done`;\n if (item.error) return `${size} · Failed — ${item.error}`;\n return `${size} · Failed`;\n }\n\n // ── Lifecycle ──\n\n ngOnInit(): void {\n const monitor$ = this.focusMonitor.monitor(this.elementRef, true);\n if (isObservable(monitor$)) {\n monitor$.pipe(takeUntilDestroyed(this.destroyRef)).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 }\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\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 // ── Helpers ──\n\n private hasAccessibleNameHint(): boolean {\n if (this.label() || this.ariaLabel() || this.ariaLabelledby()) return true;\n const host = this.elementRef.nativeElement;\n return !!host.textContent && host.textContent.trim().length > 0;\n }\n}\n","<input\n #hiddenInput\n type=\"file\"\n class=\"sr-only\"\n tabindex=\"-1\"\n [id]=\"hiddenInputId\"\n [attr.aria-label]=\"ariaLabel() ?? label() ?? triggerLabel()\"\n [attr.name]=\"name() || null\"\n [attr.accept]=\"accept() || null\"\n [multiple]=\"multiple()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n (change)=\"onNativeChange($event)\"\n/>\n\n<!-- The dropzone is a mouse click/drop convenience target, intentionally NOT a\n focusable control: the inner trigger <button> owns keyboard operability, so\n adding tabindex/keydown here would create a nested-interactive structure.\n No keyboard user is locked out, so the rules' concern does not apply. -->\n<!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n<div\n #dropzone\n [class]=\"dropzoneClasses()\"\n (click)=\"open()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div [class]=\"dropzoneInnerClasses()\">\n <div [class]=\"illustrationClasses()\">\n <ng-content select=\"[twFileUploadIcon]\">\n <tw-icon name=\"upload-cloud\" [size]=\"iconSize()\" aria-hidden=\"true\" />\n </ng-content>\n </div>\n\n <span [id]=\"headlineId\" [class]=\"headlineClasses()\">\n <ng-content select=\"[twFileUploadHeadline]\">\n @if (label(); as l) {\n {{ l }}\n } @else {\n Drag files here or click to browse\n }\n </ng-content>\n </span>\n\n <span [id]=\"descriptionId\" [class]=\"descriptionClasses()\">\n <ng-content select=\"[twFileUploadDescription]\">\n @if (description(); as d) {\n {{ d }}\n }\n </ng-content>\n </span>\n\n <button\n #trigger\n type=\"button\"\n twButton\n variant=\"outline\"\n color=\"neutral\"\n [size]=\"size()\"\n [disabled]=\"disabled()\"\n [attr.aria-describedby]=\"effectiveAriaDescribedby() || null\"\n (click)=\"onTriggerClick($event)\"\n >\n {{ triggerLabel() }}\n </button>\n </div>\n</div>\n\n<ul [class]=\"listClasses()\" role=\"list\">\n @for (item of items(); track item.id) {\n <li>\n @if (itemSlot(); as slot) {\n <ng-container\n [ngTemplateOutlet]=\"slot.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item, item: item }\"\n />\n } @else {\n <div [class]=\"itemClasses()\">\n <tw-icon\n [name]=\"iconNameFor(item)\"\n size=\"md\"\n [class]=\"itemIconClasses()\"\n aria-hidden=\"true\"\n />\n <div [class]=\"itemBodyClasses()\">\n <span [class]=\"itemNameClasses()\">{{ item.file.name }}</span>\n <span [class]=\"itemMetaClasses()\">{{ metaTextFor(item) }}</span>\n @if (shouldShowProgress(item)) {\n <tw-progress-bar\n [class]=\"itemProgressClasses()\"\n [value]=\"item.progress\"\n size=\"sm\"\n [color]=\"progressColorFor(item)\"\n />\n }\n </div>\n <div [class]=\"itemActionsClasses()\">\n <button\n type=\"button\"\n twButton\n variant=\"ghost\"\n color=\"neutral\"\n size=\"sm\"\n data-tw-file-upload-remove\n [attr.aria-label]=\"'Remove ' + item.file.name\"\n (click)=\"remove(item.id)\"\n >\n <tw-icon twButtonIcon name=\"x\" />\n </button>\n </div>\n </div>\n }\n </li>\n }\n</ul>\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-file-upload.mjs","sources":["../../../projects/ngx-tw/file-upload/file-upload.ts","../../../projects/ngx-tw/file-upload/file-upload.html","../../../projects/ngx-tw/file-upload/cdevhub-ngx-tw-file-upload.ts"],"sourcesContent":["/**\n * `tw-file-upload` — selects one or more files via button / click / drag-and-drop.\n *\n * Surfaces the selected files as a `File[]` value through `ControlValueAccessor`\n * so the component works identically with template-driven `ngModel`, reactive\n * `[formControl]`, and signal-based `[formField]` strategies. Integrates with\n * `<tw-form-field>` for label / hint / error chrome.\n *\n * Built-in validation (`accept`, `maxSize`, `maxFiles`) rejects files at the\n * UI layer and surfaces them via the `fileRejected` output and `LiveAnnouncer`.\n * These rejections do NOT flow through `NgControl.errors`, so they cannot be\n * matched with `[twError match=\"size\"]`. Use Angular `Validator`s on the bound\n * `NgControl` for error-key-driven UI (cross-field or async validation).\n *\n * The component does NOT issue HTTP requests. Consumers own the upload pipeline\n * and push progress / status back into the component via `setItemProgress` and\n * `setItemStatus`.\n */\nimport {\n afterNextRender,\n booleanAttribute,\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 type OnInit,\n output,\n signal,\n type Signal,\n TemplateRef,\n viewChild,\n} from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { type ControlValueAccessor, NgControl } from '@angular/forms';\nimport { FocusMonitor, LiveAnnouncer } from '@angular/cdk/a11y';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { isObservable } from 'rxjs';\nimport { tv } from 'tailwind-variants';\nimport {\n type ErrorStateMatcher,\n type TwSize,\n wireErrorState,\n} from '@cdevhub/ngx-tw/core';\nimport { FormFieldControl, TW_FORM_FIELD_CONTROL } from '@cdevhub/ngx-tw/form-field';\nimport { ButtonDirective } from '@cdevhub/ngx-tw/button';\nimport { IconComponent } from '@cdevhub/ngx-tw/icon';\nimport { ProgressBarComponent } from '@cdevhub/ngx-tw/progress-bar';\n\n/** Lifecycle status of a single selected file. */\nexport type FileUploadStatus = 'pending' | 'uploading' | 'success' | 'error';\n\n/** Visual variant of the drop zone container. */\nexport type FileUploadVariant = 'outline' | 'soft';\n\n/** Reason a file was rejected during validation. */\nexport type FileUploadRejectionReason = 'accept' | 'size' | 'count';\n\n/** A single tracked entry in the file-upload's internal state. */\nexport interface FileUploadItem {\n /** Stable opaque id for this entry. Generated by the component on add. Use as the key when calling `setItemProgress` / `setItemStatus`. */\n readonly id: string;\n /** The underlying `File` object as provided by the browser (or by `writeValue`). */\n readonly file: File;\n /** Current upload progress, integer 0–100. `0` when no progress has been reported. */\n readonly progress: number;\n /** Current lifecycle status. Defaults to `'pending'`. */\n readonly status: FileUploadStatus;\n /** Optional error message attached when `status === 'error'`. Displayed in the file row and announced via `LiveAnnouncer`. */\n readonly error?: string;\n}\n\n/** Payload emitted on `fileRejected`. */\nexport interface FileUploadRejection {\n /** The browser-supplied `File` that was rejected. */\n readonly file: File;\n /** Why the file was rejected. */\n readonly reason: FileUploadRejectionReason;\n /** Human-readable message suitable for assistive-tech announcement and inline display. */\n readonly message: string;\n}\n\n// ── Structural slot directive ────────────────────────────────────\n\n/**\n * Structural directive that captures a template used to render each item row.\n * Apply with `*twFileUploadItem=\"let item\"` to override the default row layout.\n *\n * The template context exposes the current `FileUploadItem` as both `$implicit`\n * and `item`, so both `let-item` and `let-item=\"item\"` work.\n */\n@Directive({ selector: 'ng-template[twFileUploadItem]' })\nexport class FileUploadItemDirective {\n /** @internal Reference to the captured template — read by the host component. */\n readonly templateRef = inject<TemplateRef<{ $implicit: FileUploadItem; item: FileUploadItem }>>(\n TemplateRef,\n );\n}\n\n// ── tv() config ──────────────────────────────────────────────────\n\nconst fileUploadVariants = tv(\n {\n slots: {\n // `relative` scopes the hidden `<input type=\"file\" class=\"sr-only\">` —\n // its `position: absolute` + `margin: -1px` would otherwise resolve\n // against the nearest positioned ancestor (often `<body>`), extending\n // the document and producing runaway horizontal/vertical scroll.\n root: 'relative flex flex-col gap-3 w-full',\n // 2px dashed border on the outline variant is the dropzone's defining\n // affordance — codified deviation from CLAUDE.md's \"2px = active state\n // indicator only\" rule. The empty dropzone IS an awaiting-input affordance.\n dropzone:\n 'relative rounded-lg transition-[border-color,background-color,transform] duration-200 motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500 cursor-pointer',\n dropzoneInner: 'flex flex-col items-center justify-center text-center gap-3',\n illustration: 'text-fg-subtle shrink-0',\n headline: 'font-semibold text-fg empty:hidden',\n description: 'text-fg-muted empty:hidden',\n list: 'flex flex-col gap-1 m-0 p-0 list-none empty:hidden',\n item: 'flex items-start gap-3 px-3 py-2 rounded-md hover:bg-surface-muted transition-colors duration-200 motion-reduce:transition-none',\n itemIcon: 'shrink-0 text-fg-muted mt-0.5',\n itemBody: 'flex-1 min-w-0 flex flex-col gap-1',\n itemName: 'text-sm font-medium text-fg truncate',\n itemMeta: 'text-xs text-fg-muted',\n itemProgress: 'mt-1',\n itemActions: 'flex items-center gap-1 shrink-0',\n },\n variants: {\n variant: {\n outline: { dropzone: 'border-2 border-dashed border-border bg-transparent' },\n soft: { dropzone: 'border border-border bg-surface-muted' },\n },\n size: {\n xs: { dropzone: 'p-2', headline: 'text-xs', description: 'text-2xs' },\n sm: { dropzone: 'p-3', headline: 'text-sm', description: 'text-xs' },\n md: { dropzone: 'p-4', headline: 'text-sm', description: 'text-xs' },\n lg: { dropzone: 'p-6', headline: 'text-sm', description: 'text-xs' },\n xl: { dropzone: 'p-8', headline: 'text-sm', description: 'text-xs' },\n },\n state: {\n idle: {},\n // 1% scale-up — below Tailwind's smallest `scale-95` step but visually\n // correct for a subtle drag-over lift; the alternative is no lift.\n // No `dark:` variant here, deliberately. The theme layer already\n // inverts the ramp: `_dark.css` maps `--color-primary-50` onto\n // `blue-950`, so `bg-primary-soft` IS the dark wash in dark mode. A\n // `dark:bg-primary-900/20` override on top resolved to `blue-100` —\n // near-white — and turned the drag-over affordance into a bright flash\n // over a `gray-950` dropzone. These were the only two `dark:` utilities\n // in the library, and both were wrong for this reason.\n draggingValid: {\n dropzone: 'border-primary-500 bg-primary-soft scale-[1.01]',\n },\n draggingInvalid: {\n dropzone: 'border-error-500 bg-error-soft',\n },\n error: { dropzone: 'border-error-500' },\n },\n disabled: {\n true: { dropzone: 'opacity-50 pointer-events-none cursor-not-allowed' },\n false: {},\n },\n },\n defaultVariants: {\n variant: 'outline',\n size: 'md',\n state: 'idle',\n disabled: false,\n },\n },\n { twMerge: true },\n);\n\n// ── Module-level counters & helpers ─────────────────────────────\n\nlet nextHostId = 0;\nlet nextItemSeq = 0;\n\nconst BYTE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB'] as const;\n\nfunction formatBytes(n: number): string {\n if (!Number.isFinite(n) || n < 0) return '0 B';\n if (n < 1024) return `${n} B`;\n let v = n;\n let i = 0;\n while (v >= 1024 && i < BYTE_UNITS.length - 1) {\n v /= 1024;\n i += 1;\n }\n return `${v < 10 ? v.toFixed(1) : Math.round(v)} ${BYTE_UNITS[i]}`;\n}\n\nfunction parseAcceptList(accept: string | undefined): string[] {\n if (!accept) return [];\n return accept\n .split(',')\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean);\n}\n\nfunction matchesAccept(file: File, patterns: readonly string[]): boolean {\n if (patterns.length === 0) return true;\n const type = file.type.toLowerCase();\n const name = file.name.toLowerCase();\n for (const pattern of patterns) {\n if (pattern.startsWith('.')) {\n if (name.endsWith(pattern)) return true;\n } else if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -1);\n if (type.startsWith(prefix)) return true;\n } else if (type === pattern) {\n return true;\n }\n }\n return false;\n}\n\nfunction iconNameFor(file: File): string {\n const type = file.type.toLowerCase();\n if (type.startsWith('image/')) return 'image';\n if (type === 'application/pdf') return 'file-text';\n if (type.startsWith('text/')) return 'file-text';\n return 'file';\n}\n\nfunction clampPercent(n: number): number {\n if (!Number.isFinite(n)) return 0;\n if (n < 0) return 0;\n if (n > 100) return 100;\n return Math.round(n);\n}\n\n// ── FileUploadComponent ─────────────────────────────────────────\n\n@Component({\n selector: 'tw-file-upload',\n exportAs: 'twFileUpload',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet, ButtonDirective, IconComponent, ProgressBarComponent],\n providers: [\n {\n provide: TW_FORM_FIELD_CONTROL,\n useExisting: forwardRef(() => FileUploadComponent),\n },\n ],\n templateUrl: './file-upload.html',\n host: {\n 'role': 'group',\n '[id]': 'id()',\n '[class]': 'rootClasses()',\n '[attr.aria-label]': 'ariaLabel() || null',\n '[attr.aria-labelledby]': 'effectiveAriaLabelledby() || null',\n '[attr.aria-describedby]': 'effectiveAriaDescribedby() || null',\n '[attr.aria-disabled]': 'disabled() || null',\n // NOTE: `aria-required` and `aria-invalid` are NOT set here. ARIA 1.2 does\n // not allow either on `role=\"group\"`, and axe flags it as a *critical*\n // `aria-allowed-attr` violation. Both belong on the control that carries\n // the value: the hidden `<input type=\"file\">` takes native `required` and\n // `aria-invalid` in `file-upload.html`.\n },\n})\nexport class FileUploadComponent\n extends FormFieldControl<File[]>\n implements ControlValueAccessor, OnInit\n{\n // ── Inputs ──\n\n /** When true, the user can select more than one file. Mirrors to the hidden `<input multiple>` attribute. Defaults to `false`. */\n readonly multiple = input<boolean, unknown>(false, { transform: booleanAttribute });\n\n /** Comma-separated list of accepted file types using the native `<input accept>` syntax (e.g., `'image/*,.pdf'`). Forwarded to the hidden input and used to reject dropped files that do not match. Defaults to `undefined` (accept any). */\n readonly accept = input<string | undefined>(undefined);\n\n /** Maximum size per file, in bytes. Files exceeding this are rejected with reason `'size'` and never reach `value`. Defaults to `undefined` (no limit). */\n readonly maxSize = input<number | undefined>(undefined);\n\n /** Maximum total file count. Drops that would push the count over this limit are rejected with reason `'count'`. Ignored when `multiple` is `false` (the limit is always 1). Defaults to `undefined` (no limit). */\n readonly maxFiles = input<number | undefined>(undefined);\n\n /** Visual style of the drop zone. `'outline'` renders a dashed-bordered transparent region; `'soft'` renders a filled muted background. Defaults to `'outline'`. */\n readonly variant = input<FileUploadVariant>('outline');\n\n /** Controls overall density: drop-zone padding, icon scale, headline typography. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, blocks file selection (button, click, drop, keyboard) and applies muted styling. Reactive forms also propagate `disabled` via `setDisabledState`. Defaults to `false`. */\n readonly disabledInput = input<boolean, unknown>(false, {\n alias: 'disabled',\n transform: booleanAttribute,\n });\n\n /** Marks the control as required. Mirrors to `aria-required`. Also inferred from `Validators.required` on a bound `NgControl`. Defaults to `false`. */\n readonly requiredInput = input<boolean, unknown>(false, {\n alias: 'required',\n transform: booleanAttribute,\n });\n\n /** Headline text rendered inside the drop zone (e.g., `'Drag files here'`). Projected `[twFileUploadHeadline]` content takes precedence over this input. Defaults to `undefined`. */\n readonly label = input<string | undefined>(undefined);\n\n /** Secondary text rendered under the label (e.g., `'PDF up to 10MB'`). Projected `[twFileUploadDescription]` content takes precedence. Defaults to `undefined`. */\n readonly description = input<string | undefined>(undefined);\n\n /** Label rendered inside the trigger button. Defaults to `'Choose files'`. Use `'Choose file'` when `multiple` is `false` (consumer responsibility). */\n readonly triggerLabel = input<string>('Choose files');\n\n /** Accessible name applied to the host when no visible label is projected. 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, {\n alias: 'aria-labelledby',\n });\n\n /** ID of an external element that describes the control. Form-field merges its hint/error ids alongside. Defaults to `undefined`. Alias: `aria-describedby`. */\n readonly ariaDescribedby = input<string | undefined>(undefined, {\n alias: 'aria-describedby',\n });\n\n /** Optional `name` attribute on the hidden `<input type=\"file\">` for native form submissions. */\n readonly name = input<string | undefined>(undefined);\n\n /** Id on the host element. Auto-generated as `tw-file-upload-N` when not provided. Used by the form-field's `<label for>` attribute. */\n readonly idInput = input<string | undefined>(undefined, { alias: 'id' });\n\n /** Per-instance override of the {@link ErrorStateMatcher}. When omitted, the component uses the `TW_ERROR_STATE_MATCHER` token's value. */\n readonly errorStateMatcher = input<ErrorStateMatcher | undefined>(undefined);\n\n // ── Outputs ──\n\n /** Fires once per add operation with the items that were accepted and appended. Does not fire for rejected files (see `fileRejected`). Does not fire on `writeValue`. */\n readonly filesAdded = output<FileUploadItem[]>();\n\n /** Fires when a file is removed via the remove button or programmatic `remove()`. Does not fire on `writeValue`. */\n readonly fileRemoved = output<FileUploadItem>();\n\n /** Fires for each file that failed validation during add. Payload includes a human-readable message suitable for assistive-tech announcement. */\n readonly fileRejected = output<FileUploadRejection>();\n\n /** Fires when all files are cleared at once via programmatic `clear()`. Does not fire on `writeValue`, even when the new value is empty. */\n readonly cleared = output<void>();\n\n // ── Injections ──\n\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n private readonly injector = inject(Injector);\n private readonly focusMonitor = inject(FocusMonitor);\n private readonly liveAnnouncer = inject(LiveAnnouncer);\n private readonly destroyRef = inject(DestroyRef);\n private readonly ngControl = inject(NgControl, { optional: true, self: true });\n\n // ── Internal mutable state ──\n\n private readonly itemsSignal = signal<readonly FileUploadItem[]>([]);\n private readonly cvaDisabled = signal(false);\n private readonly isDraggingSignal = signal(false);\n private readonly dragHasInvalidFilesSignal = 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 dragCounter = 0;\n\n private onChange: (value: File[]) => void = () => {};\n private onTouched: () => void = () => {};\n\n // ── Template refs ──\n\n /** @internal Captured custom-item template (from `*twFileUploadItem`). When absent, the default row template renders. */\n readonly itemSlot = contentChild(FileUploadItemDirective);\n\n /** @internal Dropzone wrapper — used to scope the form-field container-click guard. */\n private readonly dropzoneRef = viewChild<ElementRef<HTMLElement>>('dropzone');\n\n /** @internal The visible trigger button — the keyboard-operable control that receives focus on container click and after the last item is removed. */\n private readonly triggerRef = viewChild<ElementRef<HTMLButtonElement>>('trigger');\n\n /** @internal Hidden native input — used as the OS picker trigger. */\n private readonly hiddenInputRef = viewChild<ElementRef<HTMLInputElement>>('hiddenInput');\n\n // ── Ids ──\n\n private readonly uid = nextHostId++;\n /** @internal Auto-generated host id used when `[id]` is not supplied. */\n readonly hostId = `tw-file-upload-${this.uid}`;\n /** @internal */\n readonly headlineId = `${this.hostId}-headline`;\n /** @internal */\n readonly descriptionId = `${this.hostId}-description`;\n /** @internal */\n readonly hiddenInputId = `${this.hostId}-input`;\n\n // ── Public readonly signals ──\n\n /** Current items with their progress and status. Snapshot of internal state. */\n readonly items: Signal<readonly FileUploadItem[]> = this.itemsSignal.asReadonly();\n\n /** True while a valid file drag is over the drop zone. */\n readonly isDragging: Signal<boolean> = this.isDraggingSignal.asReadonly();\n\n /** Convenience alias for `items().length`. Useful for counter hints. */\n readonly valueLength: Signal<number> = computed(() => this.itemsSignal().length);\n\n // ── FormFieldControl signals ──\n\n /** @internal */\n readonly id: Signal<string> = computed(() => this.idInput() ?? this.hostId);\n\n /** @internal */\n readonly value: Signal<File[] | null> = computed(() => {\n const list = this.itemsSignal();\n return list.length ? list.map((i) => i.file) : null;\n });\n\n /** @internal */\n readonly focused: Signal<boolean> = this._focused.asReadonly();\n\n /** @internal */\n readonly empty: Signal<boolean> = computed(() => this.itemsSignal().length === 0);\n\n /** @internal */\n readonly disabled: Signal<boolean> = computed(() => {\n this.errorWiring.rev();\n return this.disabledInput() || this.cvaDisabled() || !!this.ngControl?.disabled;\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 Validation errors map from the bound `NgControl`. */\n override readonly errors = this.errorWiring.errors;\n\n /** @internal */\n readonly controlType = 'file-upload';\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 // ── Effective ARIA ──\n //\n // When wrapped by `<tw-form-field>`, the form-field calls `setDescribedByIds`\n // / `setLabelledByIds` with the FULLY MERGED id list (hint/error/label + the\n // consumer's `aria-*by` ids). In that case the pushed ids alone are the\n // source of truth. When standalone, fall back to the consumer-supplied\n // `aria-*by` input and the internal description id.\n\n /** @internal */\n readonly effectiveAriaLabelledby = computed(() => {\n const pushed = this.labelledByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n return this.ariaLabelledby() || undefined;\n });\n\n /** @internal */\n readonly effectiveAriaDescribedby = computed(() => {\n const pushed = this.describedByIdsSignal();\n if (pushed.length) return pushed.join(' ');\n const merged: string[] = [];\n const external = this.ariaDescribedby();\n if (external) {\n for (const id of external.split(/\\s+/).filter(Boolean)) merged.push(id);\n }\n if (this.description()) merged.push(this.descriptionId);\n return merged.length ? merged.join(' ') : undefined;\n });\n\n // ── Variant computeds ──\n\n private readonly stateVariant = computed<'idle' | 'draggingValid' | 'draggingInvalid' | 'error'>(\n () => {\n if (this.disabled()) return 'idle';\n if (this.isDraggingSignal()) {\n return this.dragHasInvalidFilesSignal() ? 'draggingInvalid' : 'draggingValid';\n }\n if (this.errorState()) return 'error';\n return 'idle';\n },\n );\n\n private readonly variantResult = computed(() =>\n fileUploadVariants({\n variant: this.variant(),\n size: this.size(),\n state: this.stateVariant(),\n disabled: this.disabled(),\n }),\n );\n\n /** @internal */\n readonly rootClasses = computed(() => this.variantResult().root());\n /** @internal */\n readonly dropzoneClasses = computed(() => this.variantResult().dropzone());\n /** @internal */\n readonly dropzoneInnerClasses = computed(() => this.variantResult().dropzoneInner());\n /** @internal */\n readonly illustrationClasses = computed(() => this.variantResult().illustration());\n /** @internal */\n readonly headlineClasses = computed(() => this.variantResult().headline());\n /** @internal */\n readonly descriptionClasses = computed(() => this.variantResult().description());\n /** @internal */\n readonly listClasses = computed(() => this.variantResult().list());\n /** @internal */\n readonly itemClasses = computed(() => this.variantResult().item());\n /** @internal */\n readonly itemIconClasses = computed(() => this.variantResult().itemIcon());\n /** @internal */\n readonly itemBodyClasses = computed(() => this.variantResult().itemBody());\n /** @internal */\n readonly itemNameClasses = computed(() => this.variantResult().itemName());\n /** @internal */\n readonly itemMetaClasses = computed(() => this.variantResult().itemMeta());\n /** @internal */\n readonly itemProgressClasses = computed(() => this.variantResult().itemProgress());\n /** @internal */\n readonly itemActionsClasses = computed(() => this.variantResult().itemActions());\n\n /** @internal Mapping component size → icon size for the illustration. */\n readonly iconSize = computed<TwSize>(() => {\n const s = this.size();\n if (s === 'xs') return 'sm';\n if (s === 'sm') return 'md';\n if (s === 'md') return 'lg';\n return 'xl';\n });\n\n // ── Construction ──\n\n constructor() {\n super();\n // Runtime CVA wiring — incompatible with a static NG_VALUE_ACCESSOR provider\n // because `inject(NgControl, { self: true })` for matcher integration would\n // create a circular DI on the same element.\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n\n afterNextRender(() => {\n if (isDevMode() && !this.hasAccessibleNameHint()) {\n console.warn(\n '[tw-file-upload] The file-upload has no accessible name. Provide a `label`, project label content, or set `aria-label` / `aria-labelledby`.',\n );\n }\n });\n }\n\n // ── Public API ──\n\n /** Programmatically opens the OS file picker. No-op when disabled. */\n open(): void {\n if (this.disabled()) return;\n const input = this.hiddenInputRef()?.nativeElement;\n if (input) input.click();\n }\n\n /** Removes the item with the given id. Emits `fileRemoved`. No-op when the id is unknown or the component is disabled. */\n remove(id: string): void {\n if (this.disabled()) return;\n const current = this.itemsSignal();\n const idx = current.findIndex((i) => i.id === id);\n if (idx === -1) return;\n const removed = current[idx];\n const next = current.slice(0, idx).concat(current.slice(idx + 1));\n this.itemsSignal.set(next);\n this.emitChange();\n this.fileRemoved.emit(removed);\n this.liveAnnouncer.announce(`${removed.file.name} removed.`, 'polite');\n // Move focus to the next remove button, or to the trigger button when none\n // remain.\n //\n // This MUST wait for the render, not merely for the microtask queue. A\n // `queueMicrotask` here (what this used to be) runs before Angular's\n // zoneless scheduler has re-rendered the list, so `nextButtons` was still\n // the PRE-removal node list: the \"next\" button we focused was the one about\n // to be destroyed, and focus fell to `<body>`. Removing the last item took\n // the `length === 0` branch for the same reason — the count was stale, so\n // the trigger never got focus either.\n //\n // It survived unit testing because a spec that calls `detectChanges()`\n // between the click and the assertion has already re-rendered by the time\n // the microtask runs, which is the opposite order from a real browser.\n afterNextRender(\n () => {\n const host = this.elementRef.nativeElement as HTMLElement;\n const nextButtons = host.querySelectorAll('[data-tw-file-upload-remove]');\n if (nextButtons.length === 0) {\n this.triggerRef()?.nativeElement.focus();\n } else {\n const fallback = nextButtons[Math.min(idx, nextButtons.length - 1)] as\n | HTMLButtonElement\n | undefined;\n fallback?.focus();\n }\n },\n { injector: this.injector },\n );\n }\n\n /** Removes all items. Emits `cleared` and calls `onChange([])`. No-op when already empty or disabled. */\n clear(): void {\n if (this.disabled()) return;\n if (this.itemsSignal().length === 0) return;\n this.itemsSignal.set([]);\n this.emitChange();\n this.cleared.emit();\n this.liveAnnouncer.announce('All files removed.', 'polite');\n }\n\n /** Updates the per-item progress (0–100, clamped). Does not change status. No-op when the id is unknown. */\n setItemProgress(id: string, percent: number): void {\n const clamped = clampPercent(percent);\n let found = false;\n const next = this.itemsSignal().map((item) => {\n if (item.id !== id) return item;\n found = true;\n if (item.progress === clamped) return item;\n return { ...item, progress: clamped };\n });\n if (found) this.itemsSignal.set(next);\n }\n\n /** Updates the per-item status and (optionally) the error message. Announces status transitions via `LiveAnnouncer`. No-op when the id is unknown. */\n setItemStatus(id: string, status: FileUploadStatus, error?: string): void {\n let target: FileUploadItem | undefined;\n let changed = false;\n const next = this.itemsSignal().map((item) => {\n if (item.id !== id) return item;\n target = item;\n const nextError = error !== undefined ? error : item.error;\n if (item.status === status && item.error === nextError) return item;\n changed = true;\n return { ...item, status, error: nextError };\n });\n if (!target) return;\n if (changed) this.itemsSignal.set(next);\n const name = target.file.name;\n if (status === 'success') {\n this.liveAnnouncer.announce(`${name} upload complete.`, 'polite');\n } else if (status === 'error') {\n this.liveAnnouncer.announce(\n error ? `${name} upload failed: ${error}.` : `${name} upload failed.`,\n 'polite',\n );\n } else if (status === 'uploading') {\n this.liveAnnouncer.announce(`${name} uploading.`, 'polite');\n }\n }\n\n // ── Drag-drop handlers ──\n\n /** @internal */\n onDragEnter(event: DragEvent): void {\n if (this.disabled()) return;\n if (!this.isFileDrag(event)) return;\n event.preventDefault();\n this.dragCounter += 1;\n if (this.dragCounter === 1) {\n this.dragHasInvalidFilesSignal.set(this.computeDragInvalid(event));\n this.isDraggingSignal.set(true);\n }\n }\n\n /** @internal */\n onDragOver(event: DragEvent): void {\n if (this.disabled()) return;\n if (!this.isFileDrag(event)) return;\n // Required to enable `drop` — browsers reject drops by default.\n event.preventDefault();\n }\n\n /** @internal */\n onDragLeave(event: DragEvent): void {\n if (this.disabled()) return;\n if (!this.isFileDrag(event)) return;\n if (this.dragCounter > 0) this.dragCounter -= 1;\n if (this.dragCounter === 0) {\n this.isDraggingSignal.set(false);\n this.dragHasInvalidFilesSignal.set(false);\n }\n }\n\n /** @internal */\n onDrop(event: DragEvent): void {\n if (this.disabled()) return;\n event.preventDefault();\n this.dragCounter = 0;\n this.isDraggingSignal.set(false);\n this.dragHasInvalidFilesSignal.set(false);\n const files = event.dataTransfer?.files;\n if (files && files.length) {\n this.addFiles(files);\n }\n }\n\n /** @internal */\n onTriggerClick(event: MouseEvent): void {\n event.stopPropagation();\n this.open();\n }\n\n /** @internal Called by the hidden `<input type=\"file\">` `change` event. */\n onNativeChange(event: Event): void {\n const target = event.target as HTMLInputElement;\n const files = target.files;\n if (files && files.length) this.addFiles(files);\n // Reset so re-selecting the same file re-fires `change`.\n target.value = '';\n }\n\n // ── Add files (validation + commit) ──\n\n private addFiles(files: FileList | readonly File[]): void {\n if (this.disabled()) return;\n const incoming: File[] = Array.from(files);\n if (incoming.length === 0) return;\n\n // Single-file mode: replace existing entry with the latest file dropped/selected.\n if (!this.multiple()) {\n const file = incoming[0];\n if (!file) return;\n const patterns = parseAcceptList(this.accept());\n if (!matchesAccept(file, patterns)) {\n this.reject(file, 'accept');\n return;\n }\n const maxSize = this.maxSize();\n if (maxSize !== undefined && file.size > maxSize) {\n this.reject(file, 'size');\n return;\n }\n const newItem = this.wrapFile(file);\n this.itemsSignal.set([newItem]);\n this.emitChange();\n this.filesAdded.emit([newItem]);\n this.liveAnnouncer.announce('1 file added.', 'polite');\n return;\n }\n\n const patterns = parseAcceptList(this.accept());\n const maxSize = this.maxSize();\n const maxFiles = this.maxFiles();\n const accepted: FileUploadItem[] = [];\n const currentCount = this.itemsSignal().length;\n\n for (const file of incoming) {\n if (!matchesAccept(file, patterns)) {\n this.reject(file, 'accept');\n continue;\n }\n if (maxSize !== undefined && file.size > maxSize) {\n this.reject(file, 'size');\n continue;\n }\n if (maxFiles !== undefined && currentCount + accepted.length >= maxFiles) {\n this.reject(file, 'count');\n continue;\n }\n accepted.push(this.wrapFile(file));\n }\n\n if (accepted.length === 0) return;\n\n this.itemsSignal.set([...this.itemsSignal(), ...accepted]);\n this.emitChange();\n this.filesAdded.emit(accepted);\n this.liveAnnouncer.announce(\n `${accepted.length} file${accepted.length === 1 ? '' : 's'} added.`,\n 'polite',\n );\n }\n\n private wrapFile(file: File): FileUploadItem {\n return {\n id: `tw-file-upload-item-${nextItemSeq++}`,\n file,\n progress: 0,\n status: 'pending',\n };\n }\n\n private reject(file: File, reason: FileUploadRejectionReason): void {\n const message = this.rejectionMessage(file, reason);\n // Sequence per-file announcements so a batch of rejections is announced cleanly.\n setTimeout(() => this.liveAnnouncer.announce(message, 'polite'));\n this.fileRejected.emit({ file, reason, message });\n }\n\n private rejectionMessage(file: File, reason: FileUploadRejectionReason): string {\n if (reason === 'accept') return `${file.name} was rejected: file type not allowed.`;\n if (reason === 'size') {\n const max = this.maxSize();\n const limit = max !== undefined ? formatBytes(max) : 'allowed size';\n return `${file.name} was rejected: exceeds ${limit}.`;\n }\n return `${file.name} was rejected: maximum file count reached.`;\n }\n\n // ── Drag inspection ──\n\n private isFileDrag(event: DragEvent): boolean {\n const dt = event.dataTransfer;\n if (!dt) return false;\n // `types` includes 'Files' when files are being dragged from the OS.\n return Array.from(dt.types).includes('Files');\n }\n\n private computeDragInvalid(event: DragEvent): boolean {\n const patterns = parseAcceptList(this.accept());\n if (patterns.length === 0) return false;\n const items = event.dataTransfer?.items;\n if (!items || items.length === 0) return false;\n // During drag, filenames are not exposed — only MIME types via `items[i].type`.\n // Extension-only patterns (`.pdf`) can't be confirmed mid-drag, so we treat\n // the drag as potentially valid if ANY item could match by MIME or if the\n // accept list contains any extension-only pattern.\n const hasExtensionPattern = patterns.some((p) => p.startsWith('.'));\n if (hasExtensionPattern) return false;\n for (const item of Array.from(items)) {\n if (item.kind !== 'file') continue;\n const type = item.type.toLowerCase();\n for (const pattern of patterns) {\n if (pattern.endsWith('/*')) {\n if (type.startsWith(pattern.slice(0, -1))) return false;\n } else if (type === pattern) {\n return false;\n }\n }\n }\n return true;\n }\n\n // ── ControlValueAccessor ──\n\n writeValue(value: File[] | File | null | undefined): void {\n if (value === null || value === undefined) {\n if (this.itemsSignal().length === 0) return;\n this.itemsSignal.set([]);\n return;\n }\n const list: File[] = Array.isArray(value) ? value : [value];\n if (list.length === 0) {\n if (this.itemsSignal().length === 0) return;\n this.itemsSignal.set([]);\n return;\n }\n const current = this.itemsSignal();\n if (\n current.length === list.length &&\n current.every((item, idx) => item.file === list[idx])\n ) {\n return;\n }\n this.itemsSignal.set(list.map((file) => this.wrapFile(file)));\n }\n\n registerOnChange(fn: (value: File[]) => 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 private emitChange(): void {\n const files = this.itemsSignal().map((i) => i.file);\n this.onChange(files);\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 */\n onContainerClick(event: MouseEvent): void {\n if (this.disabled()) return;\n if (event.defaultPrevented) return;\n const dropzone = this.dropzoneRef()?.nativeElement;\n if (!dropzone) return;\n const target = event.target as Node | null;\n if (target && dropzone.contains(target)) return;\n this.triggerRef()?.nativeElement.focus();\n }\n\n // ── Rendering helpers ──\n\n /** @internal */\n iconNameFor(item: FileUploadItem): string {\n return iconNameFor(item.file);\n }\n\n /** @internal */\n shouldShowProgress(item: FileUploadItem): boolean {\n if (item.status === 'pending' && item.progress === 0) return false;\n return true;\n }\n\n /** @internal */\n progressColorFor(item: FileUploadItem): 'primary' | 'success' | 'error' {\n if (item.status === 'error') return 'error';\n if (item.status === 'success' || item.progress >= 100) return 'success';\n return 'primary';\n }\n\n /** @internal */\n metaTextFor(item: FileUploadItem): string {\n const size = formatBytes(item.file.size);\n if (item.status === 'pending') return size;\n if (item.status === 'uploading') return `${size} · Uploading`;\n if (item.status === 'success') return `${size} · Done`;\n if (item.error) return `${size} · Failed — ${item.error}`;\n return `${size} · Failed`;\n }\n\n // ── Lifecycle ──\n\n ngOnInit(): void {\n const monitor$ = this.focusMonitor.monitor(this.elementRef, true);\n if (isObservable(monitor$)) {\n monitor$.pipe(takeUntilDestroyed(this.destroyRef)).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 }\n this.destroyRef.onDestroy(() => {\n this.focusMonitor.stopMonitoring(this.elementRef);\n });\n\n this.errorWiring.connect();\n }\n\n // ── Helpers ──\n\n private hasAccessibleNameHint(): boolean {\n if (this.label() || this.ariaLabel() || this.ariaLabelledby()) return true;\n const host = this.elementRef.nativeElement;\n return !!host.textContent && host.textContent.trim().length > 0;\n }\n}\n","<input\n #hiddenInput\n type=\"file\"\n class=\"sr-only\"\n tabindex=\"-1\"\n [id]=\"hiddenInputId\"\n [attr.aria-label]=\"ariaLabel() ?? label() ?? triggerLabel()\"\n [attr.name]=\"name() || null\"\n [attr.accept]=\"accept() || null\"\n [multiple]=\"multiple()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [attr.aria-invalid]=\"errorState() || null\"\n (change)=\"onNativeChange($event)\"\n/>\n\n<!-- The dropzone is a mouse click/drop convenience target, intentionally NOT a\n focusable control: the inner trigger <button> owns keyboard operability, so\n adding tabindex/keydown here would create a nested-interactive structure.\n No keyboard user is locked out, so the rules' concern does not apply. -->\n<!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n<div\n #dropzone\n [class]=\"dropzoneClasses()\"\n (click)=\"open()\"\n (dragenter)=\"onDragEnter($event)\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div [class]=\"dropzoneInnerClasses()\">\n <div [class]=\"illustrationClasses()\">\n <ng-content select=\"[twFileUploadIcon]\">\n <tw-icon name=\"upload-cloud\" [size]=\"iconSize()\" aria-hidden=\"true\" />\n </ng-content>\n </div>\n\n <span [id]=\"headlineId\" [class]=\"headlineClasses()\">\n <ng-content select=\"[twFileUploadHeadline]\">\n @if (label(); as l) {\n {{ l }}\n } @else {\n Drag files here or click to browse\n }\n </ng-content>\n </span>\n\n <span [id]=\"descriptionId\" [class]=\"descriptionClasses()\">\n <ng-content select=\"[twFileUploadDescription]\">\n @if (description(); as d) {\n {{ d }}\n }\n </ng-content>\n </span>\n\n <button\n #trigger\n type=\"button\"\n twButton\n variant=\"outline\"\n color=\"neutral\"\n [size]=\"size()\"\n [disabled]=\"disabled()\"\n [attr.aria-describedby]=\"effectiveAriaDescribedby() || null\"\n (click)=\"onTriggerClick($event)\"\n >\n {{ triggerLabel() }}\n </button>\n </div>\n</div>\n\n<ul [class]=\"listClasses()\" role=\"list\">\n @for (item of items(); track item.id) {\n <li>\n @if (itemSlot(); as slot) {\n <ng-container\n [ngTemplateOutlet]=\"slot.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: item, item: item }\"\n />\n } @else {\n <div [class]=\"itemClasses()\">\n <tw-icon\n [name]=\"iconNameFor(item)\"\n size=\"md\"\n [class]=\"itemIconClasses()\"\n aria-hidden=\"true\"\n />\n <div [class]=\"itemBodyClasses()\">\n <span [class]=\"itemNameClasses()\">{{ item.file.name }}</span>\n <span [class]=\"itemMetaClasses()\">{{ metaTextFor(item) }}</span>\n @if (shouldShowProgress(item)) {\n <tw-progress-bar\n [class]=\"itemProgressClasses()\"\n [value]=\"item.progress\"\n size=\"sm\"\n [color]=\"progressColorFor(item)\"\n />\n }\n </div>\n <div [class]=\"itemActionsClasses()\">\n <button\n type=\"button\"\n twButton\n variant=\"ghost\"\n color=\"neutral\"\n size=\"sm\"\n data-tw-file-upload-remove\n [attr.aria-label]=\"'Remove ' + item.file.name\"\n (click)=\"remove(item.id)\"\n >\n <tw-icon twButtonIcon name=\"x\" />\n </button>\n </div>\n </div>\n }\n </li>\n }\n</ul>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -3,10 +3,23 @@ import { input, booleanAttribute, model, inject, DestroyRef, viewChild, signal,
3
3
  import { LiveAnnouncer } from '@angular/cdk/a11y';
4
4
  import { tv } from 'tailwind-variants';
5
5
 
6
+ /** Maps every legacy spelling onto its canonical replacement. */
7
+ const VARIANT_ALIASES = {
8
+ outlined: 'outline',
9
+ };
6
10
  // ── tv() config ──
7
11
  const flipCardVariants = tv({
8
12
  slots: {
9
13
  root: 'relative block rounded-lg transition-shadow duration-normal motion-reduce:transition-none tw-flip-perspective',
14
+ // `duration-300` sits above the codified transition scale
15
+ // (`duration-150` / `duration-200` / `duration-normal`), and none of
16
+ // those govern here: the scale is calibrated for colour and shadow
17
+ // shifts that travel no distance, while this is a 180° 3-D rotation of
18
+ // the whole card through `rotateY`/`rotateX`. At `duration-200` the
19
+ // faces swap before the perspective reads as depth and the flip looks
20
+ // like a hard cut; 300ms is the shortest step where the rotation is
21
+ // legible as one continuous motion. The `motion-reduce:transition-none`
22
+ // guard the scale requires is still applied.
10
23
  inner: 'relative h-full w-full tw-flip-inner transition-transform duration-300 ease-in-out motion-reduce:transition-none',
11
24
  face: 'absolute inset-0 h-full w-full rounded-lg overflow-hidden tw-flip-face',
12
25
  front: '',
@@ -14,7 +27,7 @@ const flipCardVariants = tv({
14
27
  },
15
28
  variants: {
16
29
  variant: {
17
- outlined: {
30
+ outline: {
18
31
  face: 'bg-surface border border-border text-fg',
19
32
  },
20
33
  elevated: {
@@ -51,7 +64,7 @@ const flipCardVariants = tv({
51
64
  },
52
65
  },
53
66
  defaultVariants: {
54
- variant: 'outlined',
67
+ variant: 'outline',
55
68
  direction: 'horizontal',
56
69
  flipped: false,
57
70
  interactive: true,
@@ -74,10 +87,11 @@ const flipCardVariants = tv({
74
87
  class FlipCardComponent {
75
88
  /**
76
89
  * Visual style of the card chrome. Mirrors `tw-card`'s variant vocabulary.
77
- * Defaults to `'outlined'` (vs `tw-card`'s `'elevated'` default) so the flip
90
+ * Defaults to `'outline'` (vs `tw-card`'s `'elevated'` default) so the flip
78
91
  * animation reads more clearly without a baseline shadow underneath.
92
+ * `'outlined'` is a deprecated alias for `'outline'` and renders identically.
79
93
  */
80
- variant = input('outlined', /* @ts-ignore */
94
+ variant = input('outline', /* @ts-ignore */
81
95
  ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
82
96
  /** Axis of rotation. `'horizontal'` rotates around the Y axis (left/right flip); `'vertical'` rotates around the X axis (top/bottom flip). Defaults to `'horizontal'`. */
83
97
  direction = input('horizontal', /* @ts-ignore */
@@ -91,15 +105,14 @@ class FlipCardComponent {
91
105
  flipped = model(false, /* @ts-ignore */
92
106
  ...(ngDevMode ? [{ debugName: "flipped" }] : /* istanbul ignore next */ []));
93
107
  /**
94
- * Accessible name for the host element. Required when `trigger` is
95
- * `'manual'` (the host renders as `role="region"`, which AXE requires to
96
- * have an accessible name); a default of `'Flip card'` is used in that
97
- * mode if no value is provided. In interactive modes the host's accessible
98
- * name is normally derived from the visible face's content — set this
99
- * input to override.
108
+ * Accessible name for the host element, mirrored to `aria-label`. Required
109
+ * when `trigger` is `'manual'` (the host renders as `role="region"`, which
110
+ * AXE requires to have an accessible name); a default of `'Flip card'` is
111
+ * used in that mode if no value is provided. In interactive modes the host's
112
+ * accessible name is normally derived from the visible face's content — set
113
+ * this input to override. Defaults to `undefined`.
100
114
  */
101
- ariaLabel = input(undefined, /* @ts-ignore */
102
- ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
115
+ ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
103
116
  liveAnnouncer = inject(LiveAnnouncer);
104
117
  destroyRef = inject(DestroyRef);
105
118
  backWrapper = viewChild('backWrapper', /* @ts-ignore */
@@ -121,9 +134,6 @@ class FlipCardComponent {
121
134
  ariaPressed = computed(() => this.interactive() ? String(this.flipped()) : null, /* @ts-ignore */
122
135
  ...(ngDevMode ? [{ debugName: "ariaPressed" }] : /* istanbul ignore next */ []));
123
136
  /** @internal */
124
- ariaLive = computed(() => this.trigger() === 'manual' ? 'polite' : null, /* @ts-ignore */
125
- ...(ngDevMode ? [{ debugName: "ariaLive" }] : /* istanbul ignore next */ []));
126
- /** @internal */
127
137
  ariaDisabled = computed(() => this.disabled() ? 'true' : null, /* @ts-ignore */
128
138
  ...(ngDevMode ? [{ debugName: "ariaDisabled" }] : /* istanbul ignore next */ []));
129
139
  /** @internal */
@@ -146,8 +156,15 @@ class FlipCardComponent {
146
156
  /** @internal */
147
157
  backInert = computed(() => !this.hasBack() || !this.flipped() ? '' : null, /* @ts-ignore */
148
158
  ...(ngDevMode ? [{ debugName: "backInert" }] : /* istanbul ignore next */ []));
159
+ /** @internal Canonical variant with legacy spellings folded in. */
160
+ resolvedVariant = computed(() => {
161
+ const v = this.variant();
162
+ return (VARIANT_ALIASES[v] ??
163
+ v);
164
+ }, /* @ts-ignore */
165
+ ...(ngDevMode ? [{ debugName: "resolvedVariant" }] : /* istanbul ignore next */ []));
149
166
  variantResult = computed(() => flipCardVariants({
150
- variant: this.variant(),
167
+ variant: this.resolvedVariant(),
151
168
  direction: this.direction(),
152
169
  flipped: this.flipped(),
153
170
  interactive: this.interactive(),
@@ -187,11 +204,13 @@ class FlipCardComponent {
187
204
  firstRun = false;
188
205
  return;
189
206
  }
190
- // Announce in any mode that exposes a flippable back face. Manual mode
191
- // historically owned this because it sets `aria-live='polite'` on the
192
- // host; interactive modes (hover, click, both) still need an explicit
193
- // `LiveAnnouncer.announce` so screen-reader users hear the transition
194
- // when triggering the card via keyboard or pointer.
207
+ // `LiveAnnouncer` is the single announcement channel, in every trigger
208
+ // mode. Manual mode used to *also* mark the host `aria-live="polite"`,
209
+ // so the `aria-hidden` face swap was announced by the live region on
210
+ // top of this call one flip, two announcements. The host region was
211
+ // dropped rather than this call, because it was the narrower of the
212
+ // two (manual mode only) and because a live region whose host also
213
+ // carries `role`/`aria-label` is announced inconsistently across ATs.
195
214
  if (this.hasBack()) {
196
215
  this.liveAnnouncer.announce(isFlipped ? 'Back face visible' : 'Front face visible');
197
216
  }
@@ -242,7 +261,7 @@ class FlipCardComponent {
242
261
  this.flipped.set(next);
243
262
  }
244
263
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: FlipCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
245
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.7", type: FlipCardComponent, isStandalone: true, selector: "tw-flip-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, flipped: { classPropertyName: "flipped", publicName: "flipped", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { flipped: "flippedChange" }, host: { listeners: { "click": "onClick()", "keydown": "onKeydown($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" }, properties: { "class": "rootClasses()", "attr.role": "hostRole()", "attr.tabindex": "hostTabindex()", "attr.aria-pressed": "ariaPressed()", "attr.aria-live": "ariaLive()", "attr.aria-disabled": "ariaDisabled()", "attr.aria-label": "hostAriaLabel()" } }, viewQueries: [{ propertyName: "backWrapper", first: true, predicate: ["backWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: `
264
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.7", type: FlipCardComponent, isStandalone: true, selector: "tw-flip-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, trigger: { classPropertyName: "trigger", publicName: "trigger", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, flipped: { classPropertyName: "flipped", publicName: "flipped", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { flipped: "flippedChange" }, host: { listeners: { "click": "onClick()", "keydown": "onKeydown($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" }, properties: { "class": "rootClasses()", "attr.role": "hostRole()", "attr.tabindex": "hostTabindex()", "attr.aria-pressed": "ariaPressed()", "attr.aria-disabled": "ariaDisabled()", "attr.aria-label": "hostAriaLabel()" } }, viewQueries: [{ propertyName: "backWrapper", first: true, predicate: ["backWrapper"], descendants: true, isSignal: true }], ngImport: i0, template: `
246
265
  <div [class]="innerClasses()">
247
266
  <div
248
267
  [class]="frontClasses()"
@@ -273,7 +292,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
273
292
  '[attr.role]': 'hostRole()',
274
293
  '[attr.tabindex]': 'hostTabindex()',
275
294
  '[attr.aria-pressed]': 'ariaPressed()',
276
- '[attr.aria-live]': 'ariaLive()',
277
295
  '[attr.aria-disabled]': 'ariaDisabled()',
278
296
  '[attr.aria-label]': 'hostAriaLabel()',
279
297
  '(click)': 'onClick()',
@@ -302,7 +320,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
302
320
  </div>
303
321
  `,
304
322
  }]
305
- }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], flipped: [{ type: i0.Input, args: [{ isSignal: true, alias: "flipped", required: false }] }, { type: i0.Output, args: ["flippedChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], backWrapper: [{ type: i0.ViewChild, args: ['backWrapper', { isSignal: true }] }] } });
323
+ }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], trigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], flipped: [{ type: i0.Input, args: [{ isSignal: true, alias: "flipped", required: false }] }, { type: i0.Output, args: ["flippedChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], backWrapper: [{ type: i0.ViewChild, args: ['backWrapper', { isSignal: true }] }] } });
306
324
 
307
325
  /**
308
326
  * Generated bundle index. Do not edit.