@ng-cn/core 1.0.11 → 1.0.14

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 (394) hide show
  1. package/package.json +2 -1
  2. package/schematics/ng-add/index.js +8 -3
  3. package/schematics/ng-add/index.ts +11 -4
  4. package/src/app/lib/components/ui/accordion/accordion-content.component.ts +53 -0
  5. package/src/app/lib/components/ui/accordion/accordion-context.ts +33 -0
  6. package/src/app/lib/components/ui/accordion/accordion-item.component.ts +86 -0
  7. package/src/app/lib/components/ui/accordion/accordion-trigger.component.ts +73 -0
  8. package/src/app/lib/components/ui/accordion/accordion.component.ts +197 -0
  9. package/src/app/lib/components/ui/accordion/index.ts +15 -0
  10. package/src/app/lib/components/ui/alert/alert-description.component.ts +33 -0
  11. package/src/app/lib/components/ui/alert/alert-title.component.ts +30 -0
  12. package/src/app/lib/components/ui/alert/alert-variants.ts +23 -0
  13. package/src/app/lib/components/ui/alert/alert.component.ts +50 -0
  14. package/src/app/lib/components/ui/alert/index.ts +5 -0
  15. package/src/app/lib/components/ui/alert-dialog/alert-dialog-action.component.ts +44 -0
  16. package/src/app/lib/components/ui/alert-dialog/alert-dialog-cancel.component.ts +45 -0
  17. package/src/app/lib/components/ui/alert-dialog/alert-dialog-content.component.ts +146 -0
  18. package/src/app/lib/components/ui/alert-dialog/alert-dialog-context.ts +14 -0
  19. package/src/app/lib/components/ui/alert-dialog/alert-dialog-description.component.ts +37 -0
  20. package/src/app/lib/components/ui/alert-dialog/alert-dialog-footer.component.ts +35 -0
  21. package/src/app/lib/components/ui/alert-dialog/alert-dialog-header.component.ts +35 -0
  22. package/src/app/lib/components/ui/alert-dialog/alert-dialog-title.component.ts +37 -0
  23. package/src/app/lib/components/ui/alert-dialog/alert-dialog-trigger.component.ts +44 -0
  24. package/src/app/lib/components/ui/alert-dialog/alert-dialog.component.ts +91 -0
  25. package/src/app/lib/components/ui/alert-dialog/index.ts +11 -0
  26. package/src/app/lib/components/ui/aspect-ratio/aspect-ratio.component.ts +63 -0
  27. package/src/app/lib/components/ui/aspect-ratio/index.ts +1 -0
  28. package/src/app/lib/components/ui/avatar/avatar-fallback.component.ts +34 -0
  29. package/src/app/lib/components/ui/avatar/avatar-image.component.ts +31 -0
  30. package/src/app/lib/components/ui/avatar/avatar.component.ts +37 -0
  31. package/src/app/lib/components/ui/avatar/index.ts +5 -0
  32. package/src/app/lib/components/ui/avatar/ui-avatar.component.ts +52 -0
  33. package/src/app/lib/components/ui/badge/badge-variants.ts +28 -0
  34. package/src/app/lib/components/ui/badge/badge.component.ts +50 -0
  35. package/src/app/lib/components/ui/badge/index.ts +3 -0
  36. package/src/app/lib/components/ui/breadcrumb/breadcrumb-ellipsis.component.ts +48 -0
  37. package/src/app/lib/components/ui/breadcrumb/breadcrumb-item.component.ts +28 -0
  38. package/src/app/lib/components/ui/breadcrumb/breadcrumb-link.component.ts +32 -0
  39. package/src/app/lib/components/ui/breadcrumb/breadcrumb-list.component.ts +31 -0
  40. package/src/app/lib/components/ui/breadcrumb/breadcrumb-page.component.ts +31 -0
  41. package/src/app/lib/components/ui/breadcrumb/breadcrumb-separator.component.ts +47 -0
  42. package/src/app/lib/components/ui/breadcrumb/breadcrumb.component.ts +43 -0
  43. package/src/app/lib/components/ui/breadcrumb/index.ts +8 -0
  44. package/src/app/lib/components/ui/button/button-variants.ts +38 -0
  45. package/src/app/lib/components/ui/button/button.component.ts +103 -0
  46. package/src/app/lib/components/ui/button/index.ts +3 -0
  47. package/src/app/lib/components/ui/button-group/button-group-variants.ts +24 -0
  48. package/src/app/lib/components/ui/button-group/button-group.component.ts +57 -0
  49. package/src/app/lib/components/ui/button-group/index.ts +6 -0
  50. package/src/app/lib/components/ui/calendar/calendar.component.ts +368 -0
  51. package/src/app/lib/components/ui/calendar/index.ts +1 -0
  52. package/src/app/lib/components/ui/card/card-action.component.ts +39 -0
  53. package/src/app/lib/components/ui/card/card-content.component.ts +31 -0
  54. package/src/app/lib/components/ui/card/card-description.component.ts +31 -0
  55. package/src/app/lib/components/ui/card/card-footer.component.ts +34 -0
  56. package/src/app/lib/components/ui/card/card-header.component.ts +37 -0
  57. package/src/app/lib/components/ui/card/card-title.component.ts +31 -0
  58. package/src/app/lib/components/ui/card/card.component.ts +41 -0
  59. package/src/app/lib/components/ui/card/index.ts +8 -0
  60. package/src/app/lib/components/ui/carousel/carousel-content.component.ts +38 -0
  61. package/src/app/lib/components/ui/carousel/carousel-context.ts +18 -0
  62. package/src/app/lib/components/ui/carousel/carousel-item.component.ts +32 -0
  63. package/src/app/lib/components/ui/carousel/carousel-next.component.ts +54 -0
  64. package/src/app/lib/components/ui/carousel/carousel-previous.component.ts +54 -0
  65. package/src/app/lib/components/ui/carousel/carousel.component.ts +125 -0
  66. package/src/app/lib/components/ui/carousel/index.ts +7 -0
  67. package/src/app/lib/components/ui/chart/chart-container.component.ts +81 -0
  68. package/src/app/lib/components/ui/chart/chart-context.ts +38 -0
  69. package/src/app/lib/components/ui/chart/chart-legend-content.component.ts +51 -0
  70. package/src/app/lib/components/ui/chart/chart-legend.component.ts +28 -0
  71. package/src/app/lib/components/ui/chart/chart-tooltip-content.component.ts +37 -0
  72. package/src/app/lib/components/ui/chart/chart-tooltip.component.ts +28 -0
  73. package/src/app/lib/components/ui/chart/chart.component.ts +308 -0
  74. package/src/app/lib/components/ui/chart/index.ts +16 -0
  75. package/src/app/lib/components/ui/checkbox/checkbox.component.ts +203 -0
  76. package/src/app/lib/components/ui/checkbox/index.ts +1 -0
  77. package/src/app/lib/components/ui/collapsible/collapsible-content.component.ts +58 -0
  78. package/src/app/lib/components/ui/collapsible/collapsible-context.ts +17 -0
  79. package/src/app/lib/components/ui/collapsible/collapsible-trigger.component.ts +56 -0
  80. package/src/app/lib/components/ui/collapsible/collapsible.component.ts +102 -0
  81. package/src/app/lib/components/ui/collapsible/index.ts +5 -0
  82. package/src/app/lib/components/ui/combobox/combobox-content.component.ts +59 -0
  83. package/src/app/lib/components/ui/combobox/combobox-context.ts +49 -0
  84. package/src/app/lib/components/ui/combobox/combobox-empty.component.ts +35 -0
  85. package/src/app/lib/components/ui/combobox/combobox-group.component.ts +32 -0
  86. package/src/app/lib/components/ui/combobox/combobox-input.component.ts +89 -0
  87. package/src/app/lib/components/ui/combobox/combobox-item.component.ts +129 -0
  88. package/src/app/lib/components/ui/combobox/combobox-list.component.ts +40 -0
  89. package/src/app/lib/components/ui/combobox/combobox-trigger.component.ts +53 -0
  90. package/src/app/lib/components/ui/combobox/combobox-value.component.ts +47 -0
  91. package/src/app/lib/components/ui/combobox/combobox.component.ts +290 -0
  92. package/src/app/lib/components/ui/combobox/index.ts +15 -0
  93. package/src/app/lib/components/ui/command/command-context.ts +24 -0
  94. package/src/app/lib/components/ui/command/command-dialog.component.ts +69 -0
  95. package/src/app/lib/components/ui/command/command-empty.component.ts +23 -0
  96. package/src/app/lib/components/ui/command/command-group.component.ts +66 -0
  97. package/src/app/lib/components/ui/command/command-input.component.ts +137 -0
  98. package/src/app/lib/components/ui/command/command-item.component.ts +148 -0
  99. package/src/app/lib/components/ui/command/command-list.component.ts +30 -0
  100. package/src/app/lib/components/ui/command/command-separator.component.ts +23 -0
  101. package/src/app/lib/components/ui/command/command-shortcut.component.ts +23 -0
  102. package/src/app/lib/components/ui/command/command.component.ts +105 -0
  103. package/src/app/lib/components/ui/command/index.ts +11 -0
  104. package/src/app/lib/components/ui/context-menu/context-menu-checkbox-item.component.ts +68 -0
  105. package/src/app/lib/components/ui/context-menu/context-menu-content.component.ts +213 -0
  106. package/src/app/lib/components/ui/context-menu/context-menu-context.ts +17 -0
  107. package/src/app/lib/components/ui/context-menu/context-menu-item.component.ts +63 -0
  108. package/src/app/lib/components/ui/context-menu/context-menu-label.component.ts +30 -0
  109. package/src/app/lib/components/ui/context-menu/context-menu-radio-group.component.ts +36 -0
  110. package/src/app/lib/components/ui/context-menu/context-menu-radio-item.component.ts +71 -0
  111. package/src/app/lib/components/ui/context-menu/context-menu-separator.component.ts +24 -0
  112. package/src/app/lib/components/ui/context-menu/context-menu-shortcut.component.ts +23 -0
  113. package/src/app/lib/components/ui/context-menu/context-menu-sub-content.component.ts +51 -0
  114. package/src/app/lib/components/ui/context-menu/context-menu-sub-trigger.component.ts +50 -0
  115. package/src/app/lib/components/ui/context-menu/context-menu-sub.component.ts +31 -0
  116. package/src/app/lib/components/ui/context-menu/context-menu-trigger.component.ts +51 -0
  117. package/src/app/lib/components/ui/context-menu/context-menu.component.ts +27 -0
  118. package/src/app/lib/components/ui/context-menu/index.ts +15 -0
  119. package/src/app/lib/components/ui/data-table/data-table-content.component.ts +226 -0
  120. package/src/app/lib/components/ui/data-table/data-table-context.ts +49 -0
  121. package/src/app/lib/components/ui/data-table/data-table-pagination.component.ts +138 -0
  122. package/src/app/lib/components/ui/data-table/data-table-search.component.ts +52 -0
  123. package/src/app/lib/components/ui/data-table/data-table-toolbar.component.ts +27 -0
  124. package/src/app/lib/components/ui/data-table/data-table-view-options.component.ts +92 -0
  125. package/src/app/lib/components/ui/data-table/data-table.component.ts +131 -0
  126. package/src/app/lib/components/ui/data-table/index.ts +16 -0
  127. package/src/app/lib/components/ui/date-picker/date-picker.component.ts +94 -0
  128. package/src/app/lib/components/ui/date-picker/index.ts +1 -0
  129. package/src/app/lib/components/ui/dialog/dialog-close.component.ts +31 -0
  130. package/src/app/lib/components/ui/dialog/dialog-content.component.ts +177 -0
  131. package/src/app/lib/components/ui/dialog/dialog-context.ts +15 -0
  132. package/src/app/lib/components/ui/dialog/dialog-description.component.ts +34 -0
  133. package/src/app/lib/components/ui/dialog/dialog-footer.component.ts +28 -0
  134. package/src/app/lib/components/ui/dialog/dialog-header.component.ts +28 -0
  135. package/src/app/lib/components/ui/dialog/dialog-title.component.ts +34 -0
  136. package/src/app/lib/components/ui/dialog/dialog-trigger.component.ts +38 -0
  137. package/src/app/lib/components/ui/dialog/dialog.component.ts +87 -0
  138. package/src/app/lib/components/ui/dialog/index.ts +10 -0
  139. package/src/app/lib/components/ui/drawer/drawer-close.component.ts +31 -0
  140. package/src/app/lib/components/ui/drawer/drawer-content.component.ts +143 -0
  141. package/src/app/lib/components/ui/drawer/drawer-context.ts +17 -0
  142. package/src/app/lib/components/ui/drawer/drawer-description.component.ts +33 -0
  143. package/src/app/lib/components/ui/drawer/drawer-footer.component.ts +28 -0
  144. package/src/app/lib/components/ui/drawer/drawer-header.component.ts +28 -0
  145. package/src/app/lib/components/ui/drawer/drawer-title.component.ts +33 -0
  146. package/src/app/lib/components/ui/drawer/drawer-trigger.component.ts +38 -0
  147. package/src/app/lib/components/ui/drawer/drawer.component.ts +93 -0
  148. package/src/app/lib/components/ui/drawer/index.ts +10 -0
  149. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.component.ts +68 -0
  150. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-content.component.ts +234 -0
  151. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-context.ts +15 -0
  152. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-group.component.ts +15 -0
  153. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-item.component.ts +56 -0
  154. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-label.component.ts +30 -0
  155. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.component.ts +42 -0
  156. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.component.ts +71 -0
  157. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-separator.component.ts +24 -0
  158. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.component.ts +23 -0
  159. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.component.ts +51 -0
  160. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.component.ts +53 -0
  161. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub.component.ts +31 -0
  162. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-trigger.component.ts +45 -0
  163. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu.component.ts +32 -0
  164. package/src/app/lib/components/ui/dropdown-menu/index.ts +16 -0
  165. package/src/app/lib/components/ui/empty/empty-action.component.ts +28 -0
  166. package/src/app/lib/components/ui/empty/empty-description.component.ts +31 -0
  167. package/src/app/lib/components/ui/empty/empty-icon.component.ts +31 -0
  168. package/src/app/lib/components/ui/empty/empty-title.component.ts +28 -0
  169. package/src/app/lib/components/ui/empty/empty.component.ts +53 -0
  170. package/src/app/lib/components/ui/empty/index.ts +6 -0
  171. package/src/app/lib/components/ui/form/form-context.ts +34 -0
  172. package/src/app/lib/components/ui/form/form-control.component.ts +137 -0
  173. package/src/app/lib/components/ui/form/form-description.component.ts +37 -0
  174. package/src/app/lib/components/ui/form/form-field.component.ts +84 -0
  175. package/src/app/lib/components/ui/form/form-item.component.ts +42 -0
  176. package/src/app/lib/components/ui/form/form-label.component.ts +58 -0
  177. package/src/app/lib/components/ui/form/form-message.component.ts +107 -0
  178. package/src/app/lib/components/ui/form/form.component.ts +123 -0
  179. package/src/app/lib/components/ui/form/index.ts +17 -0
  180. package/src/app/lib/components/ui/hover-card/hover-card-content.component.ts +203 -0
  181. package/src/app/lib/components/ui/hover-card/hover-card-context.ts +25 -0
  182. package/src/app/lib/components/ui/hover-card/hover-card-trigger.component.ts +160 -0
  183. package/src/app/lib/components/ui/hover-card/hover-card.component.ts +147 -0
  184. package/src/app/lib/components/ui/hover-card/index.ts +13 -0
  185. package/src/app/lib/components/ui/index.ts +551 -0
  186. package/src/app/lib/components/ui/input/index.ts +1 -0
  187. package/src/app/lib/components/ui/input/input.component.ts +165 -0
  188. package/src/app/lib/components/ui/input-group/index.ts +4 -0
  189. package/src/app/lib/components/ui/input-group/input-group-addon.component.ts +43 -0
  190. package/src/app/lib/components/ui/input-group/input-group-input.component.ts +33 -0
  191. package/src/app/lib/components/ui/input-group/input-group.component.ts +53 -0
  192. package/src/app/lib/components/ui/input-otp/index.ts +14 -0
  193. package/src/app/lib/components/ui/input-otp/input-otp-context.ts +31 -0
  194. package/src/app/lib/components/ui/input-otp/input-otp-group.component.ts +23 -0
  195. package/src/app/lib/components/ui/input-otp/input-otp-separator.component.ts +31 -0
  196. package/src/app/lib/components/ui/input-otp/input-otp-slot.component.ts +67 -0
  197. package/src/app/lib/components/ui/input-otp/input-otp.component.ts +240 -0
  198. package/src/app/lib/components/ui/kbd/index.ts +3 -0
  199. package/src/app/lib/components/ui/kbd/kbd-variants.ts +23 -0
  200. package/src/app/lib/components/ui/kbd/kbd.component.ts +50 -0
  201. package/src/app/lib/components/ui/label/index.ts +1 -0
  202. package/src/app/lib/components/ui/label/label.component.ts +139 -0
  203. package/src/app/lib/components/ui/menubar/index.ts +26 -0
  204. package/src/app/lib/components/ui/menubar/menubar-checkbox-item.component.ts +66 -0
  205. package/src/app/lib/components/ui/menubar/menubar-content.component.ts +236 -0
  206. package/src/app/lib/components/ui/menubar/menubar-context.ts +63 -0
  207. package/src/app/lib/components/ui/menubar/menubar-item.component.ts +60 -0
  208. package/src/app/lib/components/ui/menubar/menubar-label.component.ts +30 -0
  209. package/src/app/lib/components/ui/menubar/menubar-menu.component.ts +40 -0
  210. package/src/app/lib/components/ui/menubar/menubar-radio-group.component.ts +36 -0
  211. package/src/app/lib/components/ui/menubar/menubar-radio-item.component.ts +66 -0
  212. package/src/app/lib/components/ui/menubar/menubar-separator.component.ts +24 -0
  213. package/src/app/lib/components/ui/menubar/menubar-shortcut.component.ts +23 -0
  214. package/src/app/lib/components/ui/menubar/menubar-sub-content.component.ts +51 -0
  215. package/src/app/lib/components/ui/menubar/menubar-sub-trigger.component.ts +50 -0
  216. package/src/app/lib/components/ui/menubar/menubar-sub.component.ts +29 -0
  217. package/src/app/lib/components/ui/menubar/menubar-trigger.component.ts +132 -0
  218. package/src/app/lib/components/ui/menubar/menubar.component.ts +158 -0
  219. package/src/app/lib/components/ui/native-select/index.ts +6 -0
  220. package/src/app/lib/components/ui/native-select/native-select-variants.ts +23 -0
  221. package/src/app/lib/components/ui/native-select/native-select.component.ts +74 -0
  222. package/src/app/lib/components/ui/navigation-menu/index.ts +21 -0
  223. package/src/app/lib/components/ui/navigation-menu/navigation-menu-content.component.ts +66 -0
  224. package/src/app/lib/components/ui/navigation-menu/navigation-menu-context.ts +55 -0
  225. package/src/app/lib/components/ui/navigation-menu/navigation-menu-indicator.component.ts +28 -0
  226. package/src/app/lib/components/ui/navigation-menu/navigation-menu-item.component.ts +29 -0
  227. package/src/app/lib/components/ui/navigation-menu/navigation-menu-link.component.ts +43 -0
  228. package/src/app/lib/components/ui/navigation-menu/navigation-menu-list.component.ts +26 -0
  229. package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger-style.ts +7 -0
  230. package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger.component.ts +58 -0
  231. package/src/app/lib/components/ui/navigation-menu/navigation-menu-viewport.component.ts +26 -0
  232. package/src/app/lib/components/ui/navigation-menu/navigation-menu.component.ts +149 -0
  233. package/src/app/lib/components/ui/pagination/index.ts +8 -0
  234. package/src/app/lib/components/ui/pagination/pagination-content.component.ts +28 -0
  235. package/src/app/lib/components/ui/pagination/pagination-ellipsis.component.ts +47 -0
  236. package/src/app/lib/components/ui/pagination/pagination-item.component.ts +28 -0
  237. package/src/app/lib/components/ui/pagination/pagination-link.component.ts +46 -0
  238. package/src/app/lib/components/ui/pagination/pagination-next.component.ts +54 -0
  239. package/src/app/lib/components/ui/pagination/pagination-previous.component.ts +54 -0
  240. package/src/app/lib/components/ui/pagination/pagination.component.ts +48 -0
  241. package/src/app/lib/components/ui/popover/index.ts +14 -0
  242. package/src/app/lib/components/ui/popover/popover-anchor.component.ts +64 -0
  243. package/src/app/lib/components/ui/popover/popover-content.component.ts +231 -0
  244. package/src/app/lib/components/ui/popover/popover-context.ts +29 -0
  245. package/src/app/lib/components/ui/popover/popover-trigger.component.ts +100 -0
  246. package/src/app/lib/components/ui/popover/popover.component.ts +163 -0
  247. package/src/app/lib/components/ui/progress/index.ts +6 -0
  248. package/src/app/lib/components/ui/progress/progress.component.ts +212 -0
  249. package/src/app/lib/components/ui/radio-group/index.ts +10 -0
  250. package/src/app/lib/components/ui/radio-group/radio-group-context.ts +38 -0
  251. package/src/app/lib/components/ui/radio-group/radio-group-item.component.ts +298 -0
  252. package/src/app/lib/components/ui/radio-group/radio-group.component.ts +275 -0
  253. package/src/app/lib/components/ui/resizable/index.ts +5 -0
  254. package/src/app/lib/components/ui/resizable/resizable-context.ts +14 -0
  255. package/src/app/lib/components/ui/resizable/resizable-handle.component.ts +232 -0
  256. package/src/app/lib/components/ui/resizable/resizable-panel-group.component.ts +140 -0
  257. package/src/app/lib/components/ui/resizable/resizable-panel.component.ts +77 -0
  258. package/src/app/lib/components/ui/scroll-area/index.ts +8 -0
  259. package/src/app/lib/components/ui/scroll-area/scroll-area.component.ts +126 -0
  260. package/src/app/lib/components/ui/scroll-area/scroll-bar.component.ts +93 -0
  261. package/src/app/lib/components/ui/segmented/index.ts +13 -0
  262. package/src/app/lib/components/ui/segmented/segmented-context.ts +11 -0
  263. package/src/app/lib/components/ui/segmented/segmented-item.component.ts +72 -0
  264. package/src/app/lib/components/ui/segmented/segmented-variants.ts +40 -0
  265. package/src/app/lib/components/ui/segmented/segmented.component.ts +99 -0
  266. package/src/app/lib/components/ui/select/index.ts +19 -0
  267. package/src/app/lib/components/ui/select/select-content.component.ts +97 -0
  268. package/src/app/lib/components/ui/select/select-context.ts +53 -0
  269. package/src/app/lib/components/ui/select/select-group.component.ts +56 -0
  270. package/src/app/lib/components/ui/select/select-item.component.ts +163 -0
  271. package/src/app/lib/components/ui/select/select-label.component.ts +32 -0
  272. package/src/app/lib/components/ui/select/select-separator.component.ts +34 -0
  273. package/src/app/lib/components/ui/select/select-trigger.component.ts +164 -0
  274. package/src/app/lib/components/ui/select/select-value.component.ts +49 -0
  275. package/src/app/lib/components/ui/select/select.component.ts +263 -0
  276. package/src/app/lib/components/ui/separator/index.ts +6 -0
  277. package/src/app/lib/components/ui/separator/separator.component.ts +128 -0
  278. package/src/app/lib/components/ui/sheet/index.ts +11 -0
  279. package/src/app/lib/components/ui/sheet/sheet-close.component.ts +32 -0
  280. package/src/app/lib/components/ui/sheet/sheet-content.component.ts +157 -0
  281. package/src/app/lib/components/ui/sheet/sheet-context.ts +15 -0
  282. package/src/app/lib/components/ui/sheet/sheet-description.component.ts +34 -0
  283. package/src/app/lib/components/ui/sheet/sheet-footer.component.ts +28 -0
  284. package/src/app/lib/components/ui/sheet/sheet-header.component.ts +28 -0
  285. package/src/app/lib/components/ui/sheet/sheet-title.component.ts +34 -0
  286. package/src/app/lib/components/ui/sheet/sheet-trigger.component.ts +38 -0
  287. package/src/app/lib/components/ui/sheet/sheet-variants.ts +22 -0
  288. package/src/app/lib/components/ui/sheet/sheet.component.ts +97 -0
  289. package/src/app/lib/components/ui/sidebar/index.ts +41 -0
  290. package/src/app/lib/components/ui/sidebar/sidebar-content.component.ts +31 -0
  291. package/src/app/lib/components/ui/sidebar/sidebar-context.ts +33 -0
  292. package/src/app/lib/components/ui/sidebar/sidebar-footer.component.ts +28 -0
  293. package/src/app/lib/components/ui/sidebar/sidebar-group-action.component.ts +33 -0
  294. package/src/app/lib/components/ui/sidebar/sidebar-group-content.component.ts +28 -0
  295. package/src/app/lib/components/ui/sidebar/sidebar-group-label.component.ts +32 -0
  296. package/src/app/lib/components/ui/sidebar/sidebar-group.component.ts +28 -0
  297. package/src/app/lib/components/ui/sidebar/sidebar-header.component.ts +28 -0
  298. package/src/app/lib/components/ui/sidebar/sidebar-input.component.ts +31 -0
  299. package/src/app/lib/components/ui/sidebar/sidebar-inset.component.ts +31 -0
  300. package/src/app/lib/components/ui/sidebar/sidebar-menu-action.component.ts +56 -0
  301. package/src/app/lib/components/ui/sidebar/sidebar-menu-badge.component.ts +42 -0
  302. package/src/app/lib/components/ui/sidebar/sidebar-menu-button.component.ts +64 -0
  303. package/src/app/lib/components/ui/sidebar/sidebar-menu-item.component.ts +32 -0
  304. package/src/app/lib/components/ui/sidebar/sidebar-menu-skeleton.component.ts +39 -0
  305. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-button.component.ts +59 -0
  306. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-item.component.ts +25 -0
  307. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub.component.ts +32 -0
  308. package/src/app/lib/components/ui/sidebar/sidebar-menu.component.ts +31 -0
  309. package/src/app/lib/components/ui/sidebar/sidebar-provider.component.ts +141 -0
  310. package/src/app/lib/components/ui/sidebar/sidebar-rail.component.ts +47 -0
  311. package/src/app/lib/components/ui/sidebar/sidebar-route-active.service.ts +124 -0
  312. package/src/app/lib/components/ui/sidebar/sidebar-separator.component.ts +28 -0
  313. package/src/app/lib/components/ui/sidebar/sidebar-trigger.component.ts +57 -0
  314. package/src/app/lib/components/ui/sidebar/sidebar.component.ts +130 -0
  315. package/src/app/lib/components/ui/skeleton/index.ts +1 -0
  316. package/src/app/lib/components/ui/skeleton/skeleton.component.ts +52 -0
  317. package/src/app/lib/components/ui/slider/index.ts +6 -0
  318. package/src/app/lib/components/ui/slider/slider.component.ts +477 -0
  319. package/src/app/lib/components/ui/spinner/index.ts +3 -0
  320. package/src/app/lib/components/ui/spinner/spinner-variants.ts +32 -0
  321. package/src/app/lib/components/ui/spinner/spinner.component.ts +77 -0
  322. package/src/app/lib/components/ui/switch/index.ts +6 -0
  323. package/src/app/lib/components/ui/switch/switch.component.ts +282 -0
  324. package/src/app/lib/components/ui/table/index.ts +9 -0
  325. package/src/app/lib/components/ui/table/table-body.component.ts +28 -0
  326. package/src/app/lib/components/ui/table/table-caption.component.ts +28 -0
  327. package/src/app/lib/components/ui/table/table-cell.component.ts +31 -0
  328. package/src/app/lib/components/ui/table/table-footer.component.ts +28 -0
  329. package/src/app/lib/components/ui/table/table-head.component.ts +36 -0
  330. package/src/app/lib/components/ui/table/table-header.component.ts +28 -0
  331. package/src/app/lib/components/ui/table/table-row.component.ts +34 -0
  332. package/src/app/lib/components/ui/table/table.component.ts +52 -0
  333. package/src/app/lib/components/ui/tabs/index.ts +14 -0
  334. package/src/app/lib/components/ui/tabs/tabs-content.component.ts +132 -0
  335. package/src/app/lib/components/ui/tabs/tabs-context.ts +33 -0
  336. package/src/app/lib/components/ui/tabs/tabs-list.component.ts +228 -0
  337. package/src/app/lib/components/ui/tabs/tabs-trigger.component.ts +167 -0
  338. package/src/app/lib/components/ui/tabs/tabs.component.ts +203 -0
  339. package/src/app/lib/components/ui/textarea/index.ts +1 -0
  340. package/src/app/lib/components/ui/textarea/textarea.component.ts +44 -0
  341. package/src/app/lib/components/ui/toast/index.ts +16 -0
  342. package/src/app/lib/components/ui/toast/toast-action.component.ts +77 -0
  343. package/src/app/lib/components/ui/toast/toast-description.component.ts +52 -0
  344. package/src/app/lib/components/ui/toast/toast-title.component.ts +52 -0
  345. package/src/app/lib/components/ui/toast/toast-variants.ts +24 -0
  346. package/src/app/lib/components/ui/toast/toast.component.ts +177 -0
  347. package/src/app/lib/components/ui/toast/toast.service.ts +202 -0
  348. package/src/app/lib/components/ui/toast/toaster.component.ts +128 -0
  349. package/src/app/lib/components/ui/toggle/index.ts +6 -0
  350. package/src/app/lib/components/ui/toggle/toggle-variants.ts +30 -0
  351. package/src/app/lib/components/ui/toggle/toggle.component.ts +199 -0
  352. package/src/app/lib/components/ui/toggle-group/index.ts +11 -0
  353. package/src/app/lib/components/ui/toggle-group/toggle-group-context.ts +48 -0
  354. package/src/app/lib/components/ui/toggle-group/toggle-group-item.component.ts +241 -0
  355. package/src/app/lib/components/ui/toggle-group/toggle-group.component.ts +288 -0
  356. package/src/app/lib/components/ui/tooltip/index.ts +14 -0
  357. package/src/app/lib/components/ui/tooltip/tooltip-content.component.ts +154 -0
  358. package/src/app/lib/components/ui/tooltip/tooltip-context.ts +29 -0
  359. package/src/app/lib/components/ui/tooltip/tooltip-provider.component.ts +95 -0
  360. package/src/app/lib/components/ui/tooltip/tooltip-trigger.component.ts +138 -0
  361. package/src/app/lib/components/ui/tooltip/tooltip.component.ts +159 -0
  362. package/src/app/lib/components/ui/typography/index.ts +13 -0
  363. package/src/app/lib/components/ui/typography/typography-blockquote.component.ts +31 -0
  364. package/src/app/lib/components/ui/typography/typography-h1.component.ts +32 -0
  365. package/src/app/lib/components/ui/typography/typography-h2.component.ts +32 -0
  366. package/src/app/lib/components/ui/typography/typography-h3.component.ts +29 -0
  367. package/src/app/lib/components/ui/typography/typography-h4.component.ts +29 -0
  368. package/src/app/lib/components/ui/typography/typography-inline-code.component.ts +31 -0
  369. package/src/app/lib/components/ui/typography/typography-large.component.ts +28 -0
  370. package/src/app/lib/components/ui/typography/typography-lead.component.ts +31 -0
  371. package/src/app/lib/components/ui/typography/typography-list.component.ts +31 -0
  372. package/src/app/lib/components/ui/typography/typography-muted.component.ts +28 -0
  373. package/src/app/lib/components/ui/typography/typography-p.component.ts +29 -0
  374. package/src/app/lib/components/ui/typography/typography-small.component.ts +28 -0
  375. package/src/app/lib/index.ts +7 -0
  376. package/src/app/lib/utils/accessibility/aria-id.service.ts +118 -0
  377. package/src/app/lib/utils/accessibility/click-outside.directive.ts +85 -0
  378. package/src/app/lib/utils/accessibility/focus-management.service.ts +231 -0
  379. package/src/app/lib/utils/accessibility/focus-trap.directive.ts +203 -0
  380. package/src/app/lib/utils/accessibility/index.ts +23 -0
  381. package/src/app/lib/utils/accessibility/keyboard-navigation.directive.ts +440 -0
  382. package/src/app/lib/utils/accessibility/live-region.directive.ts +260 -0
  383. package/src/app/lib/utils/accessibility/touch-target.directive.ts +81 -0
  384. package/src/app/lib/utils/accessibility/visually-hidden.component.ts +79 -0
  385. package/src/app/lib/utils/animation/animated.directive.ts +191 -0
  386. package/src/app/lib/utils/animation/animation-tokens.service.ts +88 -0
  387. package/src/app/lib/utils/animation/animation.types.ts +55 -0
  388. package/src/app/lib/utils/animation/animation.utils.ts +158 -0
  389. package/src/app/lib/utils/animation/index.ts +17 -0
  390. package/src/app/lib/utils/animation/presence.component.ts +168 -0
  391. package/src/app/lib/utils/animation/presence.directive.ts +169 -0
  392. package/src/app/lib/utils/cn.ts +15 -0
  393. package/src/app/lib/utils/index.ts +11 -0
  394. package/src/app/lib/utils/positioning/index.ts +218 -0
