@ng-cn/core 1.0.15 → 1.0.17

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 (380) hide show
  1. package/package.json +34 -33
  2. package/schematics/component/index.js +454 -95
  3. package/schematics/component/index.ts +459 -98
  4. package/schematics/ng-add/index.js +539 -55
  5. package/schematics/ng-add/index.ts +555 -62
  6. package/schematics/ng-add/schema.json +8 -2
  7. package/schematics/test-schematic.js +1 -2
  8. package/src/app/lib/components/ui/.gitkeep +0 -0
  9. package/src/app/lib/components/ui/accordion/accordion-content.component.ts +16 -24
  10. package/src/app/lib/components/ui/accordion/accordion-context.ts +4 -9
  11. package/src/app/lib/components/ui/accordion/accordion-item.component.ts +33 -29
  12. package/src/app/lib/components/ui/accordion/accordion-trigger.component.ts +11 -14
  13. package/src/app/lib/components/ui/accordion/accordion.component.ts +60 -49
  14. package/src/app/lib/components/ui/accordion/index.ts +5 -6
  15. package/src/app/lib/components/ui/alert/alert-description.component.ts +3 -8
  16. package/src/app/lib/components/ui/alert/alert-title.component.ts +2 -7
  17. package/src/app/lib/components/ui/alert/alert-variants.ts +19 -5
  18. package/src/app/lib/components/ui/alert/alert.component.ts +2 -10
  19. package/src/app/lib/components/ui/alert/index.ts +0 -1
  20. package/src/app/lib/components/ui/alert-dialog/alert-dialog-action.component.ts +5 -12
  21. package/src/app/lib/components/ui/alert-dialog/alert-dialog-cancel.component.ts +5 -11
  22. package/src/app/lib/components/ui/alert-dialog/alert-dialog-content.component.ts +63 -66
  23. package/src/app/lib/components/ui/alert-dialog/alert-dialog-context.ts +10 -5
  24. package/src/app/lib/components/ui/alert-dialog/alert-dialog-description.component.ts +5 -10
  25. package/src/app/lib/components/ui/alert-dialog/alert-dialog-footer.component.ts +3 -7
  26. package/src/app/lib/components/ui/alert-dialog/alert-dialog-header.component.ts +3 -7
  27. package/src/app/lib/components/ui/alert-dialog/alert-dialog-title.component.ts +5 -12
  28. package/src/app/lib/components/ui/alert-dialog/alert-dialog-trigger.component.ts +8 -12
  29. package/src/app/lib/components/ui/alert-dialog/alert-dialog.component.ts +28 -34
  30. package/src/app/lib/components/ui/alert-dialog/index.ts +0 -1
  31. package/src/app/lib/components/ui/aspect-ratio/aspect-ratio.component.ts +3 -9
  32. package/src/app/lib/components/ui/avatar/avatar-context.ts +9 -0
  33. package/src/app/lib/components/ui/avatar/avatar-fallback.component.ts +7 -18
  34. package/src/app/lib/components/ui/avatar/avatar-image.component.ts +39 -17
  35. package/src/app/lib/components/ui/avatar/avatar.component.ts +17 -20
  36. package/src/app/lib/components/ui/avatar/index.ts +1 -1
  37. package/src/app/lib/components/ui/avatar/ui-avatar.component.ts +9 -30
  38. package/src/app/lib/components/ui/badge/badge-variants.ts +5 -5
  39. package/src/app/lib/components/ui/badge/badge.component.ts +4 -8
  40. package/src/app/lib/components/ui/badge/index.ts +0 -1
  41. package/src/app/lib/components/ui/breadcrumb/breadcrumb-ellipsis.component.ts +3 -7
  42. package/src/app/lib/components/ui/breadcrumb/breadcrumb-item.component.ts +5 -14
  43. package/src/app/lib/components/ui/breadcrumb/breadcrumb-link.component.ts +6 -18
  44. package/src/app/lib/components/ui/breadcrumb/breadcrumb-list.component.ts +6 -15
  45. package/src/app/lib/components/ui/breadcrumb/breadcrumb-page.component.ts +3 -7
  46. package/src/app/lib/components/ui/breadcrumb/breadcrumb-separator.component.ts +22 -31
  47. package/src/app/lib/components/ui/breadcrumb/breadcrumb.component.ts +3 -9
  48. package/src/app/lib/components/ui/breadcrumb/index.ts +0 -1
  49. package/src/app/lib/components/ui/button/button-variants.ts +6 -8
  50. package/src/app/lib/components/ui/button/button.component.ts +4 -8
  51. package/src/app/lib/components/ui/button/index.ts +0 -1
  52. package/src/app/lib/components/ui/button-group/button-group-variants.ts +12 -15
  53. package/src/app/lib/components/ui/button-group/button-group.component.ts +6 -14
  54. package/src/app/lib/components/ui/button-group/index.ts +1 -5
  55. package/src/app/lib/components/ui/calendar/calendar.component.ts +103 -115
  56. package/src/app/lib/components/ui/card/card-action.component.ts +2 -10
  57. package/src/app/lib/components/ui/card/card-content.component.ts +1 -6
  58. package/src/app/lib/components/ui/card/card-description.component.ts +2 -7
  59. package/src/app/lib/components/ui/card/card-footer.component.ts +2 -7
  60. package/src/app/lib/components/ui/card/card-header.component.ts +3 -8
  61. package/src/app/lib/components/ui/card/card-title.component.ts +2 -9
  62. package/src/app/lib/components/ui/card/card.component.ts +3 -8
  63. package/src/app/lib/components/ui/card/index.ts +0 -1
  64. package/src/app/lib/components/ui/carousel/carousel-content.component.ts +3 -9
  65. package/src/app/lib/components/ui/carousel/carousel-item.component.ts +5 -5
  66. package/src/app/lib/components/ui/carousel/carousel-next.component.ts +9 -8
  67. package/src/app/lib/components/ui/carousel/carousel-previous.component.ts +9 -8
  68. package/src/app/lib/components/ui/carousel/carousel.component.ts +14 -25
  69. package/src/app/lib/components/ui/carousel/index.ts +5 -2
  70. package/src/app/lib/components/ui/chart/chart-container.component.ts +20 -26
  71. package/src/app/lib/components/ui/chart/chart-legend-content.component.ts +6 -16
  72. package/src/app/lib/components/ui/chart/chart-legend.component.ts +2 -7
  73. package/src/app/lib/components/ui/chart/chart-tooltip-content.component.ts +2 -9
  74. package/src/app/lib/components/ui/chart/chart-tooltip.component.ts +2 -7
  75. package/src/app/lib/components/ui/chart/chart.component.ts +12 -32
  76. package/src/app/lib/components/ui/chart/index.ts +7 -8
  77. package/src/app/lib/components/ui/checkbox/checkbox.component.ts +55 -74
  78. package/src/app/lib/components/ui/collapsible/collapsible-content.component.ts +16 -25
  79. package/src/app/lib/components/ui/collapsible/collapsible-context.ts +0 -8
  80. package/src/app/lib/components/ui/collapsible/collapsible-trigger.component.ts +6 -16
  81. package/src/app/lib/components/ui/collapsible/collapsible.component.ts +29 -33
  82. package/src/app/lib/components/ui/collapsible/index.ts +0 -1
  83. package/src/app/lib/components/ui/combobox/combobox-content.component.ts +8 -15
  84. package/src/app/lib/components/ui/combobox/combobox-context.ts +5 -4
  85. package/src/app/lib/components/ui/combobox/combobox-empty.component.ts +5 -12
  86. package/src/app/lib/components/ui/combobox/combobox-group.component.ts +3 -7
  87. package/src/app/lib/components/ui/combobox/combobox-input.component.ts +25 -25
  88. package/src/app/lib/components/ui/combobox/combobox-item.component.ts +45 -44
  89. package/src/app/lib/components/ui/combobox/combobox-list.component.ts +14 -12
  90. package/src/app/lib/components/ui/combobox/combobox-trigger.component.ts +24 -14
  91. package/src/app/lib/components/ui/combobox/combobox-value.component.ts +27 -22
  92. package/src/app/lib/components/ui/combobox/combobox.component.ts +74 -54
  93. package/src/app/lib/components/ui/combobox/index.ts +1 -6
  94. package/src/app/lib/components/ui/command/command-context.ts +1 -5
  95. package/src/app/lib/components/ui/command/command-dialog.component.ts +12 -14
  96. package/src/app/lib/components/ui/command/command-empty.component.ts +2 -3
  97. package/src/app/lib/components/ui/command/command-group.component.ts +32 -25
  98. package/src/app/lib/components/ui/command/command-input.component.ts +29 -28
  99. package/src/app/lib/components/ui/command/command-item.component.ts +46 -58
  100. package/src/app/lib/components/ui/command/command-list.component.ts +5 -4
  101. package/src/app/lib/components/ui/command/command-separator.component.ts +2 -3
  102. package/src/app/lib/components/ui/command/command-shortcut.component.ts +2 -1
  103. package/src/app/lib/components/ui/command/command.component.ts +33 -22
  104. package/src/app/lib/components/ui/command/index.ts +0 -1
  105. package/src/app/lib/components/ui/context-menu/context-menu-checkbox-item.component.ts +20 -11
  106. package/src/app/lib/components/ui/context-menu/context-menu-content.component.ts +36 -43
  107. package/src/app/lib/components/ui/context-menu/context-menu-context.ts +1 -1
  108. package/src/app/lib/components/ui/context-menu/context-menu-item.component.ts +12 -13
  109. package/src/app/lib/components/ui/context-menu/context-menu-label.component.ts +2 -5
  110. package/src/app/lib/components/ui/context-menu/context-menu-radio-group.component.ts +9 -2
  111. package/src/app/lib/components/ui/context-menu/context-menu-radio-item.component.ts +14 -14
  112. package/src/app/lib/components/ui/context-menu/context-menu-separator.component.ts +2 -3
  113. package/src/app/lib/components/ui/context-menu/context-menu-shortcut.component.ts +2 -1
  114. package/src/app/lib/components/ui/context-menu/context-menu-sub-content.component.ts +5 -5
  115. package/src/app/lib/components/ui/context-menu/context-menu-sub-trigger.component.ts +8 -7
  116. package/src/app/lib/components/ui/context-menu/context-menu-sub.component.ts +9 -2
  117. package/src/app/lib/components/ui/context-menu/context-menu-trigger.component.ts +8 -7
  118. package/src/app/lib/components/ui/context-menu/context-menu.component.ts +1 -0
  119. package/src/app/lib/components/ui/context-menu/index.ts +15 -4
  120. package/src/app/lib/components/ui/data-table/data-table-content.component.ts +22 -28
  121. package/src/app/lib/components/ui/data-table/data-table-context.ts +1 -3
  122. package/src/app/lib/components/ui/data-table/data-table-pagination.component.ts +17 -27
  123. package/src/app/lib/components/ui/data-table/data-table-search.component.ts +6 -14
  124. package/src/app/lib/components/ui/data-table/data-table-toolbar.component.ts +3 -7
  125. package/src/app/lib/components/ui/data-table/data-table-view-options.component.ts +11 -20
  126. package/src/app/lib/components/ui/data-table/data-table.component.ts +41 -49
  127. package/src/app/lib/components/ui/data-table/index.ts +7 -8
  128. package/src/app/lib/components/ui/date-picker/date-picker.component.ts +24 -24
  129. package/src/app/lib/components/ui/dialog/dialog-close.component.ts +4 -8
  130. package/src/app/lib/components/ui/dialog/dialog-content.component.ts +72 -73
  131. package/src/app/lib/components/ui/dialog/dialog-context.ts +7 -5
  132. package/src/app/lib/components/ui/dialog/dialog-description.component.ts +5 -10
  133. package/src/app/lib/components/ui/dialog/dialog-footer.component.ts +3 -7
  134. package/src/app/lib/components/ui/dialog/dialog-header.component.ts +3 -7
  135. package/src/app/lib/components/ui/dialog/dialog-title.component.ts +5 -10
  136. package/src/app/lib/components/ui/dialog/dialog-trigger.component.ts +7 -11
  137. package/src/app/lib/components/ui/dialog/dialog.component.ts +29 -34
  138. package/src/app/lib/components/ui/dialog/index.ts +0 -1
  139. package/src/app/lib/components/ui/drawer/drawer-close.component.ts +4 -8
  140. package/src/app/lib/components/ui/drawer/drawer-content.component.ts +39 -35
  141. package/src/app/lib/components/ui/drawer/drawer-description.component.ts +5 -10
  142. package/src/app/lib/components/ui/drawer/drawer-footer.component.ts +3 -7
  143. package/src/app/lib/components/ui/drawer/drawer-header.component.ts +3 -7
  144. package/src/app/lib/components/ui/drawer/drawer-title.component.ts +5 -10
  145. package/src/app/lib/components/ui/drawer/drawer-trigger.component.ts +7 -11
  146. package/src/app/lib/components/ui/drawer/drawer.component.ts +25 -26
  147. package/src/app/lib/components/ui/drawer/index.ts +0 -1
  148. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.component.ts +20 -11
  149. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-content.component.ts +96 -61
  150. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-context.ts +1 -1
  151. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-group.component.ts +1 -0
  152. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-item.component.ts +10 -11
  153. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-label.component.ts +2 -5
  154. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.component.ts +14 -5
  155. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.component.ts +14 -14
  156. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-separator.component.ts +2 -3
  157. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.component.ts +2 -1
  158. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.component.ts +5 -5
  159. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.component.ts +8 -7
  160. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub.component.ts +9 -2
  161. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-trigger.component.ts +6 -5
  162. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu.component.ts +1 -0
  163. package/src/app/lib/components/ui/dropdown-menu/index.ts +10 -3
  164. package/src/app/lib/components/ui/empty/empty-action.component.ts +2 -9
  165. package/src/app/lib/components/ui/empty/empty-description.component.ts +2 -10
  166. package/src/app/lib/components/ui/empty/empty-icon.component.ts +3 -8
  167. package/src/app/lib/components/ui/empty/empty-title.component.ts +2 -9
  168. package/src/app/lib/components/ui/empty/empty.component.ts +3 -8
  169. package/src/app/lib/components/ui/empty/index.ts +0 -1
  170. package/src/app/lib/components/ui/form/form-context.ts +1 -11
  171. package/src/app/lib/components/ui/form/form-control.component.ts +22 -22
  172. package/src/app/lib/components/ui/form/form-description.component.ts +4 -10
  173. package/src/app/lib/components/ui/form/form-field.component.ts +7 -10
  174. package/src/app/lib/components/ui/form/form-item.component.ts +2 -12
  175. package/src/app/lib/components/ui/form/form-label.component.ts +15 -15
  176. package/src/app/lib/components/ui/form/form-message.component.ts +7 -15
  177. package/src/app/lib/components/ui/form/form.component.ts +9 -20
  178. package/src/app/lib/components/ui/form/index.ts +4 -5
  179. package/src/app/lib/components/ui/hover-card/hover-card-content.component.ts +21 -33
  180. package/src/app/lib/components/ui/hover-card/hover-card-context.ts +0 -8
  181. package/src/app/lib/components/ui/hover-card/hover-card-trigger.component.ts +17 -26
  182. package/src/app/lib/components/ui/hover-card/hover-card.component.ts +18 -28
  183. package/src/app/lib/components/ui/hover-card/index.ts +9 -6
  184. package/src/app/lib/components/ui/input/input.component.ts +57 -75
  185. package/src/app/lib/components/ui/input-group/index.ts +0 -1
  186. package/src/app/lib/components/ui/input-group/input-group-addon.component.ts +4 -11
  187. package/src/app/lib/components/ui/input-group/input-group-input.component.ts +3 -8
  188. package/src/app/lib/components/ui/input-group/input-group.component.ts +4 -9
  189. package/src/app/lib/components/ui/input-otp/index.ts +4 -5
  190. package/src/app/lib/components/ui/input-otp/input-otp-context.ts +0 -8
  191. package/src/app/lib/components/ui/input-otp/input-otp-group.component.ts +2 -3
  192. package/src/app/lib/components/ui/input-otp/input-otp-separator.component.ts +4 -3
  193. package/src/app/lib/components/ui/input-otp/input-otp-slot.component.ts +8 -10
  194. package/src/app/lib/components/ui/input-otp/input-otp.component.ts +27 -45
  195. package/src/app/lib/components/ui/kbd/index.ts +0 -1
  196. package/src/app/lib/components/ui/kbd/kbd-variants.ts +1 -1
  197. package/src/app/lib/components/ui/kbd/kbd.component.ts +4 -8
  198. package/src/app/lib/components/ui/label/label.component.ts +15 -28
  199. package/src/app/lib/components/ui/menubar/index.ts +11 -8
  200. package/src/app/lib/components/ui/menubar/menubar-checkbox-item.component.ts +21 -12
  201. package/src/app/lib/components/ui/menubar/menubar-content.component.ts +46 -53
  202. package/src/app/lib/components/ui/menubar/menubar-context.ts +3 -9
  203. package/src/app/lib/components/ui/menubar/menubar-item.component.ts +13 -14
  204. package/src/app/lib/components/ui/menubar/menubar-label.component.ts +2 -5
  205. package/src/app/lib/components/ui/menubar/menubar-menu.component.ts +14 -2
  206. package/src/app/lib/components/ui/menubar/menubar-radio-group.component.ts +9 -2
  207. package/src/app/lib/components/ui/menubar/menubar-radio-item.component.ts +13 -13
  208. package/src/app/lib/components/ui/menubar/menubar-separator.component.ts +2 -3
  209. package/src/app/lib/components/ui/menubar/menubar-shortcut.component.ts +2 -1
  210. package/src/app/lib/components/ui/menubar/menubar-sub-content.component.ts +5 -5
  211. package/src/app/lib/components/ui/menubar/menubar-sub-trigger.component.ts +7 -6
  212. package/src/app/lib/components/ui/menubar/menubar-sub.component.ts +8 -1
  213. package/src/app/lib/components/ui/menubar/menubar-trigger.component.ts +26 -21
  214. package/src/app/lib/components/ui/menubar/menubar.component.ts +6 -13
  215. package/src/app/lib/components/ui/native-select/index.ts +1 -5
  216. package/src/app/lib/components/ui/native-select/native-select-variants.ts +1 -1
  217. package/src/app/lib/components/ui/native-select/native-select.component.ts +14 -15
  218. package/src/app/lib/components/ui/navigation-menu/index.ts +10 -8
  219. package/src/app/lib/components/ui/navigation-menu/navigation-menu-content.component.ts +18 -13
  220. package/src/app/lib/components/ui/navigation-menu/navigation-menu-context.ts +2 -10
  221. package/src/app/lib/components/ui/navigation-menu/navigation-menu-indicator.component.ts +3 -2
  222. package/src/app/lib/components/ui/navigation-menu/navigation-menu-item.component.ts +6 -1
  223. package/src/app/lib/components/ui/navigation-menu/navigation-menu-link.component.ts +3 -8
  224. package/src/app/lib/components/ui/navigation-menu/navigation-menu-list.component.ts +2 -4
  225. package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger-style.ts +1 -1
  226. package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger.component.ts +8 -7
  227. package/src/app/lib/components/ui/navigation-menu/navigation-menu-viewport.component.ts +3 -2
  228. package/src/app/lib/components/ui/navigation-menu/navigation-menu.component.ts +8 -15
  229. package/src/app/lib/components/ui/pagination/index.ts +0 -1
  230. package/src/app/lib/components/ui/pagination/pagination-content.component.ts +3 -7
  231. package/src/app/lib/components/ui/pagination/pagination-ellipsis.component.ts +3 -7
  232. package/src/app/lib/components/ui/pagination/pagination-item.component.ts +3 -9
  233. package/src/app/lib/components/ui/pagination/pagination-link.component.ts +4 -8
  234. package/src/app/lib/components/ui/pagination/pagination-next.component.ts +3 -11
  235. package/src/app/lib/components/ui/pagination/pagination-previous.component.ts +3 -11
  236. package/src/app/lib/components/ui/pagination/pagination.component.ts +3 -7
  237. package/src/app/lib/components/ui/popover/index.ts +9 -6
  238. package/src/app/lib/components/ui/popover/popover-anchor.component.ts +2 -13
  239. package/src/app/lib/components/ui/popover/popover-content.component.ts +119 -69
  240. package/src/app/lib/components/ui/popover/popover-context.ts +0 -8
  241. package/src/app/lib/components/ui/popover/popover-trigger.component.ts +22 -22
  242. package/src/app/lib/components/ui/popover/popover.component.ts +20 -33
  243. package/src/app/lib/components/ui/progress/index.ts +1 -6
  244. package/src/app/lib/components/ui/progress/progress.component.ts +15 -30
  245. package/src/app/lib/components/ui/radio-group/index.ts +1 -4
  246. package/src/app/lib/components/ui/radio-group/radio-group-context.ts +1 -7
  247. package/src/app/lib/components/ui/radio-group/radio-group-item.component.ts +36 -69
  248. package/src/app/lib/components/ui/radio-group/radio-group.component.ts +38 -67
  249. package/src/app/lib/components/ui/resizable/index.ts +0 -1
  250. package/src/app/lib/components/ui/resizable/resizable-handle.component.ts +25 -39
  251. package/src/app/lib/components/ui/resizable/resizable-panel-group.component.ts +15 -18
  252. package/src/app/lib/components/ui/resizable/resizable-panel.component.ts +12 -31
  253. package/src/app/lib/components/ui/scroll-area/index.ts +4 -5
  254. package/src/app/lib/components/ui/scroll-area/scroll-area.component.ts +5 -19
  255. package/src/app/lib/components/ui/scroll-area/scroll-bar.component.ts +8 -27
  256. package/src/app/lib/components/ui/segmented/index.ts +5 -9
  257. package/src/app/lib/components/ui/segmented/segmented-context.ts +1 -3
  258. package/src/app/lib/components/ui/segmented/segmented-item.component.ts +21 -29
  259. package/src/app/lib/components/ui/segmented/segmented-variants.ts +2 -2
  260. package/src/app/lib/components/ui/segmented/segmented.component.ts +24 -32
  261. package/src/app/lib/components/ui/select/index.ts +5 -6
  262. package/src/app/lib/components/ui/select/select-content.component.ts +34 -62
  263. package/src/app/lib/components/ui/select/select-context.ts +4 -14
  264. package/src/app/lib/components/ui/select/select-group.component.ts +6 -7
  265. package/src/app/lib/components/ui/select/select-item.component.ts +46 -55
  266. package/src/app/lib/components/ui/select/select-label.component.ts +2 -7
  267. package/src/app/lib/components/ui/select/select-separator.component.ts +3 -8
  268. package/src/app/lib/components/ui/select/select-trigger.component.ts +28 -25
  269. package/src/app/lib/components/ui/select/select-value.component.ts +7 -13
  270. package/src/app/lib/components/ui/select/select.component.ts +52 -64
  271. package/src/app/lib/components/ui/separator/index.ts +1 -6
  272. package/src/app/lib/components/ui/separator/separator.component.ts +4 -19
  273. package/src/app/lib/components/ui/sheet/index.ts +0 -1
  274. package/src/app/lib/components/ui/sheet/sheet-close.component.ts +4 -8
  275. package/src/app/lib/components/ui/sheet/sheet-content.component.ts +31 -36
  276. package/src/app/lib/components/ui/sheet/sheet-description.component.ts +5 -10
  277. package/src/app/lib/components/ui/sheet/sheet-footer.component.ts +3 -7
  278. package/src/app/lib/components/ui/sheet/sheet-header.component.ts +3 -7
  279. package/src/app/lib/components/ui/sheet/sheet-title.component.ts +5 -10
  280. package/src/app/lib/components/ui/sheet/sheet-trigger.component.ts +7 -11
  281. package/src/app/lib/components/ui/sheet/sheet-variants.ts +1 -1
  282. package/src/app/lib/components/ui/sheet/sheet.component.ts +36 -36
  283. package/src/app/lib/components/ui/sidebar/index.ts +14 -15
  284. package/src/app/lib/components/ui/sidebar/sidebar-content.component.ts +4 -8
  285. package/src/app/lib/components/ui/sidebar/sidebar-context.ts +1 -3
  286. package/src/app/lib/components/ui/sidebar/sidebar-footer.component.ts +3 -9
  287. package/src/app/lib/components/ui/sidebar/sidebar-group-action.component.ts +4 -8
  288. package/src/app/lib/components/ui/sidebar/sidebar-group-content.component.ts +3 -9
  289. package/src/app/lib/components/ui/sidebar/sidebar-group-label.component.ts +4 -8
  290. package/src/app/lib/components/ui/sidebar/sidebar-group.component.ts +3 -7
  291. package/src/app/lib/components/ui/sidebar/sidebar-header.component.ts +3 -9
  292. package/src/app/lib/components/ui/sidebar/sidebar-input.component.ts +4 -8
  293. package/src/app/lib/components/ui/sidebar/sidebar-inset.component.ts +4 -8
  294. package/src/app/lib/components/ui/sidebar/sidebar-menu-action.component.ts +4 -8
  295. package/src/app/lib/components/ui/sidebar/sidebar-menu-badge.component.ts +4 -8
  296. package/src/app/lib/components/ui/sidebar/sidebar-menu-button.component.ts +4 -9
  297. package/src/app/lib/components/ui/sidebar/sidebar-menu-item.component.ts +3 -9
  298. package/src/app/lib/components/ui/sidebar/sidebar-menu-skeleton.component.ts +6 -11
  299. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-button.component.ts +4 -8
  300. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-item.component.ts +2 -6
  301. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub.component.ts +4 -8
  302. package/src/app/lib/components/ui/sidebar/sidebar-menu.component.ts +3 -7
  303. package/src/app/lib/components/ui/sidebar/sidebar-provider.component.ts +46 -52
  304. package/src/app/lib/components/ui/sidebar/sidebar-rail.component.ts +6 -11
  305. package/src/app/lib/components/ui/sidebar/sidebar-route-active.service.ts +17 -17
  306. package/src/app/lib/components/ui/sidebar/sidebar-separator.component.ts +3 -7
  307. package/src/app/lib/components/ui/sidebar/sidebar-trigger.component.ts +6 -11
  308. package/src/app/lib/components/ui/sidebar/sidebar.component.ts +20 -31
  309. package/src/app/lib/components/ui/skeleton/skeleton.component.ts +3 -8
  310. package/src/app/lib/components/ui/slider/index.ts +1 -6
  311. package/src/app/lib/components/ui/slider/slider.component.ts +73 -138
  312. package/src/app/lib/components/ui/spinner/index.ts +0 -1
  313. package/src/app/lib/components/ui/spinner/spinner-variants.ts +19 -22
  314. package/src/app/lib/components/ui/spinner/spinner.component.ts +4 -8
  315. package/src/app/lib/components/ui/switch/index.ts +1 -6
  316. package/src/app/lib/components/ui/switch/switch.component.ts +83 -108
  317. package/src/app/lib/components/ui/table/index.ts +0 -1
  318. package/src/app/lib/components/ui/table/table-body.component.ts +6 -10
  319. package/src/app/lib/components/ui/table/table-caption.component.ts +6 -8
  320. package/src/app/lib/components/ui/table/table-cell.component.ts +4 -8
  321. package/src/app/lib/components/ui/table/table-footer.component.ts +6 -8
  322. package/src/app/lib/components/ui/table/table-head.component.ts +4 -8
  323. package/src/app/lib/components/ui/table/table-header.component.ts +6 -10
  324. package/src/app/lib/components/ui/table/table-row.component.ts +6 -11
  325. package/src/app/lib/components/ui/table/table.component.ts +4 -8
  326. package/src/app/lib/components/ui/tabs/index.ts +14 -7
  327. package/src/app/lib/components/ui/tabs/tabs-content.component.ts +11 -36
  328. package/src/app/lib/components/ui/tabs/tabs-context.ts +0 -8
  329. package/src/app/lib/components/ui/tabs/tabs-list.component.ts +54 -60
  330. package/src/app/lib/components/ui/tabs/tabs-trigger.component.ts +20 -35
  331. package/src/app/lib/components/ui/tabs/tabs.component.ts +32 -49
  332. package/src/app/lib/components/ui/textarea/textarea.component.ts +3 -8
  333. package/src/app/lib/components/ui/toast/index.ts +6 -7
  334. package/src/app/lib/components/ui/toast/toast-action.component.ts +7 -18
  335. package/src/app/lib/components/ui/toast/toast-description.component.ts +2 -11
  336. package/src/app/lib/components/ui/toast/toast-title.component.ts +2 -9
  337. package/src/app/lib/components/ui/toast/toast-variants.ts +1 -1
  338. package/src/app/lib/components/ui/toast/toast.component.ts +18 -24
  339. package/src/app/lib/components/ui/toast/toast.service.ts +22 -37
  340. package/src/app/lib/components/ui/toast/toaster.component.ts +6 -16
  341. package/src/app/lib/components/ui/toggle/index.ts +1 -5
  342. package/src/app/lib/components/ui/toggle/toggle-variants.ts +2 -2
  343. package/src/app/lib/components/ui/toggle/toggle.component.ts +32 -51
  344. package/src/app/lib/components/ui/toggle-group/index.ts +1 -4
  345. package/src/app/lib/components/ui/toggle-group/toggle-group-context.ts +1 -7
  346. package/src/app/lib/components/ui/toggle-group/toggle-group-item.component.ts +38 -59
  347. package/src/app/lib/components/ui/toggle-group/toggle-group.component.ts +33 -51
  348. package/src/app/lib/components/ui/tooltip/index.ts +9 -6
  349. package/src/app/lib/components/ui/tooltip/tooltip-content.component.ts +6 -24
  350. package/src/app/lib/components/ui/tooltip/tooltip-context.ts +0 -8
  351. package/src/app/lib/components/ui/tooltip/tooltip-provider.component.ts +12 -24
  352. package/src/app/lib/components/ui/tooltip/tooltip-trigger.component.ts +4 -21
  353. package/src/app/lib/components/ui/tooltip/tooltip.component.ts +21 -33
  354. package/src/app/lib/components/ui/typography/index.ts +0 -1
  355. package/src/app/lib/components/ui/typography/typography-blockquote.component.ts +3 -7
  356. package/src/app/lib/components/ui/typography/typography-h1.component.ts +3 -10
  357. package/src/app/lib/components/ui/typography/typography-h2.component.ts +3 -10
  358. package/src/app/lib/components/ui/typography/typography-h3.component.ts +3 -7
  359. package/src/app/lib/components/ui/typography/typography-h4.component.ts +3 -7
  360. package/src/app/lib/components/ui/typography/typography-inline-code.component.ts +4 -8
  361. package/src/app/lib/components/ui/typography/typography-large.component.ts +3 -9
  362. package/src/app/lib/components/ui/typography/typography-lead.component.ts +3 -7
  363. package/src/app/lib/components/ui/typography/typography-list.component.ts +3 -7
  364. package/src/app/lib/components/ui/typography/typography-muted.component.ts +3 -7
  365. package/src/app/lib/components/ui/typography/typography-p.component.ts +3 -7
  366. package/src/app/lib/components/ui/typography/typography-small.component.ts +3 -7
  367. package/src/app/lib/utils/accessibility/click-outside.directive.ts +1 -8
  368. package/src/app/lib/utils/accessibility/focus-management.service.ts +4 -15
  369. package/src/app/lib/utils/accessibility/focus-trap.directive.ts +32 -106
  370. package/src/app/lib/utils/accessibility/index.ts +16 -5
  371. package/src/app/lib/utils/accessibility/keyboard-navigation.directive.ts +5 -8
  372. package/src/app/lib/utils/accessibility/live-region.directive.ts +10 -13
  373. package/src/app/lib/utils/accessibility/touch-target.directive.ts +1 -8
  374. package/src/app/lib/utils/animation/animation.utils.ts +4 -7
  375. package/src/app/lib/utils/animation/index.ts +15 -5
  376. package/src/app/lib/utils/animation/presence.component.ts +1 -1
  377. package/src/app/lib/utils/animation/presence.directive.ts +2 -2
  378. package/src/app/lib/utils/positioning/index.ts +40 -18
  379. package/src/app/lib/components/ui/index.ts +0 -551
  380. package/src/app/lib/index.ts +0 -7
