@ojiepermana/angular 22.1.11 → 22.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -26
- package/chart/README.md +272 -0
- package/component/README.md +89 -0
- package/component/accordion/README.md +195 -0
- package/component/alert/README.md +184 -0
- package/component/alert-dialog/README.md +255 -0
- package/component/aspect-ratio/README.md +116 -0
- package/component/avatar/README.md +182 -0
- package/component/badge/README.md +143 -0
- package/component/breadcrumb/README.md +223 -0
- package/component/button/README.md +141 -0
- package/component/button-group/README.md +214 -0
- package/component/calendar/README.md +137 -0
- package/component/card/README.md +232 -0
- package/component/carousel/README.md +276 -0
- package/component/checkbox/README.md +153 -0
- package/component/collapsible/README.md +216 -0
- package/component/combobox/README.md +202 -0
- package/component/command/README.md +287 -0
- package/component/composer/README.md +241 -0
- package/component/context-menu/README.md +268 -0
- package/component/date-picker/README.md +202 -0
- package/component/dialog/README.md +276 -0
- package/component/drawer/README.md +147 -0
- package/component/dropdown-menu/README.md +336 -0
- package/component/editor/README.md +152 -0
- package/component/empty/README.md +193 -0
- package/component/form/README.md +216 -0
- package/component/hover-card/README.md +150 -0
- package/component/icon/README.md +25 -0
- package/component/input/README.md +160 -0
- package/component/input-group/README.md +245 -0
- package/component/input-otp/README.md +331 -0
- package/component/item/README.md +254 -0
- package/component/kanban/README.md +81 -0
- package/component/kbd/README.md +141 -0
- package/component/label/README.md +137 -0
- package/component/menubar/README.md +270 -0
- package/component/native-select/README.md +176 -0
- package/component/navigation-menu/README.md +165 -0
- package/component/pagination/README.md +151 -0
- package/component/pillbox/README.md +68 -0
- package/component/popover/README.md +54 -0
- package/component/progress/README.md +160 -0
- package/component/radio/README.md +212 -0
- package/component/resizable/README.md +178 -0
- package/component/scroll-area/README.md +150 -0
- package/component/select/README.md +228 -0
- package/component/separator/README.md +175 -0
- package/component/sheet/README.md +190 -0
- package/component/skeleton/README.md +158 -0
- package/component/slider/README.md +207 -0
- package/component/spinner/README.md +160 -0
- package/component/switch/README.md +170 -0
- package/component/table/README.md +292 -0
- package/component/tabs/README.md +220 -0
- package/component/textarea/README.md +169 -0
- package/component/timeline/README.md +94 -0
- package/component/toast/README.md +173 -0
- package/component/toggle/README.md +133 -0
- package/component/toggle-group/README.md +234 -0
- package/component/tooltip/README.md +230 -0
- package/fesm2022/ojiepermana-angular-chart-area.mjs +289 -3
- package/fesm2022/ojiepermana-angular-chart-bar.mjs +722 -3
- package/fesm2022/ojiepermana-angular-chart-core.mjs +1482 -3
- package/fesm2022/ojiepermana-angular-chart-line.mjs +294 -3
- package/fesm2022/ojiepermana-angular-chart-pie.mjs +291 -3
- package/fesm2022/ojiepermana-angular-chart-primitives.mjs +1301 -3
- package/fesm2022/ojiepermana-angular-chart-radar.mjs +421 -3
- package/fesm2022/ojiepermana-angular-chart-radial.mjs +295 -3
- package/fesm2022/ojiepermana-angular-chart-scatter.mjs +306 -3
- package/fesm2022/ojiepermana-angular-chart.mjs +12 -3
- package/fesm2022/ojiepermana-angular-component-accordion.mjs +267 -3
- package/fesm2022/ojiepermana-angular-component-alert-dialog.mjs +359 -3
- package/fesm2022/ojiepermana-angular-component-alert.mjs +101 -3
- package/fesm2022/ojiepermana-angular-component-aspect-ratio.mjs +31 -3
- package/fesm2022/ojiepermana-angular-component-avatar.mjs +139 -3
- package/fesm2022/ojiepermana-angular-component-badge.mjs +57 -3
- package/fesm2022/ojiepermana-angular-component-breadcrumb.mjs +192 -3
- package/fesm2022/ojiepermana-angular-component-button-group.mjs +95 -3
- package/fesm2022/ojiepermana-angular-component-button.mjs +73 -3
- package/fesm2022/ojiepermana-angular-component-calendar.mjs +718 -3
- package/fesm2022/ojiepermana-angular-component-card.mjs +167 -3
- package/fesm2022/ojiepermana-angular-component-carousel.mjs +326 -3
- package/fesm2022/ojiepermana-angular-component-checkbox.mjs +190 -3
- package/fesm2022/ojiepermana-angular-component-collapsible.mjs +117 -3
- package/fesm2022/ojiepermana-angular-component-combobox.mjs +327 -3
- package/fesm2022/ojiepermana-angular-component-command.mjs +351 -3
- package/fesm2022/ojiepermana-angular-component-composer.mjs +359 -3
- package/fesm2022/ojiepermana-angular-component-context-menu.mjs +158 -3
- package/fesm2022/ojiepermana-angular-component-date-picker.mjs +482 -3
- package/fesm2022/ojiepermana-angular-component-dialog.mjs +400 -3
- package/fesm2022/ojiepermana-angular-component-drawer.mjs +1 -3
- package/fesm2022/ojiepermana-angular-component-dropdown-menu.mjs +689 -3
- package/fesm2022/ojiepermana-angular-component-editor.mjs +511 -3
- package/fesm2022/ojiepermana-angular-component-empty.mjs +134 -3
- package/fesm2022/ojiepermana-angular-component-form.mjs +438 -3
- package/fesm2022/ojiepermana-angular-component-hover-card.mjs +273 -3
- package/fesm2022/ojiepermana-angular-component-icon.mjs +139 -3
- package/fesm2022/ojiepermana-angular-component-input-group.mjs +176 -3
- package/fesm2022/ojiepermana-angular-component-input-otp.mjs +550 -3
- package/fesm2022/ojiepermana-angular-component-input.mjs +52 -3
- package/fesm2022/ojiepermana-angular-component-item.mjs +264 -3
- package/fesm2022/ojiepermana-angular-component-kanban.mjs +310 -3
- package/fesm2022/ojiepermana-angular-component-kbd.mjs +48 -3
- package/fesm2022/ojiepermana-angular-component-label.mjs +27 -3
- package/fesm2022/ojiepermana-angular-component-menubar.mjs +327 -3
- package/fesm2022/ojiepermana-angular-component-native-select.mjs +62 -3
- package/fesm2022/ojiepermana-angular-component-navigation-menu.mjs +378 -3
- package/fesm2022/ojiepermana-angular-component-pagination.mjs +238 -3
- package/fesm2022/ojiepermana-angular-component-pillbox.mjs +999 -3
- package/fesm2022/ojiepermana-angular-component-popover.mjs +201 -3
- package/fesm2022/ojiepermana-angular-component-progress.mjs +57 -3
- package/fesm2022/ojiepermana-angular-component-radio.mjs +180 -3
- package/fesm2022/ojiepermana-angular-component-resizable.mjs +493 -3
- package/fesm2022/ojiepermana-angular-component-scroll-area.mjs +51 -3
- package/fesm2022/ojiepermana-angular-component-segmented-control.mjs +227 -3
- package/fesm2022/ojiepermana-angular-component-select.mjs +609 -3
- package/fesm2022/ojiepermana-angular-component-separator.mjs +31 -3
- package/fesm2022/ojiepermana-angular-component-sheet.mjs +407 -3
- package/fesm2022/ojiepermana-angular-component-skeleton.mjs +25 -3
- package/fesm2022/ojiepermana-angular-component-slider.mjs +456 -3
- package/fesm2022/ojiepermana-angular-component-spinner.mjs +56 -3
- package/fesm2022/ojiepermana-angular-component-switch.mjs +145 -3
- package/fesm2022/ojiepermana-angular-component-table.mjs +155 -3
- package/fesm2022/ojiepermana-angular-component-tabs.mjs +315 -3
- package/fesm2022/ojiepermana-angular-component-textarea.mjs +46 -3
- package/fesm2022/ojiepermana-angular-component-timeline.mjs +237 -3
- package/fesm2022/ojiepermana-angular-component-toast.mjs +241 -3
- package/fesm2022/ojiepermana-angular-component-toggle-group.mjs +290 -3
- package/fesm2022/ojiepermana-angular-component-toggle.mjs +76 -3
- package/fesm2022/ojiepermana-angular-component-tooltip.mjs +519 -3
- package/fesm2022/ojiepermana-angular-component-utils-core.mjs +310 -3
- package/fesm2022/ojiepermana-angular-component-utils-overlay.mjs +62 -3
- package/fesm2022/ojiepermana-angular-component-utils-scale.mjs +34 -3
- package/fesm2022/ojiepermana-angular-component-utils.mjs +3 -2
- package/fesm2022/ojiepermana-angular-component.mjs +4 -4
- package/fesm2022/ojiepermana-angular-navigation-core.mjs +21 -3
- package/fesm2022/ojiepermana-angular-navigation-icon.mjs +20 -3
- package/fesm2022/ojiepermana-angular-navigation-navigation-badge-count.component-CDBxQ8rk.mjs +91 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-dockbar-menu.component-DBQHdvGa.mjs +512 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-entry-grid.component-Cd-jh6tg.mjs +623 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-flyout-menu.component-BCGvhoYj.mjs +404 -0
- package/fesm2022/ojiepermana-angular-navigation-navigation-horizontal.component-Dk_03e-6.mjs +466 -0
- package/fesm2022/ojiepermana-angular-navigation-ojiepermana-angular-navigation-DNKU6viC.mjs +2642 -0
- package/fesm2022/ojiepermana-angular-navigation-service.mjs +725 -3
- package/fesm2022/ojiepermana-angular-navigation-types.mjs +65 -4
- package/fesm2022/ojiepermana-angular-navigation.mjs +4 -10
- package/fesm2022/ojiepermana-angular-sdk.mjs +204 -4
- package/fesm2022/ojiepermana-angular-theme-component-settings.mjs +1387 -3
- package/fesm2022/ojiepermana-angular-theme-layout-services.mjs +331 -3
- package/fesm2022/ojiepermana-angular-theme-layout-types.mjs +45 -4
- package/fesm2022/ojiepermana-angular-theme-layout-wrapper.mjs +1044 -3
- package/fesm2022/ojiepermana-angular-theme-layout.mjs +729 -3
- package/fesm2022/ojiepermana-angular-theme-page-core.mjs +381 -3
- package/fesm2022/ojiepermana-angular-theme-page-filter.mjs +267 -3
- package/fesm2022/ojiepermana-angular-theme-page-root.mjs +361 -3
- package/fesm2022/ojiepermana-angular-theme-page-side.mjs +198 -3
- package/fesm2022/ojiepermana-angular-theme-page-slots.mjs +110 -3
- package/fesm2022/ojiepermana-angular-theme-page.mjs +7 -2
- package/fesm2022/ojiepermana-angular-theme-shell-services.mjs +338 -3
- package/fesm2022/ojiepermana-angular-theme-shell-types.mjs +160 -4
- package/fesm2022/ojiepermana-angular-theme-shell.mjs +811 -3
- package/fesm2022/ojiepermana-angular-theme-styles.mjs +783 -3
- package/fesm2022/ojiepermana-angular-theme.mjs +4 -4
- package/fesm2022/ojiepermana-angular.mjs +6 -11
- package/navigation/README.md +374 -0
- package/package.json +81 -20
- package/sdk/README.md +212 -0
- package/sdk/schematics/collection.json +20 -0
- package/sdk/schematics/init/index.js +83 -0
- package/sdk/schematics/init/schema.json +19 -0
- package/sdk/schematics/ng-add/index.js +147 -0
- package/sdk/schematics/ng-add/schema.json +14 -0
- package/sdk/schematics/package.json +3 -0
- package/sdk/schematics/sdk/index.js +175 -0
- package/sdk/schematics/sdk/schema.json +19 -0
- package/sdk/sdk.config.example.json +24 -0
- package/sdk/src/config/loader.js +43 -0
- package/sdk/src/config/schema.js +59 -0
- package/sdk/src/emit/client.js +251 -0
- package/sdk/src/emit/metadata.js +310 -0
- package/sdk/src/emit/models.js +104 -0
- package/sdk/src/emit/navigation.js +56 -0
- package/sdk/src/emit/operations.js +118 -0
- package/sdk/src/emit/public-api.js +54 -0
- package/sdk/src/emit/services.js +110 -0
- package/sdk/src/engine.js +67 -0
- package/sdk/src/layout/per-domain.js +360 -0
- package/sdk/src/package.json +3 -0
- package/sdk/src/parser/bundle.js +25 -0
- package/sdk/src/parser/ir.js +429 -0
- package/sdk/src/parser/types.js +7 -0
- package/sdk/src/render/template.js +152 -0
- package/sdk/src/writer/index.js +286 -0
- package/theme/README.md +126 -0
- package/theme/component/settings/README.md +135 -0
- package/theme/layout/README.md +539 -0
- package/theme/page/README.md +453 -0
- package/theme/shell/README.md +340 -0
- package/theme/styles/README.md +178 -0
- package/theme/styles/css/base/components.css +553 -0
- package/theme/styles/css/base/index.css +14 -0
- package/theme/styles/css/base/package.css +9 -0
- package/theme/styles/css/base/prefers-dark.css +86 -0
- package/theme/styles/css/base/print.css +62 -0
- package/theme/styles/css/base/status.css +38 -0
- package/theme/styles/css/base/tailwind.css +165 -0
- package/theme/styles/css/base/theme.css +373 -0
- package/theme/styles/css/base/tokens.css +361 -0
- package/theme/styles/css/color/amber.css +72 -0
- package/theme/styles/css/color/blue.css +72 -0
- package/theme/styles/css/color/brand.css +38 -0
- package/theme/styles/css/color/cyan.css +72 -0
- package/theme/styles/css/color/emerald.css +72 -0
- package/theme/styles/css/color/fuchsia.css +72 -0
- package/theme/styles/css/color/green.css +72 -0
- package/theme/styles/css/color/index.css +19 -0
- package/theme/styles/css/color/indigo.css +72 -0
- package/theme/styles/css/color/lime.css +72 -0
- package/theme/styles/css/color/orange.css +72 -0
- package/theme/styles/css/color/pink.css +72 -0
- package/theme/styles/css/color/purple.css +72 -0
- package/theme/styles/css/color/red.css +72 -0
- package/theme/styles/css/color/rose.css +72 -0
- package/theme/styles/css/color/sky.css +72 -0
- package/theme/styles/css/color/teal.css +72 -0
- package/theme/styles/css/color/violet.css +72 -0
- package/theme/styles/css/color/yellow.css +72 -0
- package/theme/styles/css/index.css +18 -0
- package/theme/styles/css/neutral/gray.css +63 -0
- package/theme/styles/css/neutral/index.css +11 -0
- package/theme/styles/css/neutral/mauve.css +63 -0
- package/theme/styles/css/neutral/mist.css +63 -0
- package/theme/styles/css/neutral/neutral.css +63 -0
- package/theme/styles/css/neutral/olive.css +63 -0
- package/theme/styles/css/neutral/slate.css +63 -0
- package/theme/styles/css/neutral/stone.css +63 -0
- package/theme/styles/css/neutral/taupe.css +63 -0
- package/theme/styles/css/neutral/zinc.css +63 -0
- package/theme/styles/css/radius/index.css +30 -0
- package/theme/styles/css/space/index.css +20 -0
- package/types/ojiepermana-angular-chart-area.d.ts +76 -1
- package/types/ojiepermana-angular-chart-bar.d.ts +201 -1
- package/types/ojiepermana-angular-chart-core.d.ts +811 -1
- package/types/ojiepermana-angular-chart-line.d.ts +75 -1
- package/types/ojiepermana-angular-chart-pie.d.ts +131 -1
- package/types/ojiepermana-angular-chart-primitives.d.ts +291 -1
- package/types/ojiepermana-angular-chart-radar.d.ts +116 -1
- package/types/ojiepermana-angular-chart-radial.d.ts +116 -1
- package/types/ojiepermana-angular-chart-scatter.d.ts +125 -1
- package/types/ojiepermana-angular-chart.d.ts +2 -1
- package/types/ojiepermana-angular-component-accordion.d.ts +85 -1
- package/types/ojiepermana-angular-component-alert-dialog.d.ts +140 -1
- package/types/ojiepermana-angular-component-alert.d.ts +42 -1
- package/types/ojiepermana-angular-component-aspect-ratio.d.ts +12 -1
- package/types/ojiepermana-angular-component-avatar.d.ts +56 -1
- package/types/ojiepermana-angular-component-badge.d.ts +24 -1
- package/types/ojiepermana-angular-component-breadcrumb.d.ts +46 -1
- package/types/ojiepermana-angular-component-button-group.d.ts +26 -1
- package/types/ojiepermana-angular-component-button.d.ts +27 -1
- package/types/ojiepermana-angular-component-calendar.d.ts +111 -1
- package/types/ojiepermana-angular-component-card.d.ts +69 -1
- package/types/ojiepermana-angular-component-carousel.d.ts +86 -1
- package/types/ojiepermana-angular-component-checkbox.d.ts +42 -1
- package/types/ojiepermana-angular-component-collapsible.d.ts +42 -1
- package/types/ojiepermana-angular-component-combobox.d.ts +60 -1
- package/types/ojiepermana-angular-component-command.d.ts +130 -1
- package/types/ojiepermana-angular-component-composer.d.ts +90 -1
- package/types/ojiepermana-angular-component-context-menu.d.ts +54 -1
- package/types/ojiepermana-angular-component-date-picker.d.ts +109 -1
- package/types/ojiepermana-angular-component-dialog.d.ts +136 -1
- package/types/ojiepermana-angular-component-drawer.d.ts +1 -1
- package/types/ojiepermana-angular-component-dropdown-menu.d.ts +248 -1
- package/types/ojiepermana-angular-component-editor.d.ts +135 -1
- package/types/ojiepermana-angular-component-empty.d.ts +50 -1
- package/types/ojiepermana-angular-component-form.d.ts +159 -1
- package/types/ojiepermana-angular-component-hover-card.d.ts +75 -1
- package/types/ojiepermana-angular-component-icon.d.ts +89 -1
- package/types/ojiepermana-angular-component-input-group.d.ts +51 -1
- package/types/ojiepermana-angular-component-input-otp.d.ts +155 -1
- package/types/ojiepermana-angular-component-input.d.ts +21 -1
- package/types/ojiepermana-angular-component-item.d.ts +93 -1
- package/types/ojiepermana-angular-component-kanban.d.ts +70 -1
- package/types/ojiepermana-angular-component-kbd.d.ts +16 -1
- package/types/ojiepermana-angular-component-label.d.ts +11 -1
- package/types/ojiepermana-angular-component-menubar.d.ts +93 -1
- package/types/ojiepermana-angular-component-native-select.d.ts +26 -1
- package/types/ojiepermana-angular-component-navigation-menu.d.ts +104 -1
- package/types/ojiepermana-angular-component-pagination.d.ts +33 -1
- package/types/ojiepermana-angular-component-pillbox.d.ts +222 -1
- package/types/ojiepermana-angular-component-popover.d.ts +66 -1
- package/types/ojiepermana-angular-component-progress.d.ts +17 -1
- package/types/ojiepermana-angular-component-radio.d.ts +60 -1
- package/types/ojiepermana-angular-component-resizable.d.ts +117 -1
- package/types/ojiepermana-angular-component-scroll-area.d.ts +19 -1
- package/types/ojiepermana-angular-component-segmented-control.d.ts +58 -1
- package/types/ojiepermana-angular-component-select.d.ts +122 -1
- package/types/ojiepermana-angular-component-separator.d.ts +14 -1
- package/types/ojiepermana-angular-component-sheet.d.ts +130 -1
- package/types/ojiepermana-angular-component-skeleton.d.ts +10 -1
- package/types/ojiepermana-angular-component-slider.d.ts +83 -1
- package/types/ojiepermana-angular-component-spinner.d.ts +13 -1
- package/types/ojiepermana-angular-component-switch.d.ts +44 -1
- package/types/ojiepermana-angular-component-table.d.ts +57 -1
- package/types/ojiepermana-angular-component-tabs.d.ts +124 -1
- package/types/ojiepermana-angular-component-textarea.d.ts +17 -1
- package/types/ojiepermana-angular-component-timeline.d.ts +64 -1
- package/types/ojiepermana-angular-component-toast.d.ts +64 -1
- package/types/ojiepermana-angular-component-toggle-group.d.ts +90 -1
- package/types/ojiepermana-angular-component-toggle.d.ts +25 -1
- package/types/ojiepermana-angular-component-tooltip.d.ts +143 -1
- package/types/ojiepermana-angular-component-utils-core.d.ts +184 -1
- package/types/ojiepermana-angular-component-utils-overlay.d.ts +21 -1
- package/types/ojiepermana-angular-component-utils-scale.d.ts +19 -1
- package/types/ojiepermana-angular-component-utils.d.ts +2 -1
- package/types/ojiepermana-angular-component.d.ts +2 -1
- package/types/ojiepermana-angular-navigation-core.d.ts +59 -1
- package/types/ojiepermana-angular-navigation-icon.d.ts +12 -1
- package/types/ojiepermana-angular-navigation-service.d.ts +116 -1
- package/types/ojiepermana-angular-navigation-types.d.ts +144 -1
- package/types/ojiepermana-angular-navigation.d.ts +507 -1
- package/types/ojiepermana-angular-sdk.d.ts +89 -1
- package/types/ojiepermana-angular-theme-component-settings.d.ts +154 -1
- package/types/ojiepermana-angular-theme-layout-services.d.ts +147 -1
- package/types/ojiepermana-angular-theme-layout-types.d.ts +40 -1
- package/types/ojiepermana-angular-theme-layout-wrapper.d.ts +299 -1
- package/types/ojiepermana-angular-theme-layout.d.ts +129 -1
- package/types/ojiepermana-angular-theme-page-core.d.ts +157 -1
- package/types/ojiepermana-angular-theme-page-filter.d.ts +77 -1
- package/types/ojiepermana-angular-theme-page-root.d.ts +88 -1
- package/types/ojiepermana-angular-theme-page-side.d.ts +50 -1
- package/types/ojiepermana-angular-theme-page-slots.d.ts +40 -1
- package/types/ojiepermana-angular-theme-page.d.ts +5 -1
- package/types/ojiepermana-angular-theme-shell-services.d.ts +193 -1
- package/types/ojiepermana-angular-theme-shell-types.d.ts +105 -1
- package/types/ojiepermana-angular-theme-shell.d.ts +100 -1
- package/types/ojiepermana-angular-theme-styles.d.ts +319 -1
- package/types/ojiepermana-angular-theme.d.ts +2 -1
- package/types/ojiepermana-angular.d.ts +5 -5
|
@@ -1,7 +1,1048 @@
|
|
|
1
|
-
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { signal, Service, input, booleanAttribute, Component, output, computed, model, inject, viewChild, effect } from '@angular/core';
|
|
3
|
+
import { NavigationHeaderInitialComponent, NavigationHeaderTitleComponent, NavigationFooterActionComponent, NavigationFooterInitialComponent, NavigationFooterTitleComponent, NavigationSidebarComponent, NavigationHeaderComponent, NavigationFooterComponent, NavigationAsideFooterDirective, NavigationDockbarComponent, NavigationNavbarComponent, NavigationFlyoutComponent, NavigationContainerComponent } from '@ojiepermana/angular/navigation';
|
|
4
|
+
import { IconComponent } from '@ojiepermana/angular/component/icon';
|
|
5
|
+
import { ThemeSettingsComponent } from '@ojiepermana/angular/theme/component/settings';
|
|
6
|
+
import { DOCUMENT, NgTemplateOutlet } from '@angular/common';
|
|
7
|
+
import { cn } from '@ojiepermana/angular/component/utils/core';
|
|
8
|
+
import { LayoutComponent, LayoutVerticalComponent, LayoutHorizontalComponent, LayoutEmptyComponent, LayoutFluidComponent, LayoutNavigationComponent, LayoutContentComponent } from '@ojiepermana/angular/theme/layout';
|
|
9
|
+
import { LAYOUT_DEFAULT_SURFACE, LAYOUT_DEFAULT_APPEARANCE, LAYOUT_DEFAULT_WIDTH, LAYOUT_DEFAULT_TYPE } from '@ojiepermana/angular/theme/layout/types';
|
|
10
|
+
import { NAVIGATION_ADAPTER } from '@ojiepermana/angular/navigation/core';
|
|
2
11
|
|
|
3
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The identity shape the layout wrappers consume. The library defines the structure
|
|
14
|
+
* only; the concrete brand and user values come from the consumer as inputs.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Registry key used only while `LayoutWrapperDefault` renders its desktop nav. */
|
|
18
|
+
const LAYOUT_DESKTOP_NAVIGATION_DATA_ID = '__layout-desktop-navigation';
|
|
19
|
+
/**
|
|
20
|
+
* Registry of the brand and user identity a shell publishes (`LayoutWrapperDefault`, for
|
|
21
|
+
* one). Other surfaces — the apps launcher in `Page`, say — read it so they show the same
|
|
22
|
+
* brand and user as the nav flyout without taking inputs of their own.
|
|
23
|
+
*/
|
|
24
|
+
class LayoutIdentityService {
|
|
25
|
+
brandState = signal(null, /* @ts-ignore */
|
|
26
|
+
...(ngDevMode ? [{ debugName: "brandState" }] : /* istanbul ignore next */ []));
|
|
27
|
+
userState = signal(null, /* @ts-ignore */
|
|
28
|
+
...(ngDevMode ? [{ debugName: "userState" }] : /* istanbul ignore next */ []));
|
|
29
|
+
brand = this.brandState.asReadonly();
|
|
30
|
+
user = this.userState.asReadonly();
|
|
31
|
+
setBrand(brand) {
|
|
32
|
+
this.brandState.set(brand);
|
|
33
|
+
}
|
|
34
|
+
setUser(user) {
|
|
35
|
+
this.userState.set(user);
|
|
36
|
+
}
|
|
37
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutIdentityService, deps: [], target: i0.ɵɵFactoryTarget.Service });
|
|
38
|
+
static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.4", ngImport: i0, type: LayoutIdentityService });
|
|
39
|
+
}
|
|
40
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutIdentityService, decorators: [{
|
|
41
|
+
type: Service
|
|
42
|
+
}] });
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The brand slot for `<NavigationHeader>`: initials or logo plus a title. Purely
|
|
46
|
+
* input-driven.
|
|
47
|
+
*
|
|
48
|
+
* `compact` (dockbar, or an icon-only rail) hides the title. `host.class = 'contents'`
|
|
49
|
+
* keeps `NavigationHeaderInitial` and `NavigationHeaderTitle` as direct flex children of
|
|
50
|
+
* the header row; the title still auto-hides on a collapsed sidebar, because
|
|
51
|
+
* `NAVIGATION_SHELL` reaches `<Navigation>` through the live injector tree.
|
|
52
|
+
*/
|
|
53
|
+
class LayoutBrand {
|
|
54
|
+
/** Identitas brand (nama, ikon, judul, subjudul). */
|
|
55
|
+
brand = input.required(/* @ts-ignore */
|
|
56
|
+
...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
57
|
+
/** Sembunyikan judul, sisakan inisial saja (dockbar / rail ikon-only). */
|
|
58
|
+
compact = input(false, { ...(ngDevMode ? { debugName: "compact" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
59
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutBrand, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
60
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: LayoutBrand, isStandalone: true, selector: "LayoutBrand", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: true, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
|
|
61
|
+
<NavigationHeaderInitial [name]="brand().name" [icon]="brand().icon" [compact]="compact()" />
|
|
62
|
+
@if (!compact()) {
|
|
63
|
+
<NavigationHeaderTitle [title]="brand().title" [subtitle]="brand().subtitle" />
|
|
64
|
+
}
|
|
65
|
+
`, isInline: true, dependencies: [{ kind: "component", type: NavigationHeaderInitialComponent, selector: "NavigationHeaderInitial", inputs: ["name", "src", "initials", "icon", "compact", "class"] }, { kind: "component", type: NavigationHeaderTitleComponent, selector: "NavigationHeaderTitle", inputs: ["title", "subtitle", "class"] }] });
|
|
66
|
+
}
|
|
67
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutBrand, decorators: [{
|
|
68
|
+
type: Component,
|
|
69
|
+
args: [{
|
|
70
|
+
selector: 'LayoutBrand',
|
|
71
|
+
imports: [NavigationHeaderInitialComponent, NavigationHeaderTitleComponent],
|
|
72
|
+
host: { class: 'contents' },
|
|
73
|
+
template: `
|
|
74
|
+
<NavigationHeaderInitial [name]="brand().name" [icon]="brand().icon" [compact]="compact()" />
|
|
75
|
+
@if (!compact()) {
|
|
76
|
+
<NavigationHeaderTitle [title]="brand().title" [subtitle]="brand().subtitle" />
|
|
77
|
+
}
|
|
78
|
+
`,
|
|
79
|
+
}]
|
|
80
|
+
}], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: true }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }] } });
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The user slot for `<NavigationFooter>`: an optional identity plus the logout action.
|
|
84
|
+
* Purely input-driven.
|
|
85
|
+
*
|
|
86
|
+
* `detailed` shows initials and name (a full sidebar); without it, only the logout
|
|
87
|
+
* button. `host.class = 'contents'` makes the children direct flex children of the
|
|
88
|
+
* footer, so `ml-auto` and the auto-hide on collapse (through `NAVIGATION_SHELL`) still
|
|
89
|
+
* apply.
|
|
90
|
+
*
|
|
91
|
+
* The logout button only emits `(logout)`. Endpoint, cookie, and redirect target differ
|
|
92
|
+
* per application, so the effect is entirely the consumer's — the library calls no
|
|
93
|
+
* endpoint and performs no navigation. A consumer that never binds `(logout)` still
|
|
94
|
+
* renders without error; the button simply does nothing, exactly as before this output
|
|
95
|
+
* existed.
|
|
96
|
+
*/
|
|
97
|
+
class LayoutUser {
|
|
98
|
+
/** Identitas user (nama + email). */
|
|
99
|
+
user = input.required(/* @ts-ignore */
|
|
100
|
+
...(ngDevMode ? [{ debugName: "user" }] : /* istanbul ignore next */ []));
|
|
101
|
+
/** Show the user identity (initials and name), not only the logout button. */
|
|
102
|
+
detailed = input(false, { ...(ngDevMode ? { debugName: "detailed" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
103
|
+
/** Accessible name for the logout button. */
|
|
104
|
+
logoutLabel = input('Logout', /* @ts-ignore */
|
|
105
|
+
...(ngDevMode ? [{ debugName: "logoutLabel" }] : /* istanbul ignore next */ []));
|
|
106
|
+
/** Material symbol for the logout button. */
|
|
107
|
+
logoutIcon = input('logout', /* @ts-ignore */
|
|
108
|
+
...(ngDevMode ? [{ debugName: "logoutIcon" }] : /* istanbul ignore next */ []));
|
|
109
|
+
/** The user pressed logout. The effect is the consumer's; the library does not navigate. */
|
|
110
|
+
logout = output();
|
|
111
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutUser, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
112
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: LayoutUser, isStandalone: true, selector: "LayoutUser", inputs: { user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: true, transformFunction: null }, detailed: { classPropertyName: "detailed", publicName: "detailed", isSignal: true, isRequired: false, transformFunction: null }, logoutLabel: { classPropertyName: "logoutLabel", publicName: "logoutLabel", isSignal: true, isRequired: false, transformFunction: null }, logoutIcon: { classPropertyName: "logoutIcon", publicName: "logoutIcon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { logout: "logout" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
|
|
113
|
+
@if (detailed()) {
|
|
114
|
+
<NavigationFooterInitial [name]="user().name" />
|
|
115
|
+
<NavigationFooterTitle class="flex-1" [title]="user().name" [subtitle]="user().email" />
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
<NavigationFooterAction class="ml-auto">
|
|
119
|
+
<button
|
|
120
|
+
type="button"
|
|
121
|
+
[attr.aria-label]="logoutLabel()"
|
|
122
|
+
[attr.title]="logoutLabel()"
|
|
123
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
124
|
+
(click)="logout.emit()"
|
|
125
|
+
>
|
|
126
|
+
<Icon [name]="logoutIcon()" [size]="18" />
|
|
127
|
+
</button>
|
|
128
|
+
<ThemeSettings [trigger-icon-only]="true" class="size-8! min-h-8!" />
|
|
129
|
+
</NavigationFooterAction>
|
|
130
|
+
`, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }, { kind: "component", type: ThemeSettingsComponent, selector: "ThemeSettings", inputs: ["open", "trigger", "triggerLabel", "trigger-icon-only", "show-trigger", "side", "class"], outputs: ["openChange"] }, { kind: "component", type: NavigationFooterActionComponent, selector: "NavigationFooterAction", inputs: ["class"] }, { kind: "component", type: NavigationFooterInitialComponent, selector: "NavigationFooterInitial", inputs: ["name", "src", "initials", "icon", "class"] }, { kind: "component", type: NavigationFooterTitleComponent, selector: "NavigationFooterTitle", inputs: ["title", "subtitle", "class"] }] });
|
|
131
|
+
}
|
|
132
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutUser, decorators: [{
|
|
133
|
+
type: Component,
|
|
134
|
+
args: [{
|
|
135
|
+
selector: 'LayoutUser',
|
|
136
|
+
imports: [
|
|
137
|
+
IconComponent,
|
|
138
|
+
ThemeSettingsComponent,
|
|
139
|
+
NavigationFooterActionComponent,
|
|
140
|
+
NavigationFooterInitialComponent,
|
|
141
|
+
NavigationFooterTitleComponent,
|
|
142
|
+
],
|
|
143
|
+
host: { class: 'contents' },
|
|
144
|
+
template: `
|
|
145
|
+
@if (detailed()) {
|
|
146
|
+
<NavigationFooterInitial [name]="user().name" />
|
|
147
|
+
<NavigationFooterTitle class="flex-1" [title]="user().name" [subtitle]="user().email" />
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
<NavigationFooterAction class="ml-auto">
|
|
151
|
+
<button
|
|
152
|
+
type="button"
|
|
153
|
+
[attr.aria-label]="logoutLabel()"
|
|
154
|
+
[attr.title]="logoutLabel()"
|
|
155
|
+
class="inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
156
|
+
(click)="logout.emit()"
|
|
157
|
+
>
|
|
158
|
+
<Icon [name]="logoutIcon()" [size]="18" />
|
|
159
|
+
</button>
|
|
160
|
+
<ThemeSettings [trigger-icon-only]="true" class="size-8! min-h-8!" />
|
|
161
|
+
</NavigationFooterAction>
|
|
162
|
+
`,
|
|
163
|
+
}]
|
|
164
|
+
}], propDecorators: { user: [{ type: i0.Input, args: [{ isSignal: true, alias: "user", required: true }] }], detailed: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailed", required: false }] }], logoutLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoutLabel", required: false }] }], logoutIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoutIcon", required: false }] }], logout: [{ type: i0.Output, args: ["logout"] }] } });
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Nav type: a collapsible vertical sidebar (the default). Brand in the header, user
|
|
168
|
+
* identity in the footer.
|
|
169
|
+
*
|
|
170
|
+
* Horizontal dividers: the sidebar ALWAYS uses the borders `NavigationHeader`
|
|
171
|
+
* (`border-b`) and `NavigationFooter` (`border-t`) bring, `border-rail` included.
|
|
172
|
+
* Layout's inset accent rail (`top-12`/`bottom-12`) sits behind a frame that is now
|
|
173
|
+
* solid (`bg-background`) and is therefore invisible inside it; those explicit borders
|
|
174
|
+
* are what keep the header and footer lines visible and running straight into the
|
|
175
|
+
* content column (both `h-12`), consistent with {@link LayoutNavDockbar}.
|
|
176
|
+
*
|
|
177
|
+
* `host.class = 'contents'` makes `<NavigationSidebar>` an effective child of
|
|
178
|
+
* `<Navigation>` (h-full, shell classes), while `NAVIGATION_SHELL` still reaches it
|
|
179
|
+
* through the live injector tree and `<NavigationHeader>` stays a direct child for the
|
|
180
|
+
* library's content projection.
|
|
181
|
+
*/
|
|
182
|
+
class LayoutNavSidebar {
|
|
183
|
+
brand = input.required(/* @ts-ignore */
|
|
184
|
+
...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
185
|
+
user = input.required(/* @ts-ignore */
|
|
186
|
+
...(ngDevMode ? [{ debugName: "user" }] : /* istanbul ignore next */ []));
|
|
187
|
+
/** Appearance from the shell (`[appearance]`); decides the separator border weight. */
|
|
188
|
+
appearance = input('flat', /* @ts-ignore */
|
|
189
|
+
...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
|
|
190
|
+
navTypeMode = input('default', { ...(ngDevMode ? { debugName: "navTypeMode" } : /* istanbul ignore next */ {}), alias: 'nav-type-mode' });
|
|
191
|
+
/** Forwarded from `<LayoutUser>`; the effect is the consumer's. */
|
|
192
|
+
logout = output();
|
|
193
|
+
isBorderRail = computed(() => this.appearance() === 'border-rail', /* @ts-ignore */
|
|
194
|
+
...(ngDevMode ? [{ debugName: "isBorderRail" }] : /* istanbul ignore next */ []));
|
|
195
|
+
isCollapsed = computed(() => this.navTypeMode() === 'collapsed', /* @ts-ignore */
|
|
196
|
+
...(ngDevMode ? [{ debugName: "isCollapsed" }] : /* istanbul ignore next */ []));
|
|
197
|
+
/** Border kanan pemisah; ketebalan ikut appearance: `border-rail` = `--layout-rail-width` (selaras rail layout), `flat` 1px. */
|
|
198
|
+
shellClass = computed(() => this.isBorderRail()
|
|
199
|
+
? 'border-r-[length:var(--layout-rail-width)] border-border'
|
|
200
|
+
: 'border-r border-border', /* @ts-ignore */
|
|
201
|
+
...(ngDevMode ? [{ debugName: "shellClass" }] : /* istanbul ignore next */ []));
|
|
202
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavSidebar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
203
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: LayoutNavSidebar, isStandalone: true, selector: "LayoutNavSidebar", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: true, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: true, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, navTypeMode: { classPropertyName: "navTypeMode", publicName: "nav-type-mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { logout: "logout" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
|
|
204
|
+
<NavigationSidebar nav-sidebar-collapse [collapsed]="isCollapsed()" [class]="shellClass()">
|
|
205
|
+
<NavigationHeader>
|
|
206
|
+
<LayoutBrand [brand]="brand()" />
|
|
207
|
+
</NavigationHeader>
|
|
208
|
+
<NavigationFooter class="px-3">
|
|
209
|
+
<LayoutUser [user]="user()" detailed (logout)="logout.emit()" />
|
|
210
|
+
</NavigationFooter>
|
|
211
|
+
</NavigationSidebar>
|
|
212
|
+
`, isInline: true, dependencies: [{ kind: "component", type: NavigationSidebarComponent, selector: "NavigationSidebar", inputs: ["position", "collapsed", "nav-sidebar-collapse", "previewExpanded", "class"] }, { kind: "component", type: NavigationHeaderComponent, selector: "NavigationHeader", inputs: ["toggle", "class"] }, { kind: "component", type: NavigationFooterComponent, selector: "NavigationFooter", inputs: ["class"] }, { kind: "component", type: LayoutBrand, selector: "LayoutBrand", inputs: ["brand", "compact"] }, { kind: "component", type: LayoutUser, selector: "LayoutUser", inputs: ["user", "detailed", "logoutLabel", "logoutIcon"], outputs: ["logout"] }] });
|
|
213
|
+
}
|
|
214
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavSidebar, decorators: [{
|
|
215
|
+
type: Component,
|
|
216
|
+
args: [{
|
|
217
|
+
selector: 'LayoutNavSidebar',
|
|
218
|
+
imports: [
|
|
219
|
+
NavigationSidebarComponent,
|
|
220
|
+
NavigationHeaderComponent,
|
|
221
|
+
NavigationFooterComponent,
|
|
222
|
+
LayoutBrand,
|
|
223
|
+
LayoutUser,
|
|
224
|
+
],
|
|
225
|
+
host: { class: 'contents' },
|
|
226
|
+
template: `
|
|
227
|
+
<NavigationSidebar nav-sidebar-collapse [collapsed]="isCollapsed()" [class]="shellClass()">
|
|
228
|
+
<NavigationHeader>
|
|
229
|
+
<LayoutBrand [brand]="brand()" />
|
|
230
|
+
</NavigationHeader>
|
|
231
|
+
<NavigationFooter class="px-3">
|
|
232
|
+
<LayoutUser [user]="user()" detailed (logout)="logout.emit()" />
|
|
233
|
+
</NavigationFooter>
|
|
234
|
+
</NavigationSidebar>
|
|
235
|
+
`,
|
|
236
|
+
}]
|
|
237
|
+
}], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: true }] }], user: [{ type: i0.Input, args: [{ isSignal: true, alias: "user", required: true }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], navTypeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-type-mode", required: false }] }], logout: [{ type: i0.Output, args: ["logout"] }] } });
|
|
238
|
+
|
|
239
|
+
const EMPTY_NAVIGATION_BADGE_CONTEXT$1 = Object.freeze({});
|
|
240
|
+
/**
|
|
241
|
+
* Nav type: a vertical icon rail (dockbar). A compact brand (initials only) in the
|
|
242
|
+
* header, the user's initials in the rail footer (title and actions auto-hide, because
|
|
243
|
+
* the rail is always collapsed), and the full identity (name, email, logout) in the
|
|
244
|
+
* aside footer — together with the rail initials they form one footer row, like an
|
|
245
|
+
* expanded sidebar.
|
|
246
|
+
*
|
|
247
|
+
* Horizontal dividers: unlike the sidebar, which leaves the separator to Layout's inset
|
|
248
|
+
* accent rail at `top-12`/`bottom-12` under `border-rail`, the dockbar ALWAYS uses the
|
|
249
|
+
* borders `NavigationHeader`/`NavigationFooter` bring. The dockbar aside covers the inset
|
|
250
|
+
* rail line with its own opaque background, so those explicit borders are what keep the
|
|
251
|
+
* separator running straight from rail to aside (header and footer are both `h-12`).
|
|
252
|
+
* See {@link LayoutNavSidebar} for why `host.class = 'contents'`.
|
|
253
|
+
*/
|
|
254
|
+
class LayoutNavDockbar {
|
|
255
|
+
brand = input.required(/* @ts-ignore */
|
|
256
|
+
...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
257
|
+
user = input.required(/* @ts-ignore */
|
|
258
|
+
...(ngDevMode ? [{ debugName: "user" }] : /* istanbul ignore next */ []));
|
|
259
|
+
/** Appearance from the shell (`[appearance]`); decides the separator border weight. */
|
|
260
|
+
appearance = input('flat', /* @ts-ignore */
|
|
261
|
+
...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
|
|
262
|
+
navTypeMode = input('default', { ...(ngDevMode ? { debugName: "navTypeMode" } : /* istanbul ignore next */ {}), alias: 'nav-type-mode' });
|
|
263
|
+
/** Opt-in route-aware header; ketika aktif, header route menggantikan compact brand. */
|
|
264
|
+
dockbarRouteContext = input(null, { ...(ngDevMode ? { debugName: "dockbarRouteContext" } : /* istanbul ignore next */ {}), alias: 'dockbar-route-context' });
|
|
265
|
+
/** The generic badge registry forwarded to `NavigationDockbar`. */
|
|
266
|
+
dockbarBadgeContext = input(EMPTY_NAVIGATION_BADGE_CONTEXT$1, { ...(ngDevMode ? { debugName: "dockbarBadgeContext" } : /* istanbul ignore next */ {}), alias: 'dockbar-badge' });
|
|
267
|
+
/** Forwarded from the rail and aside footer logout buttons; the effect is the consumer's. */
|
|
268
|
+
logout = output();
|
|
269
|
+
isBorderRail = computed(() => this.appearance() === 'border-rail', /* @ts-ignore */
|
|
270
|
+
...(ngDevMode ? [{ debugName: "isBorderRail" }] : /* istanbul ignore next */ []));
|
|
271
|
+
dockbarMode = computed(() => this.navTypeMode() === 'drawer' ? 'drawer' : 'sticky', /* @ts-ignore */
|
|
272
|
+
...(ngDevMode ? [{ debugName: "dockbarMode" }] : /* istanbul ignore next */ []));
|
|
273
|
+
routeContextEnabled = computed(() => {
|
|
274
|
+
const context = this.dockbarRouteContext();
|
|
275
|
+
return context !== null && context !== false;
|
|
276
|
+
}, /* @ts-ignore */
|
|
277
|
+
...(ngDevMode ? [{ debugName: "routeContextEnabled" }] : /* istanbul ignore next */ []));
|
|
278
|
+
/** Border kanan pemisah; ketebalan ikut appearance: `border-rail` = `--layout-rail-width` (selaras rail layout), `flat` 1px. */
|
|
279
|
+
shellClass = computed(() => this.isBorderRail()
|
|
280
|
+
? 'border-r-[length:var(--layout-rail-width)] border-border'
|
|
281
|
+
: 'border-r border-border', /* @ts-ignore */
|
|
282
|
+
...(ngDevMode ? [{ debugName: "shellClass" }] : /* istanbul ignore next */ []));
|
|
283
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavDockbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
284
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: LayoutNavDockbar, isStandalone: true, selector: "LayoutNavDockbar", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: true, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: true, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, navTypeMode: { classPropertyName: "navTypeMode", publicName: "nav-type-mode", isSignal: true, isRequired: false, transformFunction: null }, dockbarRouteContext: { classPropertyName: "dockbarRouteContext", publicName: "dockbar-route-context", isSignal: true, isRequired: false, transformFunction: null }, dockbarBadgeContext: { classPropertyName: "dockbarBadgeContext", publicName: "dockbar-badge", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { logout: "logout" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
|
|
285
|
+
<NavigationDockbar
|
|
286
|
+
[mode]="dockbarMode()"
|
|
287
|
+
[dockbar-route-context]="dockbarRouteContext()"
|
|
288
|
+
[dockbar-badge]="dockbarBadgeContext()"
|
|
289
|
+
[class]="shellClass()"
|
|
290
|
+
>
|
|
291
|
+
@if (!routeContextEnabled()) {
|
|
292
|
+
<NavigationHeader>
|
|
293
|
+
<LayoutBrand [brand]="brand()" compact />
|
|
294
|
+
</NavigationHeader>
|
|
295
|
+
}
|
|
296
|
+
<NavigationFooter class="px-3">
|
|
297
|
+
<LayoutUser [user]="user()" detailed (logout)="logout.emit()" />
|
|
298
|
+
</NavigationFooter>
|
|
299
|
+
|
|
300
|
+
<ng-template NavigationAsideFooter>
|
|
301
|
+
<div class="flex min-w-0 flex-col justify-center">
|
|
302
|
+
<span class="block truncate text-sm font-semibold leading-tight text-foreground">{{
|
|
303
|
+
user().name
|
|
304
|
+
}}</span>
|
|
305
|
+
<span class="block truncate text-xs leading-tight text-muted-foreground">{{
|
|
306
|
+
user().email
|
|
307
|
+
}}</span>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<button
|
|
311
|
+
type="button"
|
|
312
|
+
aria-label="Logout"
|
|
313
|
+
title="Logout"
|
|
314
|
+
class="ml-auto inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
315
|
+
(click)="logout.emit()"
|
|
316
|
+
>
|
|
317
|
+
<Icon name="logout" [size]="18" />
|
|
318
|
+
</button>
|
|
319
|
+
</ng-template>
|
|
320
|
+
</NavigationDockbar>
|
|
321
|
+
`, isInline: true, dependencies: [{ kind: "component", type: IconComponent, selector: "Icon", inputs: ["name", "class", "size", "fill", "weight", "grade", "opticalSize"] }, { kind: "directive", type: NavigationAsideFooterDirective, selector: "ng-template[NavigationAsideFooter]" }, { kind: "component", type: NavigationDockbarComponent, selector: "NavigationDockbar", inputs: ["mode", "position", "dockbar-route-context", "dockbar-badge", "class"] }, { kind: "component", type: NavigationHeaderComponent, selector: "NavigationHeader", inputs: ["toggle", "class"] }, { kind: "component", type: NavigationFooterComponent, selector: "NavigationFooter", inputs: ["class"] }, { kind: "component", type: LayoutBrand, selector: "LayoutBrand", inputs: ["brand", "compact"] }, { kind: "component", type: LayoutUser, selector: "LayoutUser", inputs: ["user", "detailed", "logoutLabel", "logoutIcon"], outputs: ["logout"] }] });
|
|
322
|
+
}
|
|
323
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavDockbar, decorators: [{
|
|
324
|
+
type: Component,
|
|
325
|
+
args: [{
|
|
326
|
+
selector: 'LayoutNavDockbar',
|
|
327
|
+
imports: [
|
|
328
|
+
IconComponent,
|
|
329
|
+
NavigationAsideFooterDirective,
|
|
330
|
+
NavigationDockbarComponent,
|
|
331
|
+
NavigationHeaderComponent,
|
|
332
|
+
NavigationFooterComponent,
|
|
333
|
+
LayoutBrand,
|
|
334
|
+
LayoutUser,
|
|
335
|
+
],
|
|
336
|
+
host: { class: 'contents' },
|
|
337
|
+
template: `
|
|
338
|
+
<NavigationDockbar
|
|
339
|
+
[mode]="dockbarMode()"
|
|
340
|
+
[dockbar-route-context]="dockbarRouteContext()"
|
|
341
|
+
[dockbar-badge]="dockbarBadgeContext()"
|
|
342
|
+
[class]="shellClass()"
|
|
343
|
+
>
|
|
344
|
+
@if (!routeContextEnabled()) {
|
|
345
|
+
<NavigationHeader>
|
|
346
|
+
<LayoutBrand [brand]="brand()" compact />
|
|
347
|
+
</NavigationHeader>
|
|
348
|
+
}
|
|
349
|
+
<NavigationFooter class="px-3">
|
|
350
|
+
<LayoutUser [user]="user()" detailed (logout)="logout.emit()" />
|
|
351
|
+
</NavigationFooter>
|
|
352
|
+
|
|
353
|
+
<ng-template NavigationAsideFooter>
|
|
354
|
+
<div class="flex min-w-0 flex-col justify-center">
|
|
355
|
+
<span class="block truncate text-sm font-semibold leading-tight text-foreground">{{
|
|
356
|
+
user().name
|
|
357
|
+
}}</span>
|
|
358
|
+
<span class="block truncate text-xs leading-tight text-muted-foreground">{{
|
|
359
|
+
user().email
|
|
360
|
+
}}</span>
|
|
361
|
+
</div>
|
|
362
|
+
|
|
363
|
+
<button
|
|
364
|
+
type="button"
|
|
365
|
+
aria-label="Logout"
|
|
366
|
+
title="Logout"
|
|
367
|
+
class="ml-auto inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
368
|
+
(click)="logout.emit()"
|
|
369
|
+
>
|
|
370
|
+
<Icon name="logout" [size]="18" />
|
|
371
|
+
</button>
|
|
372
|
+
</ng-template>
|
|
373
|
+
</NavigationDockbar>
|
|
374
|
+
`,
|
|
375
|
+
}]
|
|
376
|
+
}], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: true }] }], user: [{ type: i0.Input, args: [{ isSignal: true, alias: "user", required: true }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], navTypeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-type-mode", required: false }] }], dockbarRouteContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dockbar-route-context", required: false }] }], dockbarBadgeContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dockbar-badge", required: false }] }], logout: [{ type: i0.Output, args: ["logout"] }] } });
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Nav type: a top bar with inline items (navbar, horizontal). `appearance` follows the
|
|
380
|
+
* shell (`flat | border-rail`). See {@link LayoutNavSidebar} for why
|
|
381
|
+
* `host.class = 'contents'`.
|
|
382
|
+
*/
|
|
383
|
+
class LayoutNavNavbar {
|
|
384
|
+
brand = input.required(/* @ts-ignore */
|
|
385
|
+
...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
386
|
+
user = input.required(/* @ts-ignore */
|
|
387
|
+
...(ngDevMode ? [{ debugName: "user" }] : /* istanbul ignore next */ []));
|
|
388
|
+
/** Appearance from the shell (`[nav-type-style]`). */
|
|
389
|
+
appearance = input('flat', /* @ts-ignore */
|
|
390
|
+
...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
|
|
391
|
+
/** Forwarded from `<LayoutUser>`; the effect is the consumer's. */
|
|
392
|
+
logout = output();
|
|
393
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavNavbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
394
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: LayoutNavNavbar, isStandalone: true, selector: "LayoutNavNavbar", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: true, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: true, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { logout: "logout" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
|
|
395
|
+
<NavigationNavbar [nav-type-style]="appearance()" class="border-b border-border">
|
|
396
|
+
<NavigationHeader>
|
|
397
|
+
<LayoutBrand [brand]="brand()" />
|
|
398
|
+
</NavigationHeader>
|
|
399
|
+
<NavigationFooter class="px-3">
|
|
400
|
+
<LayoutUser [user]="user()" (logout)="logout.emit()" />
|
|
401
|
+
</NavigationFooter>
|
|
402
|
+
</NavigationNavbar>
|
|
403
|
+
`, isInline: true, dependencies: [{ kind: "component", type: NavigationNavbarComponent, selector: "NavigationNavbar", inputs: ["nav-position", "nav-type-style", "class"] }, { kind: "component", type: NavigationHeaderComponent, selector: "NavigationHeader", inputs: ["toggle", "class"] }, { kind: "component", type: NavigationFooterComponent, selector: "NavigationFooter", inputs: ["class"] }, { kind: "component", type: LayoutBrand, selector: "LayoutBrand", inputs: ["brand", "compact"] }, { kind: "component", type: LayoutUser, selector: "LayoutUser", inputs: ["user", "detailed", "logoutLabel", "logoutIcon"], outputs: ["logout"] }] });
|
|
404
|
+
}
|
|
405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavNavbar, decorators: [{
|
|
406
|
+
type: Component,
|
|
407
|
+
args: [{
|
|
408
|
+
selector: 'LayoutNavNavbar',
|
|
409
|
+
imports: [
|
|
410
|
+
NavigationNavbarComponent,
|
|
411
|
+
NavigationHeaderComponent,
|
|
412
|
+
NavigationFooterComponent,
|
|
413
|
+
LayoutBrand,
|
|
414
|
+
LayoutUser,
|
|
415
|
+
],
|
|
416
|
+
host: { class: 'contents' },
|
|
417
|
+
template: `
|
|
418
|
+
<NavigationNavbar [nav-type-style]="appearance()" class="border-b border-border">
|
|
419
|
+
<NavigationHeader>
|
|
420
|
+
<LayoutBrand [brand]="brand()" />
|
|
421
|
+
</NavigationHeader>
|
|
422
|
+
<NavigationFooter class="px-3">
|
|
423
|
+
<LayoutUser [user]="user()" (logout)="logout.emit()" />
|
|
424
|
+
</NavigationFooter>
|
|
425
|
+
</NavigationNavbar>
|
|
426
|
+
`,
|
|
427
|
+
}]
|
|
428
|
+
}], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: true }] }], user: [{ type: i0.Input, args: [{ isSignal: true, alias: "user", required: true }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], logout: [{ type: i0.Output, args: ["logout"] }] } });
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Nav type: a top bar with a flyout trigger button (horizontal). `appearance` follows the
|
|
432
|
+
* shell. See {@link LayoutNavSidebar} for why `host.class = 'contents'`.
|
|
433
|
+
*/
|
|
434
|
+
class LayoutNavFlyout {
|
|
435
|
+
brand = input.required(/* @ts-ignore */
|
|
436
|
+
...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
437
|
+
user = input.required(/* @ts-ignore */
|
|
438
|
+
...(ngDevMode ? [{ debugName: "user" }] : /* istanbul ignore next */ []));
|
|
439
|
+
/** Appearance from the shell (`[nav-type-style]`). */
|
|
440
|
+
appearance = input('flat', /* @ts-ignore */
|
|
441
|
+
...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
|
|
442
|
+
/** Forwarded from `<LayoutUser>`; the effect is the consumer's. */
|
|
443
|
+
logout = output();
|
|
444
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavFlyout, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
445
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: LayoutNavFlyout, isStandalone: true, selector: "LayoutNavFlyout", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: true, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: true, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { logout: "logout" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
|
|
446
|
+
<NavigationFlyout
|
|
447
|
+
[nav-type-style]="appearance()"
|
|
448
|
+
label="Menu"
|
|
449
|
+
icon="apps"
|
|
450
|
+
class="border-b border-border"
|
|
451
|
+
>
|
|
452
|
+
<NavigationHeader>
|
|
453
|
+
<LayoutBrand [brand]="brand()" />
|
|
454
|
+
</NavigationHeader>
|
|
455
|
+
<NavigationFooter class="px-3">
|
|
456
|
+
<LayoutUser [user]="user()" (logout)="logout.emit()" />
|
|
457
|
+
</NavigationFooter>
|
|
458
|
+
</NavigationFlyout>
|
|
459
|
+
`, isInline: true, dependencies: [{ kind: "component", type: NavigationFlyoutComponent, selector: "NavigationFlyout", inputs: ["label", "icon", "icon-only", "icon-position", "trigger-variant", "trigger-floating", "panel-viewport", "trigger-class", "trigger-button-class", "nav-position", "nav-type-style", "class"] }, { kind: "component", type: NavigationHeaderComponent, selector: "NavigationHeader", inputs: ["toggle", "class"] }, { kind: "component", type: NavigationFooterComponent, selector: "NavigationFooter", inputs: ["class"] }, { kind: "component", type: LayoutBrand, selector: "LayoutBrand", inputs: ["brand", "compact"] }, { kind: "component", type: LayoutUser, selector: "LayoutUser", inputs: ["user", "detailed", "logoutLabel", "logoutIcon"], outputs: ["logout"] }] });
|
|
460
|
+
}
|
|
461
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavFlyout, decorators: [{
|
|
462
|
+
type: Component,
|
|
463
|
+
args: [{
|
|
464
|
+
selector: 'LayoutNavFlyout',
|
|
465
|
+
imports: [
|
|
466
|
+
NavigationFlyoutComponent,
|
|
467
|
+
NavigationHeaderComponent,
|
|
468
|
+
NavigationFooterComponent,
|
|
469
|
+
LayoutBrand,
|
|
470
|
+
LayoutUser,
|
|
471
|
+
],
|
|
472
|
+
host: { class: 'contents' },
|
|
473
|
+
template: `
|
|
474
|
+
<NavigationFlyout
|
|
475
|
+
[nav-type-style]="appearance()"
|
|
476
|
+
label="Menu"
|
|
477
|
+
icon="apps"
|
|
478
|
+
class="border-b border-border"
|
|
479
|
+
>
|
|
480
|
+
<NavigationHeader>
|
|
481
|
+
<LayoutBrand [brand]="brand()" />
|
|
482
|
+
</NavigationHeader>
|
|
483
|
+
<NavigationFooter class="px-3">
|
|
484
|
+
<LayoutUser [user]="user()" (logout)="logout.emit()" />
|
|
485
|
+
</NavigationFooter>
|
|
486
|
+
</NavigationFlyout>
|
|
487
|
+
`,
|
|
488
|
+
}]
|
|
489
|
+
}], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: true }] }], user: [{ type: i0.Input, args: [{ isSignal: true, alias: "user", required: true }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], logout: [{ type: i0.Output, args: ["logout"] }] } });
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Nav type: a brand-only sidebar for the `empty` and `fluid` variants, where
|
|
493
|
+
* `LayoutNavigation` hides the nav — so no collapse and no footer. See
|
|
494
|
+
* {@link LayoutNavSidebar} for why `host.class = 'contents'`.
|
|
495
|
+
*/
|
|
496
|
+
class LayoutNavMinimal {
|
|
497
|
+
brand = input.required(/* @ts-ignore */
|
|
498
|
+
...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
499
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavMinimal, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
500
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: LayoutNavMinimal, isStandalone: true, selector: "LayoutNavMinimal", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
|
|
501
|
+
<NavigationSidebar>
|
|
502
|
+
<NavigationHeader>
|
|
503
|
+
<LayoutBrand [brand]="brand()" />
|
|
504
|
+
</NavigationHeader>
|
|
505
|
+
</NavigationSidebar>
|
|
506
|
+
`, isInline: true, dependencies: [{ kind: "component", type: NavigationSidebarComponent, selector: "NavigationSidebar", inputs: ["position", "collapsed", "nav-sidebar-collapse", "previewExpanded", "class"] }, { kind: "component", type: NavigationHeaderComponent, selector: "NavigationHeader", inputs: ["toggle", "class"] }, { kind: "component", type: LayoutBrand, selector: "LayoutBrand", inputs: ["brand", "compact"] }] });
|
|
507
|
+
}
|
|
508
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutNavMinimal, decorators: [{
|
|
509
|
+
type: Component,
|
|
510
|
+
args: [{
|
|
511
|
+
selector: 'LayoutNavMinimal',
|
|
512
|
+
imports: [NavigationSidebarComponent, NavigationHeaderComponent, LayoutBrand],
|
|
513
|
+
host: { class: 'contents' },
|
|
514
|
+
template: `
|
|
515
|
+
<NavigationSidebar>
|
|
516
|
+
<NavigationHeader>
|
|
517
|
+
<LayoutBrand [brand]="brand()" />
|
|
518
|
+
</NavigationHeader>
|
|
519
|
+
</NavigationSidebar>
|
|
520
|
+
`,
|
|
521
|
+
}]
|
|
522
|
+
}], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: true }] }] } });
|
|
523
|
+
|
|
524
|
+
const EMPTY_NAVIGATION_BADGE_CONTEXT = Object.freeze({});
|
|
525
|
+
/**
|
|
526
|
+
* A ready-made layout shell — the consumer supplies data through inputs instead of
|
|
527
|
+
* assembling `Layout > LayoutVertical/Horizontal/Empty/Fluid > LayoutNavigation >
|
|
528
|
+
* Navigation > nav type` by hand.
|
|
529
|
+
*
|
|
530
|
+
* ```html
|
|
531
|
+
* <LayoutWrapperDefault
|
|
532
|
+
* [surface]="surface" [layout-appearance]="appearance" [width]="width"
|
|
533
|
+
* [layout-type]="layoutType" [nav-type]="navType"
|
|
534
|
+
* [data]="navItems" [brand]="brand" [user]="user"
|
|
535
|
+
* (logout)="signOut()"
|
|
536
|
+
* >
|
|
537
|
+
* <router-outlet /> <!-- page content is projected into LayoutContent -->
|
|
538
|
+
* </LayoutWrapperDefault>
|
|
539
|
+
* ```
|
|
540
|
+
*
|
|
541
|
+
* The `register*` defaults (LayoutService) stay the consumer's job; this wrapper is purely
|
|
542
|
+
* presentational — two axes (`effectiveLayoutType` → wrapper, `navKind` → nav type) over one
|
|
543
|
+
* shared skeleton. Injection stays sound: `<Navigation>` provides `NAVIGATION_SHELL` inside
|
|
544
|
+
* `#body`, and each nav type is `display:contents`, so `<NavigationXxx>` is an effective child
|
|
545
|
+
* of `<Navigation>`.
|
|
546
|
+
*/
|
|
547
|
+
class LayoutWrapperDefault {
|
|
548
|
+
/** Surface latar shell (mis. `grid`, `flat`). */
|
|
549
|
+
surface = input(LAYOUT_DEFAULT_SURFACE, /* @ts-ignore */
|
|
550
|
+
...(ngDevMode ? [{ debugName: "surface" }] : /* istanbul ignore next */ []));
|
|
551
|
+
/** Appearance shell & nav (`flat | border-rail`). */
|
|
552
|
+
appearance = input(LAYOUT_DEFAULT_APPEARANCE, { ...(ngDevMode ? { debugName: "appearance" } : /* istanbul ignore next */ {}), alias: 'layout-appearance' });
|
|
553
|
+
/** Frame width (`full`, `container`, and so on). */
|
|
554
|
+
width = input(LAYOUT_DEFAULT_WIDTH, /* @ts-ignore */
|
|
555
|
+
...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
556
|
+
/** Tipe layout dasar (`vertical | horizontal | empty | fluid`); `empty`/`fluid` override nav. */
|
|
557
|
+
layoutType = input(LAYOUT_DEFAULT_TYPE, { ...(ngDevMode ? { debugName: "layoutType" } : /* istanbul ignore next */ {}), alias: 'layout-type' });
|
|
558
|
+
/**
|
|
559
|
+
* The shell's navigation type. `desktop` only means anything on a horizontal frame:
|
|
560
|
+
* the titlebar becomes the primary chrome and the navigation area follows the
|
|
561
|
+
* content-focused `empty` behaviour.
|
|
562
|
+
*/
|
|
563
|
+
navType = input('sidebar', { ...(ngDevMode ? { debugName: "navType" } : /* istanbul ignore next */ {}), alias: 'nav-type' });
|
|
564
|
+
/** Presentation mode for the active nav type (`collapsed` sidebar / `drawer` dockbar). */
|
|
565
|
+
navTypeMode = input('default', { ...(ngDevMode ? { debugName: "navTypeMode" } : /* istanbul ignore next */ {}), alias: 'nav-type-mode' });
|
|
566
|
+
/** Opt-in route-aware dockbar state; ignored by other navigation types. */
|
|
567
|
+
dockbarRouteContext = input(null, { ...(ngDevMode ? { debugName: "dockbarRouteContext" } : /* istanbul ignore next */ {}), alias: 'dockbar-route-context' });
|
|
568
|
+
/** Generic dockbar badge registry; ignored by sidebar/navbar/flyout. */
|
|
569
|
+
dockbarBadgeContext = input(EMPTY_NAVIGATION_BADGE_CONTEXT, { ...(ngDevMode ? { debugName: "dockbarBadgeContext" } : /* istanbul ignore next */ {}), alias: 'dockbar-badge' });
|
|
570
|
+
/** Item navigasi. */
|
|
571
|
+
data = input.required(/* @ts-ignore */
|
|
572
|
+
...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
|
|
573
|
+
/** Identitas brand. */
|
|
574
|
+
brand = input.required(/* @ts-ignore */
|
|
575
|
+
...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
576
|
+
/** Identitas user. */
|
|
577
|
+
user = input.required(/* @ts-ignore */
|
|
578
|
+
...(ngDevMode ? [{ debugName: "user" }] : /* istanbul ignore next */ []));
|
|
579
|
+
/** Id landmark konten utama sekaligus target skip link. */
|
|
580
|
+
contentId = input('main-content', { ...(ngDevMode ? { debugName: "contentId" } : /* istanbul ignore next */ {}), alias: 'content-id' });
|
|
581
|
+
/** Skip-link label; the consumer can localise it. */
|
|
582
|
+
skipLinkLabel = input('Skip to main content', { ...(ngDevMode ? { debugName: "skipLinkLabel" } : /* istanbul ignore next */ {}), alias: 'skip-link-label' });
|
|
583
|
+
/** Fokuskan landmark utama setelah route selesai berubah. */
|
|
584
|
+
focusOnNavigation = input(false, { ...(ngDevMode ? { debugName: "focusOnNavigation" } : /* istanbul ignore next */ {}), alias: 'focus-on-navigation' });
|
|
585
|
+
/** Controlled/uncontrolled state drawer navigasi mobile. */
|
|
586
|
+
mobileNavOpen = model(false, { ...(ngDevMode ? { debugName: "mobileNavOpen" } : /* istanbul ignore next */ {}), alias: 'mobile-nav-open' });
|
|
587
|
+
mobileNavLabel = input('Open navigation', { ...(ngDevMode ? { debugName: "mobileNavLabel" } : /* istanbul ignore next */ {}), alias: 'mobile-nav-label' });
|
|
588
|
+
closeMobileNavLabel = input('Close navigation', { ...(ngDevMode ? { debugName: "closeMobileNavLabel" } : /* istanbul ignore next */ {}), alias: 'close-mobile-nav-label' });
|
|
589
|
+
/**
|
|
590
|
+
* The user pressed logout in the navigation footer. Forwarded from every nav type that
|
|
591
|
+
* shows the user identity (`sidebar`, `dockbar`, `navbar`, `flyout`), the mobile drawer
|
|
592
|
+
* included, so one binding covers all of them. The library calls no endpoint and performs
|
|
593
|
+
* no navigation; what happens next is entirely the consumer's.
|
|
594
|
+
*/
|
|
595
|
+
logout = output();
|
|
596
|
+
identity = inject(LayoutIdentityService);
|
|
597
|
+
navigation = inject(NAVIGATION_ADAPTER);
|
|
598
|
+
desktopNavigationDataOwner = {};
|
|
599
|
+
document = inject(DOCUMENT, { optional: true });
|
|
600
|
+
mobileNavTriggerRef = viewChild('mobileNavTrigger', /* @ts-ignore */
|
|
601
|
+
...(ngDevMode ? [{ debugName: "mobileNavTriggerRef" }] : /* istanbul ignore next */ []));
|
|
602
|
+
constructor() {
|
|
603
|
+
// Publikasikan identitas ke registry agar surface lain (mis. apps-launcher di `Page`)
|
|
604
|
+
// menampilkan brand/user yang sama dengan flyout nav.
|
|
605
|
+
effect(() => this.identity.setBrand(this.brand()));
|
|
606
|
+
effect(() => this.identity.setUser(this.user()));
|
|
607
|
+
// Desktop navigation has no in-layout <Navigation> node: its trigger belongs
|
|
608
|
+
// to the window titlebar. Publish the same data through a dedicated key so
|
|
609
|
+
// <Shell> can surface it without duplicating navbar/dockbar configurations.
|
|
610
|
+
effect((onCleanup) => {
|
|
611
|
+
if (this.navType() !== 'desktop') {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
this.navigation.publishData(LAYOUT_DESKTOP_NAVIGATION_DATA_ID, this.data(), this.desktopNavigationDataOwner);
|
|
615
|
+
onCleanup(() => this.navigation.clearData(LAYOUT_DESKTOP_NAVIGATION_DATA_ID, this.desktopNavigationDataOwner));
|
|
616
|
+
});
|
|
617
|
+
// Drawer tidak boleh tetap modal ketika viewport kembali ke desktop.
|
|
618
|
+
effect((onCleanup) => {
|
|
619
|
+
const media = this.document?.defaultView?.matchMedia?.('(min-width: 640px)');
|
|
620
|
+
if (!media) {
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
const closeOnDesktop = (event) => {
|
|
624
|
+
if (event.matches) {
|
|
625
|
+
this.mobileNavOpen.set(false);
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
closeOnDesktop(media);
|
|
629
|
+
media.addEventListener('change', closeOnDesktop);
|
|
630
|
+
onCleanup(() => media.removeEventListener('change', closeOnDesktop));
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Classes for `<LayoutContent>`, chosen by the consumer (padding, say). Empty by
|
|
635
|
+
* default: the library no longer forces `p-6`; the consumer or `<Page>` decides spacing.
|
|
636
|
+
*/
|
|
637
|
+
contentClassInput = input('', { ...(ngDevMode ? { debugName: "contentClassInput" } : /* istanbul ignore next */ {}), alias: 'content-class' });
|
|
638
|
+
/** Wrapper layout & nilai `<Layout [layout-type]>`: navbar/flyout = horizontal, sisanya vertical. */
|
|
639
|
+
effectiveLayoutType = computed(() => {
|
|
640
|
+
const layoutType = this.layoutType();
|
|
641
|
+
if (layoutType === 'empty' || layoutType === 'fluid') {
|
|
642
|
+
return layoutType;
|
|
643
|
+
}
|
|
644
|
+
return this.navType() === 'navbar' ||
|
|
645
|
+
this.navType() === 'flyout' ||
|
|
646
|
+
this.navType() === 'desktop'
|
|
647
|
+
? 'horizontal'
|
|
648
|
+
: 'vertical';
|
|
649
|
+
}, /* @ts-ignore */
|
|
650
|
+
...(ngDevMode ? [{ debugName: "effectiveLayoutType" }] : /* istanbul ignore next */ []));
|
|
651
|
+
/** Tipe nav di dalam `#body`: `empty`/`fluid` → `brand` (header-only); selain itu `nav-type`. */
|
|
652
|
+
navKind = computed(() => {
|
|
653
|
+
const layoutType = this.layoutType();
|
|
654
|
+
const navType = this.navType();
|
|
655
|
+
return layoutType === 'empty' || layoutType === 'fluid' || navType === 'desktop'
|
|
656
|
+
? 'brand'
|
|
657
|
+
: navType;
|
|
658
|
+
}, /* @ts-ignore */
|
|
659
|
+
...(ngDevMode ? [{ debugName: "navKind" }] : /* istanbul ignore next */ []));
|
|
660
|
+
/** Lebar host `<Navigation>`: penuh-tinggi (vertical) atau penuh-lebar (horizontal). */
|
|
661
|
+
navClass = computed(() => this.effectiveLayoutType() === 'horizontal' ? 'w-full' : 'h-full', /* @ts-ignore */
|
|
662
|
+
...(ngDevMode ? [{ debugName: "navClass" }] : /* istanbul ignore next */ []));
|
|
663
|
+
showsMobileNavigation = computed(() => {
|
|
664
|
+
if (this.navType() === 'desktop') {
|
|
665
|
+
return false;
|
|
666
|
+
}
|
|
667
|
+
const type = this.effectiveLayoutType();
|
|
668
|
+
return type === 'vertical' || type === 'horizontal';
|
|
669
|
+
}, /* @ts-ignore */
|
|
670
|
+
...(ngDevMode ? [{ debugName: "showsMobileNavigation" }] : /* istanbul ignore next */ []));
|
|
671
|
+
/** Internal shell owns responsive placement while primitives remain composition-safe. */
|
|
672
|
+
defaultShellClasses = computed(() => {
|
|
673
|
+
const type = this.effectiveLayoutType();
|
|
674
|
+
if (type === 'empty' || type === 'fluid' || this.navType() === 'desktop') {
|
|
675
|
+
return 'contents';
|
|
676
|
+
}
|
|
677
|
+
return cn('relative grid h-full min-h-0 w-full min-w-0 grid-cols-1 grid-rows-[3rem_minmax(0,1fr)]', type === 'horizontal'
|
|
678
|
+
? 'sm:flex sm:flex-col'
|
|
679
|
+
: 'col-span-2 sm:grid-cols-[auto_minmax(0,1fr)] sm:grid-rows-1');
|
|
680
|
+
}, /* @ts-ignore */
|
|
681
|
+
...(ngDevMode ? [{ debugName: "defaultShellClasses" }] : /* istanbul ignore next */ []));
|
|
682
|
+
/** Kelas `<LayoutContent>`: `fluid` membatasi lebar & memusatkan; padding diserahkan ke consumer. */
|
|
683
|
+
contentClass = computed(() => cn(this.effectiveLayoutType() === 'fluid' ? 'w-full max-w-3xl' : '', this.contentClassInput()), /* @ts-ignore */
|
|
684
|
+
...(ngDevMode ? [{ debugName: "contentClass" }] : /* istanbul ignore next */ []));
|
|
685
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: LayoutWrapperDefault, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
686
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: LayoutWrapperDefault, isStandalone: true, selector: "LayoutWrapperDefault", inputs: { surface: { classPropertyName: "surface", publicName: "surface", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "layout-appearance", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, layoutType: { classPropertyName: "layoutType", publicName: "layout-type", isSignal: true, isRequired: false, transformFunction: null }, navType: { classPropertyName: "navType", publicName: "nav-type", isSignal: true, isRequired: false, transformFunction: null }, navTypeMode: { classPropertyName: "navTypeMode", publicName: "nav-type-mode", isSignal: true, isRequired: false, transformFunction: null }, dockbarRouteContext: { classPropertyName: "dockbarRouteContext", publicName: "dockbar-route-context", isSignal: true, isRequired: false, transformFunction: null }, dockbarBadgeContext: { classPropertyName: "dockbarBadgeContext", publicName: "dockbar-badge", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: true, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: true, transformFunction: null }, contentId: { classPropertyName: "contentId", publicName: "content-id", isSignal: true, isRequired: false, transformFunction: null }, skipLinkLabel: { classPropertyName: "skipLinkLabel", publicName: "skip-link-label", isSignal: true, isRequired: false, transformFunction: null }, focusOnNavigation: { classPropertyName: "focusOnNavigation", publicName: "focus-on-navigation", isSignal: true, isRequired: false, transformFunction: null }, mobileNavOpen: { classPropertyName: "mobileNavOpen", publicName: "mobile-nav-open", isSignal: true, isRequired: false, transformFunction: null }, mobileNavLabel: { classPropertyName: "mobileNavLabel", publicName: "mobile-nav-label", isSignal: true, isRequired: false, transformFunction: null }, closeMobileNavLabel: { classPropertyName: "closeMobileNavLabel", publicName: "close-mobile-nav-label", isSignal: true, isRequired: false, transformFunction: null }, contentClassInput: { classPropertyName: "contentClassInput", publicName: "content-class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mobileNavOpen: "mobile-nav-openChange", logout: "logout" }, host: { classAttribute: "contents" }, viewQueries: [{ propertyName: "mobileNavTriggerRef", first: true, predicate: ["mobileNavTrigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
687
|
+
<Layout
|
|
688
|
+
[surface]="surface()"
|
|
689
|
+
[layout-appearance]="appearance()"
|
|
690
|
+
[width]="width()"
|
|
691
|
+
[layout-type]="effectiveLayoutType()"
|
|
692
|
+
>
|
|
693
|
+
<!-- Skeleton bersama: dipakai ulang oleh setiap wrapper di @switch bawah. -->
|
|
694
|
+
<ng-template #body>
|
|
695
|
+
<div data-layout-default-shell [class]="defaultShellClasses()">
|
|
696
|
+
<a
|
|
697
|
+
[attr.href]="'#' + contentId()"
|
|
698
|
+
class="sr-only z-50 rounded-md bg-background px-3 py-2 text-sm text-foreground shadow-md focus:not-sr-only focus:absolute focus:left-2 focus:top-2 focus:outline-none focus:ring-2 focus:ring-ring"
|
|
699
|
+
>
|
|
700
|
+
{{ skipLinkLabel() }}
|
|
701
|
+
</a>
|
|
702
|
+
|
|
703
|
+
@if (showsMobileNavigation()) {
|
|
704
|
+
<div
|
|
705
|
+
data-layout-mobile-app-bar
|
|
706
|
+
class="flex h-12 min-h-12 items-center gap-2 border-b border-border bg-background px-2 sm:hidden"
|
|
707
|
+
>
|
|
708
|
+
<button
|
|
709
|
+
type="button"
|
|
710
|
+
#mobileNavTrigger
|
|
711
|
+
class="inline-flex size-10 shrink-0 items-center justify-center rounded-md text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none"
|
|
712
|
+
[attr.aria-label]="mobileNavLabel()"
|
|
713
|
+
aria-haspopup="dialog"
|
|
714
|
+
[attr.aria-expanded]="mobileNavOpen()"
|
|
715
|
+
(click)="mobileNavOpen.set(true)"
|
|
716
|
+
>
|
|
717
|
+
<span aria-hidden="true" class="grid w-5 gap-1">
|
|
718
|
+
<span class="h-0.5 rounded-full bg-current"></span>
|
|
719
|
+
<span class="h-0.5 rounded-full bg-current"></span>
|
|
720
|
+
<span class="h-0.5 rounded-full bg-current"></span>
|
|
721
|
+
</span>
|
|
722
|
+
</button>
|
|
723
|
+
|
|
724
|
+
<div class="flex min-w-0 flex-1 items-center gap-2">
|
|
725
|
+
<LayoutBrand [brand]="brand()" />
|
|
726
|
+
</div>
|
|
727
|
+
|
|
728
|
+
@defer (when mobileNavOpen()) {
|
|
729
|
+
<Sheet
|
|
730
|
+
[open]="mobileNavOpen()"
|
|
731
|
+
(openChange)="mobileNavOpen.set($event)"
|
|
732
|
+
[restoreFocus]="mobileNavTriggerRef()?.nativeElement ?? null"
|
|
733
|
+
side="left"
|
|
734
|
+
class="w-3/4 p-0! sm:max-w-sm [&_.sheet-close-button]:z-50"
|
|
735
|
+
[closeButtonLabel]="closeMobileNavLabel()"
|
|
736
|
+
>
|
|
737
|
+
<SheetTitle class="sr-only">{{ mobileNavLabel() }}</SheetTitle>
|
|
738
|
+
<Navigation
|
|
739
|
+
id="main-mobile"
|
|
740
|
+
data-id="main"
|
|
741
|
+
[data]="data()"
|
|
742
|
+
ariaLabel="Primary navigation"
|
|
743
|
+
class="h-full w-full"
|
|
744
|
+
(itemSelected)="mobileNavOpen.set(false)"
|
|
745
|
+
>
|
|
746
|
+
<LayoutNavSidebar
|
|
747
|
+
[brand]="brand()"
|
|
748
|
+
[user]="user()"
|
|
749
|
+
[appearance]="appearance()"
|
|
750
|
+
(logout)="logout.emit()"
|
|
751
|
+
/>
|
|
752
|
+
</Navigation>
|
|
753
|
+
</Sheet>
|
|
754
|
+
}
|
|
755
|
+
</div>
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
@if (navType() !== 'desktop') {
|
|
759
|
+
<LayoutNavigation
|
|
760
|
+
ariaLabel="Primary navigation"
|
|
761
|
+
[landmark]="false"
|
|
762
|
+
class="max-sm:hidden"
|
|
763
|
+
>
|
|
764
|
+
<Navigation id="main" data-id="main" [data]="data()" [class]="navClass()">
|
|
765
|
+
@switch (navKind()) {
|
|
766
|
+
@case ('navbar') {
|
|
767
|
+
<LayoutNavNavbar
|
|
768
|
+
[brand]="brand()"
|
|
769
|
+
[user]="user()"
|
|
770
|
+
[appearance]="appearance()"
|
|
771
|
+
(logout)="logout.emit()"
|
|
772
|
+
/>
|
|
773
|
+
}
|
|
774
|
+
@case ('flyout') {
|
|
775
|
+
<LayoutNavFlyout
|
|
776
|
+
[brand]="brand()"
|
|
777
|
+
[user]="user()"
|
|
778
|
+
[appearance]="appearance()"
|
|
779
|
+
(logout)="logout.emit()"
|
|
780
|
+
/>
|
|
781
|
+
}
|
|
782
|
+
@case ('dockbar') {
|
|
783
|
+
<LayoutNavDockbar
|
|
784
|
+
[brand]="brand()"
|
|
785
|
+
[user]="user()"
|
|
786
|
+
[appearance]="appearance()"
|
|
787
|
+
[nav-type-mode]="navTypeMode()"
|
|
788
|
+
[dockbar-route-context]="dockbarRouteContext()"
|
|
789
|
+
[dockbar-badge]="dockbarBadgeContext()"
|
|
790
|
+
(logout)="logout.emit()"
|
|
791
|
+
/>
|
|
792
|
+
}
|
|
793
|
+
@case ('brand') {
|
|
794
|
+
<LayoutNavMinimal [brand]="brand()" />
|
|
795
|
+
}
|
|
796
|
+
@default {
|
|
797
|
+
<LayoutNavSidebar
|
|
798
|
+
[brand]="brand()"
|
|
799
|
+
[user]="user()"
|
|
800
|
+
[appearance]="appearance()"
|
|
801
|
+
[nav-type-mode]="navTypeMode()"
|
|
802
|
+
(logout)="logout.emit()"
|
|
803
|
+
/>
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
</Navigation>
|
|
807
|
+
</LayoutNavigation>
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
<LayoutContent
|
|
811
|
+
[class]="contentClass()"
|
|
812
|
+
[content-id]="contentId()"
|
|
813
|
+
[focus-on-navigation]="focusOnNavigation()"
|
|
814
|
+
>
|
|
815
|
+
<ng-content />
|
|
816
|
+
</LayoutContent>
|
|
817
|
+
</div>
|
|
818
|
+
</ng-template>
|
|
819
|
+
|
|
820
|
+
@switch (effectiveLayoutType()) {
|
|
821
|
+
@case ('empty') {
|
|
822
|
+
<LayoutEmpty>
|
|
823
|
+
<ng-container [ngTemplateOutlet]="body" />
|
|
824
|
+
</LayoutEmpty>
|
|
825
|
+
}
|
|
826
|
+
@case ('fluid') {
|
|
827
|
+
<LayoutFluid>
|
|
828
|
+
<ng-container [ngTemplateOutlet]="body" />
|
|
829
|
+
</LayoutFluid>
|
|
830
|
+
}
|
|
831
|
+
@case ('horizontal') {
|
|
832
|
+
<LayoutHorizontal>
|
|
833
|
+
<ng-container [ngTemplateOutlet]="body" />
|
|
834
|
+
</LayoutHorizontal>
|
|
835
|
+
}
|
|
836
|
+
@default {
|
|
837
|
+
<LayoutVertical>
|
|
838
|
+
<ng-container [ngTemplateOutlet]="body" />
|
|
839
|
+
</LayoutVertical>
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
</Layout>
|
|
843
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: LayoutComponent, selector: "Layout", inputs: ["surface", "appearance", "layout-appearance", "width", "layout-type", "class"] }, { kind: "component", type: LayoutVerticalComponent, selector: "LayoutVertical", inputs: ["class"] }, { kind: "component", type: LayoutHorizontalComponent, selector: "LayoutHorizontal", inputs: ["class"] }, { kind: "component", type: LayoutEmptyComponent, selector: "LayoutEmpty", inputs: ["class"] }, { kind: "component", type: LayoutFluidComponent, selector: "LayoutFluid", inputs: ["class"] }, { kind: "component", type: LayoutNavigationComponent, selector: "LayoutNavigation", inputs: ["ariaLabel", "landmark", "class"] }, { kind: "component", type: LayoutContentComponent, selector: "LayoutContent", inputs: ["class", "content-id", "focus-on-navigation"] }, { kind: "component", type: NavigationContainerComponent, selector: "Navigation", inputs: ["id", "data-id", "data", "ariaLabel", "compact", "collapse-tree", "class", "itemClass", "nav-group-class", "activeIds", "activeUrl", "openedIds"], outputs: ["openedIdsChange", "itemSelected"] }, { kind: "component", type: LayoutBrand, selector: "LayoutBrand", inputs: ["brand", "compact"] }, { kind: "component", type: LayoutNavSidebar, selector: "LayoutNavSidebar", inputs: ["brand", "user", "appearance", "nav-type-mode"], outputs: ["logout"] }, { kind: "component", type: LayoutNavDockbar, selector: "LayoutNavDockbar", inputs: ["brand", "user", "appearance", "nav-type-mode", "dockbar-route-context", "dockbar-badge"], outputs: ["logout"] }, { kind: "component", type: LayoutNavNavbar, selector: "LayoutNavNavbar", inputs: ["brand", "user", "appearance"], outputs: ["logout"] }, { kind: "component", type: LayoutNavFlyout, selector: "LayoutNavFlyout", inputs: ["brand", "user", "appearance"], outputs: ["logout"] }, { kind: "component", type: LayoutNavMinimal, selector: "LayoutNavMinimal", inputs: ["brand"] }], deferBlockDependencies: [() => [/* @ts-ignore */
|
|
844
|
+
import('@ojiepermana/angular/component/sheet').then(m => m.SheetComponent), /* @ts-ignore */
|
|
845
|
+
import('@ojiepermana/angular/component/sheet').then(m => m.SheetTitleComponent), NavigationContainerComponent,
|
|
846
|
+
LayoutNavSidebar]] });
|
|
847
|
+
}
|
|
848
|
+
i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.4", ngImport: i0, type: LayoutWrapperDefault, resolveDeferredDeps: () => [/* @ts-ignore */
|
|
849
|
+
import('@ojiepermana/angular/component/sheet').then(m => m.SheetComponent), /* @ts-ignore */
|
|
850
|
+
import('@ojiepermana/angular/component/sheet').then(m => m.SheetTitleComponent)], resolveMetadata: (SheetComponent, SheetTitleComponent) => ({ decorators: [{
|
|
851
|
+
type: Component,
|
|
852
|
+
args: [{
|
|
853
|
+
selector: 'LayoutWrapperDefault',
|
|
854
|
+
host: { class: 'contents' },
|
|
855
|
+
imports: [
|
|
856
|
+
NgTemplateOutlet,
|
|
857
|
+
LayoutComponent,
|
|
858
|
+
LayoutVerticalComponent,
|
|
859
|
+
LayoutHorizontalComponent,
|
|
860
|
+
LayoutEmptyComponent,
|
|
861
|
+
LayoutFluidComponent,
|
|
862
|
+
LayoutNavigationComponent,
|
|
863
|
+
LayoutContentComponent,
|
|
864
|
+
SheetComponent,
|
|
865
|
+
SheetTitleComponent,
|
|
866
|
+
NavigationContainerComponent,
|
|
867
|
+
LayoutBrand,
|
|
868
|
+
LayoutNavSidebar,
|
|
869
|
+
LayoutNavDockbar,
|
|
870
|
+
LayoutNavNavbar,
|
|
871
|
+
LayoutNavFlyout,
|
|
872
|
+
LayoutNavMinimal,
|
|
873
|
+
],
|
|
874
|
+
template: `
|
|
875
|
+
<Layout
|
|
876
|
+
[surface]="surface()"
|
|
877
|
+
[layout-appearance]="appearance()"
|
|
878
|
+
[width]="width()"
|
|
879
|
+
[layout-type]="effectiveLayoutType()"
|
|
880
|
+
>
|
|
881
|
+
<!-- Skeleton bersama: dipakai ulang oleh setiap wrapper di @switch bawah. -->
|
|
882
|
+
<ng-template #body>
|
|
883
|
+
<div data-layout-default-shell [class]="defaultShellClasses()">
|
|
884
|
+
<a
|
|
885
|
+
[attr.href]="'#' + contentId()"
|
|
886
|
+
class="sr-only z-50 rounded-md bg-background px-3 py-2 text-sm text-foreground shadow-md focus:not-sr-only focus:absolute focus:left-2 focus:top-2 focus:outline-none focus:ring-2 focus:ring-ring"
|
|
887
|
+
>
|
|
888
|
+
{{ skipLinkLabel() }}
|
|
889
|
+
</a>
|
|
890
|
+
|
|
891
|
+
@if (showsMobileNavigation()) {
|
|
892
|
+
<div
|
|
893
|
+
data-layout-mobile-app-bar
|
|
894
|
+
class="flex h-12 min-h-12 items-center gap-2 border-b border-border bg-background px-2 sm:hidden"
|
|
895
|
+
>
|
|
896
|
+
<button
|
|
897
|
+
type="button"
|
|
898
|
+
#mobileNavTrigger
|
|
899
|
+
class="inline-flex size-10 shrink-0 items-center justify-center rounded-md text-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring motion-reduce:transition-none"
|
|
900
|
+
[attr.aria-label]="mobileNavLabel()"
|
|
901
|
+
aria-haspopup="dialog"
|
|
902
|
+
[attr.aria-expanded]="mobileNavOpen()"
|
|
903
|
+
(click)="mobileNavOpen.set(true)"
|
|
904
|
+
>
|
|
905
|
+
<span aria-hidden="true" class="grid w-5 gap-1">
|
|
906
|
+
<span class="h-0.5 rounded-full bg-current"></span>
|
|
907
|
+
<span class="h-0.5 rounded-full bg-current"></span>
|
|
908
|
+
<span class="h-0.5 rounded-full bg-current"></span>
|
|
909
|
+
</span>
|
|
910
|
+
</button>
|
|
911
|
+
|
|
912
|
+
<div class="flex min-w-0 flex-1 items-center gap-2">
|
|
913
|
+
<LayoutBrand [brand]="brand()" />
|
|
914
|
+
</div>
|
|
915
|
+
|
|
916
|
+
@defer (when mobileNavOpen()) {
|
|
917
|
+
<Sheet
|
|
918
|
+
[open]="mobileNavOpen()"
|
|
919
|
+
(openChange)="mobileNavOpen.set($event)"
|
|
920
|
+
[restoreFocus]="mobileNavTriggerRef()?.nativeElement ?? null"
|
|
921
|
+
side="left"
|
|
922
|
+
class="w-3/4 p-0! sm:max-w-sm [&_.sheet-close-button]:z-50"
|
|
923
|
+
[closeButtonLabel]="closeMobileNavLabel()"
|
|
924
|
+
>
|
|
925
|
+
<SheetTitle class="sr-only">{{ mobileNavLabel() }}</SheetTitle>
|
|
926
|
+
<Navigation
|
|
927
|
+
id="main-mobile"
|
|
928
|
+
data-id="main"
|
|
929
|
+
[data]="data()"
|
|
930
|
+
ariaLabel="Primary navigation"
|
|
931
|
+
class="h-full w-full"
|
|
932
|
+
(itemSelected)="mobileNavOpen.set(false)"
|
|
933
|
+
>
|
|
934
|
+
<LayoutNavSidebar
|
|
935
|
+
[brand]="brand()"
|
|
936
|
+
[user]="user()"
|
|
937
|
+
[appearance]="appearance()"
|
|
938
|
+
(logout)="logout.emit()"
|
|
939
|
+
/>
|
|
940
|
+
</Navigation>
|
|
941
|
+
</Sheet>
|
|
942
|
+
}
|
|
943
|
+
</div>
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
@if (navType() !== 'desktop') {
|
|
947
|
+
<LayoutNavigation
|
|
948
|
+
ariaLabel="Primary navigation"
|
|
949
|
+
[landmark]="false"
|
|
950
|
+
class="max-sm:hidden"
|
|
951
|
+
>
|
|
952
|
+
<Navigation id="main" data-id="main" [data]="data()" [class]="navClass()">
|
|
953
|
+
@switch (navKind()) {
|
|
954
|
+
@case ('navbar') {
|
|
955
|
+
<LayoutNavNavbar
|
|
956
|
+
[brand]="brand()"
|
|
957
|
+
[user]="user()"
|
|
958
|
+
[appearance]="appearance()"
|
|
959
|
+
(logout)="logout.emit()"
|
|
960
|
+
/>
|
|
961
|
+
}
|
|
962
|
+
@case ('flyout') {
|
|
963
|
+
<LayoutNavFlyout
|
|
964
|
+
[brand]="brand()"
|
|
965
|
+
[user]="user()"
|
|
966
|
+
[appearance]="appearance()"
|
|
967
|
+
(logout)="logout.emit()"
|
|
968
|
+
/>
|
|
969
|
+
}
|
|
970
|
+
@case ('dockbar') {
|
|
971
|
+
<LayoutNavDockbar
|
|
972
|
+
[brand]="brand()"
|
|
973
|
+
[user]="user()"
|
|
974
|
+
[appearance]="appearance()"
|
|
975
|
+
[nav-type-mode]="navTypeMode()"
|
|
976
|
+
[dockbar-route-context]="dockbarRouteContext()"
|
|
977
|
+
[dockbar-badge]="dockbarBadgeContext()"
|
|
978
|
+
(logout)="logout.emit()"
|
|
979
|
+
/>
|
|
980
|
+
}
|
|
981
|
+
@case ('brand') {
|
|
982
|
+
<LayoutNavMinimal [brand]="brand()" />
|
|
983
|
+
}
|
|
984
|
+
@default {
|
|
985
|
+
<LayoutNavSidebar
|
|
986
|
+
[brand]="brand()"
|
|
987
|
+
[user]="user()"
|
|
988
|
+
[appearance]="appearance()"
|
|
989
|
+
[nav-type-mode]="navTypeMode()"
|
|
990
|
+
(logout)="logout.emit()"
|
|
991
|
+
/>
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
</Navigation>
|
|
995
|
+
</LayoutNavigation>
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
<LayoutContent
|
|
999
|
+
[class]="contentClass()"
|
|
1000
|
+
[content-id]="contentId()"
|
|
1001
|
+
[focus-on-navigation]="focusOnNavigation()"
|
|
1002
|
+
>
|
|
1003
|
+
<ng-content />
|
|
1004
|
+
</LayoutContent>
|
|
1005
|
+
</div>
|
|
1006
|
+
</ng-template>
|
|
1007
|
+
|
|
1008
|
+
@switch (effectiveLayoutType()) {
|
|
1009
|
+
@case ('empty') {
|
|
1010
|
+
<LayoutEmpty>
|
|
1011
|
+
<ng-container [ngTemplateOutlet]="body" />
|
|
1012
|
+
</LayoutEmpty>
|
|
1013
|
+
}
|
|
1014
|
+
@case ('fluid') {
|
|
1015
|
+
<LayoutFluid>
|
|
1016
|
+
<ng-container [ngTemplateOutlet]="body" />
|
|
1017
|
+
</LayoutFluid>
|
|
1018
|
+
}
|
|
1019
|
+
@case ('horizontal') {
|
|
1020
|
+
<LayoutHorizontal>
|
|
1021
|
+
<ng-container [ngTemplateOutlet]="body" />
|
|
1022
|
+
</LayoutHorizontal>
|
|
1023
|
+
}
|
|
1024
|
+
@default {
|
|
1025
|
+
<LayoutVertical>
|
|
1026
|
+
<ng-container [ngTemplateOutlet]="body" />
|
|
1027
|
+
</LayoutVertical>
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
</Layout>
|
|
1031
|
+
`,
|
|
1032
|
+
}]
|
|
1033
|
+
}], ctorParameters: () => [], propDecorators: { surface: [{ type: i0.Input, args: [{ isSignal: true, alias: "surface", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout-appearance", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], layoutType: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout-type", required: false }] }], navType: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-type", required: false }] }], navTypeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "nav-type-mode", required: false }] }], dockbarRouteContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dockbar-route-context", required: false }] }], dockbarBadgeContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dockbar-badge", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: true }] }], user: [{ type: i0.Input, args: [{ isSignal: true, alias: "user", required: true }] }], contentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "content-id", required: false }] }], skipLinkLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "skip-link-label", required: false }] }], focusOnNavigation: [{ type: i0.Input, args: [{ isSignal: true, alias: "focus-on-navigation", required: false }] }], mobileNavOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobile-nav-open", required: false }] }, { type: i0.Output, args: ["mobile-nav-openChange"] }], mobileNavLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobile-nav-label", required: false }] }], closeMobileNavLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "close-mobile-nav-label", required: false }] }], logout: [{ type: i0.Output, args: ["logout"] }], mobileNavTriggerRef: [{ type: i0.ViewChild, args: ['mobileNavTrigger', { isSignal: true }] }], contentClassInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "content-class", required: false }] }] } }) });
|
|
1034
|
+
|
|
1035
|
+
/*
|
|
1036
|
+
* Public API of @ojiepermana/angular/theme/layout/wrapper
|
|
1037
|
+
*
|
|
1038
|
+
* Wrapper blok-jadi untuk layout shell: consumer cukup menyediakan data input
|
|
1039
|
+
* (surface, appearance, width, layout-type, nav-type, navigation data, brand, user)
|
|
1040
|
+
* tanpa merakit komponen bersarang. `register*` default tetap di consumer.
|
|
1041
|
+
*/
|
|
1042
|
+
// Identitas (bentuk data yang disediakan consumer)
|
|
4
1043
|
|
|
5
1044
|
/**
|
|
6
1045
|
* Generated bundle index. Do not edit.
|
|
7
|
-
*/
|
|
1046
|
+
*/
|
|
1047
|
+
|
|
1048
|
+
export { LAYOUT_DESKTOP_NAVIGATION_DATA_ID, LayoutBrand, LayoutIdentityService, LayoutNavDockbar, LayoutNavFlyout, LayoutNavMinimal, LayoutNavNavbar, LayoutNavSidebar, LayoutUser, LayoutWrapperDefault };
|