@ojiepermana/angular 21.3.4 → 22.0.1

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 (290) hide show
  1. package/README.md +10 -6
  2. package/component/accordion/README.md +195 -0
  3. package/component/alert/README.md +182 -0
  4. package/component/alert-dialog/README.md +239 -0
  5. package/component/aspect-ratio/README.md +112 -0
  6. package/component/avatar/README.md +176 -0
  7. package/component/badge/README.md +133 -0
  8. package/component/breadcrumb/README.md +216 -0
  9. package/component/button/README.md +139 -0
  10. package/component/button-group/README.md +208 -0
  11. package/component/calendar/README.md +132 -0
  12. package/component/card/README.md +220 -0
  13. package/component/carousel/README.md +276 -0
  14. package/component/checkbox/README.md +149 -0
  15. package/component/collapsible/README.md +195 -0
  16. package/component/combobox/README.md +198 -0
  17. package/component/command/README.md +275 -0
  18. package/component/composer/README.md +235 -0
  19. package/component/composer/package.json +4 -0
  20. package/component/context-menu/README.md +267 -0
  21. package/component/date-picker/README.md +177 -0
  22. package/component/dialog/README.md +237 -0
  23. package/component/drawer/README.md +145 -0
  24. package/component/dropdown-menu/README.md +311 -0
  25. package/component/editor/README.md +136 -0
  26. package/component/editor/package.json +4 -0
  27. package/component/empty/README.md +183 -0
  28. package/component/empty/package.json +4 -0
  29. package/component/form/README.md +210 -0
  30. package/component/hover-card/README.md +146 -0
  31. package/component/hover-card/package.json +4 -0
  32. package/component/input/README.md +159 -0
  33. package/component/input-group/README.md +239 -0
  34. package/component/input-otp/README.md +278 -0
  35. package/component/input-otp/package.json +4 -0
  36. package/component/item/README.md +247 -0
  37. package/component/kanban/README.md +81 -0
  38. package/component/kanban/package.json +4 -0
  39. package/component/kbd/README.md +139 -0
  40. package/component/kbd/package.json +4 -0
  41. package/component/label/README.md +136 -0
  42. package/component/menubar/README.md +269 -0
  43. package/component/menubar/package.json +4 -0
  44. package/component/native-select/README.md +176 -0
  45. package/component/native-select/package.json +4 -0
  46. package/component/navigation-menu/README.md +160 -0
  47. package/component/navigation-menu/package.json +4 -0
  48. package/component/pagination/README.md +144 -0
  49. package/component/pillbox/README.md +67 -0
  50. package/component/pillbox/package.json +4 -0
  51. package/component/popover/README.md +43 -0
  52. package/component/progress/README.md +160 -0
  53. package/component/radio/README.md +209 -0
  54. package/component/resizable/README.md +168 -0
  55. package/component/resizable/package.json +4 -0
  56. package/component/scroll-area/README.md +143 -0
  57. package/component/select/README.md +174 -0
  58. package/component/separator/README.md +170 -0
  59. package/component/sheet/README.md +183 -0
  60. package/component/skeleton/README.md +158 -0
  61. package/component/slider/README.md +207 -0
  62. package/component/spinner/README.md +160 -0
  63. package/component/spinner/package.json +4 -0
  64. package/component/switch/README.md +166 -0
  65. package/component/table/README.md +291 -0
  66. package/component/tabs/README.md +219 -0
  67. package/component/textarea/README.md +154 -0
  68. package/component/timeline/README.md +94 -0
  69. package/component/timeline/package.json +4 -0
  70. package/component/toast/README.md +321 -0
  71. package/component/toggle/README.md +131 -0
  72. package/component/toggle/package.json +4 -0
  73. package/component/toggle-group/README.md +206 -0
  74. package/component/toggle-group/package.json +4 -0
  75. package/component/tooltip/README.md +211 -0
  76. package/fesm2022/ojiepermana-angular-component-accordion.mjs +45 -30
  77. package/fesm2022/ojiepermana-angular-component-accordion.mjs.map +1 -1
  78. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +95 -61
  79. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs.map +1 -1
  80. package/fesm2022/ojiepermana-angular-component-alert.mjs +30 -21
  81. package/fesm2022/ojiepermana-angular-component-alert.mjs.map +1 -1
  82. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +11 -7
  83. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs.map +1 -1
  84. package/fesm2022/ojiepermana-angular-component-avatar.mjs +50 -34
  85. package/fesm2022/ojiepermana-angular-component-avatar.mjs.map +1 -1
  86. package/fesm2022/ojiepermana-angular-component-badge.mjs +9 -6
  87. package/fesm2022/ojiepermana-angular-component-badge.mjs.map +1 -1
  88. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +49 -35
  89. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs.map +1 -1
  90. package/fesm2022/ojiepermana-angular-component-button-group.mjs +25 -17
  91. package/fesm2022/ojiepermana-angular-component-button-group.mjs.map +1 -1
  92. package/fesm2022/ojiepermana-angular-component-button.mjs +11 -7
  93. package/fesm2022/ojiepermana-angular-component-button.mjs.map +1 -1
  94. package/fesm2022/ojiepermana-angular-component-calendar.mjs +23 -13
  95. package/fesm2022/ojiepermana-angular-component-calendar.mjs.map +1 -1
  96. package/fesm2022/ojiepermana-angular-component-card.mjs +51 -36
  97. package/fesm2022/ojiepermana-angular-component-card.mjs.map +1 -1
  98. package/fesm2022/ojiepermana-angular-component-carousel.mjs +66 -42
  99. package/fesm2022/ojiepermana-angular-component-carousel.mjs.map +1 -1
  100. package/fesm2022/ojiepermana-angular-component-chart.mjs +494 -283
  101. package/fesm2022/ojiepermana-angular-component-chart.mjs.map +1 -1
  102. package/fesm2022/ojiepermana-angular-component-checkbox.mjs +23 -13
  103. package/fesm2022/ojiepermana-angular-component-checkbox.mjs.map +1 -1
  104. package/fesm2022/ojiepermana-angular-component-collapsible.mjs +28 -20
  105. package/fesm2022/ojiepermana-angular-component-collapsible.mjs.map +1 -1
  106. package/fesm2022/ojiepermana-angular-component-combobox.mjs +27 -18
  107. package/fesm2022/ojiepermana-angular-component-combobox.mjs.map +1 -1
  108. package/fesm2022/ojiepermana-angular-component-command.mjs +77 -52
  109. package/fesm2022/ojiepermana-angular-component-command.mjs.map +1 -1
  110. package/fesm2022/ojiepermana-angular-component-composer.mjs +352 -0
  111. package/fesm2022/ojiepermana-angular-component-composer.mjs.map +1 -0
  112. package/fesm2022/ojiepermana-angular-component-context-menu.mjs +9 -6
  113. package/fesm2022/ojiepermana-angular-component-context-menu.mjs.map +1 -1
  114. package/fesm2022/ojiepermana-angular-component-date-picker.mjs +34 -19
  115. package/fesm2022/ojiepermana-angular-component-date-picker.mjs.map +1 -1
  116. package/fesm2022/ojiepermana-angular-component-dialog.mjs +55 -38
  117. package/fesm2022/ojiepermana-angular-component-dialog.mjs.map +1 -1
  118. package/fesm2022/ojiepermana-angular-component-drawer.mjs.map +1 -1
  119. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +108 -74
  120. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs.map +1 -1
  121. package/fesm2022/ojiepermana-angular-component-editor.mjs +717 -0
  122. package/fesm2022/ojiepermana-angular-component-editor.mjs.map +1 -0
  123. package/fesm2022/ojiepermana-angular-component-empty.mjs +145 -0
  124. package/fesm2022/ojiepermana-angular-component-empty.mjs.map +1 -0
  125. package/fesm2022/ojiepermana-angular-component-form.mjs +200 -42
  126. package/fesm2022/ojiepermana-angular-component-form.mjs.map +1 -1
  127. package/fesm2022/ojiepermana-angular-component-hover-card.mjs +297 -0
  128. package/fesm2022/ojiepermana-angular-component-hover-card.mjs.map +1 -0
  129. package/fesm2022/ojiepermana-angular-component-input-group.mjs +48 -33
  130. package/fesm2022/ojiepermana-angular-component-input-group.mjs.map +1 -1
  131. package/fesm2022/ojiepermana-angular-component-input-otp.mjs +514 -0
  132. package/fesm2022/ojiepermana-angular-component-input-otp.mjs.map +1 -0
  133. package/fesm2022/ojiepermana-angular-component-input.mjs +7 -5
  134. package/fesm2022/ojiepermana-angular-component-input.mjs.map +1 -1
  135. package/fesm2022/ojiepermana-angular-component-item.mjs +76 -53
  136. package/fesm2022/ojiepermana-angular-component-item.mjs.map +1 -1
  137. package/fesm2022/ojiepermana-angular-component-kanban.mjs +314 -0
  138. package/fesm2022/ojiepermana-angular-component-kanban.mjs.map +1 -0
  139. package/fesm2022/ojiepermana-angular-component-kbd.mjs +55 -0
  140. package/fesm2022/ojiepermana-angular-component-kbd.mjs.map +1 -0
  141. package/fesm2022/ojiepermana-angular-component-label.mjs +9 -6
  142. package/fesm2022/ojiepermana-angular-component-label.mjs.map +1 -1
  143. package/fesm2022/ojiepermana-angular-component-menubar.mjs +308 -0
  144. package/fesm2022/ojiepermana-angular-component-menubar.mjs.map +1 -0
  145. package/fesm2022/ojiepermana-angular-component-native-select.mjs +67 -0
  146. package/fesm2022/ojiepermana-angular-component-native-select.mjs.map +1 -0
  147. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +413 -0
  148. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs.map +1 -0
  149. package/fesm2022/ojiepermana-angular-component-pagination.mjs +65 -31
  150. package/fesm2022/ojiepermana-angular-component-pagination.mjs.map +1 -1
  151. package/fesm2022/ojiepermana-angular-component-pillbox.mjs +812 -0
  152. package/fesm2022/ojiepermana-angular-component-pillbox.mjs.map +1 -0
  153. package/fesm2022/ojiepermana-angular-component-popover.mjs +18 -12
  154. package/fesm2022/ojiepermana-angular-component-popover.mjs.map +1 -1
  155. package/fesm2022/ojiepermana-angular-component-progress.mjs +17 -10
  156. package/fesm2022/ojiepermana-angular-component-progress.mjs.map +1 -1
  157. package/fesm2022/ojiepermana-angular-component-radio.mjs +47 -17
  158. package/fesm2022/ojiepermana-angular-component-radio.mjs.map +1 -1
  159. package/fesm2022/ojiepermana-angular-component-resizable.mjs +481 -0
  160. package/fesm2022/ojiepermana-angular-component-resizable.mjs.map +1 -0
  161. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +15 -9
  162. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs.map +1 -1
  163. package/fesm2022/ojiepermana-angular-component-select.mjs +71 -26
  164. package/fesm2022/ojiepermana-angular-component-select.mjs.map +1 -1
  165. package/fesm2022/ojiepermana-angular-component-separator.mjs +11 -7
  166. package/fesm2022/ojiepermana-angular-component-separator.mjs.map +1 -1
  167. package/fesm2022/ojiepermana-angular-component-sheet.mjs +91 -42
  168. package/fesm2022/ojiepermana-angular-component-sheet.mjs.map +1 -1
  169. package/fesm2022/ojiepermana-angular-component-skeleton.mjs +7 -5
  170. package/fesm2022/ojiepermana-angular-component-skeleton.mjs.map +1 -1
  171. package/fesm2022/ojiepermana-angular-component-slider.mjs +401 -7
  172. package/fesm2022/ojiepermana-angular-component-slider.mjs.map +1 -1
  173. package/fesm2022/ojiepermana-angular-component-spinner.mjs +60 -0
  174. package/fesm2022/ojiepermana-angular-component-spinner.mjs.map +1 -0
  175. package/fesm2022/ojiepermana-angular-component-switch.mjs +47 -15
  176. package/fesm2022/ojiepermana-angular-component-switch.mjs.map +1 -1
  177. package/fesm2022/ojiepermana-angular-component-table.mjs +56 -40
  178. package/fesm2022/ojiepermana-angular-component-table.mjs.map +1 -1
  179. package/fesm2022/ojiepermana-angular-component-tabs.mjs +58 -38
  180. package/fesm2022/ojiepermana-angular-component-tabs.mjs.map +1 -1
  181. package/fesm2022/ojiepermana-angular-component-textarea.mjs +8 -6
  182. package/fesm2022/ojiepermana-angular-component-textarea.mjs.map +1 -1
  183. package/fesm2022/ojiepermana-angular-component-timeline.mjs +237 -0
  184. package/fesm2022/ojiepermana-angular-component-timeline.mjs.map +1 -0
  185. package/fesm2022/ojiepermana-angular-component-toast.mjs +28 -4
  186. package/fesm2022/ojiepermana-angular-component-toast.mjs.map +1 -1
  187. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +289 -0
  188. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs.map +1 -0
  189. package/fesm2022/ojiepermana-angular-component-toggle.mjs +82 -0
  190. package/fesm2022/ojiepermana-angular-component-toggle.mjs.map +1 -0
  191. package/fesm2022/ojiepermana-angular-component-tooltip.mjs +304 -6
  192. package/fesm2022/ojiepermana-angular-component-tooltip.mjs.map +1 -1
  193. package/fesm2022/ojiepermana-angular-component-utils.mjs.map +1 -1
  194. package/fesm2022/ojiepermana-angular-layout-component.mjs +45 -24
  195. package/fesm2022/ojiepermana-angular-layout-component.mjs.map +1 -1
  196. package/fesm2022/ojiepermana-angular-layout-provider.mjs.map +1 -1
  197. package/fesm2022/ojiepermana-angular-layout-services.mjs +7 -5
  198. package/fesm2022/ojiepermana-angular-layout-services.mjs.map +1 -1
  199. package/fesm2022/ojiepermana-angular-layout-shell.mjs +3 -3
  200. package/fesm2022/ojiepermana-angular-layout-shell.mjs.map +1 -1
  201. package/fesm2022/ojiepermana-angular-layout-token-directive.mjs +9 -6
  202. package/fesm2022/ojiepermana-angular-layout-token-directive.mjs.map +1 -1
  203. package/fesm2022/ojiepermana-angular-layout-token.mjs.map +1 -1
  204. package/fesm2022/{ojiepermana-angular-layout-empty.mjs → ojiepermana-angular-layout-type-empty.mjs} +4 -4
  205. package/fesm2022/ojiepermana-angular-layout-type-empty.mjs.map +1 -0
  206. package/fesm2022/{ojiepermana-angular-layout-horizontal.mjs → ojiepermana-angular-layout-type-horizontal.mjs} +26 -17
  207. package/fesm2022/ojiepermana-angular-layout-type-horizontal.mjs.map +1 -0
  208. package/fesm2022/{ojiepermana-angular-layout-vertical.mjs → ojiepermana-angular-layout-type-vertical.mjs} +28 -18
  209. package/fesm2022/ojiepermana-angular-layout-type-vertical.mjs.map +1 -0
  210. package/fesm2022/ojiepermana-angular-layout.mjs +74 -50
  211. package/fesm2022/ojiepermana-angular-layout.mjs.map +1 -1
  212. package/fesm2022/ojiepermana-angular-navigation-demo-data.mjs.map +1 -1
  213. package/fesm2022/ojiepermana-angular-navigation-icon.mjs +11 -7
  214. package/fesm2022/ojiepermana-angular-navigation-icon.mjs.map +1 -1
  215. package/fesm2022/ojiepermana-angular-navigation-item.mjs +27 -16
  216. package/fesm2022/ojiepermana-angular-navigation-item.mjs.map +1 -1
  217. package/fesm2022/ojiepermana-angular-navigation-service.mjs +29 -20
  218. package/fesm2022/ojiepermana-angular-navigation-service.mjs.map +1 -1
  219. package/fesm2022/ojiepermana-angular-navigation-sidebar.mjs +71 -43
  220. package/fesm2022/ojiepermana-angular-navigation-sidebar.mjs.map +1 -1
  221. package/fesm2022/ojiepermana-angular-navigation-topbar.mjs +261 -24
  222. package/fesm2022/ojiepermana-angular-navigation-topbar.mjs.map +1 -1
  223. package/fesm2022/ojiepermana-angular-theme-provider.mjs.map +1 -1
  224. package/fesm2022/ojiepermana-angular-theme-services.mjs +19 -11
  225. package/fesm2022/ojiepermana-angular-theme-services.mjs.map +1 -1
  226. package/fesm2022/ojiepermana-angular-theme-token.mjs.map +1 -1
  227. package/fesm2022/ojiepermana-angular-theme.mjs +19 -11
  228. package/fesm2022/ojiepermana-angular-theme.mjs.map +1 -1
  229. package/generator/api/bin/src/emit/client.js +4 -2
  230. package/generator/api/bin/src/writer/index.js +2 -2
  231. package/generator/guide/bin/schematics/build/index.js +3 -2
  232. package/generator/guide/bin/src/engine/component.js +2 -2
  233. package/generator/guide/bin/src/engine/index.js +3 -3
  234. package/generator/guide/bin/src/engine/render.js +10 -5
  235. package/layout/type/empty/package.json +4 -0
  236. package/layout/type/horizontal/package.json +4 -0
  237. package/layout/type/vertical/package.json +4 -0
  238. package/navigation/topbar/README.md +196 -0
  239. package/package.json +89 -25
  240. package/theme/README.md +110 -3
  241. package/theme/styles/integrations/material/autocomplete.css +178 -0
  242. package/theme/styles/integrations/material/button.css +468 -0
  243. package/theme/styles/integrations/material/dialog.css +152 -0
  244. package/theme/styles/integrations/material/select.css +175 -0
  245. package/theme/styles/integrations/material/slide-toggle.css +234 -0
  246. package/theme/styles/integrations/material/slider.css +194 -0
  247. package/theme/styles/integrations/material/tabs.css +229 -0
  248. package/theme/styles/integrations/material.css +70 -60
  249. package/types/ojiepermana-angular-component-combobox.d.ts +1 -2
  250. package/types/ojiepermana-angular-component-composer.d.ts +90 -0
  251. package/types/ojiepermana-angular-component-dropdown-menu.d.ts +2 -0
  252. package/types/ojiepermana-angular-component-editor.d.ts +123 -0
  253. package/types/ojiepermana-angular-component-empty.d.ts +50 -0
  254. package/types/ojiepermana-angular-component-form.d.ts +52 -3
  255. package/types/ojiepermana-angular-component-hover-card.d.ts +74 -0
  256. package/types/ojiepermana-angular-component-input-otp.d.ts +136 -0
  257. package/types/ojiepermana-angular-component-kanban.d.ts +70 -0
  258. package/types/ojiepermana-angular-component-kbd.d.ts +16 -0
  259. package/types/ojiepermana-angular-component-menubar.d.ts +67 -0
  260. package/types/ojiepermana-angular-component-native-select.d.ts +26 -0
  261. package/types/ojiepermana-angular-component-navigation-menu.d.ts +96 -0
  262. package/types/ojiepermana-angular-component-pagination.d.ts +10 -4
  263. package/types/ojiepermana-angular-component-pillbox.d.ts +157 -0
  264. package/types/ojiepermana-angular-component-radio.d.ts +7 -1
  265. package/types/ojiepermana-angular-component-resizable.d.ts +99 -0
  266. package/types/ojiepermana-angular-component-select.d.ts +17 -5
  267. package/types/ojiepermana-angular-component-sheet.d.ts +3 -1
  268. package/types/ojiepermana-angular-component-slider.d.ts +59 -1
  269. package/types/ojiepermana-angular-component-spinner.d.ts +13 -0
  270. package/types/ojiepermana-angular-component-switch.d.ts +13 -3
  271. package/types/ojiepermana-angular-component-timeline.d.ts +63 -0
  272. package/types/ojiepermana-angular-component-toast.d.ts +12 -3
  273. package/types/ojiepermana-angular-component-toggle-group.d.ts +89 -0
  274. package/types/ojiepermana-angular-component-toggle.d.ts +25 -0
  275. package/types/ojiepermana-angular-component-tooltip.d.ts +72 -5
  276. package/types/{ojiepermana-angular-layout-horizontal.d.ts → ojiepermana-angular-layout-type-horizontal.d.ts} +3 -3
  277. package/types/{ojiepermana-angular-layout-vertical.d.ts → ojiepermana-angular-layout-type-vertical.d.ts} +3 -3
  278. package/types/ojiepermana-angular-layout.d.ts +5 -5
  279. package/types/ojiepermana-angular-navigation-item.d.ts +1 -1
  280. package/types/ojiepermana-angular-navigation-service.d.ts +7 -7
  281. package/types/ojiepermana-angular-navigation-sidebar.d.ts +8 -8
  282. package/types/ojiepermana-angular-navigation-topbar.d.ts +24 -4
  283. package/types/ojiepermana-angular-navigation-types.d.ts +14 -8
  284. package/fesm2022/ojiepermana-angular-layout-empty.mjs.map +0 -1
  285. package/fesm2022/ojiepermana-angular-layout-horizontal.mjs.map +0 -1
  286. package/fesm2022/ojiepermana-angular-layout-vertical.mjs.map +0 -1
  287. package/layout/empty/package.json +0 -4
  288. package/layout/horizontal/package.json +0 -4
  289. package/layout/vertical/package.json +0 -4
  290. /package/types/{ojiepermana-angular-layout-empty.d.ts → ojiepermana-angular-layout-type-empty.d.ts} +0 -0
