@radix-ng/primitives 0.11.0 → 0.12.0

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 (445) hide show
  1. package/.compodocrc.json +12 -0
  2. package/CHANGELOG.md +182 -0
  3. package/LICENSE +21 -0
  4. package/accordion/__tests__/accordion-content.directive.spec.ts +8 -0
  5. package/accordion/__tests__/accordion-header.directive.spec.ts +8 -0
  6. package/accordion/__tests__/accordion-item.directive.spec.ts +8 -0
  7. package/accordion/__tests__/accordion-root.directive.spec.ts +8 -0
  8. package/accordion/__tests__/accordion-trigger.directive.spec.ts +8 -0
  9. package/accordion/ng-package.json +5 -0
  10. package/accordion/src/accordion-content.directive.ts +46 -0
  11. package/accordion/src/accordion-header.directive.ts +15 -0
  12. package/accordion/src/accordion-item.directive.ts +216 -0
  13. package/accordion/src/accordion-root.directive.ts +205 -0
  14. package/accordion/src/accordion-trigger.directive.ts +37 -0
  15. package/accordion/stories/accordion.docs.mdx +77 -0
  16. package/accordion/stories/accordion.stories.ts +340 -0
  17. package/alert-dialog/{index.d.ts → index.ts} +1 -0
  18. package/alert-dialog/ng-package.json +5 -0
  19. package/alert-dialog/src/alert-dialog-cancel.directive.ts +17 -0
  20. package/alert-dialog/src/alert-dialog-content.directive.ts +24 -0
  21. package/alert-dialog/src/alert-dialog-root.directive.ts +15 -0
  22. package/alert-dialog/src/alert-dialog-title.directive.ts +7 -0
  23. package/alert-dialog/src/alert-dialog-trigger.directive.ts +17 -0
  24. package/alert-dialog/src/alert-dialog.service.ts +51 -0
  25. package/alert-dialog/stories/alert-dialog.stories.ts +139 -0
  26. package/avatar/__tests__/avatar-fallback.directive.spec.ts +31 -0
  27. package/avatar/__tests__/avatar-image.directive.spec.ts +36 -0
  28. package/avatar/ng-package.json +5 -0
  29. package/avatar/src/avatar-fallback.directive.ts +62 -0
  30. package/avatar/src/avatar-image.directive.ts +55 -0
  31. package/avatar/src/avatar-root.directive.ts +35 -0
  32. package/avatar/src/avatar.config.ts +29 -0
  33. package/avatar/stories/avatar.docs.mdx +37 -0
  34. package/avatar/stories/avatar.stories.ts +87 -0
  35. package/button/__tests__/.gitkeep +0 -0
  36. package/button/src/button-abstract.directive.ts +46 -0
  37. package/checkbox/ng-package.json +5 -0
  38. package/checkbox/src/checkbox-button.directive.ts +26 -0
  39. package/checkbox/src/checkbox-indicator.directive.ts +16 -0
  40. package/checkbox/src/checkbox-input.directive.ts +36 -0
  41. package/checkbox/src/checkbox.directive.ts +146 -0
  42. package/checkbox/src/checkbox.token.ts +8 -0
  43. package/checkbox/stories/checkbox-group.component.ts +87 -0
  44. package/checkbox/stories/checkbox-group.styles.scss +49 -0
  45. package/checkbox/stories/checkbox-indeterminate.component.ts +52 -0
  46. package/checkbox/stories/checkbox.docs.mdx +58 -0
  47. package/checkbox/stories/checkbox.stories.ts +105 -0
  48. package/collapsible/__tests__/collapsible-content.directive.spec.ts +30 -0
  49. package/collapsible/__tests__/collapsible-root.directive.spec.ts +27 -0
  50. package/collapsible/__tests__/collapsible-trigger.directive.spec.ts +30 -0
  51. package/collapsible/ng-package.json +5 -0
  52. package/collapsible/src/collapsible-content.directive.ts +34 -0
  53. package/collapsible/src/collapsible-content.token.ts +6 -0
  54. package/collapsible/src/collapsible-root.directive.ts +120 -0
  55. package/collapsible/src/collapsible-trigger.directive.ts +44 -0
  56. package/collapsible/stories/collapsible-animation.component.ts +116 -0
  57. package/collapsible/stories/collapsible-external-triggering.component.ts +86 -0
  58. package/collapsible/stories/collapsible.docs.mdx +53 -0
  59. package/collapsible/stories/collapsible.stories.ts +151 -0
  60. package/context-menu/README.md +1 -0
  61. package/context-menu/index.ts +10 -0
  62. package/context-menu/ng-package.json +5 -0
  63. package/context-menu/src/context-menu-content.directive.ts +47 -0
  64. package/context-menu/src/context-menu-item-checkbox.directive.ts +30 -0
  65. package/context-menu/src/context-menu-item-indicator.directive.ts +14 -0
  66. package/context-menu/src/context-menu-item-radio-group.directive.ts +31 -0
  67. package/context-menu/src/context-menu-item-radio.directive.ts +69 -0
  68. package/context-menu/src/context-menu-item-selectable.ts +18 -0
  69. package/context-menu/src/context-menu-item.directive.ts +65 -0
  70. package/context-menu/src/context-menu-label.directive.ts +7 -0
  71. package/context-menu/src/context-menu-separator.directive.ts +13 -0
  72. package/context-menu/src/context-menu-trigger.directive.ts +82 -0
  73. package/context-menu/stories/context-menu.docs.mdx +23 -0
  74. package/context-menu/stories/context-menu.stories.ts +253 -0
  75. package/core/index.ts +3 -0
  76. package/core/src/accessor/provide-value-accessor.ts +20 -0
  77. package/core/src/auto-focus.directive.ts +81 -0
  78. package/core/src/inject-ng-control.ts +28 -0
  79. package/core/src/mount.ts +27 -0
  80. package/dialog/README.md +1 -0
  81. package/dialog/__tests__/dialog-content.directive.spec.ts +77 -0
  82. package/dialog/__tests__/dialog-trigger.directive.spec.ts +85 -0
  83. package/dialog/index.ts +31 -0
  84. package/dialog/ng-package.json +5 -0
  85. package/dialog/src/dialog-close.directive.ts +18 -0
  86. package/dialog/src/dialog-content.directive.ts +45 -0
  87. package/dialog/src/dialog-description.directive.ts +7 -0
  88. package/dialog/src/dialog-dismiss.directive.ts +18 -0
  89. package/dialog/src/dialog-ref.ts +70 -0
  90. package/dialog/src/dialog-title.directive.ts +7 -0
  91. package/dialog/src/dialog-trigger.directive.ts +52 -0
  92. package/dialog/src/dialog.config.ts +55 -0
  93. package/dialog/src/dialog.injectors.ts +12 -0
  94. package/dialog/src/dialog.providers.ts +27 -0
  95. package/dialog/src/dialog.service.ts +94 -0
  96. package/dialog/stories/dialog.docs.mdx +32 -0
  97. package/dialog/stories/dialog.stories.ts +233 -0
  98. package/dropdown-menu/ng-package.json +5 -0
  99. package/dropdown-menu/src/dropdown-menu-content.directive.ts +47 -0
  100. package/dropdown-menu/src/dropdown-menu-item-checkbox.directive.ts +30 -0
  101. package/dropdown-menu/src/dropdown-menu-item-indicator.directive.ts +14 -0
  102. package/dropdown-menu/src/dropdown-menu-item-radio-group.directive.ts +31 -0
  103. package/dropdown-menu/src/dropdown-menu-item-radio.directive.ts +72 -0
  104. package/dropdown-menu/src/dropdown-menu-item-selectable.ts +18 -0
  105. package/dropdown-menu/src/dropdown-menu-item.directive.ts +66 -0
  106. package/dropdown-menu/src/dropdown-menu-label.directive.ts +7 -0
  107. package/dropdown-menu/src/dropdown-menu-separator.directive.ts +13 -0
  108. package/dropdown-menu/src/dropdown-menu-trigger.directive.ts +185 -0
  109. package/dropdown-menu/stories/dropdown-menu-item-checkbox.component.ts +104 -0
  110. package/dropdown-menu/stories/dropdown-menu-item-checkbox.styles.scss +106 -0
  111. package/dropdown-menu/stories/dropdown-menu-item-radio.component.ts +95 -0
  112. package/dropdown-menu/stories/dropdown-menu-item-radio.styles.scss +106 -0
  113. package/dropdown-menu/stories/dropdown.docs.mdx +27 -0
  114. package/dropdown-menu/stories/dropdown.stories.ts +212 -0
  115. package/form-field/index.ts +1 -0
  116. package/form-field/src/.gitkeep +0 -0
  117. package/jest.config.ts +21 -0
  118. package/label/__tests__/label-root.directive.spec.ts +99 -0
  119. package/label/ng-package.json +5 -0
  120. package/label/src/label.directive.ts +58 -0
  121. package/label/stories/label.docs.mdx +40 -0
  122. package/label/stories/label.stories.ts +76 -0
  123. package/menu/index.ts +29 -0
  124. package/menu/ng-package.json +5 -0
  125. package/menu/src/menu-content.directive.ts +9 -0
  126. package/menu/src/menu-directive.ts +10 -0
  127. package/menu/src/menu-group.directive.ts +12 -0
  128. package/menu/src/menu-item.directive.ts +44 -0
  129. package/menu/src/menu-label.directive.ts +7 -0
  130. package/menu/src/menu-separator.directive.ts +13 -0
  131. package/menubar/index.ts +38 -0
  132. package/menubar/ng-package.json +5 -0
  133. package/menubar/src/menubar-content.directive.ts +9 -0
  134. package/menubar/src/menubar-item-checkbox.directive.ts +32 -0
  135. package/menubar/src/menubar-item-indicator.directive.ts +10 -0
  136. package/menubar/src/menubar-item-radio.directive.ts +33 -0
  137. package/menubar/src/menubar-item.directive.ts +12 -0
  138. package/menubar/src/menubar-radio-group.directive.ts +9 -0
  139. package/menubar/src/menubar-root.directive.ts +15 -0
  140. package/menubar/src/menubar-separator.directive.ts +9 -0
  141. package/menubar/src/menubar-trigger.directive.ts +40 -0
  142. package/menubar/stories/menubar.stories.ts +229 -0
  143. package/ng-package.json +8 -0
  144. package/package.json +4 -112
  145. package/portal/stories/portal.docs.mdx +85 -0
  146. package/presence/__test__/presence-test.component.ts +51 -0
  147. package/presence/__test__/presence.spec.ts +50 -0
  148. package/presence/index.ts +4 -0
  149. package/presence/src/presence.ts +119 -0
  150. package/presence/src/transitions/transition.collapse.ts +99 -0
  151. package/presence/src/transitions/transition.toast.ts +27 -0
  152. package/presence/src/types.ts +20 -0
  153. package/presence/src/utils.ts +63 -0
  154. package/presence/stories/presence-story.componen.ts +69 -0
  155. package/presence/stories/presence.docs.mdx +40 -0
  156. package/presence/stories/presence.stories.ts +29 -0
  157. package/progress/__test__/progress.spec.ts +55 -0
  158. package/progress/{index.d.ts → index.ts} +1 -0
  159. package/progress/ng-package.json +5 -0
  160. package/progress/src/progress-indicator.directive.ts +26 -0
  161. package/progress/src/progress-root.directive.ts +134 -0
  162. package/progress/stories/progress.docs.mdx +65 -0
  163. package/progress/stories/progress.stories.ts +66 -0
  164. package/project.json +39 -0
  165. package/radio/{index.d.ts → index.ts} +1 -0
  166. package/radio/ng-package.json +5 -0
  167. package/radio/src/radio-indicator.directive.ts +17 -0
  168. package/radio/src/radio-item.directive.ts +68 -0
  169. package/radio/src/radio-root.directive.ts +207 -0
  170. package/radio/src/{radio-tokens.d.ts → radio-tokens.ts} +5 -1
  171. package/radio/stories/radio-group.component.ts +39 -0
  172. package/radio/stories/radio-group.styles.scss +70 -0
  173. package/radio/stories/radio.docs.mdx +68 -0
  174. package/radio/stories/radio.stories.ts +155 -0
  175. package/separator/__tests__/separator.directive.spec.ts +58 -0
  176. package/separator/ng-package.json +5 -0
  177. package/separator/src/separator.directive.ts +35 -0
  178. package/separator/stories/separator.docs.mdx +37 -0
  179. package/separator/stories/separator.stories.ts +82 -0
  180. package/slider/src/slider-input.directive.ts +0 -0
  181. package/slider/src/slider-thumb.directives.ts +60 -0
  182. package/slider/src/slider-track.directive.ts +11 -0
  183. package/slider/src/slider.directive.ts +59 -0
  184. package/slider/src/slider.types.ts +4 -0
  185. package/switch/index.ts +22 -0
  186. package/switch/ng-package.json +5 -0
  187. package/switch/src/switch-input.directive.ts +24 -0
  188. package/switch/src/switch-root.directive.ts +127 -0
  189. package/switch/src/switch-thumb.directive.ts +15 -0
  190. package/switch/stories/switch.docs.mdx +83 -0
  191. package/switch/stories/switch.stories.ts +149 -0
  192. package/tabs/__tests__/tabs-context.service.spec.ts +35 -0
  193. package/tabs/index.ts +26 -0
  194. package/tabs/ng-package.json +5 -0
  195. package/tabs/src/tabs-content.directive.ts +23 -0
  196. package/tabs/src/tabs-context.service.ts +43 -0
  197. package/tabs/src/tabs-list.directive.ts +21 -0
  198. package/tabs/src/tabs-root.directive.ts +70 -0
  199. package/tabs/src/tabs-trigger.directive.ts +55 -0
  200. package/tabs/stories/tabs.stories.ts +213 -0
  201. package/test-setup.ts +1 -0
  202. package/toggle/__tests__/toggle.directive.spec.ts +87 -0
  203. package/toggle/ng-package.json +5 -0
  204. package/toggle/src/toggle.directive.ts +49 -0
  205. package/toggle/stories/toggle.docs.mdx +60 -0
  206. package/toggle/stories/toggle.stories.ts +84 -0
  207. package/toggle-group/ng-package.json +5 -0
  208. package/toggle-group/src/toggle-group-button.directive.ts +73 -0
  209. package/toggle-group/src/toggle-group-button.token.ts +8 -0
  210. package/toggle-group/src/toggle-group-multi.directive.ts +158 -0
  211. package/toggle-group/src/toggle-group.directive.ts +148 -0
  212. package/toggle-group/src/toggle-group.token.ts +11 -0
  213. package/toggle-group/stories/toggle-group.docs.mdx +87 -0
  214. package/toggle-group/stories/toggle-group.stories.ts +95 -0
  215. package/tsconfig.doc.json +11 -0
  216. package/tsconfig.json +29 -0
  217. package/tsconfig.lib.json +19 -0
  218. package/tsconfig.lib.prod.json +12 -0
  219. package/tsconfig.spec.json +11 -0
  220. package/visually-hidden/README.md +3 -0
  221. package/visually-hidden/stories/visually-hidden.docs.mdx +36 -0
  222. package/accordion/src/accordion-content.directive.d.ts +0 -16
  223. package/accordion/src/accordion-header.directive.d.ts +0 -7
  224. package/accordion/src/accordion-item.directive.d.ts +0 -62
  225. package/accordion/src/accordion-root.directive.d.ts +0 -78
  226. package/accordion/src/accordion-trigger.directive.d.ts +0 -15
  227. package/alert-dialog/src/alert-dialog-cancel.directive.d.ts +0 -7
  228. package/alert-dialog/src/alert-dialog-content.directive.d.ts +0 -9
  229. package/alert-dialog/src/alert-dialog-root.directive.d.ts +0 -9
  230. package/alert-dialog/src/alert-dialog-title.directive.d.ts +0 -5
  231. package/alert-dialog/src/alert-dialog-trigger.directive.d.ts +0 -7
  232. package/alert-dialog/src/alert-dialog.service.d.ts +0 -14
  233. package/avatar/src/avatar-fallback.directive.d.ts +0 -27
  234. package/avatar/src/avatar-image.directive.d.ts +0 -16
  235. package/avatar/src/avatar-root.directive.d.ts +0 -21
  236. package/avatar/src/avatar.config.d.ts +0 -13
  237. package/checkbox/src/checkbox-button.directive.d.ts +0 -8
  238. package/checkbox/src/checkbox-indicator.directive.d.ts +0 -6
  239. package/checkbox/src/checkbox-input.directive.d.ts +0 -9
  240. package/checkbox/src/checkbox.directive.d.ts +0 -75
  241. package/checkbox/src/checkbox.token.d.ts +0 -4
  242. package/collapsible/src/collapsible-content.directive.d.ts +0 -17
  243. package/collapsible/src/collapsible-content.token.d.ts +0 -3
  244. package/collapsible/src/collapsible-root.directive.d.ts +0 -55
  245. package/collapsible/src/collapsible-trigger.directive.d.ts +0 -26
  246. package/compodoc/documentation.json +0 -11395
  247. package/dropdown-menu/src/dropdown-menu-content.directive.d.ts +0 -15
  248. package/dropdown-menu/src/dropdown-menu-item-checkbox.directive.d.ts +0 -9
  249. package/dropdown-menu/src/dropdown-menu-item-indicator.directive.d.ts +0 -7
  250. package/dropdown-menu/src/dropdown-menu-item-radio-group.directive.d.ts +0 -12
  251. package/dropdown-menu/src/dropdown-menu-item-radio.directive.d.ts +0 -19
  252. package/dropdown-menu/src/dropdown-menu-item-selectable.d.ts +0 -12
  253. package/dropdown-menu/src/dropdown-menu-item.directive.d.ts +0 -17
  254. package/dropdown-menu/src/dropdown-menu-label.directive.d.ts +0 -5
  255. package/dropdown-menu/src/dropdown-menu-separator.directive.d.ts +0 -6
  256. package/dropdown-menu/src/dropdown-menu-trigger.directive.d.ts +0 -43
  257. package/esm2022/accordion/index.mjs +0 -6
  258. package/esm2022/accordion/radix-ng-primitives-accordion.mjs +0 -5
  259. package/esm2022/accordion/src/accordion-content.directive.mjs +0 -36
  260. package/esm2022/accordion/src/accordion-header.directive.mjs +0 -23
  261. package/esm2022/accordion/src/accordion-item.directive.mjs +0 -170
  262. package/esm2022/accordion/src/accordion-root.directive.mjs +0 -157
  263. package/esm2022/accordion/src/accordion-trigger.directive.mjs +0 -42
  264. package/esm2022/alert-dialog/index.mjs +0 -7
  265. package/esm2022/alert-dialog/radix-ng-primitives-alert-dialog.mjs +0 -5
  266. package/esm2022/alert-dialog/src/alert-dialog-cancel.directive.mjs +0 -24
  267. package/esm2022/alert-dialog/src/alert-dialog-content.directive.mjs +0 -34
  268. package/esm2022/alert-dialog/src/alert-dialog-root.directive.mjs +0 -25
  269. package/esm2022/alert-dialog/src/alert-dialog-title.directive.mjs +0 -14
  270. package/esm2022/alert-dialog/src/alert-dialog-trigger.directive.mjs +0 -24
  271. package/esm2022/alert-dialog/src/alert-dialog.service.mjs +0 -47
  272. package/esm2022/avatar/index.mjs +0 -5
  273. package/esm2022/avatar/radix-ng-primitives-avatar.mjs +0 -5
  274. package/esm2022/avatar/src/avatar-fallback.directive.mjs +0 -54
  275. package/esm2022/avatar/src/avatar-image.directive.mjs +0 -48
  276. package/esm2022/avatar/src/avatar-root.directive.mjs +0 -38
  277. package/esm2022/avatar/src/avatar.config.mjs +0 -17
  278. package/esm2022/checkbox/index.mjs +0 -6
  279. package/esm2022/checkbox/radix-ng-primitives-checkbox.mjs +0 -5
  280. package/esm2022/checkbox/src/checkbox-button.directive.mjs +0 -33
  281. package/esm2022/checkbox/src/checkbox-indicator.directive.mjs +0 -24
  282. package/esm2022/checkbox/src/checkbox-input.directive.mjs +0 -41
  283. package/esm2022/checkbox/src/checkbox.directive.mjs +0 -141
  284. package/esm2022/checkbox/src/checkbox.token.mjs +0 -6
  285. package/esm2022/collapsible/index.mjs +0 -4
  286. package/esm2022/collapsible/radix-ng-primitives-collapsible.mjs +0 -5
  287. package/esm2022/collapsible/src/collapsible-content.directive.mjs +0 -45
  288. package/esm2022/collapsible/src/collapsible-content.token.mjs +0 -3
  289. package/esm2022/collapsible/src/collapsible-root.directive.mjs +0 -118
  290. package/esm2022/collapsible/src/collapsible-trigger.directive.mjs +0 -49
  291. package/esm2022/dropdown-menu/index.mjs +0 -11
  292. package/esm2022/dropdown-menu/radix-ng-primitives-dropdown-menu.mjs +0 -5
  293. package/esm2022/dropdown-menu/src/dropdown-menu-content.directive.mjs +0 -56
  294. package/esm2022/dropdown-menu/src/dropdown-menu-item-checkbox.directive.mjs +0 -36
  295. package/esm2022/dropdown-menu/src/dropdown-menu-item-indicator.directive.mjs +0 -22
  296. package/esm2022/dropdown-menu/src/dropdown-menu-item-radio-group.directive.mjs +0 -37
  297. package/esm2022/dropdown-menu/src/dropdown-menu-item-radio.directive.mjs +0 -64
  298. package/esm2022/dropdown-menu/src/dropdown-menu-item-selectable.mjs +0 -31
  299. package/esm2022/dropdown-menu/src/dropdown-menu-item.directive.mjs +0 -71
  300. package/esm2022/dropdown-menu/src/dropdown-menu-label.directive.mjs +0 -14
  301. package/esm2022/dropdown-menu/src/dropdown-menu-separator.directive.mjs +0 -21
  302. package/esm2022/dropdown-menu/src/dropdown-menu-trigger.directive.mjs +0 -176
  303. package/esm2022/index.mjs +0 -2
  304. package/esm2022/label/index.mjs +0 -2
  305. package/esm2022/label/radix-ng-primitives-label.mjs +0 -5
  306. package/esm2022/label/src/label.directive.mjs +0 -59
  307. package/esm2022/menu/index.mjs +0 -45
  308. package/esm2022/menu/radix-ng-primitives-menu.mjs +0 -5
  309. package/esm2022/menu/src/menu-content.directive.mjs +0 -17
  310. package/esm2022/menu/src/menu-directive.mjs +0 -18
  311. package/esm2022/menu/src/menu-group.directive.mjs +0 -20
  312. package/esm2022/menu/src/menu-item.directive.mjs +0 -46
  313. package/esm2022/menu/src/menu-label.directive.mjs +0 -14
  314. package/esm2022/menu/src/menu-separator.directive.mjs +0 -21
  315. package/esm2022/menubar/index.mjs +0 -60
  316. package/esm2022/menubar/radix-ng-primitives-menubar.mjs +0 -5
  317. package/esm2022/menubar/src/menubar-content.directive.mjs +0 -17
  318. package/esm2022/menubar/src/menubar-item-checkbox.directive.mjs +0 -34
  319. package/esm2022/menubar/src/menubar-item-indicator.directive.mjs +0 -17
  320. package/esm2022/menubar/src/menubar-item-radio.directive.mjs +0 -35
  321. package/esm2022/menubar/src/menubar-item.directive.mjs +0 -20
  322. package/esm2022/menubar/src/menubar-radio-group.directive.mjs +0 -17
  323. package/esm2022/menubar/src/menubar-root.directive.mjs +0 -24
  324. package/esm2022/menubar/src/menubar-separator.directive.mjs +0 -17
  325. package/esm2022/menubar/src/menubar-trigger.directive.mjs +0 -45
  326. package/esm2022/progress/index.mjs +0 -3
  327. package/esm2022/progress/radix-ng-primitives-progress.mjs +0 -5
  328. package/esm2022/progress/src/progress-indicator.directive.mjs +0 -34
  329. package/esm2022/progress/src/progress-root.directive.mjs +0 -127
  330. package/esm2022/radio/index.mjs +0 -4
  331. package/esm2022/radio/radix-ng-primitives-radio.mjs +0 -5
  332. package/esm2022/radio/src/radio-indicator.directive.mjs +0 -25
  333. package/esm2022/radio/src/radio-item.directive.mjs +0 -70
  334. package/esm2022/radio/src/radio-root.directive.mjs +0 -194
  335. package/esm2022/radio/src/radio-tokens.mjs +0 -3
  336. package/esm2022/radix-ng-primitives.mjs +0 -5
  337. package/esm2022/separator/index.mjs +0 -2
  338. package/esm2022/separator/radix-ng-primitives-separator.mjs +0 -5
  339. package/esm2022/separator/src/separator.directive.mjs +0 -31
  340. package/esm2022/switch/index.mjs +0 -30
  341. package/esm2022/switch/radix-ng-primitives-switch.mjs +0 -5
  342. package/esm2022/switch/src/switch-input.directive.mjs +0 -32
  343. package/esm2022/switch/src/switch-root.directive.mjs +0 -95
  344. package/esm2022/switch/src/switch-thumb.directive.mjs +0 -23
  345. package/esm2022/tabs/index.mjs +0 -38
  346. package/esm2022/tabs/radix-ng-primitives-tabs.mjs +0 -5
  347. package/esm2022/tabs/src/tabs-content.directive.mjs +0 -29
  348. package/esm2022/tabs/src/tabs-context.service.mjs +0 -43
  349. package/esm2022/tabs/src/tabs-list.directive.mjs +0 -23
  350. package/esm2022/tabs/src/tabs-root.directive.mjs +0 -54
  351. package/esm2022/tabs/src/tabs-trigger.directive.mjs +0 -52
  352. package/esm2022/toggle/index.mjs +0 -2
  353. package/esm2022/toggle/radix-ng-primitives-toggle.mjs +0 -5
  354. package/esm2022/toggle/src/toggle.directive.mjs +0 -39
  355. package/esm2022/toggle-group/index.mjs +0 -6
  356. package/esm2022/toggle-group/radix-ng-primitives-toggle-group.mjs +0 -5
  357. package/esm2022/toggle-group/src/toggle-group-button.directive.mjs +0 -75
  358. package/esm2022/toggle-group/src/toggle-group-button.token.mjs +0 -6
  359. package/esm2022/toggle-group/src/toggle-group-multi.directive.mjs +0 -143
  360. package/esm2022/toggle-group/src/toggle-group.directive.mjs +0 -134
  361. package/esm2022/toggle-group/src/toggle-group.token.mjs +0 -6
  362. package/fesm2022/radix-ng-primitives-accordion.mjs +0 -418
  363. package/fesm2022/radix-ng-primitives-accordion.mjs.map +0 -1
  364. package/fesm2022/radix-ng-primitives-alert-dialog.mjs +0 -161
  365. package/fesm2022/radix-ng-primitives-alert-dialog.mjs.map +0 -1
  366. package/fesm2022/radix-ng-primitives-avatar.mjs +0 -156
  367. package/fesm2022/radix-ng-primitives-avatar.mjs.map +0 -1
  368. package/fesm2022/radix-ng-primitives-checkbox.mjs +0 -241
  369. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +0 -1
  370. package/fesm2022/radix-ng-primitives-collapsible.mjs +0 -213
  371. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +0 -1
  372. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs +0 -502
  373. package/fesm2022/radix-ng-primitives-dropdown-menu.mjs.map +0 -1
  374. package/fesm2022/radix-ng-primitives-label.mjs +0 -66
  375. package/fesm2022/radix-ng-primitives-label.mjs.map +0 -1
  376. package/fesm2022/radix-ng-primitives-menu.mjs +0 -158
  377. package/fesm2022/radix-ng-primitives-menu.mjs.map +0 -1
  378. package/fesm2022/radix-ng-primitives-menubar.mjs +0 -245
  379. package/fesm2022/radix-ng-primitives-menubar.mjs.map +0 -1
  380. package/fesm2022/radix-ng-primitives-progress.mjs +0 -165
  381. package/fesm2022/radix-ng-primitives-progress.mjs.map +0 -1
  382. package/fesm2022/radix-ng-primitives-radio.mjs +0 -289
  383. package/fesm2022/radix-ng-primitives-radio.mjs.map +0 -1
  384. package/fesm2022/radix-ng-primitives-separator.mjs +0 -38
  385. package/fesm2022/radix-ng-primitives-separator.mjs.map +0 -1
  386. package/fesm2022/radix-ng-primitives-switch.mjs +0 -173
  387. package/fesm2022/radix-ng-primitives-switch.mjs.map +0 -1
  388. package/fesm2022/radix-ng-primitives-tabs.mjs +0 -222
  389. package/fesm2022/radix-ng-primitives-tabs.mjs.map +0 -1
  390. package/fesm2022/radix-ng-primitives-toggle-group.mjs +0 -358
  391. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +0 -1
  392. package/fesm2022/radix-ng-primitives-toggle.mjs +0 -46
  393. package/fesm2022/radix-ng-primitives-toggle.mjs.map +0 -1
  394. package/fesm2022/radix-ng-primitives.mjs +0 -4
  395. package/fesm2022/radix-ng-primitives.mjs.map +0 -1
  396. package/label/src/label.directive.d.ts +0 -29
  397. package/menu/index.d.ts +0 -18
  398. package/menu/src/menu-content.directive.d.ts +0 -6
  399. package/menu/src/menu-directive.d.ts +0 -6
  400. package/menu/src/menu-group.directive.d.ts +0 -6
  401. package/menu/src/menu-item.directive.d.ts +0 -12
  402. package/menu/src/menu-label.directive.d.ts +0 -5
  403. package/menu/src/menu-separator.directive.d.ts +0 -6
  404. package/menubar/index.d.ts +0 -24
  405. package/menubar/src/menubar-content.directive.d.ts +0 -6
  406. package/menubar/src/menubar-item-checkbox.directive.d.ts +0 -14
  407. package/menubar/src/menubar-item-indicator.directive.d.ts +0 -5
  408. package/menubar/src/menubar-item-radio.directive.d.ts +0 -14
  409. package/menubar/src/menubar-item.directive.d.ts +0 -8
  410. package/menubar/src/menubar-radio-group.directive.d.ts +0 -6
  411. package/menubar/src/menubar-root.directive.d.ts +0 -7
  412. package/menubar/src/menubar-separator.directive.d.ts +0 -6
  413. package/menubar/src/menubar-trigger.directive.d.ts +0 -11
  414. package/progress/src/progress-indicator.directive.d.ts +0 -16
  415. package/progress/src/progress-root.directive.d.ts +0 -63
  416. package/radio/src/radio-indicator.directive.d.ts +0 -9
  417. package/radio/src/radio-item.directive.d.ts +0 -21
  418. package/radio/src/radio-root.directive.d.ts +0 -72
  419. package/separator/src/separator.directive.d.ts +0 -22
  420. package/switch/index.d.ts +0 -13
  421. package/switch/src/switch-input.directive.d.ts +0 -6
  422. package/switch/src/switch-root.directive.d.ts +0 -51
  423. package/switch/src/switch-thumb.directive.d.ts +0 -6
  424. package/tabs/index.d.ts +0 -15
  425. package/tabs/src/tabs-content.directive.d.ts +0 -8
  426. package/tabs/src/tabs-context.service.d.ts +0 -22
  427. package/tabs/src/tabs-list.directive.d.ts +0 -6
  428. package/tabs/src/tabs-root.directive.d.ts +0 -37
  429. package/tabs/src/tabs-trigger.directive.d.ts +0 -19
  430. package/toggle/src/toggle.directive.d.ts +0 -30
  431. package/toggle-group/src/toggle-group-button.directive.d.ts +0 -39
  432. package/toggle-group/src/toggle-group-button.token.d.ts +0 -4
  433. package/toggle-group/src/toggle-group-multi.directive.d.ts +0 -93
  434. package/toggle-group/src/toggle-group.directive.d.ts +0 -84
  435. package/toggle-group/src/toggle-group.token.d.ts +0 -5
  436. /package/accordion/{index.d.ts → index.ts} +0 -0
  437. /package/avatar/{index.d.ts → index.ts} +0 -0
  438. /package/checkbox/{index.d.ts → index.ts} +0 -0
  439. /package/collapsible/{index.d.ts → index.ts} +0 -0
  440. /package/dropdown-menu/{index.d.ts → index.ts} +0 -0
  441. /package/{index.d.ts → index.ts} +0 -0
  442. /package/label/{index.d.ts → index.ts} +0 -0
  443. /package/separator/{index.d.ts → index.ts} +0 -0
  444. /package/toggle/{index.d.ts → index.ts} +0 -0
  445. /package/toggle-group/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,20 @@
