@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,241 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ inject,
7
+ input,
8
+ OnDestroy,
9
+ OnInit,
10
+ } from '@angular/core';
11
+ import { toggleVariants, type ToggleVariants } from '../toggle/toggle-variants';
12
+ import { TOGGLE_GROUP_CONTEXT } from './toggle-group-context';
13
+
14
+ // ============================================================================
15
+ // Types
16
+ // ============================================================================
17
+
18
+ export type ToggleGroupItemProps = {
19
+ /** The unique value for this toggle item */
20
+ value: string;
21
+ /** Override the variant from the group */
22
+ variant?: ToggleVariants['variant'];
23
+ /** Override the size from the group */
24
+ size?: ToggleVariants['size'];
25
+ /** Whether this toggle item is disabled */
26
+ disabled?: boolean;
27
+ /** Additional CSS classes */
28
+ class?: string;
29
+ };
30
+
31
+ // ============================================================================
32
+ // ToggleGroupItem Component
33
+ // ============================================================================
34
+
35
+ /**
36
+ * ToggleGroupItem component - individual toggle button within a group.
37
+ * Based on Radix UI ToggleGroup.Item with shadcn/ui styling.
38
+ * Supports keyboard navigation with arrow keys.
39
+ *
40
+ * ## Features
41
+ * - Can be individually styled with variant/size overrides
42
+ * - Inherits disabled state from parent group
43
+ * - Roving tabindex for efficient keyboard navigation
44
+ * - Full keyboard support
45
+ *
46
+ * ## Accessibility
47
+ * - Uses `aria-pressed` to indicate pressed state
48
+ * - Part of roving tabindex pattern
49
+ * - Supports keyboard navigation from parent group
50
+ *
51
+ * ## Data Attributes
52
+ * - `data-state`: "on" | "off"
53
+ * - `data-disabled`: Present when disabled
54
+ * - `data-value`: The item's value
55
+ *
56
+ * @example
57
+ * <ToggleGroupItem value="bold" aria-label="Toggle bold">
58
+ * <BoldIcon />
59
+ * </ToggleGroupItem>
60
+ *
61
+ * @example
62
+ * <!-- With custom variant override -->
63
+ * <ToggleGroupItem value="special" variant="outline">
64
+ * Special
65
+ * </ToggleGroupItem>
66
+ *
67
+ * @example
68
+ * <!-- Individually disabled -->
69
+ * <ToggleGroupItem value="unavailable" [disabled]="true">
70
+ * Unavailable
71
+ * </ToggleGroupItem>
72
+ *
73
+ * @see {@link https://www.radix-ui.com/primitives/docs/components/toggle-group Radix ToggleGroup}
74
+ * @see {@link https://ui.shadcn.com/docs/components/toggle-group shadcn/ui ToggleGroup}
75
+ */
76
+ @Component({
77
+ selector: 'ToggleGroupItem',
78
+ template: `<ng-content />`,
79
+ host: {
80
+ '[class]': 'computedClass()',
81
+ type: 'button',
82
+ '[attr.aria-pressed]': 'isPressed()',
83
+ '[attr.data-state]': 'state()',
84
+ '[attr.data-disabled]': 'isDisabled() ? "" : null',
85
+ '[attr.data-value]': 'value()',
86
+ '[attr.disabled]': 'isDisabled() ? "" : null',
87
+ '[attr.tabindex]': 'tabIndex()',
88
+ '(click)': 'toggle()',
89
+ '(keydown)': 'onKeyDown($event)',
90
+ 'data-slot': 'toggle-group-item',
91
+ },
92
+ changeDetection: ChangeDetectionStrategy.OnPush,
93
+ })
94
+ export class ToggleGroupItem implements OnInit, OnDestroy {
95
+ private readonly context = inject(TOGGLE_GROUP_CONTEXT, { optional: true });
96
+
97
+ /** The value of this toggle item */
98
+ readonly value = input.required<string>();
99
+
100
+ /** Override the variant from the group */
101
+ readonly variant = input<ToggleVariants['variant']>();
102
+
103
+ /** Override the size from the group */
104
+ readonly size = input<ToggleVariants['size']>();
105
+
106
+ /** Whether this toggle item is disabled */
107
+ readonly disabled = input<boolean>(false);
108
+
109
+ /** Additional CSS classes to apply */
110
+ readonly class = input<string>('');
111
+
112
+ /** Whether this item is pressed */
113
+ protected readonly isPressed = computed(() => {
114
+ return this.context?.isPressed(this.value()) ?? false;
115
+ });
116
+
117
+ /** State for data attribute */
118
+ protected readonly state = computed(() => (this.isPressed() ? 'on' : 'off'));
119
+
120
+ /** Whether this item is disabled */
121
+ protected readonly isDisabled = computed(() => {
122
+ return this.disabled() || this.context?.disabled() || false;
123
+ });
124
+
125
+ /**
126
+ * Roving tabindex pattern:
127
+ * - If roving focus is enabled: first item or focused item is tabbable
128
+ * - Otherwise: all items are tabbable
129
+ */
130
+ protected readonly tabIndex = computed(() => {
131
+ if (this.isDisabled()) return -1;
132
+ if (!this.context) return 0;
133
+
134
+ const rovingFocus = this.context.rovingFocus();
135
+ if (!rovingFocus) return 0;
136
+
137
+ const itemValues = this.context.itemValues();
138
+ const focusedValue = this.context.focusedValue();
139
+
140
+ // If an item is explicitly focused, only that item is tabbable
141
+ if (focusedValue !== null) {
142
+ return focusedValue === this.value() ? 0 : -1;
143
+ }
144
+
145
+ // Otherwise, first item is tabbable
146
+ if (itemValues.length > 0 && itemValues[0] === this.value()) {
147
+ return 0;
148
+ }
149
+
150
+ return -1;
151
+ });
152
+
153
+ /** Get the effective variant */
154
+ protected readonly effectiveVariant = computed(() => {
155
+ return this.variant() ?? this.context?.variant() ?? 'default';
156
+ });
157
+
158
+ /** Get the effective size */
159
+ protected readonly effectiveSize = computed(() => {
160
+ return this.size() ?? this.context?.size() ?? 'default';
161
+ });
162
+
163
+ ngOnInit(): void {
164
+ // Register this item with the group
165
+ this.context?.itemValues.update((values) => {
166
+ if (!values.includes(this.value())) {
167
+ return [...values, this.value()];
168
+ }
169
+ return values;
170
+ });
171
+ }
172
+
173
+ ngOnDestroy(): void {
174
+ // Unregister this item from the group
175
+ this.context?.itemValues.update((values) =>
176
+ values.filter((v) => v !== this.value())
177
+ );
178
+ }
179
+
180
+ /** Toggle this item */
181
+ toggle(): void {
182
+ if (!this.isDisabled()) {
183
+ this.context?.toggle(this.value());
184
+ }
185
+ }
186
+
187
+ /** Handle keyboard navigation */
188
+ onKeyDown(event: KeyboardEvent): void {
189
+ if (this.isDisabled() || !this.context) return;
190
+
191
+ const orientation = this.context.orientation();
192
+ const isVertical = orientation === 'vertical';
193
+ const isHorizontal = orientation === 'horizontal';
194
+
195
+ switch (event.key) {
196
+ case 'ArrowDown':
197
+ if (isVertical) {
198
+ event.preventDefault();
199
+ this.context.focusNext(this.value());
200
+ }
201
+ break;
202
+ case 'ArrowUp':
203
+ if (isVertical) {
204
+ event.preventDefault();
205
+ this.context.focusPrevious(this.value());
206
+ }
207
+ break;
208
+ case 'ArrowRight':
209
+ if (isHorizontal) {
210
+ event.preventDefault();
211
+ this.context.focusNext(this.value());
212
+ }
213
+ break;
214
+ case 'ArrowLeft':
215
+ if (isHorizontal) {
216
+ event.preventDefault();
217
+ this.context.focusPrevious(this.value());
218
+ }
219
+ break;
220
+ case 'Home':
221
+ event.preventDefault();
222
+ this.context.focusFirst();
223
+ break;
224
+ case 'End':
225
+ event.preventDefault();
226
+ this.context.focusLast();
227
+ break;
228
+ }
229
+ }
230
+
231
+ /** Computed class combining variants and custom classes */
232
+ protected readonly computedClass = computed(() =>
233
+ cn(
234
+ toggleVariants({
235
+ variant: this.effectiveVariant(),
236
+ size: this.effectiveSize(),
237
+ }),
238
+ this.class()
239
+ )
240
+ );
241
+ }
@@ -0,0 +1,288 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ ElementRef,
7
+ forwardRef,
8
+ inject,
9
+ input,
10
+ model,
11
+ output,
12
+ signal,
13
+ } from '@angular/core';
14
+ import type { ToggleVariants } from '../toggle/toggle-variants';
15
+ import {
16
+ TOGGLE_GROUP_CONTEXT,
17
+ type ToggleGroupContext,
18
+ type ToggleGroupOrientation,
19
+ type ToggleGroupType,
20
+ } from './toggle-group-context';
21
+
22
+ // ============================================================================
23
+ // Types
24
+ // ============================================================================
25
+
26
+ export type ToggleGroupProps = {
27
+ /** Selection type: single or multiple */
28
+ type?: ToggleGroupType;
29
+ /** Current selected value(s) */
30
+ value?: string | string[];
31
+ /** Default value for uncontrolled mode */
32
+ defaultValue?: string | string[];
33
+ /** Whether the group is disabled */
34
+ disabled?: boolean;
35
+ /** Visual variant for all items */
36
+ variant?: ToggleVariants['variant'];
37
+ /** Size for all items */
38
+ size?: ToggleVariants['size'];
39
+ /** Orientation for keyboard navigation */
40
+ orientation?: ToggleGroupOrientation;
41
+ /** Whether to loop focus at boundaries */
42
+ loop?: boolean;
43
+ /** Whether focus should follow selection */
44
+ rovingFocus?: boolean;
45
+ /** Additional CSS classes */
46
+ class?: string;
47
+ };
48
+
49
+ // ============================================================================
50
+ // ToggleGroup Component
51
+ // ============================================================================
52
+
53
+ /**
54
+ * ToggleGroup component - a set of toggle buttons where one or more can be pressed.
55
+ * Based on Radix UI ToggleGroup primitive with shadcn/ui styling.
56
+ * Implements keyboard navigation per WAI-ARIA toolbar pattern.
57
+ *
58
+ * ## Features
59
+ * - Single selection (only one item pressed at a time)
60
+ * - Multiple selection (any number of items can be pressed)
61
+ * - Full keyboard navigation with arrow keys
62
+ * - Roving tabindex for efficient keyboard navigation
63
+ * - Configurable variants and sizes for all items
64
+ * - Horizontal or vertical orientation
65
+ *
66
+ * ## Accessibility
67
+ * - Uses `role="group"` for grouping semantics
68
+ * - `aria-orientation` indicates layout direction
69
+ * - Roving tabindex: only one item is in tab order
70
+ * - Arrow keys navigate between items
71
+ * - Home/End keys navigate to first/last item
72
+ *
73
+ * ## Keyboard Navigation
74
+ * - **ArrowRight/ArrowDown**: Focus next item
75
+ * - **ArrowLeft/ArrowUp**: Focus previous item
76
+ * - **Home**: Focus first item
77
+ * - **End**: Focus last item
78
+ * - **Space/Enter**: Toggle focused item
79
+ *
80
+ * ## Data Attributes
81
+ * - `data-orientation`: "horizontal" | "vertical"
82
+ *
83
+ * @example
84
+ * <!-- Single selection -->
85
+ * <ToggleGroup type="single" [(value)]="alignment">
86
+ * <ToggleGroupItem value="left" aria-label="Align left">
87
+ * <AlignLeftIcon />
88
+ * </ToggleGroupItem>
89
+ * <ToggleGroupItem value="center" aria-label="Align center">
90
+ * <AlignCenterIcon />
91
+ * </ToggleGroupItem>
92
+ * <ToggleGroupItem value="right" aria-label="Align right">
93
+ * <AlignRightIcon />
94
+ * </ToggleGroupItem>
95
+ * </ToggleGroup>
96
+ *
97
+ * @example
98
+ * <!-- Multiple selection -->
99
+ * <ToggleGroup type="multiple" [(value)]="formats">
100
+ * <ToggleGroupItem value="bold" aria-label="Toggle bold">
101
+ * <BoldIcon />
102
+ * </ToggleGroupItem>
103
+ * <ToggleGroupItem value="italic" aria-label="Toggle italic">
104
+ * <ItalicIcon />
105
+ * </ToggleGroupItem>
106
+ * <ToggleGroupItem value="underline" aria-label="Toggle underline">
107
+ * <UnderlineIcon />
108
+ * </ToggleGroupItem>
109
+ * </ToggleGroup>
110
+ *
111
+ * @example
112
+ * <!-- With outline variant -->
113
+ * <ToggleGroup type="single" variant="outline" [(value)]="view">
114
+ * <ToggleGroupItem value="list">List</ToggleGroupItem>
115
+ * <ToggleGroupItem value="grid">Grid</ToggleGroupItem>
116
+ * </ToggleGroup>
117
+ *
118
+ * @example
119
+ * <!-- Vertical orientation -->
120
+ * <ToggleGroup type="single" orientation="vertical" [(value)]="size">
121
+ * <ToggleGroupItem value="sm">Small</ToggleGroupItem>
122
+ * <ToggleGroupItem value="md">Medium</ToggleGroupItem>
123
+ * <ToggleGroupItem value="lg">Large</ToggleGroupItem>
124
+ * </ToggleGroup>
125
+ *
126
+ * @see {@link https://www.radix-ui.com/primitives/docs/components/toggle-group Radix ToggleGroup}
127
+ * @see {@link https://ui.shadcn.com/docs/components/toggle-group shadcn/ui ToggleGroup}
128
+ */
129
+ @Component({
130
+ selector: 'ToggleGroup',
131
+ template: `<ng-content />`,
132
+ host: {
133
+ '[class]': 'computedClass()',
134
+ role: 'group',
135
+ '[attr.aria-orientation]': 'orientation()',
136
+ '[attr.data-orientation]': 'orientation()',
137
+ 'data-slot': 'toggle-group',
138
+ },
139
+ providers: [
140
+ {
141
+ provide: TOGGLE_GROUP_CONTEXT,
142
+ useFactory: (component: ToggleGroup) => component.context,
143
+ deps: [forwardRef(() => ToggleGroup)],
144
+ },
145
+ ],
146
+ changeDetection: ChangeDetectionStrategy.OnPush,
147
+ })
148
+ export class ToggleGroup {
149
+ private readonly elementRef = inject(ElementRef<HTMLElement>);
150
+
151
+ /** The current selected value(s) */
152
+ readonly value = model<string | string[]>('');
153
+
154
+ /** Default value for uncontrolled mode */
155
+ readonly defaultValue = input<string | string[]>('');
156
+
157
+ /** Selection type: single or multiple */
158
+ readonly type = input<ToggleGroupType>('single');
159
+
160
+ /** The visual style variant of the toggle items */
161
+ readonly variant = input<ToggleVariants['variant']>('default');
162
+
163
+ /** The size of the toggle items */
164
+ readonly size = input<ToggleVariants['size']>('default');
165
+
166
+ /** Whether the toggle group is disabled */
167
+ readonly disabled = input<boolean>(false);
168
+
169
+ /** The orientation of the toggle group */
170
+ readonly orientation = input<ToggleGroupOrientation>('horizontal');
171
+
172
+ /** Whether to loop focus at boundaries */
173
+ readonly loop = input<boolean>(true);
174
+
175
+ /** Whether focus should follow selection in single mode */
176
+ readonly rovingFocus = input<boolean>(true);
177
+
178
+ /** Additional CSS classes to apply */
179
+ readonly class = input<string>('');
180
+
181
+ /** Emitted when value changes */
182
+ readonly valueChange = output<string | string[]>();
183
+
184
+ /** Context for child ToggleGroupItem components */
185
+ readonly context: ToggleGroupContext = {
186
+ value: signal(this.value()),
187
+ type: signal(this.type()),
188
+ disabled: signal(this.disabled()),
189
+ variant: signal(this.variant()),
190
+ size: signal(this.size()),
191
+ orientation: signal(this.orientation()),
192
+ loop: signal(this.loop()),
193
+ rovingFocus: signal(this.rovingFocus()),
194
+ itemValues: signal<string[]>([]),
195
+ focusedValue: signal<string | null>(null),
196
+ toggle: (itemValue: string) => {
197
+ const currentType = this.type();
198
+ const currentValue = this.value();
199
+
200
+ let newValue: string | string[];
201
+
202
+ if (currentType === 'single') {
203
+ // In single mode, toggle off if same value, otherwise set new value
204
+ newValue = currentValue === itemValue ? '' : itemValue;
205
+ } else {
206
+ // In multiple mode, add or remove from array
207
+ const currentArray = Array.isArray(currentValue) ? currentValue : [];
208
+ newValue = currentArray.includes(itemValue)
209
+ ? currentArray.filter((v) => v !== itemValue)
210
+ : [...currentArray, itemValue];
211
+ }
212
+
213
+ this.value.set(newValue);
214
+ this.context.value.set(newValue);
215
+ this.valueChange.emit(newValue);
216
+ },
217
+ isPressed: (itemValue: string) => {
218
+ const currentValue = this.context.value();
219
+ if (Array.isArray(currentValue)) {
220
+ return currentValue.includes(itemValue);
221
+ }
222
+ return currentValue === itemValue;
223
+ },
224
+ focusNext: (currentValue: string) => this.focusItem(currentValue, 1),
225
+ focusPrevious: (currentValue: string) => this.focusItem(currentValue, -1),
226
+ focusFirst: () => this.focusItemByIndex(0),
227
+ focusLast: () =>
228
+ this.focusItemByIndex(this.context.itemValues().length - 1),
229
+ };
230
+
231
+ /** Computed class combining base styles and custom classes */
232
+ protected readonly computedClass = computed(() =>
233
+ cn(
234
+ 'flex items-center justify-center gap-1',
235
+ this.orientation() === 'vertical' && 'flex-col',
236
+ this.class()
237
+ )
238
+ );
239
+
240
+ ngOnChanges(): void {
241
+ this.context.value.set(this.value());
242
+ this.context.type.set(this.type());
243
+ this.context.disabled.set(this.disabled());
244
+ this.context.variant.set(this.variant());
245
+ this.context.size.set(this.size());
246
+ this.context.orientation.set(this.orientation());
247
+ this.context.loop.set(this.loop());
248
+ this.context.rovingFocus.set(this.rovingFocus());
249
+ }
250
+
251
+ /** Focus a toggle item relative to the current item */
252
+ private focusItem(currentValue: string, direction: number): void {
253
+ const values = this.context.itemValues();
254
+ const currentIndex = values.indexOf(currentValue);
255
+ if (currentIndex === -1) return;
256
+
257
+ const shouldLoop = this.loop();
258
+ let nextIndex = currentIndex + direction;
259
+
260
+ if (shouldLoop) {
261
+ // Wrap around
262
+ if (nextIndex < 0) nextIndex = values.length - 1;
263
+ if (nextIndex >= values.length) nextIndex = 0;
264
+ } else {
265
+ // Clamp to boundaries
266
+ if (nextIndex < 0 || nextIndex >= values.length) return;
267
+ }
268
+
269
+ this.focusItemByIndex(nextIndex);
270
+ }
271
+
272
+ /** Focus a toggle item by index */
273
+ private focusItemByIndex(index: number): void {
274
+ const values = this.context.itemValues();
275
+ if (index < 0 || index >= values.length) return;
276
+
277
+ const value = values[index];
278
+ this.context.focusedValue.set(value);
279
+
280
+ const item = this.elementRef.nativeElement.querySelector(
281
+ `[data-slot="toggle-group-item"][data-value="${value}"]`
282
+ ) as HTMLElement;
283
+
284
+ if (item) {
285
+ item.focus();
286
+ }
287
+ }
288
+ }
@@ -0,0 +1,14 @@
1
+ // Context and types
2
+ export {
3
+ TOOLTIP_CONTEXT,
4
+ type TooltipAlign,
5
+ type TooltipContextValue,
6
+ type TooltipSide
7
+ } from './tooltip-context';
8
+
9
+ // Components and their types
10
+ export { TooltipContent, type TooltipContentProps, type TooltipContentState } from './tooltip-content.component';
11
+ export { TooltipProvider, type TooltipProviderProps } from './tooltip-provider.component';
12
+ export { TooltipTrigger, type TooltipTriggerProps } from './tooltip-trigger.component';
13
+ export { Tooltip, type TooltipProps, type TooltipState } from './tooltip.component';
14
+
@@ -0,0 +1,154 @@
1
+ import { cn, Presence } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ inject,
7
+ input,
8
+ } from '@angular/core';
9
+ import { TOOLTIP_CONTEXT, TooltipAlign, TooltipSide } from './tooltip-context';
10
+
11
+ // ============================================================================
12
+ // Types
13
+ // ============================================================================
14
+
15
+ export type TooltipContentState = 'open' | 'closed';
16
+
17
+ /**
18
+ * Props for the TooltipContent component
19
+ */
20
+ export interface TooltipContentProps {
21
+ /** The preferred side of the trigger to render against.
22
+ * @default 'top' */
23
+ side?: TooltipSide;
24
+ /** The distance in pixels from the trigger.
25
+ * @default 4 */
26
+ sideOffset?: number;
27
+ /** The preferred alignment against the trigger.
28
+ * @default 'center' */
29
+ align?: TooltipAlign;
30
+ /** An offset in pixels from the "start" or "end" alignment options.
31
+ * @default 0 */
32
+ alignOffset?: number;
33
+ /** The padding between the arrow and the edges of the content.
34
+ * @default 0 */
35
+ arrowPadding?: number;
36
+ /** Additional CSS classes */
37
+ class?: string;
38
+ }
39
+
40
+ // ============================================================================
41
+ // Component
42
+ // ============================================================================
43
+
44
+ /**
45
+ * @component TooltipContent
46
+ *
47
+ * The component that pops out when the tooltip is open.
48
+ *
49
+ * @description
50
+ * TooltipContent displays the actual tooltip content. It supports positioning
51
+ * on different sides and alignments relative to the trigger.
52
+ *
53
+ * ## Features
54
+ * - Configurable side (top, right, bottom, left)
55
+ * - Configurable alignment (start, center, end)
56
+ * - Customizable offset from trigger
57
+ * - Smooth enter/exit animations
58
+ * - Uses Presence for proper exit animations
59
+ *
60
+ * ## Accessibility
61
+ * - `role="tooltip"` on the element
62
+ * - Unique ID for aria-describedby relationship with trigger
63
+ *
64
+ * @example Basic usage
65
+ * ```html
66
+ * <TooltipContent>
67
+ * <p>Tooltip content</p>
68
+ * </TooltipContent>
69
+ * ```
70
+ *
71
+ * @example With side and alignment
72
+ * ```html
73
+ * <TooltipContent side="right" align="start">
74
+ * <p>Right-aligned tooltip</p>
75
+ * </TooltipContent>
76
+ * ```
77
+ *
78
+ * @example With offset
79
+ * ```html
80
+ * <TooltipContent [sideOffset]="8">
81
+ * <p>Tooltip with more spacing</p>
82
+ * </TooltipContent>
83
+ * ```
84
+ *
85
+ * @data-attributes
86
+ * - `data-state` - 'open' | 'closed'
87
+ * - `data-side` - 'top' | 'right' | 'bottom' | 'left'
88
+ * - `data-align` - 'start' | 'center' | 'end'
89
+ */
90
+ @Component({
91
+ selector: 'TooltipContent',
92
+ imports: [Presence],
93
+ template: `
94
+ <Presence [present]="context.open()">
95
+ <div
96
+ [class]="computedClass()"
97
+ [attr.data-state]="state()"
98
+ [attr.data-side]="side()"
99
+ [attr.data-align]="align()"
100
+ role="tooltip"
101
+ [id]="context.tooltipId"
102
+ >
103
+ <ng-content />
104
+ </div>
105
+ </Presence>
106
+ `,
107
+ host: {
108
+ class: 'contents',
109
+ },
110
+ changeDetection: ChangeDetectionStrategy.OnPush,
111
+ })
112
+ export class TooltipContent {
113
+ protected readonly context = inject(TOOLTIP_CONTEXT);
114
+
115
+ /** The preferred side of the trigger to render against */
116
+ readonly side = input<TooltipSide>('top');
117
+
118
+ /** The distance in pixels from the trigger */
119
+ readonly sideOffset = input<number>(4);
120
+
121
+ /** The preferred alignment against the trigger */
122
+ readonly align = input<TooltipAlign>('center');
123
+
124
+ /** An offset in pixels from the alignment options */
125
+ readonly alignOffset = input<number>(0);
126
+
127
+ /** Additional CSS classes */
128
+ readonly class = input<string>('');
129
+
130
+ /** Current state: open or closed */
131
+ protected readonly state = computed<TooltipContentState>(() =>
132
+ this.context.open() ? 'open' : 'closed'
133
+ );
134
+
135
+ protected readonly computedClass = computed(() => {
136
+ const sideClasses = {
137
+ top: 'bottom-full left-1/2 -translate-x-1/2 mb-2',
138
+ bottom: 'top-full left-1/2 -translate-x-1/2 mt-2',
139
+ left: 'right-full top-1/2 -translate-y-1/2 mr-2',
140
+ right: 'left-full top-1/2 -translate-y-1/2 ml-2',
141
+ };
142
+
143
+ return cn(
144
+ 'absolute z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md',
145
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out',
146
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
147
+ 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
148
+ 'data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2',
149
+ 'data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
150
+ sideClasses[this.side()],
151
+ this.class()
152
+ );
153
+ });
154
+ }