@ojiepermana/angular 22.1.11 → 22.1.13

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 +374 -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
@@ -0,0 +1,2642 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, signal, computed, effect, InjectionToken, input, model, output, contentChild, isDevMode, forwardRef, Component, DestroyRef, booleanAttribute, TemplateRef, Directive, ElementRef, Injector, afterNextRender, ViewContainerRef } from '@angular/core';
3
+ import { ActivatedRoute, RouterLink, RouterLinkActive } from '@angular/router';
4
+ import { cn } from '@ojiepermana/angular/component/utils/core';
5
+ import { NavigationIconDirective } from '@ojiepermana/angular/navigation/icon';
6
+ import { NAVIGATION_ADAPTER, NAVIGATION_ROUTE_CONTEXT_ADAPTER } from '@ojiepermana/angular/navigation/core';
7
+ import { normalizeUiNavItems, NAVIGATION_DOCKBAR_FALLBACK_ICON } from '@ojiepermana/angular/navigation/types';
8
+ import { NgTemplateOutlet } from '@angular/common';
9
+ import { IconComponent } from '@ojiepermana/angular/component/icon';
10
+
11
+ function injectNavigationController(inputs) {
12
+ const nav = inject(NAVIGATION_ADAPTER);
13
+ // Token unik per instance <Navigation> untuk validasi keunikan id di NavigationService.
14
+ const owner = {};
15
+ const registeredState = signal(null, /* @ts-ignore */
16
+ ...(ngDevMode ? [{ debugName: "registeredState" }] : /* istanbul ignore next */ []));
17
+ const normalizedNavId = computed(() => normalizeId(inputs.navId()), /* @ts-ignore */
18
+ ...(ngDevMode ? [{ debugName: "normalizedNavId" }] : /* istanbul ignore next */ []));
19
+ const collapsedPreference = computed(() => inputs.collapsed() ?? (inputs.compact() ? true : null), /* @ts-ignore */
20
+ ...(ngDevMode ? [{ debugName: "collapsedPreference" }] : /* istanbul ignore next */ []));
21
+ const normalizedItems = computed(() => normalizeUiNavItems(inputs.data()), /* @ts-ignore */
22
+ ...(ngDevMode ? [{ debugName: "normalizedItems" }] : /* istanbul ignore next */ []));
23
+ const fallbackState = computed(() => ({
24
+ id: normalizedNavId(),
25
+ orientation: inputs.orientation(),
26
+ type: fallbackType(inputs.orientation(), inputs.type()),
27
+ position: inputs.position() ?? (inputs.orientation() === 'horizontal' ? 'top' : 'left'),
28
+ collapsed: collapsedPreference() ?? false,
29
+ dockbarMode: inputs.dockbarMode() ?? 'sticky',
30
+ }), /* @ts-ignore */
31
+ ...(ngDevMode ? [{ debugName: "fallbackState" }] : /* istanbul ignore next */ []));
32
+ const resolvedState = computed(() => nav.currentState(normalizedNavId()) ?? registeredState() ?? fallbackState(), /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "resolvedState" }] : /* istanbul ignore next */ []));
34
+ const activeIdSet = computed(() => {
35
+ const ids = inputs.activeIds();
36
+ if (!ids) {
37
+ return new Set();
38
+ }
39
+ return ids instanceof Set ? new Set(ids) : new Set(ids);
40
+ }, /* @ts-ignore */
41
+ ...(ngDevMode ? [{ debugName: "activeIdSet" }] : /* istanbul ignore next */ []));
42
+ effect((onCleanup) => {
43
+ if (!inputs.enabled()) {
44
+ return;
45
+ }
46
+ const nextState = nav.register({
47
+ id: normalizedNavId(),
48
+ orientation: inputs.orientation(),
49
+ type: inputs.type(),
50
+ position: inputs.position(),
51
+ collapsed: collapsedPreference(),
52
+ dockbarMode: inputs.dockbarMode(),
53
+ }, owner);
54
+ registeredState.set(nextState);
55
+ onCleanup(() => nav.unregister(nextState.id, owner));
56
+ });
57
+ return {
58
+ normalizedNavId,
59
+ normalizedItems,
60
+ resolvedState,
61
+ activeIdSet,
62
+ toggleCollapsed: () => nav.toggleCollapsed(normalizedNavId()),
63
+ };
64
+ }
65
+ function normalizeId(value) {
66
+ return value.trim() || 'default';
67
+ }
68
+ function fallbackType(orientation, type) {
69
+ if (orientation === 'vertical' && (type === 'sidebar' || type === 'dockbar')) {
70
+ return type;
71
+ }
72
+ if (orientation === 'horizontal' && (type === 'navbar' || type === 'flyout')) {
73
+ return type;
74
+ }
75
+ return orientation === 'horizontal' ? 'navbar' : 'sidebar';
76
+ }
77
+
78
+ const NAVIGATION_SHELL = new InjectionToken('NAVIGATION_SHELL');
79
+
80
+ const EMPTY_NAVIGATION_BADGE_CONTEXT$1 = Object.freeze({});
81
+ const EMPTY_NAVIGATION_ACTIVE_IDS = new Set();
82
+ /**
83
+ * Container navigasi deklaratif. Type ditentukan oleh komponen anak:
84
+ *
85
+ * ```html
86
+ * <Navigation id="main" [data]="items">
87
+ * <NavigationSidebar>
88
+ * <NavigationHeader>…</NavigationHeader>
89
+ * <NavigationContent />
90
+ * <NavigationFooter>…</NavigationFooter>
91
+ * </NavigationSidebar>
92
+ * </Navigation>
93
+ * ```
94
+ *
95
+ * Header dan footer opsional; `NavigationContent` selalu dirender oleh
96
+ * type (default otomatis bila tidak diproyeksikan).
97
+ */
98
+ class NavigationContainerComponent {
99
+ navId = input('default', { ...(ngDevMode ? { debugName: "navId" } : /* istanbul ignore next */ {}), alias: 'id' });
100
+ /** Id data publik dapat dipisahkan dari id state. Berguna untuk mirror mobile tanpa berbagi persistence state. */
101
+ dataId = input(null, { ...(ngDevMode ? { debugName: "dataId" } : /* istanbul ignore next */ {}), alias: 'data-id' });
102
+ data = input([], /* @ts-ignore */
103
+ ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
104
+ ariaLabel = input('Primary navigation', /* @ts-ignore */
105
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
106
+ compact = input(false, /* @ts-ignore */
107
+ ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
108
+ collapseTree = input('stairs', { ...(ngDevMode ? { debugName: "collapseTree" } : /* istanbul ignore next */ {}), alias: 'collapse-tree' });
109
+ class = input('', /* @ts-ignore */
110
+ ...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
111
+ itemClass = input('', /* @ts-ignore */
112
+ ...(ngDevMode ? [{ debugName: "itemClass" }] : /* istanbul ignore next */ []));
113
+ /** Kelas Tailwind untuk container `<li>` group horizontal (flyout tab / navbar group). */
114
+ groupClass = input('', { ...(ngDevMode ? { debugName: "groupClass" } : /* istanbul ignore next */ {}), alias: 'nav-group-class' });
115
+ activeIds = input(null, /* @ts-ignore */
116
+ ...(ngDevMode ? [{ debugName: "activeIds" }] : /* istanbul ignore next */ []));
117
+ activeUrl = input(null, /* @ts-ignore */
118
+ ...(ngDevMode ? [{ debugName: "activeUrl" }] : /* istanbul ignore next */ []));
119
+ openedIds = model([], /* @ts-ignore */
120
+ ...(ngDevMode ? [{ debugName: "openedIds" }] : /* istanbul ignore next */ []));
121
+ itemSelected = output();
122
+ nav = inject(NAVIGATION_ADAPTER);
123
+ routeContextAdapter = inject(NAVIGATION_ROUTE_CONTEXT_ADAPTER);
124
+ activatedRoute = inject(ActivatedRoute, { optional: true });
125
+ dataOwner = {};
126
+ hoverPreviewExpanded = signal(false, /* @ts-ignore */
127
+ ...(ngDevMode ? [{ debugName: "hoverPreviewExpanded" }] : /* istanbul ignore next */ []));
128
+ /**
129
+ * Keyboard twin of the hover preview: a collapsed rail hides the children of
130
+ * every collapsible, so without this the only way into a nested route is a
131
+ * pointer hovering the rail.
132
+ */
133
+ focusPreviewExpanded = signal(false, /* @ts-ignore */
134
+ ...(ngDevMode ? [{ debugName: "focusPreviewExpanded" }] : /* istanbul ignore next */ []));
135
+ /** Konfigurasi type aktif yang didaftarkan wrapper anak (sidebar/dockbar/navbar/flyout). */
136
+ typeConfig = signal(null, /* @ts-ignore */
137
+ ...(ngDevMode ? [{ debugName: "typeConfig" }] : /* istanbul ignore next */ []));
138
+ orientationPreference = computed(() => this.typeConfig()?.orientation ?? 'vertical', /* @ts-ignore */
139
+ ...(ngDevMode ? [{ debugName: "orientationPreference" }] : /* istanbul ignore next */ []));
140
+ typePreference = computed(() => this.typeConfig()?.type ?? null, /* @ts-ignore */
141
+ ...(ngDevMode ? [{ debugName: "typePreference" }] : /* istanbul ignore next */ []));
142
+ positionPreference = computed(() => this.typeConfig()?.position?.() ?? null, /* @ts-ignore */
143
+ ...(ngDevMode ? [{ debugName: "positionPreference" }] : /* istanbul ignore next */ []));
144
+ collapsedPreference = computed(() => this.typeConfig()?.collapsed?.() ?? null, /* @ts-ignore */
145
+ ...(ngDevMode ? [{ debugName: "collapsedPreference" }] : /* istanbul ignore next */ []));
146
+ dockbarModePreference = computed(() => this.typeConfig()?.dockbarMode?.() ?? null, /* @ts-ignore */
147
+ ...(ngDevMode ? [{ debugName: "dockbarModePreference" }] : /* istanbul ignore next */ []));
148
+ dockbarRouteContextPreference = computed(() => this.typeConfig()?.dockbarRouteContext?.() ?? null, /* @ts-ignore */
149
+ ...(ngDevMode ? [{ debugName: "dockbarRouteContextPreference" }] : /* istanbul ignore next */ []));
150
+ dockbarBadgeContext = computed(() => this.typeConfig()?.dockbarBadgeContext?.() ?? EMPTY_NAVIGATION_BADGE_CONTEXT$1, /* @ts-ignore */
151
+ ...(ngDevMode ? [{ debugName: "dockbarBadgeContext" }] : /* istanbul ignore next */ []));
152
+ dockbarRouteHeaderVisible = computed(() => this.typeConfig()?.dockbarRouteHeaderVisible?.() ?? false, /* @ts-ignore */
153
+ ...(ngDevMode ? [{ debugName: "dockbarRouteHeaderVisible" }] : /* istanbul ignore next */ []));
154
+ /** Template footer aside dockbar dari slot `ng-template[NavigationAsideFooter]`. */
155
+ dockbarAsideFooter = computed(() => this.typeConfig()?.dockbarAsideFooter?.() ?? null, /* @ts-ignore */
156
+ ...(ngDevMode ? [{ debugName: "dockbarAsideFooter" }] : /* istanbul ignore next */ []));
157
+ sidebarCollapse = computed(() => this.typeConfig()?.sidebarCollapse?.() ?? false, /* @ts-ignore */
158
+ ...(ngDevMode ? [{ debugName: "sidebarCollapse" }] : /* istanbul ignore next */ []));
159
+ previewExpanded = computed(() => this.typeConfig()?.previewExpanded?.() ?? false, /* @ts-ignore */
160
+ ...(ngDevMode ? [{ debugName: "previewExpanded" }] : /* istanbul ignore next */ []));
161
+ typeStyle = computed(() => this.typeConfig()?.typeStyle?.() ?? 'flat', /* @ts-ignore */
162
+ ...(ngDevMode ? [{ debugName: "typeStyle" }] : /* istanbul ignore next */ []));
163
+ flyoutLabel = computed(() => this.typeConfig()?.flyoutLabel?.() ?? 'Menu', /* @ts-ignore */
164
+ ...(ngDevMode ? [{ debugName: "flyoutLabel" }] : /* istanbul ignore next */ []));
165
+ flyoutIcon = computed(() => this.typeConfig()?.flyoutIcon?.() ?? null, /* @ts-ignore */
166
+ ...(ngDevMode ? [{ debugName: "flyoutIcon" }] : /* istanbul ignore next */ []));
167
+ flyoutIconOnly = computed(() => this.typeConfig()?.flyoutIconOnly?.() ?? false, /* @ts-ignore */
168
+ ...(ngDevMode ? [{ debugName: "flyoutIconOnly" }] : /* istanbul ignore next */ []));
169
+ flyoutIconPosition = computed(() => this.typeConfig()?.flyoutIconPosition?.() ?? 'start', /* @ts-ignore */
170
+ ...(ngDevMode ? [{ debugName: "flyoutIconPosition" }] : /* istanbul ignore next */ []));
171
+ flyoutTriggerVariant = computed(() => this.typeConfig()?.flyoutTriggerVariant?.() ?? 'button', /* @ts-ignore */
172
+ ...(ngDevMode ? [{ debugName: "flyoutTriggerVariant" }] : /* istanbul ignore next */ []));
173
+ flyoutTriggerFloating = computed(() => this.typeConfig()?.flyoutTriggerFloating?.() ?? false, /* @ts-ignore */
174
+ ...(ngDevMode ? [{ debugName: "flyoutTriggerFloating" }] : /* istanbul ignore next */ []));
175
+ flyoutPanelViewport = computed(() => this.typeConfig()?.flyoutPanelViewport?.() ?? false, /* @ts-ignore */
176
+ ...(ngDevMode ? [{ debugName: "flyoutPanelViewport" }] : /* istanbul ignore next */ []));
177
+ flyoutTriggerClass = computed(() => this.typeConfig()?.flyoutTriggerClass?.() ?? '', /* @ts-ignore */
178
+ ...(ngDevMode ? [{ debugName: "flyoutTriggerClass" }] : /* istanbul ignore next */ []));
179
+ flyoutTriggerButtonClass = computed(() => this.typeConfig()?.flyoutTriggerButtonClass?.() ?? '', /* @ts-ignore */
180
+ ...(ngDevMode ? [{ debugName: "flyoutTriggerButtonClass" }] : /* istanbul ignore next */ []));
181
+ controller = injectNavigationController({
182
+ navId: this.navId,
183
+ data: this.data,
184
+ orientation: this.orientationPreference,
185
+ type: this.typePreference,
186
+ position: this.positionPreference,
187
+ collapsed: this.collapsedPreference,
188
+ dockbarMode: this.dockbarModePreference,
189
+ compact: this.compact,
190
+ activeIds: this.activeIds,
191
+ enabled: computed(() => this.typeConfig() !== null),
192
+ });
193
+ iconTemplate = contentChild(NavigationIconDirective, /* @ts-ignore */
194
+ ...(ngDevMode ? [{ debugName: "iconTemplate" }] : /* istanbul ignore next */ []));
195
+ normalizedItems = this.controller.normalizedItems;
196
+ resolvedState = this.controller.resolvedState;
197
+ activeIdSet = this.controller.activeIdSet;
198
+ dockbarRouteEnabled = computed(() => {
199
+ const context = this.dockbarRouteContextPreference();
200
+ return context !== null && context !== false;
201
+ }, /* @ts-ignore */
202
+ ...(ngDevMode ? [{ debugName: "dockbarRouteEnabled" }] : /* istanbul ignore next */ []));
203
+ dockbarResolvedRouteContext = computed(() => {
204
+ const automatic = this.routeContextAdapter.routeContext();
205
+ const config = this.dockbarRouteConfig();
206
+ return {
207
+ url: this.cleanString(config.url) ?? this.activeUrl() ?? automatic.url,
208
+ icon: config.icon === undefined ? automatic.icon : this.cleanString(config.icon),
209
+ badge: config.badge === undefined ? automatic.badge : this.cleanString(config.badge),
210
+ label: config.label === undefined ? automatic.label : this.cleanString(config.label),
211
+ };
212
+ }, /* @ts-ignore */
213
+ ...(ngDevMode ? [{ debugName: "dockbarResolvedRouteContext" }] : /* istanbul ignore next */ []));
214
+ dockbarActiveRouteEntry = computed(() => {
215
+ if (!this.dockbarRouteEnabled()) {
216
+ return null;
217
+ }
218
+ const activeUrl = this.dockbarResolvedRouteContext().url;
219
+ return (this.normalizedItems().find((entry) => this.routeContextAdapter.isItemRouteActive(entry, activeUrl, this.activatedRoute)) ?? null);
220
+ }, /* @ts-ignore */
221
+ ...(ngDevMode ? [{ debugName: "dockbarActiveRouteEntry" }] : /* istanbul ignore next */ []));
222
+ dockbarResolvedActiveIds = computed(() => this.dockbarRouteEnabled() ? EMPTY_NAVIGATION_ACTIVE_IDS : this.activeIdSet(), /* @ts-ignore */
223
+ ...(ngDevMode ? [{ debugName: "dockbarResolvedActiveIds" }] : /* istanbul ignore next */ []));
224
+ dockbarActiveRoutePanelGroup = computed(() => {
225
+ const entry = this.dockbarActiveRouteEntry();
226
+ return entry && entry.children.length > 0 ? entry : null;
227
+ }, /* @ts-ignore */
228
+ ...(ngDevMode ? [{ debugName: "dockbarActiveRoutePanelGroup" }] : /* istanbul ignore next */ []));
229
+ dockbarRouteHeader = computed(() => {
230
+ if (!this.dockbarRouteEnabled()) {
231
+ return null;
232
+ }
233
+ const activeEntry = this.dockbarActiveRouteEntry();
234
+ const route = this.dockbarResolvedRouteContext();
235
+ const fallbackIcon = this.cleanString(this.dockbarRouteConfig().fallbackIcon) ?? NAVIGATION_DOCKBAR_FALLBACK_ICON;
236
+ const icon = activeEntry
237
+ ? (this.cleanString(activeEntry.icon) ?? fallbackIcon)
238
+ : (route.icon ?? fallbackIcon);
239
+ const label = this.cleanString(activeEntry?.title) ?? route.label ?? 'Current navigation route';
240
+ const badgeKey = activeEntry?.badge?.source ?? route.badge;
241
+ const badge = badgeKey ? (this.dockbarBadgeContext()[badgeKey] ?? null) : null;
242
+ const item = activeEntry?.source ?? { title: label, icon };
243
+ return {
244
+ activeEntry,
245
+ panelGroup: this.dockbarActiveRoutePanelGroup(),
246
+ icon,
247
+ label,
248
+ badge,
249
+ badgeClass: cn('absolute -right-1 -top-1', activeEntry?.badge?.classes),
250
+ iconContext: {
251
+ $implicit: icon,
252
+ icon,
253
+ item,
254
+ active: true,
255
+ orientation: 'vertical',
256
+ level: 0,
257
+ },
258
+ };
259
+ }, /* @ts-ignore */
260
+ ...(ngDevMode ? [{ debugName: "dockbarRouteHeader" }] : /* istanbul ignore next */ []));
261
+ dockbarRailItems = computed(() => {
262
+ const activeEntry = this.dockbarRouteHeaderVisible() ? this.dockbarActiveRouteEntry() : null;
263
+ if (activeEntry === null) {
264
+ return this.normalizedItems();
265
+ }
266
+ return this.normalizedItems().filter((entry) => entry.key !== activeEntry.key);
267
+ }, /* @ts-ignore */
268
+ ...(ngDevMode ? [{ debugName: "dockbarRailItems" }] : /* istanbul ignore next */ []));
269
+ dockbarAsideId = computed(() => `nav-dockbar-${this.safeId(this.resolvedState().id)}`, /* @ts-ignore */
270
+ ...(ngDevMode ? [{ debugName: "dockbarAsideId" }] : /* istanbul ignore next */ []));
271
+ dockbarOpenGroup = computed(() => {
272
+ const state = this.resolvedState();
273
+ if (state.type !== 'dockbar') {
274
+ return null;
275
+ }
276
+ if (!this.dockbarRouteEnabled()) {
277
+ return this.nav.resolveDockbarGroup(state.id, this.normalizedItems(), state.dockbarMode, this.activeIdSet(), this.activeUrl());
278
+ }
279
+ const groups = this.nav.dockbarGroups(this.normalizedItems());
280
+ const explicitKey = this.nav.currentPanelKey(state.id);
281
+ const explicitGroup = explicitKey === null ? null : (groups.find((group) => group.key === explicitKey) ?? null);
282
+ if (explicitGroup !== null) {
283
+ return explicitGroup;
284
+ }
285
+ return state.dockbarMode === 'sticky' ? this.dockbarActiveRoutePanelGroup() : null;
286
+ }, /* @ts-ignore */
287
+ ...(ngDevMode ? [{ debugName: "dockbarOpenGroup" }] : /* istanbul ignore next */ []));
288
+ dockbarActiveRoutePanelExpanded = computed(() => {
289
+ const panelGroup = this.dockbarActiveRoutePanelGroup();
290
+ const state = this.resolvedState();
291
+ if (panelGroup === null || state.type !== 'dockbar') {
292
+ return false;
293
+ }
294
+ return this.dockbarOpenGroup()?.key === panelGroup.key;
295
+ }, /* @ts-ignore */
296
+ ...(ngDevMode ? [{ debugName: "dockbarActiveRoutePanelExpanded" }] : /* istanbul ignore next */ []));
297
+ previewRailExpanded = computed(() => {
298
+ const state = this.resolvedState();
299
+ if (state.orientation !== 'vertical' || state.type !== 'sidebar' || !state.collapsed) {
300
+ return false;
301
+ }
302
+ return (this.previewExpanded() ||
303
+ (this.sidebarCollapse() && (this.hoverPreviewExpanded() || this.focusPreviewExpanded())));
304
+ }, /* @ts-ignore */
305
+ ...(ngDevMode ? [{ debugName: "previewRailExpanded" }] : /* istanbul ignore next */ []));
306
+ previewRailOffset = computed(() => this.previewRailExpanded()
307
+ ? 'calc(var(--layout-sidebar-width) - var(--layout-sidebar-collapsed-width))'
308
+ : '0px', /* @ts-ignore */
309
+ ...(ngDevMode ? [{ debugName: "previewRailOffset" }] : /* istanbul ignore next */ []));
310
+ displayState = computed(() => {
311
+ const state = this.resolvedState();
312
+ if (state.type === 'dockbar') {
313
+ return { ...state, collapsed: true };
314
+ }
315
+ return this.previewRailExpanded() ? { ...state, collapsed: false } : state;
316
+ }, /* @ts-ignore */
317
+ ...(ngDevMode ? [{ debugName: "displayState" }] : /* istanbul ignore next */ []));
318
+ dockbarAsideOpen = computed(() => {
319
+ const state = this.resolvedState();
320
+ if (state.type !== 'dockbar' || state.dockbarMode !== 'sticky') {
321
+ return false;
322
+ }
323
+ return this.dockbarOpenGroup() !== null;
324
+ }, /* @ts-ignore */
325
+ ...(ngDevMode ? [{ debugName: "dockbarAsideOpen" }] : /* istanbul ignore next */ []));
326
+ collapseEnabled = computed(() => {
327
+ const state = this.resolvedState();
328
+ return this.sidebarCollapse() && state.orientation === 'vertical' && state.type === 'sidebar';
329
+ }, /* @ts-ignore */
330
+ ...(ngDevMode ? [{ debugName: "collapseEnabled" }] : /* istanbul ignore next */ []));
331
+ /** Kelas shell yang dipakai host komponen type (eks `div` shell internal). */
332
+ shellClasses = computed(() => cn('flex h-full min-h-0 transition-[width,box-shadow,transform] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:transition-none', this.resolvedState().orientation === 'horizontal'
333
+ ? 'flex-row items-stretch overflow-visible'
334
+ : this.resolvedState().type === 'dockbar'
335
+ ? 'flex-col overflow-visible'
336
+ : 'flex-col overflow-hidden', this.resolvedState().type === 'dockbar' && [
337
+ 'w-(--layout-sidebar-collapsed-width) shrink-0',
338
+ this.resolvedState().position === 'right' && 'ml-auto',
339
+ ], this.resolvedState().position === 'right' ? 'origin-right' : 'origin-left', this.previewRailExpanded() && [
340
+ 'absolute inset-y-0 z-20 w-(--layout-sidebar-width) overflow-hidden bg-background shadow-xl',
341
+ this.resolvedState().position === 'right'
342
+ ? 'right-0 border-l border-border'
343
+ : 'left-0 border-r border-border',
344
+ ]), /* @ts-ignore */
345
+ ...(ngDevMode ? [{ debugName: "shellClasses" }] : /* istanbul ignore next */ []));
346
+ state = this.resolvedState;
347
+ resolvedDataId = computed(() => this.dataId()?.trim() || this.navId().trim() || 'default', /* @ts-ignore */
348
+ ...(ngDevMode ? [{ debugName: "resolvedDataId" }] : /* istanbul ignore next */ []));
349
+ hostClasses = computed(() => cn('relative block min-h-0 text-foreground transition-[width] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:transition-none', this.resolvedState().orientation === 'horizontal'
350
+ ? 'h-full w-full'
351
+ : this.resolvedState().type === 'dockbar'
352
+ ? this.dockbarAsideOpen()
353
+ ? // Rail + aside sit side by side, so the host reserves both widths.
354
+ 'w-[calc(var(--layout-sidebar-collapsed-width)+var(--layout-aside-width))]'
355
+ : 'w-(--layout-sidebar-collapsed-width)'
356
+ : this.resolvedState().collapsed
357
+ ? 'w-(--layout-sidebar-collapsed-width)'
358
+ : 'w-(--layout-sidebar-width)', this.resolvedState().orientation === 'horizontal' ||
359
+ this.resolvedState().type === 'dockbar' ||
360
+ this.previewRailExpanded()
361
+ ? 'overflow-visible'
362
+ : 'overflow-hidden', this.class()), /* @ts-ignore */
363
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
364
+ constructor() {
365
+ // Publikasikan data ke registry by id agar surface lain (mis. apps-launcher di `Page`)
366
+ // bisa membaca nav by id tanpa mendaftarkan ulang `<Navigation>` dengan id yang sama.
367
+ effect((onCleanup) => {
368
+ const dataId = this.resolvedDataId();
369
+ this.nav.publishData(dataId, this.data(), this.dataOwner);
370
+ onCleanup(() => this.nav.clearData(dataId, this.dataOwner));
371
+ });
372
+ }
373
+ /**
374
+ * Dipanggil komponen type saat dibuat. Satu `<Navigation>` hanya boleh
375
+ * memuat satu type hidup — pendaftaran ganda dianggap salah konfigurasi.
376
+ */
377
+ registerType(config) {
378
+ if (this.typeConfig() !== null && isDevMode()) {
379
+ throw new Error('[Navigation] Hanya satu type (<NavigationSidebar>/<NavigationDockbar>/<NavigationNavbar>/<NavigationFlyout>) yang boleh hidup dalam satu <Navigation>.');
380
+ }
381
+ this.typeConfig.set(config);
382
+ }
383
+ unregisterType(config) {
384
+ if (this.typeConfig() === config) {
385
+ this.typeConfig.set(null);
386
+ }
387
+ }
388
+ toggleCollapsed() {
389
+ this.controller.toggleCollapsed();
390
+ }
391
+ toggleDockbarActiveRoutePanel() {
392
+ const state = this.resolvedState();
393
+ const panelGroup = this.dockbarActiveRoutePanelGroup();
394
+ if (state.type === 'dockbar' && state.dockbarMode === 'drawer' && panelGroup !== null) {
395
+ this.nav.togglePanel(state.id, panelGroup);
396
+ }
397
+ }
398
+ closeDockbarPanel() {
399
+ const state = this.resolvedState();
400
+ if (state.type === 'dockbar' && this.nav.currentPanelKey(state.id) !== null) {
401
+ this.nav.closePanel(state.id);
402
+ return true;
403
+ }
404
+ return false;
405
+ }
406
+ restoreDockbarRoutePanel() {
407
+ const state = this.resolvedState();
408
+ if (!this.dockbarRouteEnabled() ||
409
+ state.type !== 'dockbar' ||
410
+ state.dockbarMode !== 'sticky' ||
411
+ this.nav.currentPanelKey(state.id) === null) {
412
+ return;
413
+ }
414
+ this.nav.closePanel(state.id);
415
+ }
416
+ setHoverPreview(value) {
417
+ this.hoverPreviewExpanded.set(this.sidebarCollapse() ? value : false);
418
+ }
419
+ setFocusPreview(value, event) {
420
+ if (!this.sidebarCollapse()) {
421
+ this.focusPreviewExpanded.set(false);
422
+ return;
423
+ }
424
+ // `focusout` also fires while focus moves between two items inside the rail;
425
+ // collapsing then would yank the next item out of the DOM mid-Tab.
426
+ if (!value && event) {
427
+ const next = event.relatedTarget;
428
+ const host = event.currentTarget;
429
+ if (next instanceof Node && host instanceof Node && host.contains(next)) {
430
+ return;
431
+ }
432
+ }
433
+ this.focusPreviewExpanded.set(value);
434
+ }
435
+ dockbarRouteConfig() {
436
+ const context = this.dockbarRouteContextPreference();
437
+ return context !== null && typeof context === 'object' ? context : {};
438
+ }
439
+ cleanString(value) {
440
+ return typeof value === 'string' && value.trim() ? value.trim() : null;
441
+ }
442
+ safeId(value) {
443
+ const normalized = value
444
+ .trim()
445
+ .toLowerCase()
446
+ .replace(/[^a-z0-9_-]+/g, '-');
447
+ return normalized || 'default';
448
+ }
449
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
450
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.4", type: NavigationContainerComponent, isStandalone: true, selector: "Navigation", inputs: { navId: { classPropertyName: "navId", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, dataId: { classPropertyName: "dataId", publicName: "data-id", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, collapseTree: { classPropertyName: "collapseTree", publicName: "collapse-tree", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, itemClass: { classPropertyName: "itemClass", publicName: "itemClass", isSignal: true, isRequired: false, transformFunction: null }, groupClass: { classPropertyName: "groupClass", publicName: "nav-group-class", isSignal: true, isRequired: false, transformFunction: null }, activeIds: { classPropertyName: "activeIds", publicName: "activeIds", isSignal: true, isRequired: false, transformFunction: null }, activeUrl: { classPropertyName: "activeUrl", publicName: "activeUrl", isSignal: true, isRequired: false, transformFunction: null }, openedIds: { classPropertyName: "openedIds", publicName: "openedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openedIds: "openedIdsChange", itemSelected: "itemSelected" }, host: { attributes: { "role": "navigation" }, listeners: { "mouseenter": "setHoverPreview(true)", "mouseleave": "setHoverPreview(false)", "focusin": "setFocusPreview(true)", "focusout": "setFocusPreview(false, $event)" }, properties: { "class": "hostClasses()", "attr.aria-label": "ariaLabel() || null", "attr.data-navigation-id": "resolvedState().id", "attr.data-id": "resolvedDataId()", "attr.data-orientation": "resolvedState().orientation", "attr.data-type": "resolvedState().type", "attr.data-type-style": "typeStyle()", "attr.data-position": "resolvedState().position", "attr.data-collapse-tree": "collapseTree()", "attr.data-preview-expanded": "previewRailExpanded() ? \"true\" : null" } }, providers: [
451
+ { provide: NAVIGATION_SHELL, useExisting: forwardRef(() => NavigationContainerComponent) },
452
+ ], queries: [{ propertyName: "iconTemplate", first: true, predicate: NavigationIconDirective, descendants: true, isSignal: true }], ngImport: i0, template: ` <ng-content /> `, isInline: true });
453
+ }
454
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationContainerComponent, decorators: [{
455
+ type: Component,
456
+ args: [{
457
+ selector: 'Navigation',
458
+ providers: [
459
+ { provide: NAVIGATION_SHELL, useExisting: forwardRef(() => NavigationContainerComponent) },
460
+ ],
461
+ host: {
462
+ '[class]': 'hostClasses()',
463
+ role: 'navigation',
464
+ '[attr.aria-label]': 'ariaLabel() || null',
465
+ '[attr.data-navigation-id]': 'resolvedState().id',
466
+ '[attr.data-id]': 'resolvedDataId()',
467
+ '[attr.data-orientation]': 'resolvedState().orientation',
468
+ '[attr.data-type]': 'resolvedState().type',
469
+ '[attr.data-type-style]': 'typeStyle()',
470
+ '[attr.data-position]': 'resolvedState().position',
471
+ '[attr.data-collapse-tree]': 'collapseTree()',
472
+ '[attr.data-preview-expanded]': 'previewRailExpanded() ? "true" : null',
473
+ '(mouseenter)': 'setHoverPreview(true)',
474
+ '(mouseleave)': 'setHoverPreview(false)',
475
+ '(focusin)': 'setFocusPreview(true)',
476
+ '(focusout)': 'setFocusPreview(false, $event)',
477
+ },
478
+ template: ` <ng-content /> `,
479
+ }]
480
+ }], ctorParameters: () => [], propDecorators: { navId: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], dataId: [{ type: i0.Input, args: [{ isSignal: true, alias: "data-id", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], collapseTree: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapse-tree", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], itemClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemClass", required: false }] }], groupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-group-class", required: false }] }], activeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIds", required: false }] }], activeUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeUrl", required: false }] }], openedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "openedIds", required: false }] }, { type: i0.Output, args: ["openedIdsChange"] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }], iconTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationIconDirective), { isSignal: true }] }] } });
481
+
482
+ class NavigationItemContentComponent {
483
+ nav = inject(NAVIGATION_ADAPTER);
484
+ item = input.required(/* @ts-ignore */
485
+ ...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
486
+ active = input(false, /* @ts-ignore */
487
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
488
+ compact = input(false, /* @ts-ignore */
489
+ ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
490
+ orientation = input('vertical', /* @ts-ignore */
491
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
492
+ level = input(0, /* @ts-ignore */
493
+ ...(ngDevMode ? [{ debugName: "level" }] : /* istanbul ignore next */ []));
494
+ iconTemplate = input(undefined, /* @ts-ignore */
495
+ ...(ngDevMode ? [{ debugName: "iconTemplate" }] : /* istanbul ignore next */ []));
496
+ iconSlotClasses = computed(() => cn('relative z-10 inline-flex shrink-0 items-center justify-center transition-colors duration-200', this.compact() && 'mx-auto', this.active() ? 'text-current' : 'text-muted-foreground group-hover/nav:text-current'), /* @ts-ignore */
497
+ ...(ngDevMode ? [{ debugName: "iconSlotClasses" }] : /* istanbul ignore next */ []));
498
+ titleClasses = computed(() => cn('block truncate', this.active() && 'text-foreground', this.item().classes?.title), /* @ts-ignore */
499
+ ...(ngDevMode ? [{ debugName: "titleClasses" }] : /* istanbul ignore next */ []));
500
+ showSubtitle = computed(() => !!this.item().subtitle && !(this.orientation() === 'horizontal' && this.level() === 0), /* @ts-ignore */
501
+ ...(ngDevMode ? [{ debugName: "showSubtitle" }] : /* istanbul ignore next */ []));
502
+ subtitleClasses = computed(() => cn('nav-subtitle block truncate text-muted-foreground', this.item().classes?.subtitle), /* @ts-ignore */
503
+ ...(ngDevMode ? [{ debugName: "subtitleClasses" }] : /* istanbul ignore next */ []));
504
+ compactFallbackClasses = computed(() => cn('inline-flex h-5 min-w-5 items-center justify-center text-(length:--nav-icon-size-sub) font-semibold uppercase'), /* @ts-ignore */
505
+ ...(ngDevMode ? [{ debugName: "compactFallbackClasses" }] : /* istanbul ignore next */ []));
506
+ defaultBadgeClasses = computed(() => cn('nav-badge ml-auto inline-flex h-5 shrink-0 items-center rounded-full px-2', this.active() ? 'bg-background text-foreground' : 'bg-muted text-muted-foreground'), /* @ts-ignore */
507
+ ...(ngDevMode ? [{ debugName: "defaultBadgeClasses" }] : /* istanbul ignore next */ []));
508
+ defaultIconClasses = computed(() => cn(this.compact() ? 'text-(length:--nav-icon-size-rail)' : 'text-(length:--nav-icon-size)', 'text-current', this.item().classes?.icon), /* @ts-ignore */
509
+ ...(ngDevMode ? [{ debugName: "defaultIconClasses" }] : /* istanbul ignore next */ []));
510
+ iconContext = computed(() => this.nav.iconContext(this.item(), this.active(), this.level(), this.orientation()), /* @ts-ignore */
511
+ ...(ngDevMode ? [{ debugName: "iconContext" }] : /* istanbul ignore next */ []));
512
+ compactFallback() {
513
+ return this.nav.compactFallback(this.item());
514
+ }
515
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationItemContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
516
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationItemContentComponent, isStandalone: true, selector: "NavigationItemContent", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, iconTemplate: { classPropertyName: "iconTemplate", publicName: "iconTemplate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
517
+ @if (item().icon; as iconName) {
518
+ <span data-navigation-icon-slot="true" [class]="iconSlotClasses()">
519
+ @if (iconTemplate(); as customIcon) {
520
+ <ng-container
521
+ [ngTemplateOutlet]="customIcon.template"
522
+ [ngTemplateOutletContext]="iconContext()"
523
+ />
524
+ } @else {
525
+ <Icon [name]="iconName" [class]="defaultIconClasses()" size="inherit" [fill]="1" />
526
+ }
527
+ </span>
528
+ }
529
+
530
+ @if (!compact()) {
531
+ <span class="min-w-0 flex-1">
532
+ <span [class]="titleClasses()">{{ item().title }}</span>
533
+ @if (showSubtitle()) {
534
+ <span [class]="subtitleClasses()">{{ item().subtitle }}</span>
535
+ }
536
+ </span>
537
+
538
+ @if (item().badge?.title; as badgeTitle) {
539
+ <span [class]="item().badge?.classes ?? defaultBadgeClasses()">{{ badgeTitle }}</span>
540
+ }
541
+ }
542
+
543
+ @if (compact() && !item().icon) {
544
+ <span aria-hidden="true" [class]="compactFallbackClasses()">{{ compactFallback() }}</span>
545
+ }
546
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }] });
547
+ }
548
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationItemContentComponent, decorators: [{
549
+ type: Component,
550
+ args: [{
551
+ selector: 'NavigationItemContent',
552
+ imports: [NgTemplateOutlet, IconComponent],
553
+ host: {
554
+ class: 'contents',
555
+ },
556
+ template: `
557
+ @if (item().icon; as iconName) {
558
+ <span data-navigation-icon-slot="true" [class]="iconSlotClasses()">
559
+ @if (iconTemplate(); as customIcon) {
560
+ <ng-container
561
+ [ngTemplateOutlet]="customIcon.template"
562
+ [ngTemplateOutletContext]="iconContext()"
563
+ />
564
+ } @else {
565
+ <Icon [name]="iconName" [class]="defaultIconClasses()" size="inherit" [fill]="1" />
566
+ }
567
+ </span>
568
+ }
569
+
570
+ @if (!compact()) {
571
+ <span class="min-w-0 flex-1">
572
+ <span [class]="titleClasses()">{{ item().title }}</span>
573
+ @if (showSubtitle()) {
574
+ <span [class]="subtitleClasses()">{{ item().subtitle }}</span>
575
+ }
576
+ </span>
577
+
578
+ @if (item().badge?.title; as badgeTitle) {
579
+ <span [class]="item().badge?.classes ?? defaultBadgeClasses()">{{ badgeTitle }}</span>
580
+ }
581
+ }
582
+
583
+ @if (compact() && !item().icon) {
584
+ <span aria-hidden="true" [class]="compactFallbackClasses()">{{ compactFallback() }}</span>
585
+ }
586
+ `,
587
+ }]
588
+ }], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], iconTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconTemplate", required: false }] }] } });
589
+
590
+ /**
591
+ * `item.panelId` is derived from the item key alone, so the same data rendered
592
+ * by two navigations — the desktop `main` rail and its `main-mobile` mirror, for
593
+ * instance — emits the same element id twice. Every id an item contributes is
594
+ * therefore scoped by the navigation that renders it.
595
+ */
596
+ function navigationPanelId(navId, item) {
597
+ return `${safeNavId(navId)}-${item.panelId}`;
598
+ }
599
+ function navigationHeadingId(navId, item) {
600
+ return `${navigationPanelId(navId, item)}-heading`;
601
+ }
602
+ function safeNavId(value) {
603
+ return (value
604
+ .trim()
605
+ .toLowerCase()
606
+ .replace(/[^a-z0-9_-]+/g, '-') || 'default');
607
+ }
608
+
609
+ class NavigationItemComponent {
610
+ nav = inject(NAVIGATION_ADAPTER);
611
+ navId = input('default', /* @ts-ignore */
612
+ ...(ngDevMode ? [{ debugName: "navId" }] : /* istanbul ignore next */ []));
613
+ item = input.required(/* @ts-ignore */
614
+ ...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
615
+ level = input(0, /* @ts-ignore */
616
+ ...(ngDevMode ? [{ debugName: "level" }] : /* istanbul ignore next */ []));
617
+ orientation = input('vertical', /* @ts-ignore */
618
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
619
+ compact = input(false, /* @ts-ignore */
620
+ ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
621
+ itemClass = input('', /* @ts-ignore */
622
+ ...(ngDevMode ? [{ debugName: "itemClass" }] : /* istanbul ignore next */ []));
623
+ activeIds = input(new Set(), /* @ts-ignore */
624
+ ...(ngDevMode ? [{ debugName: "activeIds" }] : /* istanbul ignore next */ []));
625
+ activeUrl = input(null, /* @ts-ignore */
626
+ ...(ngDevMode ? [{ debugName: "activeUrl" }] : /* istanbul ignore next */ []));
627
+ iconTemplate = input(undefined, /* @ts-ignore */
628
+ ...(ngDevMode ? [{ debugName: "iconTemplate" }] : /* istanbul ignore next */ []));
629
+ collapseTree = input('stairs', /* @ts-ignore */
630
+ ...(ngDevMode ? [{ debugName: "collapseTree" }] : /* istanbul ignore next */ []));
631
+ straightRail = input(false, /* @ts-ignore */
632
+ ...(ngDevMode ? [{ debugName: "straightRail" }] : /* istanbul ignore next */ []));
633
+ stairsRail = input(false, /* @ts-ignore */
634
+ ...(ngDevMode ? [{ debugName: "stairsRail" }] : /* istanbul ignore next */ []));
635
+ straightRailActive = input(false, /* @ts-ignore */
636
+ ...(ngDevMode ? [{ debugName: "straightRailActive" }] : /* istanbul ignore next */ []));
637
+ firstInBranch = input(false, /* @ts-ignore */
638
+ ...(ngDevMode ? [{ debugName: "firstInBranch" }] : /* istanbul ignore next */ []));
639
+ lastInBranch = input(false, /* @ts-ignore */
640
+ ...(ngDevMode ? [{ debugName: "lastInBranch" }] : /* istanbul ignore next */ []));
641
+ openedIds = input([], /* @ts-ignore */
642
+ ...(ngDevMode ? [{ debugName: "openedIds" }] : /* istanbul ignore next */ []));
643
+ openedIdsChange = output();
644
+ itemSelected = output();
645
+ openedIdSet = computed(() => new Set(this.openedIds()), /* @ts-ignore */
646
+ ...(ngDevMode ? [{ debugName: "openedIdSet" }] : /* istanbul ignore next */ []));
647
+ listedAsOpen = computed(() => this.openedIdSet().has(this.item().stateId) || this.openedIdSet().has(this.item().key), /* @ts-ignore */
648
+ ...(ngDevMode ? [{ debugName: "listedAsOpen" }] : /* istanbul ignore next */ []));
649
+ /**
650
+ * An active branch opens itself, which leaves `openedIds` unable to say
651
+ * "closed": dropping the id lets `isActive()` re-open the branch on the next
652
+ * read, so `aria-expanded` reports a state the chevron never reaches.
653
+ *
654
+ * Auto-opening is therefore only a starting position. Once the chevron has
655
+ * been used, `openedIds` alone decides, so a collapse holds and a later
656
+ * `openedIds` carrying this branch still re-opens it.
657
+ */
658
+ userToggled = signal(false, /* @ts-ignore */
659
+ ...(ngDevMode ? [{ debugName: "userToggled" }] : /* istanbul ignore next */ []));
660
+ isHorizontalRoot = computed(() => this.orientation() === 'horizontal' && this.level() === 0, /* @ts-ignore */
661
+ ...(ngDevMode ? [{ debugName: "isHorizontalRoot" }] : /* istanbul ignore next */ []));
662
+ isActive = computed(() => this.nav.isItemActive(this.item(), this.activeIds(), this.activeUrl()), /* @ts-ignore */
663
+ ...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
664
+ showChildren = computed(() => !this.compact() && this.isOpen(), /* @ts-ignore */
665
+ ...(ngDevMode ? [{ debugName: "showChildren" }] : /* istanbul ignore next */ []));
666
+ hostClasses = computed(() => {
667
+ if (this.item().type === 'divider') {
668
+ return this.dividerClasses();
669
+ }
670
+ if (this.item().type === 'spacer') {
671
+ return 'flex-1';
672
+ }
673
+ if (this.item().type === 'group' || this.item().type === 'mega') {
674
+ return this.groupContainerClasses();
675
+ }
676
+ return this.itemContainerClasses();
677
+ }, /* @ts-ignore */
678
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
679
+ hostRole = computed(() => {
680
+ // Dividers are decorative (aria-hidden); a `separator` role is not a valid
681
+ // child of `list` and would trip axe's aria-required-children. Horizontal
682
+ // items are presentational `<li>` wrappers around the real menuitem.
683
+ return this.orientation() === 'horizontal' ? 'none' : null;
684
+ }, /* @ts-ignore */
685
+ ...(ngDevMode ? [{ debugName: "hostRole" }] : /* istanbul ignore next */ []));
686
+ panelId = computed(() => navigationPanelId(this.navId(), this.item()), /* @ts-ignore */
687
+ ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
688
+ headingId = computed(() => navigationHeadingId(this.navId(), this.item()), /* @ts-ignore */
689
+ ...(ngDevMode ? [{ debugName: "headingId" }] : /* istanbul ignore next */ []));
690
+ isRouterItem() {
691
+ return this.nav.isRouterItem(this.item());
692
+ }
693
+ hrefFor() {
694
+ return this.nav.hrefFor(this.item());
695
+ }
696
+ /**
697
+ * The `routerLink` a disabled item never gets.
698
+ *
699
+ * `RouterLink` registers its OWN click listener on the host, so a guard in
700
+ * `selectItem` was racing it rather than stopping it: the route changed even
701
+ * though the item looked dead. Not binding the link at all removes the
702
+ * navigation path from the start, which is the only version of "disabled" that
703
+ * is actually true.
704
+ */
705
+ routerLinkFor() {
706
+ return this.item().disabled ? null : (this.item().link ?? null);
707
+ }
708
+ /** Same rule for a plain anchor: no `href` means nothing to follow. */
709
+ hrefAttribute() {
710
+ return this.item().disabled ? null : this.hrefFor();
711
+ }
712
+ /**
713
+ * An anchor without `href` is already out of the tab order; this states it
714
+ * outright, so the item cannot be reached by Tab and then activated by Enter.
715
+ */
716
+ leafTabIndex() {
717
+ return this.item().disabled ? -1 : null;
718
+ }
719
+ relFor() {
720
+ return this.nav.relFor(this.item());
721
+ }
722
+ routerLinkActiveOptions() {
723
+ return this.nav.routerLinkActiveOptions(this.item());
724
+ }
725
+ itemRole() {
726
+ return this.nav.itemRole(this.orientation(), this.level());
727
+ }
728
+ compactLabel() {
729
+ return this.nav.compactLabel(this.item(), this.compact());
730
+ }
731
+ titleFor() {
732
+ return this.nav.titleFor(this.item(), this.compact());
733
+ }
734
+ isOpen() {
735
+ if (this.userToggled()) {
736
+ return this.listedAsOpen();
737
+ }
738
+ return this.listedAsOpen() || this.isActive();
739
+ }
740
+ toggleOpen() {
741
+ if (this.item().disabled) {
742
+ return;
743
+ }
744
+ const open = this.isOpen();
745
+ this.userToggled.set(true);
746
+ const next = new Set(this.openedIds());
747
+ if (open) {
748
+ next.delete(this.item().stateId);
749
+ }
750
+ else {
751
+ next.add(this.item().stateId);
752
+ }
753
+ this.openedIdsChange.emit([...next]);
754
+ }
755
+ selectItem(event) {
756
+ if (this.item().disabled) {
757
+ event.preventDefault();
758
+ event.stopPropagation();
759
+ return;
760
+ }
761
+ this.item().action?.(this.item().source);
762
+ this.itemSelected.emit({
763
+ item: this.item().source,
764
+ key: this.item().key,
765
+ type: this.item().type,
766
+ link: this.item().link,
767
+ external: !!this.hrefFor(),
768
+ });
769
+ this.nav.closePanel(this.navId());
770
+ this.nav.closeDrawer(this.navId());
771
+ }
772
+ leafClasses(active) {
773
+ return cn('NavigationItem nav-text group/nav inline-flex min-w-0 items-center rounded-md transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', this.orientation() === 'horizontal' && this.level() === 0
774
+ ? 'h-(--nav-item-height) px-(--nav-item-padding-x)'
775
+ : 'min-h-(--nav-item-height) w-full px-(--nav-item-padding-x) py-1 text-left', 'gap-(--nav-item-gap)', this.compact() && 'size-(--nav-rail-item-size) justify-center gap-0 px-0 py-0 text-center', this.interactiveStateClasses(active), this.item().disabled && 'pointer-events-none opacity-50', this.item().classes?.wrapper, this.itemClass());
776
+ }
777
+ triggerClasses(active) {
778
+ return cn('nav-trigger nav-text group/nav inline-flex min-w-0 items-center rounded-md transition-colors', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50', this.orientation() === 'horizontal' && this.level() === 0
779
+ ? 'h-(--nav-item-height) px-(--nav-item-padding-x)'
780
+ : 'min-h-(--nav-item-height) w-full px-(--nav-item-padding-x) py-1 text-left', 'gap-(--nav-item-gap)', this.compact() && 'size-(--nav-rail-item-size) justify-center gap-0 px-0 py-0 text-center', this.interactiveStateClasses(active), this.item().classes?.wrapper, this.itemClass());
781
+ }
782
+ interactiveStateClasses(active) {
783
+ // Konektor hanya digambar saat list induk memang menggambar rail stairs —
784
+ // anak langsung sebuah group tidak punya rail, konektornya akan mengambang.
785
+ const showsNestedActiveConnector = active && this.orientation() === 'vertical' && !this.compact() && this.stairsRail();
786
+ if (this.orientation() === 'vertical' && !this.compact()) {
787
+ return cn('relative isolate', "before:pointer-events-none before:absolute before:inset-y-0 before:left-2 before:right-2 before:-z-10 before:rounded-md before:border before:border-transparent before:bg-transparent before:transition-colors before:duration-200 before:content-['']", showsNestedActiveConnector &&
788
+ "after:pointer-events-none after:absolute after:-left-[calc(var(--nav-indent)-var(--nav-rail-offset))] after:top-1/2 after:-z-10 after:h-px after:w-[calc(var(--nav-indent)-var(--nav-rail-offset))] after:-translate-y-1/2 after:rounded-full after:bg-current/25 after:content-['']", active
789
+ ? 'text-foreground before:bg-accent'
790
+ : 'text-foreground/80 hover:text-accent-foreground hover:before:bg-accent');
791
+ }
792
+ return active
793
+ ? 'text-foreground bg-accent'
794
+ : 'text-foreground/80 hover:bg-accent hover:text-accent-foreground';
795
+ }
796
+ chevronClasses() {
797
+ return cn('ml-auto shrink-0 self-center text-(length:--nav-icon-size-sub) text-muted-foreground/70 transition-transform duration-200', this.isOpen() && 'rotate-90');
798
+ }
799
+ itemContainerClasses() {
800
+ return cn(this.orientation() === 'horizontal' && this.level() === 0 ? 'relative' : 'w-full', this.compact() && 'flex justify-center', this.straightRailClasses());
801
+ }
802
+ groupContainerClasses() {
803
+ return cn('w-full', this.level() > 0 && 'pt-2');
804
+ }
805
+ dividerClasses() {
806
+ return cn(this.orientation() === 'horizontal' && this.level() === 0
807
+ ? 'mx-1 h-5 w-px'
808
+ : 'my-2 w-full px-2');
809
+ }
810
+ groupHeadingClasses() {
811
+ return cn('nav-heading px-(--nav-item-padding-x) pt-4 pb-1 text-muted-foreground', this.item().classes?.title);
812
+ }
813
+ childListClasses() {
814
+ const isGroupedBranch = this.item().type === 'group' || this.item().type === 'mega';
815
+ const usesStairsTree = this.collapseTree() === 'stairs';
816
+ return cn('flex list-none flex-col gap-0.5 p-0', !this.compact() && 'mt-0.5', this.level() >= 0 &&
817
+ !this.compact() &&
818
+ !isGroupedBranch &&
819
+ usesStairsTree &&
820
+ cn("relative ml-(--nav-rail-offset) pl-[calc(var(--nav-indent)-var(--nav-rail-offset))] before:absolute before:-top-2 before:bottom-0 before:left-0 before:w-px before:-translate-x-1/2 before:rounded-full before:content-['']", this.isActive() ? 'before:bg-current/25' : 'before:bg-border'));
821
+ }
822
+ showsStairsRailForChildren() {
823
+ return (!this.compact() &&
824
+ this.collapseTree() === 'stairs' &&
825
+ this.item().type !== 'group' &&
826
+ this.item().type !== 'mega');
827
+ }
828
+ showStraightRailForChildren() {
829
+ return (!this.compact() &&
830
+ this.collapseTree() === 'straight' &&
831
+ this.item().type !== 'group' &&
832
+ this.item().type !== 'mega');
833
+ }
834
+ straightRailClasses() {
835
+ if (!this.straightRail() || this.orientation() !== 'vertical' || this.compact()) {
836
+ return '';
837
+ }
838
+ return cn('relative', "before:pointer-events-none before:absolute before:left-(--nav-rail-offset) before:w-0 before:-z-10 before:border-l before:border-dotted before:content-['']", this.straightRailActive() ? 'before:border-primary/50' : 'before:border-border/50', this.firstInBranch()
839
+ ? 'before:-top-[calc(var(--nav-item-height)/2+var(--spacing-base)*0.5)]'
840
+ : 'before:-top-0.5', this.lastInBranch()
841
+ ? 'before:bottom-[calc(100%-var(--nav-item-height)/2)]'
842
+ : 'before:-bottom-0.5');
843
+ }
844
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
845
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationItemComponent, isStandalone: true, selector: "li[NavigationItem]", inputs: { navId: { classPropertyName: "navId", publicName: "navId", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, itemClass: { classPropertyName: "itemClass", publicName: "itemClass", isSignal: true, isRequired: false, transformFunction: null }, activeIds: { classPropertyName: "activeIds", publicName: "activeIds", isSignal: true, isRequired: false, transformFunction: null }, activeUrl: { classPropertyName: "activeUrl", publicName: "activeUrl", isSignal: true, isRequired: false, transformFunction: null }, iconTemplate: { classPropertyName: "iconTemplate", publicName: "iconTemplate", isSignal: true, isRequired: false, transformFunction: null }, collapseTree: { classPropertyName: "collapseTree", publicName: "collapseTree", isSignal: true, isRequired: false, transformFunction: null }, straightRail: { classPropertyName: "straightRail", publicName: "straightRail", isSignal: true, isRequired: false, transformFunction: null }, stairsRail: { classPropertyName: "stairsRail", publicName: "stairsRail", isSignal: true, isRequired: false, transformFunction: null }, straightRailActive: { classPropertyName: "straightRailActive", publicName: "straightRailActive", isSignal: true, isRequired: false, transformFunction: null }, firstInBranch: { classPropertyName: "firstInBranch", publicName: "firstInBranch", isSignal: true, isRequired: false, transformFunction: null }, lastInBranch: { classPropertyName: "lastInBranch", publicName: "lastInBranch", isSignal: true, isRequired: false, transformFunction: null }, openedIds: { classPropertyName: "openedIds", publicName: "openedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openedIdsChange: "openedIdsChange", itemSelected: "itemSelected" }, host: { properties: { "class": "hostClasses()", "attr.role": "hostRole()", "attr.data-navigation-item-key": "item().key", "attr.aria-hidden": "item().type === \"spacer\" || item().type === \"divider\" ? \"true\" : null" } }, ngImport: i0, template: `
846
+ @switch (item().type) {
847
+ @case ('divider') {
848
+ <span class="block h-px w-full bg-border"></span>
849
+ }
850
+
851
+ @case ('spacer') {}
852
+
853
+ @case ('group') {
854
+ @if (!compact() && item().title) {
855
+ <div [id]="headingId()" [class]="groupHeadingClasses()">
856
+ <span class="block truncate">{{ item().title }}</span>
857
+
858
+ @if (item().subtitle) {
859
+ <span
860
+ class="nav-subtitle -mt-0.5 block truncate text-2xs normal-case text-muted-foreground"
861
+ data-navigation-group-subtitle
862
+ >
863
+ {{ item().subtitle }}
864
+ </span>
865
+ }
866
+ </div>
867
+ }
868
+
869
+ <ul
870
+ [class]="childListClasses()"
871
+ role="list"
872
+ [attr.aria-labelledby]="item().title ? headingId() : null"
873
+ >
874
+ <ng-container [ngTemplateOutlet]="childItems" />
875
+ </ul>
876
+ }
877
+
878
+ @case ('collapsible') {
879
+ <button
880
+ type="button"
881
+ [class]="triggerClasses(isActive())"
882
+ [attr.aria-expanded]="showChildren()"
883
+ [attr.aria-controls]="showChildren() ? panelId() : null"
884
+ [attr.aria-label]="compactLabel()"
885
+ [attr.title]="titleFor()"
886
+ [disabled]="item().disabled || null"
887
+ (click)="toggleOpen()"
888
+ >
889
+ <NavigationItemContent
890
+ [item]="item()"
891
+ [active]="isActive()"
892
+ [compact]="compact()"
893
+ [orientation]="orientation()"
894
+ [level]="level()"
895
+ [iconTemplate]="iconTemplate()"
896
+ />
897
+
898
+ @if (!compact()) {
899
+ <Icon name="chevron_right" size="inherit" [class]="chevronClasses()" />
900
+ }
901
+ </button>
902
+
903
+ @if (showChildren()) {
904
+ <ul [id]="panelId()" [class]="childListClasses()" role="list">
905
+ <ng-container [ngTemplateOutlet]="childItems" />
906
+ </ul>
907
+ }
908
+ }
909
+
910
+ @case ('mega') {
911
+ @if (!compact() && item().title) {
912
+ <div [id]="headingId()" [class]="groupHeadingClasses()">{{ item().title }}</div>
913
+ }
914
+
915
+ <ul
916
+ [class]="childListClasses()"
917
+ role="list"
918
+ [attr.aria-labelledby]="item().title ? headingId() : null"
919
+ >
920
+ <ng-container [ngTemplateOutlet]="childItems" />
921
+ </ul>
922
+ }
923
+
924
+ @default {
925
+ @if (isRouterItem()) {
926
+ <a
927
+ [class]="leafClasses(routerActive.isActive || isActive())"
928
+ [routerLink]="routerLinkFor()"
929
+ [queryParams]="item().queryParams ?? null"
930
+ [queryParamsHandling]="item().queryParamsHandling ?? null"
931
+ [fragment]="item().fragment ?? undefined"
932
+ [preserveFragment]="item().preserveFragment ?? false"
933
+ [target]="item().target ?? undefined"
934
+ [attr.rel]="relFor()"
935
+ routerLinkActive
936
+ #routerActive="routerLinkActive"
937
+ [routerLinkActiveOptions]="routerLinkActiveOptions()"
938
+ [attr.aria-current]="routerActive.isActive || isActive() ? 'page' : null"
939
+ [attr.aria-disabled]="item().disabled || null"
940
+ [attr.tabindex]="leafTabIndex()"
941
+ [attr.aria-label]="compactLabel()"
942
+ [attr.title]="titleFor()"
943
+ [attr.role]="itemRole()"
944
+ [attr.data-navigation-root-item]="isHorizontalRoot() ? 'true' : null"
945
+ (click)="selectItem($event)"
946
+ >
947
+ <NavigationItemContent
948
+ [item]="item()"
949
+ [active]="routerActive.isActive || isActive()"
950
+ [compact]="compact()"
951
+ [orientation]="orientation()"
952
+ [level]="level()"
953
+ [iconTemplate]="iconTemplate()"
954
+ />
955
+ </a>
956
+ } @else if (hrefFor()) {
957
+ <a
958
+ [class]="leafClasses(isActive())"
959
+ [attr.href]="hrefAttribute()"
960
+ [attr.target]="item().target ?? (item().externalLink ? '_blank' : null)"
961
+ [attr.rel]="relFor()"
962
+ [attr.aria-current]="isActive() ? 'page' : null"
963
+ [attr.aria-disabled]="item().disabled || null"
964
+ [attr.tabindex]="leafTabIndex()"
965
+ [attr.aria-label]="compactLabel()"
966
+ [attr.title]="titleFor()"
967
+ [attr.role]="itemRole()"
968
+ [attr.data-navigation-root-item]="isHorizontalRoot() ? 'true' : null"
969
+ (click)="selectItem($event)"
970
+ >
971
+ <NavigationItemContent
972
+ [item]="item()"
973
+ [active]="isActive()"
974
+ [compact]="compact()"
975
+ [orientation]="orientation()"
976
+ [level]="level()"
977
+ [iconTemplate]="iconTemplate()"
978
+ />
979
+ </a>
980
+ } @else {
981
+ <button
982
+ type="button"
983
+ [class]="leafClasses(isActive())"
984
+ [disabled]="item().disabled || null"
985
+ [attr.aria-current]="isActive() ? 'page' : null"
986
+ [attr.aria-label]="compactLabel()"
987
+ [attr.title]="titleFor()"
988
+ [attr.role]="itemRole()"
989
+ [attr.data-navigation-root-item]="isHorizontalRoot() ? 'true' : null"
990
+ (click)="selectItem($event)"
991
+ >
992
+ <NavigationItemContent
993
+ [item]="item()"
994
+ [active]="isActive()"
995
+ [compact]="compact()"
996
+ [orientation]="orientation()"
997
+ [level]="level()"
998
+ [iconTemplate]="iconTemplate()"
999
+ />
1000
+ </button>
1001
+ }
1002
+ }
1003
+ }
1004
+ <!--
1005
+ The recursive child list, defined once.
1006
+
1007
+ It was written out three times, in the group, collapsible, and mega
1008
+ branches, 25 identical lines each. Nothing needs passing in: every binding
1009
+ is a member of this component and so is lexically in scope here, and
1010
+ isFirst / isLast are @for locals declared inside.
1011
+
1012
+ The collapsible copy used to hardcode compact="false". That is the same
1013
+ value there: its list only renders under showChildren(), which already
1014
+ requires compact() to be false.
1015
+ -->
1016
+ <ng-template #childItems>
1017
+ @for (child of item().children; track child.key; let isFirst = $first; let isLast = $last) {
1018
+ <li
1019
+ NavigationItem
1020
+ [navId]="navId()"
1021
+ [item]="child"
1022
+ [level]="level() + 1"
1023
+ [orientation]="orientation()"
1024
+ [compact]="compact()"
1025
+ [itemClass]="itemClass()"
1026
+ [activeIds]="activeIds()"
1027
+ [activeUrl]="activeUrl()"
1028
+ [iconTemplate]="iconTemplate()"
1029
+ [collapseTree]="collapseTree()"
1030
+ [straightRail]="showStraightRailForChildren()"
1031
+ [stairsRail]="showsStairsRailForChildren()"
1032
+ [straightRailActive]="isActive()"
1033
+ [firstInBranch]="isFirst"
1034
+ [lastInBranch]="isLast"
1035
+ [openedIds]="openedIds()"
1036
+ (openedIdsChange)="openedIdsChange.emit($event)"
1037
+ (itemSelected)="itemSelected.emit($event)"
1038
+ ></li>
1039
+ }
1040
+ </ng-template>
1041
+ `, isInline: true, dependencies: [{ kind: "component", type: NavigationItemComponent, selector: "li[NavigationItem]", inputs: ["navId", "item", "level", "orientation", "compact", "itemClass", "activeIds", "activeUrl", "iconTemplate", "collapseTree", "straightRail", "stairsRail", "straightRailActive", "firstInBranch", "lastInBranch", "openedIds"], outputs: ["openedIdsChange", "itemSelected"] }, { kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }, { kind: "component", type: NavigationItemContentComponent, selector: "NavigationItemContent", inputs: ["item", "active", "compact", "orientation", "level", "iconTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
1042
+ }
1043
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationItemComponent, decorators: [{
1044
+ type: Component,
1045
+ args: [{
1046
+ selector: 'li[NavigationItem]',
1047
+ imports: [
1048
+ IconComponent,
1049
+ NavigationItemContentComponent,
1050
+ NgTemplateOutlet,
1051
+ RouterLink,
1052
+ RouterLinkActive,
1053
+ ],
1054
+ host: {
1055
+ '[class]': 'hostClasses()',
1056
+ '[attr.role]': 'hostRole()',
1057
+ '[attr.data-navigation-item-key]': 'item().key',
1058
+ '[attr.aria-hidden]': 'item().type === "spacer" || item().type === "divider" ? "true" : null',
1059
+ },
1060
+ template: `
1061
+ @switch (item().type) {
1062
+ @case ('divider') {
1063
+ <span class="block h-px w-full bg-border"></span>
1064
+ }
1065
+
1066
+ @case ('spacer') {}
1067
+
1068
+ @case ('group') {
1069
+ @if (!compact() && item().title) {
1070
+ <div [id]="headingId()" [class]="groupHeadingClasses()">
1071
+ <span class="block truncate">{{ item().title }}</span>
1072
+
1073
+ @if (item().subtitle) {
1074
+ <span
1075
+ class="nav-subtitle -mt-0.5 block truncate text-2xs normal-case text-muted-foreground"
1076
+ data-navigation-group-subtitle
1077
+ >
1078
+ {{ item().subtitle }}
1079
+ </span>
1080
+ }
1081
+ </div>
1082
+ }
1083
+
1084
+ <ul
1085
+ [class]="childListClasses()"
1086
+ role="list"
1087
+ [attr.aria-labelledby]="item().title ? headingId() : null"
1088
+ >
1089
+ <ng-container [ngTemplateOutlet]="childItems" />
1090
+ </ul>
1091
+ }
1092
+
1093
+ @case ('collapsible') {
1094
+ <button
1095
+ type="button"
1096
+ [class]="triggerClasses(isActive())"
1097
+ [attr.aria-expanded]="showChildren()"
1098
+ [attr.aria-controls]="showChildren() ? panelId() : null"
1099
+ [attr.aria-label]="compactLabel()"
1100
+ [attr.title]="titleFor()"
1101
+ [disabled]="item().disabled || null"
1102
+ (click)="toggleOpen()"
1103
+ >
1104
+ <NavigationItemContent
1105
+ [item]="item()"
1106
+ [active]="isActive()"
1107
+ [compact]="compact()"
1108
+ [orientation]="orientation()"
1109
+ [level]="level()"
1110
+ [iconTemplate]="iconTemplate()"
1111
+ />
1112
+
1113
+ @if (!compact()) {
1114
+ <Icon name="chevron_right" size="inherit" [class]="chevronClasses()" />
1115
+ }
1116
+ </button>
1117
+
1118
+ @if (showChildren()) {
1119
+ <ul [id]="panelId()" [class]="childListClasses()" role="list">
1120
+ <ng-container [ngTemplateOutlet]="childItems" />
1121
+ </ul>
1122
+ }
1123
+ }
1124
+
1125
+ @case ('mega') {
1126
+ @if (!compact() && item().title) {
1127
+ <div [id]="headingId()" [class]="groupHeadingClasses()">{{ item().title }}</div>
1128
+ }
1129
+
1130
+ <ul
1131
+ [class]="childListClasses()"
1132
+ role="list"
1133
+ [attr.aria-labelledby]="item().title ? headingId() : null"
1134
+ >
1135
+ <ng-container [ngTemplateOutlet]="childItems" />
1136
+ </ul>
1137
+ }
1138
+
1139
+ @default {
1140
+ @if (isRouterItem()) {
1141
+ <a
1142
+ [class]="leafClasses(routerActive.isActive || isActive())"
1143
+ [routerLink]="routerLinkFor()"
1144
+ [queryParams]="item().queryParams ?? null"
1145
+ [queryParamsHandling]="item().queryParamsHandling ?? null"
1146
+ [fragment]="item().fragment ?? undefined"
1147
+ [preserveFragment]="item().preserveFragment ?? false"
1148
+ [target]="item().target ?? undefined"
1149
+ [attr.rel]="relFor()"
1150
+ routerLinkActive
1151
+ #routerActive="routerLinkActive"
1152
+ [routerLinkActiveOptions]="routerLinkActiveOptions()"
1153
+ [attr.aria-current]="routerActive.isActive || isActive() ? 'page' : null"
1154
+ [attr.aria-disabled]="item().disabled || null"
1155
+ [attr.tabindex]="leafTabIndex()"
1156
+ [attr.aria-label]="compactLabel()"
1157
+ [attr.title]="titleFor()"
1158
+ [attr.role]="itemRole()"
1159
+ [attr.data-navigation-root-item]="isHorizontalRoot() ? 'true' : null"
1160
+ (click)="selectItem($event)"
1161
+ >
1162
+ <NavigationItemContent
1163
+ [item]="item()"
1164
+ [active]="routerActive.isActive || isActive()"
1165
+ [compact]="compact()"
1166
+ [orientation]="orientation()"
1167
+ [level]="level()"
1168
+ [iconTemplate]="iconTemplate()"
1169
+ />
1170
+ </a>
1171
+ } @else if (hrefFor()) {
1172
+ <a
1173
+ [class]="leafClasses(isActive())"
1174
+ [attr.href]="hrefAttribute()"
1175
+ [attr.target]="item().target ?? (item().externalLink ? '_blank' : null)"
1176
+ [attr.rel]="relFor()"
1177
+ [attr.aria-current]="isActive() ? 'page' : null"
1178
+ [attr.aria-disabled]="item().disabled || null"
1179
+ [attr.tabindex]="leafTabIndex()"
1180
+ [attr.aria-label]="compactLabel()"
1181
+ [attr.title]="titleFor()"
1182
+ [attr.role]="itemRole()"
1183
+ [attr.data-navigation-root-item]="isHorizontalRoot() ? 'true' : null"
1184
+ (click)="selectItem($event)"
1185
+ >
1186
+ <NavigationItemContent
1187
+ [item]="item()"
1188
+ [active]="isActive()"
1189
+ [compact]="compact()"
1190
+ [orientation]="orientation()"
1191
+ [level]="level()"
1192
+ [iconTemplate]="iconTemplate()"
1193
+ />
1194
+ </a>
1195
+ } @else {
1196
+ <button
1197
+ type="button"
1198
+ [class]="leafClasses(isActive())"
1199
+ [disabled]="item().disabled || null"
1200
+ [attr.aria-current]="isActive() ? 'page' : null"
1201
+ [attr.aria-label]="compactLabel()"
1202
+ [attr.title]="titleFor()"
1203
+ [attr.role]="itemRole()"
1204
+ [attr.data-navigation-root-item]="isHorizontalRoot() ? 'true' : null"
1205
+ (click)="selectItem($event)"
1206
+ >
1207
+ <NavigationItemContent
1208
+ [item]="item()"
1209
+ [active]="isActive()"
1210
+ [compact]="compact()"
1211
+ [orientation]="orientation()"
1212
+ [level]="level()"
1213
+ [iconTemplate]="iconTemplate()"
1214
+ />
1215
+ </button>
1216
+ }
1217
+ }
1218
+ }
1219
+ <!--
1220
+ The recursive child list, defined once.
1221
+
1222
+ It was written out three times, in the group, collapsible, and mega
1223
+ branches, 25 identical lines each. Nothing needs passing in: every binding
1224
+ is a member of this component and so is lexically in scope here, and
1225
+ isFirst / isLast are @for locals declared inside.
1226
+
1227
+ The collapsible copy used to hardcode compact="false". That is the same
1228
+ value there: its list only renders under showChildren(), which already
1229
+ requires compact() to be false.
1230
+ -->
1231
+ <ng-template #childItems>
1232
+ @for (child of item().children; track child.key; let isFirst = $first; let isLast = $last) {
1233
+ <li
1234
+ NavigationItem
1235
+ [navId]="navId()"
1236
+ [item]="child"
1237
+ [level]="level() + 1"
1238
+ [orientation]="orientation()"
1239
+ [compact]="compact()"
1240
+ [itemClass]="itemClass()"
1241
+ [activeIds]="activeIds()"
1242
+ [activeUrl]="activeUrl()"
1243
+ [iconTemplate]="iconTemplate()"
1244
+ [collapseTree]="collapseTree()"
1245
+ [straightRail]="showStraightRailForChildren()"
1246
+ [stairsRail]="showsStairsRailForChildren()"
1247
+ [straightRailActive]="isActive()"
1248
+ [firstInBranch]="isFirst"
1249
+ [lastInBranch]="isLast"
1250
+ [openedIds]="openedIds()"
1251
+ (openedIdsChange)="openedIdsChange.emit($event)"
1252
+ (itemSelected)="itemSelected.emit($event)"
1253
+ ></li>
1254
+ }
1255
+ </ng-template>
1256
+ `,
1257
+ }]
1258
+ }], propDecorators: { navId: [{ type: i0.Input, args: [{ isSignal: true, alias: "navId", required: false }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], itemClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemClass", required: false }] }], activeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIds", required: false }] }], activeUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeUrl", required: false }] }], iconTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconTemplate", required: false }] }], collapseTree: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseTree", required: false }] }], straightRail: [{ type: i0.Input, args: [{ isSignal: true, alias: "straightRail", required: false }] }], stairsRail: [{ type: i0.Input, args: [{ isSignal: true, alias: "stairsRail", required: false }] }], straightRailActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "straightRailActive", required: false }] }], firstInBranch: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstInBranch", required: false }] }], lastInBranch: [{ type: i0.Input, args: [{ isSignal: true, alias: "lastInBranch", required: false }] }], openedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "openedIds", required: false }] }], openedIdsChange: [{ type: i0.Output, args: ["openedIdsChange"] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
1259
+
1260
+ class NavigationListComponent {
1261
+ navId = input('default', /* @ts-ignore */
1262
+ ...(ngDevMode ? [{ debugName: "navId" }] : /* istanbul ignore next */ []));
1263
+ items = input([], /* @ts-ignore */
1264
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
1265
+ collapsed = input(false, /* @ts-ignore */
1266
+ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
1267
+ compact = input(false, /* @ts-ignore */
1268
+ ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
1269
+ position = input('left', /* @ts-ignore */
1270
+ ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
1271
+ itemClass = input('', /* @ts-ignore */
1272
+ ...(ngDevMode ? [{ debugName: "itemClass" }] : /* istanbul ignore next */ []));
1273
+ activeIds = input(new Set(), /* @ts-ignore */
1274
+ ...(ngDevMode ? [{ debugName: "activeIds" }] : /* istanbul ignore next */ []));
1275
+ activeUrl = input(null, /* @ts-ignore */
1276
+ ...(ngDevMode ? [{ debugName: "activeUrl" }] : /* istanbul ignore next */ []));
1277
+ iconTemplate = input(undefined, /* @ts-ignore */
1278
+ ...(ngDevMode ? [{ debugName: "iconTemplate" }] : /* istanbul ignore next */ []));
1279
+ collapseTree = input('stairs', /* @ts-ignore */
1280
+ ...(ngDevMode ? [{ debugName: "collapseTree" }] : /* istanbul ignore next */ []));
1281
+ openedIds = input([], /* @ts-ignore */
1282
+ ...(ngDevMode ? [{ debugName: "openedIds" }] : /* istanbul ignore next */ []));
1283
+ openedIdsChange = output();
1284
+ itemSelected = output();
1285
+ isCollapsed = computed(() => this.collapsed() || this.compact(), /* @ts-ignore */
1286
+ ...(ngDevMode ? [{ debugName: "isCollapsed" }] : /* istanbul ignore next */ []));
1287
+ hostClasses = computed(() => cn('block', this.position() === 'right' && 'items-end text-right'), /* @ts-ignore */
1288
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1289
+ listClasses = computed(() => this.isCollapsed()
1290
+ ? cn('flex list-none flex-col items-center gap-0.5 p-0')
1291
+ : cn('flex list-none flex-col gap-0.5 p-0', this.position() === 'right' && 'items-end'), /* @ts-ignore */
1292
+ ...(ngDevMode ? [{ debugName: "listClasses" }] : /* istanbul ignore next */ []));
1293
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1294
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationListComponent, isStandalone: true, selector: "NavigationList", inputs: { navId: { classPropertyName: "navId", publicName: "navId", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, itemClass: { classPropertyName: "itemClass", publicName: "itemClass", isSignal: true, isRequired: false, transformFunction: null }, activeIds: { classPropertyName: "activeIds", publicName: "activeIds", isSignal: true, isRequired: false, transformFunction: null }, activeUrl: { classPropertyName: "activeUrl", publicName: "activeUrl", isSignal: true, isRequired: false, transformFunction: null }, iconTemplate: { classPropertyName: "iconTemplate", publicName: "iconTemplate", isSignal: true, isRequired: false, transformFunction: null }, collapseTree: { classPropertyName: "collapseTree", publicName: "collapseTree", isSignal: true, isRequired: false, transformFunction: null }, openedIds: { classPropertyName: "openedIds", publicName: "openedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openedIdsChange: "openedIdsChange", itemSelected: "itemSelected" }, host: { properties: { "class": "hostClasses()", "attr.data-position": "position()" } }, ngImport: i0, template: `
1295
+ <ul [class]="listClasses()" role="list">
1296
+ @for (item of items(); track item.key) {
1297
+ <li
1298
+ NavigationItem
1299
+ [navId]="navId()"
1300
+ [item]="item"
1301
+ [level]="0"
1302
+ [orientation]="'vertical'"
1303
+ [compact]="isCollapsed()"
1304
+ [itemClass]="itemClass()"
1305
+ [activeIds]="activeIds()"
1306
+ [activeUrl]="activeUrl()"
1307
+ [iconTemplate]="iconTemplate()"
1308
+ [collapseTree]="collapseTree()"
1309
+ [openedIds]="openedIds()"
1310
+ (openedIdsChange)="openedIdsChange.emit($event)"
1311
+ (itemSelected)="itemSelected.emit($event)"
1312
+ ></li>
1313
+ }
1314
+ </ul>
1315
+ `, isInline: true, dependencies: [{ kind: "component", type: NavigationItemComponent, selector: "li[NavigationItem]", inputs: ["navId", "item", "level", "orientation", "compact", "itemClass", "activeIds", "activeUrl", "iconTemplate", "collapseTree", "straightRail", "stairsRail", "straightRailActive", "firstInBranch", "lastInBranch", "openedIds"], outputs: ["openedIdsChange", "itemSelected"] }] });
1316
+ }
1317
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationListComponent, decorators: [{
1318
+ type: Component,
1319
+ args: [{
1320
+ selector: 'NavigationList',
1321
+ imports: [NavigationItemComponent],
1322
+ host: {
1323
+ '[class]': 'hostClasses()',
1324
+ '[attr.data-position]': 'position()',
1325
+ },
1326
+ template: `
1327
+ <ul [class]="listClasses()" role="list">
1328
+ @for (item of items(); track item.key) {
1329
+ <li
1330
+ NavigationItem
1331
+ [navId]="navId()"
1332
+ [item]="item"
1333
+ [level]="0"
1334
+ [orientation]="'vertical'"
1335
+ [compact]="isCollapsed()"
1336
+ [itemClass]="itemClass()"
1337
+ [activeIds]="activeIds()"
1338
+ [activeUrl]="activeUrl()"
1339
+ [iconTemplate]="iconTemplate()"
1340
+ [collapseTree]="collapseTree()"
1341
+ [openedIds]="openedIds()"
1342
+ (openedIdsChange)="openedIdsChange.emit($event)"
1343
+ (itemSelected)="itemSelected.emit($event)"
1344
+ ></li>
1345
+ }
1346
+ </ul>
1347
+ `,
1348
+ }]
1349
+ }], propDecorators: { navId: [{ type: i0.Input, args: [{ isSignal: true, alias: "navId", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], itemClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemClass", required: false }] }], activeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIds", required: false }] }], activeUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeUrl", required: false }] }], iconTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconTemplate", required: false }] }], collapseTree: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapseTree", required: false }] }], openedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "openedIds", required: false }] }], openedIdsChange: [{ type: i0.Output, args: ["openedIdsChange"] }], itemSelected: [{ type: i0.Output, args: ["itemSelected"] }] } });
1350
+
1351
+ /**
1352
+ * Area konten navigasi: merender daftar item sesuai type aktif dari
1353
+ * `<Navigation>` induk. Selalu hadir di setiap type — komponen type
1354
+ * merender default-nya bila consumer tidak memproyeksikan `<NavigationContent />`.
1355
+ */
1356
+ class NavigationContentComponent {
1357
+ container = inject(NavigationContainerComponent);
1358
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
1359
+ hostClasses = computed(() => cn('min-h-0 flex-1', this.container.displayState().orientation === 'horizontal'
1360
+ ? 'flex h-full min-w-0 items-stretch justify-center overflow-visible'
1361
+ : 'block overflow-y-auto overflow-x-hidden py-2', this.class()), /* @ts-ignore */
1362
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1363
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1364
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationContentComponent, isStandalone: true, selector: "NavigationContent", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
1365
+ @let navState = container.displayState();
1366
+
1367
+ @if (navState.orientation === 'horizontal' && navState.type === 'flyout') {
1368
+ <!-- Less-common renderers are code-split: a sidebar-only app never bundles them. -->
1369
+ @defer (on immediate) {
1370
+ <NavigationFlyoutMenu
1371
+ [navId]="navState.id"
1372
+ [items]="container.normalizedItems()"
1373
+ [label]="container.flyoutLabel()"
1374
+ [icon]="container.flyoutIcon()"
1375
+ [iconOnly]="container.flyoutIconOnly()"
1376
+ [iconPosition]="container.flyoutIconPosition()"
1377
+ [variant]="container.flyoutTriggerVariant()"
1378
+ [floating]="container.flyoutTriggerFloating()"
1379
+ [viewport]="container.flyoutPanelViewport()"
1380
+ [triggerClass]="container.flyoutTriggerClass()"
1381
+ [triggerButtonClass]="container.flyoutTriggerButtonClass()"
1382
+ [position]="navState.position"
1383
+ [typeStyle]="container.typeStyle()"
1384
+ [compact]="container.compact()"
1385
+ [itemClass]="container.itemClass()"
1386
+ [groupClass]="container.groupClass()"
1387
+ [activeIds]="container.activeIdSet()"
1388
+ [activeUrl]="container.activeUrl()"
1389
+ [iconTemplate]="container.iconTemplate()"
1390
+ [collapseTree]="container.collapseTree()"
1391
+ [openedIds]="container.openedIds()"
1392
+ (openedIdsChange)="container.openedIds.set($event)"
1393
+ (itemSelected)="container.itemSelected.emit($event)"
1394
+ >
1395
+ <ng-content select="NavigationHeader" ngProjectAs="NavigationHeader" />
1396
+ <ng-content select="NavigationFooter" ngProjectAs="NavigationFooter" />
1397
+ </NavigationFlyoutMenu>
1398
+ }
1399
+ } @else if (navState.orientation === 'horizontal') {
1400
+ @defer (on immediate) {
1401
+ <NavigationHorizontal
1402
+ [navId]="navState.id"
1403
+ [items]="container.normalizedItems()"
1404
+ [position]="navState.position"
1405
+ [typeStyle]="container.typeStyle()"
1406
+ [compact]="container.compact()"
1407
+ [itemClass]="container.itemClass()"
1408
+ [groupClass]="container.groupClass()"
1409
+ [activeIds]="container.activeIdSet()"
1410
+ [activeUrl]="container.activeUrl()"
1411
+ [iconTemplate]="container.iconTemplate()"
1412
+ [collapseTree]="container.collapseTree()"
1413
+ [openedIds]="container.openedIds()"
1414
+ (openedIdsChange)="container.openedIds.set($event)"
1415
+ (itemSelected)="container.itemSelected.emit($event)"
1416
+ />
1417
+ }
1418
+ } @else if (navState.type === 'dockbar') {
1419
+ @defer (on immediate) {
1420
+ <NavigationDockbarMenu
1421
+ [navId]="navState.id"
1422
+ [items]="container.normalizedItems()"
1423
+ [railItems]="container.dockbarRailItems()"
1424
+ [badgeContext]="container.dockbarBadgeContext()"
1425
+ [mode]="navState.dockbarMode"
1426
+ [position]="navState.position"
1427
+ [asideFooterTemplate]="container.dockbarAsideFooter()"
1428
+ [itemClass]="container.itemClass()"
1429
+ [activeIds]="container.dockbarResolvedActiveIds()"
1430
+ [resolvedGroup]="container.dockbarOpenGroup()"
1431
+ [activeUrl]="
1432
+ container.dockbarRouteEnabled()
1433
+ ? container.dockbarResolvedRouteContext().url
1434
+ : container.activeUrl()
1435
+ "
1436
+ [iconTemplate]="container.iconTemplate()"
1437
+ [collapseTree]="container.collapseTree()"
1438
+ [openedIds]="container.openedIds()"
1439
+ (openedIdsChange)="container.openedIds.set($event)"
1440
+ (itemSelected)="container.itemSelected.emit($event)"
1441
+ />
1442
+ }
1443
+ } @else {
1444
+ <!-- The vertical list (sidebar) is the common default — kept eager, no first-paint pop-in. -->
1445
+ <NavigationList
1446
+ [navId]="navState.id"
1447
+ [items]="container.normalizedItems()"
1448
+ [collapsed]="navState.collapsed"
1449
+ [position]="navState.position"
1450
+ [itemClass]="container.itemClass()"
1451
+ [activeIds]="container.activeIdSet()"
1452
+ [activeUrl]="container.activeUrl()"
1453
+ [iconTemplate]="container.iconTemplate()"
1454
+ [collapseTree]="container.collapseTree()"
1455
+ [openedIds]="container.openedIds()"
1456
+ (openedIdsChange)="container.openedIds.set($event)"
1457
+ (itemSelected)="container.itemSelected.emit($event)"
1458
+ />
1459
+ }
1460
+ `, isInline: true, dependencies: [{ kind: "component", type: NavigationListComponent, selector: "NavigationList", inputs: ["navId", "items", "collapsed", "compact", "position", "itemClass", "activeIds", "activeUrl", "iconTemplate", "collapseTree", "openedIds"], outputs: ["openedIdsChange", "itemSelected"] }], deferBlockDependencies: [() => [/* @ts-ignore */
1461
+ import('./ojiepermana-angular-navigation-navigation-flyout-menu.component-BCGvhoYj.mjs').then(m => m.NavigationFlyoutMenuComponent)], () => [/* @ts-ignore */
1462
+ import('./ojiepermana-angular-navigation-navigation-horizontal.component-Dk_03e-6.mjs').then(m => m.NavigationHorizontalComponent)], () => [/* @ts-ignore */
1463
+ import('./ojiepermana-angular-navigation-navigation-dockbar-menu.component-DBQHdvGa.mjs').then(m => m.NavigationDockbarMenuComponent)]] });
1464
+ }
1465
+ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.4", ngImport: i0, type: NavigationContentComponent, resolveDeferredDeps: () => [/* @ts-ignore */
1466
+ import('./ojiepermana-angular-navigation-navigation-flyout-menu.component-BCGvhoYj.mjs').then(m => m.NavigationFlyoutMenuComponent), /* @ts-ignore */
1467
+ import('./ojiepermana-angular-navigation-navigation-horizontal.component-Dk_03e-6.mjs').then(m => m.NavigationHorizontalComponent), /* @ts-ignore */
1468
+ import('./ojiepermana-angular-navigation-navigation-dockbar-menu.component-DBQHdvGa.mjs').then(m => m.NavigationDockbarMenuComponent)], resolveMetadata: (NavigationFlyoutMenuComponent, NavigationHorizontalComponent, NavigationDockbarMenuComponent) => ({ decorators: [{
1469
+ type: Component,
1470
+ args: [{
1471
+ selector: 'NavigationContent',
1472
+ imports: [
1473
+ NavigationDockbarMenuComponent,
1474
+ NavigationFlyoutMenuComponent,
1475
+ NavigationHorizontalComponent,
1476
+ NavigationListComponent,
1477
+ ],
1478
+ host: {
1479
+ '[class]': 'hostClasses()',
1480
+ },
1481
+ template: `
1482
+ @let navState = container.displayState();
1483
+
1484
+ @if (navState.orientation === 'horizontal' && navState.type === 'flyout') {
1485
+ <!-- Less-common renderers are code-split: a sidebar-only app never bundles them. -->
1486
+ @defer (on immediate) {
1487
+ <NavigationFlyoutMenu
1488
+ [navId]="navState.id"
1489
+ [items]="container.normalizedItems()"
1490
+ [label]="container.flyoutLabel()"
1491
+ [icon]="container.flyoutIcon()"
1492
+ [iconOnly]="container.flyoutIconOnly()"
1493
+ [iconPosition]="container.flyoutIconPosition()"
1494
+ [variant]="container.flyoutTriggerVariant()"
1495
+ [floating]="container.flyoutTriggerFloating()"
1496
+ [viewport]="container.flyoutPanelViewport()"
1497
+ [triggerClass]="container.flyoutTriggerClass()"
1498
+ [triggerButtonClass]="container.flyoutTriggerButtonClass()"
1499
+ [position]="navState.position"
1500
+ [typeStyle]="container.typeStyle()"
1501
+ [compact]="container.compact()"
1502
+ [itemClass]="container.itemClass()"
1503
+ [groupClass]="container.groupClass()"
1504
+ [activeIds]="container.activeIdSet()"
1505
+ [activeUrl]="container.activeUrl()"
1506
+ [iconTemplate]="container.iconTemplate()"
1507
+ [collapseTree]="container.collapseTree()"
1508
+ [openedIds]="container.openedIds()"
1509
+ (openedIdsChange)="container.openedIds.set($event)"
1510
+ (itemSelected)="container.itemSelected.emit($event)"
1511
+ >
1512
+ <ng-content select="NavigationHeader" ngProjectAs="NavigationHeader" />
1513
+ <ng-content select="NavigationFooter" ngProjectAs="NavigationFooter" />
1514
+ </NavigationFlyoutMenu>
1515
+ }
1516
+ } @else if (navState.orientation === 'horizontal') {
1517
+ @defer (on immediate) {
1518
+ <NavigationHorizontal
1519
+ [navId]="navState.id"
1520
+ [items]="container.normalizedItems()"
1521
+ [position]="navState.position"
1522
+ [typeStyle]="container.typeStyle()"
1523
+ [compact]="container.compact()"
1524
+ [itemClass]="container.itemClass()"
1525
+ [groupClass]="container.groupClass()"
1526
+ [activeIds]="container.activeIdSet()"
1527
+ [activeUrl]="container.activeUrl()"
1528
+ [iconTemplate]="container.iconTemplate()"
1529
+ [collapseTree]="container.collapseTree()"
1530
+ [openedIds]="container.openedIds()"
1531
+ (openedIdsChange)="container.openedIds.set($event)"
1532
+ (itemSelected)="container.itemSelected.emit($event)"
1533
+ />
1534
+ }
1535
+ } @else if (navState.type === 'dockbar') {
1536
+ @defer (on immediate) {
1537
+ <NavigationDockbarMenu
1538
+ [navId]="navState.id"
1539
+ [items]="container.normalizedItems()"
1540
+ [railItems]="container.dockbarRailItems()"
1541
+ [badgeContext]="container.dockbarBadgeContext()"
1542
+ [mode]="navState.dockbarMode"
1543
+ [position]="navState.position"
1544
+ [asideFooterTemplate]="container.dockbarAsideFooter()"
1545
+ [itemClass]="container.itemClass()"
1546
+ [activeIds]="container.dockbarResolvedActiveIds()"
1547
+ [resolvedGroup]="container.dockbarOpenGroup()"
1548
+ [activeUrl]="
1549
+ container.dockbarRouteEnabled()
1550
+ ? container.dockbarResolvedRouteContext().url
1551
+ : container.activeUrl()
1552
+ "
1553
+ [iconTemplate]="container.iconTemplate()"
1554
+ [collapseTree]="container.collapseTree()"
1555
+ [openedIds]="container.openedIds()"
1556
+ (openedIdsChange)="container.openedIds.set($event)"
1557
+ (itemSelected)="container.itemSelected.emit($event)"
1558
+ />
1559
+ }
1560
+ } @else {
1561
+ <!-- The vertical list (sidebar) is the common default — kept eager, no first-paint pop-in. -->
1562
+ <NavigationList
1563
+ [navId]="navState.id"
1564
+ [items]="container.normalizedItems()"
1565
+ [collapsed]="navState.collapsed"
1566
+ [position]="navState.position"
1567
+ [itemClass]="container.itemClass()"
1568
+ [activeIds]="container.activeIdSet()"
1569
+ [activeUrl]="container.activeUrl()"
1570
+ [iconTemplate]="container.iconTemplate()"
1571
+ [collapseTree]="container.collapseTree()"
1572
+ [openedIds]="container.openedIds()"
1573
+ (openedIdsChange)="container.openedIds.set($event)"
1574
+ (itemSelected)="container.itemSelected.emit($event)"
1575
+ />
1576
+ }
1577
+ `,
1578
+ }]
1579
+ }], ctorParameters: null, propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } }) });
1580
+
1581
+ class NavigationFooterComponent {
1582
+ shell = inject(NAVIGATION_SHELL, { optional: true });
1583
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
1584
+ isHorizontal = computed(() => this.shell?.displayState().orientation === 'horizontal', /* @ts-ignore */
1585
+ ...(ngDevMode ? [{ debugName: "isHorizontal" }] : /* istanbul ignore next */ []));
1586
+ displayCollapsed = computed(() => this.shell?.displayState().collapsed ?? false, /* @ts-ignore */
1587
+ ...(ngDevMode ? [{ debugName: "displayCollapsed" }] : /* istanbul ignore next */ []));
1588
+ /**
1589
+ * Baris isi footer. Saat collapsed/dockbar (vertical) isi (inisial user) dipusatkan
1590
+ * di tengah rail agar simetris dengan `NavigationHeader` dan ikon nav-item; selain
1591
+ * itu rata kiri dengan `gap-3` (padding diserahkan consumer, mis. `px-3`).
1592
+ */
1593
+ rowClasses = computed(() => cn('flex h-full min-w-0 w-full items-center', !this.isHorizontal() && this.displayCollapsed() ? 'justify-center' : 'gap-3'), /* @ts-ignore */
1594
+ ...(ngDevMode ? [{ debugName: "rowClasses" }] : /* istanbul ignore next */ []));
1595
+ hostClasses = computed(() => cn(this.isHorizontal()
1596
+ ? 'relative z-10 block h-full w-auto shrink-0'
1597
+ : 'sticky bottom-0 z-10 block h-(--layout-topbar-height) shrink-0 border-t border-[hsl(var(--border)/var(--section-border-opacity))]', this.class()), /* @ts-ignore */
1598
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1599
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1600
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: NavigationFooterComponent, isStandalone: true, selector: "NavigationFooter", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.data-collapsed": "displayCollapsed()" } }, ngImport: i0, template: `
1601
+ <div [class]="rowClasses()">
1602
+ <ng-content />
1603
+ </div>
1604
+ `, isInline: true });
1605
+ }
1606
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFooterComponent, decorators: [{
1607
+ type: Component,
1608
+ args: [{
1609
+ selector: 'NavigationFooter',
1610
+ host: {
1611
+ '[class]': 'hostClasses()',
1612
+ '[attr.data-collapsed]': 'displayCollapsed()',
1613
+ },
1614
+ template: `
1615
+ <div [class]="rowClasses()">
1616
+ <ng-content />
1617
+ </div>
1618
+ `,
1619
+ }]
1620
+ }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
1621
+
1622
+ class NavigationHeaderComponent {
1623
+ shell = inject(NAVIGATION_SHELL);
1624
+ toggle = input(false, /* @ts-ignore */
1625
+ ...(ngDevMode ? [{ debugName: "toggle" }] : /* istanbul ignore next */ []));
1626
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
1627
+ collapsed = computed(() => this.shell.state().collapsed, /* @ts-ignore */
1628
+ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
1629
+ displayCollapsed = computed(() => this.shell.displayState().collapsed, /* @ts-ignore */
1630
+ ...(ngDevMode ? [{ debugName: "displayCollapsed" }] : /* istanbul ignore next */ []));
1631
+ isHorizontal = computed(() => this.shell.displayState().orientation === 'horizontal', /* @ts-ignore */
1632
+ ...(ngDevMode ? [{ debugName: "isHorizontal" }] : /* istanbul ignore next */ []));
1633
+ /**
1634
+ * The toggle used to disappear once the rail collapsed, which left the
1635
+ * collapsed rail with no control that could expand it again — nested items
1636
+ * below a collapsible were then reachable by hover only.
1637
+ */
1638
+ showToggle = computed(() => {
1639
+ if (this.isHorizontal()) {
1640
+ return false;
1641
+ }
1642
+ return this.toggle() || this.shell.collapseEnabled();
1643
+ }, /* @ts-ignore */
1644
+ ...(ngDevMode ? [{ debugName: "showToggle" }] : /* istanbul ignore next */ []));
1645
+ toggleAriaLabel = computed(() => this.collapsed() ? 'Expand navigation' : 'Collapse navigation', /* @ts-ignore */
1646
+ ...(ngDevMode ? [{ debugName: "toggleAriaLabel" }] : /* istanbul ignore next */ []));
1647
+ toggleIconName = computed(() => this.collapsed() ? 'left_panel_open' : 'left_panel_close', /* @ts-ignore */
1648
+ ...(ngDevMode ? [{ debugName: "toggleIconName" }] : /* istanbul ignore next */ []));
1649
+ /**
1650
+ * Baris isi header. Saat collapsed/dockbar (vertical) isi (inisial/ikon) dipusatkan di tengah
1651
+ * rail agar simetris dengan ikon nav-item di bawahnya (yang juga center di rail); selain itu kiri
1652
+ * dengan padding `px-3`.
1653
+ */
1654
+ rowClasses = computed(() => cn('flex h-full items-center', !this.isHorizontal() && this.displayCollapsed() ? 'justify-center' : 'gap-3 px-3'), /* @ts-ignore */
1655
+ ...(ngDevMode ? [{ debugName: "rowClasses" }] : /* istanbul ignore next */ []));
1656
+ contentClasses = computed(() => {
1657
+ if (this.isHorizontal()) {
1658
+ return 'flex min-w-0 items-center gap-3';
1659
+ }
1660
+ // Collapsed/dockbar: inisial center (tanpa `flex-1` yang membuatnya rata kiri).
1661
+ return this.displayCollapsed()
1662
+ ? 'flex min-w-0 items-center justify-center'
1663
+ : 'flex min-w-0 flex-1 items-center gap-3';
1664
+ }, /* @ts-ignore */
1665
+ ...(ngDevMode ? [{ debugName: "contentClasses" }] : /* istanbul ignore next */ []));
1666
+ hostClasses = computed(() => cn(this.isHorizontal()
1667
+ ? 'relative z-10 block h-full w-auto shrink-0'
1668
+ : 'sticky top-0 z-10 block h-(--layout-topbar-height) shrink-0 border-b border-[hsl(var(--border)/var(--section-border-opacity))]', this.class()), /* @ts-ignore */
1669
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1670
+ toggleCollapsed() {
1671
+ this.shell.toggleCollapsed();
1672
+ }
1673
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1674
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationHeaderComponent, isStandalone: true, selector: "NavigationHeader", inputs: { toggle: { classPropertyName: "toggle", publicName: "toggle", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.data-collapsed": "displayCollapsed()" } }, ngImport: i0, template: `
1675
+ <div [class]="rowClasses()">
1676
+ <div [class]="contentClasses()">
1677
+ <ng-content />
1678
+ </div>
1679
+
1680
+ @if (showToggle()) {
1681
+ <button
1682
+ type="button"
1683
+ class="inline-flex size-8 shrink-0 items-center justify-center bg-transparent text-foreground/80 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
1684
+ [attr.aria-label]="toggleAriaLabel()"
1685
+ [attr.title]="toggleAriaLabel()"
1686
+ data-navigation-header-toggle="true"
1687
+ (click)="toggleCollapsed()"
1688
+ >
1689
+ <Icon
1690
+ data-navigation-header-toggle-icon="true"
1691
+ [name]="toggleIconName()"
1692
+ size="inherit"
1693
+ class="text-(length:--nav-icon-size)"
1694
+ />
1695
+ </button>
1696
+ }
1697
+ </div>
1698
+ `, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }] });
1699
+ }
1700
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationHeaderComponent, decorators: [{
1701
+ type: Component,
1702
+ args: [{
1703
+ selector: 'NavigationHeader',
1704
+ imports: [IconComponent],
1705
+ host: {
1706
+ '[class]': 'hostClasses()',
1707
+ '[attr.data-collapsed]': 'displayCollapsed()',
1708
+ },
1709
+ template: `
1710
+ <div [class]="rowClasses()">
1711
+ <div [class]="contentClasses()">
1712
+ <ng-content />
1713
+ </div>
1714
+
1715
+ @if (showToggle()) {
1716
+ <button
1717
+ type="button"
1718
+ class="inline-flex size-8 shrink-0 items-center justify-center bg-transparent text-foreground/80 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
1719
+ [attr.aria-label]="toggleAriaLabel()"
1720
+ [attr.title]="toggleAriaLabel()"
1721
+ data-navigation-header-toggle="true"
1722
+ (click)="toggleCollapsed()"
1723
+ >
1724
+ <Icon
1725
+ data-navigation-header-toggle-icon="true"
1726
+ [name]="toggleIconName()"
1727
+ size="inherit"
1728
+ class="text-(length:--nav-icon-size)"
1729
+ />
1730
+ </button>
1731
+ }
1732
+ </div>
1733
+ `,
1734
+ }]
1735
+ }], propDecorators: { toggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggle", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
1736
+
1737
+ /**
1738
+ * Type sidebar vertikal untuk `<Navigation>`. Slot `NavigationHeader` dan
1739
+ * `NavigationFooter` opsional; `NavigationContent` selalu dirender (default
1740
+ * otomatis bila tidak diproyeksikan).
1741
+ */
1742
+ class NavigationSidebarComponent {
1743
+ container = inject(NavigationContainerComponent);
1744
+ destroyRef = inject(DestroyRef);
1745
+ position = input(null, /* @ts-ignore */
1746
+ ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
1747
+ collapsed = input(null, /* @ts-ignore */
1748
+ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
1749
+ collapse = input(false, { ...(ngDevMode ? { debugName: "collapse" } : /* istanbul ignore next */ {}), alias: 'nav-sidebar-collapse', transform: booleanAttribute });
1750
+ previewExpanded = input(false, /* @ts-ignore */
1751
+ ...(ngDevMode ? [{ debugName: "previewExpanded" }] : /* istanbul ignore next */ []));
1752
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
1753
+ headerSlot = contentChild(NavigationHeaderComponent, /* @ts-ignore */
1754
+ ...(ngDevMode ? [{ debugName: "headerSlot" }] : /* istanbul ignore next */ []));
1755
+ contentSlot = contentChild(NavigationContentComponent, /* @ts-ignore */
1756
+ ...(ngDevMode ? [{ debugName: "contentSlot" }] : /* istanbul ignore next */ []));
1757
+ footerSlot = contentChild(NavigationFooterComponent, /* @ts-ignore */
1758
+ ...(ngDevMode ? [{ debugName: "footerSlot" }] : /* istanbul ignore next */ []));
1759
+ hostClasses = computed(() => cn(this.container.shellClasses(), this.class()), /* @ts-ignore */
1760
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1761
+ constructor() {
1762
+ const config = {
1763
+ orientation: 'vertical',
1764
+ type: 'sidebar',
1765
+ position: this.position,
1766
+ collapsed: this.collapsed,
1767
+ sidebarCollapse: this.collapse,
1768
+ previewExpanded: this.previewExpanded,
1769
+ };
1770
+ this.container.registerType(config);
1771
+ this.destroyRef.onDestroy(() => this.container.unregisterType(config));
1772
+ }
1773
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1774
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationSidebarComponent, isStandalone: true, selector: "NavigationSidebar", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, collapse: { classPropertyName: "collapse", publicName: "nav-sidebar-collapse", isSignal: true, isRequired: false, transformFunction: null }, previewExpanded: { classPropertyName: "previewExpanded", publicName: "previewExpanded", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, queries: [{ propertyName: "headerSlot", first: true, predicate: NavigationHeaderComponent, descendants: true, isSignal: true }, { propertyName: "contentSlot", first: true, predicate: NavigationContentComponent, descendants: true, isSignal: true }, { propertyName: "footerSlot", first: true, predicate: NavigationFooterComponent, descendants: true, isSignal: true }], ngImport: i0, template: `
1775
+ @if (headerSlot()) {
1776
+ <ng-content select="NavigationHeader" />
1777
+ }
1778
+
1779
+ @if (contentSlot()) {
1780
+ <ng-content select="NavigationContent" />
1781
+ } @else {
1782
+ <NavigationContent />
1783
+ }
1784
+
1785
+ @if (footerSlot()) {
1786
+ <ng-content select="NavigationFooter" />
1787
+ }
1788
+ `, isInline: true, dependencies: [{ kind: "component", type: NavigationContentComponent, selector: "NavigationContent", inputs: ["class"] }] });
1789
+ }
1790
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationSidebarComponent, decorators: [{
1791
+ type: Component,
1792
+ args: [{
1793
+ selector: 'NavigationSidebar',
1794
+ imports: [NavigationContentComponent],
1795
+ host: {
1796
+ '[class]': 'hostClasses()',
1797
+ },
1798
+ template: `
1799
+ @if (headerSlot()) {
1800
+ <ng-content select="NavigationHeader" />
1801
+ }
1802
+
1803
+ @if (contentSlot()) {
1804
+ <ng-content select="NavigationContent" />
1805
+ } @else {
1806
+ <NavigationContent />
1807
+ }
1808
+
1809
+ @if (footerSlot()) {
1810
+ <ng-content select="NavigationFooter" />
1811
+ }
1812
+ `,
1813
+ }]
1814
+ }], ctorParameters: () => [], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], collapse: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-sidebar-collapse", required: false }] }], previewExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewExpanded", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], headerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationHeaderComponent), { isSignal: true }] }], contentSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationContentComponent), { isSignal: true }] }], footerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationFooterComponent), { isSignal: true }] }] } });
1815
+
1816
+ /**
1817
+ * Slot footer untuk aside dockbar. Proyeksikan sebagai `ng-template` di dalam
1818
+ * `<NavigationDockbar>`; dirender di dasar aside (h-12, border-t) setiap kali
1819
+ * panel group terbuka — baik mode `sticky` maupun `drawer`.
1820
+ *
1821
+ * ```html
1822
+ * <NavigationDockbar>
1823
+ * <NavigationFooter>…rail…</NavigationFooter>
1824
+ * <ng-template NavigationAsideFooter>…identitas user + aksi…</ng-template>
1825
+ * </NavigationDockbar>
1826
+ * ```
1827
+ *
1828
+ * Berbeda dengan `NavigationFooter` (kolom rail, selalu collapsed pada dockbar),
1829
+ * isi template ini tampil dalam konteks lebar penuh aside — cocok untuk nama +
1830
+ * email + tombol aksi seperti footer sidebar expanded.
1831
+ */
1832
+ class NavigationAsideFooterDirective {
1833
+ templateRef = inject((TemplateRef));
1834
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationAsideFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1835
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: NavigationAsideFooterDirective, isStandalone: true, selector: "ng-template[NavigationAsideFooter]", ngImport: i0 });
1836
+ }
1837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationAsideFooterDirective, decorators: [{
1838
+ type: Directive,
1839
+ args: [{
1840
+ selector: 'ng-template[NavigationAsideFooter]',
1841
+ }]
1842
+ }] });
1843
+
1844
+ const EMPTY_NAVIGATION_BADGE_CONTEXT = Object.freeze({});
1845
+ /**
1846
+ * Type dockbar vertikal (rail ikon + aside) untuk `<Navigation>`. Slot
1847
+ * `NavigationHeader` dan `NavigationFooter` opsional; `NavigationContent`
1848
+ * selalu dirender (default otomatis bila tidak diproyeksikan). Slot
1849
+ * `ng-template[NavigationAsideFooter]` opsional — dirender sebagai footer di
1850
+ * dasar aside saat panel group terbuka.
1851
+ */
1852
+ class NavigationDockbarComponent {
1853
+ container = inject(NavigationContainerComponent);
1854
+ destroyRef = inject(DestroyRef);
1855
+ host = inject(ElementRef);
1856
+ injector = inject(Injector);
1857
+ mode = input(null, /* @ts-ignore */
1858
+ ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
1859
+ position = input(null, /* @ts-ignore */
1860
+ ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
1861
+ routeContext = input(null, { ...(ngDevMode ? { debugName: "routeContext" } : /* istanbul ignore next */ {}), alias: 'dockbar-route-context' });
1862
+ badgeContext = input(EMPTY_NAVIGATION_BADGE_CONTEXT, { ...(ngDevMode ? { debugName: "badgeContext" } : /* istanbul ignore next */ {}), alias: 'dockbar-badge' });
1863
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
1864
+ headerSlot = contentChild(NavigationHeaderComponent, /* @ts-ignore */
1865
+ ...(ngDevMode ? [{ debugName: "headerSlot" }] : /* istanbul ignore next */ []));
1866
+ contentSlot = contentChild(NavigationContentComponent, /* @ts-ignore */
1867
+ ...(ngDevMode ? [{ debugName: "contentSlot" }] : /* istanbul ignore next */ []));
1868
+ footerSlot = contentChild(NavigationFooterComponent, /* @ts-ignore */
1869
+ ...(ngDevMode ? [{ debugName: "footerSlot" }] : /* istanbul ignore next */ []));
1870
+ asideFooterSlot = contentChild(NavigationAsideFooterDirective, /* @ts-ignore */
1871
+ ...(ngDevMode ? [{ debugName: "asideFooterSlot" }] : /* istanbul ignore next */ []));
1872
+ routeContextEnabled = computed(() => {
1873
+ const context = this.routeContext();
1874
+ return context !== null && context !== false;
1875
+ }, /* @ts-ignore */
1876
+ ...(ngDevMode ? [{ debugName: "routeContextEnabled" }] : /* istanbul ignore next */ []));
1877
+ hostClasses = computed(() => cn(this.container.shellClasses(), this.class()), /* @ts-ignore */
1878
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1879
+ constructor() {
1880
+ const config = {
1881
+ orientation: 'vertical',
1882
+ type: 'dockbar',
1883
+ position: this.position,
1884
+ dockbarMode: this.mode,
1885
+ dockbarRouteContext: this.routeContext,
1886
+ dockbarBadgeContext: this.badgeContext,
1887
+ dockbarRouteHeaderVisible: computed(() => this.routeContextEnabled() && this.headerSlot() === undefined),
1888
+ dockbarAsideFooter: computed(() => this.asideFooterSlot()?.templateRef ?? null),
1889
+ };
1890
+ this.container.registerType(config);
1891
+ this.destroyRef.onDestroy(() => this.container.unregisterType(config));
1892
+ }
1893
+ onPointerOut(event) {
1894
+ const relatedTarget = event.relatedTarget;
1895
+ const nodeType = this.host.nativeElement.ownerDocument.defaultView?.Node;
1896
+ if (relatedTarget !== null &&
1897
+ nodeType !== undefined &&
1898
+ relatedTarget instanceof nodeType &&
1899
+ this.host.nativeElement.contains(relatedTarget)) {
1900
+ return;
1901
+ }
1902
+ this.container.restoreDockbarRoutePanel();
1903
+ }
1904
+ onEscape(event) {
1905
+ const state = this.container.resolvedState();
1906
+ // Escape dari menu/aside sudah ditangani child dan ditandai preventDefault.
1907
+ // Handler host ini menutup gap saat fokus kembali ke route-header sibling.
1908
+ if (event.defaultPrevented || state.type !== 'dockbar' || state.dockbarMode !== 'drawer') {
1909
+ return;
1910
+ }
1911
+ if (!this.container.closeDockbarPanel()) {
1912
+ return;
1913
+ }
1914
+ event.preventDefault();
1915
+ this.host.nativeElement
1916
+ .querySelector('[data-navigation-dockbar-route-trigger="true"]')
1917
+ ?.focus();
1918
+ }
1919
+ toggleActiveRoutePanel() {
1920
+ const wasExpanded = this.container.dockbarActiveRoutePanelExpanded();
1921
+ this.container.toggleDockbarActiveRoutePanel();
1922
+ if (!wasExpanded) {
1923
+ afterNextRender({
1924
+ read: () => {
1925
+ const aside = this.host.nativeElement.querySelector(`#${this.container.dockbarAsideId()}`);
1926
+ aside
1927
+ ?.querySelector('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])')
1928
+ ?.focus();
1929
+ },
1930
+ }, { injector: this.injector });
1931
+ }
1932
+ }
1933
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationDockbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1934
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationDockbarComponent, isStandalone: true, selector: "NavigationDockbar", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, routeContext: { classPropertyName: "routeContext", publicName: "dockbar-route-context", isSignal: true, isRequired: false, transformFunction: null }, badgeContext: { classPropertyName: "badgeContext", publicName: "dockbar-badge", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown.escape": "onEscape($event)", "pointerout": "onPointerOut($event)" }, properties: { "class": "hostClasses()" } }, queries: [{ propertyName: "headerSlot", first: true, predicate: NavigationHeaderComponent, descendants: true, isSignal: true }, { propertyName: "contentSlot", first: true, predicate: NavigationContentComponent, descendants: true, isSignal: true }, { propertyName: "footerSlot", first: true, predicate: NavigationFooterComponent, descendants: true, isSignal: true }, { propertyName: "asideFooterSlot", first: true, predicate: NavigationAsideFooterDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
1935
+ @if (headerSlot()) {
1936
+ <ng-content select="NavigationHeader" />
1937
+ } @else if (container.dockbarRouteHeader(); as routeHeader) {
1938
+ <NavigationHeader>
1939
+ <ng-template #routeIndicator>
1940
+ <span
1941
+ aria-hidden="true"
1942
+ class="inline-flex items-center justify-center text-(length:--nav-icon-size-rail) text-current"
1943
+ >
1944
+ @if (container.iconTemplate(); as customIcon) {
1945
+ <ng-container
1946
+ [ngTemplateOutlet]="customIcon.template"
1947
+ [ngTemplateOutletContext]="routeHeader.iconContext"
1948
+ />
1949
+ } @else {
1950
+ <Icon [name]="routeHeader.icon" size="inherit" [fill]="1" />
1951
+ }
1952
+ </span>
1953
+
1954
+ @if (routeHeader.badge; as badge) {
1955
+ @defer (on immediate) {
1956
+ <NavigationBadgeCount [badge]="badge" [class]="routeHeader.badgeClass" />
1957
+ }
1958
+ }
1959
+ </ng-template>
1960
+
1961
+ @if (routeHeader.panelGroup && container.resolvedState().dockbarMode === 'drawer') {
1962
+ <button
1963
+ type="button"
1964
+ data-navigation-dockbar-route-header="true"
1965
+ data-navigation-dockbar-route-trigger="true"
1966
+ [attr.data-navigation-item-key]="routeHeader.activeEntry?.key"
1967
+ class="relative inline-flex size-(--nav-rail-item-size) items-center justify-center rounded-md bg-accent text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
1968
+ [attr.aria-controls]="container.dockbarAsideId()"
1969
+ [attr.aria-expanded]="container.dockbarActiveRoutePanelExpanded()"
1970
+ (click)="toggleActiveRoutePanel()"
1971
+ >
1972
+ <span class="sr-only">{{ routeHeader.label }}</span>
1973
+ <ng-container [ngTemplateOutlet]="routeIndicator" />
1974
+ </button>
1975
+ } @else {
1976
+ <span
1977
+ data-navigation-dockbar-route-header="true"
1978
+ class="relative inline-flex size-(--nav-rail-item-size) items-center justify-center text-foreground"
1979
+ >
1980
+ <span class="sr-only">{{ routeHeader.label }}</span>
1981
+ <ng-container [ngTemplateOutlet]="routeIndicator" />
1982
+ </span>
1983
+ }
1984
+ </NavigationHeader>
1985
+ }
1986
+
1987
+ @if (contentSlot()) {
1988
+ <ng-content select="NavigationContent" />
1989
+ } @else {
1990
+ <NavigationContent />
1991
+ }
1992
+
1993
+ @if (footerSlot()) {
1994
+ <ng-content select="NavigationFooter" />
1995
+ }
1996
+ `, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }, { kind: "component", type: NavigationContentComponent, selector: "NavigationContent", inputs: ["class"] }, { kind: "component", type: NavigationHeaderComponent, selector: "NavigationHeader", inputs: ["toggle", "class"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], deferBlockDependencies: [() => [/* @ts-ignore */
1997
+ import('./ojiepermana-angular-navigation-navigation-badge-count.component-CDBxQ8rk.mjs').then(m => m.NavigationBadgeCountComponent)]] });
1998
+ }
1999
+ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.4", ngImport: i0, type: NavigationDockbarComponent, resolveDeferredDeps: () => [/* @ts-ignore */
2000
+ import('./ojiepermana-angular-navigation-navigation-badge-count.component-CDBxQ8rk.mjs').then(m => m.NavigationBadgeCountComponent)], resolveMetadata: NavigationBadgeCountComponent => ({ decorators: [{
2001
+ type: Component,
2002
+ args: [{
2003
+ selector: 'NavigationDockbar',
2004
+ imports: [
2005
+ IconComponent,
2006
+ NavigationBadgeCountComponent,
2007
+ NavigationContentComponent,
2008
+ NavigationHeaderComponent,
2009
+ NgTemplateOutlet,
2010
+ ],
2011
+ host: {
2012
+ '[class]': 'hostClasses()',
2013
+ '(keydown.escape)': 'onEscape($event)',
2014
+ '(pointerout)': 'onPointerOut($event)',
2015
+ },
2016
+ template: `
2017
+ @if (headerSlot()) {
2018
+ <ng-content select="NavigationHeader" />
2019
+ } @else if (container.dockbarRouteHeader(); as routeHeader) {
2020
+ <NavigationHeader>
2021
+ <ng-template #routeIndicator>
2022
+ <span
2023
+ aria-hidden="true"
2024
+ class="inline-flex items-center justify-center text-(length:--nav-icon-size-rail) text-current"
2025
+ >
2026
+ @if (container.iconTemplate(); as customIcon) {
2027
+ <ng-container
2028
+ [ngTemplateOutlet]="customIcon.template"
2029
+ [ngTemplateOutletContext]="routeHeader.iconContext"
2030
+ />
2031
+ } @else {
2032
+ <Icon [name]="routeHeader.icon" size="inherit" [fill]="1" />
2033
+ }
2034
+ </span>
2035
+
2036
+ @if (routeHeader.badge; as badge) {
2037
+ @defer (on immediate) {
2038
+ <NavigationBadgeCount [badge]="badge" [class]="routeHeader.badgeClass" />
2039
+ }
2040
+ }
2041
+ </ng-template>
2042
+
2043
+ @if (routeHeader.panelGroup && container.resolvedState().dockbarMode === 'drawer') {
2044
+ <button
2045
+ type="button"
2046
+ data-navigation-dockbar-route-header="true"
2047
+ data-navigation-dockbar-route-trigger="true"
2048
+ [attr.data-navigation-item-key]="routeHeader.activeEntry?.key"
2049
+ class="relative inline-flex size-(--nav-rail-item-size) items-center justify-center rounded-md bg-accent text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
2050
+ [attr.aria-controls]="container.dockbarAsideId()"
2051
+ [attr.aria-expanded]="container.dockbarActiveRoutePanelExpanded()"
2052
+ (click)="toggleActiveRoutePanel()"
2053
+ >
2054
+ <span class="sr-only">{{ routeHeader.label }}</span>
2055
+ <ng-container [ngTemplateOutlet]="routeIndicator" />
2056
+ </button>
2057
+ } @else {
2058
+ <span
2059
+ data-navigation-dockbar-route-header="true"
2060
+ class="relative inline-flex size-(--nav-rail-item-size) items-center justify-center text-foreground"
2061
+ >
2062
+ <span class="sr-only">{{ routeHeader.label }}</span>
2063
+ <ng-container [ngTemplateOutlet]="routeIndicator" />
2064
+ </span>
2065
+ }
2066
+ </NavigationHeader>
2067
+ }
2068
+
2069
+ @if (contentSlot()) {
2070
+ <ng-content select="NavigationContent" />
2071
+ } @else {
2072
+ <NavigationContent />
2073
+ }
2074
+
2075
+ @if (footerSlot()) {
2076
+ <ng-content select="NavigationFooter" />
2077
+ }
2078
+ `,
2079
+ }]
2080
+ }], ctorParameters: () => [], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], routeContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dockbar-route-context", required: false }] }], badgeContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dockbar-badge", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], headerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationHeaderComponent), { isSignal: true }] }], contentSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationContentComponent), { isSignal: true }] }], footerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationFooterComponent), { isSignal: true }] }], asideFooterSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationAsideFooterDirective), { isSignal: true }] }] } }) });
2081
+
2082
+ /**
2083
+ * Type navbar horizontal untuk `<Navigation>`. Slot `NavigationHeader`
2084
+ * dan `NavigationFooter` opsional; `NavigationContent` selalu dirender
2085
+ * (default otomatis bila tidak diproyeksikan).
2086
+ */
2087
+ class NavigationNavbarComponent {
2088
+ container = inject(NavigationContainerComponent);
2089
+ destroyRef = inject(DestroyRef);
2090
+ /** Posisi bar terhadap konten layout: `top` (default) atau `bottom` — panel grid membuka ke arah sebaliknya. */
2091
+ position = input(null, { ...(ngDevMode ? { debugName: "position" } : /* istanbul ignore next */ {}), alias: 'nav-position' });
2092
+ typeStyle = input('flat', { ...(ngDevMode ? { debugName: "typeStyle" } : /* istanbul ignore next */ {}), alias: 'nav-type-style' });
2093
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
2094
+ headerSlot = contentChild(NavigationHeaderComponent, /* @ts-ignore */
2095
+ ...(ngDevMode ? [{ debugName: "headerSlot" }] : /* istanbul ignore next */ []));
2096
+ contentSlot = contentChild(NavigationContentComponent, /* @ts-ignore */
2097
+ ...(ngDevMode ? [{ debugName: "contentSlot" }] : /* istanbul ignore next */ []));
2098
+ footerSlot = contentChild(NavigationFooterComponent, /* @ts-ignore */
2099
+ ...(ngDevMode ? [{ debugName: "footerSlot" }] : /* istanbul ignore next */ []));
2100
+ hostClasses = computed(() => cn(this.container.shellClasses(), this.class()), /* @ts-ignore */
2101
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2102
+ constructor() {
2103
+ const config = {
2104
+ orientation: 'horizontal',
2105
+ type: 'navbar',
2106
+ position: this.position,
2107
+ typeStyle: this.typeStyle,
2108
+ };
2109
+ this.container.registerType(config);
2110
+ this.destroyRef.onDestroy(() => this.container.unregisterType(config));
2111
+ }
2112
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationNavbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2113
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationNavbarComponent, isStandalone: true, selector: "NavigationNavbar", inputs: { position: { classPropertyName: "position", publicName: "nav-position", isSignal: true, isRequired: false, transformFunction: null }, typeStyle: { classPropertyName: "typeStyle", publicName: "nav-type-style", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, queries: [{ propertyName: "headerSlot", first: true, predicate: NavigationHeaderComponent, descendants: true, isSignal: true }, { propertyName: "contentSlot", first: true, predicate: NavigationContentComponent, descendants: true, isSignal: true }, { propertyName: "footerSlot", first: true, predicate: NavigationFooterComponent, descendants: true, isSignal: true }], ngImport: i0, template: `
2114
+ @if (headerSlot()) {
2115
+ <ng-content select="NavigationHeader" />
2116
+ }
2117
+
2118
+ @if (contentSlot()) {
2119
+ <ng-content select="NavigationContent" />
2120
+ } @else {
2121
+ <NavigationContent />
2122
+ }
2123
+
2124
+ @if (footerSlot()) {
2125
+ <ng-content select="NavigationFooter" />
2126
+ }
2127
+ `, isInline: true, dependencies: [{ kind: "component", type: NavigationContentComponent, selector: "NavigationContent", inputs: ["class"] }] });
2128
+ }
2129
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationNavbarComponent, decorators: [{
2130
+ type: Component,
2131
+ args: [{
2132
+ selector: 'NavigationNavbar',
2133
+ imports: [NavigationContentComponent],
2134
+ host: {
2135
+ '[class]': 'hostClasses()',
2136
+ },
2137
+ template: `
2138
+ @if (headerSlot()) {
2139
+ <ng-content select="NavigationHeader" />
2140
+ }
2141
+
2142
+ @if (contentSlot()) {
2143
+ <ng-content select="NavigationContent" />
2144
+ } @else {
2145
+ <NavigationContent />
2146
+ }
2147
+
2148
+ @if (footerSlot()) {
2149
+ <ng-content select="NavigationFooter" />
2150
+ }
2151
+ `,
2152
+ }]
2153
+ }], ctorParameters: () => [], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-position", required: false }] }], typeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-type-style", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], headerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationHeaderComponent), { isSignal: true }] }], contentSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationContentComponent), { isSignal: true }] }], footerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => NavigationFooterComponent), { isSignal: true }] }] } });
2154
+
2155
+ /**
2156
+ * Type flyout horizontal (trigger + panel menu) untuk `<Navigation>`.
2157
+ * Slot `NavigationHeader` dan `NavigationFooter` opsional; `NavigationContent`
2158
+ * selalu dirender (default otomatis bila tidak diproyeksikan).
2159
+ */
2160
+ class NavigationFlyoutComponent {
2161
+ container = inject(NavigationContainerComponent);
2162
+ destroyRef = inject(DestroyRef);
2163
+ label = input('Menu', /* @ts-ignore */
2164
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2165
+ /** Nama Material Symbols untuk trigger (mis. `apps`, `menu`); `null` = label saja. */
2166
+ icon = input(null, /* @ts-ignore */
2167
+ ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
2168
+ /** Trigger hanya menampilkan ikon; label tetap dipakai sebagai aria-label/title. */
2169
+ iconOnly = input(false, { ...(ngDevMode ? { debugName: "iconOnly" } : /* istanbul ignore next */ {}), alias: 'icon-only', transform: booleanAttribute });
2170
+ /** Penempatan ikon relatif terhadap label: `start` (default) atau `end`. */
2171
+ iconPosition = input('start', { ...(ngDevMode ? { debugName: "iconPosition" } : /* istanbul ignore next */ {}), alias: 'icon-position' });
2172
+ /** Bentuk visual tombol trigger: `button` (pil, default) | `link` | `plain` (ghost). */
2173
+ triggerVariant = input('button', { ...(ngDevMode ? { debugName: "triggerVariant" } : /* istanbul ignore next */ {}), alias: 'trigger-variant' });
2174
+ /**
2175
+ * Trigger mengambang (`fixed`) alih-alih mengalir di dalam bar/div. Default pojok kanan-atas;
2176
+ * pakai `trigger-class` untuk pindah pojok (mis. `bottom-6 right-6 top-auto`).
2177
+ *
2178
+ * Catatan: `position: fixed` ber-anchor ke viewport HANYA bila tak ada ancestor pembentuk
2179
+ * containing block. Di dalam `<Layout>` (frame-nya memakai `backdrop-blur`), trigger ber-anchor
2180
+ * ke kotak konten frame (bukan viewport sebenarnya) dan bisa ter-clip oleh frame `overflow-hidden`.
2181
+ * Untuk floating sebenar-viewport, tempatkan `<Navigation>` flyout di luar frame `<Layout>`.
2182
+ */
2183
+ triggerFloating = input(false, { ...(ngDevMode ? { debugName: "triggerFloating" } : /* istanbul ignore next */ {}), alias: 'trigger-floating',
2184
+ transform: booleanAttribute });
2185
+ /**
2186
+ * Saat trigger floating dibuka, tempelkan panel ke batas atas viewport dan
2187
+ * bentangkan sepanjang viewport. Dipakai window chrome; default popover tetap
2188
+ * menempel ke trigger.
2189
+ */
2190
+ panelViewport = input(false, { ...(ngDevMode ? { debugName: "panelViewport" } : /* istanbul ignore next */ {}), alias: 'panel-viewport',
2191
+ transform: booleanAttribute });
2192
+ /** Kelas Tailwind untuk host trigger (posisi pojok floating / styling wrapper saat in-flow). */
2193
+ triggerClass = input('', { ...(ngDevMode ? { debugName: "triggerClass" } : /* istanbul ignore next */ {}), alias: 'trigger-class' });
2194
+ /** Kelas tambahan khusus tombol trigger, tanpa memengaruhi host atau item di dalam panel. */
2195
+ triggerButtonClass = input('', { ...(ngDevMode ? { debugName: "triggerButtonClass" } : /* istanbul ignore next */ {}), alias: 'trigger-button-class' });
2196
+ /** Posisi bar terhadap konten layout: `top` (default) atau `bottom` — panel membuka ke arah sebaliknya. */
2197
+ position = input(null, { ...(ngDevMode ? { debugName: "position" } : /* istanbul ignore next */ {}), alias: 'nav-position' });
2198
+ typeStyle = input('flat', { ...(ngDevMode ? { debugName: "typeStyle" } : /* istanbul ignore next */ {}), alias: 'nav-type-style' });
2199
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
2200
+ hostClasses = computed(() => cn(this.container.shellClasses(), this.class()), /* @ts-ignore */
2201
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2202
+ constructor() {
2203
+ const config = {
2204
+ orientation: 'horizontal',
2205
+ type: 'flyout',
2206
+ position: this.position,
2207
+ flyoutLabel: this.label,
2208
+ flyoutIcon: this.icon,
2209
+ flyoutIconOnly: this.iconOnly,
2210
+ flyoutIconPosition: this.iconPosition,
2211
+ flyoutTriggerVariant: this.triggerVariant,
2212
+ flyoutTriggerFloating: this.triggerFloating,
2213
+ flyoutPanelViewport: this.panelViewport,
2214
+ flyoutTriggerClass: this.triggerClass,
2215
+ flyoutTriggerButtonClass: this.triggerButtonClass,
2216
+ typeStyle: this.typeStyle,
2217
+ };
2218
+ this.container.registerType(config);
2219
+ this.destroyRef.onDestroy(() => this.container.unregisterType(config));
2220
+ }
2221
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFlyoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2222
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: NavigationFlyoutComponent, isStandalone: true, selector: "NavigationFlyout", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "icon-only", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "icon-position", isSignal: true, isRequired: false, transformFunction: null }, triggerVariant: { classPropertyName: "triggerVariant", publicName: "trigger-variant", isSignal: true, isRequired: false, transformFunction: null }, triggerFloating: { classPropertyName: "triggerFloating", publicName: "trigger-floating", isSignal: true, isRequired: false, transformFunction: null }, panelViewport: { classPropertyName: "panelViewport", publicName: "panel-viewport", isSignal: true, isRequired: false, transformFunction: null }, triggerClass: { classPropertyName: "triggerClass", publicName: "trigger-class", isSignal: true, isRequired: false, transformFunction: null }, triggerButtonClass: { classPropertyName: "triggerButtonClass", publicName: "trigger-button-class", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "nav-position", isSignal: true, isRequired: false, transformFunction: null }, typeStyle: { classPropertyName: "typeStyle", publicName: "nav-type-style", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
2223
+ <!-- Bar hanya berisi trigger (dari NavigationContent → FlyoutMenu); NavigationHeader &
2224
+ NavigationFooter di-re-project ke DALAM panel flyout saat dibuka. Urutan dibaca dari sisi
2225
+ bar ke arah luar: header (menempel bar, sticky) → menu → footer (ujung jauh). Mode top:
2226
+ brand atas, logout bawah; mode bottom: cerminannya (brand bawah dekat bar, logout atas). -->
2227
+ <NavigationContent>
2228
+ <ng-content select="NavigationHeader" ngProjectAs="NavigationHeader" />
2229
+ <ng-content select="NavigationFooter" ngProjectAs="NavigationFooter" />
2230
+ </NavigationContent>
2231
+ `, isInline: true, dependencies: [{ kind: "component", type: NavigationContentComponent, selector: "NavigationContent", inputs: ["class"] }] });
2232
+ }
2233
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFlyoutComponent, decorators: [{
2234
+ type: Component,
2235
+ args: [{
2236
+ selector: 'NavigationFlyout',
2237
+ imports: [NavigationContentComponent],
2238
+ host: {
2239
+ '[class]': 'hostClasses()',
2240
+ },
2241
+ template: `
2242
+ <!-- Bar hanya berisi trigger (dari NavigationContent → FlyoutMenu); NavigationHeader &
2243
+ NavigationFooter di-re-project ke DALAM panel flyout saat dibuka. Urutan dibaca dari sisi
2244
+ bar ke arah luar: header (menempel bar, sticky) → menu → footer (ujung jauh). Mode top:
2245
+ brand atas, logout bawah; mode bottom: cerminannya (brand bawah dekat bar, logout atas). -->
2246
+ <NavigationContent>
2247
+ <ng-content select="NavigationHeader" ngProjectAs="NavigationHeader" />
2248
+ <ng-content select="NavigationFooter" ngProjectAs="NavigationFooter" />
2249
+ </NavigationContent>
2250
+ `,
2251
+ }]
2252
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon-only", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon-position", required: false }] }], triggerVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger-variant", required: false }] }], triggerFloating: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger-floating", required: false }] }], panelViewport: [{ type: i0.Input, args: [{ isSignal: true, alias: "panel-viewport", required: false }] }], triggerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger-class", required: false }] }], triggerButtonClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "trigger-button-class", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-position", required: false }] }], typeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-type-style", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
2253
+
2254
+ /**
2255
+ * Tampilan compact aktif saat sidebar collapsible sedang collapsed, atau saat
2256
+ * type dockbar aktif — rail dockbar selalu selebar ikon
2257
+ * (`--layout-sidebar-collapsed-width`) sehingga
2258
+ * konten expanded tidak pernah muat.
2259
+ */
2260
+ function isCompactDisplay(shell) {
2261
+ const state = shell.displayState();
2262
+ if (state.orientation !== 'vertical') {
2263
+ return false;
2264
+ }
2265
+ if (state.type === 'dockbar') {
2266
+ return true;
2267
+ }
2268
+ return shell.collapseEnabled() && state.collapsed;
2269
+ }
2270
+ class NavigationCollapseRootDirective {
2271
+ shell = inject(NAVIGATION_SHELL);
2272
+ collapseEnabled = computed(() => {
2273
+ const state = this.shell.displayState();
2274
+ return (state.orientation === 'vertical' && (this.shell.collapseEnabled() || state.type === 'dockbar'));
2275
+ }, /* @ts-ignore */
2276
+ ...(ngDevMode ? [{ debugName: "collapseEnabled" }] : /* istanbul ignore next */ []));
2277
+ displayCollapsed = computed(() => isCompactDisplay(this.shell), /* @ts-ignore */
2278
+ ...(ngDevMode ? [{ debugName: "displayCollapsed" }] : /* istanbul ignore next */ []));
2279
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationCollapseRootDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2280
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: NavigationCollapseRootDirective, isStandalone: true, selector: "[NavigationCollapseRoot]", host: { properties: { "class.w-full": "collapseEnabled()", "class.justify-center": "displayCollapsed()" } }, ngImport: i0 });
2281
+ }
2282
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationCollapseRootDirective, decorators: [{
2283
+ type: Directive,
2284
+ args: [{
2285
+ selector: '[NavigationCollapseRoot]',
2286
+ host: {
2287
+ '[class.w-full]': 'collapseEnabled()',
2288
+ '[class.justify-center]': 'displayCollapsed()',
2289
+ },
2290
+ }]
2291
+ }] });
2292
+ class NavigationCollapseExpandedDirective {
2293
+ shell = inject(NAVIGATION_SHELL);
2294
+ templateRef = inject((TemplateRef));
2295
+ viewContainer = inject(ViewContainerRef);
2296
+ hasView = false;
2297
+ shouldRender = computed(() => !isCompactDisplay(this.shell), /* @ts-ignore */
2298
+ ...(ngDevMode ? [{ debugName: "shouldRender" }] : /* istanbul ignore next */ []));
2299
+ constructor() {
2300
+ effect(() => {
2301
+ if (this.shouldRender()) {
2302
+ if (!this.hasView) {
2303
+ this.viewContainer.createEmbeddedView(this.templateRef);
2304
+ this.hasView = true;
2305
+ }
2306
+ return;
2307
+ }
2308
+ if (this.hasView) {
2309
+ this.viewContainer.clear();
2310
+ this.hasView = false;
2311
+ }
2312
+ });
2313
+ }
2314
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationCollapseExpandedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2315
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: NavigationCollapseExpandedDirective, isStandalone: true, selector: "[NavigationCollapseExpanded]", ngImport: i0 });
2316
+ }
2317
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationCollapseExpandedDirective, decorators: [{
2318
+ type: Directive,
2319
+ args: [{
2320
+ selector: '[NavigationCollapseExpanded]',
2321
+ }]
2322
+ }], ctorParameters: () => [] });
2323
+
2324
+ /**
2325
+ * Slot aksi di sisi kanan `NavigationFooter`. Selalu didorong ke kanan (`ml-auto`),
2326
+ * rata tengah vertikal, dengan jarak antar-child otomatis (`gap`). Isi bebas dengan
2327
+ * ikon, button, atau teks — mis. tombol logout.
2328
+ *
2329
+ * Otomatis disembunyikan saat sidebar vertical sedang collapsed (rail icon-only)
2330
+ * agar tidak overflow; konsisten dengan `NavigationFooterTitle`.
2331
+ */
2332
+ class NavigationFooterActionComponent {
2333
+ shell = inject(NAVIGATION_SHELL, { optional: true });
2334
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
2335
+ collapsed = computed(() => {
2336
+ const state = this.shell?.displayState();
2337
+ return state ? state.orientation === 'vertical' && state.collapsed : false;
2338
+ }, /* @ts-ignore */
2339
+ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
2340
+ hostClasses = computed(() => cn(this.collapsed() ? 'hidden' : 'ml-auto flex shrink-0 items-center gap-1', this.class()), /* @ts-ignore */
2341
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2342
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFooterActionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2343
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: NavigationFooterActionComponent, isStandalone: true, selector: "NavigationFooterAction", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `<ng-content />`, isInline: true });
2344
+ }
2345
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFooterActionComponent, decorators: [{
2346
+ type: Component,
2347
+ args: [{
2348
+ selector: 'NavigationFooterAction',
2349
+ host: {
2350
+ '[class]': 'hostClasses()',
2351
+ },
2352
+ template: `<ng-content />`,
2353
+ }]
2354
+ }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
2355
+
2356
+ /**
2357
+ * Turunkan inisial ringkas dari sebuah nama untuk avatar fallback.
2358
+ *
2359
+ * "Ojie Permana" → "OP"
2360
+ * "Ojiepermana" → "OJ"
2361
+ * "" → ""
2362
+ *
2363
+ * Mengambil huruf depan kata pertama dan kata terakhir; bila hanya satu kata,
2364
+ * memakai dua huruf pertamanya.
2365
+ */
2366
+ function deriveNavigationInitials(name) {
2367
+ const parts = name.trim().split(/\s+/).filter(Boolean);
2368
+ if (parts.length === 0) {
2369
+ return '';
2370
+ }
2371
+ const first = parts[0] ?? '';
2372
+ if (parts.length === 1) {
2373
+ return first.slice(0, 2).toUpperCase();
2374
+ }
2375
+ const last = parts[parts.length - 1] ?? '';
2376
+ return (first.charAt(0) + last.charAt(0)).toUpperCase();
2377
+ }
2378
+
2379
+ /**
2380
+ * Internal, on purpose: this file is deliberately NOT re-exported from
2381
+ * `shell/public-api.ts`. `navigation-initials.ts` is, and putting the
2382
+ * composition there would have made it public API by accident.
2383
+ */
2384
+ /** The base look of an initial block, shared by the header and footer slots. */
2385
+ const INITIAL_HOST_CLASSES = 'inline-flex size-8 shrink-0 items-center justify-center overflow-hidden rounded-md bg-primary/10 text-primary';
2386
+ /**
2387
+ * The derived state both initial blocks need.
2388
+ *
2389
+ * `NavigationHeaderInitial` and `NavigationFooterInitial` were 95 percent the
2390
+ * same file, differing only in whether they exposed a `compact` input. Each
2391
+ * component keeps its own decorator (the selector, host bindings, and template
2392
+ * have to stay literal for the compiler) and takes its derived state from here,
2393
+ * so the initials rule and the base look cannot drift between the two.
2394
+ */
2395
+ function setupNavigationInitial(sources) {
2396
+ return {
2397
+ // An explicit `initials` override wins, trimmed to two upper-case letters.
2398
+ resolvedInitials: computed(() => sources.initials()?.slice(0, 2).toUpperCase() || deriveNavigationInitials(sources.name())),
2399
+ iconClasses: computed(() => sources.compact() ? 'text-(length:--nav-icon-size-rail)' : 'text-(length:--nav-icon-size)'),
2400
+ hostClasses: computed(() => cn(INITIAL_HOST_CLASSES, sources.class())),
2401
+ };
2402
+ }
2403
+
2404
+ /**
2405
+ * Blok avatar/inisial untuk slot `NavigationFooter` (profil user). Sama seperti
2406
+ * `NavigationHeaderInitial` dengan bentuk identitas yang seragam (rounded-md).
2407
+ * Consumer cukup memberi `name`; inisial diturunkan otomatis. Beri `src` untuk
2408
+ * foto, `icon` untuk material symbol, atau `initials` untuk override.
2409
+ *
2410
+ * Tetap tampil saat sidebar collapsed; pasangannya `NavigationFooterTitle` yang
2411
+ * menyembunyikan diri.
2412
+ */
2413
+ class NavigationFooterInitialComponent {
2414
+ name = input('', /* @ts-ignore */
2415
+ ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
2416
+ src = input(null, /* @ts-ignore */
2417
+ ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
2418
+ initials = input(null, /* @ts-ignore */
2419
+ ...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
2420
+ icon = input(null, /* @ts-ignore */
2421
+ ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
2422
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
2423
+ view = setupNavigationInitial({
2424
+ name: () => this.name(),
2425
+ initials: () => this.initials(),
2426
+ // The footer slot has no `compact` input and never used the rail token, so
2427
+ // this stays false rather than widening its public surface.
2428
+ compact: () => false,
2429
+ class: () => this.class(),
2430
+ });
2431
+ resolvedInitials = this.view.resolvedInitials;
2432
+ hostClasses = this.view.hostClasses;
2433
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFooterInitialComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2434
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationFooterInitialComponent, isStandalone: true, selector: "NavigationFooterInitial", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, initials: { classPropertyName: "initials", publicName: "initials", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.role": "name() ? 'img' : null", "attr.aria-label": "name() || null" } }, ngImport: i0, template: `
2435
+ @if (src(); as source) {
2436
+ <img [src]="source" alt="" class="h-full w-full rounded-[inherit] object-cover" />
2437
+ } @else if (icon(); as glyph) {
2438
+ <Icon [name]="glyph" size="inherit" [fill]="1" class="text-(length:--nav-icon-size)" />
2439
+ } @else {
2440
+ <span class="text-xs font-semibold leading-none">{{ resolvedInitials() }}</span>
2441
+ }
2442
+ `, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }] });
2443
+ }
2444
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFooterInitialComponent, decorators: [{
2445
+ type: Component,
2446
+ args: [{
2447
+ selector: 'NavigationFooterInitial',
2448
+ imports: [IconComponent],
2449
+ host: {
2450
+ '[class]': 'hostClasses()',
2451
+ '[attr.role]': "name() ? 'img' : null",
2452
+ '[attr.aria-label]': 'name() || null',
2453
+ },
2454
+ template: `
2455
+ @if (src(); as source) {
2456
+ <img [src]="source" alt="" class="h-full w-full rounded-[inherit] object-cover" />
2457
+ } @else if (icon(); as glyph) {
2458
+ <Icon [name]="glyph" size="inherit" [fill]="1" class="text-(length:--nav-icon-size)" />
2459
+ } @else {
2460
+ <span class="text-xs font-semibold leading-none">{{ resolvedInitials() }}</span>
2461
+ }
2462
+ `,
2463
+ }]
2464
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
2465
+
2466
+ /**
2467
+ * Judul + subjudul untuk slot `NavigationFooter` (mis. nama + email user).
2468
+ * Otomatis disembunyikan saat sidebar vertical sedang collapsed (rail icon-only)
2469
+ * dengan membaca `NAVIGATION_SHELL`.
2470
+ */
2471
+ class NavigationFooterTitleComponent {
2472
+ shell = inject(NAVIGATION_SHELL, { optional: true });
2473
+ title = input('', /* @ts-ignore */
2474
+ ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
2475
+ subtitle = input(null, /* @ts-ignore */
2476
+ ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
2477
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
2478
+ collapsed = computed(() => {
2479
+ const state = this.shell?.displayState();
2480
+ return state ? state.orientation === 'vertical' && state.collapsed : false;
2481
+ }, /* @ts-ignore */
2482
+ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
2483
+ hostClasses = computed(() => cn(this.collapsed() ? 'hidden' : 'flex min-w-0 flex-col justify-center', this.class()), /* @ts-ignore */
2484
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2485
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFooterTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2486
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationFooterTitleComponent, isStandalone: true, selector: "NavigationFooterTitle", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.data-collapsed": "collapsed()" } }, ngImport: i0, template: `
2487
+ <span class="nav-text block truncate text-foreground">{{ title() }}</span>
2488
+ @if (subtitle(); as sub) {
2489
+ <span
2490
+ class="nav-subtitle -mt-0.5 block truncate text-muted-foreground"
2491
+ data-navigation-sidebar-subtitle
2492
+ >
2493
+ {{ sub }}
2494
+ </span>
2495
+ }
2496
+ `, isInline: true });
2497
+ }
2498
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationFooterTitleComponent, decorators: [{
2499
+ type: Component,
2500
+ args: [{
2501
+ selector: 'NavigationFooterTitle',
2502
+ host: {
2503
+ '[class]': 'hostClasses()',
2504
+ '[attr.data-collapsed]': 'collapsed()',
2505
+ },
2506
+ template: `
2507
+ <span class="nav-text block truncate text-foreground">{{ title() }}</span>
2508
+ @if (subtitle(); as sub) {
2509
+ <span
2510
+ class="nav-subtitle -mt-0.5 block truncate text-muted-foreground"
2511
+ data-navigation-sidebar-subtitle
2512
+ >
2513
+ {{ sub }}
2514
+ </span>
2515
+ }
2516
+ `,
2517
+ }]
2518
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
2519
+
2520
+ /**
2521
+ * Blok avatar/inisial untuk slot `NavigationHeader` (brand/logo). Consumer cukup
2522
+ * memberi `name`; inisial diturunkan otomatis ("Ojie Permana" → "OP"). Beri `src`
2523
+ * untuk gambar, `icon` (material symbol) sebagai ganti inisial, atau `initials`
2524
+ * untuk override manual.
2525
+ *
2526
+ * Selalu tampil baik saat sidebar expanded maupun collapsed karena ukurannya muat
2527
+ * di rail icon-only — pasangannya, `NavigationHeaderTitle`, yang menyembunyikan
2528
+ * diri saat collapsed.
2529
+ */
2530
+ class NavigationHeaderInitialComponent {
2531
+ name = input('', /* @ts-ignore */
2532
+ ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
2533
+ src = input(null, /* @ts-ignore */
2534
+ ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
2535
+ initials = input(null, /* @ts-ignore */
2536
+ ...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
2537
+ icon = input(null, /* @ts-ignore */
2538
+ ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
2539
+ /** Use the rail icon token when the header is rendered in compact navigation. */
2540
+ compact = input(false, { ...(ngDevMode ? { debugName: "compact" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2541
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
2542
+ view = setupNavigationInitial({
2543
+ name: () => this.name(),
2544
+ initials: () => this.initials(),
2545
+ compact: () => this.compact(),
2546
+ class: () => this.class(),
2547
+ });
2548
+ resolvedInitials = this.view.resolvedInitials;
2549
+ iconClasses = this.view.iconClasses;
2550
+ hostClasses = this.view.hostClasses;
2551
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationHeaderInitialComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2552
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationHeaderInitialComponent, isStandalone: true, selector: "NavigationHeaderInitial", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, initials: { classPropertyName: "initials", publicName: "initials", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.role": "name() ? 'img' : null", "attr.aria-label": "name() || null" } }, ngImport: i0, template: `
2553
+ @if (src(); as source) {
2554
+ <img [src]="source" alt="" class="h-full w-full rounded-[inherit] object-cover" />
2555
+ } @else if (icon(); as glyph) {
2556
+ <Icon [name]="glyph" size="inherit" [fill]="1" [class]="iconClasses()" />
2557
+ } @else {
2558
+ <span class="text-xs font-semibold leading-none">{{ resolvedInitials() }}</span>
2559
+ }
2560
+ `, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }] });
2561
+ }
2562
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationHeaderInitialComponent, decorators: [{
2563
+ type: Component,
2564
+ args: [{
2565
+ selector: 'NavigationHeaderInitial',
2566
+ imports: [IconComponent],
2567
+ host: {
2568
+ '[class]': 'hostClasses()',
2569
+ '[attr.role]': "name() ? 'img' : null",
2570
+ '[attr.aria-label]': 'name() || null',
2571
+ },
2572
+ template: `
2573
+ @if (src(); as source) {
2574
+ <img [src]="source" alt="" class="h-full w-full rounded-[inherit] object-cover" />
2575
+ } @else if (icon(); as glyph) {
2576
+ <Icon [name]="glyph" size="inherit" [fill]="1" [class]="iconClasses()" />
2577
+ } @else {
2578
+ <span class="text-xs font-semibold leading-none">{{ resolvedInitials() }}</span>
2579
+ }
2580
+ `,
2581
+ }]
2582
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
2583
+
2584
+ /**
2585
+ * Judul + subjudul untuk slot `NavigationHeader`. Otomatis disembunyikan saat
2586
+ * sidebar vertical sedang collapsed (rail icon-only) dengan membaca
2587
+ * `NAVIGATION_SHELL` — consumer tidak perlu mengelola state collapse sendiri.
2588
+ */
2589
+ class NavigationHeaderTitleComponent {
2590
+ shell = inject(NAVIGATION_SHELL, { optional: true });
2591
+ title = input('', /* @ts-ignore */
2592
+ ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
2593
+ subtitle = input(null, /* @ts-ignore */
2594
+ ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
2595
+ class = input('', { ...(ngDevMode ? { debugName: "class" } : /* istanbul ignore next */ {}), alias: 'class' });
2596
+ collapsed = computed(() => {
2597
+ const state = this.shell?.displayState();
2598
+ return state ? state.orientation === 'vertical' && state.collapsed : false;
2599
+ }, /* @ts-ignore */
2600
+ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
2601
+ hostClasses = computed(() => cn(this.collapsed() ? 'hidden' : 'flex min-w-0 flex-col justify-center', this.class()), /* @ts-ignore */
2602
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2603
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationHeaderTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2604
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: NavigationHeaderTitleComponent, isStandalone: true, selector: "NavigationHeaderTitle", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()", "attr.data-collapsed": "collapsed()" } }, ngImport: i0, template: `
2605
+ <span class="nav-text block truncate text-foreground">{{ title() }}</span>
2606
+ @if (subtitle(); as sub) {
2607
+ <span
2608
+ class="nav-subtitle block truncate text-muted-foreground"
2609
+ data-navigation-sidebar-subtitle
2610
+ >
2611
+ {{ sub }}
2612
+ </span>
2613
+ }
2614
+ `, isInline: true });
2615
+ }
2616
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: NavigationHeaderTitleComponent, decorators: [{
2617
+ type: Component,
2618
+ args: [{
2619
+ selector: 'NavigationHeaderTitle',
2620
+ host: {
2621
+ '[class]': 'hostClasses()',
2622
+ '[attr.data-collapsed]': 'collapsed()',
2623
+ },
2624
+ template: `
2625
+ <span class="nav-text block truncate text-foreground">{{ title() }}</span>
2626
+ @if (subtitle(); as sub) {
2627
+ <span
2628
+ class="nav-subtitle block truncate text-muted-foreground"
2629
+ data-navigation-sidebar-subtitle
2630
+ >
2631
+ {{ sub }}
2632
+ </span>
2633
+ }
2634
+ `,
2635
+ }]
2636
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
2637
+
2638
+ /**
2639
+ * Generated bundle index. Do not edit.
2640
+ */
2641
+
2642
+ export { NavigationItemComponent as N, NavigationItemContentComponent as a, NavigationListComponent as b, NavigationAsideFooterDirective as c, NavigationCollapseExpandedDirective as d, NavigationCollapseRootDirective as e, NavigationContainerComponent as f, NavigationContentComponent as g, NavigationDockbarComponent as h, NavigationFlyoutComponent as i, NavigationFooterActionComponent as j, NavigationFooterComponent as k, NavigationFooterInitialComponent as l, NavigationFooterTitleComponent as m, navigationPanelId as n, NavigationHeaderComponent as o, NavigationHeaderInitialComponent as p, NavigationHeaderTitleComponent as q, NavigationNavbarComponent as r, NavigationSidebarComponent as s, deriveNavigationInitials as t };