@ng-cn/core 1.0.10 → 1.0.12

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 (392) hide show
  1. package/package.json +3 -2
  2. package/src/app/lib/components/ui/accordion/accordion-content.component.ts +53 -0
  3. package/src/app/lib/components/ui/accordion/accordion-context.ts +33 -0
  4. package/src/app/lib/components/ui/accordion/accordion-item.component.ts +86 -0
  5. package/src/app/lib/components/ui/accordion/accordion-trigger.component.ts +73 -0
  6. package/src/app/lib/components/ui/accordion/accordion.component.ts +197 -0
  7. package/src/app/lib/components/ui/accordion/index.ts +15 -0
  8. package/src/app/lib/components/ui/alert/alert-description.component.ts +33 -0
  9. package/src/app/lib/components/ui/alert/alert-title.component.ts +30 -0
  10. package/src/app/lib/components/ui/alert/alert-variants.ts +23 -0
  11. package/src/app/lib/components/ui/alert/alert.component.ts +50 -0
  12. package/src/app/lib/components/ui/alert/index.ts +5 -0
  13. package/src/app/lib/components/ui/alert-dialog/alert-dialog-action.component.ts +44 -0
  14. package/src/app/lib/components/ui/alert-dialog/alert-dialog-cancel.component.ts +45 -0
  15. package/src/app/lib/components/ui/alert-dialog/alert-dialog-content.component.ts +146 -0
  16. package/src/app/lib/components/ui/alert-dialog/alert-dialog-context.ts +14 -0
  17. package/src/app/lib/components/ui/alert-dialog/alert-dialog-description.component.ts +37 -0
  18. package/src/app/lib/components/ui/alert-dialog/alert-dialog-footer.component.ts +35 -0
  19. package/src/app/lib/components/ui/alert-dialog/alert-dialog-header.component.ts +35 -0
  20. package/src/app/lib/components/ui/alert-dialog/alert-dialog-title.component.ts +37 -0
  21. package/src/app/lib/components/ui/alert-dialog/alert-dialog-trigger.component.ts +44 -0
  22. package/src/app/lib/components/ui/alert-dialog/alert-dialog.component.ts +91 -0
  23. package/src/app/lib/components/ui/alert-dialog/index.ts +11 -0
  24. package/src/app/lib/components/ui/aspect-ratio/aspect-ratio.component.ts +63 -0
  25. package/src/app/lib/components/ui/aspect-ratio/index.ts +1 -0
  26. package/src/app/lib/components/ui/avatar/avatar-fallback.component.ts +34 -0
  27. package/src/app/lib/components/ui/avatar/avatar-image.component.ts +31 -0
  28. package/src/app/lib/components/ui/avatar/avatar.component.ts +37 -0
  29. package/src/app/lib/components/ui/avatar/index.ts +5 -0
  30. package/src/app/lib/components/ui/avatar/ui-avatar.component.ts +52 -0
  31. package/src/app/lib/components/ui/badge/badge-variants.ts +28 -0
  32. package/src/app/lib/components/ui/badge/badge.component.ts +50 -0
  33. package/src/app/lib/components/ui/badge/index.ts +3 -0
  34. package/src/app/lib/components/ui/breadcrumb/breadcrumb-ellipsis.component.ts +48 -0
  35. package/src/app/lib/components/ui/breadcrumb/breadcrumb-item.component.ts +28 -0
  36. package/src/app/lib/components/ui/breadcrumb/breadcrumb-link.component.ts +32 -0
  37. package/src/app/lib/components/ui/breadcrumb/breadcrumb-list.component.ts +31 -0
  38. package/src/app/lib/components/ui/breadcrumb/breadcrumb-page.component.ts +31 -0
  39. package/src/app/lib/components/ui/breadcrumb/breadcrumb-separator.component.ts +47 -0
  40. package/src/app/lib/components/ui/breadcrumb/breadcrumb.component.ts +43 -0
  41. package/src/app/lib/components/ui/breadcrumb/index.ts +8 -0
  42. package/src/app/lib/components/ui/button/button-variants.ts +38 -0
  43. package/src/app/lib/components/ui/button/button.component.ts +103 -0
  44. package/src/app/lib/components/ui/button/index.ts +3 -0
  45. package/src/app/lib/components/ui/button-group/button-group-variants.ts +24 -0
  46. package/src/app/lib/components/ui/button-group/button-group.component.ts +57 -0
  47. package/src/app/lib/components/ui/button-group/index.ts +6 -0
  48. package/src/app/lib/components/ui/calendar/calendar.component.ts +368 -0
  49. package/src/app/lib/components/ui/calendar/index.ts +1 -0
  50. package/src/app/lib/components/ui/card/card-action.component.ts +39 -0
  51. package/src/app/lib/components/ui/card/card-content.component.ts +31 -0
  52. package/src/app/lib/components/ui/card/card-description.component.ts +31 -0
  53. package/src/app/lib/components/ui/card/card-footer.component.ts +34 -0
  54. package/src/app/lib/components/ui/card/card-header.component.ts +37 -0
  55. package/src/app/lib/components/ui/card/card-title.component.ts +31 -0
  56. package/src/app/lib/components/ui/card/card.component.ts +41 -0
  57. package/src/app/lib/components/ui/card/index.ts +8 -0
  58. package/src/app/lib/components/ui/carousel/carousel-content.component.ts +38 -0
  59. package/src/app/lib/components/ui/carousel/carousel-context.ts +18 -0
  60. package/src/app/lib/components/ui/carousel/carousel-item.component.ts +32 -0
  61. package/src/app/lib/components/ui/carousel/carousel-next.component.ts +54 -0
  62. package/src/app/lib/components/ui/carousel/carousel-previous.component.ts +54 -0
  63. package/src/app/lib/components/ui/carousel/carousel.component.ts +125 -0
  64. package/src/app/lib/components/ui/carousel/index.ts +7 -0
  65. package/src/app/lib/components/ui/chart/chart-container.component.ts +81 -0
  66. package/src/app/lib/components/ui/chart/chart-context.ts +38 -0
  67. package/src/app/lib/components/ui/chart/chart-legend-content.component.ts +51 -0
  68. package/src/app/lib/components/ui/chart/chart-legend.component.ts +28 -0
  69. package/src/app/lib/components/ui/chart/chart-tooltip-content.component.ts +37 -0
  70. package/src/app/lib/components/ui/chart/chart-tooltip.component.ts +28 -0
  71. package/src/app/lib/components/ui/chart/chart.component.ts +308 -0
  72. package/src/app/lib/components/ui/chart/index.ts +16 -0
  73. package/src/app/lib/components/ui/checkbox/checkbox.component.ts +203 -0
  74. package/src/app/lib/components/ui/checkbox/index.ts +1 -0
  75. package/src/app/lib/components/ui/collapsible/collapsible-content.component.ts +58 -0
  76. package/src/app/lib/components/ui/collapsible/collapsible-context.ts +17 -0
  77. package/src/app/lib/components/ui/collapsible/collapsible-trigger.component.ts +56 -0
  78. package/src/app/lib/components/ui/collapsible/collapsible.component.ts +102 -0
  79. package/src/app/lib/components/ui/collapsible/index.ts +5 -0
  80. package/src/app/lib/components/ui/combobox/combobox-content.component.ts +59 -0
  81. package/src/app/lib/components/ui/combobox/combobox-context.ts +49 -0
  82. package/src/app/lib/components/ui/combobox/combobox-empty.component.ts +35 -0
  83. package/src/app/lib/components/ui/combobox/combobox-group.component.ts +32 -0
  84. package/src/app/lib/components/ui/combobox/combobox-input.component.ts +89 -0
  85. package/src/app/lib/components/ui/combobox/combobox-item.component.ts +129 -0
  86. package/src/app/lib/components/ui/combobox/combobox-list.component.ts +40 -0
  87. package/src/app/lib/components/ui/combobox/combobox-trigger.component.ts +53 -0
  88. package/src/app/lib/components/ui/combobox/combobox-value.component.ts +47 -0
  89. package/src/app/lib/components/ui/combobox/combobox.component.ts +290 -0
  90. package/src/app/lib/components/ui/combobox/index.ts +15 -0
  91. package/src/app/lib/components/ui/command/command-context.ts +24 -0
  92. package/src/app/lib/components/ui/command/command-dialog.component.ts +69 -0
  93. package/src/app/lib/components/ui/command/command-empty.component.ts +23 -0
  94. package/src/app/lib/components/ui/command/command-group.component.ts +66 -0
  95. package/src/app/lib/components/ui/command/command-input.component.ts +137 -0
  96. package/src/app/lib/components/ui/command/command-item.component.ts +148 -0
  97. package/src/app/lib/components/ui/command/command-list.component.ts +30 -0
  98. package/src/app/lib/components/ui/command/command-separator.component.ts +23 -0
  99. package/src/app/lib/components/ui/command/command-shortcut.component.ts +23 -0
  100. package/src/app/lib/components/ui/command/command.component.ts +105 -0
  101. package/src/app/lib/components/ui/command/index.ts +11 -0
  102. package/src/app/lib/components/ui/context-menu/context-menu-checkbox-item.component.ts +68 -0
  103. package/src/app/lib/components/ui/context-menu/context-menu-content.component.ts +213 -0
  104. package/src/app/lib/components/ui/context-menu/context-menu-context.ts +17 -0
  105. package/src/app/lib/components/ui/context-menu/context-menu-item.component.ts +63 -0
  106. package/src/app/lib/components/ui/context-menu/context-menu-label.component.ts +30 -0
  107. package/src/app/lib/components/ui/context-menu/context-menu-radio-group.component.ts +36 -0
  108. package/src/app/lib/components/ui/context-menu/context-menu-radio-item.component.ts +71 -0
  109. package/src/app/lib/components/ui/context-menu/context-menu-separator.component.ts +24 -0
  110. package/src/app/lib/components/ui/context-menu/context-menu-shortcut.component.ts +23 -0
  111. package/src/app/lib/components/ui/context-menu/context-menu-sub-content.component.ts +51 -0
  112. package/src/app/lib/components/ui/context-menu/context-menu-sub-trigger.component.ts +50 -0
  113. package/src/app/lib/components/ui/context-menu/context-menu-sub.component.ts +31 -0
  114. package/src/app/lib/components/ui/context-menu/context-menu-trigger.component.ts +51 -0
  115. package/src/app/lib/components/ui/context-menu/context-menu.component.ts +27 -0
  116. package/src/app/lib/components/ui/context-menu/index.ts +15 -0
  117. package/src/app/lib/components/ui/data-table/data-table-content.component.ts +226 -0
  118. package/src/app/lib/components/ui/data-table/data-table-context.ts +49 -0
  119. package/src/app/lib/components/ui/data-table/data-table-pagination.component.ts +138 -0
  120. package/src/app/lib/components/ui/data-table/data-table-search.component.ts +52 -0
  121. package/src/app/lib/components/ui/data-table/data-table-toolbar.component.ts +27 -0
  122. package/src/app/lib/components/ui/data-table/data-table-view-options.component.ts +92 -0
  123. package/src/app/lib/components/ui/data-table/data-table.component.ts +131 -0
  124. package/src/app/lib/components/ui/data-table/index.ts +16 -0
  125. package/src/app/lib/components/ui/date-picker/date-picker.component.ts +94 -0
  126. package/src/app/lib/components/ui/date-picker/index.ts +1 -0
  127. package/src/app/lib/components/ui/dialog/dialog-close.component.ts +31 -0
  128. package/src/app/lib/components/ui/dialog/dialog-content.component.ts +177 -0
  129. package/src/app/lib/components/ui/dialog/dialog-context.ts +15 -0
  130. package/src/app/lib/components/ui/dialog/dialog-description.component.ts +34 -0
  131. package/src/app/lib/components/ui/dialog/dialog-footer.component.ts +28 -0
  132. package/src/app/lib/components/ui/dialog/dialog-header.component.ts +28 -0
  133. package/src/app/lib/components/ui/dialog/dialog-title.component.ts +34 -0
  134. package/src/app/lib/components/ui/dialog/dialog-trigger.component.ts +38 -0
  135. package/src/app/lib/components/ui/dialog/dialog.component.ts +87 -0
  136. package/src/app/lib/components/ui/dialog/index.ts +10 -0
  137. package/src/app/lib/components/ui/drawer/drawer-close.component.ts +31 -0
  138. package/src/app/lib/components/ui/drawer/drawer-content.component.ts +143 -0
  139. package/src/app/lib/components/ui/drawer/drawer-context.ts +17 -0
  140. package/src/app/lib/components/ui/drawer/drawer-description.component.ts +33 -0
  141. package/src/app/lib/components/ui/drawer/drawer-footer.component.ts +28 -0
  142. package/src/app/lib/components/ui/drawer/drawer-header.component.ts +28 -0
  143. package/src/app/lib/components/ui/drawer/drawer-title.component.ts +33 -0
  144. package/src/app/lib/components/ui/drawer/drawer-trigger.component.ts +38 -0
  145. package/src/app/lib/components/ui/drawer/drawer.component.ts +93 -0
  146. package/src/app/lib/components/ui/drawer/index.ts +10 -0
  147. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.component.ts +68 -0
  148. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-content.component.ts +234 -0
  149. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-context.ts +15 -0
  150. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-group.component.ts +15 -0
  151. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-item.component.ts +56 -0
  152. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-label.component.ts +30 -0
  153. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.component.ts +42 -0
  154. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.component.ts +71 -0
  155. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-separator.component.ts +24 -0
  156. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.component.ts +23 -0
  157. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.component.ts +51 -0
  158. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.component.ts +53 -0
  159. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-sub.component.ts +31 -0
  160. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu-trigger.component.ts +45 -0
  161. package/src/app/lib/components/ui/dropdown-menu/dropdown-menu.component.ts +32 -0
  162. package/src/app/lib/components/ui/dropdown-menu/index.ts +16 -0
  163. package/src/app/lib/components/ui/empty/empty-action.component.ts +28 -0
  164. package/src/app/lib/components/ui/empty/empty-description.component.ts +31 -0
  165. package/src/app/lib/components/ui/empty/empty-icon.component.ts +31 -0
  166. package/src/app/lib/components/ui/empty/empty-title.component.ts +28 -0
  167. package/src/app/lib/components/ui/empty/empty.component.ts +53 -0
  168. package/src/app/lib/components/ui/empty/index.ts +6 -0
  169. package/src/app/lib/components/ui/form/form-context.ts +34 -0
  170. package/src/app/lib/components/ui/form/form-control.component.ts +137 -0
  171. package/src/app/lib/components/ui/form/form-description.component.ts +37 -0
  172. package/src/app/lib/components/ui/form/form-field.component.ts +84 -0
  173. package/src/app/lib/components/ui/form/form-item.component.ts +42 -0
  174. package/src/app/lib/components/ui/form/form-label.component.ts +58 -0
  175. package/src/app/lib/components/ui/form/form-message.component.ts +107 -0
  176. package/src/app/lib/components/ui/form/form.component.ts +123 -0
  177. package/src/app/lib/components/ui/form/index.ts +17 -0
  178. package/src/app/lib/components/ui/hover-card/hover-card-content.component.ts +203 -0
  179. package/src/app/lib/components/ui/hover-card/hover-card-context.ts +25 -0
  180. package/src/app/lib/components/ui/hover-card/hover-card-trigger.component.ts +160 -0
  181. package/src/app/lib/components/ui/hover-card/hover-card.component.ts +147 -0
  182. package/src/app/lib/components/ui/hover-card/index.ts +13 -0
  183. package/src/app/lib/components/ui/index.ts +551 -0
  184. package/src/app/lib/components/ui/input/index.ts +1 -0
  185. package/src/app/lib/components/ui/input/input.component.ts +165 -0
  186. package/src/app/lib/components/ui/input-group/index.ts +4 -0
  187. package/src/app/lib/components/ui/input-group/input-group-addon.component.ts +43 -0
  188. package/src/app/lib/components/ui/input-group/input-group-input.component.ts +33 -0
  189. package/src/app/lib/components/ui/input-group/input-group.component.ts +53 -0
  190. package/src/app/lib/components/ui/input-otp/index.ts +14 -0
  191. package/src/app/lib/components/ui/input-otp/input-otp-context.ts +31 -0
  192. package/src/app/lib/components/ui/input-otp/input-otp-group.component.ts +23 -0
  193. package/src/app/lib/components/ui/input-otp/input-otp-separator.component.ts +31 -0
  194. package/src/app/lib/components/ui/input-otp/input-otp-slot.component.ts +67 -0
  195. package/src/app/lib/components/ui/input-otp/input-otp.component.ts +240 -0
  196. package/src/app/lib/components/ui/kbd/index.ts +3 -0
  197. package/src/app/lib/components/ui/kbd/kbd-variants.ts +23 -0
  198. package/src/app/lib/components/ui/kbd/kbd.component.ts +50 -0
  199. package/src/app/lib/components/ui/label/index.ts +1 -0
  200. package/src/app/lib/components/ui/label/label.component.ts +139 -0
  201. package/src/app/lib/components/ui/menubar/index.ts +26 -0
  202. package/src/app/lib/components/ui/menubar/menubar-checkbox-item.component.ts +66 -0
  203. package/src/app/lib/components/ui/menubar/menubar-content.component.ts +236 -0
  204. package/src/app/lib/components/ui/menubar/menubar-context.ts +63 -0
  205. package/src/app/lib/components/ui/menubar/menubar-item.component.ts +60 -0
  206. package/src/app/lib/components/ui/menubar/menubar-label.component.ts +30 -0
  207. package/src/app/lib/components/ui/menubar/menubar-menu.component.ts +40 -0
  208. package/src/app/lib/components/ui/menubar/menubar-radio-group.component.ts +36 -0
  209. package/src/app/lib/components/ui/menubar/menubar-radio-item.component.ts +66 -0
  210. package/src/app/lib/components/ui/menubar/menubar-separator.component.ts +24 -0
  211. package/src/app/lib/components/ui/menubar/menubar-shortcut.component.ts +23 -0
  212. package/src/app/lib/components/ui/menubar/menubar-sub-content.component.ts +51 -0
  213. package/src/app/lib/components/ui/menubar/menubar-sub-trigger.component.ts +50 -0
  214. package/src/app/lib/components/ui/menubar/menubar-sub.component.ts +29 -0
  215. package/src/app/lib/components/ui/menubar/menubar-trigger.component.ts +132 -0
  216. package/src/app/lib/components/ui/menubar/menubar.component.ts +158 -0
  217. package/src/app/lib/components/ui/native-select/index.ts +6 -0
  218. package/src/app/lib/components/ui/native-select/native-select-variants.ts +23 -0
  219. package/src/app/lib/components/ui/native-select/native-select.component.ts +74 -0
  220. package/src/app/lib/components/ui/navigation-menu/index.ts +21 -0
  221. package/src/app/lib/components/ui/navigation-menu/navigation-menu-content.component.ts +66 -0
  222. package/src/app/lib/components/ui/navigation-menu/navigation-menu-context.ts +55 -0
  223. package/src/app/lib/components/ui/navigation-menu/navigation-menu-indicator.component.ts +28 -0
  224. package/src/app/lib/components/ui/navigation-menu/navigation-menu-item.component.ts +29 -0
  225. package/src/app/lib/components/ui/navigation-menu/navigation-menu-link.component.ts +43 -0
  226. package/src/app/lib/components/ui/navigation-menu/navigation-menu-list.component.ts +26 -0
  227. package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger-style.ts +7 -0
  228. package/src/app/lib/components/ui/navigation-menu/navigation-menu-trigger.component.ts +58 -0
  229. package/src/app/lib/components/ui/navigation-menu/navigation-menu-viewport.component.ts +26 -0
  230. package/src/app/lib/components/ui/navigation-menu/navigation-menu.component.ts +149 -0
  231. package/src/app/lib/components/ui/pagination/index.ts +8 -0
  232. package/src/app/lib/components/ui/pagination/pagination-content.component.ts +28 -0
  233. package/src/app/lib/components/ui/pagination/pagination-ellipsis.component.ts +47 -0
  234. package/src/app/lib/components/ui/pagination/pagination-item.component.ts +28 -0
  235. package/src/app/lib/components/ui/pagination/pagination-link.component.ts +46 -0
  236. package/src/app/lib/components/ui/pagination/pagination-next.component.ts +54 -0
  237. package/src/app/lib/components/ui/pagination/pagination-previous.component.ts +54 -0
  238. package/src/app/lib/components/ui/pagination/pagination.component.ts +48 -0
  239. package/src/app/lib/components/ui/popover/index.ts +14 -0
  240. package/src/app/lib/components/ui/popover/popover-anchor.component.ts +64 -0
  241. package/src/app/lib/components/ui/popover/popover-content.component.ts +231 -0
  242. package/src/app/lib/components/ui/popover/popover-context.ts +29 -0
  243. package/src/app/lib/components/ui/popover/popover-trigger.component.ts +100 -0
  244. package/src/app/lib/components/ui/popover/popover.component.ts +163 -0
  245. package/src/app/lib/components/ui/progress/index.ts +6 -0
  246. package/src/app/lib/components/ui/progress/progress.component.ts +212 -0
  247. package/src/app/lib/components/ui/radio-group/index.ts +10 -0
  248. package/src/app/lib/components/ui/radio-group/radio-group-context.ts +38 -0
  249. package/src/app/lib/components/ui/radio-group/radio-group-item.component.ts +298 -0
  250. package/src/app/lib/components/ui/radio-group/radio-group.component.ts +275 -0
  251. package/src/app/lib/components/ui/resizable/index.ts +5 -0
  252. package/src/app/lib/components/ui/resizable/resizable-context.ts +14 -0
  253. package/src/app/lib/components/ui/resizable/resizable-handle.component.ts +232 -0
  254. package/src/app/lib/components/ui/resizable/resizable-panel-group.component.ts +140 -0
  255. package/src/app/lib/components/ui/resizable/resizable-panel.component.ts +77 -0
  256. package/src/app/lib/components/ui/scroll-area/index.ts +8 -0
  257. package/src/app/lib/components/ui/scroll-area/scroll-area.component.ts +126 -0
  258. package/src/app/lib/components/ui/scroll-area/scroll-bar.component.ts +93 -0
  259. package/src/app/lib/components/ui/segmented/index.ts +13 -0
  260. package/src/app/lib/components/ui/segmented/segmented-context.ts +11 -0
  261. package/src/app/lib/components/ui/segmented/segmented-item.component.ts +72 -0
  262. package/src/app/lib/components/ui/segmented/segmented-variants.ts +40 -0
  263. package/src/app/lib/components/ui/segmented/segmented.component.ts +99 -0
  264. package/src/app/lib/components/ui/select/index.ts +19 -0
  265. package/src/app/lib/components/ui/select/select-content.component.ts +97 -0
  266. package/src/app/lib/components/ui/select/select-context.ts +53 -0
  267. package/src/app/lib/components/ui/select/select-group.component.ts +56 -0
  268. package/src/app/lib/components/ui/select/select-item.component.ts +163 -0
  269. package/src/app/lib/components/ui/select/select-label.component.ts +32 -0
  270. package/src/app/lib/components/ui/select/select-separator.component.ts +34 -0
  271. package/src/app/lib/components/ui/select/select-trigger.component.ts +164 -0
  272. package/src/app/lib/components/ui/select/select-value.component.ts +49 -0
  273. package/src/app/lib/components/ui/select/select.component.ts +263 -0
  274. package/src/app/lib/components/ui/separator/index.ts +6 -0
  275. package/src/app/lib/components/ui/separator/separator.component.ts +128 -0
  276. package/src/app/lib/components/ui/sheet/index.ts +11 -0
  277. package/src/app/lib/components/ui/sheet/sheet-close.component.ts +32 -0
  278. package/src/app/lib/components/ui/sheet/sheet-content.component.ts +157 -0
  279. package/src/app/lib/components/ui/sheet/sheet-context.ts +15 -0
  280. package/src/app/lib/components/ui/sheet/sheet-description.component.ts +34 -0
  281. package/src/app/lib/components/ui/sheet/sheet-footer.component.ts +28 -0
  282. package/src/app/lib/components/ui/sheet/sheet-header.component.ts +28 -0
  283. package/src/app/lib/components/ui/sheet/sheet-title.component.ts +34 -0
  284. package/src/app/lib/components/ui/sheet/sheet-trigger.component.ts +38 -0
  285. package/src/app/lib/components/ui/sheet/sheet-variants.ts +22 -0
  286. package/src/app/lib/components/ui/sheet/sheet.component.ts +97 -0
  287. package/src/app/lib/components/ui/sidebar/index.ts +41 -0
  288. package/src/app/lib/components/ui/sidebar/sidebar-content.component.ts +31 -0
  289. package/src/app/lib/components/ui/sidebar/sidebar-context.ts +33 -0
  290. package/src/app/lib/components/ui/sidebar/sidebar-footer.component.ts +28 -0
  291. package/src/app/lib/components/ui/sidebar/sidebar-group-action.component.ts +33 -0
  292. package/src/app/lib/components/ui/sidebar/sidebar-group-content.component.ts +28 -0
  293. package/src/app/lib/components/ui/sidebar/sidebar-group-label.component.ts +32 -0
  294. package/src/app/lib/components/ui/sidebar/sidebar-group.component.ts +28 -0
  295. package/src/app/lib/components/ui/sidebar/sidebar-header.component.ts +28 -0
  296. package/src/app/lib/components/ui/sidebar/sidebar-input.component.ts +31 -0
  297. package/src/app/lib/components/ui/sidebar/sidebar-inset.component.ts +31 -0
  298. package/src/app/lib/components/ui/sidebar/sidebar-menu-action.component.ts +56 -0
  299. package/src/app/lib/components/ui/sidebar/sidebar-menu-badge.component.ts +42 -0
  300. package/src/app/lib/components/ui/sidebar/sidebar-menu-button.component.ts +64 -0
  301. package/src/app/lib/components/ui/sidebar/sidebar-menu-item.component.ts +32 -0
  302. package/src/app/lib/components/ui/sidebar/sidebar-menu-skeleton.component.ts +39 -0
  303. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-button.component.ts +59 -0
  304. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub-item.component.ts +25 -0
  305. package/src/app/lib/components/ui/sidebar/sidebar-menu-sub.component.ts +32 -0
  306. package/src/app/lib/components/ui/sidebar/sidebar-menu.component.ts +31 -0
  307. package/src/app/lib/components/ui/sidebar/sidebar-provider.component.ts +141 -0
  308. package/src/app/lib/components/ui/sidebar/sidebar-rail.component.ts +47 -0
  309. package/src/app/lib/components/ui/sidebar/sidebar-route-active.service.ts +124 -0
  310. package/src/app/lib/components/ui/sidebar/sidebar-separator.component.ts +28 -0
  311. package/src/app/lib/components/ui/sidebar/sidebar-trigger.component.ts +57 -0
  312. package/src/app/lib/components/ui/sidebar/sidebar.component.ts +130 -0
  313. package/src/app/lib/components/ui/skeleton/index.ts +1 -0
  314. package/src/app/lib/components/ui/skeleton/skeleton.component.ts +52 -0
  315. package/src/app/lib/components/ui/slider/index.ts +6 -0
  316. package/src/app/lib/components/ui/slider/slider.component.ts +477 -0
  317. package/src/app/lib/components/ui/spinner/index.ts +3 -0
  318. package/src/app/lib/components/ui/spinner/spinner-variants.ts +32 -0
  319. package/src/app/lib/components/ui/spinner/spinner.component.ts +77 -0
  320. package/src/app/lib/components/ui/switch/index.ts +6 -0
  321. package/src/app/lib/components/ui/switch/switch.component.ts +282 -0
  322. package/src/app/lib/components/ui/table/index.ts +9 -0
  323. package/src/app/lib/components/ui/table/table-body.component.ts +28 -0
  324. package/src/app/lib/components/ui/table/table-caption.component.ts +28 -0
  325. package/src/app/lib/components/ui/table/table-cell.component.ts +31 -0
  326. package/src/app/lib/components/ui/table/table-footer.component.ts +28 -0
  327. package/src/app/lib/components/ui/table/table-head.component.ts +36 -0
  328. package/src/app/lib/components/ui/table/table-header.component.ts +28 -0
  329. package/src/app/lib/components/ui/table/table-row.component.ts +34 -0
  330. package/src/app/lib/components/ui/table/table.component.ts +52 -0
  331. package/src/app/lib/components/ui/tabs/index.ts +14 -0
  332. package/src/app/lib/components/ui/tabs/tabs-content.component.ts +132 -0
  333. package/src/app/lib/components/ui/tabs/tabs-context.ts +33 -0
  334. package/src/app/lib/components/ui/tabs/tabs-list.component.ts +228 -0
  335. package/src/app/lib/components/ui/tabs/tabs-trigger.component.ts +167 -0
  336. package/src/app/lib/components/ui/tabs/tabs.component.ts +203 -0
  337. package/src/app/lib/components/ui/textarea/index.ts +1 -0
  338. package/src/app/lib/components/ui/textarea/textarea.component.ts +44 -0
  339. package/src/app/lib/components/ui/toast/index.ts +16 -0
  340. package/src/app/lib/components/ui/toast/toast-action.component.ts +77 -0
  341. package/src/app/lib/components/ui/toast/toast-description.component.ts +52 -0
  342. package/src/app/lib/components/ui/toast/toast-title.component.ts +52 -0
  343. package/src/app/lib/components/ui/toast/toast-variants.ts +24 -0
  344. package/src/app/lib/components/ui/toast/toast.component.ts +177 -0
  345. package/src/app/lib/components/ui/toast/toast.service.ts +202 -0
  346. package/src/app/lib/components/ui/toast/toaster.component.ts +128 -0
  347. package/src/app/lib/components/ui/toggle/index.ts +6 -0
  348. package/src/app/lib/components/ui/toggle/toggle-variants.ts +30 -0
  349. package/src/app/lib/components/ui/toggle/toggle.component.ts +199 -0
  350. package/src/app/lib/components/ui/toggle-group/index.ts +11 -0
  351. package/src/app/lib/components/ui/toggle-group/toggle-group-context.ts +48 -0
  352. package/src/app/lib/components/ui/toggle-group/toggle-group-item.component.ts +241 -0
  353. package/src/app/lib/components/ui/toggle-group/toggle-group.component.ts +288 -0
  354. package/src/app/lib/components/ui/tooltip/index.ts +14 -0
  355. package/src/app/lib/components/ui/tooltip/tooltip-content.component.ts +154 -0
  356. package/src/app/lib/components/ui/tooltip/tooltip-context.ts +29 -0
  357. package/src/app/lib/components/ui/tooltip/tooltip-provider.component.ts +95 -0
  358. package/src/app/lib/components/ui/tooltip/tooltip-trigger.component.ts +138 -0
  359. package/src/app/lib/components/ui/tooltip/tooltip.component.ts +159 -0
  360. package/src/app/lib/components/ui/typography/index.ts +13 -0
  361. package/src/app/lib/components/ui/typography/typography-blockquote.component.ts +31 -0
  362. package/src/app/lib/components/ui/typography/typography-h1.component.ts +32 -0
  363. package/src/app/lib/components/ui/typography/typography-h2.component.ts +32 -0
  364. package/src/app/lib/components/ui/typography/typography-h3.component.ts +29 -0
  365. package/src/app/lib/components/ui/typography/typography-h4.component.ts +29 -0
  366. package/src/app/lib/components/ui/typography/typography-inline-code.component.ts +31 -0
  367. package/src/app/lib/components/ui/typography/typography-large.component.ts +28 -0
  368. package/src/app/lib/components/ui/typography/typography-lead.component.ts +31 -0
  369. package/src/app/lib/components/ui/typography/typography-list.component.ts +31 -0
  370. package/src/app/lib/components/ui/typography/typography-muted.component.ts +28 -0
  371. package/src/app/lib/components/ui/typography/typography-p.component.ts +29 -0
  372. package/src/app/lib/components/ui/typography/typography-small.component.ts +28 -0
  373. package/src/app/lib/index.ts +7 -0
  374. package/src/app/lib/utils/accessibility/aria-id.service.ts +118 -0
  375. package/src/app/lib/utils/accessibility/click-outside.directive.ts +85 -0
  376. package/src/app/lib/utils/accessibility/focus-management.service.ts +231 -0
  377. package/src/app/lib/utils/accessibility/focus-trap.directive.ts +203 -0
  378. package/src/app/lib/utils/accessibility/index.ts +23 -0
  379. package/src/app/lib/utils/accessibility/keyboard-navigation.directive.ts +440 -0
  380. package/src/app/lib/utils/accessibility/live-region.directive.ts +260 -0
  381. package/src/app/lib/utils/accessibility/touch-target.directive.ts +81 -0
  382. package/src/app/lib/utils/accessibility/visually-hidden.component.ts +79 -0
  383. package/src/app/lib/utils/animation/animated.directive.ts +191 -0
  384. package/src/app/lib/utils/animation/animation-tokens.service.ts +88 -0
  385. package/src/app/lib/utils/animation/animation.types.ts +55 -0
  386. package/src/app/lib/utils/animation/animation.utils.ts +158 -0
  387. package/src/app/lib/utils/animation/index.ts +17 -0
  388. package/src/app/lib/utils/animation/presence.component.ts +168 -0
  389. package/src/app/lib/utils/animation/presence.directive.ts +169 -0
  390. package/src/app/lib/utils/cn.ts +15 -0
  391. package/src/app/lib/utils/index.ts +11 -0
  392. package/src/app/lib/utils/positioning/index.ts +218 -0
