@spartan-ng/cli 0.0.1-alpha.584 → 0.0.1-alpha.586

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 (215) hide show
  1. package/package.json +1 -1
  2. package/src/generators/migrate-brain-imports/import-map.d.ts +0 -1
  3. package/src/generators/migrate-brain-imports/import-map.js +0 -1
  4. package/src/generators/migrate-brain-imports/import-map.js.map +1 -1
  5. package/src/generators/ui/libs/accordion/files/lib/hlm-accordion-content.ts.template +6 -13
  6. package/src/generators/ui/libs/accordion/files/lib/hlm-accordion-icon.ts.template +8 -13
  7. package/src/generators/ui/libs/accordion/files/lib/hlm-accordion-item.ts.template +5 -10
  8. package/src/generators/ui/libs/accordion/files/lib/hlm-accordion-trigger.ts.template +8 -11
  9. package/src/generators/ui/libs/accordion/files/lib/hlm-accordion.ts.template +5 -10
  10. package/src/generators/ui/libs/alert/files/lib/hlm-alert-description.ts.template +5 -13
  11. package/src/generators/ui/libs/alert/files/lib/hlm-alert-title.ts.template +5 -10
  12. package/src/generators/ui/libs/alert/files/lib/hlm-alert.ts.template +6 -7
  13. package/src/generators/ui/libs/alert-dialog/files/lib/hlm-alert-dialog-content.ts.template +8 -11
  14. package/src/generators/ui/libs/alert-dialog/files/lib/hlm-alert-dialog-description.ts.template +5 -6
  15. package/src/generators/ui/libs/alert-dialog/files/lib/hlm-alert-dialog-footer.ts.template +5 -8
  16. package/src/generators/ui/libs/alert-dialog/files/lib/hlm-alert-dialog-header.ts.template +5 -8
  17. package/src/generators/ui/libs/alert-dialog/files/lib/hlm-alert-dialog-title.ts.template +5 -6
  18. package/src/generators/ui/libs/aspect-ratio/files/lib/helm-aspect-ratio.ts.template +9 -15
  19. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-empty.ts.template +5 -8
  20. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-group.ts.template +5 -13
  21. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-item.ts.template +8 -16
  22. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete-list.ts.template +5 -13
  23. package/src/generators/ui/libs/autocomplete/files/lib/hlm-autocomplete.ts.template +7 -13
  24. package/src/generators/ui/libs/avatar/files/lib/fallback/hlm-avatar-fallback.ts.template +5 -11
  25. package/src/generators/ui/libs/avatar/files/lib/hlm-avatar.ts.template +6 -11
  26. package/src/generators/ui/libs/avatar/files/lib/image/hlm-avatar-image.ts.template +6 -9
  27. package/src/generators/ui/libs/badge/files/lib/hlm-badge.ts.template +6 -7
  28. package/src/generators/ui/libs/breadcrumb/files/lib/hlm-breadcrumb-item.ts.template +5 -9
  29. package/src/generators/ui/libs/breadcrumb/files/lib/hlm-breadcrumb-link.ts.template +6 -9
  30. package/src/generators/ui/libs/breadcrumb/files/lib/hlm-breadcrumb-list.ts.template +5 -11
  31. package/src/generators/ui/libs/breadcrumb/files/lib/hlm-breadcrumb-page.ts.template +5 -7
  32. package/src/generators/ui/libs/breadcrumb/files/lib/hlm-breadcrumb-separator.ts.template +5 -7
  33. package/src/generators/ui/libs/breadcrumb/files/lib/hlm-breadcrumb.ts.template +1 -7
  34. package/src/generators/ui/libs/button/files/lib/hlm-button.ts.template +6 -9
  35. package/src/generators/ui/libs/button-group/files/lib/hlm-button-group-separator.ts.template +8 -12
  36. package/src/generators/ui/libs/button-group/files/lib/hlm-button-group-text.ts.template +8 -14
  37. package/src/generators/ui/libs/button-group/files/lib/hlm-button-group.ts.template +6 -9
  38. package/src/generators/ui/libs/card/files/lib/hlm-card-action.ts.template +5 -10
  39. package/src/generators/ui/libs/card/files/lib/hlm-card-content.ts.template +5 -8
  40. package/src/generators/ui/libs/card/files/lib/hlm-card-description.ts.template +5 -8
  41. package/src/generators/ui/libs/card/files/lib/hlm-card-footer.ts.template +5 -8
  42. package/src/generators/ui/libs/card/files/lib/hlm-card-header.ts.template +8 -13
  43. package/src/generators/ui/libs/card/files/lib/hlm-card-title.ts.template +5 -8
  44. package/src/generators/ui/libs/card/files/lib/hlm-card.ts.template +5 -8
  45. package/src/generators/ui/libs/carousel/files/lib/hlm-carousel-content.ts.template +5 -8
  46. package/src/generators/ui/libs/carousel/files/lib/hlm-carousel-item.ts.template +5 -8
  47. package/src/generators/ui/libs/carousel/files/lib/hlm-carousel-next.ts.template +1 -4
  48. package/src/generators/ui/libs/carousel/files/lib/hlm-carousel-previous.ts.template +1 -6
  49. package/src/generators/ui/libs/carousel/files/lib/hlm-carousel-slide-display.ts.template +0 -5
  50. package/src/generators/ui/libs/carousel/files/lib/hlm-carousel.ts.template +5 -6
  51. package/src/generators/ui/libs/collapsible/files/lib/hlm-collapsible-content.ts.template +5 -7
  52. package/src/generators/ui/libs/command/files/lib/hlm-command-dialog-close-button.ts.template +8 -13
  53. package/src/generators/ui/libs/command/files/lib/hlm-command-dialog.ts.template +7 -12
  54. package/src/generators/ui/libs/command/files/lib/hlm-command-empty.ts.template +5 -6
  55. package/src/generators/ui/libs/command/files/lib/hlm-command-group-label.ts.template +5 -11
  56. package/src/generators/ui/libs/command/files/lib/hlm-command-group.ts.template +5 -11
  57. package/src/generators/ui/libs/command/files/lib/hlm-command-icon.ts.template +5 -8
  58. package/src/generators/ui/libs/command/files/lib/hlm-command-item.ts.template +8 -14
  59. package/src/generators/ui/libs/command/files/lib/hlm-command-list.ts.template +5 -11
  60. package/src/generators/ui/libs/command/files/lib/hlm-command-search-input.ts.template +8 -14
  61. package/src/generators/ui/libs/command/files/lib/hlm-command-search.ts.template +5 -11
  62. package/src/generators/ui/libs/command/files/lib/hlm-command-separator.ts.template +5 -9
  63. package/src/generators/ui/libs/command/files/lib/hlm-command-shortcut.ts.template +5 -8
  64. package/src/generators/ui/libs/command/files/lib/hlm-command.ts.template +5 -11
  65. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-close.ts.template +8 -12
  66. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-content.ts.template +6 -10
  67. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-description.ts.template +5 -6
  68. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-footer.ts.template +5 -8
  69. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-header.ts.template +5 -8
  70. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-overlay.ts.template +2 -2
  71. package/src/generators/ui/libs/dialog/files/lib/hlm-dialog-title.ts.template +5 -6
  72. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-checkbox-indicator.ts.template +8 -13
  73. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-checkbox.ts.template +9 -13
  74. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-group.ts.template +5 -6
  75. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-item-sub-indicator.ts.template +5 -8
  76. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-item.ts.template +9 -12
  77. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-label.ts.template +5 -8
  78. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-radio-indicator.ts.template +8 -13
  79. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-radio.ts.template +9 -13
  80. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-separator.ts.template +5 -6
  81. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-shortcut.ts.template +5 -8
  82. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu-sub.ts.template +7 -12
  83. package/src/generators/ui/libs/dropdown-menu/files/lib/hlm-dropdown-menu.ts.template +7 -12
  84. package/src/generators/ui/libs/empty/files/lib/hlm-empty-content.ts.template +5 -9
  85. package/src/generators/ui/libs/empty/files/lib/hlm-empty-description.ts.template +7 -12
  86. package/src/generators/ui/libs/empty/files/lib/hlm-empty-header.ts.template +5 -9
  87. package/src/generators/ui/libs/empty/files/lib/hlm-empty-media.ts.template +6 -9
  88. package/src/generators/ui/libs/empty/files/lib/hlm-empty-title.ts.template +5 -7
  89. package/src/generators/ui/libs/empty/files/lib/hlm-empty.ts.template +8 -12
  90. package/src/generators/ui/libs/field/files/lib/hlm-field-content.ts.template +5 -9
  91. package/src/generators/ui/libs/field/files/lib/hlm-field-description.ts.template +6 -11
  92. package/src/generators/ui/libs/field/files/lib/hlm-field-group.ts.template +8 -12
  93. package/src/generators/ui/libs/field/files/lib/hlm-field-label.ts.template +6 -11
  94. package/src/generators/ui/libs/field/files/lib/hlm-field-legend.ts.template +6 -9
  95. package/src/generators/ui/libs/field/files/lib/hlm-field-separator.ts.template +5 -9
  96. package/src/generators/ui/libs/field/files/lib/hlm-field-set.ts.template +6 -11
  97. package/src/generators/ui/libs/field/files/lib/hlm-field-title.ts.template +8 -12
  98. package/src/generators/ui/libs/field/files/lib/hlm-field.ts.template +5 -9
  99. package/src/generators/ui/libs/form-field/files/lib/hlm-error.ts.template +5 -10
  100. package/src/generators/ui/libs/form-field/files/lib/hlm-form-field.ts.template +3 -16
  101. package/src/generators/ui/libs/form-field/files/lib/hlm-hint.ts.template +5 -8
  102. package/src/generators/ui/libs/hover-card/files/lib/hlm-hover-card-content.ts.template +5 -11
  103. package/src/generators/ui/libs/input/files/lib/hlm-input.ts.template +4 -10
  104. package/src/generators/ui/libs/input-group/files/lib/hlm-input-group-addon.ts.template +5 -8
  105. package/src/generators/ui/libs/input-group/files/lib/hlm-input-group-button.ts.template +3 -12
  106. package/src/generators/ui/libs/input-group/files/lib/hlm-input-group-input.ts.template +3 -18
  107. package/src/generators/ui/libs/input-group/files/lib/hlm-input-group-text.ts.template +8 -14
  108. package/src/generators/ui/libs/input-group/files/lib/hlm-input-group-textarea.ts.template +6 -18
  109. package/src/generators/ui/libs/input-group/files/lib/hlm-input-group.ts.template +6 -12
  110. package/src/generators/ui/libs/input-otp/files/lib/hlm-input-otp-group.ts.template +5 -7
  111. package/src/generators/ui/libs/input-otp/files/lib/hlm-input-otp-separator.ts.template +5 -7
  112. package/src/generators/ui/libs/input-otp/files/lib/hlm-input-otp-slot.ts.template +6 -11
  113. package/src/generators/ui/libs/input-otp/files/lib/hlm-input-otp.ts.template +5 -9
  114. package/src/generators/ui/libs/item/files/lib/hlm-item-actions.ts.template +5 -6
  115. package/src/generators/ui/libs/item/files/lib/hlm-item-content.ts.template +5 -8
  116. package/src/generators/ui/libs/item/files/lib/hlm-item-description.ts.template +6 -10
  117. package/src/generators/ui/libs/item/files/lib/hlm-item-footer.ts.template +5 -8
  118. package/src/generators/ui/libs/item/files/lib/hlm-item-group.ts.template +6 -6
  119. package/src/generators/ui/libs/item/files/lib/hlm-item-header.ts.template +5 -8
  120. package/src/generators/ui/libs/item/files/lib/hlm-item-media.ts.template +6 -10
  121. package/src/generators/ui/libs/item/files/lib/hlm-item-separator.ts.template +6 -7
  122. package/src/generators/ui/libs/item/files/lib/hlm-item-title.ts.template +5 -8
  123. package/src/generators/ui/libs/item/files/lib/hlm-item.ts.template +6 -10
  124. package/src/generators/ui/libs/kbd/files/lib/hlm-kbd-group.ts.template +5 -6
  125. package/src/generators/ui/libs/kbd/files/lib/hlm-kbd.ts.template +6 -10
  126. package/src/generators/ui/libs/label/files/lib/hlm-label.ts.template +8 -14
  127. package/src/generators/ui/libs/menubar/files/lib/hlm-menubar-trigger.ts.template +6 -11
  128. package/src/generators/ui/libs/menubar/files/lib/hlm-menubar.ts.template +5 -8
  129. package/src/generators/ui/libs/navigation-menu/files/hlm-navigation-menu-content.ts.template +7 -13
  130. package/src/generators/ui/libs/navigation-menu/files/hlm-navigation-menu-item.ts.template +5 -8
  131. package/src/generators/ui/libs/navigation-menu/files/hlm-navigation-menu-link.ts.template +6 -12
  132. package/src/generators/ui/libs/navigation-menu/files/hlm-navigation-menu-list.ts.template +6 -12
  133. package/src/generators/ui/libs/navigation-menu/files/hlm-navigation-menu-trigger.ts.template +8 -13
  134. package/src/generators/ui/libs/navigation-menu/files/hlm-navigation-menu.ts.template +5 -10
  135. package/src/generators/ui/libs/pagination/files/lib/hlm-pagination-content.ts.template +5 -6
  136. package/src/generators/ui/libs/pagination/files/lib/hlm-pagination-ellipsis.ts.template +6 -6
  137. package/src/generators/ui/libs/pagination/files/lib/hlm-pagination-item.ts.template +5 -6
  138. package/src/generators/ui/libs/pagination/files/lib/hlm-pagination-link.ts.template +7 -12
  139. package/src/generators/ui/libs/pagination/files/lib/hlm-pagination-next.ts.template +5 -8
  140. package/src/generators/ui/libs/pagination/files/lib/hlm-pagination-previous.ts.template +4 -8
  141. package/src/generators/ui/libs/pagination/files/lib/hlm-pagination.ts.template +6 -7
  142. package/src/generators/ui/libs/popover/files/lib/hlm-popover-content.ts.template +7 -14
  143. package/src/generators/ui/libs/progress/files/lib/hlm-progress-indicator.ts.template +7 -15
  144. package/src/generators/ui/libs/progress/files/lib/hlm-progress.ts.template +5 -10
  145. package/src/generators/ui/libs/radio-group/files/lib/hlm-radio-group.ts.template +5 -6
  146. package/src/generators/ui/libs/radio-group/files/lib/hlm-radio-indicator.ts.template +8 -11
  147. package/src/generators/ui/libs/resizable/files/lib/hlm-resizable-group.ts.template +5 -9
  148. package/src/generators/ui/libs/resizable/files/lib/hlm-resizable-handle.ts.template +8 -12
  149. package/src/generators/ui/libs/resizable/files/lib/hlm-resizable-panel.ts.template +2 -8
  150. package/src/generators/ui/libs/scroll-area/files/lib/hlm-scroll-area.ts.template +5 -6
  151. package/src/generators/ui/libs/select/files/lib/hlm-select-content.ts.template +8 -11
  152. package/src/generators/ui/libs/select/files/lib/hlm-select-group.ts.template +2 -10
  153. package/src/generators/ui/libs/select/files/lib/hlm-select-label.ts.template +7 -12
  154. package/src/generators/ui/libs/select/files/lib/hlm-select-option.ts.template +8 -13
  155. package/src/generators/ui/libs/select/files/lib/hlm-select-scroll-down.ts.template +5 -10
  156. package/src/generators/ui/libs/select/files/lib/hlm-select-scroll-up.ts.template +5 -10
  157. package/src/generators/ui/libs/select/files/lib/hlm-select-value.ts.template +5 -10
  158. package/src/generators/ui/libs/select/files/lib/hlm-select.ts.template +5 -8
  159. package/src/generators/ui/libs/separator/files/lib/hlm-separator.ts.template +5 -8
  160. package/src/generators/ui/libs/sheet/files/lib/hlm-sheet-close.ts.template +8 -11
  161. package/src/generators/ui/libs/sheet/files/lib/hlm-sheet-content.ts.template +3 -19
  162. package/src/generators/ui/libs/sheet/files/lib/hlm-sheet-description.ts.template +5 -6
  163. package/src/generators/ui/libs/sheet/files/lib/hlm-sheet-footer.ts.template +5 -6
  164. package/src/generators/ui/libs/sheet/files/lib/hlm-sheet-header.ts.template +5 -6
  165. package/src/generators/ui/libs/sheet/files/lib/hlm-sheet-title.ts.template +5 -6
  166. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-content.ts.template +5 -11
  167. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-footer.ts.template +5 -6
  168. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-group-action.ts.template +6 -10
  169. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-group-content.ts.template +5 -6
  170. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-group-label.ts.template +6 -10
  171. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-group.ts.template +5 -8
  172. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-header.ts.template +5 -6
  173. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-input.ts.template +7 -8
  174. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-inset.ts.template +6 -10
  175. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu-action.ts.template +7 -10
  176. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu-badge.ts.template +6 -10
  177. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu-button.ts.template +5 -7
  178. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu-item.ts.template +5 -6
  179. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu-skeleton.ts.template +6 -8
  180. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu-sub-button.ts.template +6 -10
  181. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu-sub-item.ts.template +5 -6
  182. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu-sub.ts.template +6 -10
  183. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-menu.ts.template +5 -6
  184. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-rail.ts.template +6 -10
  185. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-separator.ts.template +5 -6
  186. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar-wrapper.ts.template +6 -9
  187. package/src/generators/ui/libs/sidebar/files/lib/hlm-sidebar.ts.template +11 -14
  188. package/src/generators/ui/libs/skeleton/files/lib/hlm-skeleton.ts.template +5 -8
  189. package/src/generators/ui/libs/slider/files/lib/hlm-slider.ts.template +5 -14
  190. package/src/generators/ui/libs/spinner/files/lib/hlm-spinner.ts.template +6 -7
  191. package/src/generators/ui/libs/switch/files/lib/hlm-switch-thumb.ts.template +8 -14
  192. package/src/generators/ui/libs/table/files/lib/hlm-table.ts.template +39 -79
  193. package/src/generators/ui/libs/tabs/files/lib/hlm-tabs-content.ts.template +8 -11
  194. package/src/generators/ui/libs/tabs/files/lib/hlm-tabs-list.ts.template +5 -8
  195. package/src/generators/ui/libs/tabs/files/lib/hlm-tabs-paginated-list.ts.template +6 -7
  196. package/src/generators/ui/libs/tabs/files/lib/hlm-tabs-trigger.ts.template +8 -11
  197. package/src/generators/ui/libs/tabs/files/lib/hlm-tabs.ts.template +5 -6
  198. package/src/generators/ui/libs/textarea/files/lib/hlm-textarea.ts.template +4 -8
  199. package/src/generators/ui/libs/toggle/files/lib/hlm-toggle.ts.template +6 -11
  200. package/src/generators/ui/libs/toggle-group/files/lib/hlm-toggle-group-item.ts.template +7 -12
  201. package/src/generators/ui/libs/toggle-group/files/lib/hlm-toggle-group.ts.template +5 -11
  202. package/src/generators/ui/libs/typography/files/lib/hlm-blockquote.ts.template +5 -8
  203. package/src/generators/ui/libs/typography/files/lib/hlm-code.ts.template +5 -8
  204. package/src/generators/ui/libs/typography/files/lib/hlm-h1.ts.template +5 -8
  205. package/src/generators/ui/libs/typography/files/lib/hlm-h2.ts.template +5 -8
  206. package/src/generators/ui/libs/typography/files/lib/hlm-h3.ts.template +5 -8
  207. package/src/generators/ui/libs/typography/files/lib/hlm-h4.ts.template +5 -8
  208. package/src/generators/ui/libs/typography/files/lib/hlm-large.ts.template +5 -8
  209. package/src/generators/ui/libs/typography/files/lib/hlm-lead.ts.template +5 -8
  210. package/src/generators/ui/libs/typography/files/lib/hlm-muted.ts.template +5 -8
  211. package/src/generators/ui/libs/typography/files/lib/hlm-p.ts.template +5 -8
  212. package/src/generators/ui/libs/typography/files/lib/hlm-small.ts.template +5 -8
  213. package/src/generators/ui/libs/typography/files/lib/hlm-ul.ts.template +5 -8
  214. package/src/generators/ui/libs/utils/files/lib/hlm.ts.template +251 -0
  215. package/src/generators/ui/supported-ui-libraries.json +66 -97
