@cdevhub/ngx-tw 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/README.md +78 -15
  2. package/fesm2022/cdevhub-ngx-tw-accordion.mjs +16 -5
  3. package/fesm2022/cdevhub-ngx-tw-accordion.mjs.map +1 -1
  4. package/fesm2022/cdevhub-ngx-tw-avatar.mjs +26 -15
  5. package/fesm2022/cdevhub-ngx-tw-avatar.mjs.map +1 -1
  6. package/fesm2022/cdevhub-ngx-tw-badge.mjs +17 -5
  7. package/fesm2022/cdevhub-ngx-tw-badge.mjs.map +1 -1
  8. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs +27 -6
  9. package/fesm2022/cdevhub-ngx-tw-breadcrumbs.mjs.map +1 -1
  10. package/fesm2022/cdevhub-ngx-tw-button.mjs +23 -11
  11. package/fesm2022/cdevhub-ngx-tw-button.mjs.map +1 -1
  12. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs +5 -5
  13. package/fesm2022/cdevhub-ngx-tw-calendar-luxon.mjs.map +1 -1
  14. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs +3 -3
  15. package/fesm2022/cdevhub-ngx-tw-calendar-testing.mjs.map +1 -1
  16. package/fesm2022/cdevhub-ngx-tw-calendar.mjs +427 -122
  17. package/fesm2022/cdevhub-ngx-tw-calendar.mjs.map +1 -1
  18. package/fesm2022/cdevhub-ngx-tw-card.mjs +21 -11
  19. package/fesm2022/cdevhub-ngx-tw-card.mjs.map +1 -1
  20. package/fesm2022/cdevhub-ngx-tw-carousel.mjs +215 -96
  21. package/fesm2022/cdevhub-ngx-tw-carousel.mjs.map +1 -1
  22. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs +108 -64
  23. package/fesm2022/cdevhub-ngx-tw-checkbox.mjs.map +1 -1
  24. package/fesm2022/cdevhub-ngx-tw-code-block.mjs +18 -6
  25. package/fesm2022/cdevhub-ngx-tw-code-block.mjs.map +1 -1
  26. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs +55 -30
  27. package/fesm2022/cdevhub-ngx-tw-collapsible.mjs.map +1 -1
  28. package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs +218 -0
  29. package/fesm2022/cdevhub-ngx-tw-combobox-testing.mjs.map +1 -0
  30. package/fesm2022/cdevhub-ngx-tw-combobox.mjs +236 -211
  31. package/fesm2022/cdevhub-ngx-tw-combobox.mjs.map +1 -1
  32. package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs +200 -0
  33. package/fesm2022/cdevhub-ngx-tw-command-palette-testing.mjs.map +1 -0
  34. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs +34 -7
  35. package/fesm2022/cdevhub-ngx-tw-command-palette.mjs.map +1 -1
  36. package/fesm2022/cdevhub-ngx-tw-core.mjs +135 -15
  37. package/fesm2022/cdevhub-ngx-tw-core.mjs.map +1 -1
  38. package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs +203 -0
  39. package/fesm2022/cdevhub-ngx-tw-date-picker-testing.mjs.map +1 -0
  40. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs +160 -102
  41. package/fesm2022/cdevhub-ngx-tw-date-picker.mjs.map +1 -1
  42. package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs +209 -0
  43. package/fesm2022/cdevhub-ngx-tw-date-range-picker-testing.mjs.map +1 -0
  44. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs +182 -107
  45. package/fesm2022/cdevhub-ngx-tw-date-range-picker.mjs.map +1 -1
  46. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs +122 -0
  47. package/fesm2022/cdevhub-ngx-tw-dialog-testing.mjs.map +1 -0
  48. package/fesm2022/cdevhub-ngx-tw-dialog.mjs +11 -2
  49. package/fesm2022/cdevhub-ngx-tw-dialog.mjs.map +1 -1
  50. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs +1 -1
  51. package/fesm2022/cdevhub-ngx-tw-empty-state.mjs.map +1 -1
  52. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs +149 -0
  53. package/fesm2022/cdevhub-ngx-tw-file-upload-testing.mjs.map +1 -0
  54. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs +57 -67
  55. package/fesm2022/cdevhub-ngx-tw-file-upload.mjs.map +1 -1
  56. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs +42 -24
  57. package/fesm2022/cdevhub-ngx-tw-flip-card.mjs.map +1 -1
  58. package/fesm2022/cdevhub-ngx-tw-form-field.mjs +114 -21
  59. package/fesm2022/cdevhub-ngx-tw-form-field.mjs.map +1 -1
  60. package/fesm2022/cdevhub-ngx-tw-icon.mjs +16 -6
  61. package/fesm2022/cdevhub-ngx-tw-icon.mjs.map +1 -1
  62. package/fesm2022/cdevhub-ngx-tw-input.mjs +52 -61
  63. package/fesm2022/cdevhub-ngx-tw-input.mjs.map +1 -1
  64. package/fesm2022/cdevhub-ngx-tw-item.mjs +18 -3
  65. package/fesm2022/cdevhub-ngx-tw-item.mjs.map +1 -1
  66. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs +168 -0
  67. package/fesm2022/cdevhub-ngx-tw-menu-testing.mjs.map +1 -0
  68. package/fesm2022/cdevhub-ngx-tw-menu.mjs +58 -21
  69. package/fesm2022/cdevhub-ngx-tw-menu.mjs.map +1 -1
  70. package/fesm2022/cdevhub-ngx-tw-number-input.mjs +34 -1
  71. package/fesm2022/cdevhub-ngx-tw-number-input.mjs.map +1 -1
  72. package/fesm2022/cdevhub-ngx-tw-paginator.mjs +95 -45
  73. package/fesm2022/cdevhub-ngx-tw-paginator.mjs.map +1 -1
  74. package/fesm2022/cdevhub-ngx-tw-popover.mjs +81 -32
  75. package/fesm2022/cdevhub-ngx-tw-popover.mjs.map +1 -1
  76. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs +1 -1
  77. package/fesm2022/cdevhub-ngx-tw-progress-bar.mjs.map +1 -1
  78. package/fesm2022/cdevhub-ngx-tw-radio.mjs +131 -98
  79. package/fesm2022/cdevhub-ngx-tw-radio.mjs.map +1 -1
  80. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs +207 -42
  81. package/fesm2022/cdevhub-ngx-tw-segmented-control.mjs.map +1 -1
  82. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs +165 -0
  83. package/fesm2022/cdevhub-ngx-tw-select-testing.mjs.map +1 -0
  84. package/fesm2022/cdevhub-ngx-tw-select.mjs +386 -210
  85. package/fesm2022/cdevhub-ngx-tw-select.mjs.map +1 -1
  86. package/fesm2022/{cdevhub-ngx-tw-sheet-sheet-renderer-ByyNluUd.mjs → cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs} +3 -3
  87. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-CqVJwgmp.mjs.map +1 -0
  88. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs +129 -0
  89. package/fesm2022/cdevhub-ngx-tw-sheet-testing.mjs.map +1 -0
  90. package/fesm2022/cdevhub-ngx-tw-sheet.mjs +23 -7
  91. package/fesm2022/cdevhub-ngx-tw-sheet.mjs.map +1 -1
  92. package/fesm2022/cdevhub-ngx-tw-slider.mjs +89 -54
  93. package/fesm2022/cdevhub-ngx-tw-slider.mjs.map +1 -1
  94. package/fesm2022/cdevhub-ngx-tw-sort.mjs +122 -17
  95. package/fesm2022/cdevhub-ngx-tw-sort.mjs.map +1 -1
  96. package/fesm2022/cdevhub-ngx-tw-split.mjs +72 -19
  97. package/fesm2022/cdevhub-ngx-tw-split.mjs.map +1 -1
  98. package/fesm2022/cdevhub-ngx-tw-stat.mjs +63 -25
  99. package/fesm2022/cdevhub-ngx-tw-stat.mjs.map +1 -1
  100. package/fesm2022/cdevhub-ngx-tw-stepper.mjs +35 -8
  101. package/fesm2022/cdevhub-ngx-tw-stepper.mjs.map +1 -1
  102. package/fesm2022/cdevhub-ngx-tw-switch.mjs +54 -48
  103. package/fesm2022/cdevhub-ngx-tw-switch.mjs.map +1 -1
  104. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs +12 -15
  105. package/fesm2022/cdevhub-ngx-tw-tab-nav.mjs.map +1 -1
  106. package/fesm2022/cdevhub-ngx-tw-table.mjs +74 -13
  107. package/fesm2022/cdevhub-ngx-tw-table.mjs.map +1 -1
  108. package/fesm2022/cdevhub-ngx-tw-tabs.mjs +84 -30
  109. package/fesm2022/cdevhub-ngx-tw-tabs.mjs.map +1 -1
  110. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs +172 -0
  111. package/fesm2022/cdevhub-ngx-tw-tags-input-testing.mjs.map +1 -0
  112. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs +107 -71
  113. package/fesm2022/cdevhub-ngx-tw-tags-input.mjs.map +1 -1
  114. package/fesm2022/cdevhub-ngx-tw-textarea.mjs +41 -9
  115. package/fesm2022/cdevhub-ngx-tw-textarea.mjs.map +1 -1
  116. package/fesm2022/cdevhub-ngx-tw-theme.mjs +257 -45
  117. package/fesm2022/cdevhub-ngx-tw-theme.mjs.map +1 -1
  118. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs +201 -0
  119. package/fesm2022/cdevhub-ngx-tw-time-picker-testing.mjs.map +1 -0
  120. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs +184 -77
  121. package/fesm2022/cdevhub-ngx-tw-time-picker.mjs.map +1 -1
  122. package/fesm2022/cdevhub-ngx-tw-timeline.mjs +110 -27
  123. package/fesm2022/cdevhub-ngx-tw-timeline.mjs.map +1 -1
  124. package/fesm2022/{cdevhub-ngx-tw-toast-toast-renderer-DSu4YoTy.mjs → cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs} +107 -19
  125. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-BlDxemsU.mjs.map +1 -0
  126. package/fesm2022/cdevhub-ngx-tw-toast.mjs +21 -13
  127. package/fesm2022/cdevhub-ngx-tw-toast.mjs.map +1 -1
  128. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs +102 -15
  129. package/fesm2022/cdevhub-ngx-tw-tooltip.mjs.map +1 -1
  130. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs +219 -0
  131. package/fesm2022/cdevhub-ngx-tw-transfer-testing.mjs.map +1 -0
  132. package/fesm2022/cdevhub-ngx-tw-transfer.mjs +88 -69
  133. package/fesm2022/cdevhub-ngx-tw-transfer.mjs.map +1 -1
  134. package/fesm2022/cdevhub-ngx-tw-tree.mjs +68 -19
  135. package/fesm2022/cdevhub-ngx-tw-tree.mjs.map +1 -1
  136. package/index.json +1 -1
  137. package/package.json +63 -2
  138. package/theme/_base.css +13 -0
  139. package/theme/_dark.css +110 -36
  140. package/theme/_high-contrast-dark.css +367 -0
  141. package/theme/_high-contrast.css +13 -2
  142. package/theme/_light.css +276 -0
  143. package/theme/_semantic.css +47 -12
  144. package/theme/_typography.css +17 -0
  145. package/theme/index.css +86 -7
  146. package/types/cdevhub-ngx-tw-accordion.d.ts +12 -4
  147. package/types/cdevhub-ngx-tw-avatar.d.ts +10 -3
  148. package/types/cdevhub-ngx-tw-button.d.ts +1 -0
  149. package/types/cdevhub-ngx-tw-calendar-luxon.d.ts +2 -2
  150. package/types/cdevhub-ngx-tw-calendar-testing.d.ts +1 -1
  151. package/types/cdevhub-ngx-tw-calendar.d.ts +179 -73
  152. package/types/cdevhub-ngx-tw-card.d.ts +11 -3
  153. package/types/cdevhub-ngx-tw-carousel.d.ts +89 -20
  154. package/types/cdevhub-ngx-tw-checkbox.d.ts +40 -12
  155. package/types/cdevhub-ngx-tw-code-block.d.ts +11 -2
  156. package/types/cdevhub-ngx-tw-collapsible.d.ts +32 -5
  157. package/types/cdevhub-ngx-tw-combobox-testing.d.ts +157 -0
  158. package/types/cdevhub-ngx-tw-combobox.d.ts +94 -53
  159. package/types/cdevhub-ngx-tw-command-palette-testing.d.ts +136 -0
  160. package/types/cdevhub-ngx-tw-command-palette.d.ts +33 -5
  161. package/types/cdevhub-ngx-tw-core.d.ts +152 -21
  162. package/types/cdevhub-ngx-tw-date-picker-testing.d.ts +141 -0
  163. package/types/cdevhub-ngx-tw-date-picker.d.ts +37 -29
  164. package/types/cdevhub-ngx-tw-date-range-picker-testing.d.ts +148 -0
  165. package/types/cdevhub-ngx-tw-date-range-picker.d.ts +36 -29
  166. package/types/cdevhub-ngx-tw-dialog-testing.d.ts +98 -0
  167. package/types/cdevhub-ngx-tw-dialog.d.ts +12 -3
  168. package/types/cdevhub-ngx-tw-file-upload-testing.d.ts +120 -0
  169. package/types/cdevhub-ngx-tw-file-upload.d.ts +8 -10
  170. package/types/cdevhub-ngx-tw-flip-card.d.ts +18 -11
  171. package/types/cdevhub-ngx-tw-form-field.d.ts +19 -2
  172. package/types/cdevhub-ngx-tw-icon.d.ts +3 -3
  173. package/types/cdevhub-ngx-tw-input.d.ts +5 -8
  174. package/types/cdevhub-ngx-tw-item.d.ts +2 -0
  175. package/types/cdevhub-ngx-tw-menu-testing.d.ts +131 -0
  176. package/types/cdevhub-ngx-tw-menu.d.ts +2 -2
  177. package/types/cdevhub-ngx-tw-number-input.d.ts +20 -0
  178. package/types/cdevhub-ngx-tw-paginator.d.ts +58 -24
  179. package/types/cdevhub-ngx-tw-popover.d.ts +41 -10
  180. package/types/cdevhub-ngx-tw-progress-bar.d.ts +1 -1
  181. package/types/cdevhub-ngx-tw-radio.d.ts +68 -25
  182. package/types/cdevhub-ngx-tw-segmented-control.d.ts +79 -16
  183. package/types/cdevhub-ngx-tw-select-testing.d.ts +114 -0
  184. package/types/cdevhub-ngx-tw-select.d.ts +104 -33
  185. package/types/cdevhub-ngx-tw-sheet-testing.d.ts +104 -0
  186. package/types/cdevhub-ngx-tw-sheet.d.ts +19 -3
  187. package/types/cdevhub-ngx-tw-slider.d.ts +79 -25
  188. package/types/cdevhub-ngx-tw-sort.d.ts +45 -4
  189. package/types/cdevhub-ngx-tw-split.d.ts +32 -2
  190. package/types/cdevhub-ngx-tw-stat.d.ts +14 -4
  191. package/types/cdevhub-ngx-tw-stepper.d.ts +16 -2
  192. package/types/cdevhub-ngx-tw-switch.d.ts +35 -13
  193. package/types/cdevhub-ngx-tw-tab-nav.d.ts +7 -6
  194. package/types/cdevhub-ngx-tw-table.d.ts +53 -10
  195. package/types/cdevhub-ngx-tw-tabs.d.ts +41 -10
  196. package/types/cdevhub-ngx-tw-tags-input-testing.d.ts +135 -0
  197. package/types/cdevhub-ngx-tw-tags-input.d.ts +26 -11
  198. package/types/cdevhub-ngx-tw-textarea.d.ts +3 -2
  199. package/types/cdevhub-ngx-tw-theme.d.ts +245 -39
  200. package/types/cdevhub-ngx-tw-time-picker-testing.d.ts +129 -0
  201. package/types/cdevhub-ngx-tw-time-picker.d.ts +76 -19
  202. package/types/cdevhub-ngx-tw-timeline.d.ts +36 -12
  203. package/types/cdevhub-ngx-tw-toast.d.ts +20 -6
  204. package/types/cdevhub-ngx-tw-tooltip.d.ts +28 -6
  205. package/types/cdevhub-ngx-tw-transfer-testing.d.ts +152 -0
  206. package/types/cdevhub-ngx-tw-transfer.d.ts +21 -8
  207. package/types/cdevhub-ngx-tw-tree.d.ts +6 -1
  208. package/fesm2022/cdevhub-ngx-tw-sheet-sheet-renderer-ByyNluUd.mjs.map +0 -1
  209. package/fesm2022/cdevhub-ngx-tw-toast-toast-renderer-DSu4YoTy.mjs.map +0 -1