@@ -0,0 +1,212 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+
9
+ // ============================================================================
10
+ // Types
11
+ // ============================================================================
12
+
13
+ export type ProgressState = 'indeterminate' | 'loading' | 'complete';
14
+
15
+ export type ProgressProps = {
16
+ /** The current progress value (0 to max). Null for indeterminate. */
17
+ value?: number | null;
18
+ /** The maximum progress value */
19
+ max?: number;
20
+ /** Accessible label for the progress bar */
21
+ ariaLabel?: string;
22
+ /** Text description of current progress (e.g., "50% complete") */
23
+ ariaValueText?: string;
24
+ /** Additional CSS classes to apply to the root */
25
+ class?: string;
26
+ /** Additional CSS classes to apply to the indicator */
27
+ indicatorClass?: string;
28
+ /**
29
+ * Function to get value label for accessibility.
30
+ * Receives current value and returns descriptive text.
31
+ */
32
+ getValueLabel?: (value: number, max: number) => string;
33
+ };
34
+
35
+ // ============================================================================
36
+ // Progress Component
37
+ // ============================================================================
38
+
39
+ /**
40
+ * Progress component displays progress feedback for tasks and operations.
41
+ * Based on Radix UI Progress primitive with shadcn/ui styling.
42
+ *
43
+ * ## Features
44
+ * - Determinate mode with value from 0 to max
45
+ * - Indeterminate mode when value is null (shows loading animation)
46
+ * - Complete state when value reaches max
47
+ * - Full ARIA progressbar implementation
48
+ * - Customizable indicator styling
49
+ *
50
+ * ## Accessibility
51
+ * - Uses native `progressbar` role
52
+ * - `aria-valuenow`, `aria-valuemin`, `aria-valuemax` for current state
53
+ * - `aria-valuetext` provides human-readable progress description
54
+ * - `aria-label` for accessible name
55
+ * - `aria-live="polite"` for screen reader announcements
56
+ *
57
+ * ## Data Attributes
58
+ * - `data-state`: "indeterminate" | "loading" | "complete"
59
+ * - `data-value`: Current numeric value
60
+ * - `data-max`: Maximum value
61
+ *
62
+ * @example
63
+ * <!-- Basic progress -->
64
+ * <Progress [value]="50" />
65
+ *
66
+ * @example
67
+ * <!-- With custom max -->
68
+ * <Progress [value]="30" [max]="50" />
69
+ *
70
+ * @example
71
+ * <!-- Indeterminate (loading) -->
72
+ * <Progress />
73
+ * <!-- or explicitly -->
74
+ * <Progress [value]="null" />
75
+ *
76
+ * @example
77
+ * <!-- Complete state -->
78
+ * <Progress [value]="100" />
79
+ *
80
+ * @example
81
+ * <!-- With accessible label -->
82
+ * <Progress [value]="66" ariaLabel="Downloading file" />
83
+ *
84
+ * @example
85
+ * <!-- With custom value text -->
86
+ * <Progress
87
+ * [value]="3"
88
+ * [max]="10"
89
+ * ariaValueText="Step 3 of 10"
90
+ * />
91
+ *
92
+ * @example
93
+ * <!-- With custom value label function -->
94
+ * <Progress
95
+ * [value]="bytesLoaded"
96
+ * [max]="totalBytes"
97
+ * [getValueLabel]="formatBytes"
98
+ * />
99
+ *
100
+ * @see {@link https://www.radix-ui.com/primitives/docs/components/progress Radix Progress}
101
+ * @see {@link https://ui.shadcn.com/docs/components/progress shadcn/ui Progress}
102
+ */
103
+ @Component({
104
+ selector: 'Progress',
105
+ template: `
106
+ <div
107
+ data-slot="progress-indicator"
108
+ [class]="computedIndicatorClass()"
109
+ [style.transform]="indicatorTransform()"
110
+ ></div>
111
+ `,
112
+ host: {
113
+ '[class]': 'computedClass()',
114
+ role: 'progressbar',
115
+ '[attr.aria-label]': 'ariaLabel()',
116
+ '[attr.aria-valuemin]': '0',
117
+ '[attr.aria-valuemax]': 'max()',
118
+ '[attr.aria-valuenow]': 'value()',
119
+ '[attr.aria-valuetext]': 'computedValueText()',
120
+ '[attr.aria-live]': '"polite"',
121
+ '[attr.data-state]': 'state()',
122
+ '[attr.data-value]': 'value()',
123
+ '[attr.data-max]': 'max()',
124
+ 'data-slot': 'progress',
125
+ },
126
+ changeDetection: ChangeDetectionStrategy.OnPush,
127
+ })
128
+ export class Progress {
129
+ /** The current progress value (0 to max). Null for indeterminate. */
130
+ readonly value = input<number | null>(null);
131
+
132
+ /** The maximum progress value */
133
+ readonly max = input<number>(100);
134
+
135
+ /** Accessible label for the progress bar */
136
+ readonly ariaLabel = input<string>('Progress');
137
+
138
+ /** Text description of current progress (e.g., "50% complete") */
139
+ readonly ariaValueText = input<string | undefined>(undefined);
140
+
141
+ /**
142
+ * Function to get value label for accessibility.
143
+ * Receives current value and returns descriptive text.
144
+ */
145
+ readonly getValueLabel = input<
146
+ ((value: number, max: number) => string) | undefined
147
+ >(undefined);
148
+
149
+ /** Additional CSS classes to apply to the root */
150
+ readonly class = input<string>('');
151
+
152
+ /** Additional CSS classes to apply to the indicator */
153
+ readonly indicatorClass = input<string>('');
154
+
155
+ /** Calculate percentage (0-100) */
156
+ protected readonly percentage = computed(() => {
157
+ const val = this.value();
158
+ const maxVal = this.max();
159
+ if (val === null || maxVal === 0) return 0;
160
+ return Math.min(100, Math.max(0, (val / maxVal) * 100));
161
+ });
162
+
163
+ /** Calculate state for data attribute */
164
+ protected readonly state = computed((): ProgressState => {
165
+ const val = this.value();
166
+ if (val === null) return 'indeterminate';
167
+ return val >= this.max() ? 'complete' : 'loading';
168
+ });
169
+
170
+ /** Compute aria-valuetext */
171
+ protected readonly computedValueText = computed(() => {
172
+ const customText = this.ariaValueText();
173
+ if (customText) return customText;
174
+
175
+ const val = this.value();
176
+ if (val === null) return 'Loading';
177
+
178
+ const getLabel = this.getValueLabel();
179
+ if (getLabel) {
180
+ return getLabel(val, this.max());
181
+ }
182
+
183
+ return `${this.percentage().toFixed(0)}% complete`;
184
+ });
185
+
186
+ /** Transform for the indicator */
187
+ protected readonly indicatorTransform = computed(() => {
188
+ return `translateX(-${100 - this.percentage()}%)`;
189
+ });
190
+
191
+ /** Computed class combining base styles and custom classes */
192
+ protected readonly computedClass = computed(() =>
193
+ cn(
194
+ // Base styles
195
+ 'bg-primary/20 relative h-2 w-full overflow-hidden rounded-full',
196
+ // Custom classes
197
+ this.class()
198
+ )
199
+ );
200
+
201
+ /** Computed indicator class */
202
+ protected readonly computedIndicatorClass = computed(() =>
203
+ cn(
204
+ // Base styles
205
+ 'bg-primary h-full w-full flex-1 transition-all duration-300 ease-in-out',
206
+ // Indeterminate animation
207
+ this.state() === 'indeterminate' && 'animate-pulse',
208
+ // Custom classes
209
+ this.indicatorClass()
210
+ )
211
+ );
212
+ }
@@ -0,0 +1,10 @@
1
+ export {
2
+ RADIO_GROUP_CONTEXT,
3
+ type RadioGroupContext,
4
+ type RadioGroupOrientation,
5
+ } from './radio-group-context';
6
+ export {
7
+ RadioGroupItem,
8
+ type RadioGroupItemProps,
9
+ } from './radio-group-item.component';
10
+ export { RadioGroup, type RadioGroupProps } from './radio-group.component';
@@ -0,0 +1,38 @@
1
+ import { InjectionToken, WritableSignal } from '@angular/core';
2
+
3
+ // ============================================================================
4
+ // Types
5
+ // ============================================================================
6
+
7
+ export type RadioGroupOrientation = 'horizontal' | 'vertical';
8
+
9
+ export interface RadioGroupContext {
10
+ /** Current selected value */
11
+ value: WritableSignal<string>;
12
+ /** Whether the group is disabled */
13
+ disabled: WritableSignal<boolean>;
14
+ /** The name for radio inputs */
15
+ name: WritableSignal<string>;
16
+ /** Orientation for keyboard navigation */
17
+ orientation: WritableSignal<RadioGroupOrientation>;
18
+ /** Whether to loop focus at boundaries */
19
+ loop: WritableSignal<boolean>;
20
+ /** Whether the group is required */
21
+ required: WritableSignal<boolean>;
22
+ /** Registry of all radio item values */
23
+ itemValues: WritableSignal<string[]>;
24
+ /** Set the selected value */
25
+ setValue: (value: string) => void;
26
+ /** Move focus to the next radio item */
27
+ focusNext: (currentValue: string) => void;
28
+ /** Move focus to the previous radio item */
29
+ focusPrevious: (currentValue: string) => void;
30
+ /** Move focus to the first radio item */
31
+ focusFirst: () => void;
32
+ /** Move focus to the last radio item */
33
+ focusLast: () => void;
34
+ }
35
+
36
+ export const RADIO_GROUP_CONTEXT = new InjectionToken<RadioGroupContext>(
37
+ 'RadioGroupContext'
38
+ );
@@ -0,0 +1,298 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ ElementRef,
7
+ inject,
8
+ input,
9
+ OnDestroy,
10
+ OnInit,
11
+ viewChild,
12
+ } from '@angular/core';
13
+ import { RADIO_GROUP_CONTEXT } from './radio-group-context';
14
+
15
+ // ============================================================================
16
+ // Types
17
+ // ============================================================================
18
+
19
+ export type RadioGroupItemProps = {
20
+ /** The unique value for this radio item */
21
+ value: string;
22
+ /** The id for the radio input */
23
+ id?: string;
24
+ /** Whether this radio item is disabled */
25
+ disabled?: boolean;
26
+ /** Whether the item is required (inherited from group if not set) */
27
+ required?: boolean;
28
+ /** Additional CSS classes */
29
+ class?: string;
30
+ };
31
+
32
+ // ============================================================================
33
+ // RadioGroupItem Component
34
+ // ============================================================================
35
+
36
+ /**
37
+ * RadioGroupItem component - individual radio option within a group.
38
+ * Based on Radix UI RadioGroup.Item with shadcn/ui styling.
39
+ * Implements roving tabindex (only checked or first item is tabbable).
40
+ *
41
+ * ## Features
42
+ * - Visual indicator shows checked state
43
+ * - Inherits disabled state from parent group
44
+ * - Roving tabindex for efficient keyboard navigation
45
+ * - Full keyboard support
46
+ *
47
+ * ## Accessibility
48
+ * - Uses native radio input for built-in accessibility
49
+ * - `aria-checked` indicates checked state
50
+ * - Part of roving tabindex pattern
51
+ * - Supports keyboard navigation from parent group
52
+ *
53
+ * ## Data Attributes
54
+ * - `data-state`: "checked" | "unchecked"
55
+ * - `data-disabled`: Present when disabled
56
+ * - `data-value`: The item's value
57
+ *
58
+ * @example
59
+ * <RadioGroupItem value="option1" id="option1" />
60
+ *
61
+ * @example
62
+ * <!-- With label -->
63
+ * <div class="flex items-center gap-2">
64
+ * <RadioGroupItem value="apple" id="apple" />
65
+ * <Label for="apple">Apple</Label>
66
+ * </div>
67
+ *
68
+ * @example
69
+ * <!-- Individually disabled -->
70
+ * <RadioGroupItem value="unavailable" [disabled]="true" />
71
+ *
72
+ * @see {@link https://www.radix-ui.com/primitives/docs/components/radio-group Radix RadioGroup}
73
+ * @see {@link https://ui.shadcn.com/docs/components/radio-group shadcn/ui RadioGroup}
74
+ */
75
+ @Component({
76
+ selector: 'RadioGroupItem',
77
+ template: `
78
+ <button
79
+ #buttonElement
80
+ type="button"
81
+ role="radio"
82
+ [attr.id]="id()"
83
+ [attr.aria-checked]="isChecked()"
84
+ [attr.data-state]="state()"
85
+ [attr.data-disabled]="isDisabled() ? '' : null"
86
+ [attr.data-value]="value()"
87
+ [disabled]="isDisabled()"
88
+ [attr.tabindex]="tabIndex()"
89
+ [class]="radioClass()"
90
+ (click)="select()"
91
+ (keydown)="onKeyDown($event)"
92
+ >
93
+ @if (isChecked()) {
94
+ <span
95
+ data-slot="radio-group-indicator"
96
+ class="flex items-center justify-center"
97
+ >
98
+ <svg
99
+ xmlns="http://www.w3.org/2000/svg"
100
+ width="24"
101
+ height="24"
102
+ viewBox="0 0 24 24"
103
+ fill="currentColor"
104
+ class="size-2.5"
105
+ >
106
+ <circle cx="12" cy="12" r="10"></circle>
107
+ </svg>
108
+ </span>
109
+ }
110
+ </button>
111
+ <!-- Hidden input for form submission -->
112
+ @if (context?.name()) {
113
+ <input
114
+ type="radio"
115
+ [attr.name]="context?.name()"
116
+ [attr.value]="value()"
117
+ [checked]="isChecked()"
118
+ [disabled]="isDisabled()"
119
+ [required]="isRequired()"
120
+ aria-hidden="true"
121
+ tabindex="-1"
122
+ class="sr-only"
123
+ />
124
+ }
125
+ `,
126
+ host: {
127
+ '[class]': 'computedClass()',
128
+ 'data-slot': 'radio-group-item',
129
+ },
130
+ changeDetection: ChangeDetectionStrategy.OnPush,
131
+ })
132
+ export class RadioGroupItem implements OnInit, OnDestroy {
133
+ protected readonly context = inject(RADIO_GROUP_CONTEXT, { optional: true });
134
+ private readonly buttonElement =
135
+ viewChild<ElementRef<HTMLButtonElement>>('buttonElement');
136
+
137
+ /** The id for the radio button - used for label association */
138
+ readonly id = input<string>();
139
+
140
+ /** The value of this radio option */
141
+ readonly value = input.required<string>();
142
+
143
+ /** Whether this radio is disabled */
144
+ readonly disabled = input<boolean>(false);
145
+
146
+ /** Whether this radio is required (inherited from group if not set) */
147
+ readonly required = input<boolean | undefined>(undefined);
148
+
149
+ /** Additional CSS classes to apply */
150
+ readonly class = input<string>('');
151
+
152
+ /** Whether this item is checked */
153
+ protected readonly isChecked = computed(() => {
154
+ return this.context?.value() === this.value();
155
+ });
156
+
157
+ /** State for data attribute */
158
+ protected readonly state = computed(() =>
159
+ this.isChecked() ? 'checked' : 'unchecked'
160
+ );
161
+
162
+ /** Whether this item is disabled */
163
+ protected readonly isDisabled = computed(() => {
164
+ return this.disabled() || this.context?.disabled() || false;
165
+ });
166
+
167
+ /** Whether this item is required */
168
+ protected readonly isRequired = computed(() => {
169
+ const explicitRequired = this.required();
170
+ if (explicitRequired !== undefined) return explicitRequired;
171
+ return this.context?.required() || false;
172
+ });
173
+
174
+ /**
175
+ * Roving tabindex: only the checked item (or first item if none checked) is tabbable.
176
+ */
177
+ protected readonly tabIndex = computed(() => {
178
+ if (this.isDisabled()) return -1;
179
+ if (!this.context) return 0;
180
+
181
+ const currentValue = this.context.value();
182
+ const itemValues = this.context.itemValues();
183
+
184
+ // If this item is checked, it's tabbable
185
+ if (currentValue === this.value()) return 0;
186
+
187
+ // If no item is checked and this is the first item, it's tabbable
188
+ if (
189
+ !currentValue &&
190
+ itemValues.length > 0 &&
191
+ itemValues[0] === this.value()
192
+ ) {
193
+ return 0;
194
+ }
195
+
196
+ return -1;
197
+ });
198
+
199
+ ngOnInit(): void {
200
+ // Register this item with the group
201
+ this.context?.itemValues.update((values) => {
202
+ if (!values.includes(this.value())) {
203
+ return [...values, this.value()];
204
+ }
205
+ return values;
206
+ });
207
+ }
208
+
209
+ ngOnDestroy(): void {
210
+ // Unregister this item from the group
211
+ this.context?.itemValues.update((values) =>
212
+ values.filter((v) => v !== this.value())
213
+ );
214
+ }
215
+
216
+ /** Select this radio option */
217
+ select(): void {
218
+ if (!this.isDisabled()) {
219
+ this.context?.setValue(this.value());
220
+ }
221
+ }
222
+
223
+ /** Focus the button element */
224
+ focus(): void {
225
+ this.buttonElement()?.nativeElement.focus();
226
+ }
227
+
228
+ /** Handle keyboard navigation */
229
+ onKeyDown(event: KeyboardEvent): void {
230
+ if (this.isDisabled() || !this.context) return;
231
+
232
+ const orientation = this.context.orientation();
233
+ const isVertical = orientation === 'vertical';
234
+ const isHorizontal = orientation === 'horizontal';
235
+
236
+ switch (event.key) {
237
+ case 'ArrowDown':
238
+ if (isVertical) {
239
+ event.preventDefault();
240
+ this.context.focusNext(this.value());
241
+ }
242
+ break;
243
+ case 'ArrowUp':
244
+ if (isVertical) {
245
+ event.preventDefault();
246
+ this.context.focusPrevious(this.value());
247
+ }
248
+ break;
249
+ case 'ArrowRight':
250
+ if (isHorizontal) {
251
+ event.preventDefault();
252
+ this.context.focusNext(this.value());
253
+ }
254
+ break;
255
+ case 'ArrowLeft':
256
+ if (isHorizontal) {
257
+ event.preventDefault();
258
+ this.context.focusPrevious(this.value());
259
+ }
260
+ break;
261
+ case 'Home':
262
+ event.preventDefault();
263
+ this.context.focusFirst();
264
+ break;
265
+ case 'End':
266
+ event.preventDefault();
267
+ this.context.focusLast();
268
+ break;
269
+ case ' ':
270
+ // Space should select if not already selected
271
+ event.preventDefault();
272
+ this.select();
273
+ break;
274
+ }
275
+ }
276
+
277
+ /** Computed class for wrapper */
278
+ protected readonly computedClass = computed(() =>
279
+ cn('relative inline-flex', this.class())
280
+ );
281
+
282
+ /** Computed radio visual class */
283
+ protected readonly radioClass = computed(() =>
284
+ cn(
285
+ // Base styles
286
+ 'aspect-square size-4 shrink-0 rounded-full border shadow-xs',
287
+ 'inline-flex items-center justify-center cursor-pointer',
288
+ 'transition-[color,box-shadow] outline-none',
289
+ // Focus styles
290
+ 'focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:border-ring',
291
+ // State styles
292
+ 'border-input text-primary',
293
+ 'data-[state=checked]:border-primary',
294
+ // Disabled styles
295
+ 'disabled:cursor-not-allowed disabled:opacity-50'
296
+ )
297
+ );
298
+ }