@@ -1,16 +1,13 @@
1
- import { Directive, computed, input } from '@angular/core';
2
- import { hlm } from '<%- importAlias %>/utils';
3
- import type { ClassValue } from 'clsx';
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
4
3
 
5
4
  export const hlmH4 = 'scroll-m-20 text-xl font-semibold tracking-tight';
6
5
 
7
6
  @Directive({
8
7
  selector: '[hlmH4]',
9
- host: {
10
- '[class]': '_computedClass()',
11
- },
12
8
  })
13
9
  export class HlmH4 {
14
- public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
- protected readonly _computedClass = computed(() => hlm(hlmH4, this.userClass()));
10
+ constructor() {
11
+ classes(() => hlmH4);
12
+ }
16
13
  }
@@ -1,16 +1,13 @@
1
- import { Directive, computed, input } from '@angular/core';
2
- import { hlm } from '<%- importAlias %>/utils';
3
- import type { ClassValue } from 'clsx';
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
4
3
 
5
4
  export const hlmLarge = 'text-lg font-semibold';
6
5
 
7
6
  @Directive({
8
7
  selector: '[hlmLarge]',
9
- host: {
10
- '[class]': '_computedClass()',
11
- },
12
8
  })
13
9
  export class HlmLarge {
14
- public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
- protected readonly _computedClass = computed(() => hlm(hlmLarge, this.userClass()));
10
+ constructor() {
11
+ classes(() => hlmLarge);
12
+ }
16
13
  }
