@ng-cn/core 1.0.11 → 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 (394) hide show
  1. package/package.json +2 -1
  2. package/schematics/ng-add/index.js +2 -2
  3. package/schematics/ng-add/index.ts +2 -2
  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,31 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+
9
+ /**
10
+ * Typography List component (unordered list)
11
+ *
12
+ * @example
13
+ * <TypographyList>
14
+ * <li>Item 1</li>
15
+ * <li>Item 2</li>
16
+ * </TypographyList>
17
+ */
18
+ @Component({
19
+ selector: 'TypographyList',
20
+ template: `<ng-content />`,
21
+ host: {
22
+ '[class]': 'computedClass()',
23
+ },
24
+ changeDetection: ChangeDetectionStrategy.OnPush,
25
+ })
26
+ export class TypographyList {
27
+ readonly class = input<string>('');
28
+ protected readonly computedClass = computed(() =>
29
+ cn('my-6 ml-6 list-disc [&>li]:mt-2', this.class())
30
+ );
31
+ }
@@ -0,0 +1,28 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+
9
+ /**
10
+ * Typography Muted component
11
+ *
12
+ * @example
13
+ * <TypographyMuted>Muted helper text</TypographyMuted>
14
+ */
15
+ @Component({
16
+ selector: 'TypographyMuted',
17
+ template: `<ng-content />`,
18
+ host: {
19
+ '[class]': 'computedClass()',
20
+ },
21
+ changeDetection: ChangeDetectionStrategy.OnPush,
22
+ })
23
+ export class TypographyMuted {
24
+ readonly class = input<string>('');
25
+ protected readonly computedClass = computed(() =>
26
+ cn('text-sm text-muted-foreground', this.class())
27
+ );
28
+ }
@@ -0,0 +1,29 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+
9
+ /**
10
+ * Typography P (paragraph) component
11
+ *
12
+ * @example
13
+ * <TypographyP>This is a paragraph of text.</TypographyP>
14
+ */
15
+ @Component({
16
+ selector: 'TypographyP',
17
+ template: `<ng-content />`,
18
+ host: {
19
+ '[class]': 'computedClass()',
20
+ style: 'display: block',
21
+ },
22
+ changeDetection: ChangeDetectionStrategy.OnPush,
23
+ })
24
+ export class TypographyP {
25
+ readonly class = input<string>('');
26
+ protected readonly computedClass = computed(() =>
27
+ cn('leading-7 [&:not(:first-child)]:mt-6', this.class())
28
+ );
29
+ }
@@ -0,0 +1,28 @@
1
+ import { cn } from '@/lib/utils';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ computed,
6
+ input,
7
+ } from '@angular/core';
8
+
9
+ /**
10
+ * Typography Small component
11
+ *
12
+ * @example
13
+ * <TypographySmall>Small text</TypographySmall>
14
+ */
15
+ @Component({
16
+ selector: 'TypographySmall',
17
+ template: `<ng-content />`,
18
+ host: {
19
+ '[class]': 'computedClass()',
20
+ },
21
+ changeDetection: ChangeDetectionStrategy.OnPush,
22
+ })
23
+ export class TypographySmall {
24
+ readonly class = input<string>('');
25
+ protected readonly computedClass = computed(() =>
26
+ cn('text-sm font-medium leading-none', this.class())
27
+ );
28
+ }
@@ -0,0 +1,7 @@
1
+ // shadcn-angular Library Public API
2
+
3
+ // Utils
4
+ export { cn } from './utils';
5
+
6
+ // UI Components
7
+ export * from './components/ui';
@@ -0,0 +1,118 @@
1
+ import { Injectable, signal } from '@angular/core';
2
+
3
+ /**
4
+ * Service to generate and manage unique ARIA IDs for accessibility relationships.
5
+ * Handles aria-labelledby, aria-describedby, aria-controls, etc.
6
+ */
7
+ @Injectable({ providedIn: 'root' })
8
+ export class AriaIdService {
9
+ private readonly counter = signal(0);
10
+ private readonly prefix = 'aria';
11
+
12
+ /**
13
+ * Generates a unique ID with an optional prefix.
14
+ * @param customPrefix - Optional prefix for the ID (e.g., 'dialog', 'menu')
15
+ * @returns A unique string ID
16
+ */
17
+ generateId(customPrefix?: string): string {
18
+ const count = this.counter();
19
+ this.counter.set(count + 1);
20
+ const basePrefix = customPrefix ? `${this.prefix}-${customPrefix}` : this.prefix;
21
+ return `${basePrefix}-${count}-${Math.random().toString(36).substring(2, 9)}`;
22
+ }
23
+
24
+ /**
25
+ * Generates a set of related IDs for a component with title and description.
26
+ * Useful for dialogs, alerts, and other components needing ARIA relationships.
27
+ * @param prefix - Component type prefix (e.g., 'dialog', 'alert')
28
+ * @returns Object containing contentId, titleId, and descriptionId
29
+ */
30
+ generateDialogIds(prefix: string = 'dialog'): AriaDialogIds {
31
+ const base = this.generateId(prefix);
32
+ return {
33
+ contentId: `${base}-content`,
34
+ titleId: `${base}-title`,
35
+ descriptionId: `${base}-description`,
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Generates IDs for menu/listbox patterns.
41
+ * @param prefix - Component type prefix (e.g., 'menu', 'listbox', 'combobox')
42
+ * @returns Object containing triggerId, contentId, and a function to generate item IDs
43
+ */
44
+ generateMenuIds(prefix: string = 'menu'): AriaMenuIds {
45
+ const base = this.generateId(prefix);
46
+ let itemCounter = 0;
47
+
48
+ return {
49
+ triggerId: `${base}-trigger`,
50
+ contentId: `${base}-content`,
51
+ labelId: `${base}-label`,
52
+ generateItemId: () => `${base}-item-${itemCounter++}`,
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Generates IDs for tab patterns.
58
+ * @param prefix - Component type prefix
59
+ * @returns Object with functions to generate tab and panel IDs
60
+ */
61
+ generateTabIds(prefix: string = 'tabs'): AriaTabIds {
62
+ const base = this.generateId(prefix);
63
+ let tabCounter = 0;
64
+
65
+ return {
66
+ tablistId: `${base}-tablist`,
67
+ generateTabId: () => {
68
+ const id = `${base}-tab-${tabCounter}`;
69
+ tabCounter++;
70
+ return id;
71
+ },
72
+ generatePanelId: (index: number) => `${base}-panel-${index}`,
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Generates IDs for accordion patterns.
78
+ * @param prefix - Component type prefix
79
+ * @returns Object with functions to generate trigger and content IDs
80
+ */
81
+ generateAccordionIds(prefix: string = 'accordion'): AriaAccordionIds {
82
+ const base = this.generateId(prefix);
83
+ let itemCounter = 0;
84
+
85
+ return {
86
+ generateTriggerId: () => {
87
+ const id = `${base}-trigger-${itemCounter}`;
88
+ itemCounter++;
89
+ return id;
90
+ },
91
+ generateContentId: (index: number) => `${base}-content-${index}`,
92
+ };
93
+ }
94
+ }
95
+
96
+ export interface AriaDialogIds {
97
+ contentId: string;
98
+ titleId: string;
99
+ descriptionId: string;
100
+ }
101
+
102
+ export interface AriaMenuIds {
103
+ triggerId: string;
104
+ contentId: string;
105
+ labelId: string;
106
+ generateItemId: () => string;
107
+ }
108
+
109
+ export interface AriaTabIds {
110
+ tablistId: string;
111
+ generateTabId: () => string;
112
+ generatePanelId: (index: number) => string;
113
+ }
114
+
115
+ export interface AriaAccordionIds {
116
+ generateTriggerId: () => string;
117
+ generateContentId: (index: number) => string;
118
+ }
@@ -0,0 +1,85 @@
1
+ import {
2
+ Directive,
3
+ ElementRef,
4
+ OnDestroy,
5
+ afterNextRender,
6
+ inject,
7
+ output,
8
+ } from '@angular/core';
9
+
10
+ /**
11
+ * Directive that detects clicks outside the host element.
12
+ * Uses CDK-grade event handling with proper cleanup.
13
+ *
14
+ * @example
15
+ * <div (clickOutside)="onClickOutside()">
16
+ * Content here
17
+ * </div>
18
+ */
19
+ @Directive({
20
+ selector: '[clickOutside]',
21
+ })
22
+ export class ClickOutsideDirective implements OnDestroy {
23
+ private readonly elementRef = inject(ElementRef);
24
+
25
+ /** Emits when a click occurs outside the host element */
26
+ readonly clickOutside = output<MouseEvent>();
27
+
28
+ private documentClickListener: ((event: MouseEvent) => void) | null = null;
29
+ private documentTouchListener: ((event: TouchEvent) => void) | null = null;
30
+
31
+ constructor() {
32
+ // Use afterNextRender for SSR compatibility
33
+ afterNextRender(() => {
34
+ this.setupListeners();
35
+ });
36
+ }
37
+
38
+ private setupListeners(): void {
39
+ // Use setTimeout to avoid capturing the opening click
40
+ setTimeout(() => {
41
+ this.documentClickListener = (event: MouseEvent) => {
42
+ this.handleEvent(event);
43
+ };
44
+
45
+ this.documentTouchListener = (event: TouchEvent) => {
46
+ // Convert touch to a simulated mouse event for the handler
47
+ const touch = event.touches[0] || event.changedTouches[0];
48
+ if (touch) {
49
+ const mouseEvent = new MouseEvent('click', {
50
+ bubbles: true,
51
+ cancelable: true,
52
+ clientX: touch.clientX,
53
+ clientY: touch.clientY,
54
+ });
55
+ this.handleEvent(mouseEvent);
56
+ }
57
+ };
58
+
59
+ document.addEventListener('click', this.documentClickListener, true);
60
+ document.addEventListener('touchstart', this.documentTouchListener, true);
61
+ }, 0);
62
+ }
63
+
64
+ private handleEvent(event: MouseEvent): void {
65
+ const targetElement = event.target as HTMLElement;
66
+
67
+ // Check if click is outside the element
68
+ if (
69
+ targetElement &&
70
+ !this.elementRef.nativeElement.contains(targetElement) &&
71
+ this.elementRef.nativeElement !== targetElement
72
+ ) {
73
+ this.clickOutside.emit(event);
74
+ }
75
+ }
76
+
77
+ ngOnDestroy(): void {
78
+ if (this.documentClickListener) {
79
+ document.removeEventListener('click', this.documentClickListener, true);
80
+ }
81
+ if (this.documentTouchListener) {
82
+ document.removeEventListener('touchstart', this.documentTouchListener, true);
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,231 @@
1
+ import { DOCUMENT } from '@angular/common';
2
+ import { Injectable, inject, signal } from '@angular/core';
3
+
4
+ /**
5
+ * Service to manage focus state across the application.
6
+ * Handles saving/restoring focus, tracking focus history, and managing focus on open/close.
7
+ */
8
+ @Injectable({ providedIn: 'root' })
9
+ export class FocusManagementService {
10
+ private readonly document = inject(DOCUMENT);
11
+ private readonly focusStack = signal<HTMLElement[]>([]);
12
+
13
+ /**
14
+ * Saves the currently focused element to the stack.
15
+ * Call this before opening a modal/overlay to restore focus later.
16
+ * @returns The element that was saved, or null if no element was focused
17
+ */
18
+ saveFocus(): HTMLElement | null {
19
+ const activeElement = this.document.activeElement as HTMLElement | null;
20
+ if (activeElement && activeElement !== this.document.body) {
21
+ this.focusStack.update((stack) => [...stack, activeElement]);
22
+ return activeElement;
23
+ }
24
+ return null;
25
+ }
26
+
27
+ /**
28
+ * Restores focus to the last saved element and removes it from the stack.
29
+ * Call this when closing a modal/overlay.
30
+ * @returns The element that was focused, or null if stack was empty
31
+ */
32
+ restoreFocus(): HTMLElement | null {
33
+ const stack = this.focusStack();
34
+ if (stack.length === 0) return null;
35
+
36
+ const lastElement = stack[stack.length - 1];
37
+ this.focusStack.update((s) => s.slice(0, -1));
38
+
39
+ if (lastElement && this.isElementFocusable(lastElement)) {
40
+ // Use setTimeout to ensure focus happens after any animations
41
+ setTimeout(() => {
42
+ lastElement.focus();
43
+ }, 0);
44
+ return lastElement;
45
+ }
46
+ return null;
47
+ }
48
+
49
+ /**
50
+ * Focuses the first focusable element within a container.
51
+ * @param container - The container element to search within
52
+ * @param options - Focus options
53
+ * @returns The element that was focused, or null if none found
54
+ */
55
+ focusFirstFocusable(
56
+ container: HTMLElement,
57
+ options: FocusOptions = {}
58
+ ): HTMLElement | null {
59
+ const focusable = this.getFocusableElements(container);
60
+ if (focusable.length > 0) {
61
+ const target = focusable[0];
62
+ this.focusElement(target, options);
63
+ return target;
64
+ }
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * Focuses the last focusable element within a container.
70
+ * @param container - The container element to search within
71
+ * @param options - Focus options
72
+ * @returns The element that was focused, or null if none found
73
+ */
74
+ focusLastFocusable(
75
+ container: HTMLElement,
76
+ options: FocusOptions = {}
77
+ ): HTMLElement | null {
78
+ const focusable = this.getFocusableElements(container);
79
+ if (focusable.length > 0) {
80
+ const target = focusable[focusable.length - 1];
81
+ this.focusElement(target, options);
82
+ return target;
83
+ }
84
+ return null;
85
+ }
86
+
87
+ /**
88
+ * Focuses a specific element with optional delay.
89
+ * @param element - The element to focus
90
+ * @param options - Focus options including preventScroll and delay
91
+ */
92
+ focusElement(element: HTMLElement, options: FocusOptions = {}): void {
93
+ const { preventScroll = false, delay = 0 } = options;
94
+
95
+ const doFocus = () => {
96
+ if (this.isElementFocusable(element)) {
97
+ element.focus({ preventScroll });
98
+ }
99
+ };
100
+
101
+ if (delay > 0) {
102
+ setTimeout(doFocus, delay);
103
+ } else {
104
+ doFocus();
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Gets all focusable elements within a container.
110
+ * @param container - The container element to search within
111
+ * @returns Array of focusable HTML elements
112
+ */
113
+ getFocusableElements(container: HTMLElement): HTMLElement[] {
114
+ const selector = [
115
+ 'a[href]',
116
+ 'button:not([disabled])',
117
+ 'input:not([disabled]):not([type="hidden"])',
118
+ 'select:not([disabled])',
119
+ 'textarea:not([disabled])',
120
+ '[tabindex]:not([tabindex="-1"])',
121
+ '[contenteditable="true"]',
122
+ 'audio[controls]',
123
+ 'video[controls]',
124
+ 'details > summary:first-of-type',
125
+ ].join(', ');
126
+
127
+ const elements = Array.from(
128
+ container.querySelectorAll<HTMLElement>(selector)
129
+ );
130
+
131
+ return elements.filter((el) => this.isElementVisible(el));
132
+ }
133
+
134
+ /**
135
+ * Gets all tabbable elements (excludes tabindex="-1").
136
+ * @param container - The container element to search within
137
+ * @returns Array of tabbable HTML elements
138
+ */
139
+ getTabbableElements(container: HTMLElement): HTMLElement[] {
140
+ return this.getFocusableElements(container).filter((el) => {
141
+ const tabindex = el.getAttribute('tabindex');
142
+ return tabindex !== '-1';
143
+ });
144
+ }
145
+
146
+ /**
147
+ * Checks if an element is currently focusable.
148
+ * @param element - The element to check
149
+ * @returns true if the element can receive focus
150
+ */
151
+ isElementFocusable(element: HTMLElement): boolean {
152
+ if (!element || !this.document.body.contains(element)) return false;
153
+ if (!this.isElementVisible(element)) return false;
154
+
155
+ const tabindex = element.getAttribute('tabindex');
156
+ if (tabindex !== null && parseInt(tabindex, 10) < 0) return false;
157
+
158
+ // Check for disabled state
159
+ if (
160
+ element instanceof HTMLButtonElement ||
161
+ element instanceof HTMLInputElement ||
162
+ element instanceof HTMLSelectElement ||
163
+ element instanceof HTMLTextAreaElement
164
+ ) {
165
+ return !element.disabled;
166
+ }
167
+
168
+ // Check if element is naturally focusable
169
+ const focusableSelectors = [
170
+ 'a[href]',
171
+ 'button',
172
+ 'input',
173
+ 'select',
174
+ 'textarea',
175
+ '[tabindex]',
176
+ '[contenteditable="true"]',
177
+ ];
178
+
179
+ return focusableSelectors.some((selector) => element.matches(selector));
180
+ }
181
+
182
+ /**
183
+ * Checks if an element is visible (not hidden by CSS).
184
+ * @param element - The element to check
185
+ * @returns true if the element is visible
186
+ */
187
+ private isElementVisible(element: HTMLElement): boolean {
188
+ if (!element) return false;
189
+
190
+ const style = getComputedStyle(element);
191
+ if (style.display === 'none' || style.visibility === 'hidden') return false;
192
+ if (element.hasAttribute('hidden')) return false;
193
+
194
+ // Check if any ancestor is hidden
195
+ let parent = element.parentElement;
196
+ while (parent) {
197
+ const parentStyle = getComputedStyle(parent);
198
+ if (
199
+ parentStyle.display === 'none' ||
200
+ parentStyle.visibility === 'hidden'
201
+ ) {
202
+ return false;
203
+ }
204
+ if (parent.hasAttribute('hidden')) return false;
205
+ parent = parent.parentElement;
206
+ }
207
+
208
+ return true;
209
+ }
210
+
211
+ /**
212
+ * Clears the focus history stack.
213
+ */
214
+ clearFocusHistory(): void {
215
+ this.focusStack.set([]);
216
+ }
217
+
218
+ /**
219
+ * Gets the current focus stack length.
220
+ */
221
+ getFocusStackDepth(): number {
222
+ return this.focusStack().length;
223
+ }
224
+ }
225
+
226
+ export interface FocusOptions {
227
+ /** Prevents scrolling to the focused element */
228
+ preventScroll?: boolean;
229
+ /** Delay in ms before focusing */
230
+ delay?: number;
231
+ }