@@ -0,0 +1,195 @@
1
+ # Collapsible
2
+
3
+ Displays an interactive disclosure region that expands and collapses inline content.
4
+
5
+ Use Collapsible for settings drawers, detail rows, compact status cards, and nested explorers where content should stay in the same document flow.
6
+
7
+ ## Import
8
+
9
+ ```ts
10
+ import {
11
+ CollapsibleComponent,
12
+ CollapsibleContentComponent,
13
+ CollapsibleTriggerDirective,
14
+ } from '@ojiepermana/angular/component/collapsible';
15
+ ```
16
+
17
+ ## Composition
18
+
19
+ The Angular composition follows the shadcn and Radix structure while using a root component, a trigger directive on a native button, and a content component.
20
+
21
+ ```text
22
+ ui-collapsible
23
+ ├── button[ui-collapsible-trigger]
24
+ └── ui-collapsible-content
25
+ ```
26
+
27
+ ## Basic usage
28
+
29
+ Bind `[(open)]` when the parent should control the disclosure state or seed a default open panel.
30
+
31
+ ```ts
32
+ readonly detailsOpen = signal(false);
33
+ ```
34
+
35
+ ```html
36
+ <ui-collapsible [(open)]="detailsOpen" class="w-full max-w-md rounded-lg border border-border p-3">
37
+ <button
38
+ ui-collapsible-trigger
39
+ class="inline-flex w-full items-center justify-between gap-2 text-left text-sm font-medium">
40
+ Can I use this in my project?
41
+ <span aria-hidden="true">+</span>
42
+ </button>
43
+
44
+ <ui-collapsible-content class="pt-3 text-sm text-muted-foreground">
45
+ Yes. The trigger and content follow the disclosure ARIA pattern and stay in normal layout flow.
46
+ </ui-collapsible-content>
47
+ </ui-collapsible>
48
+ ```
49
+
50
+ ## Common patterns
51
+
52
+ ### Controlled state
53
+
54
+ Use a signal boolean with `[(open)]` when another control needs to observe or update the open state.
55
+
56
+ ```ts
57
+ readonly isOpen = signal(false);
58
+
59
+ toggleFromElsewhere(): void {
60
+ this.isOpen.update((value) => !value);
61
+ }
62
+ ```
63
+
64
+ ### Button composition
65
+
66
+ `button[ui-collapsible-trigger]` is a directive, so it can compose with the local button primitive on the same element.
67
+
68
+ ```html
69
+ <ui-collapsible [(open)]="basicOpen" class="rounded-md border border-border p-2">
70
+ <button ui-button ui-collapsible-trigger variant="ghost" class="w-full justify-between px-2">
71
+ Product details
72
+ <svg aria-hidden="true" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
73
+ <polyline points="6 9 12 15 18 9" />
74
+ </svg>
75
+ </button>
76
+
77
+ <ui-collapsible-content class="px-2 pb-2 pt-1 text-sm text-muted-foreground">
78
+ This panel can reveal additional details without leaving the page.
79
+ </ui-collapsible-content>
80
+ </ui-collapsible>
81
+ ```
82
+
83
+ ### Settings drawer
84
+
85
+ Wrap the trigger and content inside a card-like surface when the disclosure belongs to a small settings editor.
86
+
87
+ ```html
88
+ <ui-collapsible [(open)]="settingsOpen" class="rounded-lg border border-border p-4">
89
+ <div class="flex items-start gap-3">
90
+ <div class="grid flex-1 grid-cols-2 gap-2">
91
+ <input ui-input placeholder="Radius X" />
92
+ <input ui-input placeholder="Radius Y" />
93
+ <ui-collapsible-content class="col-span-full grid grid-cols-2 gap-2 pt-0">
94
+ <input ui-input placeholder="Blur" />
95
+ <input ui-input placeholder="Spread" />
96
+ </ui-collapsible-content>
97
+ </div>
98
+
99
+ <button ui-button ui-collapsible-trigger variant="outline" size="icon" aria-label="Toggle advanced fields">
100
+ <span aria-hidden="true">...</span>
101
+ </button>
102
+ </div>
103
+ </ui-collapsible>
104
+ ```
105
+
106
+ ### Nested file tree
107
+
108
+ Nested `ui-collapsible` roots work well for compact explorers and outline views.
109
+
110
+ ```html
111
+ <ui-collapsible [(open)]="componentsOpen">
112
+ <button ui-collapsible-trigger class="inline-flex items-center gap-2 text-sm font-medium">components</button>
113
+
114
+ <ui-collapsible-content class="ml-5 mt-2 flex flex-col gap-1">
115
+ <ui-collapsible [(open)]="uiOpen">
116
+ <button ui-collapsible-trigger class="inline-flex items-center gap-2 text-sm font-medium">ui</button>
117
+ <ui-collapsible-content class="ml-5 mt-2 flex flex-col gap-1 text-sm text-muted-foreground">
118
+ <span>button.ts</span>
119
+ <span>collapsible.ts</span>
120
+ </ui-collapsible-content>
121
+ </ui-collapsible>
122
+ </ui-collapsible-content>
123
+ </ui-collapsible>
124
+ ```
125
+
126
+ ### RTL
127
+
128
+ For right-to-left interfaces, set `dir="rtl"` on a wrapping container or the collapsible root.
129
+
130
+ ```html
131
+ <section dir="rtl" lang="ar" class="max-w-md text-right">
132
+ <ui-collapsible [(open)]="rtlOpen" class="flex flex-col gap-2">
133
+ <button ui-collapsible-trigger class="inline-flex items-center justify-between gap-2 text-sm font-medium">
134
+ تبديل التفاصيل
135
+ </button>
136
+ <ui-collapsible-content class="flex flex-col gap-2 text-sm">
137
+ <div class="rounded-md border border-border px-4 py-2">عنوان الشحن</div>
138
+ <div class="rounded-md border border-border px-4 py-2">2x سماعات الاستوديو</div>
139
+ </ui-collapsible-content>
140
+ </ui-collapsible>
141
+ </section>
142
+ ```
143
+
144
+ ## API reference
145
+
146
+ ### `CollapsibleComponent`
147
+
148
+ | Input | Type | Default |
149
+ | -------------- | --------- | ------- |
150
+ | `open` (model) | `boolean` | `false` |
151
+ | `disabled` | `boolean` | `false` |
152
+ | `class` | `string` | `''` |
153
+
154
+ ### `CollapsibleContentComponent`
155
+
156
+ | Input | Type | Default |
157
+ | ------------ | --------- | ------- |
158
+ | `forceMount` | `boolean` | `false` |
159
+ | `class` | `string` | `''` |
160
+
161
+ ### Parts
162
+
163
+ - `button[ui-collapsible-trigger]` is the interactive control. It manages `aria-expanded`, `aria-controls`, `data-state`, and root toggling.
164
+ - `ui-collapsible-content` is the panel region. It applies `role="region"`, `aria-labelledby`, `data-state`, and optional persistent projection via `forceMount`.
165
+ - Lower-level behavior follows the Radix Collapsible model: <https://www.radix-ui.com/primitives/docs/components/collapsible#api-reference>.
166
+
167
+ ## Styling and theming
168
+
169
+ Pass `class` to the root or content, and use the native `class` attribute on the trigger button. The root and content expose `data-state="open" | "closed"` so surrounding styles or transitions can react to the current disclosure state.
170
+
171
+ Use theme tokens such as `border-border`, `bg-card`, `text-muted-foreground`, and spacing utilities to match the rest of the library.
172
+
173
+ ## Accessibility
174
+
175
+ - The primitive follows the disclosure WAI-ARIA pattern.
176
+ - Trigger is a native button, so Enter and Space work without extra key handling.
177
+ - Trigger receives `aria-controls` and `aria-expanded`; content receives `role="region"` and `aria-labelledby`.
178
+ - `disabled` keeps the control visible while preventing interaction.
179
+
180
+ ## Keyboard interactions
181
+
182
+ - `Enter` toggles the collapsible.
183
+ - `Space` toggles the collapsible.
184
+ - Tab order follows the DOM order of the trigger and any focusable controls inside the content.
185
+
186
+ ## Angular notes
187
+
188
+ - `[(open)]` is the Angular equivalent of shadcn's `open` and `onOpenChange` props.
189
+ - `button[ui-collapsible-trigger]` is a directive, not a component, so it can compose with `button[ui-button]` on the same element.
190
+ - `forceMount` keeps projected content rendered even when the panel is closed, which is useful for measuring or animating content without re-creating it.
191
+ - The local API intentionally does not add an `asChild` prop; Angular composition is handled through selectors and host directives instead.
192
+
193
+ ## Source parity
194
+
195
+ This Angular implementation follows the shadcn Collapsible structure and examples while translating the API to standalone Angular imports, signal-backed state, button-directive composition, and Angular-friendly RTL guidance.
@@ -0,0 +1,198 @@
1
+ # Combobox
2
+
3
+ Searchable single-select surface built from a button trigger, a CDK overlay,
4
+ and the shared [Command](../command/README.md) list primitives.
5
+
6
+ Use Combobox when users need type-to-filter selection from a medium-sized list
7
+ without leaving the current form, settings screen, or dashboard panel.
8
+
9
+ ## Import
10
+
11
+ ```ts
12
+ import { ComboboxComponent, type ComboboxOption } from '@ojiepermana/angular/component/combobox';
13
+ ```
14
+
15
+ ## Composition
16
+
17
+ The Angular structure maps the combobox idea onto the existing library stack:
18
+
19
+ ```text
20
+ ui-combobox
21
+ ├── button[role="combobox"]
22
+ └── CDK overlay
23
+ └── ui-command
24
+ ├── input[ui-command-input]
25
+ └── ui-command-list
26
+ └── button[ui-command-item]
27
+ ```
28
+
29
+ This differs from the current shadcn Base UI page, which documents an input-first
30
+ combobox. The Angular library currently ships the common searchable single-select
31
+ pattern on top of Button + Command + CDK Overlay.
32
+
33
+ ## Basic usage
34
+
35
+ Bind `[(value)]` when a signal or parent component should own the selected value.
36
+ Pass width or layout utilities through the host `class`; the trigger fills that
37
+ host width.
38
+
39
+ ```ts
40
+ frameworkOptions: ComboboxOption<string>[] = [
41
+ { value: 'angular', label: 'Angular' },
42
+ { value: 'nextjs', label: 'Next.js' },
43
+ { value: 'astro', label: 'Astro' },
44
+ ];
45
+
46
+ selectedFramework = signal<string | null>(null);
47
+ ```
48
+
49
+ ```html
50
+ <ui-combobox
51
+ class="w-80"
52
+ [options]="frameworkOptions"
53
+ [(value)]="selectedFramework"
54
+ placeholder="Select framework"
55
+ searchPlaceholder="Search frameworks..." />
56
+ ```
57
+
58
+ ## Common patterns
59
+
60
+ ### Object-backed values
61
+
62
+ Option values can be full domain objects, not only strings.
63
+
64
+ ```ts
65
+ type Country = {
66
+ code: string;
67
+ label: string;
68
+ region: string;
69
+ currency: string;
70
+ };
71
+
72
+ countryOptions: ComboboxOption<Country>[] = [
73
+ {
74
+ value: { code: 'ca', label: 'Canada', region: 'North America', currency: 'CAD' },
75
+ label: 'Canada',
76
+ },
77
+ {
78
+ value: { code: 'jp', label: 'Japan', region: 'Asia', currency: 'JPY' },
79
+ label: 'Japan',
80
+ },
81
+ ];
82
+
83
+ selectedCountry = signal<Country | null>(countryOptions[0]?.value ?? null);
84
+ ```
85
+
86
+ ```html
87
+ <ui-combobox
88
+ class="w-full max-w-sm"
89
+ [options]="countryOptions"
90
+ [(value)]="selectedCountry"
91
+ placeholder="Select country"
92
+ searchPlaceholder="Search countries..." />
93
+ ```
94
+
95
+ ### Disabled options and empty states
96
+
97
+ Mark options with `disabled: true` when they should stay visible but unavailable.
98
+ Tune `searchPlaceholder` and `emptyText` so large lists feel intentional.
99
+
100
+ ```ts
101
+ feedOptions: ComboboxOption<string>[] = [
102
+ { value: 'release-notes', label: 'Release notes' },
103
+ { value: 'beta-api', label: 'Beta API access', disabled: true },
104
+ { value: 'status-page', label: 'Status page' },
105
+ ];
106
+ ```
107
+
108
+ ```html
109
+ <ui-combobox
110
+ class="w-full max-w-sm"
111
+ [options]="feedOptions"
112
+ placeholder="Choose a feed"
113
+ searchPlaceholder="Search feeds..."
114
+ emptyText="No feeds matched your query." />
115
+ ```
116
+
117
+ ### Reactive forms
118
+
119
+ The component implements `ControlValueAccessor`, so it also works with Angular
120
+ reactive forms.
121
+
122
+ ```ts
123
+ readonly form = new FormGroup({
124
+ framework: new FormControl<string | null>(null),
125
+ });
126
+ ```
127
+
128
+ ```html
129
+ <form [formGroup]="form">
130
+ <ui-combobox
131
+ class="w-80"
132
+ formControlName="framework"
133
+ [options]="frameworkOptions"
134
+ placeholder="Select framework"
135
+ searchPlaceholder="Search frameworks..." />
136
+ </form>
137
+ ```
138
+
139
+ ## API reference
140
+
141
+ | Input or model | Type | Default |
142
+ | ------------------- | ---------------------------------- | --------------------- |
143
+ | `options` | `ReadonlyArray<ComboboxOption<T>>` | `[]` |
144
+ | `value` | `T \| null` | `null` |
145
+ | `placeholder` | `string` | `'Select…'` |
146
+ | `searchPlaceholder` | `string` | `'Search…'` |
147
+ | `emptyText` | `string` | `'No results found.'` |
148
+ | `disabled` | `boolean` | `false` |
149
+ | `class` | `string` | `''` |
150
+
151
+ Output: `valueChange: T | null`.
152
+
153
+ ### `ComboboxOption<T>`
154
+
155
+ ```ts
156
+ interface ComboboxOption<T = unknown> {
157
+ value: T;
158
+ label: string;
159
+ disabled?: boolean;
160
+ }
161
+ ```
162
+
163
+ ## Styling and theming
164
+
165
+ - Pass `class` to the host element for width and layout. The trigger fills the host width.
166
+ - Trigger uses the shared `outline` button variant.
167
+ - Overlay panel class is `ui-combobox-panel`.
168
+ - Overlay width tracks the trigger with `--ui-combobox-trigger-width`.
169
+
170
+ ## Accessibility
171
+
172
+ - Trigger exposes `role="combobox"`, `aria-expanded`, `aria-controls`, and `aria-haspopup="listbox"`.
173
+ - Panel content is powered by `ui-command`, which provides the filter input and listbox roles.
174
+ - Escape and outside click close the panel; focus returns to the trigger.
175
+ - Keep a visible label or surrounding explanatory copy when placeholder text alone is not enough context.
176
+
177
+ ## Keyboard interactions
178
+
179
+ - Enter or Space opens the trigger because it is a native button.
180
+ - Arrow keys move between filtered command items once the search input is focused.
181
+ - Enter selects the active option, and Escape closes the surface.
182
+ - Tab leaves the combobox in normal DOM order.
183
+
184
+ ## Angular notes
185
+
186
+ - `[(value)]` is the simplest signal-friendly binding for standalone components.
187
+ - Because the component implements `ControlValueAccessor`, it also works with reactive forms.
188
+ - Object-backed selections rely on strict equality. Reuse the same object instances from the bound `options` array.
189
+
190
+ ## Source parity
191
+
192
+ The current shadcn combobox docs also cover grouped collections, popup triggers,
193
+ clear buttons, invalid styling, input add-ons, and multi-select chips. Those
194
+ variants are not exposed by `ui-combobox` yet.
195
+
196
+ This README documents the supported Angular surface today and calls out the
197
+ upstream shadcn page as a reference for future expansion, not as a promise that
198
+ every upstream example already exists in this package.
@@ -0,0 +1,275 @@
1
+ # Command
2
+
3
+ Searchable command palette primitive for quick actions, navigation, and settings.
4
+
5
+ Use Command inline for filterable action lists, or compose it with Dialog to recreate shadcn's `CommandDialog` pattern. The same primitive also powers [Combobox](../combobox/README.md).
6
+
7
+ ## Import
8
+
9
+ Import the command parts directly from the component package.
10
+
11
+ ```ts
12
+ import {
13
+ CommandComponent,
14
+ CommandEmptyComponent,
15
+ CommandGroupComponent,
16
+ CommandInputComponent,
17
+ CommandItemComponent,
18
+ CommandListComponent,
19
+ CommandSeparatorComponent,
20
+ CommandShortcutComponent,
21
+ } from '@ojiepermana/angular/component/command';
22
+ ```
23
+
24
+ When you want a palette launcher like shadcn's `CommandDialog`, add Button and Dialog primitives as well.
25
+
26
+ ```ts
27
+ import { ButtonComponent } from '@ojiepermana/angular/component/button';
28
+ import {
29
+ DialogComponent,
30
+ DialogDescriptionComponent,
31
+ DialogHeaderComponent,
32
+ DialogTitleComponent,
33
+ } from '@ojiepermana/angular/component/dialog';
34
+ ```
35
+
36
+ ## Composition
37
+
38
+ The Angular composition mirrors shadcn's structure while keeping overlay behavior separate.
39
+
40
+ ```text
41
+ ui-command
42
+ ├── input[ui-command-input]
43
+ └── ui-command-list
44
+ ├── ui-command-empty
45
+ ├── ui-command-group
46
+ │ ├── button[ui-command-item]
47
+ │ └── button[ui-command-item]
48
+ ├── ui-command-separator
49
+ └── ui-command-group
50
+ ├── button[ui-command-item]
51
+ └── button[ui-command-item]
52
+ ```
53
+
54
+ ## Basic usage
55
+
56
+ Build the searchable surface from the root, input, list, and grouped items. Add `span[ui-command-shortcut]` when an item should expose a trailing keyboard hint.
57
+
58
+ ```html
59
+ <ui-command class="max-w-md rounded-lg border border-border">
60
+ <input ui-command-input placeholder="Type a command or search..." />
61
+ <ui-command-list>
62
+ <ui-command-empty>No results found.</ui-command-empty>
63
+
64
+ <ui-command-group heading="Suggestions">
65
+ <button type="button" ui-command-item value="Calendar" (selected)="open('calendar')">Calendar</button>
66
+ <button type="button" ui-command-item value="Search Emoji" (selected)="open('emoji')">Search Emoji</button>
67
+ </ui-command-group>
68
+
69
+ <ui-command-separator />
70
+
71
+ <ui-command-group heading="Settings">
72
+ <button type="button" ui-command-item value="Profile" (selected)="open('profile')">
73
+ Profile
74
+ <span ui-command-shortcut>⌘P</span>
75
+ </button>
76
+ </ui-command-group>
77
+ </ui-command-list>
78
+ </ui-command>
79
+ ```
80
+
81
+ ## Common patterns
82
+
83
+ ### Command palette dialog
84
+
85
+ shadcn ships a dedicated `CommandDialog` helper. In this Angular library, compose `ui-dialog` with `ui-command` instead.
86
+
87
+ ```ts
88
+ const commandOpen = signal(false);
89
+ ```
90
+
91
+ ```html
92
+ <button type="button" ui-button variant="outline" (click)="commandOpen.set(true)">Open menu</button>
93
+
94
+ <ui-dialog [(open)]="commandOpen">
95
+ <ui-dialog-header>
96
+ <ui-dialog-title>Command palette</ui-dialog-title>
97
+ <ui-dialog-description> Search for navigation, billing, or settings actions. </ui-dialog-description>
98
+ </ui-dialog-header>
99
+
100
+ <ui-command class="mt-4 rounded-lg border border-border">
101
+ <input ui-command-input placeholder="Type a command or search..." />
102
+ <ui-command-list>
103
+ <ui-command-empty>No results found.</ui-command-empty>
104
+ <ui-command-group heading="Suggestions">
105
+ <button type="button" ui-command-item value="Calendar" (selected)="commandOpen.set(false)">Calendar</button>
106
+ </ui-command-group>
107
+ </ui-command-list>
108
+ </ui-command>
109
+ </ui-dialog>
110
+ ```
111
+
112
+ ### Shortcuts
113
+
114
+ Use `span[ui-command-shortcut]` for keyboard hints aligned to the trailing edge of each row.
115
+
116
+ ```html
117
+ <ui-command class="max-w-md rounded-lg border border-border">
118
+ <input ui-command-input placeholder="Search shortcuts..." />
119
+ <ui-command-list>
120
+ <ui-command-group heading="Quick actions">
121
+ <button type="button" ui-command-item value="Profile">
122
+ Profile
123
+ <span ui-command-shortcut>⌘P</span>
124
+ </button>
125
+ <button type="button" ui-command-item value="Billing">
126
+ Billing
127
+ <span ui-command-shortcut>⌘B</span>
128
+ </button>
129
+ </ui-command-group>
130
+ </ui-command-list>
131
+ </ui-command>
132
+ ```
133
+
134
+ ### Scrollable command lists
135
+
136
+ The list container defaults to a scrollable max height. Override it with `class` when the palette needs to expose many groups.
137
+
138
+ ```html
139
+ <ui-command class="max-w-xl rounded-lg border border-border">
140
+ <input ui-command-input placeholder="Jump to a tool or action..." />
141
+ <ui-command-list class="max-h-56">
142
+ <ui-command-empty>No results found.</ui-command-empty>
143
+ <ui-command-group heading="Navigation">...</ui-command-group>
144
+ <ui-command-separator />
145
+ <ui-command-group heading="Actions">...</ui-command-group>
146
+ <ui-command-separator />
147
+ <ui-command-group heading="Tools">...</ui-command-group>
148
+ </ui-command-list>
149
+ </ui-command>
150
+ ```
151
+
152
+ ### Controlled query
153
+
154
+ Two-way bind the query when the parent needs to inspect, reset, or prefill the current search string.
155
+
156
+ ```ts
157
+ const query = signal('');
158
+ ```
159
+
160
+ ```html
161
+ <ui-command [(query)]="query" class="max-w-md rounded-lg border border-border">
162
+ <input ui-command-input placeholder="Filter actions..." />
163
+ <ui-command-list>...</ui-command-list>
164
+ </ui-command>
165
+ ```
166
+
167
+ ### RTL
168
+
169
+ For right-to-left interfaces, apply `dir="rtl"` to the wrapper and input.
170
+
171
+ ```html
172
+ <section dir="rtl" lang="ar" class="max-w-md text-right">
173
+ <ui-command class="rounded-lg border border-border">
174
+ <input ui-command-input placeholder="اكتب أمرًا أو ابحث..." dir="rtl" />
175
+ <ui-command-list>
176
+ <ui-command-empty>لم يتم العثور على نتائج.</ui-command-empty>
177
+ <ui-command-group heading="اقتراحات">...</ui-command-group>
178
+ <ui-command-separator />
179
+ <ui-command-group heading="الإعدادات">...</ui-command-group>
180
+ </ui-command-list>
181
+ </ui-command>
182
+ </section>
183
+ ```
184
+
185
+ ## API reference
186
+
187
+ ### `CommandComponent`
188
+
189
+ | Input / Model | Type | Default |
190
+ | ------------- | -------- | ------- |
191
+ | `query` | `string` | `''` |
192
+ | `class` | `string` | `''` |
193
+
194
+ ### `CommandInputComponent`
195
+
196
+ | Input | Type | Default |
197
+ | ------------- | -------- | ----------------------------- |
198
+ | `placeholder` | `string` | `Type a command or search...` |
199
+ | `class` | `string` | `''` |
200
+
201
+ Behavior:
202
+
203
+ - Uses `role="combobox"` and `aria-autocomplete="list"`.
204
+ - Arrow Down and Arrow Up move the active item.
205
+ - Enter selects the active visible item.
206
+
207
+ ### `CommandListComponent`
208
+
209
+ | Input | Type | Default |
210
+ | ------- | -------- | ------- |
211
+ | `class` | `string` | `''` |
212
+
213
+ Behavior: renders the listbox region and scroll container.
214
+
215
+ ### `CommandGroupComponent`
216
+
217
+ | Input | Type | Default |
218
+ | --------- | ---------------- | ------- |
219
+ | `heading` | `string \| null` | `null` |
220
+ | `class` | `string` | `''` |
221
+
222
+ ### `CommandItemComponent`
223
+
224
+ | Input / Output | Type | Default |
225
+ | -------------- | ----------------------------- | -------------------- |
226
+ | `value` | `string` | `''` |
227
+ | `disabled` | `boolean` | `false` |
228
+ | `class` | `string` | `''` |
229
+ | `selected` | `MouseEvent \| KeyboardEvent` | emitted on selection |
230
+
231
+ Behavior:
232
+
233
+ - Uses `role="option"`.
234
+ - Hides automatically when the current query does not match its `value` or text content.
235
+ - Skips selection when `disabled` is `true`.
236
+
237
+ ### Auxiliary parts
238
+
239
+ - `ui-command-empty` appears only when no visible items match the query.
240
+ - `ui-command-separator` renders a divider between groups.
241
+ - `span[ui-command-shortcut]` aligns trailing shortcut text with `ml-auto` styling.
242
+
243
+ ## Styling and theming
244
+
245
+ Pass `class` to the root and parts to tune borders, width, list height, and embedded dialog layouts.
246
+
247
+ The primitive already applies shared theme tokens such as `bg-popover`, `text-popover-foreground`, `border-border`, and active-row accent styles. Typical overrides include:
248
+
249
+ - `rounded-lg border border-border` on the root for shadcn-like cards.
250
+ - `max-h-*` on `ui-command-list` for taller or shorter scroll regions.
251
+ - Additional spacing or layout classes on items when an app supplies inline badges or icons.
252
+
253
+ ## Accessibility
254
+
255
+ - The input uses combobox semantics while the list exposes listbox-style options.
256
+ - Items expose `aria-selected`, `data-active`, and disabled state markers.
257
+ - Disabled items remain visible for discoverability but are skipped by keyboard selection.
258
+ - Keep item labels descriptive and avoid deeply nested interactive content inside a command item.
259
+
260
+ ## Keyboard interactions
261
+
262
+ - Arrow Down and Arrow Up move the active option through visible items.
263
+ - Enter selects the active item.
264
+ - Typing filters items by the configured `value` or fallback text content.
265
+
266
+ ## Angular notes
267
+
268
+ - The root exposes a signal-backed `query` model, so `[(query)]` works naturally in standalone components.
269
+ - `button[ui-command-item]` is the most practical item host because it preserves native semantics for click and keyboard handlers.
270
+ - `ComboboxComponent` already builds on this primitive, so keep command examples action-oriented instead of mixing them with form-specific behavior.
271
+ - This primitive intentionally stays presentational. Compose it with higher-level surfaces such as Dialog rather than coupling it to overlay infrastructure.
272
+
273
+ ## Source parity
274
+
275
+ This Angular implementation follows shadcn's Command information architecture and `cmdk` mental model while translating the dialog helper into existing `ui-dialog` primitives and Angular selectors.