@@ -1,16 +1,13 @@
1
- import { Directive, computed, input } from '@angular/core';
2
- import { hlm } from '<%- importAlias %>/utils';
3
- import type { ClassValue } from 'clsx';
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
4
3
 
5
4
  export const hlmLead = 'text-xl text-muted-foreground';
6
5
 
7
6
  @Directive({
8
7
  selector: '[hlmLead]',
9
- host: {
10
- '[class]': '_computedClass()',
11
- },
12
8
  })
13
9
  export class HlmLead {
14
- public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
- protected readonly _computedClass = computed(() => hlm(hlmLead, this.userClass()));
10
+ constructor() {
11
+ classes(() => hlmLead);
12
+ }
16
13
  }
@@ -1,16 +1,13 @@
1
- import { Directive, computed, input } from '@angular/core';
2
- import { hlm } from '<%- importAlias %>/utils';
3
- import type { ClassValue } from 'clsx';
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
4
3
 
5
4
  export const hlmMuted = 'text-sm text-muted-foreground';
6
5
 
7
6
  @Directive({
8
7
  selector: '[hlmMuted]',
9
- host: {
10
- '[class]': '_computedClass()',
11
- },
12
8
  })
13
9
  export class HlmMuted {
14
- public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
- protected readonly _computedClass = computed(() => hlm(hlmMuted, this.userClass()));
10
+ constructor() {
11
+ classes(() => hlmMuted);
12
+ }
16
13
  }