1
+ import { Provider, Type } from '@angular/core';
2
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
3
+
4
+ /**
5
+ * Include in the providers section of a component which utilizes ControlValueAccessor to redundant code.
6
+ *
7
+ * ```ts
8
+ * @Directive({
9
+ * providers: [provideValueAccessor(ExampleDirective)]
10
+ *}
11
+ * export class ExampleDirective{}
12
+ * ```
13
+ */
14
+ export function provideValueAccessor(type: Type<never>): Provider {
15
+ return {
16
+ provide: NG_VALUE_ACCESSOR,
17
+ useExisting: type,
18
+ multi: true
19
+ };
20
+ }
@@ -0,0 +1,81 @@
1
+ import { booleanAttribute, Directive, ElementRef, inject, Input, NgZone } from '@angular/core';
2
+
3
+ /*
4
+ * <div [rdxAutoFocus]="true"></div>
5
+ */
6
+
7
+ @Directive({
8
+ selector: '[rdxAutoFocus]',
9
+ standalone: true
10
+ })
11
+ export class RdxAutoFocusDirective {
12
+ #elementRef = inject(ElementRef);
13
+ #ngZone = inject(NgZone);
14
+
15
+ private _autoSelect = false;
16
+
17
+ /**
18
+ * @default false
19
+ */
20
+ @Input({ alias: 'rdxAutoFocus', transform: booleanAttribute })
21
+ set autoFocus(value: boolean) {
22
+ if (value) {
23
+ // Note: Running this outside Angular's zone because `element.focus()` does not trigger change detection.
24
+ this.#ngZone.runOutsideAngular(() =>
25
+ // Note: `element.focus()` causes re-layout which might lead to frame drops on slower devices.
26
+ // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#setting-focus
27
+ // `setTimeout` is a macrotask executed within the current rendering frame.
28
+ // Animation tasks are executed in the next rendering frame.
29
+ reqAnimationFrame(() => {
30
+ this.#elementRef.nativeElement.focus();
31
+ if (this._autoSelect && this.#elementRef.nativeElement.select) {
32
+ this.#elementRef.nativeElement.select();
33
+ }
34
+ })
35
+ );
36
+ }
37
+ }
38
+
39
+ // Setter for autoSelect attribute to enable text selection when autoFocus is true.
40
+ @Input({ transform: booleanAttribute })
41
+ set autoSelect(value: boolean) {
42
+ this._autoSelect = value;
43
+ }
44
+ }
45
+
46
+ const availablePrefixes = ['moz', 'ms', 'webkit'];
47
+
48
+ function requestAnimationFramePolyfill(): typeof requestAnimationFrame {
49
+ let lastTime = 0;
50
+
51
+ return function (callback: FrameRequestCallback): number {
52
+ const currTime = new Date().getTime();
53
+ const timeToCall = Math.max(0, 16 - (currTime - lastTime));
54
+
55
+ const id = setTimeout(() => {
56
+ callback(currTime + timeToCall);
57
+ }, timeToCall) as any;
58
+
59
+ lastTime = currTime + timeToCall;
60
+
61
+ return id;
62
+ };
63
+ }
64
+
65
+ // Function to get the appropriate requestAnimationFrame method with fallback to polyfill.
66
+ function getRequestAnimationFrame(): typeof requestAnimationFrame {
67
+ if (typeof window === 'undefined') {
68
+ return () => 0;
69
+ }
70
+ if (window.requestAnimationFrame) {
71
+ // https://github.com/vuejs/vue/issues/4465
72
+ return window.requestAnimationFrame.bind(window);
73
+ }
74
+
75
+ const prefix = availablePrefixes.filter((key) => `${key}RequestAnimationFrame` in window)[0];
76
+
77
+ return prefix ? (window as any)[`${prefix}RequestAnimationFrame`] : requestAnimationFramePolyfill();
78
+ }
79
+
80
+ // Get the requestAnimationFrame function or its polyfill.
81
+ const reqAnimationFrame = getRequestAnimationFrame();
@@ -0,0 +1,28 @@
1
+ import { inject } from '@angular/core';
2
+ import { FormControlDirective, FormControlName, NgControl, NgModel } from '@angular/forms';
3
+
4
+ export function injectNgControl(params: {
5
+ optional: true;
6
+ }): FormControlDirective | FormControlName | NgModel | undefined;
7
+ export function injectNgControl(params: { optional: false }): FormControlDirective | FormControlName | NgModel;
8
+ export function injectNgControl(): FormControlDirective | FormControlName | NgModel;
9
+
10
+ export function injectNgControl(params?: { optional: true } | { optional: false }) {
11
+ const ngControl = inject(NgControl, { self: true, optional: true });
12
+
13
+ if (!params?.optional && !ngControl) throw new Error('NgControl not found');
14
+
15
+ if (
16
+ ngControl instanceof FormControlDirective ||
17
+ ngControl instanceof FormControlName ||
18
+ ngControl instanceof NgModel
19
+ ) {
20
+ return ngControl;
21
+ }
22
+
23
+ if (params?.optional) {
24
+ return undefined;
25
+ }
26
+
27
+ throw new Error('NgControl is not an instance of FormControlDirective, FormControlName or NgModel');
28
+ }
@@ -0,0 +1,27 @@
1
+ import { AfterViewInit, Directive } from '@angular/core';
2
+
3
+ const callAll =
4
+ <T extends (...a: never[]) => void>(...fns: (T | undefined)[]) =>
5
+ (...a: Parameters<T>) => {
6
+ fns.forEach(function (fn) {
7
+ fn?.(...a);
8
+ });
9
+ };
10
+
11
+ @Directive({
12
+ standalone: true
13
+ })
14
+ export class OnMountDirective implements AfterViewInit {
15
+ #onMountFns?: () => void;
16
+
17
+ onMount(fn: () => void) {
18
+ this.#onMountFns = callAll(this.#onMountFns, fn);
19
+ }
20
+
21
+ ngAfterViewInit() {
22
+ if (!this.#onMountFns) {
23
+ throw new Error('The onMount function must be called before the component is mounted.');
24
+ }
25
+ this.#onMountFns();
26
+ }
27
+ }
@@ -0,0 +1 @@
1
+ # @radix-ng/primitives/dialog
@@ -0,0 +1,77 @@
1
+ import { Component, DebugElement } from '@angular/core';
2
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
3
+ import { By } from '@angular/platform-browser';
4
+ import { Subject } from 'rxjs';
5
+ import { RdxDialogContentDirective } from '../src/dialog-content.directive';
6
+ import { RdxDialogRef } from '../src/dialog-ref';
7
+
8
+ @Component({
9
+ template: '<div rdxDialogContent>Dialog Content</div>'
10
+ })
11
+ class TestComponent {}
12
+
13
+ describe('RdxDialogContentDirective', () => {
14
+ let fixture: ComponentFixture<TestComponent>;
15
+ let directiveElement: DebugElement;
16
+ let directive: RdxDialogContentDirective;
17
+ let dialogRefMock: jest.Mocked<RdxDialogRef>;
18
+ let closedSubject: Subject<any>;
19
+
20
+ beforeEach(async () => {
21
+ closedSubject = new Subject();
22
+ dialogRefMock = {
23
+ closed$: closedSubject.asObservable(),
24
+ close: jest.fn(),
25
+ dismiss: jest.fn()
26
+ } as any;
27
+
28
+ await TestBed.configureTestingModule({
29
+ declarations: [TestComponent],
30
+ imports: [RdxDialogContentDirective],
31
+ providers: [
32
+ { provide: RdxDialogRef, useValue: dialogRefMock }]
33
+ }).compileComponents();
34
+
35
+ fixture = TestBed.createComponent(TestComponent);
36
+ directiveElement = fixture.debugElement.query(By.directive(RdxDialogContentDirective));
37
+ directive = directiveElement.injector.get(RdxDialogContentDirective);
38
+ fixture.detectChanges();
39
+ });
40
+
41
+ it('should create', () => {
42
+ expect(directive).toBeTruthy();
43
+ });
44
+
45
+ it('should have correct initial state', () => {
46
+ expect(directive['state']()).toBe('open');
47
+ });
48
+
49
+ it('should update state when dialog is closed', () => {
50
+ closedSubject.next(undefined);
51
+ fixture.detectChanges();
52
+ expect(directive['state']()).toBe('closed');
53
+ });
54
+
55
+ it('should call dialogRef.dismiss when dismiss method is called', () => {
56
+ directive.dismiss();
57
+ expect(dialogRefMock.dismiss).toHaveBeenCalled();
58
+ });
59
+
60
+ it('should call dialogRef.dismiss when dismiss method is called', () => {
61
+ directive.dismiss();
62
+ expect(dialogRefMock.dismiss).toHaveBeenCalled();
63
+ });
64
+
65
+ it('should have correct host bindings', () => {
66
+ const element = directiveElement.nativeElement;
67
+ expect(element.getAttribute('role')).toBe('dialog');
68
+ expect(element.getAttribute('aria-describedby')).toBe('true');
69
+ expect(element.getAttribute('aria-labelledby')).toBe('true');
70
+ expect(element.getAttribute('data-state')).toBe('open');
71
+
72
+ closedSubject.next(undefined);
73
+ fixture.detectChanges();
74
+
75
+ expect(element.getAttribute('data-state')).toBe('closed');
76
+ });
77
+ });
@@ -0,0 +1,85 @@
1
+ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
2
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
3
+ import { By } from '@angular/platform-browser';
4
+ import { of } from 'rxjs';
5
+ import { RdxDialogRef } from '../src/dialog-ref';
6
+ import { RdxDialogTriggerDirective } from '../src/dialog-trigger.directive';
7
+ import { RdxDialogConfig } from '../src/dialog.config';
8
+ import { RdxDialogService } from '../src/dialog.service';
9
+
10
+ @Component({
11
+ template: `
12
+ <button [rdxDialogTrigger]="dialogTemplate" [rdxDialogConfig]="config">Open Dialog</button>
13
+ <ng-template #dialogTemplate>Dialog Content</ng-template>
14
+ `
15
+ })
16
+ class TestHostComponent implements OnInit {
17
+ @ViewChild('dialogTemplate') dialogTemplate: TemplateRef<any>;
18
+
19
+ config: RdxDialogConfig<unknown>;
20
+
21
+ ngOnInit() {
22
+ this.config = {
23
+ content: this.dialogTemplate,
24
+ modal: true,
25
+ ariaLabel: 'Test Dialog',
26
+ autoFocus: 'first-tabbable',
27
+ canClose: () => true,
28
+ canCloseWithBackdrop: true,
29
+ mode: 'default'
30
+ };
31
+ }
32
+ }
33
+
34
+ describe('RdxDialogTriggerDirective', () => {
35
+ let fixture: ComponentFixture<TestHostComponent>;
36
+ let directive: RdxDialogTriggerDirective;
37
+ let dialogServiceMock: jest.Mocked<RdxDialogService>;
38
+ let dialogRefMock: jest.Mocked<RdxDialogRef>;
39
+
40
+ beforeEach(async () => {
41
+ dialogRefMock = {
42
+ closed$: of(undefined)
43
+ } as any;
44
+
45
+ dialogServiceMock = {
46
+ open: jest.fn().mockReturnValue(dialogRefMock)
47
+ } as any;
48
+
49
+ await TestBed.configureTestingModule({
50
+ declarations: [TestHostComponent],
51
+ imports: [RdxDialogTriggerDirective],
52
+ providers: [
53
+ { provide: RdxDialogService, useValue: dialogServiceMock }]
54
+ }).compileComponents();
55
+
56
+ fixture = TestBed.createComponent(TestHostComponent);
57
+ fixture.detectChanges();
58
+
59
+ const directiveEl = fixture.debugElement.query(By.directive(RdxDialogTriggerDirective));
60
+ directive = directiveEl.injector.get(RdxDialogTriggerDirective);
61
+ });
62
+
63
+ it('should create', () => {
64
+ expect(directive).toBeTruthy();
65
+ });
66
+
67
+ it('should have correct initial state', () => {
68
+ expect(directive.isOpen()).toBe(false);
69
+ expect(directive.state()).toBe('closed');
70
+ });
71
+
72
+ it('should have correct aria attributes', () => {
73
+ const button = fixture.debugElement.query(By.css('button'));
74
+ expect(button.nativeElement.getAttribute('aria-haspopup')).toBe('dialog');
75
+ expect(button.nativeElement.getAttribute('aria-expanded')).toBe('false');
76
+ expect(button.nativeElement.getAttribute('data-state')).toBe('closed');
77
+
78
+ button.nativeElement.click();
79
+
80
+ fixture.detectChanges();
81
+
82
+ expect(button.nativeElement.getAttribute('aria-expanded')).toBe('true');
83
+ expect(button.nativeElement.getAttribute('data-state')).toBe('open');
84
+ });
85
+ });
@@ -0,0 +1,31 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { RdxDialogCloseDirective } from './src/dialog-close.directive';
3
+ import { RdxDialogContentDirective } from './src/dialog-content.directive';
4
+ import { RdxDialogDescriptionDirective } from './src/dialog-description.directive';
5
+ import { RdxDialogDismissDirective } from './src/dialog-dismiss.directive';
6
+ import { RdxDialogTitleDirective } from './src/dialog-title.directive';
7
+ import { RdxDialogTriggerDirective } from './src/dialog-trigger.directive';
8
+
9
+ export * from './src/dialog-close.directive';
10
+ export * from './src/dialog-content.directive';
11
+ export * from './src/dialog-description.directive';
12
+ export * from './src/dialog-dismiss.directive';
13
+ export * from './src/dialog-ref';
14
+ export * from './src/dialog-title.directive';
15
+ export * from './src/dialog-trigger.directive';
16
+ export * from './src/dialog.config';
17
+ export * from './src/dialog.injectors';
18
+ export * from './src/dialog.providers';
19
+ export * from './src/dialog.service';
20
+
21
+ const dialogImports = [
22
+ RdxDialogTriggerDirective,
23
+ RdxDialogContentDirective,
24
+ RdxDialogTitleDirective,
25
+ RdxDialogCloseDirective,
26
+ RdxDialogDescriptionDirective,
27
+ RdxDialogDismissDirective
28
+ ];
29
+
30
+ @NgModule({ imports: [...dialogImports], exports: [...dialogImports] })
31
+ export class RdxDialogModule {}
@@ -0,0 +1,5 @@
1
+ {
2
+ "lib": {
3
+ "entryFile": "index.ts"
4
+ }
5
+ }
@@ -0,0 +1,18 @@
1
+ import { Directive, inject } from '@angular/core';
2
+ import { RdxDialogRef } from './dialog-ref';
3
+
4
+ @Directive({
5
+ selector: 'button[rdxDialogClose]',
6
+ standalone: true,
7
+ host: {
8
+ type: 'button',
9
+ '(click)': 'onClick()'
10
+ }
11
+ })
12
+ export class RdxDialogCloseDirective {
13
+ private readonly ref = inject<RdxDialogRef>(RdxDialogRef);
14
+
15
+ protected onClick(): void {
16
+ this.ref.close();
17
+ }
18
+ }
@@ -0,0 +1,45 @@
1
+ import { computed, DestroyRef, Directive, inject, signal } from '@angular/core';
2
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
+ import { RdxDialogRef } from './dialog-ref';
4
+ import { getState, RdxDialogResult } from './dialog.config';
5
+
6
+ @Directive({
7
+ selector: '[rdxDialogContent]',
8
+ standalone: true,
9
+ host: {
10
+ role: 'dialog',
11
+ '[attr.aria-describedby]': '"true"',
12
+ '[attr.aria-labelledby]': '"true"',
13
+ '[attr.data-state]': 'state()'
14
+ }
15
+ })
16
+ export class RdxDialogContentDirective<C = unknown> {
17
+ private readonly dialogRef = inject<RdxDialogRef<C>>(RdxDialogRef);
18
+ private readonly destroyRef = inject(DestroyRef);
19
+
20
+ private readonly isOpen = signal(true);
21
+
22
+ readonly state = computed(() => getState(this.isOpen()));
23
+
24
+ constructor() {
25
+ this.dialogRef.closed$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
26
+ this.isOpen.set(false);
27
+ });
28
+ }
29
+
30
+ /**
31
+ * Closes the dialog with a specified result.
32
+ *
33
+ * @param result The result to be passed back when closing the dialog
34
+ */
35
+ close(result: RdxDialogResult<C>): void {
36
+ this.dialogRef.close(result);
37
+ }
38
+
39
+ /**
40
+ * Dismisses the dialog without a result.
41
+ */
42
+ dismiss(): void {
43
+ this.dialogRef.dismiss();
44
+ }
45
+ }
@@ -0,0 +1,7 @@
1
+ import { Directive } from '@angular/core';
2
+
3
+ @Directive({
4
+ selector: '[rdxDialogDescription]',
5
+ standalone: true
6
+ })
7
+ export class RdxDialogDescriptionDirective {}
@@ -0,0 +1,18 @@
1
+ import { Directive, inject } from '@angular/core';
2
+ import { RdxDialogRef } from './dialog-ref';
3
+
4
+ @Directive({
5
+ selector: 'button[rdxDialogDismiss]',
6
+ standalone: true,
7
+ host: {
8
+ type: 'button',
9
+ '(click)': 'onClick()'
10
+ }
11
+ })
12
+ export class RdxDialogDismissDirective {
13
+ private readonly ref = inject<RdxDialogRef>(RdxDialogRef);
14
+
15
+ protected onClick(): void {
16
+ this.ref.dismiss();
17
+ }
18
+ }
@@ -0,0 +1,70 @@
1
+ import { DialogRef } from '@angular/cdk/dialog';
2
+ import { filter, isObservable, map, Observable, of, take } from 'rxjs';
3
+ import { RdxDialogConfig, RdxDialogResult } from './dialog.config';
4
+
5
+ export const DISMISSED_VALUE = {} as const;
6
+
7
+ function isDismissed(v: unknown): v is typeof DISMISSED_VALUE {
8
+ return v === DISMISSED_VALUE;
9
+ }
10
+
11
+ /**
12
+ * Represents a reference to an open dialog.
13
+ * Provides methods and observables to interact with and monitor the dialog's state.
14
+ * @template C - The type of the dialog's content component
15
+ */
16
+ export class RdxDialogRef<C = unknown> {
17
+ closed$: Observable<RdxDialogResult<C> | undefined> = this.cdkRef.closed.pipe(
18
+ map((res): RdxDialogResult<C> | undefined => (isDismissed(res) ? undefined : res))
19
+ );
20
+
21
+ dismissed$: Observable<void> = this.cdkRef.closed.pipe(
22
+ filter((res) => res === DISMISSED_VALUE),
23
+ map((): void => undefined)
24
+ );
25
+
26
+ result$: Observable<RdxDialogResult<C>> = this.cdkRef.closed.pipe(
27
+ filter((res): res is RdxDialogResult<C> => !isDismissed(res))
28
+ );
29
+
30
+ /**
31
+ * @param cdkRef - Reference to the underlying CDK dialog
32
+ * @param config - Configuration options for the dialog
33
+ */
34
+ constructor(
35
+ public readonly cdkRef: DialogRef<RdxDialogResult<C> | typeof DISMISSED_VALUE, C>,
36
+ public readonly config: RdxDialogConfig<C>
37
+ ) {}
38
+
39
+ get instance(): C | null {
40
+ return this.cdkRef.componentInstance;
41
+ }
42
+
43
+ /**
44
+ * Attempts to dismiss the dialog
45
+ * Checks the canClose condition before dismissing
46
+ */
47
+ dismiss(): void {
48
+ if (!this.instance) {
49
+ return;
50
+ }
51
+ const canClose = this.config.canClose?.(this.instance) ?? true;
52
+ const canClose$ = isObservable(canClose) ? canClose : of(canClose);
53
+ canClose$.pipe(take(1)).subscribe((close) => {
54
+ if (close) {
55
+ this.cdkRef.close(DISMISSED_VALUE);
56
+ }
57
+ });
58
+ }
59
+
60
+ close(result: RdxDialogResult<C>): void {
61
+ this.cdkRef.close(result);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Represents a simplified interface for dialog interaction
67
+ * Typically used by dialog content components
68
+ * @template R - The type of the result when closing the dialog
69
+ */
70
+ export type RdxDialogSelfRef<R> = { dismiss(): void; close(res: R): void };
@@ -0,0 +1,7 @@
1
+ import { Directive } from '@angular/core';
2
+
3
+ @Directive({
4
+ selector: '[rdxDialogTitle]',
5
+ standalone: true
6
+ })
7
+ export class RdxDialogTitleDirective {}
@@ -0,0 +1,52 @@
1
+ import { computed, Directive, inject, Input, input, signal, TemplateRef } from '@angular/core';
2
+ import { RdxDialogRef } from './dialog-ref';
3
+ import { getState, RdxDialogConfig, RdxDialogState } from './dialog.config';
4
+ import { provideRdxDialog } from './dialog.providers';
5
+ import { RdxDialogService } from './dialog.service';
6
+
7
+ let nextId = 0;
8
+
9
+ // Primitive.button
10
+ @Directive({
11
+ selector: '[rdxDialogTrigger]',
12
+ standalone: true,
13
+ providers: [provideRdxDialog()],
14
+ host: {
15
+ type: 'button',
16
+ '[attr.id]': 'id()',
17
+ '[attr.aria-haspopup]': '"dialog"',
18
+ '[attr.aria-expanded]': 'isOpen()',
19
+ '[attr.aria-controls]': 'dialogId()',
20
+ '[attr.data-state]': 'state()',
21
+ '(click)': 'onClick()'
22
+ }
23
+ })
24
+ export class RdxDialogTriggerDirective {
25
+ private readonly dialogService = inject(RdxDialogService);
26
+
27
+ readonly id = input(`rdx-dialog-trigger-${nextId++}`);
28
+ readonly dialogId = computed(() => `rdx-dialog-${this.id()}`);
29
+
30
+ @Input({ required: true, alias: 'rdxDialogTrigger' }) dialog: TemplateRef<void>;
31
+
32
+ @Input({ alias: 'rdxDialogConfig' }) dialogConfig: RdxDialogConfig<unknown>;
33
+
34
+ readonly isOpen = signal(false);
35
+ readonly state = computed<RdxDialogState>(() => getState(this.isOpen()));
36
+
37
+ private currentDialogRef: RdxDialogRef | null = null;
38
+
39
+ protected onClick() {
40
+ this.currentDialogRef = this.dialogService.open({
41
+ ...this.dialogConfig,
42
+ content: this.dialog
43
+ });
44
+
45
+ this.isOpen.set(true);
46
+
47
+ this.currentDialogRef.closed$.subscribe(() => {
48
+ this.isOpen.set(false);
49
+ this.currentDialogRef = null;
50
+ });
51
+ }
52
+ }
@@ -0,0 +1,55 @@
1
+ import { AutoFocusTarget, DialogConfig } from '@angular/cdk/dialog';
2
+ import { ComponentType } from '@angular/cdk/overlay';
3
+ import { TemplateRef } from '@angular/core';
4
+ import { Observable } from 'rxjs';
5
+
6
+ const ɵdialogData = Symbol.for('rdxDialogData');
7
+ const ɵdialogResult = Symbol.for('rdxDialogResult');
8
+
9
+ export type ɵDialogDataFlag = { [ɵdialogData]: unknown };
10
+ export type ɵDialogResultFlag<R> = { [ɵdialogResult]: R };
11
+
12
+ export type RdxDialogData<T> = {
13
+ [K in keyof T]: T[K] extends ɵDialogDataFlag ? Omit<T[K], typeof ɵdialogData> : never;
14
+ }[keyof T];
15
+
16
+ type DialogRefProps<C> = { [K in keyof C]: C[K] extends ɵDialogResultFlag<unknown> ? K : never }[keyof C] & keyof C;
17
+ export type RdxDialogResult<C> =
18
+ DialogRefProps<C> extends never ? void : C[DialogRefProps<C>] extends ɵDialogResultFlag<infer T> ? T : void;
19
+
20
+ type RdxDialogMode = 'default' | 'drawer' | 'drawer-bottom';
21
+
22
+ type RdxBaseDialogConfig<C> = {
23
+ content: ComponentType<C> | TemplateRef<C>;
24
+
25
+ data: RdxDialogData<C>;
26
+
27
+ modal?: boolean;
28
+
29
+ ariaLabel?: string;
30
+
31
+ autoFocus?: AutoFocusTarget | 'first-input' | string;
32
+
33
+ canClose?: (comp: C) => boolean | Observable<boolean>;
34
+
35
+ canCloseWithBackdrop?: boolean;
36
+
37
+ cdkConfigOverride?: Partial<DialogConfig<C>>;
38
+
39
+ mode?: RdxDialogMode;
40
+
41
+ backdropClass?: string;
42
+
43
+ panelClasses?: string[];
44
+ };
45
+
46
+ export type RdxDialogConfig<T> =
47
+ RdxDialogData<T> extends never
48
+ ? Omit<RdxBaseDialogConfig<T>, 'data'>
49
+ : RdxBaseDialogConfig<T> & { data: Required<RdxDialogData<T>> };
50
+
51
+ export type RdxDialogState = 'open' | 'closed';
52
+
53
+ export function getState(open: boolean): RdxDialogState {
54
+ return open ? 'open' : 'closed';
55
+ }
@@ -0,0 +1,12 @@
1
+ import { DIALOG_DATA } from '@angular/cdk/dialog';
2
+ import { inject } from '@angular/core';
3
+ import { RdxDialogRef, RdxDialogSelfRef } from './dialog-ref';
4
+ import { ɵDialogDataFlag, ɵDialogResultFlag } from './dialog.config';
5
+
6
+ export function injectDialogData<TData>(): TData & ɵDialogDataFlag {
7
+ return inject<TData & ɵDialogDataFlag>(DIALOG_DATA);
8
+ }
9
+
10
+ export function injectDialogRef<R = void>(): RdxDialogSelfRef<R> & ɵDialogResultFlag<R> {
11
+ return inject<RdxDialogSelfRef<R>>(RdxDialogRef) as RdxDialogSelfRef<R> & ɵDialogResultFlag<R>;
12
+ }