@ojiepermana/angular 22.1.10 → 22.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/README.md +32 -26
  2. package/chart/README.md +272 -0
  3. package/component/README.md +89 -0
  4. package/component/accordion/README.md +195 -0
  5. package/component/alert/README.md +184 -0
  6. package/component/alert-dialog/README.md +255 -0
  7. package/component/aspect-ratio/README.md +116 -0
  8. package/component/avatar/README.md +182 -0
  9. package/component/badge/README.md +143 -0
  10. package/component/breadcrumb/README.md +223 -0
  11. package/component/button/README.md +141 -0
  12. package/component/button-group/README.md +214 -0
  13. package/component/calendar/README.md +137 -0
  14. package/component/card/README.md +232 -0
  15. package/component/carousel/README.md +276 -0
  16. package/component/checkbox/README.md +153 -0
  17. package/component/collapsible/README.md +216 -0
  18. package/component/combobox/README.md +202 -0
  19. package/component/command/README.md +287 -0
  20. package/component/composer/README.md +241 -0
  21. package/component/context-menu/README.md +268 -0
  22. package/component/date-picker/README.md +202 -0
  23. package/component/dialog/README.md +276 -0
  24. package/component/drawer/README.md +147 -0
  25. package/component/dropdown-menu/README.md +336 -0
  26. package/component/editor/README.md +152 -0
  27. package/component/empty/README.md +193 -0
  28. package/component/form/README.md +216 -0
  29. package/component/hover-card/README.md +150 -0
  30. package/component/icon/README.md +25 -0
  31. package/component/input/README.md +160 -0
  32. package/component/input-group/README.md +245 -0
  33. package/component/input-otp/README.md +331 -0
  34. package/component/item/README.md +254 -0
  35. package/component/kanban/README.md +81 -0
  36. package/component/kbd/README.md +141 -0
  37. package/component/label/README.md +137 -0
  38. package/component/menubar/README.md +270 -0
  39. package/component/native-select/README.md +176 -0
  40. package/component/navigation-menu/README.md +165 -0
  41. package/component/pagination/README.md +151 -0
  42. package/component/pillbox/README.md +68 -0
  43. package/component/popover/README.md +54 -0
  44. package/component/progress/README.md +160 -0
  45. package/component/radio/README.md +212 -0
  46. package/component/resizable/README.md +178 -0
  47. package/component/scroll-area/README.md +150 -0
  48. package/component/select/README.md +228 -0
  49. package/component/separator/README.md +175 -0
  50. package/component/sheet/README.md +190 -0
  51. package/component/skeleton/README.md +158 -0
  52. package/component/slider/README.md +207 -0
  53. package/component/spinner/README.md +160 -0
  54. package/component/switch/README.md +170 -0
  55. package/component/table/README.md +292 -0
  56. package/component/tabs/README.md +220 -0
  57. package/component/textarea/README.md +169 -0
  58. package/component/timeline/README.md +94 -0
  59. package/component/toast/README.md +173 -0
  60. package/component/toggle/README.md +133 -0
  61. package/component/toggle-group/README.md +234 -0
  62. package/component/tooltip/README.md +230 -0
  63. package/fesm2022/ojiepermana-angular-chart-area.mjs +289 -3
  64. package/fesm2022/ojiepermana-angular-chart-bar.mjs +722 -3
  65. package/fesm2022/ojiepermana-angular-chart-core.mjs +1482 -3
  66. package/fesm2022/ojiepermana-angular-chart-line.mjs +294 -3
  67. package/fesm2022/ojiepermana-angular-chart-pie.mjs +291 -3
  68. package/fesm2022/ojiepermana-angular-chart-primitives.mjs +1301 -3
  69. package/fesm2022/ojiepermana-angular-chart-radar.mjs +421 -3
  70. package/fesm2022/ojiepermana-angular-chart-radial.mjs +295 -3
  71. package/fesm2022/ojiepermana-angular-chart-scatter.mjs +306 -3
  72. package/fesm2022/ojiepermana-angular-chart.mjs +12 -3
  73. package/fesm2022/ojiepermana-angular-component-accordion.mjs +267 -3
  74. package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +359 -3
  75. package/fesm2022/ojiepermana-angular-component-alert.mjs +101 -3
  76. package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +31 -3
  77. package/fesm2022/ojiepermana-angular-component-avatar.mjs +139 -3
  78. package/fesm2022/ojiepermana-angular-component-badge.mjs +57 -3
  79. package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +192 -3
  80. package/fesm2022/ojiepermana-angular-component-button-group.mjs +95 -3
  81. package/fesm2022/ojiepermana-angular-component-button.mjs +73 -3
  82. package/fesm2022/ojiepermana-angular-component-calendar.mjs +718 -3
  83. package/fesm2022/ojiepermana-angular-component-card.mjs +167 -3
  84. package/fesm2022/ojiepermana-angular-component-carousel.mjs +326 -3
  85. package/fesm2022/ojiepermana-angular-component-checkbox.mjs +190 -3
  86. package/fesm2022/ojiepermana-angular-component-collapsible.mjs +117 -3
  87. package/fesm2022/ojiepermana-angular-component-combobox.mjs +327 -3
  88. package/fesm2022/ojiepermana-angular-component-command.mjs +351 -3
  89. package/fesm2022/ojiepermana-angular-component-composer.mjs +359 -3
  90. package/fesm2022/ojiepermana-angular-component-context-menu.mjs +158 -3
  91. package/fesm2022/ojiepermana-angular-component-date-picker.mjs +482 -3
  92. package/fesm2022/ojiepermana-angular-component-dialog.mjs +400 -3
  93. package/fesm2022/ojiepermana-angular-component-drawer.mjs +1 -3
  94. package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +689 -3
  95. package/fesm2022/ojiepermana-angular-component-editor.mjs +511 -3
  96. package/fesm2022/ojiepermana-angular-component-empty.mjs +134 -3
  97. package/fesm2022/ojiepermana-angular-component-form.mjs +438 -3
  98. package/fesm2022/ojiepermana-angular-component-hover-card.mjs +273 -3
  99. package/fesm2022/ojiepermana-angular-component-icon.mjs +139 -3
  100. package/fesm2022/ojiepermana-angular-component-input-group.mjs +176 -3
  101. package/fesm2022/ojiepermana-angular-component-input-otp.mjs +550 -3
  102. package/fesm2022/ojiepermana-angular-component-input.mjs +52 -3
  103. package/fesm2022/ojiepermana-angular-component-item.mjs +264 -3
  104. package/fesm2022/ojiepermana-angular-component-kanban.mjs +310 -3
  105. package/fesm2022/ojiepermana-angular-component-kbd.mjs +48 -3
  106. package/fesm2022/ojiepermana-angular-component-label.mjs +27 -3
  107. package/fesm2022/ojiepermana-angular-component-menubar.mjs +327 -3
  108. package/fesm2022/ojiepermana-angular-component-native-select.mjs +62 -3
  109. package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +378 -3
  110. package/fesm2022/ojiepermana-angular-component-pagination.mjs +238 -3
  111. package/fesm2022/ojiepermana-angular-component-pillbox.mjs +999 -3
  112. package/fesm2022/ojiepermana-angular-component-popover.mjs +201 -3
  113. package/fesm2022/ojiepermana-angular-component-progress.mjs +57 -3
  114. package/fesm2022/ojiepermana-angular-component-radio.mjs +180 -3
  115. package/fesm2022/ojiepermana-angular-component-resizable.mjs +493 -3
  116. package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +51 -3
  117. package/fesm2022/ojiepermana-angular-component-segmented-control.mjs +227 -3
  118. package/fesm2022/ojiepermana-angular-component-select.mjs +609 -3
  119. package/fesm2022/ojiepermana-angular-component-separator.mjs +31 -3
  120. package/fesm2022/ojiepermana-angular-component-sheet.mjs +407 -3
  121. package/fesm2022/ojiepermana-angular-component-skeleton.mjs +25 -3
  122. package/fesm2022/ojiepermana-angular-component-slider.mjs +456 -3
  123. package/fesm2022/ojiepermana-angular-component-spinner.mjs +56 -3
  124. package/fesm2022/ojiepermana-angular-component-switch.mjs +145 -3
  125. package/fesm2022/ojiepermana-angular-component-table.mjs +155 -3
  126. package/fesm2022/ojiepermana-angular-component-tabs.mjs +315 -3
  127. package/fesm2022/ojiepermana-angular-component-textarea.mjs +46 -3
  128. package/fesm2022/ojiepermana-angular-component-timeline.mjs +237 -3
  129. package/fesm2022/ojiepermana-angular-component-toast.mjs +241 -3
  130. package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +290 -3
  131. package/fesm2022/ojiepermana-angular-component-toggle.mjs +76 -3
  132. package/fesm2022/ojiepermana-angular-component-tooltip.mjs +519 -3
  133. package/fesm2022/ojiepermana-angular-component-utils-core.mjs +310 -3
  134. package/fesm2022/ojiepermana-angular-component-utils-overlay.mjs +62 -3
  135. package/fesm2022/ojiepermana-angular-component-utils-scale.mjs +34 -3
  136. package/fesm2022/ojiepermana-angular-component-utils.mjs +3 -2
  137. package/fesm2022/ojiepermana-angular-component.mjs +4 -4
  138. package/fesm2022/ojiepermana-angular-navigation-core.mjs +21 -3
  139. package/fesm2022/ojiepermana-angular-navigation-icon.mjs +20 -3
  140. package/fesm2022/ojiepermana-angular-navigation-navigation-badge-count.component-CDBxQ8rk.mjs +91 -0
  141. package/fesm2022/ojiepermana-angular-navigation-navigation-dockbar-menu.component-DBQHdvGa.mjs +512 -0
  142. package/fesm2022/ojiepermana-angular-navigation-navigation-entry-grid.component-Cd-jh6tg.mjs +623 -0
  143. package/fesm2022/ojiepermana-angular-navigation-navigation-flyout-menu.component-BCGvhoYj.mjs +404 -0
  144. package/fesm2022/ojiepermana-angular-navigation-navigation-horizontal.component-Dk_03e-6.mjs +466 -0
  145. package/fesm2022/ojiepermana-angular-navigation-ojiepermana-angular-navigation-DNKU6viC.mjs +2642 -0
  146. package/fesm2022/ojiepermana-angular-navigation-service.mjs +725 -3
  147. package/fesm2022/ojiepermana-angular-navigation-types.mjs +65 -4
  148. package/fesm2022/ojiepermana-angular-navigation.mjs +4 -10
  149. package/fesm2022/ojiepermana-angular-sdk.mjs +204 -4
  150. package/fesm2022/ojiepermana-angular-theme-component-settings.mjs +1387 -3
  151. package/fesm2022/ojiepermana-angular-theme-layout-services.mjs +331 -3
  152. package/fesm2022/ojiepermana-angular-theme-layout-types.mjs +45 -4
  153. package/fesm2022/ojiepermana-angular-theme-layout-wrapper.mjs +1044 -3
  154. package/fesm2022/ojiepermana-angular-theme-layout.mjs +729 -3
  155. package/fesm2022/ojiepermana-angular-theme-page-core.mjs +381 -3
  156. package/fesm2022/ojiepermana-angular-theme-page-filter.mjs +267 -3
  157. package/fesm2022/ojiepermana-angular-theme-page-root.mjs +361 -3
  158. package/fesm2022/ojiepermana-angular-theme-page-side.mjs +198 -3
  159. package/fesm2022/ojiepermana-angular-theme-page-slots.mjs +110 -3
  160. package/fesm2022/ojiepermana-angular-theme-page.mjs +7 -2
  161. package/fesm2022/ojiepermana-angular-theme-shell-services.mjs +338 -3
  162. package/fesm2022/ojiepermana-angular-theme-shell-types.mjs +160 -4
  163. package/fesm2022/ojiepermana-angular-theme-shell.mjs +811 -3
  164. package/fesm2022/ojiepermana-angular-theme-styles.mjs +783 -3
  165. package/fesm2022/ojiepermana-angular-theme.mjs +4 -4
  166. package/fesm2022/ojiepermana-angular.mjs +6 -11
  167. package/navigation/README.md +374 -0
  168. package/package.json +81 -20
  169. package/sdk/README.md +212 -0
  170. package/sdk/schematics/collection.json +20 -0
  171. package/sdk/schematics/init/index.js +83 -0
  172. package/sdk/schematics/init/schema.json +19 -0
  173. package/sdk/schematics/ng-add/index.js +147 -0
  174. package/sdk/schematics/ng-add/schema.json +14 -0
  175. package/sdk/schematics/package.json +3 -0
  176. package/sdk/schematics/sdk/index.js +175 -0
  177. package/sdk/schematics/sdk/schema.json +19 -0
  178. package/sdk/sdk.config.example.json +24 -0
  179. package/sdk/src/config/loader.js +43 -0
  180. package/sdk/src/config/schema.js +59 -0
  181. package/sdk/src/emit/client.js +251 -0
  182. package/sdk/src/emit/metadata.js +310 -0
  183. package/sdk/src/emit/models.js +104 -0
  184. package/sdk/src/emit/navigation.js +56 -0
  185. package/sdk/src/emit/operations.js +118 -0
  186. package/sdk/src/emit/public-api.js +54 -0
  187. package/sdk/src/emit/services.js +110 -0
  188. package/sdk/src/engine.js +67 -0
  189. package/sdk/src/layout/per-domain.js +360 -0
  190. package/sdk/src/package.json +3 -0
  191. package/sdk/src/parser/bundle.js +25 -0
  192. package/sdk/src/parser/ir.js +429 -0
  193. package/sdk/src/parser/types.js +7 -0
  194. package/sdk/src/render/template.js +152 -0
  195. package/sdk/src/writer/index.js +286 -0
  196. package/theme/README.md +126 -0
  197. package/theme/component/settings/README.md +135 -0
  198. package/theme/layout/README.md +539 -0
  199. package/theme/page/README.md +453 -0
  200. package/theme/shell/README.md +340 -0
  201. package/theme/styles/README.md +178 -0
  202. package/theme/styles/css/base/components.css +553 -0
  203. package/theme/styles/css/base/index.css +14 -0
  204. package/theme/styles/css/base/package.css +9 -0
  205. package/theme/styles/css/base/prefers-dark.css +86 -0
  206. package/theme/styles/css/base/print.css +62 -0
  207. package/theme/styles/css/base/status.css +38 -0
  208. package/theme/styles/css/base/tailwind.css +165 -0
  209. package/theme/styles/css/base/theme.css +373 -0
  210. package/theme/styles/css/base/tokens.css +361 -0
  211. package/theme/styles/css/color/amber.css +72 -0
  212. package/theme/styles/css/color/blue.css +72 -0
  213. package/theme/styles/css/color/brand.css +38 -0
  214. package/theme/styles/css/color/cyan.css +72 -0
  215. package/theme/styles/css/color/emerald.css +72 -0
  216. package/theme/styles/css/color/fuchsia.css +72 -0
  217. package/theme/styles/css/color/green.css +72 -0
  218. package/theme/styles/css/color/index.css +19 -0
  219. package/theme/styles/css/color/indigo.css +72 -0
  220. package/theme/styles/css/color/lime.css +72 -0
  221. package/theme/styles/css/color/orange.css +72 -0
  222. package/theme/styles/css/color/pink.css +72 -0
  223. package/theme/styles/css/color/purple.css +72 -0
  224. package/theme/styles/css/color/red.css +72 -0
  225. package/theme/styles/css/color/rose.css +72 -0
  226. package/theme/styles/css/color/sky.css +72 -0
  227. package/theme/styles/css/color/teal.css +72 -0
  228. package/theme/styles/css/color/violet.css +72 -0
  229. package/theme/styles/css/color/yellow.css +72 -0
  230. package/theme/styles/css/index.css +18 -0
  231. package/theme/styles/css/neutral/gray.css +63 -0
  232. package/theme/styles/css/neutral/index.css +11 -0
  233. package/theme/styles/css/neutral/mauve.css +63 -0
  234. package/theme/styles/css/neutral/mist.css +63 -0
  235. package/theme/styles/css/neutral/neutral.css +63 -0
  236. package/theme/styles/css/neutral/olive.css +63 -0
  237. package/theme/styles/css/neutral/slate.css +63 -0
  238. package/theme/styles/css/neutral/stone.css +63 -0
  239. package/theme/styles/css/neutral/taupe.css +63 -0
  240. package/theme/styles/css/neutral/zinc.css +63 -0
  241. package/theme/styles/css/radius/index.css +30 -0
  242. package/theme/styles/css/space/index.css +20 -0
  243. package/types/ojiepermana-angular-chart-area.d.ts +76 -1
  244. package/types/ojiepermana-angular-chart-bar.d.ts +201 -1
  245. package/types/ojiepermana-angular-chart-core.d.ts +811 -1
  246. package/types/ojiepermana-angular-chart-line.d.ts +75 -1
  247. package/types/ojiepermana-angular-chart-pie.d.ts +131 -1
  248. package/types/ojiepermana-angular-chart-primitives.d.ts +291 -1
  249. package/types/ojiepermana-angular-chart-radar.d.ts +116 -1
  250. package/types/ojiepermana-angular-chart-radial.d.ts +116 -1
  251. package/types/ojiepermana-angular-chart-scatter.d.ts +125 -1
  252. package/types/ojiepermana-angular-chart.d.ts +2 -1
  253. package/types/ojiepermana-angular-component-accordion.d.ts +85 -1
  254. package/types/ojiepermana-angular-component-alert-dialog.d.ts +140 -1
  255. package/types/ojiepermana-angular-component-alert.d.ts +42 -1
  256. package/types/ojiepermana-angular-component-aspect-ratio.d.ts +12 -1
  257. package/types/ojiepermana-angular-component-avatar.d.ts +56 -1
  258. package/types/ojiepermana-angular-component-badge.d.ts +24 -1
  259. package/types/ojiepermana-angular-component-breadcrumb.d.ts +46 -1
  260. package/types/ojiepermana-angular-component-button-group.d.ts +26 -1
  261. package/types/ojiepermana-angular-component-button.d.ts +27 -1
  262. package/types/ojiepermana-angular-component-calendar.d.ts +111 -1
  263. package/types/ojiepermana-angular-component-card.d.ts +69 -1
  264. package/types/ojiepermana-angular-component-carousel.d.ts +86 -1
  265. package/types/ojiepermana-angular-component-checkbox.d.ts +42 -1
  266. package/types/ojiepermana-angular-component-collapsible.d.ts +42 -1
  267. package/types/ojiepermana-angular-component-combobox.d.ts +60 -1
  268. package/types/ojiepermana-angular-component-command.d.ts +130 -1
  269. package/types/ojiepermana-angular-component-composer.d.ts +90 -1
  270. package/types/ojiepermana-angular-component-context-menu.d.ts +54 -1
  271. package/types/ojiepermana-angular-component-date-picker.d.ts +109 -1
  272. package/types/ojiepermana-angular-component-dialog.d.ts +136 -1
  273. package/types/ojiepermana-angular-component-drawer.d.ts +1 -1
  274. package/types/ojiepermana-angular-component-dropdown-menu.d.ts +248 -1
  275. package/types/ojiepermana-angular-component-editor.d.ts +135 -1
  276. package/types/ojiepermana-angular-component-empty.d.ts +50 -1
  277. package/types/ojiepermana-angular-component-form.d.ts +159 -1
  278. package/types/ojiepermana-angular-component-hover-card.d.ts +75 -1
  279. package/types/ojiepermana-angular-component-icon.d.ts +89 -1
  280. package/types/ojiepermana-angular-component-input-group.d.ts +51 -1
  281. package/types/ojiepermana-angular-component-input-otp.d.ts +155 -1
  282. package/types/ojiepermana-angular-component-input.d.ts +21 -1
  283. package/types/ojiepermana-angular-component-item.d.ts +93 -1
  284. package/types/ojiepermana-angular-component-kanban.d.ts +70 -1
  285. package/types/ojiepermana-angular-component-kbd.d.ts +16 -1
  286. package/types/ojiepermana-angular-component-label.d.ts +11 -1
  287. package/types/ojiepermana-angular-component-menubar.d.ts +93 -1
  288. package/types/ojiepermana-angular-component-native-select.d.ts +26 -1
  289. package/types/ojiepermana-angular-component-navigation-menu.d.ts +104 -1
  290. package/types/ojiepermana-angular-component-pagination.d.ts +33 -1
  291. package/types/ojiepermana-angular-component-pillbox.d.ts +222 -1
  292. package/types/ojiepermana-angular-component-popover.d.ts +66 -1
  293. package/types/ojiepermana-angular-component-progress.d.ts +17 -1
  294. package/types/ojiepermana-angular-component-radio.d.ts +60 -1
  295. package/types/ojiepermana-angular-component-resizable.d.ts +117 -1
  296. package/types/ojiepermana-angular-component-scroll-area.d.ts +19 -1
  297. package/types/ojiepermana-angular-component-segmented-control.d.ts +58 -1
  298. package/types/ojiepermana-angular-component-select.d.ts +122 -1
  299. package/types/ojiepermana-angular-component-separator.d.ts +14 -1
  300. package/types/ojiepermana-angular-component-sheet.d.ts +130 -1
  301. package/types/ojiepermana-angular-component-skeleton.d.ts +10 -1
  302. package/types/ojiepermana-angular-component-slider.d.ts +83 -1
  303. package/types/ojiepermana-angular-component-spinner.d.ts +13 -1
  304. package/types/ojiepermana-angular-component-switch.d.ts +44 -1
  305. package/types/ojiepermana-angular-component-table.d.ts +57 -1
  306. package/types/ojiepermana-angular-component-tabs.d.ts +124 -1
  307. package/types/ojiepermana-angular-component-textarea.d.ts +17 -1
  308. package/types/ojiepermana-angular-component-timeline.d.ts +64 -1
  309. package/types/ojiepermana-angular-component-toast.d.ts +64 -1
  310. package/types/ojiepermana-angular-component-toggle-group.d.ts +90 -1
  311. package/types/ojiepermana-angular-component-toggle.d.ts +25 -1
  312. package/types/ojiepermana-angular-component-tooltip.d.ts +143 -1
  313. package/types/ojiepermana-angular-component-utils-core.d.ts +184 -1
  314. package/types/ojiepermana-angular-component-utils-overlay.d.ts +21 -1
  315. package/types/ojiepermana-angular-component-utils-scale.d.ts +19 -1
  316. package/types/ojiepermana-angular-component-utils.d.ts +2 -1
  317. package/types/ojiepermana-angular-component.d.ts +2 -1
  318. package/types/ojiepermana-angular-navigation-core.d.ts +59 -1
  319. package/types/ojiepermana-angular-navigation-icon.d.ts +12 -1
  320. package/types/ojiepermana-angular-navigation-service.d.ts +116 -1
  321. package/types/ojiepermana-angular-navigation-types.d.ts +144 -1
  322. package/types/ojiepermana-angular-navigation.d.ts +507 -1
  323. package/types/ojiepermana-angular-sdk.d.ts +89 -1
  324. package/types/ojiepermana-angular-theme-component-settings.d.ts +154 -1
  325. package/types/ojiepermana-angular-theme-layout-services.d.ts +147 -1
  326. package/types/ojiepermana-angular-theme-layout-types.d.ts +40 -1
  327. package/types/ojiepermana-angular-theme-layout-wrapper.d.ts +299 -1
  328. package/types/ojiepermana-angular-theme-layout.d.ts +129 -1
  329. package/types/ojiepermana-angular-theme-page-core.d.ts +157 -1
  330. package/types/ojiepermana-angular-theme-page-filter.d.ts +77 -1
  331. package/types/ojiepermana-angular-theme-page-root.d.ts +88 -1
  332. package/types/ojiepermana-angular-theme-page-side.d.ts +50 -1
  333. package/types/ojiepermana-angular-theme-page-slots.d.ts +40 -1
  334. package/types/ojiepermana-angular-theme-page.d.ts +5 -1
  335. package/types/ojiepermana-angular-theme-shell-services.d.ts +193 -1
  336. package/types/ojiepermana-angular-theme-shell-types.d.ts +105 -1
  337. package/types/ojiepermana-angular-theme-shell.d.ts +100 -1
  338. package/types/ojiepermana-angular-theme-styles.d.ts +319 -1
  339. package/types/ojiepermana-angular-theme.d.ts +2 -1
  340. package/types/ojiepermana-angular.d.ts +5 -5