@@ -0,0 +1,102 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ booleanAttribute,
4
+ ChangeDetectionStrategy,
5
+ Component,
6
+ computed,
7
+ effect,
8
+ forwardRef,
9
+ input,
10
+ model,
11
+ output,
12
+ signal,
13
+ } from '@angular/core';
14
+ import { COLLAPSIBLE_CONTEXT, CollapsibleContext } from './collapsible-context';
15
+
16
+ /**
17
+ * Collapsible component - root container for collapsible content.
18
+ * Matches shadcn/ui React Collapsible exactly.
19
+ *
20
+ * @example
21
+ * <Collapsible>
22
+ * <CollapsibleTrigger>Toggle</CollapsibleTrigger>
23
+ * <CollapsibleContent>Content here</CollapsibleContent>
24
+ * </Collapsible>
25
+ *
26
+ * @example
27
+ * <!-- With default open -->
28
+ * <Collapsible [defaultOpen]="true">
29
+ * <CollapsibleTrigger>Toggle</CollapsibleTrigger>
30
+ * <CollapsibleContent>Content here</CollapsibleContent>
31
+ * </Collapsible>
32
+ */
33
+ @Component({
34
+ selector: 'Collapsible',
35
+ template: `<ng-content />`,
36
+ host: {
37
+ '[class]': 'computedClass()',
38
+ '[attr.data-state]': 'isOpen() ? "open" : "closed"',
39
+ '[attr.data-disabled]': 'disabled() ? "" : null',
40
+ },
41
+ providers: [
42
+ {
43
+ provide: COLLAPSIBLE_CONTEXT,
44
+ useExisting: forwardRef(() => Collapsible),
45
+ },
46
+ ],
47
+ changeDetection: ChangeDetectionStrategy.OnPush,
48
+ })
49
+ export class Collapsible implements CollapsibleContext {
50
+ /** Whether the collapsible is open by default */
51
+ readonly defaultOpen = input<boolean, unknown>(false, { transform: booleanAttribute });
52
+
53
+ /** Controlled open state - two-way binding supported */
54
+ readonly open = model<boolean | undefined>(undefined);
55
+
56
+ /** Whether the collapsible is disabled */
57
+ readonly disabled = input<boolean, unknown>(false, { transform: booleanAttribute });
58
+
59
+ /** Additional CSS classes */
60
+ readonly class = input<string>('');
61
+
62
+ /** Event emitted when open state changes */
63
+ readonly openChange = output<boolean>();
64
+
65
+ /** Internal state for open/closed */
66
+ private readonly _isOpen = signal<boolean>(false);
67
+
68
+ constructor() {
69
+ // Initialize with defaultOpen
70
+ effect(() => {
71
+ const defaultVal = this.defaultOpen();
72
+ const controlled = this.open();
73
+
74
+ if (controlled !== undefined) {
75
+ this._isOpen.set(controlled);
76
+ } else if (defaultVal && !this._isOpen()) {
77
+ this._isOpen.set(defaultVal);
78
+ }
79
+ });
80
+ }
81
+
82
+ /** Get the current open state */
83
+ isOpen = () => this.open() ?? this._isOpen();
84
+
85
+ /** Toggle the open state */
86
+ toggle = () => {
87
+ if (this.disabled()) return;
88
+
89
+ const newState = !this.isOpen();
90
+
91
+ if (this.open() === undefined) {
92
+ this._isOpen.set(newState);
93
+ }
94
+
95
+ this.open.set(newState);
96
+ this.openChange.emit(newState);
97
+ };
98
+
99
+ protected readonly computedClass = computed(() =>
100
+ cn('', this.class())
101
+ );
102
+ }
@@ -0,0 +1,5 @@
1
+ export { CollapsibleContent } from './collapsible-content.component';
2
+ export { COLLAPSIBLE_CONTEXT, type CollapsibleContext } from './collapsible-context';
3
+ export { CollapsibleTrigger } from './collapsible-trigger.component';
4
+ export { Collapsible } from './collapsible.component';
5
+
@@ -0,0 +1,59 @@
1
+ import { cn, Presence } from '@/lib/utils';
2
+ import { ClickOutsideDirective } from '@/lib/utils/accessibility';
3
+ import {
4
+ ChangeDetectionStrategy,
5
+ Component,
6
+ computed,
7
+ inject,
8
+ input,
9
+ } from '@angular/core';
10
+ import { COMBOBOX_CONTEXT } from './combobox-context';
11
+
12
+ /**
13
+ * ComboboxContent component - container for the combobox dropdown.
14
+ * Implements proper listbox role and click-outside behavior.
15
+ */
16
+ @Component({
17
+ selector: 'ComboboxContent',
18
+ imports: [ClickOutsideDirective, Presence],
19
+ template: `
20
+ <Presence [present]="context.open()">
21
+ <div
22
+ [id]="context.listboxId"
23
+ [class]="dropdownClass()"
24
+ [attr.data-state]="context.open() ? 'open' : 'closed'"
25
+ role="listbox"
26
+ [attr.aria-labelledby]="context.id + '-trigger'"
27
+ (clickOutside)="onClickOutside()"
28
+ >
29
+ <ng-content />
30
+ </div>
31
+ </Presence>
32
+ `,
33
+ host: {
34
+ '[class]': 'computedClass()',
35
+ '[attr.data-state]': 'context.open() ? "open" : "closed"',
36
+ },
37
+ changeDetection: ChangeDetectionStrategy.OnPush,
38
+ })
39
+ export class ComboboxContent {
40
+ protected readonly context = inject(COMBOBOX_CONTEXT);
41
+
42
+ /** Additional CSS classes */
43
+ readonly class = input<string>('');
44
+
45
+ protected readonly computedClass = computed(() =>
46
+ cn('contents', this.class())
47
+ );
48
+
49
+ protected readonly dropdownClass = computed(() =>
50
+ cn(
51
+ 'absolute z-50 mt-1 max-h-60 w-full min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md',
52
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95'
53
+ )
54
+ );
55
+
56
+ protected onClickOutside(): void {
57
+ this.context.onOpenChange(false);
58
+ }
59
+ }
@@ -0,0 +1,49 @@
1
+ import { InjectionToken, Signal, WritableSignal } from '@angular/core';
2
+
3
+ export interface ComboboxOption {
4
+ value: string;
5
+ label: string;
6
+ disabled?: boolean;
7
+ }
8
+
9
+ export interface ComboboxContext {
10
+ /** Unique ID for the combobox */
11
+ id: string;
12
+ /** Whether the dropdown is open */
13
+ open: WritableSignal<boolean>;
14
+ /** Currently selected value */
15
+ value: WritableSignal<string>;
16
+ /** Current search/filter text */
17
+ search: WritableSignal<string>;
18
+ /** All available options */
19
+ options: WritableSignal<ComboboxOption[]>;
20
+ /** Filtered options based on search */
21
+ filteredOptions: Signal<ComboboxOption[]>;
22
+ /** Currently highlighted option index for keyboard navigation */
23
+ highlightedIndex: WritableSignal<number>;
24
+ /** ID of the listbox element */
25
+ listboxId: string;
26
+ /** ID of the currently highlighted option */
27
+ activeDescendantId: Signal<string | null>;
28
+ /** Select an option */
29
+ onSelect: (value: string) => void;
30
+ /** Toggle or set open state */
31
+ onOpenChange: (open: boolean) => void;
32
+ /** Handle search input */
33
+ onSearch: (searchTerm: string) => void;
34
+ /** Handle keyboard navigation */
35
+ onKeyDown: (event: KeyboardEvent) => void;
36
+ /** Move highlight up */
37
+ highlightPrevious: () => void;
38
+ /** Move highlight down */
39
+ highlightNext: () => void;
40
+ /** Select highlighted option */
41
+ selectHighlighted: () => void;
42
+ /** Get option ID for ARIA */
43
+ getOptionId: (index: number) => string;
44
+ }
45
+
46
+ export const COMBOBOX_CONTEXT = new InjectionToken<ComboboxContext>(
47
+ 'ComboboxContext'
48
+ );
49
+
@@ -0,0 +1,35 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ inject,
7
+ input,
8
+ } from '@angular/core';
9
+ import { COMBOBOX_CONTEXT } from './combobox-context';
10
+
11
+ /**
12
+ * ComboboxEmpty component - displayed when no options match the search.
13
+ */
14
+ @Component({
15
+ selector: 'ComboboxEmpty',
16
+ template: `
17
+ @if (context.filteredOptions().length === 0) {
18
+ <ng-content />
19
+ }
20
+ `,
21
+ host: {
22
+ '[class]': 'computedClass()',
23
+ },
24
+ changeDetection: ChangeDetectionStrategy.OnPush,
25
+ })
26
+ export class ComboboxEmpty {
27
+ protected readonly context = inject(COMBOBOX_CONTEXT);
28
+
29
+ /** Additional CSS classes */
30
+ readonly class = input<string>('');
31
+
32
+ protected readonly computedClass = computed(() =>
33
+ cn('py-6 text-center text-sm', this.class())
34
+ );
35
+ }
@@ -0,0 +1,32 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+
9
+ /**
10
+ * ComboboxGroup component - groups combobox items with proper accessibility.
11
+ */
12
+ @Component({
13
+ selector: 'ComboboxGroup',
14
+ template: `<ng-content />`,
15
+ host: {
16
+ '[class]': 'computedClass()',
17
+ role: 'group',
18
+ '[attr.aria-label]': 'label()',
19
+ },
20
+ changeDetection: ChangeDetectionStrategy.OnPush,
21
+ })
22
+ export class ComboboxGroup {
23
+ /** Accessible label for this group */
24
+ readonly label = input<string>();
25
+
26
+ /** Additional CSS classes */
27
+ readonly class = input<string>('');
28
+
29
+ protected readonly computedClass = computed(() =>
30
+ cn('overflow-hidden p-1 overflow-y-auto', this.class())
31
+ );
32
+ }
@@ -0,0 +1,89 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ effect,
7
+ ElementRef,
8
+ inject,
9
+ input,
10
+ viewChild
11
+ } from '@angular/core';
12
+ import { LucideAngularModule, Search } from 'lucide-angular';
13
+ import { COMBOBOX_CONTEXT } from './combobox-context';
14
+
15
+ /**
16
+ * ComboboxInput component - search input for filtering options.
17
+ * Supports keyboard navigation within the combobox.
18
+ */
19
+ @Component({
20
+ selector: 'ComboboxInput',
21
+ imports: [LucideAngularModule],
22
+ template: `
23
+ <lucide-icon [img]="SearchIcon" class="mr-2 h-4 w-4 shrink-0 opacity-50" aria-hidden="true" />
24
+ <input
25
+ #searchInput
26
+ type="text"
27
+ [class]="inputClass()"
28
+ [placeholder]="placeholder()"
29
+ [value]="context.search()"
30
+ role="searchbox"
31
+ [attr.aria-label]="placeholder()"
32
+ [attr.aria-controls]="context.listboxId"
33
+ [attr.aria-activedescendant]="context.activeDescendantId()"
34
+ autocomplete="off"
35
+ autocorrect="off"
36
+ autocapitalize="off"
37
+ spellcheck="false"
38
+ (input)="onInput($event)"
39
+ (keydown)="onKeyDown($event)"
40
+ />
41
+ `,
42
+ host: {
43
+ '[class]': 'computedClass()',
44
+ },
45
+ changeDetection: ChangeDetectionStrategy.OnPush,
46
+ })
47
+ export class ComboboxInput {
48
+ protected readonly context = inject(COMBOBOX_CONTEXT);
49
+ protected readonly SearchIcon = Search;
50
+
51
+ private readonly searchInput = viewChild<ElementRef<HTMLInputElement>>('searchInput');
52
+
53
+ /** Placeholder text */
54
+ readonly placeholder = input<string>('Search...');
55
+
56
+ /** Additional CSS classes */
57
+ readonly class = input<string>('');
58
+
59
+ protected readonly computedClass = computed(() =>
60
+ cn('flex items-center border-b px-3', this.class())
61
+ );
62
+
63
+ protected readonly inputClass = computed(() =>
64
+ cn(
65
+ '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'
66
+ )
67
+ );
68
+
69
+ constructor() {
70
+ // Auto-focus input when combobox opens
71
+ effect(() => {
72
+ if (this.context.open()) {
73
+ setTimeout(() => {
74
+ this.searchInput()?.nativeElement?.focus();
75
+ }, 0);
76
+ }
77
+ });
78
+ }
79
+
80
+ protected onInput(event: Event): void {
81
+ const target = event.target as HTMLInputElement;
82
+ this.context.onSearch(target.value);
83
+ }
84
+
85
+ protected onKeyDown(event: KeyboardEvent): void {
86
+ // Pass keyboard events to the main handler for navigation
87
+ this.context.onKeyDown(event);
88
+ }
89
+ }
@@ -0,0 +1,129 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ effect,
7
+ ElementRef,
8
+ inject,
9
+ input,
10
+ viewChild,
11
+ } from '@angular/core';
12
+ import { COMBOBOX_CONTEXT } from './combobox-context';
13
+
14
+ /**
15
+ * ComboboxItem component - individual option in the combobox.
16
+ * Implements WAI-ARIA option pattern with keyboard navigation support.
17
+ */
18
+ @Component({
19
+ selector: 'ComboboxItem',
20
+ template: `
21
+ <div #itemElement [class]="innerClass()">
22
+ <svg
23
+ [class]="checkClass()"
24
+ xmlns="http://www.w3.org/2000/svg"
25
+ width="24"
26
+ height="24"
27
+ viewBox="0 0 24 24"
28
+ fill="none"
29
+ stroke="currentColor"
30
+ stroke-width="2"
31
+ stroke-linecap="round"
32
+ stroke-linejoin="round"
33
+ aria-hidden="true"
34
+ >
35
+ <path d="M20 6 9 17l-5-5" />
36
+ </svg>
37
+ <ng-content />
38
+ </div>
39
+ `,
40
+ host: {
41
+ '[class]': 'computedClass()',
42
+ '[id]': 'optionId()',
43
+ role: 'option',
44
+ '[attr.aria-selected]': 'isSelected()',
45
+ '[attr.aria-disabled]': 'disabled()',
46
+ '[attr.data-selected]': 'isSelected() ? "" : null',
47
+ '[attr.data-highlighted]': 'isHighlighted() ? "" : null',
48
+ '[attr.data-disabled]': 'disabled() ? "" : null',
49
+ '(click)': 'onSelect()',
50
+ '(mouseenter)': 'onMouseEnter()',
51
+ },
52
+ changeDetection: ChangeDetectionStrategy.OnPush,
53
+ })
54
+ export class ComboboxItem {
55
+ protected readonly context = inject(COMBOBOX_CONTEXT);
56
+
57
+ private readonly itemElement = viewChild<ElementRef<HTMLDivElement>>('itemElement');
58
+
59
+ /** The value of this item */
60
+ readonly value = input.required<string>();
61
+
62
+ /** Index of this item in the filtered list */
63
+ readonly index = input<number>(0);
64
+
65
+ /** Whether this item is disabled */
66
+ readonly disabled = input<boolean>(false);
67
+
68
+ /** Additional CSS classes */
69
+ readonly class = input<string>('');
70
+
71
+ protected readonly optionId = computed(() =>
72
+ this.context.getOptionId(this.index())
73
+ );
74
+
75
+ protected readonly isSelected = computed(
76
+ () => this.context.value() === this.value()
77
+ );
78
+
79
+ protected readonly isHighlighted = computed(
80
+ () => this.context.highlightedIndex() === this.index()
81
+ );
82
+
83
+ protected readonly computedClass = computed(() =>
84
+ cn('contents', this.class())
85
+ );
86
+
87
+ protected readonly innerClass = computed(() =>
88
+ cn(
89
+ 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none',
90
+ 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
91
+ 'data-[selected]:bg-accent data-[selected]:text-accent-foreground',
92
+ 'data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground',
93
+ 'hover:bg-accent hover:text-accent-foreground',
94
+ this.isSelected() && 'bg-accent text-accent-foreground',
95
+ this.isHighlighted() && 'bg-accent text-accent-foreground'
96
+ )
97
+ );
98
+
99
+ protected readonly checkClass = computed(() =>
100
+ cn(
101
+ 'absolute right-2 h-4 w-4',
102
+ this.isSelected() ? 'opacity-100' : 'opacity-0'
103
+ )
104
+ );
105
+
106
+ constructor() {
107
+ // Scroll into view when highlighted
108
+ effect(() => {
109
+ if (this.isHighlighted()) {
110
+ this.itemElement()?.nativeElement?.scrollIntoView({
111
+ block: 'nearest',
112
+ behavior: 'smooth',
113
+ });
114
+ }
115
+ });
116
+ }
117
+
118
+ protected onSelect(): void {
119
+ if (!this.disabled()) {
120
+ this.context.onSelect(this.value());
121
+ }
122
+ }
123
+
124
+ protected onMouseEnter(): void {
125
+ if (!this.disabled()) {
126
+ this.context.highlightedIndex.set(this.index());
127
+ }
128
+ }
129
+ }
@@ -0,0 +1,40 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ Component,
4
+ inject
5
+ } from '@angular/core';
6
+ import { COMBOBOX_CONTEXT } from './combobox-context';
7
+ import { ComboboxItem } from './combobox-item.component';
8
+
9
+ /**
10
+ * ComboboxList component - renders filtered combobox items.
11
+ * Automatically handles filtering and index assignment.
12
+ *
13
+ * @example
14
+ * <ComboboxContent>
15
+ * <ComboboxInput placeholder="Search..." />
16
+ * <ComboboxEmpty>No options found.</ComboboxEmpty>
17
+ * <ComboboxGroup>
18
+ * <ComboboxList />
19
+ * </ComboboxGroup>
20
+ * </ComboboxContent>
21
+ */
22
+ @Component({
23
+ selector: 'ComboboxList',
24
+ imports: [ComboboxItem],
25
+ template: `
26
+ @for (option of context.filteredOptions(); track option.value; let i = $index) {
27
+ <ComboboxItem [value]="option.value" [index]="i" [disabled]="option.disabled ?? false">
28
+ {{ option.label }}
29
+ </ComboboxItem>
30
+ }
31
+ `,
32
+ host: {
33
+ 'class': 'contents',
34
+ 'data-slot': 'combobox-list',
35
+ },
36
+ changeDetection: ChangeDetectionStrategy.OnPush,
37
+ })
38
+ export class ComboboxList {
39
+ protected readonly context = inject(COMBOBOX_CONTEXT);
40
+ }
@@ -0,0 +1,53 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ inject,
7
+ input,
8
+ } from '@angular/core';
9
+ import { COMBOBOX_CONTEXT } from './combobox-context';
10
+
11
+ /**
12
+ * ComboboxTrigger component - button that opens the combobox.
13
+ * Implements WAI-ARIA combobox trigger pattern.
14
+ */
15
+ @Component({
16
+ selector: 'ComboboxTrigger',
17
+ template: `<ng-content />`,
18
+ host: {
19
+ '[class]': 'computedClass()',
20
+ role: 'combobox',
21
+ '[attr.id]': 'context.id + "-trigger"',
22
+ '[attr.aria-expanded]': 'context.open()',
23
+ '[attr.aria-haspopup]': '"listbox"',
24
+ '[attr.aria-controls]': 'context.listboxId',
25
+ '[attr.aria-activedescendant]': 'context.open() ? context.activeDescendantId() : null',
26
+ '[attr.tabindex]': '0',
27
+ '(click)': 'onClick()',
28
+ '(keydown)': 'onKeyDown($event)',
29
+ },
30
+ changeDetection: ChangeDetectionStrategy.OnPush,
31
+ })
32
+ export class ComboboxTrigger {
33
+ protected readonly context = inject(COMBOBOX_CONTEXT);
34
+
35
+ /** Additional CSS classes */
36
+ readonly class = input<string>('');
37
+
38
+ protected readonly computedClass = computed(() =>
39
+ 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
+ )
43
+ );
44
+
45
+ protected onClick(): void {
46
+ this.context.onOpenChange(!this.context.open());
47
+ }
48
+
49
+ protected onKeyDown(event: KeyboardEvent): void {
50
+ // Let the main combobox handle most keyboard events
51
+ this.context.onKeyDown(event);
52
+ }
53
+ }
@@ -0,0 +1,47 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ inject,
7
+ input,
8
+ } from '@angular/core';
9
+ import { COMBOBOX_CONTEXT } from './combobox-context';
10
+
11
+ /**
12
+ * ComboboxValue component - displays the selected value or placeholder.
13
+ */
14
+ @Component({
15
+ selector: 'ComboboxValue',
16
+ template: `
17
+ @if (selectedLabel()) {
18
+ {{ selectedLabel() }}
19
+ } @else {
20
+ <span class="text-muted-foreground">{{ placeholder() }}</span>
21
+ }
22
+ `,
23
+ host: {
24
+ '[class]': 'computedClass()',
25
+ },
26
+ changeDetection: ChangeDetectionStrategy.OnPush,
27
+ })
28
+ export class ComboboxValue {
29
+ protected readonly context = inject(COMBOBOX_CONTEXT);
30
+
31
+ /** Placeholder text */
32
+ readonly placeholder = input<string>('Select...');
33
+
34
+ /** Additional CSS classes */
35
+ readonly class = input<string>('');
36
+
37
+ protected readonly selectedLabel = computed(() => {
38
+ const value = this.context.value();
39
+ const options = this.context.options();
40
+ const option = options.find((o) => o.value === value);
41
+ return option?.label || '';
42
+ });
43
+
44
+ protected readonly computedClass = computed(() =>
45
+ cn('pointer-events-none flex-1 text-left', this.class())
46
+ );
47
+ }