@@ -1,16 +1,13 @@
1
- import { Directive, computed, input } from '@angular/core';
2
- import { hlm } from '<%- importAlias %>/utils';
3
- import type { ClassValue } from 'clsx';
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
4
3
 
5
4
  export const hlmP = 'leading-7 [&:not(:first-child)]:mt-6';
6
5
 
7
6
  @Directive({
8
7
  selector: '[hlmP]',
9
- host: {
10
- '[class]': '_computedClass()',
11
- },
12
8
  })
13
9
  export class HlmP {
14
- public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
- protected readonly _computedClass = computed(() => hlm(hlmP, this.userClass()));
10
+ constructor() {
11
+ classes(() => hlmP);
12
+ }
16
13
  }
@@ -1,16 +1,13 @@
1
- import { Directive, computed, input } from '@angular/core';
2
- import { hlm } from '<%- importAlias %>/utils';
3
- import type { ClassValue } from 'clsx';
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
4
3
 
5
4
  export const hlmSmall = 'text-sm font-medium leading-none';
6
5
 
7
6
  @Directive({
8
7
  selector: '[hlmSmall]',
9
- host: {
10
- '[class]': '_computedClass()',
11
- },
12
8
  })
13
9
  export class HlmSmall {
14
- public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
- protected readonly _computedClass = computed(() => hlm(hlmSmall, this.userClass()));
10
+ constructor() {
11
+ classes(() => hlmSmall);
12
+ }
16
13
  }