package/README.md CHANGED
@@ -87,7 +87,7 @@ import { Star, Search, Settings } from 'lucide';
87
87
 
88
88
  export const appConfig: ApplicationConfig = {
89
89
  providers: [
90
- provideTheme(), // theme service + persistence
90
+ provideTheme(), // applies + persists the theme
91
91
  provideNativeDateAdapter(), // calendar / date pickers
92
92
  provideTwLucideIcons({ Star, Search, Settings }), // register named icons
93
93
  provideTwDialog(), // tw-dialog overlay service
@@ -101,7 +101,7 @@ You only need the providers for the features you use:
101
101
 
102
102
  | Provider | Required for | Entry point |
103
103
  |---|---|---|
104
- | `provideTheme()` | runtime theme switching / `ThemeService` (optional — see below) | `@cdevhub/ngx-tw/theme` |
104
+ | `provideTheme()` | explicit / persisted theme switching and `ThemeService` (optional — pure-CSS dark mode needs none) | `@cdevhub/ngx-tw/theme` |
105
105
  | `provideNativeDateAdapter()` | `calendar`, `date-picker`, `date-range-picker` | `@cdevhub/ngx-tw/calendar` |
106
106
  | `provideTwLucideIcons()` / `provideTwIcons()` | `<tw-icon>` and any component that renders glyphs | `@cdevhub/ngx-tw/icon/lucide`, `@cdevhub/ngx-tw/icon` |
107
107
  | `provideTwDialog()` | imperative dialogs via the `TwDialog` service | `@cdevhub/ngx-tw/dialog` |
@@ -153,13 +153,25 @@ library — including dark mode and brand palettes — by overriding those token
153
153
 
154
154
  ### Dark mode & runtime switching
155
155
 
156
- Dark mode is driven by a `data-theme` attribute on `<html>` (with a
157
- `prefers-color-scheme` fallback when no attribute is set), so the simplest setup
158
- needs **no JavaScript** — the imported theme CSS already responds to the OS
159
- preference.
156
+ Dark mode is driven by a `data-theme` attribute (with a `prefers-color-scheme`
157
+ fallback when no attribute is set), so the simplest setup needs **no
158
+ JavaScript** — the imported theme CSS already responds to the OS preference.
160
159
 
161
- For explicit, persisted switching, register `provideTheme()` and inject
162
- `ThemeService`:
160
+ All three schemes ship as element-agnostic `[data-theme="…"]` blocks, so the
161
+ attribute works on `<html>` *and* on any element in the page — including
162
+ switching a subtree back to `light` inside a dark page.
163
+
164
+ For explicit, persisted switching, register `provideTheme()`:
165
+
166
+ ```ts
167
+ import { provideTheme } from '@cdevhub/ngx-tw/theme';
168
+
169
+ bootstrapApplication(App, { providers: [provideTheme()] });
170
+ ```
171
+
172
+ `provideTheme()` is self-sufficient: it constructs `ThemeService` at bootstrap,
173
+ so the stored preference is applied on first paint whether or not anything
174
+ injects the service. Inject it where you need to read or change the theme:
163
175
 
164
176
  ```ts
165
177
  import { ThemeService } from '@cdevhub/ngx-tw/theme';
@@ -181,11 +193,62 @@ export class ThemeToggle {
181
193
  }
182
194
  ```
183
195
 
184
- `ThemeService` writes the active theme to `data-theme` on `documentElement`,
185
- tracks the OS preference, and persists the selection to `localStorage`
186
- (`ngx-tw-theme` by default). Configure via `provideTheme({ defaultTheme,
187
- storageKey, attribute, target })`. A `[twTheme]` directive is also available to
188
- scope a theme to a subtree.
196
+ `ThemeService` writes the active theme to `data-theme` on `documentElement` and
197
+ tracks the OS preference `prefers-color-scheme: dark` resolves `'system'` to
198
+ `dark`, and `prefers-contrast: more` resolves it to `high-contrast` when dark is
199
+ not also requested (the shipped high-contrast scheme is light-based, so contrast
200
+ never overrides a dark preference). Configure via `provideTheme({ defaultTheme,
201
+ storageKey, attribute, target })`.
202
+
203
+ **Storage is written only by `setTheme()` / `cycleTheme()`.** Providing the
204
+ service never touches `localStorage`, so `defaultTheme` keeps applying until the
205
+ user actually picks something, and apps under a storage-consent flow can
206
+ register the provider before consent is granted.
207
+
208
+ ### Scoping a theme to a subtree
209
+
210
+ The `[twTheme]` directive writes `data-theme` on its host, and the token blocks
211
+ re-resolve there and cascade into the subtree — in any direction:
212
+
213
+ ```html
214
+ <div [twTheme]="'light'" class="bg-surface text-fg p-4">
215
+ Always light, even on a dark page.
216
+ </div>
217
+ ```
218
+
219
+ Note the directive writes the literal `data-theme` attribute, which is what the
220
+ shipped CSS keys off. `provideTheme({ attribute })` renames the attribute
221
+ `ThemeService` writes to the document, but a renamed attribute needs matching
222
+ CSS of your own.
223
+
224
+ ### Avoiding a theme flash on reload
225
+
226
+ The CSS fallback already gives a flash-free first paint to anyone who never
227
+ picked a theme. An **explicit** choice that disagrees with the OS is different:
228
+ `ThemeService` is application JavaScript, so the browser paints the OS-derived
229
+ theme before the bundle runs. Add the standard inline bootstrap to `index.html`
230
+ — it must be inline in `<head>`, before any stylesheet:
231
+
232
+ ```html
233
+ <head>
234
+ <script>try{var t=localStorage.getItem('ngx-tw-theme');if(t&&t!=='system')document.documentElement.setAttribute('data-theme',t)}catch(e){}</script>
235
+ </head>
236
+ ```
237
+
238
+ The same string is exported as `TW_THEME_BOOTSTRAP_SCRIPT` for SSR or
239
+ `index.html`-transform setups, built from the same defaults `ThemeService` uses
240
+ so the key and attribute cannot drift:
241
+
242
+ ```ts
243
+ import { TW_THEME_BOOTSTRAP_SCRIPT } from '@cdevhub/ngx-tw/theme';
244
+
245
+ const head = `<script>${TW_THEME_BOOTSTRAP_SCRIPT}</script>`;
246
+ ```
247
+
248
+ A stored `'system'` deliberately writes nothing, so the CSS
249
+ `prefers-color-scheme` fallback keeps deciding. The snippet assumes the default
250
+ `target: 'documentElement'` — a `<head>` script runs before `<body>` exists — and
251
+ if you overrode `storageKey` or `attribute`, adapt the literal snippet to match.
189
252
 
190
253
  ## Icons
191
254
 
@@ -326,8 +389,8 @@ for full API tables and examples.
326
389
  | `@cdevhub/ngx-tw/<component>` | One per component (preferred — tree-shakeable) |
327
390
  | `@cdevhub/ngx-tw` | Catch-all re-export of every public API (convenience) |
328
391
  | `@cdevhub/ngx-tw/core` | Shared types (`TwColor`, `TwSize`) and `TW_ERROR_STATE_MATCHER` |
329
- | `@cdevhub/ngx-tw/theme` | `ThemeService`, `provideTheme`, `[twTheme]`, theme types |
330
- | `@cdevhub/ngx-tw/theme/index.css` | Default semantic theme stylesheet (asset) |
392
+ | `@cdevhub/ngx-tw/theme` | `ThemeService`, `provideTheme`, `[twTheme]`, `TW_THEME_BOOTSTRAP_SCRIPT`, theme types |
393
+ | `@cdevhub/ngx-tw/theme/index.css` | Default semantic theme stylesheet — the same directory ships as a copied CSS asset *and* as the TypeScript entry point above |
331
394
  | `@cdevhub/ngx-tw/icon/lucide` | `provideTwLucideIcons`, `fromLucideIcon` |
332
395
  | `@cdevhub/ngx-tw/calendar/luxon` | Luxon date adapter |
333
396
  | `@cdevhub/ngx-tw/calendar/testing` | Calendar test harnesses |
@@ -3,6 +3,10 @@ import { input, booleanAttribute, computed, forwardRef, ChangeDetectionStrategy,
3
3
  import { tv } from 'tailwind-variants';
4
4
  import { CollapsibleGroupComponent } from '@cdevhub/ngx-tw/collapsible';
5
5
 
6
+ /** Maps every legacy spelling onto its canonical replacement. */
7
+ const VARIANT_ALIASES = {
8
+ bordered: 'outline',
9
+ };
6
10
  // ── tv() config ──
7
11
  const accordionVariants = tv({
8
12
  slots: {
@@ -13,7 +17,7 @@ const accordionVariants = tv({
13
17
  default: {
14
18
  root: 'rounded-lg overflow-hidden divide-y divide-border',
15
19
  },
16
- bordered: {
20
+ outline: {
17
21
  root: 'rounded-lg overflow-hidden divide-y divide-border border border-border',
18
22
  },
19
23
  ghost: {
@@ -48,21 +52,28 @@ class AccordionComponent extends CollapsibleGroupComponent {
48
52
  /** Open mode. `'single'` allows one panel open at a time; `'multiple'` allows many. Defaults to `'single'`. */
49
53
  type = input('single', /* @ts-ignore */
50
54
  ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
51
- /** Visual style of the accordion container. Defaults to `'default'`. */
55
+ /** Visual style of the accordion container. Defaults to `'default'`. `'bordered'` is a deprecated alias for `'outline'` and renders identically. */
52
56
  variant = input('default', /* @ts-ignore */
53
57
  ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
54
58
  /** In `'single'` mode, whether re-clicking the open panel closes it. Defaults to `true` — accordions are collapsible by definition; opt-out only. */
55
59
  collapsible = input(true, { ...(ngDevMode ? { debugName: "collapsible" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
56
- /** Accessible name for the accordion. Use when surrounding context doesn't make the purpose obvious. */
60
+ /** Accessible name for the accordion. Use when surrounding context doesn't make the purpose obvious. Defaults to `undefined`. Alias: `aria-label`. */
57
61
  ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
58
- /** ID(s) of element(s) that label the accordion. Use instead of `aria-label` when a visible heading is available. */
62
+ /** ID(s) of element(s) that label the accordion. Use instead of `aria-label` when a visible heading is available. Defaults to `undefined`. Alias: `aria-labelledby`. */
59
63
  ariaLabelledby = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabelledby" } : /* istanbul ignore next */ {}), alias: 'aria-labelledby' });
60
64
  // ── Inherited-binding overrides ──
61
65
  /** @internal APG: accordions don't carry `role="group"`. */
62
66
  hostRole = computed(() => null, /* @ts-ignore */
63
67
  ...(ngDevMode ? [{ debugName: "hostRole" }] : /* istanbul ignore next */ []));
68
+ /** @internal Canonical variant with legacy spellings folded in. */
69
+ resolvedVariant = computed(() => {
70
+ const v = this.variant();
71
+ return (VARIANT_ALIASES[v] ??
72
+ v);
73
+ }, /* @ts-ignore */
74
+ ...(ngDevMode ? [{ debugName: "resolvedVariant" }] : /* istanbul ignore next */ []));
64
75
  /** @internal Variant-driven container classes; replaces the parent's default group string. */
65
- hostClasses = computed(() => accordionVariants({ variant: this.variant() }).root(), /* @ts-ignore */
76
+ hostClasses = computed(() => accordionVariants({ variant: this.resolvedVariant() }).root(), /* @ts-ignore */
66
77
  ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
67
78
  // ── Virtual-hook overrides ──
68
79
  /** @internal Drive single-open-panel behaviour from `type`, ignoring the inherited `accordion` input. */
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-accordion.mjs","sources":["../../../projects/ngx-tw/accordion/accordion.ts","../../../projects/ngx-tw/accordion/cdevhub-ngx-tw-accordion.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n forwardRef,\n input,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport { CollapsibleGroupComponent } from '@cdevhub/ngx-tw/collapsible';\n\n/** Open mode of the accordion. */\nexport type AccordionType = 'single' | 'multiple';\n\n/** Visual style of the accordion container. */\nexport type AccordionVariant = 'default' | 'bordered' | 'ghost';\n\n// ── tv() config ──\n\nconst accordionVariants = tv(\n {\n slots: {\n root: 'block',\n },\n variants: {\n variant: {\n default: {\n root: 'rounded-lg overflow-hidden divide-y divide-border',\n },\n bordered: {\n root: 'rounded-lg overflow-hidden divide-y divide-border border border-border',\n },\n ghost: {\n root: '',\n },\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n {\n twMerge: true,\n },\n);\n\n// ── AccordionComponent ──\n\n/**\n * Accordion — single- or multiple-open-panel group built on top of\n * `<tw-collapsible>` children. Extends `CollapsibleGroupComponent` to inherit\n * the keyboard navigation, value-sync, and toggle wiring; overrides the\n * virtual `isAccordionMode()` / `canCollapseSingleMode()` hooks so the\n * single-mode behaviour is driven from the local `type` + `collapsible`\n * inputs instead of the parent's `accordion` input. The `hostRole` and\n * `hostClasses` signals are also overridden so the accordion drops APG's\n * `role=\"group\"` and renders the variant-driven container classes.\n *\n * The `providers` block exposes the accordion instance to its descendant\n * collapsibles via the `CollapsibleGroupComponent` DI token — Angular DI\n * uses class identity rather than the prototype chain, so the explicit\n * `useExisting` is required even though `AccordionComponent extends\n * CollapsibleGroupComponent`.\n */\n@Component({\n selector: 'tw-accordion',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n // `[class]` + `[attr.role]` are inherited from the parent's host metadata\n // and read the overridden `hostClasses` / `hostRole` computeds below.\n // We only need to add accordion-specific bindings here.\n '[attr.aria-multiselectable]': \"type() === 'multiple' ? 'true' : 'false'\",\n '[attr.aria-label]': 'ariaLabel() ?? null',\n '[attr.aria-labelledby]': 'ariaLabelledby() ?? null',\n },\n template: `<ng-content />`,\n providers: [\n {\n provide: CollapsibleGroupComponent,\n useExisting: forwardRef(() => AccordionComponent),\n },\n ],\n})\nexport class AccordionComponent extends CollapsibleGroupComponent {\n /** Open mode. `'single'` allows one panel open at a time; `'multiple'` allows many. Defaults to `'single'`. */\n readonly type = input<AccordionType>('single');\n\n /** Visual style of the accordion container. Defaults to `'default'`. */\n readonly variant = input<AccordionVariant>('default');\n\n /** In `'single'` mode, whether re-clicking the open panel closes it. Defaults to `true` — accordions are collapsible by definition; opt-out only. */\n readonly collapsible = input(true, { transform: booleanAttribute });\n\n /** Accessible name for the accordion. Use when surrounding context doesn't make the purpose obvious. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID(s) of element(s) that label the accordion. Use instead of `aria-label` when a visible heading is available. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n // ── Inherited-binding overrides ──\n\n /** @internal APG: accordions don't carry `role=\"group\"`. */\n override readonly hostRole = computed<string | null>(() => null);\n\n /** @internal Variant-driven container classes; replaces the parent's default group string. */\n override readonly hostClasses = computed(() =>\n accordionVariants({ variant: this.variant() }).root(),\n );\n\n // ── Virtual-hook overrides ──\n\n /** @internal Drive single-open-panel behaviour from `type`, ignoring the inherited `accordion` input. */\n protected override isAccordionMode(): boolean {\n return this.type() === 'single';\n }\n\n /** @internal Honour the `collapsible` opt-out in single mode. */\n protected override canCollapseSingleMode(): boolean {\n return this.collapsible();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-accordion.mjs","sources":["../../../projects/ngx-tw/accordion/accordion.ts","../../../projects/ngx-tw/accordion/cdevhub-ngx-tw-accordion.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n forwardRef,\n input,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport { CollapsibleGroupComponent } from '@cdevhub/ngx-tw/collapsible';\n\n/** Open mode of the accordion. */\nexport type AccordionType = 'single' | 'multiple';\n\n/** Visual style of the accordion container. */\nexport type AccordionVariant = 'default' | 'outline' | 'ghost' | AccordionVariantLegacy;\n\n/**\n * Legacy `variant` spellings, kept so existing templates keep compiling.\n * @deprecated `'bordered'` is an alias for `'outline'` and renders identically.\n * It will be removed in the next major — prefer `'outline'`.\n */\nexport type AccordionVariantLegacy = 'bordered';\n\n/** Canonical `variant` spellings — the set `tv()` actually keys on. */\ntype AccordionVariantCanonical = Exclude<AccordionVariant, AccordionVariantLegacy>;\n\n/** Maps every legacy spelling onto its canonical replacement. */\nconst VARIANT_ALIASES: Readonly<\n Record<AccordionVariantLegacy, AccordionVariantCanonical>\n> = {\n bordered: 'outline',\n};\n\n// ── tv() config ──\n\nconst accordionVariants = tv(\n {\n slots: {\n root: 'block',\n },\n variants: {\n variant: {\n default: {\n root: 'rounded-lg overflow-hidden divide-y divide-border',\n },\n outline: {\n root: 'rounded-lg overflow-hidden divide-y divide-border border border-border',\n },\n ghost: {\n root: '',\n },\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n {\n twMerge: true,\n },\n);\n\n// ── AccordionComponent ──\n\n/**\n * Accordion — single- or multiple-open-panel group built on top of\n * `<tw-collapsible>` children. Extends `CollapsibleGroupComponent` to inherit\n * the keyboard navigation, value-sync, and toggle wiring; overrides the\n * virtual `isAccordionMode()` / `canCollapseSingleMode()` hooks so the\n * single-mode behaviour is driven from the local `type` + `collapsible`\n * inputs instead of the parent's `accordion` input. The `hostRole` and\n * `hostClasses` signals are also overridden so the accordion drops APG's\n * `role=\"group\"` and renders the variant-driven container classes.\n *\n * The `providers` block exposes the accordion instance to its descendant\n * collapsibles via the `CollapsibleGroupComponent` DI token — Angular DI\n * uses class identity rather than the prototype chain, so the explicit\n * `useExisting` is required even though `AccordionComponent extends\n * CollapsibleGroupComponent`.\n */\n@Component({\n selector: 'tw-accordion',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n // `[class]` + `[attr.role]` are inherited from the parent's host metadata\n // and read the overridden `hostClasses` / `hostRole` computeds below.\n // We only need to add accordion-specific bindings here.\n '[attr.aria-multiselectable]': \"type() === 'multiple' ? 'true' : 'false'\",\n '[attr.aria-label]': 'ariaLabel() ?? null',\n '[attr.aria-labelledby]': 'ariaLabelledby() ?? null',\n },\n template: `<ng-content />`,\n providers: [\n {\n provide: CollapsibleGroupComponent,\n useExisting: forwardRef(() => AccordionComponent),\n },\n ],\n})\nexport class AccordionComponent extends CollapsibleGroupComponent {\n /** Open mode. `'single'` allows one panel open at a time; `'multiple'` allows many. Defaults to `'single'`. */\n readonly type = input<AccordionType>('single');\n\n /** Visual style of the accordion container. Defaults to `'default'`. `'bordered'` is a deprecated alias for `'outline'` and renders identically. */\n readonly variant = input<AccordionVariant>('default');\n\n /** In `'single'` mode, whether re-clicking the open panel closes it. Defaults to `true` — accordions are collapsible by definition; opt-out only. */\n readonly collapsible = input(true, { transform: booleanAttribute });\n\n /** Accessible name for the accordion. Use when surrounding context doesn't make the purpose obvious. Defaults to `undefined`. Alias: `aria-label`. */\n readonly ariaLabel = input<string | undefined>(undefined, { alias: 'aria-label' });\n\n /** ID(s) of element(s) that label the accordion. Use instead of `aria-label` when a visible heading is available. Defaults to `undefined`. Alias: `aria-labelledby`. */\n readonly ariaLabelledby = input<string | undefined>(undefined, { alias: 'aria-labelledby' });\n\n // ── Inherited-binding overrides ──\n\n /** @internal APG: accordions don't carry `role=\"group\"`. */\n override readonly hostRole = computed<string | null>(() => null);\n\n /** @internal Canonical variant with legacy spellings folded in. */\n private readonly resolvedVariant = computed<AccordionVariantCanonical>(() => {\n const v = this.variant();\n return (\n (VARIANT_ALIASES as Record<string, AccordionVariantCanonical | undefined>)[v] ??\n (v as AccordionVariantCanonical)\n );\n });\n\n /** @internal Variant-driven container classes; replaces the parent's default group string. */\n override readonly hostClasses = computed(() =>\n accordionVariants({ variant: this.resolvedVariant() }).root(),\n );\n\n // ── Virtual-hook overrides ──\n\n /** @internal Drive single-open-panel behaviour from `type`, ignoring the inherited `accordion` input. */\n protected override isAccordionMode(): boolean {\n return this.type() === 'single';\n }\n\n /** @internal Honour the `collapsible` opt-out in single mode. */\n protected override canCollapseSingleMode(): boolean {\n return this.collapsible();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -6,7 +6,14 @@ import { tv } from 'tailwind-variants';
6
6
  * Injection token used by `AvatarGroupComponent` to propagate its size
7
7
  * to child avatars. When present, overrides the individual avatar's `size` input.
8
8
  */
9
- const AVATAR_GROUP_SIZE = new InjectionToken('AVATAR_GROUP_SIZE');
9
+ const TW_AVATAR_GROUP_SIZE = new InjectionToken('TW_AVATAR_GROUP_SIZE');
10
+ /**
11
+ * @deprecated Renamed to {@link TW_AVATAR_GROUP_SIZE} for consistency with every
12
+ * other ngx-tw injection token. This is the *same token instance*, not a copy —
13
+ * providing under either name and injecting under the other resolves — so the
14
+ * rename is safe to adopt incrementally. Removed in the next major.
15
+ */
16
+ const AVATAR_GROUP_SIZE = TW_AVATAR_GROUP_SIZE;
10
17
  const avatarVariants = tv({
11
18
  slots: {
12
19
  root: 'relative inline-flex items-center justify-center overflow-hidden shrink-0',
@@ -21,14 +28,19 @@ const avatarVariants = tv({
21
28
  },
22
29
  variants: {
23
30
  size: {
31
+ // `root` follows the container scale — avatars are surfaces, not glyphs
32
+ // (see CLAUDE.md icon sizing). `status` follows CLAUDE.md's **dot
33
+ // indicator** sub-scale (2 / 2.5 / 3 / 3.5 / 4), the same five-step 2px
34
+ // cadence `badge-dot` was corrected onto. It previously rendered
35
+ // 2/2/2.5/3/3, which duplicated `xs`→`sm` and froze `lg`/`xl` at 12px,
36
+ // leaving two of the five advertised steps dead.
24
37
  xs: { root: 'size-6 text-xs', status: 'size-2' },
25
- sm: { root: 'size-8 text-xs', status: 'size-2' },
26
- md: { root: 'size-10 text-sm', status: 'size-2.5' },
27
- lg: { root: 'size-12 text-sm', status: 'size-3' },
28
- // Container scale — avatars are surfaces, not glyphs (see CLAUDE.md icon sizing).
38
+ sm: { root: 'size-8 text-xs', status: 'size-2.5' },
39
+ md: { root: 'size-10 text-sm', status: 'size-3' },
40
+ lg: { root: 'size-12 text-sm', status: 'size-3.5' },
29
41
  // The xl avatar lands at 64px, which sits above the glyph scale's ceiling
30
42
  // (size-10 / 40px) because avatars host imagery, initials, or icon glyphs.
31
- xl: { root: 'size-16 text-base', status: 'size-3' },
43
+ xl: { root: 'size-16 text-base', status: 'size-4' },
32
44
  },
33
45
  rounded: {
34
46
  full: { root: 'rounded-full', status: 'bottom-0 right-0' },
@@ -91,7 +103,7 @@ class AvatarComponent {
91
103
  */
92
104
  groupHidden = signal(false, /* @ts-ignore */
93
105
  ...(ngDevMode ? [{ debugName: "groupHidden" }] : /* istanbul ignore next */ []));
94
- groupSize = inject(AVATAR_GROUP_SIZE, { optional: true });
106
+ groupSize = inject(TW_AVATAR_GROUP_SIZE, { optional: true });
95
107
  constructor() {
96
108
  if (isDevMode()) {
97
109
  effect(() => {
@@ -228,9 +240,8 @@ class AvatarGroupComponent {
228
240
  /** Maximum number of avatars to display. Remaining count is shown as a "+N" overflow indicator. Defaults to `null` (show all). */
229
241
  max = input(null, /* @ts-ignore */
230
242
  ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
231
- /** Accessible label for the avatar group. Defaults to `'Avatar group'` (English) — override for localisation. */
232
- ariaLabel = input('Avatar group', /* @ts-ignore */
233
- ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
243
+ /** Accessible label for the avatar group, mirrored to `aria-label`. Defaults to `'Avatar group'` (English) — override for localisation. */
244
+ ariaLabel = input('Avatar group', { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
234
245
  avatars = contentChildren(AvatarComponent, /* @ts-ignore */
235
246
  ...(ngDevMode ? [{ debugName: "avatars" }] : /* istanbul ignore next */ []));
236
247
  overflowCount = computed(() => {
@@ -261,9 +272,9 @@ class AvatarGroupComponent {
261
272
  }, /* @ts-ignore */
262
273
  ...(ngDevMode ? [{ debugName: "visibilityEffect" }] : /* istanbul ignore next */ []));
263
274
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: AvatarGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
264
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: AvatarGroupComponent, isStandalone: true, selector: "tw-avatar-group", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "class": "hostClasses()", "attr.aria-label": "ariaLabel()" } }, providers: [
275
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.7", type: AvatarGroupComponent, isStandalone: true, selector: "tw-avatar-group", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "class": "hostClasses()", "attr.aria-label": "ariaLabel()" } }, providers: [
265
276
  {
266
- provide: AVATAR_GROUP_SIZE,
277
+ provide: TW_AVATAR_GROUP_SIZE,
267
278
  useFactory: () => {
268
279
  const group = inject(AvatarGroupComponent);
269
280
  return () => group.size();
@@ -283,7 +294,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
283
294
  changeDetection: ChangeDetectionStrategy.OnPush,
284
295
  providers: [
285
296
  {
286
- provide: AVATAR_GROUP_SIZE,
297
+ provide: TW_AVATAR_GROUP_SIZE,
287
298
  useFactory: () => {
288
299
  const group = inject(AvatarGroupComponent);
289
300
  return () => group.size();
@@ -302,11 +313,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
302
313
  }
303
314
  `,
304
315
  }]
305
- }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], avatars: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => AvatarComponent), { isSignal: true }] }] } });
316
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], avatars: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => AvatarComponent), { isSignal: true }] }] } });
306
317
 
307
318
  /**
308
319
  * Generated bundle index. Do not edit.
309
320
  */
310
321
 
311
- export { AVATAR_GROUP_SIZE, AvatarComponent, AvatarGroupComponent };
322
+ export { AVATAR_GROUP_SIZE, AvatarComponent, AvatarGroupComponent, TW_AVATAR_GROUP_SIZE };
312
323
  //# sourceMappingURL=cdevhub-ngx-tw-avatar.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-avatar.mjs","sources":["../../../projects/ngx-tw/avatar/avatar.ts","../../../projects/ngx-tw/avatar/cdevhub-ngx-tw-avatar.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChildren,\n effect,\n ElementRef,\n InjectionToken,\n inject,\n input,\n isDevMode,\n linkedSignal,\n output,\n signal,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor, TwSize } from '@cdevhub/ngx-tw/core';\n\n/** Status indicator for the avatar. */\nexport type AvatarStatus = 'online' | 'busy' | 'away' | 'offline';\n\n/** Border radius shape for the avatar. */\nexport type AvatarRounded = 'full' | 'lg' | 'none';\n\n/** Decorative axes bundled into a single avatar input. */\nexport interface AvatarAppearance {\n /** Border-radius shape. Defaults to `'full'`. */\n rounded?: AvatarRounded;\n /** Status indicator dot. Defaults to `null` (no indicator). */\n status?: AvatarStatus | null;\n}\n\n/**\n * Injection token used by `AvatarGroupComponent` to propagate its size\n * to child avatars. When present, overrides the individual avatar's `size` input.\n */\nexport const AVATAR_GROUP_SIZE = new InjectionToken<() => TwSize>('AVATAR_GROUP_SIZE');\n\nconst avatarVariants = tv({\n slots: {\n root: 'relative inline-flex items-center justify-center overflow-hidden shrink-0',\n img: 'size-full object-cover',\n initials: 'font-medium select-none uppercase',\n // size-[60%]: keeps the fallback glyph proportional to the avatar; no Tailwind size token expresses a percentage of parent.\n // Container scale — avatars are surfaces, not glyphs (see CLAUDE.md icon sizing).\n // The fallback child glyph is sized as a percentage of the avatar container\n // so it scales proportionally across every TwSize.\n fallback: 'size-[60%] text-fg-subtle',\n status: 'absolute rounded-full ring-2 ring-surface',\n },\n variants: {\n size: {\n xs: { root: 'size-6 text-xs', status: 'size-2' },\n sm: { root: 'size-8 text-xs', status: 'size-2' },\n md: { root: 'size-10 text-sm', status: 'size-2.5' },\n lg: { root: 'size-12 text-sm', status: 'size-3' },\n // Container scale — avatars are surfaces, not glyphs (see CLAUDE.md icon sizing).\n // The xl avatar lands at 64px, which sits above the glyph scale's ceiling\n // (size-10 / 40px) because avatars host imagery, initials, or icon glyphs.\n xl: { root: 'size-16 text-base', status: 'size-3' },\n },\n rounded: {\n full: { root: 'rounded-full', status: 'bottom-0 right-0' },\n lg: { root: 'rounded-lg', status: '-bottom-0.5 -right-0.5' },\n none: { root: 'rounded-none', status: '-bottom-0.5 -right-0.5' },\n },\n color: {\n primary: { root: 'bg-primary-100 text-primary-700' },\n secondary: { root: 'bg-secondary-100 text-secondary-700' },\n accent: { root: 'bg-accent-100 text-accent-700' },\n neutral: { root: 'bg-surface-muted text-fg-muted' },\n info: { root: 'bg-info-100 text-info-700' },\n success: { root: 'bg-success-100 text-success-700' },\n warning: { root: 'bg-warning-100 text-warning-700' },\n error: { root: 'bg-error-100 text-error-700' },\n },\n },\n defaultVariants: {\n size: 'md',\n rounded: 'full',\n color: 'neutral',\n },\n}, {\n twMerge: true,\n});\n\nconst statusColorMap: Record<AvatarStatus, string> = {\n online: 'bg-success-500',\n busy: 'bg-error-500',\n away: 'bg-warning-500',\n offline: 'bg-fg-subtle',\n};\n\n@Component({\n selector: 'tw-avatar',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n '[attr.role]': 'displayMode() !== \"image\" ? \"img\" : null',\n '[attr.aria-label]': 'displayMode() !== \"image\" && alt() ? alt() : null',\n // Only hide non-image avatars without alt text from AT. Image-mode avatars\n // expose their `alt` attribute directly on the underlying `<img>`; hiding\n // the host would suppress the image from assistive tech entirely.\n '[attr.aria-hidden]': 'displayMode() !== \"image\" && !alt() ? \"true\" : null',\n '[attr.hidden]': 'groupHidden() ? \"\" : null',\n },\n template: `\n @switch (displayMode()) {\n @case ('image') {\n <img\n [src]=\"src()\"\n [alt]=\"alt()\"\n [class]=\"imgClasses()\"\n (load)=\"imageLoaded.set(true)\"\n (error)=\"onImageError($event)\"\n />\n }\n @case ('initials') {\n <span [class]=\"initialsClasses()\">{{ initials() }}</span>\n }\n @case ('fallback') {\n <ng-content>\n <svg [class]=\"fallbackClasses()\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n </ng-content>\n }\n }\n @if (resolvedStatus()) {\n <span [class]=\"statusClasses()\" aria-hidden=\"true\"></span>\n }\n `,\n})\nexport class AvatarComponent {\n /** URL of the avatar image. When set, renders an `<img>`. Falls back to initials or projected content on load error. Defaults to `null`. */\n readonly src = input<string | null>(null);\n\n /** Alt text for the avatar image. Also used as `aria-label` for non-image avatars. Defaults to `''`. */\n readonly alt = input('');\n\n /** Text initials displayed when no image is available (1-2 characters). Rendered uppercase regardless of input casing. Defaults to `null`. */\n readonly initials = input<string | null>(null);\n\n /** Semantic color for the initials/icon background. Only applies when no image is shown. Defaults to `'neutral'`. */\n readonly color = input<TwColor>('neutral');\n\n /** Controls the avatar dimensions. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Bundles decorative axes: `rounded` (shape) and `status` (indicator dot). Defaults to `{ rounded: 'full', status: null }`. */\n readonly appearance = input<AvatarAppearance>({});\n\n /** Fires when the avatar image fails to load. Payload is the native `Event` from the `<img>` `error` event. */\n readonly imageError = output<Event>();\n\n /** @internal */\n readonly elementRef = inject(ElementRef<HTMLElement>);\n\n /**\n * @internal\n * Toggled by `AvatarGroupComponent` to hide overflow avatars. Drives the\n * host `[attr.hidden]` binding so the group's effect stays declarative\n * (no direct `style.display` mutation).\n */\n readonly groupHidden = signal(false);\n\n private readonly groupSize = inject(AVATAR_GROUP_SIZE, { optional: true });\n\n constructor() {\n if (isDevMode()) {\n effect(() => {\n if (this.displayMode() === 'image' && !this.alt()) {\n console.warn(\n '<tw-avatar> rendered as image without alt text — provide alt for accessibility',\n );\n }\n });\n }\n }\n\n readonly resolvedSize = computed(() => this.groupSize ? this.groupSize() : this.size());\n readonly resolvedRounded = computed<AvatarRounded>(() => this.appearance().rounded ?? 'full');\n readonly resolvedStatus = computed<AvatarStatus | null>(() => this.appearance().status ?? null);\n\n readonly imageLoaded = linkedSignal<string | null, boolean | null>({\n source: this.src,\n computation: () => null,\n });\n\n readonly displayMode = computed<'image' | 'initials' | 'fallback'>(() => {\n if (this.src() && this.imageLoaded() !== false) return 'image';\n if (this.initials()) return 'initials';\n return 'fallback';\n });\n\n private readonly variantResult = computed(() =>\n avatarVariants({\n size: this.resolvedSize(),\n rounded: this.resolvedRounded(),\n color: this.color(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly imgClasses = computed(() => this.variantResult().img());\n readonly initialsClasses = computed(() => this.variantResult().initials());\n readonly fallbackClasses = computed(() => this.variantResult().fallback());\n\n readonly statusClasses = computed(() => {\n const base = this.variantResult().status();\n const statusValue = this.resolvedStatus();\n if (!statusValue) return base;\n return `${base} ${statusColorMap[statusValue]}`;\n });\n\n protected onImageError(event: Event): void {\n this.imageLoaded.set(false);\n this.imageError.emit(event);\n }\n}\n\nconst groupOverlapMap: Record<TwSize, string> = {\n xs: '[&>tw-avatar+tw-avatar]:-ml-1.5 [&>tw-avatar+span]:-ml-1.5',\n sm: '[&>tw-avatar+tw-avatar]:-ml-1.5 [&>tw-avatar+span]:-ml-1.5',\n md: '[&>tw-avatar+tw-avatar]:-ml-2 [&>tw-avatar+span]:-ml-2',\n lg: '[&>tw-avatar+tw-avatar]:-ml-3 [&>tw-avatar+span]:-ml-3',\n xl: '[&>tw-avatar+tw-avatar]:-ml-3 [&>tw-avatar+span]:-ml-3',\n};\n\n@Component({\n selector: 'tw-avatar-group',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: AVATAR_GROUP_SIZE,\n useFactory: () => {\n const group = inject(AvatarGroupComponent);\n return () => group.size();\n },\n },\n ],\n host: {\n role: 'group',\n '[class]': 'hostClasses()',\n '[attr.aria-label]': 'ariaLabel()',\n },\n template: `\n <ng-content />\n @if (overflowCount() > 0) {\n <span [class]=\"overflowClasses()\">+{{ overflowCount() }}</span>\n }\n `,\n})\nexport class AvatarGroupComponent {\n /** Sets the size for all child avatars. Individual avatar size inputs are ignored when inside a group. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Maximum number of avatars to display. Remaining count is shown as a \"+N\" overflow indicator. Defaults to `null` (show all). */\n readonly max = input<number | null>(null);\n\n /** Accessible label for the avatar group. Defaults to `'Avatar group'` (English) — override for localisation. */\n readonly ariaLabel = input('Avatar group');\n\n private readonly avatars = contentChildren(AvatarComponent);\n\n readonly overflowCount = computed(() => {\n const all = this.avatars();\n const maxVal = this.max();\n if (maxVal === null || maxVal >= all.length) return 0;\n return all.length - maxVal;\n });\n\n readonly hostClasses = computed(() => {\n const s = this.size();\n return `inline-flex items-center [&>tw-avatar]:ring-2 [&>tw-avatar]:ring-surface ${groupOverlapMap[s]}`;\n });\n\n readonly overflowClasses = computed(() => {\n const s = this.size();\n const sizeClasses = avatarVariants({ size: s, rounded: 'full', color: 'neutral' });\n return `${sizeClasses.root()} bg-surface-muted text-fg-muted font-medium ring-2 ring-surface`;\n });\n\n private readonly visibilityEffect = effect(() => {\n const all = this.avatars();\n const maxVal = this.max();\n all.forEach((avatar, index) => {\n avatar.groupHidden.set(maxVal !== null && index >= maxVal);\n });\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-avatar.mjs","sources":["../../../projects/ngx-tw/avatar/avatar.ts","../../../projects/ngx-tw/avatar/cdevhub-ngx-tw-avatar.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChildren,\n effect,\n ElementRef,\n InjectionToken,\n inject,\n input,\n isDevMode,\n linkedSignal,\n output,\n signal,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor, TwSize } from '@cdevhub/ngx-tw/core';\n\n/** Status indicator for the avatar. */\nexport type AvatarStatus = 'online' | 'busy' | 'away' | 'offline';\n\n/** Border radius shape for the avatar. */\nexport type AvatarRounded = 'full' | 'lg' | 'none';\n\n/** Decorative axes bundled into a single avatar input. */\nexport interface AvatarAppearance {\n /** Border-radius shape. Defaults to `'full'`. */\n rounded?: AvatarRounded;\n /** Status indicator dot. Defaults to `null` (no indicator). */\n status?: AvatarStatus | null;\n}\n\n/**\n * Injection token used by `AvatarGroupComponent` to propagate its size\n * to child avatars. When present, overrides the individual avatar's `size` input.\n */\nexport const TW_AVATAR_GROUP_SIZE = new InjectionToken<() => TwSize>('TW_AVATAR_GROUP_SIZE');\n\n/**\n * @deprecated Renamed to {@link TW_AVATAR_GROUP_SIZE} for consistency with every\n * other ngx-tw injection token. This is the *same token instance*, not a copy —\n * providing under either name and injecting under the other resolves — so the\n * rename is safe to adopt incrementally. Removed in the next major.\n */\nexport const AVATAR_GROUP_SIZE = TW_AVATAR_GROUP_SIZE;\n\nconst avatarVariants = tv({\n slots: {\n root: 'relative inline-flex items-center justify-center overflow-hidden shrink-0',\n img: 'size-full object-cover',\n initials: 'font-medium select-none uppercase',\n // size-[60%]: keeps the fallback glyph proportional to the avatar; no Tailwind size token expresses a percentage of parent.\n // Container scale — avatars are surfaces, not glyphs (see CLAUDE.md icon sizing).\n // The fallback child glyph is sized as a percentage of the avatar container\n // so it scales proportionally across every TwSize.\n fallback: 'size-[60%] text-fg-subtle',\n status: 'absolute rounded-full ring-2 ring-surface',\n },\n variants: {\n size: {\n // `root` follows the container scale — avatars are surfaces, not glyphs\n // (see CLAUDE.md icon sizing). `status` follows CLAUDE.md's **dot\n // indicator** sub-scale (2 / 2.5 / 3 / 3.5 / 4), the same five-step 2px\n // cadence `badge-dot` was corrected onto. It previously rendered\n // 2/2/2.5/3/3, which duplicated `xs`→`sm` and froze `lg`/`xl` at 12px,\n // leaving two of the five advertised steps dead.\n xs: { root: 'size-6 text-xs', status: 'size-2' },\n sm: { root: 'size-8 text-xs', status: 'size-2.5' },\n md: { root: 'size-10 text-sm', status: 'size-3' },\n lg: { root: 'size-12 text-sm', status: 'size-3.5' },\n // The xl avatar lands at 64px, which sits above the glyph scale's ceiling\n // (size-10 / 40px) because avatars host imagery, initials, or icon glyphs.\n xl: { root: 'size-16 text-base', status: 'size-4' },\n },\n rounded: {\n full: { root: 'rounded-full', status: 'bottom-0 right-0' },\n lg: { root: 'rounded-lg', status: '-bottom-0.5 -right-0.5' },\n none: { root: 'rounded-none', status: '-bottom-0.5 -right-0.5' },\n },\n color: {\n primary: { root: 'bg-primary-100 text-primary-700' },\n secondary: { root: 'bg-secondary-100 text-secondary-700' },\n accent: { root: 'bg-accent-100 text-accent-700' },\n neutral: { root: 'bg-surface-muted text-fg-muted' },\n info: { root: 'bg-info-100 text-info-700' },\n success: { root: 'bg-success-100 text-success-700' },\n warning: { root: 'bg-warning-100 text-warning-700' },\n error: { root: 'bg-error-100 text-error-700' },\n },\n },\n defaultVariants: {\n size: 'md',\n rounded: 'full',\n color: 'neutral',\n },\n}, {\n twMerge: true,\n});\n\nconst statusColorMap: Record<AvatarStatus, string> = {\n online: 'bg-success-500',\n busy: 'bg-error-500',\n away: 'bg-warning-500',\n offline: 'bg-fg-subtle',\n};\n\n@Component({\n selector: 'tw-avatar',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n '[attr.role]': 'displayMode() !== \"image\" ? \"img\" : null',\n '[attr.aria-label]': 'displayMode() !== \"image\" && alt() ? alt() : null',\n // Only hide non-image avatars without alt text from AT. Image-mode avatars\n // expose their `alt` attribute directly on the underlying `<img>`; hiding\n // the host would suppress the image from assistive tech entirely.\n '[attr.aria-hidden]': 'displayMode() !== \"image\" && !alt() ? \"true\" : null',\n '[attr.hidden]': 'groupHidden() ? \"\" : null',\n },\n template: `\n @switch (displayMode()) {\n @case ('image') {\n <img\n [src]=\"src()\"\n [alt]=\"alt()\"\n [class]=\"imgClasses()\"\n (load)=\"imageLoaded.set(true)\"\n (error)=\"onImageError($event)\"\n />\n }\n @case ('initials') {\n <span [class]=\"initialsClasses()\">{{ initials() }}</span>\n }\n @case ('fallback') {\n <ng-content>\n <svg [class]=\"fallbackClasses()\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z\" clip-rule=\"evenodd\" />\n </svg>\n </ng-content>\n }\n }\n @if (resolvedStatus()) {\n <span [class]=\"statusClasses()\" aria-hidden=\"true\"></span>\n }\n `,\n})\nexport class AvatarComponent {\n /** URL of the avatar image. When set, renders an `<img>`. Falls back to initials or projected content on load error. Defaults to `null`. */\n readonly src = input<string | null>(null);\n\n /** Alt text for the avatar image. Also used as `aria-label` for non-image avatars. Defaults to `''`. */\n readonly alt = input('');\n\n /** Text initials displayed when no image is available (1-2 characters). Rendered uppercase regardless of input casing. Defaults to `null`. */\n readonly initials = input<string | null>(null);\n\n /** Semantic color for the initials/icon background. Only applies when no image is shown. Defaults to `'neutral'`. */\n readonly color = input<TwColor>('neutral');\n\n /** Controls the avatar dimensions. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Bundles decorative axes: `rounded` (shape) and `status` (indicator dot). Defaults to `{ rounded: 'full', status: null }`. */\n readonly appearance = input<AvatarAppearance>({});\n\n /** Fires when the avatar image fails to load. Payload is the native `Event` from the `<img>` `error` event. */\n readonly imageError = output<Event>();\n\n /** @internal */\n readonly elementRef = inject(ElementRef<HTMLElement>);\n\n /**\n * @internal\n * Toggled by `AvatarGroupComponent` to hide overflow avatars. Drives the\n * host `[attr.hidden]` binding so the group's effect stays declarative\n * (no direct `style.display` mutation).\n */\n readonly groupHidden = signal(false);\n\n private readonly groupSize = inject(TW_AVATAR_GROUP_SIZE, { optional: true });\n\n constructor() {\n if (isDevMode()) {\n effect(() => {\n if (this.displayMode() === 'image' && !this.alt()) {\n console.warn(\n '<tw-avatar> rendered as image without alt text — provide alt for accessibility',\n );\n }\n });\n }\n }\n\n readonly resolvedSize = computed(() => this.groupSize ? this.groupSize() : this.size());\n readonly resolvedRounded = computed<AvatarRounded>(() => this.appearance().rounded ?? 'full');\n readonly resolvedStatus = computed<AvatarStatus | null>(() => this.appearance().status ?? null);\n\n readonly imageLoaded = linkedSignal<string | null, boolean | null>({\n source: this.src,\n computation: () => null,\n });\n\n readonly displayMode = computed<'image' | 'initials' | 'fallback'>(() => {\n if (this.src() && this.imageLoaded() !== false) return 'image';\n if (this.initials()) return 'initials';\n return 'fallback';\n });\n\n private readonly variantResult = computed(() =>\n avatarVariants({\n size: this.resolvedSize(),\n rounded: this.resolvedRounded(),\n color: this.color(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly imgClasses = computed(() => this.variantResult().img());\n readonly initialsClasses = computed(() => this.variantResult().initials());\n readonly fallbackClasses = computed(() => this.variantResult().fallback());\n\n readonly statusClasses = computed(() => {\n const base = this.variantResult().status();\n const statusValue = this.resolvedStatus();\n if (!statusValue) return base;\n return `${base} ${statusColorMap[statusValue]}`;\n });\n\n protected onImageError(event: Event): void {\n this.imageLoaded.set(false);\n this.imageError.emit(event);\n }\n}\n\nconst groupOverlapMap: Record<TwSize, string> = {\n xs: '[&>tw-avatar+tw-avatar]:-ml-1.5 [&>tw-avatar+span]:-ml-1.5',\n sm: '[&>tw-avatar+tw-avatar]:-ml-1.5 [&>tw-avatar+span]:-ml-1.5',\n md: '[&>tw-avatar+tw-avatar]:-ml-2 [&>tw-avatar+span]:-ml-2',\n lg: '[&>tw-avatar+tw-avatar]:-ml-3 [&>tw-avatar+span]:-ml-3',\n xl: '[&>tw-avatar+tw-avatar]:-ml-3 [&>tw-avatar+span]:-ml-3',\n};\n\n@Component({\n selector: 'tw-avatar-group',\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: TW_AVATAR_GROUP_SIZE,\n useFactory: () => {\n const group = inject(AvatarGroupComponent);\n return () => group.size();\n },\n },\n ],\n host: {\n role: 'group',\n '[class]': 'hostClasses()',\n '[attr.aria-label]': 'ariaLabel()',\n },\n template: `\n <ng-content />\n @if (overflowCount() > 0) {\n <span [class]=\"overflowClasses()\">+{{ overflowCount() }}</span>\n }\n `,\n})\nexport class AvatarGroupComponent {\n /** Sets the size for all child avatars. Individual avatar size inputs are ignored when inside a group. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** Maximum number of avatars to display. Remaining count is shown as a \"+N\" overflow indicator. Defaults to `null` (show all). */\n readonly max = input<number | null>(null);\n\n /** Accessible label for the avatar group, mirrored to `aria-label`. Defaults to `'Avatar group'` (English) — override for localisation. */\n readonly ariaLabel = input('Avatar group', { alias: 'aria-label' });\n\n private readonly avatars = contentChildren(AvatarComponent);\n\n readonly overflowCount = computed(() => {\n const all = this.avatars();\n const maxVal = this.max();\n if (maxVal === null || maxVal >= all.length) return 0;\n return all.length - maxVal;\n });\n\n readonly hostClasses = computed(() => {\n const s = this.size();\n return `inline-flex items-center [&>tw-avatar]:ring-2 [&>tw-avatar]:ring-surface ${groupOverlapMap[s]}`;\n });\n\n readonly overflowClasses = computed(() => {\n const s = this.size();\n const sizeClasses = avatarVariants({ size: s, rounded: 'full', color: 'neutral' });\n return `${sizeClasses.root()} bg-surface-muted text-fg-muted font-medium ring-2 ring-surface`;\n });\n\n private readonly visibilityEffect = effect(() => {\n const all = this.avatars();\n const maxVal = this.max();\n all.forEach((avatar, index) => {\n avatar.groupHidden.set(maxVal !== null && index >= maxVal);\n });\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -287,12 +287,24 @@ const badgeDotVariants = tv({
287
287
  warning: 'bg-warning-500',
288
288
  error: 'bg-error-500',
289
289
  },
290
+ // Dot-indicator sub-scale, 2px per step: 8 / 10 / 12 / 14 / 16 px.
291
+ //
292
+ // xs / sm / md are CLAUDE.md's documented dot table verbatim (`size-2` / `size-2.5` /
293
+ // `size-3`). The table stops at md, so lg and xl continue its own 2px progression. They
294
+ // are NOT free choices: CLAUDE.md forbids `size-5` for a dot outright ("never size-5 for
295
+ // a dot indicator"), which caps the scale at 16px, and five distinct steps ending at 16
296
+ // with a 2px cadence admits exactly one assignment.
297
+ //
298
+ // Was 6 / 6 / 8 / 10 / 10 — an entire step below the documented scale, with dead steps at
299
+ // both ends (xs === sm, lg === xl).
290
300
  size: {
291
- xs: 'size-1.5',
292
- sm: 'size-1.5',
293
- md: 'size-2',
294
- lg: 'size-2.5',
295
- xl: 'size-2.5',
301
+ xs: 'size-2',
302
+ sm: 'size-2.5',
303
+ md: 'size-3',
304
+ // `size-3.5` (14px) and `size-4` (16px) extend the dot table past its documented md
305
+ // row; both keep the 2px cadence rather than jumping to the glyph scale.
306
+ lg: 'size-3.5',
307
+ xl: 'size-4',
296
308
  },
297
309
  },
298
310
  defaultVariants: {
@@ -1 +1 @@
1
- {"version":3,"file":"cdevhub-ngx-tw-badge.mjs","sources":["../../../projects/ngx-tw/badge/badge.ts","../../../projects/ngx-tw/badge/badge-dot.ts","../../../projects/ngx-tw/badge/cdevhub-ngx-tw-badge.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n input,\n output,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor, TwSize } from '@cdevhub/ngx-tw/core';\nimport { AvatarComponent } from '@cdevhub/ngx-tw/avatar';\nimport { IconComponent } from '@cdevhub/ngx-tw/icon';\n\n/** Visual style of the badge. */\nexport type BadgeVariant = 'solid' | 'outline' | 'soft';\n\nconst badgeVariants = tv({\n slots: {\n root: 'inline-flex items-center font-medium w-fit',\n content: 'inline-flex items-center',\n dismiss:\n 'inline-flex items-center justify-center rounded-md cursor-pointer hover:bg-surface-muted transition-colors duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n dismissIcon: 'shrink-0',\n leadingAvatar: 'inline-flex shrink-0 rounded-full overflow-hidden [&>tw-avatar]:size-full',\n leadingIcon: 'inline-flex shrink-0 [&>tw-icon]:size-full',\n },\n variants: {\n variant: {\n solid: { root: '' },\n outline: { root: 'border' },\n soft: { root: '' },\n },\n color: {\n primary: {},\n secondary: {},\n accent: {},\n neutral: {},\n info: {},\n success: {},\n warning: {},\n error: {},\n },\n size: {\n xs: {\n root: 'px-1.5 py-0.5 text-xs gap-1',\n // size-6 (24px) meets WCAG 2.5.8 target-size; negative margins keep\n // the visible badge box centred without inflating its layout height.\n dismiss: 'size-6 -my-1 -mr-1',\n dismissIcon: 'size-3',\n leadingAvatar: 'size-4',\n leadingIcon: 'size-3',\n },\n sm: {\n root: 'px-2 py-0.5 text-xs gap-1',\n dismiss: 'size-6 -my-1 -mr-1',\n dismissIcon: 'size-3',\n leadingAvatar: 'size-4',\n leadingIcon: 'size-3',\n },\n md: {\n root: 'px-2 py-1 text-xs gap-1.5',\n // size-7 (28px) keeps the dismiss target comfortable at md density;\n // negative margins absorb the overflow so the badge height is unchanged.\n dismiss: 'size-7 -my-1.5 -mr-1.5',\n // size-3.5 (14px) half-step: sits between the size-3 used at xs/sm and\n // the size-4 used at lg/xl, balancing the X glyph against text-xs at\n // md density without dominating the dismiss button.\n dismissIcon: 'size-3.5',\n leadingAvatar: 'size-5',\n // size-3.5 (14px) half-step: the md badge sits between xs/sm (size-3\n // leading icon, text-xs) and lg/xl (size-4, text-sm); 14px is the\n // visual mid-point that lines up with text-xs at this density.\n leadingIcon: 'size-3.5',\n },\n lg: {\n root: 'px-3 py-1.5 text-sm gap-1.5',\n dismiss: 'size-8 -my-1.5 -mr-1.5',\n dismissIcon: 'size-4',\n leadingAvatar: 'size-5',\n leadingIcon: 'size-4',\n },\n xl: {\n root: 'px-3 py-1.5 text-sm gap-1.5',\n dismiss: 'size-8 -my-1.5 -mr-1.5',\n dismissIcon: 'size-4',\n leadingAvatar: 'size-6',\n leadingIcon: 'size-4',\n },\n },\n pill: {\n true: { root: 'rounded-full' },\n false: { root: 'rounded-md' },\n },\n hasAvatar: {\n true: {},\n false: {},\n },\n },\n compoundVariants: [\n // ===== Primary =====\n // Solid variants consume the semantic `${color}-solid` slot pair (AA-tuned\n // in theme/_semantic.css) instead of a raw `${color}-600` shade — sky-600 /\n // green-600 on white fail AA (3.85:1 / 3.3:1); the `-solid` slots map to\n // `-700` where needed so every color meets the body-text threshold.\n { variant: 'solid', color: 'primary', class: { root: 'bg-primary-solid text-primary-solid-fg' } },\n { variant: 'outline', color: 'primary', class: { root: 'border-primary-300 text-primary-700' } },\n { variant: 'soft', color: 'primary', class: { root: 'bg-primary-50 text-primary-800' } },\n\n // ===== Secondary =====\n { variant: 'solid', color: 'secondary', class: { root: 'bg-secondary-solid text-secondary-solid-fg' } },\n { variant: 'outline', color: 'secondary', class: { root: 'border-secondary-300 text-secondary-700' } },\n { variant: 'soft', color: 'secondary', class: { root: 'bg-secondary-50 text-secondary-800' } },\n\n // ===== Accent =====\n { variant: 'solid', color: 'accent', class: { root: 'bg-accent-solid text-accent-solid-fg' } },\n { variant: 'outline', color: 'accent', class: { root: 'border-accent-300 text-accent-700' } },\n { variant: 'soft', color: 'accent', class: { root: 'bg-accent-50 text-accent-800' } },\n\n // ===== Neutral ===== (surface/fg tokens auto-adapt to dark mode)\n { variant: 'solid', color: 'neutral', class: { root: 'bg-surface-muted text-fg' } },\n { variant: 'outline', color: 'neutral', class: { root: 'border-border text-fg' } },\n { variant: 'soft', color: 'neutral', class: { root: 'bg-surface-muted text-fg-muted' } },\n\n // ===== Info =====\n { variant: 'solid', color: 'info', class: { root: 'bg-info-solid text-info-solid-fg' } },\n { variant: 'outline', color: 'info', class: { root: 'border-info-300 text-info-700' } },\n { variant: 'soft', color: 'info', class: { root: 'bg-info-50 text-info-800' } },\n\n // ===== Success =====\n { variant: 'solid', color: 'success', class: { root: 'bg-success-solid text-success-solid-fg' } },\n { variant: 'outline', color: 'success', class: { root: 'border-success-300 text-success-700' } },\n { variant: 'soft', color: 'success', class: { root: 'bg-success-50 text-success-800' } },\n\n // ===== Warning =====\n { variant: 'solid', color: 'warning', class: { root: 'bg-warning-solid text-warning-solid-fg' } },\n { variant: 'outline', color: 'warning', class: { root: 'border-warning-300 text-warning-700' } },\n { variant: 'soft', color: 'warning', class: { root: 'bg-warning-50 text-warning-800' } },\n\n // ===== Error =====\n { variant: 'solid', color: 'error', class: { root: 'bg-error-solid text-error-solid-fg' } },\n { variant: 'outline', color: 'error', class: { root: 'border-error-300 text-error-700' } },\n { variant: 'soft', color: 'error', class: { root: 'bg-error-50 text-error-800' } },\n\n // ===== Reduced left padding when avatar is present =====\n { hasAvatar: true, size: 'xs', class: { root: 'pl-0.5' } },\n { hasAvatar: true, size: 'sm', class: { root: 'pl-1' } },\n { hasAvatar: true, size: 'md', class: { root: 'pl-1' } },\n { hasAvatar: true, size: 'lg', class: { root: 'pl-1.5' } },\n { hasAvatar: true, size: 'xl', class: { root: 'pl-1.5' } },\n ],\n defaultVariants: {\n variant: 'soft',\n color: 'neutral',\n size: 'md',\n pill: false,\n hasAvatar: false,\n },\n}, {\n twMerge: true,\n});\n\n/**\n * Compact status label, tag, or count attached to any host element.\n *\n * Uses an attribute selector (`[twBadge]`) rather than the library's canonical\n * element selector so consumers can apply the badge styling to any inline\n * element — `<span>`, `<a>`, `<div>` — without an extra wrapper. The trade-off\n * is intentional: badges most often live inside an existing text flow or list\n * item where wrapping in a `<tw-badge>` element would add structural noise.\n *\n * For dot-only presence indicators (no text, no padding), use the sibling\n * `[twBadgeDot]` directive — its rendering shape (no children, no dismiss,\n * no leading slot) is structurally distinct from the labelled badge.\n */\n@Component({\n selector: '[twBadge]',\n exportAs: 'twBadge',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n '[attr.role]': 'live() ? \"status\" : null',\n },\n template: `\n @if (hasLeadingAvatar()) {\n <span [class]=\"leadingAvatarClasses()\"><ng-content select=\"tw-avatar\" /></span>\n }\n @if (hasLeadingIcon() && !hasLeadingAvatar()) {\n <span [class]=\"leadingIconClasses()\"><ng-content select=\"tw-icon\" /></span>\n }\n <span [class]=\"contentClasses()\"><ng-content /></span>\n @if (dismissible()) {\n <button\n type=\"button\"\n [attr.aria-label]=\"dismissLabel()\"\n [class]=\"dismissClasses()\"\n (click)=\"dismissed.emit()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" [class]=\"dismissIconClasses()\">\n <path d=\"M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z\"/>\n </svg>\n </button>\n }\n `,\n})\nexport class BadgeComponent {\n /** Sets the semantic color palette. Defaults to `'neutral'`. */\n readonly color = input<TwColor>('neutral');\n\n /** Controls the visual style. Defaults to `'soft'`. */\n readonly variant = input<BadgeVariant>('soft');\n\n /** Controls badge size (padding, font, icon size). Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, uses fully rounded corners instead of default `rounded-md`. Defaults to `false`. */\n readonly pill = input(false);\n\n /** When true, renders a dismiss button inside the badge. Defaults to `false`. */\n readonly dismissible = input(false);\n\n /**\n * When true, exposes the badge as an ARIA live region (`role=\"status\"`)\n * so assistive technology announces content changes. Defaults to `false`\n * because most badges are decorative tags or labels — opt in only when\n * the badge represents a value that actually updates in place.\n */\n readonly live = input(false);\n\n /** Accessible label for the dismiss button. Override for localization. Defaults to `'Dismiss'`. */\n readonly dismissLabel = input<string>('Dismiss');\n\n /** Fires when the dismiss button is clicked. */\n readonly dismissed = output<void>();\n\n /** @internal */\n readonly avatarChild = contentChild(AvatarComponent);\n\n /** @internal */\n readonly iconChild = contentChild(IconComponent);\n\n readonly hasLeadingAvatar = computed(() => !!this.avatarChild());\n readonly hasLeadingIcon = computed(() => !!this.iconChild());\n\n private readonly variantResult = computed(() =>\n badgeVariants({\n variant: this.variant(),\n color: this.color(),\n size: this.size(),\n pill: this.pill(),\n hasAvatar: this.hasLeadingAvatar(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly contentClasses = computed(() => this.variantResult().content());\n readonly dismissClasses = computed(() => this.variantResult().dismiss());\n readonly dismissIconClasses = computed(() => this.variantResult().dismissIcon());\n readonly leadingAvatarClasses = computed(() => this.variantResult().leadingAvatar());\n readonly leadingIconClasses = computed(() => this.variantResult().leadingIcon());\n}\n","import {\n Directive,\n computed,\n input,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor, TwSize } from '@cdevhub/ngx-tw/core';\n\n/**\n * Dot indicator styling and color tokens for `[twBadgeDot]`. Mirrors the\n * `dot` slot rules previously embedded in the badge component but lives in\n * its own variant table because the dot has no text content, no padding,\n * and no border / variant axis.\n */\nconst badgeDotVariants = tv({\n base: 'inline-block rounded-full shrink-0',\n variants: {\n color: {\n primary: 'bg-primary-500',\n secondary: 'bg-secondary-500',\n accent: 'bg-accent-500',\n neutral: 'bg-fg-muted',\n info: 'bg-info-500',\n success: 'bg-success-500',\n warning: 'bg-warning-500',\n error: 'bg-error-500',\n },\n size: {\n xs: 'size-1.5',\n sm: 'size-1.5',\n md: 'size-2',\n lg: 'size-2.5',\n xl: 'size-2.5',\n },\n },\n defaultVariants: {\n color: 'neutral',\n size: 'md',\n },\n}, {\n twMerge: true,\n});\n\n/**\n * Compact colored dot used as a presence indicator, unread marker, or status\n * pip. Applies as an attribute selector so the host element controls the\n * structure — wrap in a `<span>`, `<div>`, list item, or any inline element.\n *\n * The dot has no text content; pair it with a visible label adjacent in the\n * DOM, or set `aria-label` on the host so assistive technology can announce\n * the state. Opt in to `live` to expose the dot as an ARIA live region when\n * the indicator state actually changes (e.g. \"new messages received\").\n *\n * @example\n * ```html\n * <span twBadgeDot color=\"success\" size=\"sm\"></span>\n * <span twBadgeDot color=\"error\" [live]=\"true\" aria-label=\"3 unread\"></span>\n * ```\n */\n@Directive({\n selector: '[twBadgeDot]',\n exportAs: 'twBadgeDot',\n host: {\n '[class]': 'classes()',\n '[attr.role]': 'live() ? \"status\" : null',\n },\n})\nexport class BadgeDotDirective {\n /** Sets the semantic color palette. Defaults to `'neutral'`. */\n readonly color = input<TwColor>('neutral');\n\n /** Controls dot dimensions. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /**\n * When true, exposes the dot as an ARIA live region (`role=\"status\"`) so\n * assistive technology announces state changes (e.g. an unread indicator\n * appearing). Defaults to `false` because most dots are decorative pips\n * paired with a visible label.\n */\n readonly live = input(false);\n\n readonly classes = computed(() =>\n badgeDotVariants({ color: this.color(), size: this.size() }),\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cdevhub-ngx-tw-badge.mjs","sources":["../../../projects/ngx-tw/badge/badge.ts","../../../projects/ngx-tw/badge/badge-dot.ts","../../../projects/ngx-tw/badge/cdevhub-ngx-tw-badge.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n input,\n output,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor, TwSize } from '@cdevhub/ngx-tw/core';\nimport { AvatarComponent } from '@cdevhub/ngx-tw/avatar';\nimport { IconComponent } from '@cdevhub/ngx-tw/icon';\n\n/** Visual style of the badge. */\nexport type BadgeVariant = 'solid' | 'outline' | 'soft';\n\nconst badgeVariants = tv({\n slots: {\n root: 'inline-flex items-center font-medium w-fit',\n content: 'inline-flex items-center',\n dismiss:\n 'inline-flex items-center justify-center rounded-md cursor-pointer hover:bg-surface-muted transition-colors duration-normal motion-reduce:transition-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-500',\n dismissIcon: 'shrink-0',\n leadingAvatar: 'inline-flex shrink-0 rounded-full overflow-hidden [&>tw-avatar]:size-full',\n leadingIcon: 'inline-flex shrink-0 [&>tw-icon]:size-full',\n },\n variants: {\n variant: {\n solid: { root: '' },\n outline: { root: 'border' },\n soft: { root: '' },\n },\n color: {\n primary: {},\n secondary: {},\n accent: {},\n neutral: {},\n info: {},\n success: {},\n warning: {},\n error: {},\n },\n size: {\n xs: {\n root: 'px-1.5 py-0.5 text-xs gap-1',\n // size-6 (24px) meets WCAG 2.5.8 target-size; negative margins keep\n // the visible badge box centred without inflating its layout height.\n dismiss: 'size-6 -my-1 -mr-1',\n dismissIcon: 'size-3',\n leadingAvatar: 'size-4',\n leadingIcon: 'size-3',\n },\n sm: {\n root: 'px-2 py-0.5 text-xs gap-1',\n dismiss: 'size-6 -my-1 -mr-1',\n dismissIcon: 'size-3',\n leadingAvatar: 'size-4',\n leadingIcon: 'size-3',\n },\n md: {\n root: 'px-2 py-1 text-xs gap-1.5',\n // size-7 (28px) keeps the dismiss target comfortable at md density;\n // negative margins absorb the overflow so the badge height is unchanged.\n dismiss: 'size-7 -my-1.5 -mr-1.5',\n // size-3.5 (14px) half-step: sits between the size-3 used at xs/sm and\n // the size-4 used at lg/xl, balancing the X glyph against text-xs at\n // md density without dominating the dismiss button.\n dismissIcon: 'size-3.5',\n leadingAvatar: 'size-5',\n // size-3.5 (14px) half-step: the md badge sits between xs/sm (size-3\n // leading icon, text-xs) and lg/xl (size-4, text-sm); 14px is the\n // visual mid-point that lines up with text-xs at this density.\n leadingIcon: 'size-3.5',\n },\n lg: {\n root: 'px-3 py-1.5 text-sm gap-1.5',\n dismiss: 'size-8 -my-1.5 -mr-1.5',\n dismissIcon: 'size-4',\n leadingAvatar: 'size-5',\n leadingIcon: 'size-4',\n },\n xl: {\n root: 'px-3 py-1.5 text-sm gap-1.5',\n dismiss: 'size-8 -my-1.5 -mr-1.5',\n dismissIcon: 'size-4',\n leadingAvatar: 'size-6',\n leadingIcon: 'size-4',\n },\n },\n pill: {\n true: { root: 'rounded-full' },\n false: { root: 'rounded-md' },\n },\n hasAvatar: {\n true: {},\n false: {},\n },\n },\n compoundVariants: [\n // ===== Primary =====\n // Solid variants consume the semantic `${color}-solid` slot pair (AA-tuned\n // in theme/_semantic.css) instead of a raw `${color}-600` shade — sky-600 /\n // green-600 on white fail AA (3.85:1 / 3.3:1); the `-solid` slots map to\n // `-700` where needed so every color meets the body-text threshold.\n { variant: 'solid', color: 'primary', class: { root: 'bg-primary-solid text-primary-solid-fg' } },\n { variant: 'outline', color: 'primary', class: { root: 'border-primary-300 text-primary-700' } },\n { variant: 'soft', color: 'primary', class: { root: 'bg-primary-50 text-primary-800' } },\n\n // ===== Secondary =====\n { variant: 'solid', color: 'secondary', class: { root: 'bg-secondary-solid text-secondary-solid-fg' } },\n { variant: 'outline', color: 'secondary', class: { root: 'border-secondary-300 text-secondary-700' } },\n { variant: 'soft', color: 'secondary', class: { root: 'bg-secondary-50 text-secondary-800' } },\n\n // ===== Accent =====\n { variant: 'solid', color: 'accent', class: { root: 'bg-accent-solid text-accent-solid-fg' } },\n { variant: 'outline', color: 'accent', class: { root: 'border-accent-300 text-accent-700' } },\n { variant: 'soft', color: 'accent', class: { root: 'bg-accent-50 text-accent-800' } },\n\n // ===== Neutral ===== (surface/fg tokens auto-adapt to dark mode)\n { variant: 'solid', color: 'neutral', class: { root: 'bg-surface-muted text-fg' } },\n { variant: 'outline', color: 'neutral', class: { root: 'border-border text-fg' } },\n { variant: 'soft', color: 'neutral', class: { root: 'bg-surface-muted text-fg-muted' } },\n\n // ===== Info =====\n { variant: 'solid', color: 'info', class: { root: 'bg-info-solid text-info-solid-fg' } },\n { variant: 'outline', color: 'info', class: { root: 'border-info-300 text-info-700' } },\n { variant: 'soft', color: 'info', class: { root: 'bg-info-50 text-info-800' } },\n\n // ===== Success =====\n { variant: 'solid', color: 'success', class: { root: 'bg-success-solid text-success-solid-fg' } },\n { variant: 'outline', color: 'success', class: { root: 'border-success-300 text-success-700' } },\n { variant: 'soft', color: 'success', class: { root: 'bg-success-50 text-success-800' } },\n\n // ===== Warning =====\n { variant: 'solid', color: 'warning', class: { root: 'bg-warning-solid text-warning-solid-fg' } },\n { variant: 'outline', color: 'warning', class: { root: 'border-warning-300 text-warning-700' } },\n { variant: 'soft', color: 'warning', class: { root: 'bg-warning-50 text-warning-800' } },\n\n // ===== Error =====\n { variant: 'solid', color: 'error', class: { root: 'bg-error-solid text-error-solid-fg' } },\n { variant: 'outline', color: 'error', class: { root: 'border-error-300 text-error-700' } },\n { variant: 'soft', color: 'error', class: { root: 'bg-error-50 text-error-800' } },\n\n // ===== Reduced left padding when avatar is present =====\n { hasAvatar: true, size: 'xs', class: { root: 'pl-0.5' } },\n { hasAvatar: true, size: 'sm', class: { root: 'pl-1' } },\n { hasAvatar: true, size: 'md', class: { root: 'pl-1' } },\n { hasAvatar: true, size: 'lg', class: { root: 'pl-1.5' } },\n { hasAvatar: true, size: 'xl', class: { root: 'pl-1.5' } },\n ],\n defaultVariants: {\n variant: 'soft',\n color: 'neutral',\n size: 'md',\n pill: false,\n hasAvatar: false,\n },\n}, {\n twMerge: true,\n});\n\n/**\n * Compact status label, tag, or count attached to any host element.\n *\n * Uses an attribute selector (`[twBadge]`) rather than the library's canonical\n * element selector so consumers can apply the badge styling to any inline\n * element — `<span>`, `<a>`, `<div>` — without an extra wrapper. The trade-off\n * is intentional: badges most often live inside an existing text flow or list\n * item where wrapping in a `<tw-badge>` element would add structural noise.\n *\n * For dot-only presence indicators (no text, no padding), use the sibling\n * `[twBadgeDot]` directive — its rendering shape (no children, no dismiss,\n * no leading slot) is structurally distinct from the labelled badge.\n */\n@Component({\n selector: '[twBadge]',\n exportAs: 'twBadge',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'rootClasses()',\n '[attr.role]': 'live() ? \"status\" : null',\n },\n template: `\n @if (hasLeadingAvatar()) {\n <span [class]=\"leadingAvatarClasses()\"><ng-content select=\"tw-avatar\" /></span>\n }\n @if (hasLeadingIcon() && !hasLeadingAvatar()) {\n <span [class]=\"leadingIconClasses()\"><ng-content select=\"tw-icon\" /></span>\n }\n <span [class]=\"contentClasses()\"><ng-content /></span>\n @if (dismissible()) {\n <button\n type=\"button\"\n [attr.aria-label]=\"dismissLabel()\"\n [class]=\"dismissClasses()\"\n (click)=\"dismissed.emit()\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"currentColor\" [class]=\"dismissIconClasses()\">\n <path d=\"M5.28 4.22a.75.75 0 0 0-1.06 1.06L6.94 8l-2.72 2.72a.75.75 0 1 0 1.06 1.06L8 9.06l2.72 2.72a.75.75 0 1 0 1.06-1.06L9.06 8l2.72-2.72a.75.75 0 0 0-1.06-1.06L8 6.94 5.28 4.22Z\"/>\n </svg>\n </button>\n }\n `,\n})\nexport class BadgeComponent {\n /** Sets the semantic color palette. Defaults to `'neutral'`. */\n readonly color = input<TwColor>('neutral');\n\n /** Controls the visual style. Defaults to `'soft'`. */\n readonly variant = input<BadgeVariant>('soft');\n\n /** Controls badge size (padding, font, icon size). Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /** When true, uses fully rounded corners instead of default `rounded-md`. Defaults to `false`. */\n readonly pill = input(false);\n\n /** When true, renders a dismiss button inside the badge. Defaults to `false`. */\n readonly dismissible = input(false);\n\n /**\n * When true, exposes the badge as an ARIA live region (`role=\"status\"`)\n * so assistive technology announces content changes. Defaults to `false`\n * because most badges are decorative tags or labels — opt in only when\n * the badge represents a value that actually updates in place.\n */\n readonly live = input(false);\n\n /** Accessible label for the dismiss button. Override for localization. Defaults to `'Dismiss'`. */\n readonly dismissLabel = input<string>('Dismiss');\n\n /** Fires when the dismiss button is clicked. */\n readonly dismissed = output<void>();\n\n /** @internal */\n readonly avatarChild = contentChild(AvatarComponent);\n\n /** @internal */\n readonly iconChild = contentChild(IconComponent);\n\n readonly hasLeadingAvatar = computed(() => !!this.avatarChild());\n readonly hasLeadingIcon = computed(() => !!this.iconChild());\n\n private readonly variantResult = computed(() =>\n badgeVariants({\n variant: this.variant(),\n color: this.color(),\n size: this.size(),\n pill: this.pill(),\n hasAvatar: this.hasLeadingAvatar(),\n }),\n );\n\n readonly rootClasses = computed(() => this.variantResult().root());\n readonly contentClasses = computed(() => this.variantResult().content());\n readonly dismissClasses = computed(() => this.variantResult().dismiss());\n readonly dismissIconClasses = computed(() => this.variantResult().dismissIcon());\n readonly leadingAvatarClasses = computed(() => this.variantResult().leadingAvatar());\n readonly leadingIconClasses = computed(() => this.variantResult().leadingIcon());\n}\n","import {\n Directive,\n computed,\n input,\n} from '@angular/core';\nimport { tv } from 'tailwind-variants';\nimport type { TwColor, TwSize } from '@cdevhub/ngx-tw/core';\n\n/**\n * Dot indicator styling and color tokens for `[twBadgeDot]`. Mirrors the\n * `dot` slot rules previously embedded in the badge component but lives in\n * its own variant table because the dot has no text content, no padding,\n * and no border / variant axis.\n */\nconst badgeDotVariants = tv({\n base: 'inline-block rounded-full shrink-0',\n variants: {\n color: {\n primary: 'bg-primary-500',\n secondary: 'bg-secondary-500',\n accent: 'bg-accent-500',\n neutral: 'bg-fg-muted',\n info: 'bg-info-500',\n success: 'bg-success-500',\n warning: 'bg-warning-500',\n error: 'bg-error-500',\n },\n // Dot-indicator sub-scale, 2px per step: 8 / 10 / 12 / 14 / 16 px.\n //\n // xs / sm / md are CLAUDE.md's documented dot table verbatim (`size-2` / `size-2.5` /\n // `size-3`). The table stops at md, so lg and xl continue its own 2px progression. They\n // are NOT free choices: CLAUDE.md forbids `size-5` for a dot outright (\"never size-5 for\n // a dot indicator\"), which caps the scale at 16px, and five distinct steps ending at 16\n // with a 2px cadence admits exactly one assignment.\n //\n // Was 6 / 6 / 8 / 10 / 10 — an entire step below the documented scale, with dead steps at\n // both ends (xs === sm, lg === xl).\n size: {\n xs: 'size-2',\n sm: 'size-2.5',\n md: 'size-3',\n // `size-3.5` (14px) and `size-4` (16px) extend the dot table past its documented md\n // row; both keep the 2px cadence rather than jumping to the glyph scale.\n lg: 'size-3.5',\n xl: 'size-4',\n },\n },\n defaultVariants: {\n color: 'neutral',\n size: 'md',\n },\n}, {\n twMerge: true,\n});\n\n/**\n * Compact colored dot used as a presence indicator, unread marker, or status\n * pip. Applies as an attribute selector so the host element controls the\n * structure — wrap in a `<span>`, `<div>`, list item, or any inline element.\n *\n * The dot has no text content; pair it with a visible label adjacent in the\n * DOM, or set `aria-label` on the host so assistive technology can announce\n * the state. Opt in to `live` to expose the dot as an ARIA live region when\n * the indicator state actually changes (e.g. \"new messages received\").\n *\n * @example\n * ```html\n * <span twBadgeDot color=\"success\" size=\"sm\"></span>\n * <span twBadgeDot color=\"error\" [live]=\"true\" aria-label=\"3 unread\"></span>\n * ```\n */\n@Directive({\n selector: '[twBadgeDot]',\n exportAs: 'twBadgeDot',\n host: {\n '[class]': 'classes()',\n '[attr.role]': 'live() ? \"status\" : null',\n },\n})\nexport class BadgeDotDirective {\n /** Sets the semantic color palette. Defaults to `'neutral'`. */\n readonly color = input<TwColor>('neutral');\n\n /** Controls dot dimensions. Defaults to `'md'`. */\n readonly size = input<TwSize>('md');\n\n /**\n * When true, exposes the dot as an ARIA live region (`role=\"status\"`) so\n * assistive technology announces state changes (e.g. an unread indicator\n * appearing). Defaults to `false` because most dots are decorative pips\n * paired with a visible label.\n */\n readonly live = input(false);\n\n readonly classes = computed(() =>\n badgeDotVariants({ color: this.color(), size: this.size() }),\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAgBA,MAAM,aAAa,GAAG,EAAE,CAAC;AACvB,IAAA,KAAK,EAAE;AACL,QAAA,IAAI,EAAE,4CAA4C;AAClD,QAAA,OAAO,EAAE,0BAA0B;AACnC,QAAA,OAAO,EACL,mPAAmP;AACrP,QAAA,WAAW,EAAE,UAAU;AACvB,QAAA,aAAa,EAAE,2EAA2E;AAC1F,QAAA,WAAW,EAAE,4CAA4C;AAC1D,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,OAAO,EAAE;AACP,YAAA,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;AACnB,YAAA,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;AAC3B,YAAA,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;AACnB,SAAA;AACD,QAAA,KAAK,EAAE;AACL,YAAA,OAAO,EAAE,EAAE;AACX,YAAA,SAAS,EAAE,EAAE;AACb,YAAA,MAAM,EAAE,EAAE;AACV,YAAA,OAAO,EAAE,EAAE;AACX,YAAA,IAAI,EAAE,EAAE;AACR,YAAA,OAAO,EAAE,EAAE;AACX,YAAA,OAAO,EAAE,EAAE;AACX,YAAA,KAAK,EAAE,EAAE;AACV,SAAA;AACD,QAAA,IAAI,EAAE;AACJ,YAAA,EAAE,EAAE;AACF,gBAAA,IAAI,EAAE,6BAA6B;;;AAGnC,gBAAA,OAAO,EAAE,oBAAoB;AAC7B,gBAAA,WAAW,EAAE,QAAQ;AACrB,gBAAA,aAAa,EAAE,QAAQ;AACvB,gBAAA,WAAW,EAAE,QAAQ;AACtB,aAAA;AACD,YAAA,EAAE,EAAE;AACF,gBAAA,IAAI,EAAE,2BAA2B;AACjC,gBAAA,OAAO,EAAE,oBAAoB;AAC7B,gBAAA,WAAW,EAAE,QAAQ;AACrB,gBAAA,aAAa,EAAE,QAAQ;AACvB,gBAAA,WAAW,EAAE,QAAQ;AACtB,aAAA;AACD,YAAA,EAAE,EAAE;AACF,gBAAA,IAAI,EAAE,2BAA2B;;;AAGjC,gBAAA,OAAO,EAAE,wBAAwB;;;;AAIjC,gBAAA,WAAW,EAAE,UAAU;AACvB,gBAAA,aAAa,EAAE,QAAQ;;;;AAIvB,gBAAA,WAAW,EAAE,UAAU;AACxB,aAAA;AACD,YAAA,EAAE,EAAE;AACF,gBAAA,IAAI,EAAE,6BAA6B;AACnC,gBAAA,OAAO,EAAE,wBAAwB;AACjC,gBAAA,WAAW,EAAE,QAAQ;AACrB,gBAAA,aAAa,EAAE,QAAQ;AACvB,gBAAA,WAAW,EAAE,QAAQ;AACtB,aAAA;AACD,YAAA,EAAE,EAAE;AACF,gBAAA,IAAI,EAAE,6BAA6B;AACnC,gBAAA,OAAO,EAAE,wBAAwB;AACjC,gBAAA,WAAW,EAAE,QAAQ;AACrB,gBAAA,aAAa,EAAE,QAAQ;AACvB,gBAAA,WAAW,EAAE,QAAQ;AACtB,aAAA;AACF,SAAA;AACD,QAAA,IAAI,EAAE;AACJ,YAAA,IAAI,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;AAC9B,YAAA,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;AAC9B,SAAA;AACD,QAAA,SAAS,EAAE;AACT,YAAA,IAAI,EAAE,EAAE;AACR,YAAA,KAAK,EAAE,EAAE;AACV,SAAA;AACF,KAAA;AACD,IAAA,gBAAgB,EAAE;;;;;;AAMhB,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,wCAAwC,EAAE,EAAE;AACjG,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,qCAAqC,EAAE,EAAE;AAChG,QAAA,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,EAAE;;AAGxF,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,4CAA4C,EAAE,EAAE;AACvG,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,yCAAyC,EAAE,EAAE;AACtG,QAAA,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,oCAAoC,EAAE,EAAE;;AAG9F,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,sCAAsC,EAAE,EAAE;AAC9F,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,mCAAmC,EAAE,EAAE;AAC7F,QAAA,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,8BAA8B,EAAE,EAAE;;AAGrF,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,EAAE;AACnF,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE,EAAE;AAClF,QAAA,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,EAAE;;AAGxF,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kCAAkC,EAAE,EAAE;AACxF,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,+BAA+B,EAAE,EAAE;AACvF,QAAA,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,EAAE;;AAG/E,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,wCAAwC,EAAE,EAAE;AACjG,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,qCAAqC,EAAE,EAAE;AAChG,QAAA,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,EAAE;;AAGxF,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,wCAAwC,EAAE,EAAE;AACjG,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,qCAAqC,EAAE,EAAE;AAChG,QAAA,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,gCAAgC,EAAE,EAAE;;AAGxF,QAAA,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,oCAAoC,EAAE,EAAE;AAC3F,QAAA,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,iCAAiC,EAAE,EAAE;AAC1F,QAAA,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,4BAA4B,EAAE,EAAE;;AAGlF,QAAA,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;AAC1D,QAAA,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;AACxD,QAAA,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;AACxD,QAAA,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;AAC1D,QAAA,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;AAC3D,KAAA;AACD,IAAA,eAAe,EAAE;AACf,QAAA,OAAO,EAAE,MAAM;AACf,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,IAAI,EAAE,KAAK;AACX,QAAA,SAAS,EAAE,KAAK;AACjB,KAAA;CACF,EAAE;AACD,IAAA,OAAO,EAAE,IAAI;AACd,CAAA,CAAC;AAEF;;;;;;;;;;;;AAYG;MA+BU,cAAc,CAAA;;IAEhB,KAAK,GAAG,KAAK,CAAU,SAAS;8EAAC;;IAGjC,OAAO,GAAG,KAAK,CAAe,MAAM;gFAAC;;IAGrC,IAAI,GAAG,KAAK,CAAS,IAAI;6EAAC;;IAG1B,IAAI,GAAG,KAAK,CAAC,KAAK;6EAAC;;IAGnB,WAAW,GAAG,KAAK,CAAC,KAAK;oFAAC;AAEnC;;;;;AAKG;IACM,IAAI,GAAG,KAAK,CAAC,KAAK;6EAAC;;IAGnB,YAAY,GAAG,KAAK,CAAS,SAAS;qFAAC;;IAGvC,SAAS,GAAG,MAAM,EAAQ;;IAG1B,WAAW,GAAG,YAAY,CAAC,eAAe;oFAAC;;IAG3C,SAAS,GAAG,YAAY,CAAC,aAAa;kFAAC;IAEvC,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;yFAAC;IACvD,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE;uFAAC;AAE3C,IAAA,aAAa,GAAG,QAAQ,CAAC,MACxC,aAAa,CAAC;AACZ,QAAA,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;AACvB,QAAA,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;AACnB,QAAA,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACjB,QAAA,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACjB,QAAA,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;KACnC,CAAC;sFACH;AAEQ,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE;oFAAC;AACzD,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE;uFAAC;AAC/D,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE;uFAAC;AAC/D,IAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE;2FAAC;AACvE,IAAA,oBAAoB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,aAAa,EAAE;6FAAC;AAC3E,IAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE;2FAAC;uGAtDrE,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAd,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,eAAA,EAAA,WAAA,EAAA,4BAAA,EAAA,EAAA,EAAA,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,aAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EA+BW,eAAe,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAGjB,aAAa,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAxDrC;;;;;;;;;;;;;;;;;;;;AAoBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA;;2FAEU,cAAc,EAAA,UAAA,EAAA,CAAA;kBA9B1B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,WAAW;AACrB,oBAAA,QAAQ,EAAE,SAAS;oBACnB,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAC/C,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,eAAe;AAC1B,wBAAA,aAAa,EAAE,0BAA0B;AAC1C,qBAAA;AACD,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;AAoBT,EAAA,CAAA;AACF,iBAAA;AAgCqC,SAAA,CAAA,EAAA,cAAA,EAAA,EAAA,KAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,SAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,aAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,IAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,KAAA,EAAA,cAAA,EAAA,QAAA,EAAA,KAAA,EAAA,CAAA,EAAA,CAAA,EAAA,SAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,CAAA,WAAA,CAAA,EAAA,CAAA,EAAA,WAAA,EAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,UAAA,CAAA,MAAA,eAAe,2FAGjB,aAAa,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;ACtOjD;;;;;AAKG;AACH,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAC1B,IAAA,IAAI,EAAE,oCAAoC;AAC1C,IAAA,QAAQ,EAAE;AACR,QAAA,KAAK,EAAE;AACL,YAAA,OAAO,EAAE,gBAAgB;AACzB,YAAA,SAAS,EAAE,kBAAkB;AAC7B,YAAA,MAAM,EAAE,eAAe;AACvB,YAAA,OAAO,EAAE,aAAa;AACtB,YAAA,IAAI,EAAE,aAAa;AACnB,YAAA,OAAO,EAAE,gBAAgB;AACzB,YAAA,OAAO,EAAE,gBAAgB;AACzB,YAAA,KAAK,EAAE,cAAc;AACtB,SAAA;;;;;;;;;;;AAWD,QAAA,IAAI,EAAE;AACJ,YAAA,EAAE,EAAE,QAAQ;AACZ,YAAA,EAAE,EAAE,UAAU;AACd,YAAA,EAAE,EAAE,QAAQ;;;AAGZ,YAAA,EAAE,EAAE,UAAU;AACd,YAAA,EAAE,EAAE,QAAQ;AACb,SAAA;AACF,KAAA;AACD,IAAA,eAAe,EAAE;AACf,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,IAAI,EAAE,IAAI;AACX,KAAA;CACF,EAAE;AACD,IAAA,OAAO,EAAE,IAAI;AACd,CAAA,CAAC;AAEF;;;;;;;;;;;;;;;AAeG;MASU,iBAAiB,CAAA;;IAEnB,KAAK,GAAG,KAAK,CAAU,SAAS;8EAAC;;IAGjC,IAAI,GAAG,KAAK,CAAS,IAAI;6EAAC;AAEnC;;;;;AAKG;IACM,IAAI,GAAG,KAAK,CAAC,KAAK;6EAAC;IAEnB,OAAO,GAAG,QAAQ,CAAC,MAC1B,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gFAC7D;uGAjBU,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;2FAAjB,iBAAiB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,WAAA,EAAA,4BAAA,EAAA,EAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;2FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAR7B,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,cAAc;AACxB,oBAAA,QAAQ,EAAE,YAAY;AACtB,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACtB,wBAAA,aAAa,EAAE,0BAA0B;AAC1C,qBAAA;AACF,iBAAA;;;AC9ED;;AAEG;;;;"}