@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-cn/core",
3
- "version": "1.0.11",
3
+ "version": "1.0.14",
4
4
  "description": "Beautifully designed Angular components built with Tailwind CSS v4 - The official Angular port of shadcn/ui",
5
5
  "keywords": [
6
6
  "angular",
@@ -27,6 +27,7 @@
27
27
  },
28
28
  "files": [
29
29
  "schematics",
30
+ "src/app/lib",
30
31
  "README.md",
31
32
  "LICENSE"
32
33
  ],
@@ -545,12 +545,17 @@ function ngAdd(options) {
545
545
  const packageJsonPath = '/package.json';
546
546
  if (tree.exists(packageJsonPath)) {
547
547
  const packageJson = JSON.parse(tree.read(packageJsonPath).toString('utf-8'));
548
+ // Detect Angular version to determine CDK version
549
+ const angularCoreVersion = packageJson.dependencies?.['@angular/core'] || packageJson.devDependencies?.['@angular/core'] || '';
550
+ const angularMajorVersion = parseInt(angularCoreVersion.replace(/[\^~]/, '').split('.')[0], 10) || 21;
551
+ // Use compatible CDK version based on Angular version
552
+ const cdkVersion = angularMajorVersion >= 21 ? '^21.0.5' : angularMajorVersion >= 20 ? '^20.0.0' : '^19.0.0';
548
553
  const requiredDependencies = {
549
554
  'lucide-angular': '^0.562.0',
550
555
  'class-variance-authority': '^0.7.1',
551
556
  'clsx': '^2.1.1',
552
557
  'tailwind-merge': '^3.4.0',
553
- '@angular/cdk': '^21.0.5',
558
+ '@angular/cdk': cdkVersion,
554
559
  'tailwindcss': '^4.1.18',
555
560
  '@tailwindcss/postcss': '^4.1.18'
556
561
  };
@@ -772,10 +777,10 @@ function ngAdd(options) {
772
777
  context.logger.info('│ ng g @ng-cn/core:c card │');
773
778
  context.logger.info('│ │');
774
779
  context.logger.info('│ 2. Or install individual packages: │');
775
- context.logger.info('│ npm i @ng-cn/core @ng-cn/core │');
780
+ context.logger.info('│ npm i @ng-cn/button @ng-cn/card │');
776
781
  context.logger.info('│ │');
777
782
  context.logger.info('│ 3. Import and use: │');
778
- context.logger.info("│ import { Button } from '@ng-cn/core'; │");
783
+ context.logger.info("│ import { Button } from '@ng-cn/button'; │");
779
784
  context.logger.info('│ │');
780
785
  context.logger.info('│ 📚 Docs: https://shadcn-angular.tigayon.com │');
781
786
  context.logger.info('╰──────────────────────────────────────────────────╯');
@@ -594,12 +594,19 @@ export function ngAdd(options: NgAddOptions): Rule {
594
594
  if (tree.exists(packageJsonPath)) {
595
595
  const packageJson = JSON.parse(tree.read(packageJsonPath)!.toString('utf-8'));
596
596
 
597
- const requiredDependencies = {
597
+ // Detect Angular version to determine CDK version
598
+ const angularCoreVersion = packageJson.dependencies?.['@angular/core'] || packageJson.devDependencies?.['@angular/core'] || '';
599
+ const angularMajorVersion = parseInt(angularCoreVersion.replace(/[\^~]/, '').split('.')[0], 10) || 21;
600
+
601
+ // Use compatible CDK version based on Angular version
602
+ const cdkVersion = angularMajorVersion >= 21 ? '^21.0.5' : angularMajorVersion >= 20 ? '^20.0.0' : '^19.0.0';
603
+
604
+ const requiredDependencies: Record<string, string> = {
598
605
  'lucide-angular': '^0.562.0',
599
606
  'class-variance-authority': '^0.7.1',
600
607
  'clsx': '^2.1.1',
601
608
  'tailwind-merge': '^3.4.0',
602
- '@angular/cdk': '^21.0.5',
609
+ '@angular/cdk': cdkVersion,
603
610
  'tailwindcss': '^4.1.18',
604
611
  '@tailwindcss/postcss': '^4.1.18'
605
612
  };
@@ -843,10 +850,10 @@ export function ngAdd(options: NgAddOptions): Rule {
843
850
  context.logger.info('│ ng g @ng-cn/core:c card │');
844
851
  context.logger.info('│ │');
845
852
  context.logger.info('│ 2. Or install individual packages: │');
846
- context.logger.info('│ npm i @ng-cn/core @ng-cn/core │');
853
+ context.logger.info('│ npm i @ng-cn/button @ng-cn/card │');
847
854
  context.logger.info('│ │');
848
855
  context.logger.info('│ 3. Import and use: │');
849
- context.logger.info("│ import { Button } from '@ng-cn/core'; │");
856
+ context.logger.info("│ import { Button } from '@ng-cn/button'; │");
850
857
  context.logger.info('│ │');
851
858
  context.logger.info('│ 📚 Docs: https://shadcn-angular.tigayon.com │');
852
859
  context.logger.info('╰──────────────────────────────────────────────────╯');
@@ -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 { ACCORDION_ITEM_CONTEXT } from './accordion-context';
10
+
11
+ /**
12
+ * AccordionContent component - expandable content area.
13
+ * Uses role="region" and aria-labelledby to associate with trigger.
14
+ *
15
+ * @example
16
+ * <AccordionContent>
17
+ * <p>Your content here</p>
18
+ * </AccordionContent>
19
+ */
20
+ @Component({
21
+ selector: 'AccordionContent',
22
+ template: `
23
+ @if (item.isOpen()) {
24
+ <div [class]="innerClass()">
25
+ <ng-content />
26
+ </div>
27
+ }
28
+ `,
29
+ host: {
30
+ 'role': 'region',
31
+ '[class]': 'computedClass()',
32
+ '[attr.id]': 'item.contentId',
33
+ '[attr.data-state]': 'item.isOpen() ? "open" : "closed"',
34
+ '[attr.aria-labelledby]': 'item.triggerId',
35
+ '[attr.aria-hidden]': '!item.isOpen()',
36
+ },
37
+ changeDetection: ChangeDetectionStrategy.OnPush,
38
+ })
39
+ export class AccordionContent {
40
+ protected readonly item = inject(ACCORDION_ITEM_CONTEXT);
41
+
42
+ /** Additional CSS classes */
43
+ readonly class = input<string>('');
44
+
45
+ protected readonly computedClass = computed(() =>
46
+ cn(
47
+ 'overflow-hidden text-sm',
48
+ 'data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down'
49
+ )
50
+ );
51
+
52
+ protected readonly innerClass = computed(() => cn('pb-4 pt-2 px-1 text-muted-foreground leading-relaxed', this.class()));
53
+ }
@@ -0,0 +1,33 @@
1
+ import { InjectionToken, WritableSignal } from '@angular/core';
2
+
3
+ // ============================================================================
4
+ // Types
5
+ // ============================================================================
6
+
7
+ export type AccordionType = 'single' | 'multiple';
8
+
9
+ export interface AccordionContext {
10
+ type: () => AccordionType;
11
+ collapsible: () => boolean;
12
+ value: () => string | string[] | undefined;
13
+ onValueChange: (itemValue: string) => void;
14
+ isItemOpen: (itemValue: string) => boolean;
15
+ /** Registry of item values for keyboard navigation */
16
+ itemValues: WritableSignal<string[]>;
17
+ }
18
+
19
+ export interface AccordionItemContext {
20
+ value: () => string;
21
+ isOpen: () => boolean;
22
+ toggle: () => void;
23
+ /** Unique IDs for ARIA relationships */
24
+ triggerId: string;
25
+ contentId: string;
26
+ }
27
+
28
+ // ============================================================================
29
+ // Injection Tokens
30
+ // ============================================================================
31
+
32
+ export const ACCORDION_CONTEXT = new InjectionToken<AccordionContext>('AccordionContext');
33
+ export const ACCORDION_ITEM_CONTEXT = new InjectionToken<AccordionItemContext>('AccordionItemContext');
@@ -0,0 +1,86 @@
1
+ import { cn } from '@/lib/utils';
2
+ import { AriaIdService } from '@/lib/utils/accessibility';
3
+ import {
4
+ ChangeDetectionStrategy,
5
+ Component,
6
+ computed,
7
+ forwardRef,
8
+ inject,
9
+ input,
10
+ OnDestroy,
11
+ OnInit,
12
+ } from '@angular/core';
13
+ import {
14
+ ACCORDION_CONTEXT,
15
+ ACCORDION_ITEM_CONTEXT,
16
+ AccordionItemContext,
17
+ } from './accordion-context';
18
+
19
+ /**
20
+ * AccordionItem component - wrapper for each accordion section.
21
+ * Provides proper ARIA relationships between trigger and content.
22
+ *
23
+ * @example
24
+ * <AccordionItem value="item-1">
25
+ * <AccordionTrigger>Title</AccordionTrigger>
26
+ * <AccordionContent>Content</AccordionContent>
27
+ * </AccordionItem>
28
+ */
29
+ @Component({
30
+ selector: 'AccordionItem',
31
+ template: `<ng-content />`,
32
+ host: {
33
+ '[class]': 'computedClass()',
34
+ '[attr.data-state]': 'isOpen() ? "open" : "closed"',
35
+ '[attr.data-value]': 'value()',
36
+ },
37
+ providers: [
38
+ {
39
+ provide: ACCORDION_ITEM_CONTEXT,
40
+ useExisting: forwardRef(() => AccordionItem),
41
+ },
42
+ ],
43
+ changeDetection: ChangeDetectionStrategy.OnPush,
44
+ })
45
+ export class AccordionItem implements AccordionItemContext, OnInit, OnDestroy {
46
+ private readonly accordion = inject(ACCORDION_CONTEXT);
47
+ private readonly ariaIdService = inject(AriaIdService);
48
+ private readonly ariaIds = this.ariaIdService.generateAccordionIds('accordion');
49
+
50
+ /** Unique value for this accordion item */
51
+ readonly value = input.required<string>();
52
+
53
+ /** Additional CSS classes */
54
+ readonly class = input<string>('');
55
+
56
+ /** ARIA IDs for relationships */
57
+ readonly triggerId = this.ariaIds.generateTriggerId();
58
+ readonly contentId = this.ariaIds.generateContentId(0);
59
+
60
+ /** Whether this item is currently open */
61
+ readonly isOpen = computed(() => this.accordion.isItemOpen(this.value()));
62
+
63
+ /** Toggle this item's open state */
64
+ toggle(): void {
65
+ this.accordion.onValueChange(this.value());
66
+ }
67
+
68
+ ngOnInit(): void {
69
+ // Register this item's value for keyboard navigation
70
+ this.accordion.itemValues.update(values => {
71
+ if (!values.includes(this.value())) {
72
+ return [...values, this.value()];
73
+ }
74
+ return values;
75
+ });
76
+ }
77
+
78
+ ngOnDestroy(): void {
79
+ // Unregister this item's value
80
+ this.accordion.itemValues.update(values =>
81
+ values.filter(v => v !== this.value())
82
+ );
83
+ }
84
+
85
+ protected readonly computedClass = computed(() => cn('border-b w-full', this.class()));
86
+ }
@@ -0,0 +1,73 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ inject,
7
+ input,
8
+ } from '@angular/core';
9
+ import { ACCORDION_ITEM_CONTEXT } from './accordion-context';
10
+
11
+ /**
12
+ * AccordionTrigger component - clickable header that toggles content.
13
+ * Implements proper ARIA pattern for accordion triggers.
14
+ *
15
+ * @example
16
+ * <AccordionTrigger>Click to expand</AccordionTrigger>
17
+ */
18
+ @Component({
19
+ selector: 'AccordionTrigger',
20
+ template: `
21
+ <span class="me-2"><ng-content /></span>
22
+ <svg
23
+ class="size-4 shrink-0 ms-auto text-muted-foreground transition-transform duration-200"
24
+ [class.rotate-180]="item.isOpen()"
25
+ xmlns="http://www.w3.org/2000/svg"
26
+ width="24"
27
+ height="24"
28
+ viewBox="0 0 24 24"
29
+ fill="none"
30
+ stroke="currentColor"
31
+ stroke-width="2"
32
+ stroke-linecap="round"
33
+ stroke-linejoin="round"
34
+ >
35
+ <path d="m6 9 6 6 6-6" />
36
+ </svg>
37
+ `,
38
+ host: {
39
+ '[class]': 'computedClass()',
40
+ '[attr.id]': 'item.triggerId',
41
+ '[attr.data-state]': 'item.isOpen() ? "open" : "closed"',
42
+ '[attr.aria-expanded]': 'item.isOpen()',
43
+ '[attr.aria-controls]': 'item.contentId',
44
+ '(click)': 'onClick()',
45
+ '(keydown.enter)': 'onClick()',
46
+ '(keydown.space)': 'onSpace($event)',
47
+ '[attr.tabindex]': '0',
48
+ 'role': 'button',
49
+ },
50
+ changeDetection: ChangeDetectionStrategy.OnPush,
51
+ })
52
+ export class AccordionTrigger {
53
+ protected readonly item = inject(ACCORDION_ITEM_CONTEXT);
54
+
55
+ /** Additional CSS classes */
56
+ readonly class = input<string>('');
57
+
58
+ protected readonly computedClass = computed(() =>
59
+ cn(
60
+ 'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline text-left [&[data-state=open]>svg]:rotate-180 cursor-pointer w-full',
61
+ this.class()
62
+ )
63
+ );
64
+
65
+ protected onClick(): void {
66
+ this.item.toggle();
67
+ }
68
+
69
+ protected onSpace(event: Event): void {
70
+ event.preventDefault();
71
+ this.item.toggle();
72
+ }
73
+ }
@@ -0,0 +1,197 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ booleanAttribute,
4
+ ChangeDetectionStrategy,
5
+ Component,
6
+ computed,
7
+ effect,
8
+ forwardRef,
9
+ input,
10
+ signal,
11
+ } from '@angular/core';
12
+ import {
13
+ ACCORDION_CONTEXT,
14
+ AccordionContext,
15
+ AccordionType,
16
+ } from './accordion-context';
17
+
18
+ /**
19
+ * Accordion component - root container for accordion items.
20
+ * Matches shadcn/ui React Accordion exactly.
21
+ * Includes full keyboard navigation with arrow keys.
22
+ *
23
+ * @example
24
+ * <Accordion type="single" collapsible defaultValue="item-1">
25
+ * <AccordionItem value="item-1">
26
+ * <AccordionTrigger>Title</AccordionTrigger>
27
+ * <AccordionContent>Content here</AccordionContent>
28
+ * </AccordionItem>
29
+ * </Accordion>
30
+ */
31
+ @Component({
32
+ selector: 'Accordion',
33
+ template: `<ng-content />`,
34
+ host: {
35
+ '[class]': 'computedClass()',
36
+ '[attr.data-orientation]': '"vertical"',
37
+ '(keydown)': 'onKeydown($event)',
38
+ },
39
+ providers: [
40
+ {
41
+ provide: ACCORDION_CONTEXT,
42
+ useExisting: forwardRef(() => Accordion),
43
+ },
44
+ ],
45
+ changeDetection: ChangeDetectionStrategy.OnPush,
46
+ })
47
+ export class Accordion implements AccordionContext {
48
+ /** Type of accordion: 'single' allows one item open, 'multiple' allows many */
49
+ readonly type = input<AccordionType>('single');
50
+
51
+ /** Whether the accordion can be fully collapsed (only for single type) */
52
+ readonly collapsible = input<boolean, unknown>(false, { transform: booleanAttribute });
53
+
54
+ /** Default value(s) to be open initially */
55
+ readonly defaultValue = input<string | string[] | undefined>(undefined);
56
+
57
+ /** Controlled value - external control of open state */
58
+ readonly controlledValue = input<string | string[] | undefined>(undefined, { alias: 'value' });
59
+
60
+ /** Additional CSS classes */
61
+ readonly class = input<string>('');
62
+
63
+ /** Internal state for open items */
64
+ private readonly openItems = signal<Set<string>>(new Set());
65
+
66
+ /** Registry of item values for keyboard navigation */
67
+ readonly itemValues = signal<string[]>([]);
68
+
69
+ /** Flag to track if initialized */
70
+ private initialized = false;
71
+
72
+ constructor() {
73
+ // Initialize with default value
74
+ effect(() => {
75
+ if (!this.initialized) {
76
+ const defaultVal = this.defaultValue();
77
+ if (defaultVal !== undefined) {
78
+ if (Array.isArray(defaultVal)) {
79
+ this.openItems.set(new Set(defaultVal));
80
+ } else {
81
+ this.openItems.set(new Set([defaultVal]));
82
+ }
83
+ }
84
+ this.initialized = true;
85
+ }
86
+ });
87
+ }
88
+
89
+ /** Get current value(s) */
90
+ readonly value = computed(() => {
91
+ const controlled = this.controlledValue();
92
+ if (controlled !== undefined) {
93
+ return controlled;
94
+ }
95
+ const items = this.openItems();
96
+ if (this.type() === 'single') {
97
+ return items.size > 0 ? Array.from(items)[0] : undefined;
98
+ }
99
+ return Array.from(items);
100
+ });
101
+
102
+ /** Handle value change from accordion items */
103
+ onValueChange(itemValue: string): void {
104
+ const currentType = this.type();
105
+ const isCollapsible = this.collapsible();
106
+
107
+ this.openItems.update((current) => {
108
+ const newSet = new Set(current);
109
+
110
+ if (currentType === 'single') {
111
+ if (newSet.has(itemValue)) {
112
+ if (isCollapsible) {
113
+ newSet.delete(itemValue);
114
+ }
115
+ } else {
116
+ newSet.clear();
117
+ newSet.add(itemValue);
118
+ }
119
+ } else {
120
+ // multiple
121
+ if (newSet.has(itemValue)) {
122
+ newSet.delete(itemValue);
123
+ } else {
124
+ newSet.add(itemValue);
125
+ }
126
+ }
127
+
128
+ return newSet;
129
+ });
130
+ }
131
+
132
+ /** Check if an item is open */
133
+ isItemOpen(itemValue: string): boolean {
134
+ const controlled = this.controlledValue();
135
+ if (controlled !== undefined) {
136
+ if (Array.isArray(controlled)) {
137
+ return controlled.includes(itemValue);
138
+ }
139
+ return controlled === itemValue;
140
+ }
141
+ return this.openItems().has(itemValue);
142
+ }
143
+
144
+ /** Handle keyboard navigation */
145
+ onKeydown(event: KeyboardEvent): void {
146
+ const values = this.itemValues();
147
+ if (values.length === 0) return;
148
+
149
+ // Find the currently focused trigger
150
+ const activeElement = document.activeElement;
151
+ const currentTrigger = activeElement?.closest('[role="button"][aria-expanded]');
152
+ if (!currentTrigger) return;
153
+
154
+ // Find current index by looking at the accordion item
155
+ const accordionItem = currentTrigger.closest('AccordionItem');
156
+ const itemValue = accordionItem?.getAttribute('data-value') ||
157
+ values.find(v => document.querySelector(`AccordionItem[data-state][data-value="${v}"]`)?.contains(currentTrigger));
158
+
159
+ if (!itemValue) return;
160
+ const currentIndex = values.indexOf(itemValue);
161
+ if (currentIndex === -1) return;
162
+
163
+ let newIndex = currentIndex;
164
+ let handled = false;
165
+
166
+ switch (event.key) {
167
+ case 'ArrowDown':
168
+ newIndex = currentIndex < values.length - 1 ? currentIndex + 1 : 0;
169
+ handled = true;
170
+ break;
171
+ case 'ArrowUp':
172
+ newIndex = currentIndex > 0 ? currentIndex - 1 : values.length - 1;
173
+ handled = true;
174
+ break;
175
+ case 'Home':
176
+ newIndex = 0;
177
+ handled = true;
178
+ break;
179
+ case 'End':
180
+ newIndex = values.length - 1;
181
+ handled = true;
182
+ break;
183
+ }
184
+
185
+ if (handled) {
186
+ event.preventDefault();
187
+ // Focus the trigger of the new item
188
+ const newValue = values[newIndex];
189
+ const newTrigger = document.querySelector(
190
+ `AccordionItem[data-value="${newValue}"] AccordionTrigger, [data-accordion-trigger="${newValue}"]`
191
+ ) as HTMLElement;
192
+ newTrigger?.focus();
193
+ }
194
+ }
195
+
196
+ protected readonly computedClass = computed(() => cn('w-full', this.class()));
197
+ }
@@ -0,0 +1,15 @@
1
+ // Context and types
2
+ export {
3
+ ACCORDION_CONTEXT,
4
+ ACCORDION_ITEM_CONTEXT,
5
+ type AccordionContext,
6
+ type AccordionItemContext,
7
+ type AccordionType
8
+ } from './accordion-context';
9
+
10
+ // Components
11
+ export { AccordionContent } from './accordion-content.component';
12
+ export { AccordionItem } from './accordion-item.component';
13
+ export { AccordionTrigger } from './accordion-trigger.component';
14
+ export { Accordion } from './accordion.component';
15
+
@@ -0,0 +1,33 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+
9
+ /**
10
+ * Alert description component.
11
+ *
12
+ * @example
13
+ * <AlertDescription>You can add components to your app using the CLI.</AlertDescription>
14
+ */
15
+ @Component({
16
+ selector: 'AlertDescription',
17
+ template: `<ng-content />`,
18
+ host: {
19
+ '[class]': 'computedClass()',
20
+ 'data-slot': 'alert-description',
21
+ },
22
+ changeDetection: ChangeDetectionStrategy.OnPush,
23
+ })
24
+ export class AlertDescription {
25
+ readonly class = input<string>('');
26
+
27
+ protected readonly computedClass = computed(() =>
28
+ cn(
29
+ 'text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed',
30
+ this.class()
31
+ )
32
+ );
33
+ }
@@ -0,0 +1,30 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+
9
+ /**
10
+ * Alert title component.
11
+ *
12
+ * @example
13
+ * <AlertTitle>Heads up!</AlertTitle>
14
+ */
15
+ @Component({
16
+ selector: 'AlertTitle',
17
+ template: `<ng-content />`,
18
+ host: {
19
+ '[class]': 'computedClass()',
20
+ 'data-slot': 'alert-title',
21
+ },
22
+ changeDetection: ChangeDetectionStrategy.OnPush,
23
+ })
24
+ export class AlertTitle {
25
+ readonly class = input<string>('');
26
+
27
+ protected readonly computedClass = computed(() =>
28
+ cn('col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight', this.class())
29
+ );
30
+ }
@@ -0,0 +1,23 @@
1
+ import { cva, type VariantProps } from 'class-variance-authority';
2
+
3
+ /**
4
+ * Alert variants using class-variance-authority
5
+ * WCAG AA compliant contrast ratios for all variants
6
+ */
7
+ export const alertVariants = cva(
8
+ 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
9
+ {
10
+ variants: {
11
+ variant: {
12
+ default: 'bg-card text-card-foreground border-border',
13
+ destructive:
14
+ 'bg-destructive/10 text-destructive border-destructive/30 [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90',
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ variant: 'default',
19
+ },
20
+ }
21
+ );
22
+
23
+ export type AlertVariants = VariantProps<typeof alertVariants>;
@@ -0,0 +1,50 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+ import { alertVariants, type AlertVariants } from './alert-variants';
9
+
10
+ /**
11
+ * Alert container component.
12
+ *
13
+ * @example
14
+ * <Alert>
15
+ * <lucide-icon name="terminal" />
16
+ * <AlertTitle>Heads up!</AlertTitle>
17
+ * <AlertDescription>You can add components to your app using the CLI.</AlertDescription>
18
+ * </Alert>
19
+ *
20
+ * <!-- Destructive variant -->
21
+ * <Alert variant="destructive">
22
+ * <lucide-icon name="alert-circle" />
23
+ * <AlertTitle>Error</AlertTitle>
24
+ * <AlertDescription>Your session has expired.</AlertDescription>
25
+ * </Alert>
26
+ */
27
+ @Component({
28
+ selector: 'Alert',
29
+ template: `<ng-content />`,
30
+ host: {
31
+ '[class]': 'computedClass()',
32
+ role: 'alert',
33
+ 'data-slot': 'alert',
34
+ },
35
+ changeDetection: ChangeDetectionStrategy.OnPush,
36
+ })
37
+ export class Alert {
38
+ /** The visual style variant */
39
+ readonly variant = input<AlertVariants['variant']>('default');
40
+
41
+ /** Additional CSS classes to apply */
42
+ readonly class = input<string>('');
43
+
44
+ protected readonly computedClass = computed(() =>
45
+ cn(
46
+ alertVariants({ variant: this.variant() }),
47
+ this.class()
48
+ )
49
+ );
50
+ }