@@ -1,16 +1,13 @@
1
- import { Directive, computed, input } from '@angular/core';
2
- import { hlm } from '<%- importAlias %>/utils';
3
- import type { ClassValue } from 'clsx';
1
+ import { Directive } from '@angular/core';
2
+ import { classes } from '<%- importAlias %>/utils';
4
3
 
5
4
  export const hlmUl = 'my-6 ml-6 list-disc [&>li]:mt-2';
6
5
 
7
6
  @Directive({
8
7
  selector: '[hlmUl]',
9
- host: {
10
- '[class]': '_computedClass()',
11
- },
12
8
  })
13
9
  export class HlmUl {
14
- public readonly userClass = input<ClassValue>('', { alias: 'class' });
15
- protected readonly _computedClass = computed(() => hlm(hlmUl, this.userClass()));
10
+ constructor() {
11
+ classes(() => hlmUl);
12
+ }
16
13
  }
@@ -1,6 +1,257 @@
1
+ import { isPlatformBrowser } from '@angular/common';
2
+ import {
3
+ DestroyRef,
4
+ effect,
5
+ ElementRef,
6
+ HostAttributeToken,
7
+ inject,
8
+ Injector,
9
+ PLATFORM_ID,
10
+ runInInjectionContext,
11
+ } from '@angular/core';
1
12
  import { type ClassValue, clsx } from 'clsx';
