@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,134 @@
1
+ import { Directive, inject, InjectionToken, Input, numberAttribute, OnChanges, SimpleChanges } from '@angular/core';
2
+
3
+ let idIterator = 0;
4
+
5
+ const MIN_PERCENT = 0;
6
+ const DEFAULT_MAX = 100;
7
+ const PROGRESS_NAME = 'Radix Progress';
8
+
9
+ const RdxProgressToken = new InjectionToken<RdxProgressRootDirective>('RdxProgressDirective');
10
+
11
+ /**
12
+ * Injects the current instance of RdxProgressRootDirective.
13
+ * @returns The instance of RdxProgressRootDirective.
14
+ */
15
+ export function injectProgress(): RdxProgressRootDirective {
16
+ return inject(RdxProgressToken);
17
+ }
18
+
19
+ export type ProgressState = 'indeterminate' | 'complete' | 'loading';
20
+
21
+ export interface ProgressProps {
22
+ value?: number | null | undefined;
23
+ max?: number;
24
+ getValueLabel?: string;
25
+ }
26
+
27
+ /**
28
+ * Directive to manage progress bar state and attributes.
29
+ *
30
+ * This directive provides a way to create a progress bar with customizable value and max attributes.
31
+ * It handles aria attributes for accessibility and provides different states like 'indeterminate', 'complete', and 'loading'.
32
+ */
33
+ @Directive({
34
+ selector: 'div[rdxProgressRoot]',
35
+ exportAs: 'ProgressRoot',
36
+ standalone: true,
37
+ providers: [{ provide: RdxProgressToken, useExisting: RdxProgressRootDirective }],
38
+ host: {
39
+ role: 'progressbar',
40
+ '[id]': 'id',
41
+ '[attr.aria-valuemax]': 'max',
42
+ '[attr.aria-valuemin]': '0',
43
+ '[attr.aria-valuenow]': 'value',
44
+ '[attr.aria-valuetext]': 'valueLabel(value, max)',
45
+ '[attr.data-state]': 'state',
46
+ '[attr.data-value]': 'value',
47
+ '[attr.data-max]': 'max',
48
+ // set tab index to -1 so screen readers will read the aria-label
49
+ // Note: there is a known issue with JAWS that does not read progressbar aria labels on FireFox
50
+ tabindex: '-1'
51
+ }
52
+ })
53
+ export class RdxProgressRootDirective implements ProgressProps, OnChanges {
54
+ /**
55
+ * The unique ID for the progress bar.
56
+ * @default 'rdx-progress-bar-{idIterator}'
57
+ */
58
+ @Input() id = `rdx-progress-bar-${idIterator++}`;
59
+
60
+ /**
61
+ * The current value of the progress bar.
62
+ * @default 0
63
+ */
64
+ @Input({ alias: 'rdxValue', transform: numberAttribute }) value = MIN_PERCENT;
65
+
66
+ /**
67
+ * The maximum value of the progress bar.
68
+ * @default 100
69
+ */
70
+ @Input({ alias: 'rdxMax', transform: numberAttribute }) max = DEFAULT_MAX;
71
+
72
+ /**
73
+ * Function to generate the value label.
74
+ */
75
+ @Input('rdxValueLabel') valueLabel: (value: number, max: number) => string = (value, max) =>
76
+ this.defaultGetValueLabel(value, max);
77
+
78
+ /**
79
+ * Lifecycle hook that is called when any data-bound property of a directive changes.
80
+ * @param changes - The changed properties.
81
+ * @ignore
82
+ */
83
+ ngOnChanges(changes: SimpleChanges) {
84
+ if (changes['max'] && !this.isValidMaxNumber(this.max)) {
85
+ console.error(this.getInvalidMaxError(`${this.max}`, PROGRESS_NAME));
86
+ }
87
+
88
+ if (changes['value'] && this.value !== null && !this.isValidValueNumber(this.value, this.max)) {
89
+ console.error(this.getInvalidValueError(`${this.value}`, PROGRESS_NAME));
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Get the state of the progress bar.
95
+ * @returns 'indeterminate' | 'loading' | 'complete'
96
+ * @ignore
97
+ */
98
+ get state(): ProgressState {
99
+ return this.getProgressState(this.value, this.max);
100
+ }
101
+
102
+ private getProgressState(value: number | undefined | null, maxValue: number): ProgressState {
103
+ return value == null ? 'indeterminate' : value === maxValue ? 'complete' : 'loading';
104
+ }
105
+
106
+ private defaultGetValueLabel(value: number, max: number) {
107
+ return `${Math.round((value / max) * 100)}%`;
108
+ }
109
+
110
+ private isValidMaxNumber(max: unknown): max is number {
111
+ return this.isNumber(max) && !isNaN(max) && max > 0;
112
+ }
113
+
114
+ private isNumber(value: unknown): value is number {
115
+ return typeof value === 'number';
116
+ }
117
+
118
+ private isValidValueNumber(value: unknown, max: number): value is number {
119
+ return this.isNumber(value) && !isNaN(value) && value <= max && value >= 0;
120
+ }
121
+
122
+ private getInvalidMaxError(propValue: string, componentName: string): string {
123
+ return `Invalid prop \`max\` of value \`${propValue}\` supplied to \`${componentName}\`. Only numbers greater than 0 are valid max values. Defaulting to \`${DEFAULT_MAX}\`.`;
124
+ }
125
+
126
+ private getInvalidValueError(propValue: string, componentName: string): string {
127
+ return `Invalid prop \`value\` of value \`${propValue}\` supplied to \`${componentName}\`. The \`value\` prop must be:
128
+ - a positive number
129
+ - less than the value passed to \`max\` (or ${DEFAULT_MAX} if no \`max\` prop is set)
130
+ - \`null\` or \`undefined\` if the progress is indeterminate.
131
+
132
+ Defaulting to \`null\`.`;
133
+ }
134
+ }
@@ -0,0 +1,65 @@
1
+ import { ArgTypes, Canvas, Markdown, Meta } from '@storybook/blocks';
2
+ import { RdxProgressRootDirective } from '../src/progress-root.directive';
3
+ import * as ProgressDirectiveStories from './progress.stories';
4
+
5
+ <Meta title="Primitives/Progress" />
6
+
7
+ # Progress
8
+
9
+ #### Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.
10
+
11
+ <Canvas sourceState="hidden" of={ProgressDirectiveStories.Default} />
12
+
13
+ ## Features
14
+
15
+ - ✅ Provides context for assistive technology to read the progress of a task.
16
+
17
+ ## Usage
18
+
19
+ Get started with importing the directive:
20
+
21
+ ```typescript
22
+ import { RdxProgressRootDirective, RdxProgressIndicatorDirective } from '@radix-ng/primitives/progress';
23
+ ```
24
+
25
+ ## Example
26
+
27
+ ```html
28
+ <div class="ProgressRoot" rdxProgressRoot [rdxValue]="progress">
29
+ <div class="ProgressIndicator" rdxProgressIndicator [style.transform]="'translateX(-' + (100 - progress) +'%)'"></div>
30
+ </div>
31
+ ```
32
+
33
+ ## API Reference
34
+
35
+ ### RdxProgressRootDirective
36
+
37
+ <ArgTypes of={RdxProgressRootDirective} />
38
+
39
+ <Markdown>
40
+ {`
41
+ | Data Attribute | Value |
42
+ | ----------- | --------- |
43
+ | [data-state] | "complete" or "indeterminate" or "loading" |
44
+ | [data-value] | The current value |
45
+ | [data-max] | The max value |
46
+ `}
47
+ </Markdown>
48
+
49
+ ### RdxProgressIndicatorDirective
50
+
51
+ Used to show the progress visually. It also makes progress accessible to assistive technologies.
52
+
53
+ <Markdown>
54
+ {`
55
+ | Data Attribute | Value |
56
+ | ----------- | --------- |
57
+ | [data-state] | "complete" or "indeterminate" or "loading" |
58
+ | [data-value] | The current value |
59
+ | [data-max] | The max value |
60
+ `}
61
+ </Markdown>
62
+
63
+ ## Accessibility
64
+
65
+ Adheres to the [`progressbar` role requirements](https://www.w3.org/WAI/ARIA/apg/patterns/meter).
@@ -0,0 +1,66 @@
1
+ import { componentWrapperDecorator, Meta, moduleMetadata, StoryObj } from '@storybook/angular';
2
+ import { RdxProgressIndicatorDirective } from '../src/progress-indicator.directive';
3
+ import { RdxProgressRootDirective } from '../src/progress-root.directive';
4
+
5
+ export default {
6
+ title: 'Primitives/Progress',
7
+ decorators: [
8
+ moduleMetadata({
9
+ imports: [RdxProgressRootDirective, RdxProgressIndicatorDirective]
10
+ }),
11
+ componentWrapperDecorator(
12
+ (story) =>
13
+ `<div class="radix-themes light light-theme"
14
+ data-radius="medium"
15
+ data-scaling="100%">${story}</div>`
16
+ )
17
+ ],
18
+ argTypes: {
19
+ progress: {
20
+ options: ['10', '30', '70', '95'],
21
+ control: { type: 'select' }
22
+ }
23
+ }
24
+ } as Meta;
25
+
26
+ type Story = StoryObj;
27
+
28
+ export const Default: Story = {
29
+ args: {
30
+ progress: 70
31
+ },
32
+ render: (args) => ({
33
+ props: args,
34
+ template: `
35
+ <style>
36
+ .ProgressRoot {
37
+ position: relative;
38
+ overflow: hidden;
39
+ background: var(--black-a9);
40
+ border-radius: 99999px;
41
+ width: 300px;
42
+ height: 25px;
43
+
44
+ /* Fix overflow clipping in Safari */
45
+ /* https://gist.github.com/domske/b66047671c780a238b51c51ffde8d3a0 */
46
+ transform: translateZ(0);
47
+ }
48
+
49
+ .ProgressIndicator {
50
+ background-color: white;
51
+ width: 100%;
52
+ height: 100%;
53
+ transition: transform 660ms cubic-bezier(0.65, 0, 0.35, 1);
54
+ }
55
+ </style>
56
+
57
+ <div rdxProgressRoot [rdxValue]="progress" class="ProgressRoot">
58
+ <div rdxProgressIndicator
59
+ [style.transform]="'translateX(-' + (100 - progress) +'%)'"
60
+ class="ProgressIndicator"
61
+ ></div>
62
+ </div>
63
+
64
+ `
65
+ })
66
+ };
package/project.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "primitives",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "packages/primitives",
5
+ "prefix": "rdx",
6
+ "projectType": "library",
7
+ "tags": [],
8
+ "targets": {
9
+ "build": {
10
+ "executor": "@nx/angular:package",
11
+ "outputs": ["{workspaceRoot}/dist/{projectRoot}"],
12
+ "options": {
13
+ "project": "packages/primitives/ng-package.json"
14
+ },
15
+ "configurations": {
16
+ "production": {
17
+ "tsConfig": "packages/primitives/tsconfig.lib.prod.json"
18
+ },
19
+ "development": {
20
+ "tsConfig": "packages/primitives/tsconfig.lib.json"
21
+ }
22
+ },
23
+ "defaultConfiguration": "production"
24
+ },
25
+ "compodoc": {
26
+ "executor": "nx:run-script",
27
+ "options": {
28
+ "script": "compodoc"
29
+ }
30
+ },
31
+ "test": {
32
+ "executor": "@nx/jest:jest",
33
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
34
+ "options": {
35
+ "jestConfig": "packages/primitives/jest.config.ts"
36
+ }
37
+ }
38
+ }
39
+ }
@@ -1,3 +1,4 @@
1
1
  export * from './src/radio-root.directive';
2
+
2
3
  export * from './src/radio-indicator.directive';
3
4
  export * from './src/radio-item.directive';
@@ -0,0 +1,5 @@
1
+ {
2
+ "lib": {
3
+ "entryFile": "index.ts"
4
+ }
5
+ }
@@ -0,0 +1,17 @@
1
+ import { Directive, inject } from '@angular/core';
2
+ import { RdxRadioItemDirective } from './radio-item.directive';
3
+ import { RDX_RADIO_GROUP, RadioGroupDirective } from './radio-tokens';
4
+
5
+ @Directive({
6
+ selector: '[rdxRadioIndicator]',
7
+ exportAs: 'rdxRadioIndicator',
8
+ standalone: true,
9
+ host: {
10
+ '[attr.data-state]': 'radioItem.checked ? "checked" : "unchecked"',
11
+ '[attr.data-disabled]': 'radioItem.disabled ? "" : null'
12
+ }
13
+ })
14
+ export class RdxRadioIndicatorDirective {
15
+ protected readonly radioGroup: RadioGroupDirective = inject(RDX_RADIO_GROUP);
16
+ protected readonly radioItem: RdxRadioItemDirective = inject(RdxRadioItemDirective);
17
+ }
@@ -0,0 +1,68 @@
1
+ import { FocusableOption } from '@angular/cdk/a11y';
2
+ import { booleanAttribute, Directive, ElementRef, inject, InjectionToken, Input, OnInit } from '@angular/core';
3
+ import { RDX_RADIO_GROUP } from './radio-tokens';
4
+
5
+ export const RdxRadioItemToken = new InjectionToken<RdxRadioItemDirective>('RadioItemToken');
6
+
7
+ export function injectRadioItem(): RdxRadioItemDirective {
8
+ return inject(RdxRadioItemToken);
9
+ }
10
+
11
+ // Increasing integer for generating unique ids for radio components.
12
+ let nextUniqueId = 0;
13
+
14
+ @Directive({
15
+ selector: '[rdxRadioItem]',
16
+ exportAs: 'rdxRadioItem',
17
+ standalone: true,
18
+ providers: [{ provide: RdxRadioItemToken, useExisting: RdxRadioItemDirective }],
19
+ host: {
20
+ type: 'button',
21
+ role: 'radio',
22
+ '[attr.id]': 'id',
23
+ '[attr.aria-checked]': 'checked',
24
+ '[attr.data-disabled]': 'disabled ? "" : null',
25
+ '[attr.data-state]': 'checked ? "checked" : "unchecked"',
26
+ '[attr.tabindex]': 'tabIndex',
27
+ '(click)': '_onClick()',
28
+ '(blur)': '_onBlur()'
29
+ }
30
+ })
31
+ export class RdxRadioItemDirective implements FocusableOption, OnInit {
32
+ private readonly radioGroup = inject(RDX_RADIO_GROUP);
33
+ readonly element = inject(ElementRef);
34
+
35
+ @Input() id = `rdx-radio-${++nextUniqueId}`;
36
+
37
+ @Input({ required: true }) value!: string;
38
+
39
+ @Input({ transform: booleanAttribute }) disabled = false;
40
+
41
+ get tabIndex(): number {
42
+ return this.disabled ? -1 : this.radioGroup.value === this.value ? 0 : -1;
43
+ }
44
+
45
+ get checked(): boolean {
46
+ return this.radioGroup.value === this.value;
47
+ }
48
+
49
+ ngOnInit() {
50
+ if (this.radioGroup.defaultValue === this.value) {
51
+ this.radioGroup.select(this.value);
52
+ }
53
+ }
54
+
55
+ focus(): void {
56
+ this.element.nativeElement.focus();
57
+ }
58
+
59
+ _onClick(): void {
60
+ if (!this.disabled) {
61
+ this.radioGroup.select(this.value);
62
+ }
63
+ }
64
+
65
+ _onBlur(): void {
66
+ this.radioGroup.onTouched?.();
67
+ }
68
+ }
@@ -0,0 +1,207 @@
1
+ import { FocusKeyManager } from '@angular/cdk/a11y';
2
+ import { DOWN_ARROW, ENTER, LEFT_ARROW, RIGHT_ARROW, SPACE, TAB, UP_ARROW } from '@angular/cdk/keycodes';
3
+ import {
4
+ AfterContentInit,
5
+ booleanAttribute,
6
+ ContentChildren,
7
+ Directive,
8
+ EventEmitter,
9
+ Input,
10
+ OnDestroy,
11
+ Output,
12
+ QueryList
13
+ } from '@angular/core';
14
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
15
+ import { Subject, takeUntil } from 'rxjs';
16
+ import { RdxRadioItemDirective } from './radio-item.directive';
17
+ import { RadioGroupDirective, RadioGroupProps, RDX_RADIO_GROUP } from './radio-tokens';
18
+
19
+ @Directive({
20
+ selector: '[rdxRadioRoot]',
21
+ exportAs: 'rdxRadioRoot',
22
+ standalone: true,
23
+ providers: [
24
+ { provide: RDX_RADIO_GROUP, useExisting: RdxRadioGroupDirective },
25
+ { provide: NG_VALUE_ACCESSOR, useExisting: RdxRadioGroupDirective, multi: true }
26
+ ],
27
+ host: {
28
+ role: 'radiogroup',
29
+ '[attr.aria-orientation]': '_orientation',
30
+ '[attr.data-disabled]': 'disabled ? "" : null',
31
+ '[attr.tabindex]': '-1',
32
+ '[attr.dir]': 'dir',
33
+ '(keydown)': '_onKeydown($event)',
34
+ '(focusin)': '_onFocusin($event)'
35
+ }
36
+ })
37
+ export class RdxRadioGroupDirective
38
+ implements RadioGroupProps, RadioGroupDirective, ControlValueAccessor, AfterContentInit, OnDestroy
39
+ {
40
+ @ContentChildren(RdxRadioItemDirective, { descendants: true }) radioItems!: QueryList<RdxRadioItemDirective>;
41
+ private focusKeyManager!: FocusKeyManager<RdxRadioItemDirective>;
42
+ private destroy$ = new Subject<void>();
43
+
44
+ name?: string | undefined;
45
+ @Input() value?: string;
46
+
47
+ @Input({ transform: booleanAttribute }) disabled = false;
48
+
49
+ @Input() dir?: string;
50
+
51
+ @Input() defaultValue?: string;
52
+
53
+ /**
54
+ * The orientation of the radio group only vertical.
55
+ * Horizontal radio buttons can sometimes be challenging to scan and localize.
56
+ * The horizontal arrangement of radio buttons may also lead to difficulties in determining which
57
+ * label corresponds to which button: whether the label is above or below the button.
58
+ * @default 'vertical'
59
+ */
60
+ readonly _orientation = 'vertical';
61
+
62
+ /**
63
+ * Event handler called when the value changes.
64
+ */
65
+ @Output() readonly onValueChange = new EventEmitter<string>();
66
+
67
+ /**
68
+ * The callback function to call when the value of the radio group changes.
69
+ */
70
+ private onChange: (value: string) => void = () => {
71
+ /* Empty */
72
+ };
73
+
74
+ /**
75
+ * The callback function to call when the radio group is touched.
76
+ */
77
+ onTouched: () => void = () => {
78
+ /* Empty */
79
+ };
80
+
81
+ ngAfterContentInit() {
82
+ this.focusKeyManager = new FocusKeyManager(this.radioItems).withWrap().withVerticalOrientation();
83
+
84
+ this.radioItems.changes.pipe(takeUntil(this.destroy$)).subscribe(() => {
85
+ this.updateActiveItem();
86
+ });
87
+
88
+ this.updateActiveItem(false);
89
+ }
90
+
91
+ ngOnDestroy() {
92
+ this.destroy$.next();
93
+ this.destroy$.complete();
94
+ }
95
+
96
+ /**
97
+ * Select a radio item.
98
+ * @param value The value of the radio item to select.
99
+ */
100
+ select(value: string): void {
101
+ this.value = value;
102
+ this.onValueChange.emit(value);
103
+ this.onChange?.(value);
104
+ this.updateActiveItem();
105
+ this.onTouched();
106
+ }
107
+
108
+ /**
109
+ * Update the value of the radio group.
110
+ * @param value The new value of the radio group.
111
+ * @internal
112
+ */
113
+ writeValue(value: string): void {
114
+ this.value = value;
115
+ if (this.radioItems) {
116
+ this.updateActiveItem(false);
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Register a callback function to call when the value of the radio group changes.
122
+ * @param fn The callback function to call when the value of the radio group changes.
123
+ * @internal
124
+ */
125
+ registerOnChange(fn: (value: string) => void): void {
126
+ this.onChange = fn;
127
+ }
128
+
129
+ registerOnTouched(fn: () => void): void {
130
+ this.onTouched = fn;
131
+ }
132
+
133
+ /**
134
+ * Set the disabled state of the radio group.
135
+ * @param isDisabled Whether the radio group is disabled.
136
+ * @internal
137
+ */
138
+ setDisabledState(isDisabled: boolean): void {
139
+ this.disabled = isDisabled;
140
+ }
141
+
142
+ /**
143
+ * When focus leaves the radio group.
144
+ */
145
+ _onFocusin(event: FocusEvent): void {
146
+ const target = event.target as HTMLElement;
147
+ const radioItem = this.radioItems.find((item) => item.element.nativeElement === target);
148
+ if (radioItem) {
149
+ this.focusKeyManager.setActiveItem(radioItem);
150
+ }
151
+ }
152
+
153
+ _onKeydown(event: KeyboardEvent): void {
154
+ if (this.disabled) return;
155
+
156
+ switch (event.keyCode) {
157
+ case ENTER:
158
+ case SPACE:
159
+ event.preventDefault();
160
+ this.selectFocusedItem();
161
+ break;
162
+ case DOWN_ARROW:
163
+ case RIGHT_ARROW:
164
+ event.preventDefault();
165
+ this.focusKeyManager.setNextItemActive();
166
+ this.selectFocusedItem();
167
+ break;
168
+ case UP_ARROW:
169
+ case LEFT_ARROW:
170
+ event.preventDefault();
171
+ this.focusKeyManager.setPreviousItemActive();
172
+ this.selectFocusedItem();
173
+ break;
174
+ case TAB:
175
+ this.tabNavigation(event);
176
+ break;
177
+ default:
178
+ this.focusKeyManager.onKeydown(event);
179
+ }
180
+ }
181
+
182
+ private selectFocusedItem(): void {
183
+ const focusedItem = this.focusKeyManager.activeItem;
184
+ if (focusedItem) {
185
+ this.select(focusedItem.value);
186
+ }
187
+ }
188
+
189
+ private updateActiveItem(setFocus = true): void {
190
+ const activeItem = this.radioItems.find((item) => item.value === this.value);
191
+ if (activeItem) {
192
+ this.focusKeyManager.setActiveItem(activeItem);
193
+ } else if (this.radioItems.length > 0 && setFocus) {
194
+ this.focusKeyManager.setFirstItemActive();
195
+ }
196
+ }
197
+
198
+ private tabNavigation(event: KeyboardEvent): void {
199
+ event.preventDefault();
200
+ const checkedItem = this.radioItems.find((item) => item.checked);
201
+ if (checkedItem) {
202
+ checkedItem.focus();
203
+ } else if (this.radioItems.first) {
204
+ this.radioItems.first.focus();
205
+ }
206
+ }
207
+ }
@@ -1,12 +1,16 @@
1
1
  import { InjectionToken } from '@angular/core';
2
+
2
3
  export interface RadioGroupProps {
3
4
  name?: string;
4
5
  disabled?: boolean;
5
6
  defaultValue?: string;
6
7
  value?: string;
7
8
  }
9
+
8
10
  export interface RadioGroupDirective extends RadioGroupProps {
9
11
  select(value: string): void;
12
+
10
13
  onTouched(): void;
11
14
  }
12
- export declare const RDX_RADIO_GROUP: InjectionToken<RadioGroupDirective>;
15
+
16
+ export const RDX_RADIO_GROUP = new InjectionToken<RadioGroupDirective>('RdxRadioGroup');
@@ -0,0 +1,39 @@
1
+ import { Component } from '@angular/core';
2
+ import { FormsModule } from '@angular/forms';
3
+ import { RdxLabelDirective } from '@radix-ng/primitives/label';
4
+ import { RdxRadioGroupDirective, RdxRadioIndicatorDirective, RdxRadioItemDirective } from '@radix-ng/primitives/radio';
5
+
6
+ @Component({
7
+ selector: 'radio-groups-forms-example',
8
+ standalone: true,
9
+ template: `
10
+ <div class="RadioGroupRoot" [(ngModel)]="hotelRoom" rdxRadioRoot aria-label="View density">
11
+ @for (room of rooms; track room) {
12
+ <div class="RadioGroup">
13
+ <button class="RadioGroupItem" [value]="room" [id]="room" rdxRadioItem>
14
+ <div class="RadioGroupIndicator" rdxRadioIndicator></div>
15
+ <input class="Input" rdxRadioIndicator type="radio" aria-hidden="true" tabindex="-1" />
16
+ </button>
17
+ <label class="Label" [htmlFor]="room" rdxLabel>
18
+ {{ room }}
19
+ </label>
20
+ </div>
21
+ }
22
+ </div>
23
+ <p>
24
+ <span>Your room is: {{ hotelRoom }}</span>
25
+ </p>
26
+ `,
27
+ styleUrl: 'radio-group.styles.scss',
28
+ imports: [
29
+ FormsModule,
30
+ RdxLabelDirective,
31
+ RdxRadioItemDirective,
32
+ RdxRadioIndicatorDirective,
33
+ RdxRadioGroupDirective
34
+ ]
35
+ })
36
+ export class RadioGroupComponent {
37
+ hotelRoom: string | undefined;
38
+ rooms = ['Default', 'Comfortable'];
39
+ }