@@ -1,11 +1,6 @@
1
1
  import { cn } from '@/lib/utils';
2
- import {
3
- ChangeDetectionStrategy,
4
- Component,
5
- computed,
6
- inject,
7
- input,
8
- } from '@angular/core';
2
+ import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';
3
+ import { ChevronDown, LucideAngularModule } from 'lucide-angular';
9
4
  import { COMBOBOX_CONTEXT } from './combobox-context';
10
5
 
11
6
  /**
@@ -14,8 +9,19 @@ import { COMBOBOX_CONTEXT } from './combobox-context';
14
9
  */
15
10
  @Component({
16
11
  selector: 'ComboboxTrigger',
17
- template: `<ng-content />`,
12
+ template: `
13
+ <ng-content />
14
+
15
+ @if (showIcon()) {
16
+ <lucide-icon
17
+ [img]="ChevronDownIcon"
18
+ class="ms-auto w-4 h-4 shrink-0 opacity-50 text-gray-500 dark:text-neutral-400"
19
+ />
20
+ }
21
+ `,
22
+ imports: [LucideAngularModule],
18
23
  host: {
24
+ 'attr.data-slot': '"combobox-trigger"',
19
25
  '[class]': 'computedClass()',
20
26
  role: 'combobox',
21
27
  '[attr.id]': 'context.id + "-trigger"',
@@ -30,22 +36,26 @@ import { COMBOBOX_CONTEXT } from './combobox-context';
30
36
  changeDetection: ChangeDetectionStrategy.OnPush,
31
37
  })
32
38
  export class ComboboxTrigger {
33
- protected readonly context = inject(COMBOBOX_CONTEXT);
34
-
35
39
  /** Additional CSS classes */
36
40
  readonly class = input<string>('');
37
41
 
42
+ /** Whether to show the dropdown chevron icon */
43
+ readonly showIcon = input<boolean>(false);
44
+
45
+ protected readonly context = inject(COMBOBOX_CONTEXT);
46
+
38
47
  protected readonly computedClass = computed(() =>
39
48
  cn(
40
- 'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
41
- this.class()
42
- )
49
+ 'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:truncate',
50
+ this.class(),
51
+ ),
43
52
  );
44
53
 
54
+ protected readonly ChevronDownIcon = ChevronDown;
55
+
45
56
  protected onClick(): void {
46
57
  this.context.onOpenChange(!this.context.open());
47
58
  }
48
-
49
59
  protected onKeyDown(event: KeyboardEvent): void {
50
60
  // Let the main combobox handle most keyboard events
51
61
  this.context.onKeyDown(event);
@@ -1,47 +1,52 @@
1
1
  import { cn } from '@/lib/utils';
2
- import {
3
- ChangeDetectionStrategy,
4
- Component,
5
- computed,
6
- inject,
7
- input,
8
- } from '@angular/core';
2
+ import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';
9
3
  import { COMBOBOX_CONTEXT } from './combobox-context';
10
4
 
5
+ import { LucideAngularModule } from 'lucide-angular';
6
+
11
7
  /**
12
8
  * ComboboxValue component - displays the selected value or placeholder.
13
9
  */
14
10
  @Component({
15
11
  selector: 'ComboboxValue',
16
- template: `
17
- @if (selectedLabel()) {
18
- {{ selectedLabel() }}
12
+ imports: [LucideAngularModule],
13
+ template: ` @if (selectedOption(); as option) {
14
+ <span class="flex items-center gap-2 text-foreground">
15
+ @if (option.icon && iconPosition() === 'left') {
16
+ <lucide-icon [img]="option.icon" class="h-4 w-4 shrink-0" />
17
+ }
18
+
19
+ <span class="truncate">{{ option.label }}</span>
20
+
21
+ @if (option.icon && iconPosition() === 'right') {
22
+ <lucide-icon [img]="option.icon" class="h-4 w-4 shrink-0 ms-auto" />
23
+ }
24
+ </span>
19
25
  } @else {
20
- <span class="text-muted-foreground">{{ placeholder() }}</span>
21
- }
22
- `,
26
+ <span class="text-neutral-500">{{ placeholder() }}</span>
27
+ }`,
23
28
  host: {
29
+ 'attr.data-slot': '"combobox-value"',
24
30
  '[class]': 'computedClass()',
25
31
  },
26
32
  changeDetection: ChangeDetectionStrategy.OnPush,
27
33
  })
28
34
  export class ComboboxValue {
29
- protected readonly context = inject(COMBOBOX_CONTEXT);
30
-
31
35
  /** Placeholder text */
32
36
  readonly placeholder = input<string>('Select...');
33
-
34
37
  /** Additional CSS classes */
35
38
  readonly class = input<string>('');
36
39
 
37
- protected readonly selectedLabel = computed(() => {
40
+ protected readonly context = inject(COMBOBOX_CONTEXT);
41
+
42
+ /** icon position either left or right text */
43
+ readonly iconPosition = computed(() => this.context.iconPosition());
44
+
45
+ protected readonly selectedOption = computed(() => {
38
46
  const value = this.context.value();
39
- const options = this.context.options();
40
- const option = options.find((o) => o.value === value);
41
- return option?.label || '';
47
+ return this.context.options().find((option) => option.value === value);
42
48
  });
43
-
44
49
  protected readonly computedClass = computed(() =>
45
- cn('pointer-events-none flex-1 text-left', this.class())
50
+ cn('pointer-events-none flex-1 text-left', this.class()),
46
51
  );
47
52
  }
@@ -1,19 +1,16 @@
1
1
  import { cn } from '@/lib/utils';
2
2
  import {
3
- ChangeDetectionStrategy,
4
- Component,
5
- computed,
6
- effect,
7
- forwardRef,
8
- input,
9
- output,
10
- signal,
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ effect,
7
+ forwardRef,
8
+ input,
9
+ output,
10
+ signal,
11
11
  } from '@angular/core';
12
- import {
13
- COMBOBOX_CONTEXT,
14
- type ComboboxContext,
15
- type ComboboxOption,
16
- } from './combobox-context';
12
+
13
+ import { COMBOBOX_CONTEXT, type ComboboxContext, type ComboboxOption } from './combobox-context';
17
14
 
18
15
  let comboboxIdCounter = 0;
19
16
 
@@ -40,9 +37,10 @@ let comboboxIdCounter = 0;
40
37
  @Component({
41
38
  selector: 'Combobox',
42
39
  template: `<ng-content />`,
40
+ exportAs: 'combobox',
43
41
  host: {
44
42
  '[class]': 'computedClass()',
45
- 'data-slot': 'combobox',
43
+ 'attr.data-slot': '"combobox"',
46
44
  },
47
45
  providers: [
48
46
  {
@@ -54,44 +52,63 @@ let comboboxIdCounter = 0;
54
52
  changeDetection: ChangeDetectionStrategy.OnPush,
55
53
  })
56
54
  export class Combobox {
57
- private readonly uniqueId = `combobox-${++comboboxIdCounter}`;
58
-
59
- /** Available options */
60
- readonly options = input<ComboboxOption[]>([]);
55
+ constructor() {
56
+ // Sync options from input to internal signal
57
+ effect(() => {
58
+ this._options.set(this.options());
59
+ });
61
60
 
62
- /** Currently selected value */
63
- readonly value = input<string>('');
61
+ // Sync value from input to internal signal
62
+ effect(() => {
63
+ this._value.set(this.value());
64
+ });
65
+ }
64
66
 
65
67
  /** Value change event */
66
68
  readonly valueChange = output<string>();
67
-
68
69
  /** Open state change event */
69
70
  readonly openChange = output<boolean>();
70
71
 
72
+ readonly iconPosition = input<'left' | 'right'>('left');
73
+ /** Available options */
74
+ readonly options = input<ComboboxOption[]>([]);
75
+ /** Currently selected value */
76
+ readonly value = input<string>('');
71
77
  /** Additional CSS classes */
72
78
  readonly class = input<string>('');
73
79
 
74
- /** Internal signals */
75
- private readonly _options = signal<ComboboxOption[]>([]);
76
- private readonly _value = signal<string>('');
77
- private readonly _open = signal<boolean>(false);
78
- private readonly _search = signal<string>('');
79
- private readonly _highlightedIndex = signal<number>(-1);
80
-
81
80
  /** Computed filtered options */
82
81
  private readonly _filteredOptions = computed(() => {
83
82
  const options = this._options();
84
- const search = this._search().toLowerCase().trim();
83
+ const raw = this._search().trim();
85
84
 
86
- if (!search) {
85
+ if (!raw) {
87
86
  return options;
88
87
  }
89
88
 
90
- return options.filter((option) =>
91
- option.label.toLowerCase().includes(search)
92
- );
93
- });
89
+ const query = raw
90
+ .toLowerCase()
91
+ .normalize('NFD')
92
+ .replace(/[\u0300-\u036f]/g, '');
93
+
94
+ const exact: ComboboxOption[] = [];
95
+ const fuzzy: ComboboxOption[] = [];
96
+
97
+ for (const option of options) {
98
+ const label = option.label
99
+ .toLowerCase()
100
+ .normalize('NFD')
101
+ .replace(/[\u0300-\u036f]/g, '');
102
+
103
+ if (label.includes(query)) {
104
+ exact.push(option);
105
+ } else if (this._isFuzzyMatch(label, query)) {
106
+ fuzzy.push(option);
107
+ }
108
+ }
94
109
 
110
+ return [...exact, ...fuzzy];
111
+ });
95
112
  /** Computed active descendant ID */
96
113
  private readonly _activeDescendantId = computed(() => {
97
114
  const index = this._highlightedIndex();
@@ -101,11 +118,20 @@ export class Combobox {
101
118
  }
102
119
  return null;
103
120
  });
121
+ protected readonly computedClass = computed(() => cn('relative inline-block', this.class()));
122
+
123
+ /** Internal signals */
124
+ private readonly _options = signal<ComboboxOption[]>([]);
125
+ private readonly _value = signal<string>('');
126
+ private readonly _isOpen = signal<boolean>(false);
127
+ private readonly _search = signal<string>('');
128
+ private readonly _highlightedIndex = signal<number>(-1);
104
129
 
130
+ private readonly uniqueId = `combobox-${++comboboxIdCounter}`;
105
131
  /** Context for child components */
106
132
  readonly context: ComboboxContext = {
107
133
  id: this.uniqueId,
108
- open: this._open,
134
+ open: this._isOpen,
109
135
  value: this._value,
110
136
  search: this._search,
111
137
  options: this._options,
@@ -113,17 +139,18 @@ export class Combobox {
113
139
  highlightedIndex: this._highlightedIndex,
114
140
  listboxId: `${this.uniqueId}-listbox`,
115
141
  activeDescendantId: this._activeDescendantId,
142
+ iconPosition: this.iconPosition,
116
143
 
117
144
  onSelect: (value: string) => {
118
145
  this._value.set(value);
119
- this._open.set(false);
146
+ this._isOpen.set(false);
120
147
  this._search.set('');
121
148
  this._highlightedIndex.set(-1);
122
149
  this.valueChange.emit(value);
123
150
  },
124
151
 
125
152
  onOpenChange: (open: boolean) => {
126
- this._open.set(open);
153
+ this._isOpen.set(open);
127
154
  if (!open) {
128
155
  this._search.set('');
129
156
  this._highlightedIndex.set(-1);
@@ -131,7 +158,7 @@ export class Combobox {
131
158
  // When opening, highlight current value if exists
132
159
  const currentValue = this._value();
133
160
  if (currentValue) {
134
- const index = this._filteredOptions().findIndex(o => o.value === currentValue);
161
+ const index = this._filteredOptions().findIndex((o) => o.value === currentValue);
135
162
  if (index >= 0) {
136
163
  this._highlightedIndex.set(index);
137
164
  }
@@ -207,25 +234,18 @@ export class Combobox {
207
234
 
208
235
  getOptionId: (index: number) => `${this.uniqueId}-option-${index}`,
209
236
  };
237
+ /** Expose filtered options for template-level custom item rendering */
238
+ readonly filteredOptions = this._filteredOptions;
210
239
 
211
- protected readonly computedClass = computed(() =>
212
- cn('relative inline-block', this.class())
213
- );
214
-
215
- constructor() {
216
- // Sync options from input to internal signal
217
- effect(() => {
218
- this._options.set(this.options());
219
- });
220
-
221
- // Sync value from input to internal signal
222
- effect(() => {
223
- this._value.set(this.value());
224
- });
240
+ private _isFuzzyMatch(text: string, query: string): boolean {
241
+ let qi = 0;
242
+ for (let i = 0; i < text.length && qi < query.length; i++) {
243
+ if (text[i] === query[qi]) qi++;
244
+ }
245
+ return qi === query.length;
225
246
  }
226
-
227
247
  private handleKeyDown(event: KeyboardEvent): void {
228
- const open = this._open();
248
+ const open = this._isOpen();
229
249
 
230
250
  switch (event.key) {
231
251
  case 'ArrowDown':
@@ -1,9 +1,5 @@
1
1
  export { ComboboxContent } from './combobox-content.component';
2
- export {
3
- COMBOBOX_CONTEXT,
4
- type ComboboxContext,
5
- type ComboboxOption
6
- } from './combobox-context';
2
+ export { COMBOBOX_CONTEXT, type ComboboxContext, type ComboboxOption } from './combobox-context';
7
3
  export { ComboboxEmpty } from './combobox-empty.component';
8
4
  export { ComboboxGroup } from './combobox-group.component';
9
5
  export { ComboboxInput } from './combobox-input.component';
@@ -12,4 +8,3 @@ export { ComboboxList } from './combobox-list.component';
12
8
  export { ComboboxTrigger } from './combobox-trigger.component';
13
9
  export { ComboboxValue } from './combobox-value.component';
14
10
  export { Combobox } from './combobox.component';
15
-
@@ -1,10 +1,6 @@
1
1
  import { InjectionToken, type Signal, type WritableSignal } from '@angular/core';
2
2
 
3
- export type CommandFilterFunction = (
4
- value: string,
5
- search: string,
6
- keywords?: string[]
7
- ) => number; // 0 = hidden, 1 = shown, between 0-1 for ranking
3
+ export type CommandFilterFunction = (value: string, search: string, keywords?: string[]) => number; // 0 = hidden, 1 = shown, between 0-1 for ranking
8
4
 
9
5
  export interface CommandContextValue {
10
6
  search: WritableSignal<string>;
@@ -16,34 +16,31 @@ import { Command } from './command.component';
16
16
  [attr.data-state]="open() ? 'open' : 'closed'"
17
17
  (click)="closeDialog()"
18
18
  ></div>
19
- <div
20
- [class]="computedDialogClass()"
21
- [attr.data-state]="open() ? 'open' : 'closed'"
22
- >
23
- <Command [class]="'[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5'">
19
+ <div [class]="computedDialogClass()" [attr.data-state]="open() ? 'open' : 'closed'">
20
+ <Command
21
+ [class]="'[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5'"
22
+ >
24
23
  <ng-content />
25
24
  </Command>
26
25
  </div>
27
26
  </Presence>
28
27
  `,
29
28
  host: {
29
+ 'attr.data-slot': '"command-dialog"',
30
30
  class: 'contents',
31
31
  '(document:keydown.escape)': 'onEscapeKey()',
32
32
  },
33
33
  changeDetection: ChangeDetectionStrategy.OnPush,
34
34
  })
35
35
  export class CommandDialog {
36
+ /** Close event */
37
+ readonly openChange = output<boolean>();
38
+
36
39
  /** Whether the dialog is open */
37
40
  readonly open = input<boolean>(false);
38
-
39
41
  /** Additional CSS classes */
40
42
  readonly class = input<string>('');
41
43
 
42
- /** Close event */
43
- readonly openChange = output<boolean>();
44
-
45
- private readonly internalOpen = signal(false);
46
-
47
44
  protected readonly computedDialogClass = computed(() =>
48
45
  cn(
49
46
  'fixed left-[50%] top-[50%] z-50 max-h-[85vh] w-full max-w-[450px] translate-x-[-50%] translate-y-[-50%] overflow-hidden rounded-lg border bg-popover shadow-lg',
@@ -53,14 +50,15 @@ export class CommandDialog {
53
50
  'data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]',
54
51
  'data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]',
55
52
  'duration-200',
56
- this.class()
57
- )
53
+ this.class(),
54
+ ),
58
55
  );
59
56
 
57
+ private readonly internalOpen = signal(false);
58
+
60
59
  protected closeDialog(): void {
61
60
  this.openChange.emit(false);
62
61
  }
63
-
64
62
  protected onEscapeKey(): void {
65
63
  if (this.open()) {
66
64
  this.closeDialog();
@@ -9,6 +9,7 @@ import { ChangeDetectionStrategy, Component, computed, input } from '@angular/co
9
9
  selector: 'CommandEmpty',
10
10
  template: `<ng-content />`,
11
11
  host: {
12
+ 'attr.data-slot': '"command-empty"',
12
13
  '[class]': 'computedClass()',
13
14
  },
14
15
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -17,7 +18,5 @@ export class CommandEmpty {
17
18
  /** Additional CSS classes */
18
19
  readonly class = input<string>('');
19
20
 
20
- protected readonly computedClass = computed(() =>
21
- cn('py-6 text-center text-sm', this.class())
22
- );
21
+ protected readonly computedClass = computed(() => cn('py-6 text-center text-sm', this.class()));
23
22
  }
@@ -1,5 +1,13 @@
1
1
  import { cn } from '@/lib/utils';
2
- import { ChangeDetectionStrategy, Component, computed, effect, ElementRef, inject, input } from '@angular/core';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ effect,
7
+ ElementRef,
8
+ inject,
9
+ input,
10
+ } from '@angular/core';
3
11
 
4
12
  /**
5
13
  * CommandGroup component - a group of command items.
@@ -15,35 +23,13 @@ import { ChangeDetectionStrategy, Component, computed, effect, ElementRef, injec
15
23
  <ng-content />
16
24
  `,
17
25
  host: {
26
+ 'attr.data-slot': '"command-group"',
18
27
  '[class]': 'computedClass()',
19
28
  '[hidden]': '!hasVisibleItems()',
20
29
  },
21
30
  changeDetection: ChangeDetectionStrategy.OnPush,
22
31
  })
23
32
  export class CommandGroup {
24
- private readonly elementRef = inject(ElementRef);
25
-
26
- /** Group heading */
27
- readonly heading = input<string>('');
28
-
29
- /** Additional CSS classes */
30
- readonly class = input<string>('');
31
-
32
- /** Check if group has any visible items */
33
- protected readonly hasVisibleItems = computed(() => {
34
- // This will be re-evaluated whenever DOM changes
35
- const element = this.elementRef.nativeElement;
36
- const visibleItems = element.querySelectorAll('CommandItem:not([hidden])');
37
- return visibleItems.length > 0;
38
- });
39
-
40
- protected readonly computedClass = computed(() =>
41
- cn(
42
- 'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',
43
- this.class()
44
- )
45
- );
46
-
47
33
  constructor() {
48
34
  // Trigger re-evaluation of hasVisibleItems when children change
49
35
  effect(() => {
@@ -53,7 +39,7 @@ export class CommandGroup {
53
39
  this.hasVisibleItems();
54
40
  });
55
41
 
56
- const element = this.elementRef.nativeElement;
42
+ const element = this._elementRef.nativeElement;
57
43
  observer.observe(element, {
58
44
  attributes: true,
59
45
  attributeFilter: ['hidden'],
@@ -63,4 +49,25 @@ export class CommandGroup {
63
49
  return () => observer.disconnect();
64
50
  });
65
51
  }
52
+
53
+ /** Group heading */
54
+ readonly heading = input<string>('');
55
+ /** Additional CSS classes */
56
+ readonly class = input<string>('');
57
+
58
+ private readonly _elementRef = inject(ElementRef);
59
+
60
+ /** Check if group has any visible items */
61
+ protected readonly hasVisibleItems = computed(() => {
62
+ // This will be re-evaluated whenever DOM changes
63
+ const element = this._elementRef.nativeElement;
64
+ const visibleItems = element.querySelectorAll('CommandItem:not([hidden])');
65
+ return visibleItems.length > 0;
66
+ });
67
+ protected readonly computedClass = computed(() =>
68
+ cn(
69
+ 'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',
70
+ this.class(),
71
+ ),
72
+ );
66
73
  }
@@ -44,22 +44,12 @@ import { COMMAND_CONTEXT } from './command-context';
44
44
  </div>
45
45
  `,
46
46
  host: {
47
+ 'attr.data-slot': '"command-input-wrapper"',
47
48
  class: 'contents',
48
49
  },
49
50
  changeDetection: ChangeDetectionStrategy.OnPush,
50
51
  })
51
52
  export class CommandInput {
52
- protected readonly context = inject(COMMAND_CONTEXT);
53
- protected readonly SearchIcon = Search;
54
-
55
- private readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('inputEl');
56
-
57
- /** Placeholder text */
58
- readonly placeholder = input<string>('Search...');
59
-
60
- /** Additional CSS classes */
61
- readonly class = input<string>('');
62
-
63
53
  constructor() {
64
54
  // Auto-focus input when rendered (browser-only)
65
55
  afterNextRender(() => {
@@ -70,13 +60,22 @@ export class CommandInput {
70
60
  });
71
61
  }
72
62
 
63
+ private readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('inputEl');
64
+
65
+ /** Placeholder text */
66
+ readonly placeholder = input<string>('Search...');
67
+
68
+ /** Additional CSS classes */
69
+ readonly class = input<string>('');
70
+
71
+ protected readonly context = inject(COMMAND_CONTEXT);
72
+
73
73
  protected readonly computedClass = computed(() =>
74
74
  cn(
75
75
  'flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
76
- this.class()
77
- )
76
+ this.class(),
77
+ ),
78
78
  );
79
-
80
79
  protected readonly activeDescendant = computed(() => {
81
80
  const index = this.context.focusedIndex();
82
81
  if (index >= 0) {
@@ -85,51 +84,53 @@ export class CommandInput {
85
84
  return null;
86
85
  });
87
86
 
87
+ protected readonly SearchIcon = Search;
88
+
88
89
  protected onInput(event: Event): void {
89
90
  const target = event.target as HTMLInputElement;
90
91
  this.context.search.set(target.value);
91
92
  // Reset focus to first visible item when searching
92
93
  this.context.focusedIndex.set(0);
93
94
  }
94
-
95
95
  protected onKeydown(event: KeyboardEvent): void {
96
- const itemCount = this.context.itemCount();
97
96
  const currentIndex = this.context.focusedIndex();
97
+ const listEl = document.getElementById(this.context.listId);
98
+ const visibleItems = listEl
99
+ ? Array.from(listEl.querySelectorAll('CommandItem:not([hidden])'))
100
+ : [];
101
+ const visibleCount = visibleItems.length;
98
102
 
99
103
  switch (event.key) {
100
104
  case 'ArrowDown':
101
105
  event.preventDefault();
102
- if (itemCount > 0) {
103
- const nextIndex = currentIndex < itemCount - 1 ? currentIndex + 1 : 0;
106
+ if (visibleCount > 0) {
107
+ const nextIndex = currentIndex < visibleCount - 1 ? currentIndex + 1 : 0;
104
108
  this.context.focusedIndex.set(nextIndex);
105
109
  }
106
110
  break;
107
111
  case 'ArrowUp':
108
112
  event.preventDefault();
109
- if (itemCount > 0) {
110
- const prevIndex = currentIndex > 0 ? currentIndex - 1 : itemCount - 1;
113
+ if (visibleCount > 0) {
114
+ const prevIndex = currentIndex > 0 ? currentIndex - 1 : visibleCount - 1;
111
115
  this.context.focusedIndex.set(prevIndex);
112
116
  }
113
117
  break;
114
118
  case 'Home':
115
119
  event.preventDefault();
116
- if (itemCount > 0) {
120
+ if (visibleCount > 0) {
117
121
  this.context.focusedIndex.set(0);
118
122
  }
119
123
  break;
120
124
  case 'End':
121
125
  event.preventDefault();
122
- if (itemCount > 0) {
123
- this.context.focusedIndex.set(itemCount - 1);
126
+ if (visibleCount > 0) {
127
+ this.context.focusedIndex.set(visibleCount - 1);
124
128
  }
125
129
  break;
126
130
  case 'Enter':
127
131
  event.preventDefault();
128
- // Selection is handled by the focused item
129
- // Trigger click on currently focused item
130
- const focusedItem = document.querySelector(`[data-command-index="${currentIndex}"]`) as HTMLElement;
131
- if (focusedItem) {
132
- focusedItem.click();
132
+ if (currentIndex >= 0 && currentIndex < visibleCount) {
133
+ (visibleItems[currentIndex] as HTMLElement).click();
133
134
  }
134
135
  break;
135
136
  }