2
13
  import { twMerge } from 'tailwind-merge';
3
14
 
4
15
  export function hlm(...inputs: ClassValue[]) {
5
16
  return twMerge(clsx(inputs));
6
17
  }
18
+
19
+ // Global map to track class managers per element
20
+ const elementClassManagers = new WeakMap<HTMLElement, ElementClassManager>();
21
+
22
+ // Global mutation observer for all elements
23
+ let globalObserver: MutationObserver | null = null;
24
+ const observedElements = new Set<HTMLElement>();
25
+
26
+ interface ElementClassManager {
27
+ element: HTMLElement;
28
+ sources: Map<number, { classes: Set<string>; order: number }>;
29
+ baseClasses: Set<string>;
30
+ isUpdating: boolean;
31
+ nextOrder: number;
32
+ hasInitialized: boolean;
33
+ }
34
+
35
+ let sourceCounter = 0;
36
+
37
+ /**
38
+ * This function dynamically adds and removes classes for a given element without requiring
39
+ * the a class binding (e.g. `[class]="..."`) which may interfere with other class bindings.
40
+ *
41
+ * 1. This will merge the existing classes on the element with the new classes.
42
+ * 2. It will also remove any classes that were previously added by this function but are no longer present in the new classes.
43
+ * 3. Multiple calls to this function on the same element will be merged efficiently.
44
+ */
45
+ export function classes(computed: () => ClassValue[] | string, options: ClassesOptions = {}) {
46
+ runInInjectionContext(options.injector ?? inject(Injector), () => {
47
+ const elementRef = options.elementRef ?? inject(ElementRef);
48
+ const platformId = inject(PLATFORM_ID);
49
+ const destroyRef = inject(DestroyRef);
50
+ const baseClasses = inject(new HostAttributeToken('class'), { optional: true });
51
+
52
+ const element = elementRef.nativeElement;
53
+
54
+ // Create unique identifier for this source
55
+ const sourceId = sourceCounter++;
56
+
57
+ // Get or create the class manager for this element
58
+ let manager = elementClassManagers.get(element);
59
+
60
+ if (!manager) {
61
+ // Initialize base classes from variation (host attribute 'class')
62
+ const initialBaseClasses = new Set<string>();
63
+
64
+ if (baseClasses) {
65
+ toClassList(baseClasses).forEach((cls) => initialBaseClasses.add(cls));
66
+ }
67
+
68
+ manager = {
69
+ element,
70
+ sources: new Map(),
71
+ baseClasses: initialBaseClasses,
72
+ isUpdating: false,
73
+ nextOrder: 0,
74
+ hasInitialized: false,
75
+ };
76
+ elementClassManagers.set(element, manager);
77
+
78
+ // Setup global observer if needed and register this element
79
+ setupGlobalObserver(platformId);
80
+ observedElements.add(element);
81
+ }
82
+
83
+ // Assign order once at registration time
84
+ const sourceOrder = manager.nextOrder++;
85
+
86
+ function updateClasses(): void {
87
+ // Get the new classes from the computed function
88
+ const newClasses = toClassList(computed());
89
+
90
+ // Update this source's classes, keeping the original order
91
+ manager!.sources.set(sourceId, {
92
+ classes: new Set(newClasses),
93
+ order: sourceOrder,
94
+ });
95
+
96
+ // Update the element
97
+ updateElement(manager!);
98
+ }
99
+
100
+ // Register cleanup with DestroyRef
101
+ destroyRef.onDestroy(() => {
102
+ // Remove this source from the manager
103
+ manager!.sources.delete(sourceId);
104
+
105
+ // If no more sources, clean up the manager
106
+ if (manager!.sources.size === 0) {
107
+ cleanupManager(element);
108
+ } else {
109
+ // Update element without this source's classes
110
+ updateElement(manager!);
111
+ }
112
+ });
113
+
114
+ /**
115
+ * We need this effect to track changes to the computed classes. Ideally, we would use
116
+ * afterRenderEffect here, but that doesn't run in SSR contexts, so we use a standard
117
+ * effect which works in both browser and SSR.
118
+ */
119
+ effect(updateClasses);
120
+ });
121
+ }
122
+
123
+ // eslint-disable-next-line @typescript-eslint/no-wrapper-object-types
124
+ function setupGlobalObserver(platformId: Object): void {
125
+ if (isPlatformBrowser(platformId) && !globalObserver) {
126
+ // Create single global observer that watches the entire document
127
+ globalObserver = new MutationObserver((mutations) => {
128
+ for (const mutation of mutations) {
129
+ if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
130
+ const element = mutation.target as HTMLElement;
131
+ const manager = elementClassManagers.get(element);
132
+
133
+ // Only process elements we're managing
134
+ if (manager && observedElements.has(element)) {
135
+ if (manager.isUpdating) continue; // Ignore changes we're making
136
+
137
+ // Update base classes to include any externally added classes
138
+ const currentClasses = toClassList(element.className);
139
+ const allSourceClasses = new Set<string>();
140
+
141
+ // Collect all classes from all sources
142
+ for (const source of manager.sources.values()) {
143
+ for (const className of source.classes) {
144
+ allSourceClasses.add(className);
145
+ }
146
+ }
147
+
148
+ // Any classes not from sources become new base classes
149
+ manager.baseClasses.clear();
150
+
151
+ for (const className of currentClasses) {
152
+ if (!allSourceClasses.has(className)) {
153
+ manager.baseClasses.add(className);
154
+ }
155
+ }
156
+
157
+ updateElement(manager);
158
+ }
159
+ }
160
+ }
161
+ });
162
+
163
+ // Start observing the entire document for class attribute changes
164
+ globalObserver.observe(document, {
165
+ attributes: true,
166
+ attributeFilter: ['class'],
167
+ subtree: true, // Watch all descendants
168
+ });
169
+ }
170
+ }
171
+
172
+ function updateElement(manager: ElementClassManager): void {
173
+ if (manager.isUpdating) return; // Prevent recursive updates
174
+
175
+ manager.isUpdating = true;
176
+
177
+ // Handle initialization: capture base classes after first source registration
178
+ if (!manager.hasInitialized && manager.sources.size > 0) {
179
+ // Get current classes on element (may include SSR classes)
180
+ const currentClasses = toClassList(manager.element.className);
181
+
182
+ // Get all classes that will be applied by sources
183
+ const allSourceClasses = new Set<string>();
184
+ for (const source of manager.sources.values()) {
185
+ source.classes.forEach((className) => allSourceClasses.add(className));
186
+ }
187
+
188
+ // Only consider classes as "base" if they're not produced by any source
189
+ // This prevents SSR-rendered classes from being preserved as base classes
190
+ currentClasses.forEach((className) => {
191
+ if (!allSourceClasses.has(className)) {
192
+ manager.baseClasses.add(className);
193
+ }
194
+ });
195
+
196
+ manager.hasInitialized = true;
197
+ }
198
+
199
+ // Get classes from all sources, sorted by registration order (later takes precedence)
200
+ const sortedSources = Array.from(manager.sources.entries()).sort(([, a], [, b]) => a.order - b.order);
201
+
202
+ const allSourceClasses: string[] = [];
203
+ for (const [, source] of sortedSources) {
204
+ allSourceClasses.push(...source.classes);
205
+ }
206
+
207
+ // Combine base classes with all source classes, ensuring base classes take precedence
208
+ const classesToApply =
209
+ allSourceClasses.length > 0 || manager.baseClasses.size > 0
210
+ ? twMerge(clsx([...allSourceClasses, ...manager.baseClasses]))
211
+ : '';
212
+
213
+ // Apply the classes to the element
214
+ if (manager.element.className !== classesToApply) {
215
+ manager.element.className = classesToApply;
216
+ }
217
+
218
+ manager.isUpdating = false;
219
+ }
220
+
221
+ function cleanupManager(element: HTMLElement): void {
222
+ // Remove from global tracking
223
+ observedElements.delete(element);
224
+ elementClassManagers.delete(element);
225
+
226
+ // If no more elements being tracked, cleanup global observer
227
+ if (observedElements.size === 0 && globalObserver) {
228
+ globalObserver.disconnect();
229
+ globalObserver = null;
230
+ }
231
+ }
232
+
233
+ interface ClassesOptions {
234
+ elementRef?: ElementRef<HTMLElement>;
235
+ injector?: Injector;
236
+ }
237
+
238
+ // Cache for parsed class lists to avoid repeated string operations
239
+ const classListCache = new Map<string, string[]>();
240
+
241
+ function toClassList(className: string | ClassValue[]): string[] {
242
+ // For simple string inputs, use cache to avoid repeated parsing
243
+ if (typeof className === 'string' && classListCache.has(className)) {
244
+ return classListCache.get(className)!;
245
+ }
246
+
247
+ const result = clsx(className)
248
+ .split(' ')
249
+ .filter((c) => c.length > 0);
250
+
251
+ // Cache string results, but limit cache size to prevent memory growth
252
+ if (typeof className === 'string' && classListCache.size < 1000) {
253
+ classListCache.set(className, result);
254
+ }
255
+
256
+ return result;
257
+ }