@@ -1,7 +1,729 @@
1
- export * from '@ojiepermana/angular-navigation/service';
1
+ import { DOCUMENT } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, signal, computed, isDevMode, Service } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { DefaultUrlSerializer, UrlTree, PRIMARY_OUTLET, Router, NavigationEnd } from '@angular/router';
6
+ import { documentLocalStorage } from '@ojiepermana/angular/component/utils/core';
2
7
 
3
- // Generated by scripts/gen-umbrella-entrypoints.mjs — do not edit by hand.
8
+ const DEFAULT_NAVIGATION_ID = 'default';
9
+ const PERSISTED_NAVIGATION_ID = 'main';
10
+ const INSTANCE_STORAGE_PROPERTIES = [
11
+ 'orientation',
12
+ 'appearance',
13
+ 'position',
14
+ 'collapsed',
15
+ 'dockbar-mode',
16
+ ];
17
+ const TYPE_MODE_STORAGE_KEY = 'nav-type-mode';
18
+ /** Resolves and persists the small navigation state contract without owning UI state. */
19
+ class NavigationPersistence {
20
+ documentRef;
21
+ /**
22
+ * The same never-throwing localStorage wrapper the theme axes use. It lives in
23
+ * `component/utils/core` rather than in the theme package precisely so this
24
+ * class can share it: navigation must not depend on theme, which already
25
+ * depends on navigation.
26
+ */
27
+ storageRef;
28
+ constructor(documentRef) {
29
+ this.documentRef = documentRef;
30
+ this.storageRef = documentLocalStorage(documentRef);
31
+ }
32
+ resolveState(input) {
33
+ const id = this.normalizeId(input.id);
34
+ const orientation = input.orientation;
35
+ const type = this.resolveType(id, orientation, input.type);
36
+ return {
37
+ id,
38
+ orientation,
39
+ type,
40
+ position: this.resolvePosition(id, orientation, input.position),
41
+ collapsed: this.resolveCollapsed(id, type, input.collapsed),
42
+ dockbarMode: this.resolveDockbarMode(id, type, input.dockbarMode),
43
+ };
44
+ }
45
+ persistState(state) {
46
+ if (state.id !== PERSISTED_NAVIGATION_ID) {
47
+ this.clearLegacyInstanceStorage(state.id);
48
+ return;
49
+ }
50
+ this.writeStorage(this.persistedStorageKey('orientation'), state.orientation);
51
+ this.writeStorage(this.persistedStorageKey('type'), state.type);
52
+ this.writeStorage(this.persistedStorageKey('position'), state.position);
53
+ this.writeStorage(TYPE_MODE_STORAGE_KEY, this.persistedTypeMode(state));
54
+ }
55
+ normalizeId(id) {
56
+ return id.trim() || DEFAULT_NAVIGATION_ID;
57
+ }
58
+ resolveType(id, orientation, type) {
59
+ if (this.isTypeForOrientation(type, orientation))
60
+ return type;
61
+ const stored = this.readInstanceStorage(id, 'type');
62
+ if (this.isTypeForOrientation(stored, orientation))
63
+ return stored;
64
+ return orientation === 'vertical' ? 'sidebar' : 'navbar';
65
+ }
66
+ resolvePosition(id, orientation, position) {
67
+ if (this.isPositionForOrientation(position, orientation))
68
+ return position;
69
+ const stored = this.readInstanceStorage(id, 'position');
70
+ if (this.isPositionForOrientation(stored, orientation))
71
+ return stored;
72
+ return orientation === 'horizontal' ? 'top' : 'left';
73
+ }
74
+ resolveCollapsed(id, type, collapsed) {
75
+ if (typeof collapsed === 'boolean')
76
+ return collapsed;
77
+ return type === 'sidebar' && this.readPersistedTypeMode(id) === 'collapsed';
78
+ }
79
+ resolveDockbarMode(id, type, mode) {
80
+ if (this.isDockbarMode(mode))
81
+ return mode;
82
+ if (type !== 'dockbar')
83
+ return 'sticky';
84
+ const stored = this.readPersistedTypeMode(id);
85
+ return this.isDockbarMode(stored) ? stored : 'sticky';
86
+ }
87
+ readStorage(key) {
88
+ return this.storageRef.read(key);
89
+ }
90
+ readInstanceStorage(id, property) {
91
+ return id === PERSISTED_NAVIGATION_ID
92
+ ? this.readStorage(this.persistedStorageKey(property))
93
+ : null;
94
+ }
95
+ readPersistedTypeMode(id) {
96
+ if (id !== PERSISTED_NAVIGATION_ID)
97
+ return null;
98
+ const stored = this.readStorage(TYPE_MODE_STORAGE_KEY);
99
+ return this.isPersistedTypeMode(stored) ? stored : null;
100
+ }
101
+ writeStorage(key, value) {
102
+ this.storageRef.write(key, value);
103
+ }
104
+ removeStorage(key) {
105
+ this.storageRef.remove(key);
106
+ }
107
+ clearLegacyInstanceStorage(id) {
108
+ for (const property of INSTANCE_STORAGE_PROPERTIES) {
109
+ this.removeStorage(`nav:${id}:${property}`);
110
+ }
111
+ }
112
+ persistedStorageKey(property) {
113
+ return `nav-${property}`;
114
+ }
115
+ persistedTypeMode(state) {
116
+ if (state.type === 'dockbar')
117
+ return state.dockbarMode;
118
+ return state.collapsed ? 'collapsed' : 'default';
119
+ }
120
+ isPersistedTypeMode(value) {
121
+ return value === 'default' || value === 'collapsed' || this.isDockbarMode(value);
122
+ }
123
+ isTypeForOrientation(value, orientation) {
124
+ return orientation === 'vertical'
125
+ ? value === 'sidebar' || value === 'dockbar'
126
+ : value === 'navbar' || value === 'flyout';
127
+ }
128
+ isPositionForOrientation(value, orientation) {
129
+ return orientation === 'vertical'
130
+ ? value === 'left' || value === 'right'
131
+ : value === 'top' || value === 'bottom';
132
+ }
133
+ isDockbarMode(value) {
134
+ return value === 'drawer' || value === 'sticky';
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Turns navigation items into `UrlTree`s and matches them against the active
140
+ * URL. Both halves are memoized: the active URL is parsed once per walk, and an
141
+ * item's own tree is cached against the item, because `Router.createUrlTree` is
142
+ * the expensive half and a plain absolute link resolves to the same tree for the
143
+ * life of that item. The cache is keyed by the normalized item, so it is
144
+ * discarded with the item the moment `normalizeUiNavItems` runs again.
145
+ */
146
+ class NavigationActiveUrlResolver {
147
+ router;
148
+ urlSerializer = new DefaultUrlSerializer();
149
+ itemUrlTrees = new WeakMap();
150
+ activeUrlTree = null;
151
+ constructor(router) {
152
+ this.router = router;
153
+ }
154
+ match(activeUrl, routerUrl, relativeTo) {
155
+ return { activeUrl, activeTree: this.parseActiveUrl(activeUrl), relativeTo, routerUrl };
156
+ }
157
+ matches(item, match, options) {
158
+ const activeTree = match.activeTree;
159
+ if (!item.link || item.externalLink || activeTree === null) {
160
+ return false;
161
+ }
162
+ const itemTree = this.cachedItemUrlTree(item, match, activeTree);
163
+ return itemTree === null ? false : containsNavigationUrlTree(activeTree, itemTree, options);
164
+ }
165
+ cachedItemUrlTree(item, match, activeTree) {
166
+ if (match.relativeTo !== null) {
167
+ return this.itemUrlTree(item, activeTree, match.relativeTo);
168
+ }
169
+ const key = this.dependsOnActiveUrl(item) ? `${match.activeUrl} ${match.routerUrl}` : null;
170
+ const cached = this.itemUrlTrees.get(item);
171
+ if (cached !== undefined && cached.key === key) {
172
+ return cached.tree;
173
+ }
174
+ const tree = this.itemUrlTree(item, activeTree, null);
175
+ this.itemUrlTrees.set(item, { key, tree });
176
+ return tree;
177
+ }
178
+ /** A relative or query/fragment-inheriting link resolves against the live URL. */
179
+ dependsOnActiveUrl(item) {
180
+ if (item.preserveFragment === true ||
181
+ item.queryParamsHandling === 'preserve' ||
182
+ item.queryParamsHandling === 'merge') {
183
+ return true;
184
+ }
185
+ const link = item.link;
186
+ if (link instanceof UrlTree) {
187
+ return false;
188
+ }
189
+ if (typeof link === 'string') {
190
+ return !link.startsWith('/');
191
+ }
192
+ const first = Array.isArray(link) ? link[0] : undefined;
193
+ return !(typeof first === 'string' && first.startsWith('/'));
194
+ }
195
+ parseActiveUrl(url) {
196
+ if (this.activeUrlTree !== null && this.activeUrlTree.url === url) {
197
+ return this.activeUrlTree.tree;
198
+ }
199
+ const tree = this.parseUrl(url);
200
+ this.activeUrlTree = { url, tree };
201
+ return tree;
202
+ }
203
+ itemUrlTree(item, activeTree, relativeTo) {
204
+ const link = item.link;
205
+ if (!link) {
206
+ return null;
207
+ }
208
+ if (link instanceof UrlTree) {
209
+ return link;
210
+ }
211
+ if (this.router !== null) {
212
+ try {
213
+ const commands = typeof link === 'string' ? [link] : Array.from(link);
214
+ return this.router.createUrlTree(commands, {
215
+ relativeTo,
216
+ queryParams: item.queryParams,
217
+ queryParamsHandling: item.queryParamsHandling,
218
+ fragment: item.fragment,
219
+ preserveFragment: item.preserveFragment,
220
+ });
221
+ }
222
+ catch {
223
+ return null;
224
+ }
225
+ }
226
+ const baseTree = typeof link === 'string' ? this.parseUrl(link) : null;
227
+ return baseTree === null ? null : this.applyRouteExtras(baseTree, item, activeTree);
228
+ }
229
+ applyRouteExtras(baseTree, item, activeTree) {
230
+ const handling = item.queryParamsHandling ?? 'replace';
231
+ let queryParams = baseTree.queryParams;
232
+ if (handling === 'preserve') {
233
+ queryParams = activeTree.queryParams;
234
+ }
235
+ else if (handling === 'merge') {
236
+ queryParams = { ...activeTree.queryParams, ...(item.queryParams ?? {}) };
237
+ }
238
+ else if (item.queryParams !== undefined) {
239
+ queryParams = item.queryParams ?? {};
240
+ }
241
+ const fragment = item.preserveFragment
242
+ ? activeTree.fragment
243
+ : (item.fragment ?? baseTree.fragment);
244
+ try {
245
+ // Serialize + parse normalizes numeric/array query values exactly as the
246
+ // Router does before applying IsActiveMatchOptions.
247
+ return this.urlSerializer.parse(this.urlSerializer.serialize(new UrlTree(baseTree.root, queryParams, fragment)));
248
+ }
249
+ catch {
250
+ return null;
251
+ }
252
+ }
253
+ parseUrl(url) {
254
+ try {
255
+ return this.router?.parseUrl(url) ?? this.urlSerializer.parse(url);
256
+ }
257
+ catch {
258
+ return null;
259
+ }
260
+ }
261
+ }
262
+ /** Pure equivalent of Router's UrlTree containment semantics for an explicit active URL. */
263
+ function containsNavigationUrlTree(container, containee, options) {
264
+ return (segmentGroupsMatch(container.root, containee.root, options.paths, options.matrixParams) &&
265
+ paramsMatch(container.queryParams, containee.queryParams, options.queryParams) &&
266
+ (options.fragment === 'ignored' || container.fragment === containee.fragment));
267
+ }
268
+ function segmentGroupsMatch(container, containee, paths, matrixParams) {
269
+ return paths === 'exact'
270
+ ? equalSegmentGroups(container, containee, matrixParams)
271
+ : containsSegmentGroup(container, containee, matrixParams);
272
+ }
273
+ function equalSegmentGroups(container, containee, matrixParams) {
274
+ if (!equalPaths(container.segments, containee.segments) ||
275
+ !matrixParamsMatch(container.segments, containee.segments, matrixParams) ||
276
+ container.numberOfChildren !== containee.numberOfChildren) {
277
+ return false;
278
+ }
279
+ return Object.entries(containee.children).every(([outlet, child]) => container.children[outlet] !== undefined &&
280
+ equalSegmentGroups(container.children[outlet], child, matrixParams));
281
+ }
282
+ function containsSegmentGroup(container, containee, matrixParams) {
283
+ return containsSegmentGroupPaths(container, containee, containee.segments, matrixParams);
284
+ }
285
+ function containsSegmentGroupPaths(container, containee, containeePaths, matrixParams) {
286
+ if (container.segments.length > containeePaths.length) {
287
+ const current = container.segments.slice(0, containeePaths.length);
288
+ return (equalPaths(current, containeePaths) &&
289
+ !containee.hasChildren() &&
290
+ matrixParamsMatch(current, containeePaths, matrixParams));
291
+ }
292
+ if (container.segments.length === containeePaths.length) {
293
+ if (!equalPaths(container.segments, containeePaths) ||
294
+ !matrixParamsMatch(container.segments, containeePaths, matrixParams)) {
295
+ return false;
296
+ }
297
+ return Object.entries(containee.children).every(([outlet, child]) => container.children[outlet] !== undefined &&
298
+ containsSegmentGroup(container.children[outlet], child, matrixParams));
299
+ }
300
+ const current = containeePaths.slice(0, container.segments.length);
301
+ const next = containeePaths.slice(container.segments.length);
302
+ const primary = container.children[PRIMARY_OUTLET];
303
+ return (equalPaths(container.segments, current) &&
304
+ matrixParamsMatch(container.segments, current, matrixParams) &&
305
+ primary !== undefined &&
306
+ containsSegmentGroupPaths(primary, containee, next, matrixParams));
307
+ }
308
+ function matrixParamsMatch(container, containee, strategy) {
309
+ return containee.every((segment, index) => paramsMatch(container[index]?.parameters ?? {}, segment.parameters, strategy));
310
+ }
311
+ function paramsMatch(container, containee, strategy) {
312
+ if (strategy === 'ignored') {
313
+ return true;
314
+ }
315
+ const containeeKeys = Object.keys(containee);
316
+ if (strategy === 'exact' && Object.keys(container).length !== containeeKeys.length) {
317
+ return false;
318
+ }
319
+ if (strategy === 'subset' && Object.keys(container).length < containeeKeys.length) {
320
+ return false;
321
+ }
322
+ return containeeKeys.every((key) => equalParamValue(container[key], containee[key]));
323
+ }
324
+ function equalParamValue(left, right) {
325
+ if (Array.isArray(left) && Array.isArray(right)) {
326
+ if (left.length !== right.length) {
327
+ return false;
328
+ }
329
+ const sortedLeft = [...left].sort();
330
+ const sortedRight = [...right].sort();
331
+ return sortedLeft.every((value, index) => value === sortedRight[index]);
332
+ }
333
+ return left === right;
334
+ }
335
+ function equalPaths(left, right) {
336
+ return (left.length === right.length &&
337
+ left.every((segment, index) => segment.path === right[index]?.path));
338
+ }
339
+
340
+ /** Referensi stabil untuk id yang belum punya data terdaftar (hindari array baru tiap evaluasi). */
341
+ const EMPTY_NAV_DATA = Object.freeze([]);
342
+ class NavigationService {
343
+ documentRef = inject(DOCUMENT, { optional: true });
344
+ persistence = new NavigationPersistence(this.documentRef);
345
+ router = inject(Router, { optional: true });
346
+ urlResolver = new NavigationActiveUrlResolver(this.router);
347
+ routerUrl = signal(this.router?.url ?? '/', /* @ts-ignore */
348
+ ...(ngDevMode ? [{ debugName: "routerUrl" }] : /* istanbul ignore next */ []));
349
+ states = signal({}, /* @ts-ignore */
350
+ ...(ngDevMode ? [{ debugName: "states" }] : /* istanbul ignore next */ []));
351
+ openPanelKeys = signal({}, /* @ts-ignore */
352
+ ...(ngDevMode ? [{ debugName: "openPanelKeys" }] : /* istanbul ignore next */ []));
353
+ drawerOpenState = signal({}, /* @ts-ignore */
354
+ ...(ngDevMode ? [{ debugName: "drawerOpenState" }] : /* istanbul ignore next */ []));
355
+ /** Data mentah per id, dipublikasikan oleh `<Navigation>` agar surface lain (mis. apps-launcher di `Page`) bisa membaca nav by id tanpa mendaftarkan ulang id yang sama. */
356
+ dataById = signal({}, /* @ts-ignore */
357
+ ...(ngDevMode ? [{ debugName: "dataById" }] : /* istanbul ignore next */ []));
358
+ /** Semua publisher hidup per data id. Publisher terakhir menjadi sumber aktif; cleanup owner lama tidak boleh menghapus publisher baru. */
359
+ dataPublishers = new Map();
360
+ /** Token stabil untuk pemanggil legacy yang tidak mengirim owner. */
361
+ ownerlessDataPublisher = {};
362
+ /** id navigasi → token owner instance, untuk menjaga setiap id hanya dipakai satu <Navigation> hidup. */
363
+ idOwners = new Map();
364
+ openPanelKey = computed(() => this.openPanelKeys()[DEFAULT_NAVIGATION_ID] ?? null, /* @ts-ignore */
365
+ ...(ngDevMode ? [{ debugName: "openPanelKey" }] : /* istanbul ignore next */ []));
366
+ /** Route aktif yang sudah dinormalisasi untuk consumer dockbar route-aware. */
367
+ routeContext = computed(() => {
368
+ const url = this.routerUrl();
369
+ return this.readRouteContext(url);
370
+ }, /* @ts-ignore */
371
+ ...(ngDevMode ? [{ debugName: "routeContext" }] : /* istanbul ignore next */ []));
372
+ exactMatchOptions = {
373
+ paths: 'exact',
374
+ queryParams: 'exact',
375
+ fragment: 'exact',
376
+ matrixParams: 'exact',
377
+ };
378
+ subsetMatchOptions = {
379
+ paths: 'subset',
380
+ queryParams: 'subset',
381
+ fragment: 'ignored',
382
+ matrixParams: 'ignored',
383
+ };
384
+ constructor() {
385
+ this.router?.events.pipe(takeUntilDestroyed()).subscribe((event) => {
386
+ if (event instanceof NavigationEnd) {
387
+ const previousUrl = this.routerUrl();
388
+ this.routerUrl.set(event.urlAfterRedirects);
389
+ if (this.urlPath(previousUrl) !== this.urlPath(event.urlAfterRedirects)) {
390
+ this.releasePanelsAfterNavigation();
391
+ }
392
+ }
393
+ });
394
+ }
395
+ /**
396
+ * Panel eksplisit (klik trigger rail/navbar) adalah state telusur sementara.
397
+ * Perpindahan path harus mengembalikan panel ke resolusi URL: tanpa pelepasan
398
+ * ini, dockbar sticky terkunci pada group lama sampai browser di-refresh,
399
+ * karena `resolveDockbarGroup` memprioritaskan panel key di atas pencocokan
400
+ * URL. Navigasi yang hanya mengubah query/fragment tidak melepas panel agar
401
+ * penelusuran group lain tidak tersentak oleh update background (mis. sort
402
+ * state yang ditulis ke query params).
403
+ */
404
+ releasePanelsAfterNavigation() {
405
+ this.openPanelKeys.update((state) => Object.values(state).some((key) => key !== null) ? {} : state);
406
+ }
407
+ urlPath(url) {
408
+ const end = url.search(/[?#]/);
409
+ return end === -1 ? url : url.slice(0, end);
410
+ }
411
+ readRouteContext(url) {
412
+ let snapshot = this.router?.routerState.snapshot.root ?? null;
413
+ let icon = null;
414
+ let badge = null;
415
+ let label = null;
416
+ while (snapshot !== null) {
417
+ const data = snapshot.data;
418
+ if (Object.prototype.hasOwnProperty.call(data, 'navigationIcon')) {
419
+ icon = this.optionalString(data.navigationIcon);
420
+ }
421
+ if (Object.prototype.hasOwnProperty.call(data, 'navigationBadge')) {
422
+ badge = this.optionalString(data.navigationBadge);
423
+ }
424
+ if (Object.prototype.hasOwnProperty.call(data, 'navigationLabel')) {
425
+ label = this.optionalString(data.navigationLabel);
426
+ }
427
+ else if (snapshot.title) {
428
+ label = snapshot.title;
429
+ }
430
+ snapshot =
431
+ snapshot.children.find((child) => child.outlet === PRIMARY_OUTLET) ??
432
+ snapshot.firstChild ??
433
+ null;
434
+ }
435
+ return { url, icon, badge, label };
436
+ }
437
+ optionalString(value) {
438
+ return typeof value === 'string' && value.trim() ? value.trim() : null;
439
+ }
440
+ register(input, owner) {
441
+ const state = this.persistence.resolveState(input);
442
+ this.claimId(state.id, owner);
443
+ this.states.update((states) => ({ ...states, [state.id]: state }));
444
+ this.persistence.persistState(state);
445
+ return state;
446
+ }
447
+ unregister(id, owner) {
448
+ const navId = this.persistence.normalizeId(id);
449
+ this.releaseId(navId, owner);
450
+ this.states.update((states) => this.withoutKey(states, navId));
451
+ this.openPanelKeys.update((state) => this.withoutKey(state, navId));
452
+ this.drawerOpenState.update((state) => this.withoutKey(state, navId));
453
+ }
454
+ /**
455
+ * Validasi keunikan id navigasi: setiap instance `<Navigation>` wajib memakai id unik.
456
+ * `owner` adalah token unik per instance — klaim ulang oleh owner yang sama (mis. perubahan
457
+ * input) diizinkan, tetapi dua instance hidup dengan id sama dianggap salah konfigurasi dan
458
+ * melempar error di mode dev. Pemanggil tanpa owner (akses langsung service) dilewati.
459
+ */
460
+ claimId(id, owner) {
461
+ if (owner === undefined) {
462
+ return;
463
+ }
464
+ const currentOwner = this.idOwners.get(id);
465
+ if (currentOwner !== undefined && currentOwner !== owner && isDevMode()) {
466
+ throw new Error(`[Navigation] Duplikasi id navigasi "${id}". Setiap <Navigation> wajib memakai id unik. ` +
467
+ `Id "main" dikhususkan untuk navigasi utama pada layout/shell (block-shell).`);
468
+ }
469
+ this.idOwners.set(id, owner);
470
+ }
471
+ releaseId(id, owner) {
472
+ if (owner === undefined || this.idOwners.get(id) === owner) {
473
+ this.idOwners.delete(id);
474
+ }
475
+ }
476
+ state(id) {
477
+ const navId = this.persistence.normalizeId(id);
478
+ return computed(() => this.states()[navId] ?? null);
479
+ }
480
+ currentState(id) {
481
+ return this.states()[this.persistence.normalizeId(id)] ?? null;
482
+ }
483
+ /** Data terdaftar untuk sebuah id sebagai signal; `[]` bila belum ada `<Navigation>` dengan id tersebut. */
484
+ data(id) {
485
+ const navId = this.persistence.normalizeId(id);
486
+ return computed(() => this.dataById()[navId] ?? EMPTY_NAV_DATA);
487
+ }
488
+ /** Dipanggil `<Navigation>` untuk mempublikasikan datanya ke registry by id. */
489
+ publishData(id, data, owner) {
490
+ const navId = this.persistence.normalizeId(id);
491
+ const publisher = owner ?? this.ownerlessDataPublisher;
492
+ const publishers = this.dataPublishers.get(navId) ?? new Map();
493
+ // Map mempertahankan insertion order. Re-publish oleh owner yang sama harus menjadi
494
+ // publisher terbaru agar data input yang berubah langsung menjadi sumber aktif.
495
+ publishers.delete(publisher);
496
+ publishers.set(publisher, data);
497
+ this.dataPublishers.set(navId, publishers);
498
+ this.dataById.update((map) => ({ ...map, [navId]: data }));
499
+ }
500
+ /** Dipanggil `<Navigation>` saat destroy untuk melepas datanya dari registry. */
501
+ clearData(id, owner) {
502
+ const navId = this.persistence.normalizeId(id);
503
+ const publisher = owner ?? this.ownerlessDataPublisher;
504
+ const publishers = this.dataPublishers.get(navId);
505
+ if (!publishers?.delete(publisher)) {
506
+ return;
507
+ }
508
+ const remaining = Array.from(publishers.values());
509
+ const fallback = remaining.at(-1);
510
+ if (fallback) {
511
+ this.dataById.update((map) => ({ ...map, [navId]: fallback }));
512
+ return;
513
+ }
514
+ this.dataPublishers.delete(navId);
515
+ this.dataById.update((map) => this.withoutKey(map, navId));
516
+ }
517
+ currentPanelKey(id) {
518
+ return this.openPanelKeys()[this.persistence.normalizeId(id)] ?? null;
519
+ }
520
+ update(id, patch) {
521
+ const navId = this.persistence.normalizeId(id);
522
+ const current = this.states()[navId] ??
523
+ this.persistence.resolveState({ id: navId, orientation: patch.orientation ?? 'vertical' });
524
+ return this.register({
525
+ id: navId,
526
+ orientation: patch.orientation ?? current.orientation,
527
+ type: patch.type ?? current.type,
528
+ position: patch.position ?? current.position,
529
+ collapsed: patch.collapsed ?? current.collapsed,
530
+ dockbarMode: patch.dockbarMode ?? current.dockbarMode,
531
+ });
532
+ }
533
+ setType(id, type) {
534
+ return this.update(id, { type });
535
+ }
536
+ setPosition(id, position) {
537
+ return this.update(id, { position });
538
+ }
539
+ setCollapsed(id, collapsed) {
540
+ return this.update(id, { collapsed });
541
+ }
542
+ toggleCollapsed(id) {
543
+ const navId = this.persistence.normalizeId(id);
544
+ const current = this.states()[navId] ?? this.persistence.resolveState({ id: navId, orientation: 'vertical' });
545
+ return this.setCollapsed(navId, !current.collapsed);
546
+ }
547
+ setDockbarMode(id, mode) {
548
+ return this.update(id, { dockbarMode: mode });
549
+ }
550
+ isRouterItem(item) {
551
+ return !!item.link && !item.externalLink;
552
+ }
553
+ hrefFor(item) {
554
+ if (item.href) {
555
+ return item.href;
556
+ }
557
+ if (item.externalLink && typeof item.link === 'string') {
558
+ return item.link;
559
+ }
560
+ return null;
561
+ }
562
+ /**
563
+ * A consumer `rel` is unioned with the safe default rather than replacing it:
564
+ * returning `rel="external"` verbatim on a `_blank` link dropped `noopener`
565
+ * and handed the opened page a live `window.opener`.
566
+ */
567
+ relFor(item) {
568
+ const consumerTokens = item.rel?.split(/\s+/).filter(Boolean) ?? [];
569
+ if (item.target !== '_blank' && !item.externalLink) {
570
+ return consumerTokens.length > 0 ? consumerTokens.join(' ') : null;
571
+ }
572
+ const tokens = new Set(consumerTokens);
573
+ tokens.add('noopener');
574
+ tokens.add('noreferrer');
575
+ return [...tokens].join(' ');
576
+ }
577
+ routerLinkActiveOptions(item) {
578
+ return (item.isActiveMatchOptions ??
579
+ (item.exactMatch ? this.exactMatchOptions : this.subsetMatchOptions));
580
+ }
581
+ itemRole(orientation, level) {
582
+ void level;
583
+ // Horizontal navs are menubars/menus (arrow-key roving) → menuitem. Vertical
584
+ // navs are plain lists of links (tab navigation, no menu keyboard model), so
585
+ // their items must NOT be menuitems — a menuitem inside a `list` is an invalid
586
+ // ARIA parent (axe `aria-required-parent`).
587
+ return orientation === 'horizontal' ? 'menuitem' : null;
588
+ }
589
+ compactLabel(item, compact) {
590
+ return compact ? (item.tooltip ?? item.title ?? null) : null;
591
+ }
592
+ titleFor(item, compact) {
593
+ return item.tooltip ?? (compact ? (item.title ?? null) : null);
594
+ }
595
+ compactFallback(item) {
596
+ return (item.title ?? item.id ?? '?').trim().slice(0, 2);
597
+ }
598
+ iconContext(item, active, level, orientation) {
599
+ return {
600
+ $implicit: item.icon ?? '',
601
+ icon: item.icon ?? '',
602
+ item: item.source,
603
+ active,
604
+ orientation,
605
+ level,
606
+ };
607
+ }
608
+ isItemActive(item, activeIds, explicitActiveUrl) {
609
+ return this.matchesActiveTreeDeep(item, activeIds, this.activeMatch(explicitActiveUrl, null));
610
+ }
611
+ /**
612
+ * Pencocokan route murni untuk state dockbar berbasis Router. Berbeda dari
613
+ * `isItemActive`, konfigurasi legacy `item.active` dan `activeIds` sengaja
614
+ * tidak ikut menentukan group route aktif.
615
+ */
616
+ isItemRouteActive(item, explicitActiveUrl, relativeTo = null) {
617
+ return this.matchesActiveTreeDeep(item, null, this.activeMatch(explicitActiveUrl, relativeTo));
618
+ }
619
+ matchesActiveTreeDeep(item, activeIds, match) {
620
+ if (activeIds !== null &&
621
+ (item.active || activeIds.has(item.stateId) || activeIds.has(item.key))) {
622
+ return true;
623
+ }
624
+ if (this.matchesActiveTree(item, match)) {
625
+ return true;
626
+ }
627
+ return item.children.some((child) => this.matchesActiveTreeDeep(child, activeIds, match));
628
+ }
629
+ /**
630
+ * The active URL is parsed once per top-level call and handed down the
631
+ * recursion; re-parsing it at every node turned one navigation into hundreds
632
+ * of identical `parseUrl` calls.
633
+ */
634
+ activeMatch(explicitActiveUrl, relativeTo) {
635
+ // Always read the signal so computed callers invalidate on NavigationEnd,
636
+ // even when Router.url is the fresher synchronous value.
637
+ const cachedUrl = this.routerUrl();
638
+ const activeUrl = explicitActiveUrl ?? this.router?.url ?? cachedUrl;
639
+ return this.urlResolver.match(activeUrl, this.router?.url ?? cachedUrl, relativeTo);
640
+ }
641
+ isPanelOpen(navIdOrItem, item) {
642
+ const { navId, navItem } = this.resolvePanelArgs('isPanelOpen', navIdOrItem, item);
643
+ return this.openPanelKeys()[navId] === navItem.key;
644
+ }
645
+ openPanel(navIdOrItem, item) {
646
+ const { navId, navItem } = this.resolvePanelArgs('openPanel', navIdOrItem, item);
647
+ if (navItem.disabled) {
648
+ return;
649
+ }
650
+ this.openPanelKeys.update((state) => ({ ...state, [navId]: navItem.key }));
651
+ }
652
+ togglePanel(navIdOrItem, item) {
653
+ const { navId, navItem } = this.resolvePanelArgs('togglePanel', navIdOrItem, item);
654
+ if (navItem.disabled) {
655
+ return;
656
+ }
657
+ this.openPanelKeys.update((state) => ({
658
+ ...state,
659
+ [navId]: state[navId] === navItem.key ? null : navItem.key,
660
+ }));
661
+ }
662
+ closePanel(id = DEFAULT_NAVIGATION_ID) {
663
+ const navId = this.persistence.normalizeId(id);
664
+ this.openPanelKeys.update((state) => ({ ...state, [navId]: null }));
665
+ }
666
+ dockbarGroups(items) {
667
+ return items.filter((item) => item.children.length > 0);
668
+ }
669
+ resolveDockbarGroup(id, items, mode, activeIds, activeUrl) {
670
+ const groups = this.dockbarGroups(items);
671
+ const panelKey = this.openPanelKeys()[this.persistence.normalizeId(id)] ?? null;
672
+ if (panelKey !== null) {
673
+ const explicit = groups.find((group) => group.key === panelKey);
674
+ if (explicit) {
675
+ return explicit;
676
+ }
677
+ }
678
+ if (mode !== 'sticky') {
679
+ return null;
680
+ }
681
+ return groups.find((group) => this.isItemActive(group, activeIds, activeUrl)) ?? null;
682
+ }
683
+ isDrawerOpen(id) {
684
+ return this.drawerOpenState()[this.persistence.normalizeId(id)] ?? false;
685
+ }
686
+ openDrawer(id) {
687
+ const navId = this.persistence.normalizeId(id);
688
+ this.drawerOpenState.update((state) => ({ ...state, [navId]: true }));
689
+ }
690
+ toggleDrawer(id) {
691
+ const navId = this.persistence.normalizeId(id);
692
+ this.drawerOpenState.update((state) => ({ ...state, [navId]: !(state[navId] ?? false) }));
693
+ }
694
+ closeDrawer(id) {
695
+ const navId = this.persistence.normalizeId(id);
696
+ this.drawerOpenState.update((state) => ({ ...state, [navId]: false }));
697
+ }
698
+ matchesActiveTree(item, match) {
699
+ return this.urlResolver.matches(item, match, this.routerLinkActiveOptions(item));
700
+ }
701
+ withoutKey(record, key) {
702
+ const next = { ...record };
703
+ delete next[key];
704
+ return next;
705
+ }
706
+ resolvePanelArgs(method, navIdOrItem, item) {
707
+ if (typeof navIdOrItem === 'string') {
708
+ if (item === undefined) {
709
+ throw new Error(`[Navigation] ${method}(navId, item) membutuhkan item navigasi sebagai argumen kedua.`);
710
+ }
711
+ return {
712
+ navId: this.persistence.normalizeId(navIdOrItem),
713
+ navItem: item,
714
+ };
715
+ }
716
+ return { navId: DEFAULT_NAVIGATION_ID, navItem: navIdOrItem };
717
+ }
718
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationService, deps: [], target: i0.ɵɵFactoryTarget.Service });
719
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.4", ngImport: i0, type: NavigationService });
720
+ }
721
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationService, decorators: [{
722
+ type: Service
723
+ }], ctorParameters: () => [] });
4
724
 
5
725
  /**
6
726
  * Generated bundle index. Do not edit.
7
- */
727
+ */
728
+
729
+ export { NavigationService };