@ojiepermana/angular 22.1.10 → 22.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
# @ojiepermana/angular/theme/layout
|
|
2
|
+
|
|
3
|
+
Primitive layout projection untuk menyusun shell UI dengan satu root `Layout`, satu variant layout (`vertical`, `horizontal`, `empty`, atau `fluid`), slot `LayoutNavigation`, dan area `LayoutContent` yang menjadi scroll container utama.
|
|
4
|
+
|
|
5
|
+
README ini mendokumentasikan seluruh API publik yang diekspor oleh package agar consumer bisa memahami kontrak komponen, type, service, dan perilaku layout tanpa perlu membaca source code.
|
|
6
|
+
|
|
7
|
+
## Entry points
|
|
8
|
+
|
|
9
|
+
`@ojiepermana/angular/theme/layout` adalah root entry point yang mengekspor seluruh primitive utama, `LayoutService`, seluruh type, constants, dan guards.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
LayoutService,
|
|
14
|
+
LayoutComponent,
|
|
15
|
+
LayoutContentComponent,
|
|
16
|
+
LayoutEmptyComponent,
|
|
17
|
+
LayoutFluidComponent,
|
|
18
|
+
LayoutHorizontalComponent,
|
|
19
|
+
LayoutNavigationComponent,
|
|
20
|
+
LayoutVerticalComponent,
|
|
21
|
+
type LayoutAppearance,
|
|
22
|
+
type LayoutSurface,
|
|
23
|
+
type LayoutType,
|
|
24
|
+
type LayoutWidth,
|
|
25
|
+
} from '@ojiepermana/angular/theme/layout';
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Secondary entry point tetap tersedia bila consumer ingin import yang lebih eksplisit.
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { LayoutService } from '@ojiepermana/angular/theme/layout/services';
|
|
32
|
+
import {
|
|
33
|
+
LAYOUT_DEFAULT_APPEARANCE,
|
|
34
|
+
LAYOUT_DEFAULT_SURFACE,
|
|
35
|
+
LAYOUT_DEFAULT_TYPE,
|
|
36
|
+
LAYOUT_DEFAULT_WIDTH,
|
|
37
|
+
LAYOUT_APPEARANCE_STORAGE_KEY,
|
|
38
|
+
LAYOUT_APPEARANCES,
|
|
39
|
+
LAYOUT_SURFACE_STORAGE_KEY,
|
|
40
|
+
LAYOUT_SURFACES,
|
|
41
|
+
LAYOUT_TYPES,
|
|
42
|
+
LAYOUT_TYPE_STORAGE_KEY,
|
|
43
|
+
LAYOUT_WIDTHS,
|
|
44
|
+
LAYOUT_WIDTH_STORAGE_KEY,
|
|
45
|
+
isUiLayoutSurface,
|
|
46
|
+
isUiLayoutAppearance,
|
|
47
|
+
isUiLayoutType,
|
|
48
|
+
isUiLayoutWidth,
|
|
49
|
+
type LayoutContextValue,
|
|
50
|
+
type LayoutAppearance,
|
|
51
|
+
type LayoutSurface,
|
|
52
|
+
type LayoutType,
|
|
53
|
+
type LayoutWidth,
|
|
54
|
+
} from '@ojiepermana/angular/theme/layout/types';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Catatan:
|
|
58
|
+
|
|
59
|
+
- Root entry point dan secondary entry point mengekspor symbol yang sama. Gunakan secondary entry point jika consumer ingin dependency path yang lebih eksplisit untuk `services` atau `types`.
|
|
60
|
+
- Untuk kasus halaman yang membaca preferensi persisted, source of truth tetap berada di `LayoutService`.
|
|
61
|
+
|
|
62
|
+
## Mental model
|
|
63
|
+
|
|
64
|
+
Struktur yang direkomendasikan adalah sebagai berikut.
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<Layout>
|
|
68
|
+
<LayoutVertical | LayoutHorizontal | LayoutEmpty | LayoutFluid>
|
|
69
|
+
<LayoutNavigation>...</LayoutNavigation>
|
|
70
|
+
<LayoutContent>...</LayoutContent>
|
|
71
|
+
</LayoutVertical | LayoutHorizontal | LayoutEmpty | LayoutFluid>
|
|
72
|
+
</Layout>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Aturan penggunaannya:
|
|
76
|
+
|
|
77
|
+
- Gunakan tepat satu variant layout di dalam `Layout`.
|
|
78
|
+
- Untuk layout `vertical` dan `horizontal`, urutan child yang umum adalah `LayoutNavigation` lalu `LayoutContent`.
|
|
79
|
+
- Untuk layout `empty`, biasanya cukup `LayoutContent`.
|
|
80
|
+
- Untuk layout `fluid`, child dapat berupa konten page tunggal yang ingin dipusatkan terhadap frame.
|
|
81
|
+
- `LayoutContent` adalah area yang memiliki `overflow-auto`, jadi konten utama sebaiknya ditempatkan di sana.
|
|
82
|
+
- Pada mode `vertical`, lebar nav mengikuti kontennya sendiri (`w-max`), bukan dipaksa oleh root layout.
|
|
83
|
+
|
|
84
|
+
## Quick start
|
|
85
|
+
|
|
86
|
+
### Vertical
|
|
87
|
+
|
|
88
|
+
```html
|
|
89
|
+
<Layout surface="grid" appearance="border-rail" width="full">
|
|
90
|
+
<LayoutVertical>
|
|
91
|
+
<LayoutNavigation ariaLabel="Primary navigation">
|
|
92
|
+
<aside class="flex h-full w-56 flex-col gap-4 bg-card/80 p-4">Navigation</aside>
|
|
93
|
+
</LayoutNavigation>
|
|
94
|
+
|
|
95
|
+
<LayoutContent class="bg-background/80 p-6"> Content </LayoutContent>
|
|
96
|
+
</LayoutVertical>
|
|
97
|
+
</Layout>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Horizontal
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<Layout surface="line-horizontal" appearance="flat" width="wide">
|
|
104
|
+
<LayoutHorizontal>
|
|
105
|
+
<LayoutNavigation ariaLabel="Top navigation">
|
|
106
|
+
<header class="flex h-full items-center px-4">Navigation</header>
|
|
107
|
+
</LayoutNavigation>
|
|
108
|
+
|
|
109
|
+
<LayoutContent class="p-6">Content</LayoutContent>
|
|
110
|
+
</LayoutHorizontal>
|
|
111
|
+
</Layout>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Empty
|
|
115
|
+
|
|
116
|
+
```html
|
|
117
|
+
<Layout surface="flat" appearance="flat" width="container">
|
|
118
|
+
<LayoutEmpty>
|
|
119
|
+
<LayoutContent class="py-8"> Content </LayoutContent>
|
|
120
|
+
</LayoutEmpty>
|
|
121
|
+
</Layout>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Fluid
|
|
125
|
+
|
|
126
|
+
```html
|
|
127
|
+
<Layout surface="grid" appearance="border-rail" width="fluid">
|
|
128
|
+
<LayoutFluid>
|
|
129
|
+
<section class="w-full max-w-xl border border-border bg-card/90 p-6">Content</section>
|
|
130
|
+
</LayoutFluid>
|
|
131
|
+
</Layout>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Pola page-level yang direkomendasikan
|
|
135
|
+
|
|
136
|
+
Untuk halaman yang memiliki default sendiri tetapi tetap harus tunduk pada nilai local storage yang sudah tersimpan, pakai `LayoutService.registerDefaults(...)` sekali di level page, lalu bind root `Layout` ke signal service.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
|
140
|
+
import {
|
|
141
|
+
LayoutService,
|
|
142
|
+
LayoutComponent,
|
|
143
|
+
LayoutContentComponent,
|
|
144
|
+
LayoutHorizontalComponent,
|
|
145
|
+
LayoutNavigationComponent,
|
|
146
|
+
} from '@ojiepermana/angular/theme/layout';
|
|
147
|
+
|
|
148
|
+
@Component({
|
|
149
|
+
selector: 'demo-board',
|
|
150
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
151
|
+
imports: [
|
|
152
|
+
LayoutComponent,
|
|
153
|
+
LayoutHorizontalComponent,
|
|
154
|
+
LayoutNavigationComponent,
|
|
155
|
+
LayoutContentComponent,
|
|
156
|
+
],
|
|
157
|
+
template: `
|
|
158
|
+
<Layout
|
|
159
|
+
[surface]="layout.surface()"
|
|
160
|
+
[appearance]="layout.appearance()"
|
|
161
|
+
[width]="layout.width()"
|
|
162
|
+
>
|
|
163
|
+
<LayoutHorizontal>
|
|
164
|
+
<LayoutNavigation ariaLabel="Board navigation">...</LayoutNavigation>
|
|
165
|
+
<LayoutContent>...</LayoutContent>
|
|
166
|
+
</LayoutHorizontal>
|
|
167
|
+
</Layout>
|
|
168
|
+
`,
|
|
169
|
+
})
|
|
170
|
+
export class DemoBoardComponent {
|
|
171
|
+
protected readonly layout = inject(LayoutService).registerDefaults({
|
|
172
|
+
surface: 'grid',
|
|
173
|
+
appearance: 'border-rail',
|
|
174
|
+
type: 'horizontal',
|
|
175
|
+
width: 'container',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Dengan pola ini:
|
|
181
|
+
|
|
182
|
+
- consumer cukup mendeklarasikan default sekali
|
|
183
|
+
- nilai valid yang sudah ada di local storage tidak akan ditimpa
|
|
184
|
+
- `layout.type()` bisa langsung dipakai untuk memilih variant `vertical`, `horizontal`, atau `empty`
|
|
185
|
+
- root `Layout` selalu merender nilai final dari service, bukan hanya fallback dari template
|
|
186
|
+
|
|
187
|
+
## API reference
|
|
188
|
+
|
|
189
|
+
### `LayoutComponent`
|
|
190
|
+
|
|
191
|
+
Root wrapper yang mengatur background surface, appearance frame, width mode, dan sinkronisasi fallback state ke `LayoutService`.
|
|
192
|
+
|
|
193
|
+
Selector: `Layout`
|
|
194
|
+
|
|
195
|
+
Inputs:
|
|
196
|
+
|
|
197
|
+
| Input | Type | Default | Deskripsi |
|
|
198
|
+
| ------------------- | -------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
199
|
+
| `surface` | `LayoutSurface` | `'flat'` | Menentukan fallback background root layout. Jika local storage `layout-surface` berisi nilai valid, nilai storage yang dipakai. |
|
|
200
|
+
| `appearance` | `LayoutAppearance or null` | `null` | API template untuk menentukan fallback appearance frame. Jika input ini kosong, primitive mencoba alias `layout-appearance`, lalu fallback efektif akhirnya `flat`. |
|
|
201
|
+
| `layout-appearance` | `LayoutAppearance or null` | `null` | Alias simetris dengan `nav-appearance` pada navigation (kosakata sama `flat \| border-rail`). Memberi `appearance` yang sama ke shell & nav membuat keduanya seragam. |
|
|
202
|
+
| `width` | `LayoutWidth` | `'full'` | Menentukan fallback padding outer dan perilaku container frame. Jika local storage `layout-width` berisi nilai valid, nilai storage yang dipakai. |
|
|
203
|
+
| `layout-type` | `LayoutType or null` | `null` | Override eksplisit type aktif (`vertical \| horizontal \| empty \| fluid`). Jika di-set, menjadi sumber kebenaran type dan menimpa variant `Layout*`. Jika `null`, variant yang menetapkan. |
|
|
204
|
+
| `class` | `string` | `''` | Menambahkan class pada host `Layout`. |
|
|
205
|
+
|
|
206
|
+
Behavior:
|
|
207
|
+
|
|
208
|
+
- Jika consumer memberi input manual `surface`, `appearance`, atau `width`, nilai itu dipakai sebagai override in-memory untuk instance aktif tanpa menulis `localStorage`.
|
|
209
|
+
- Jika input manual kosong, primitive mendaftarkan default `surface`, `appearance`, dan `width` ke `LayoutService` hanya saat local storage belum memiliki nilai valid.
|
|
210
|
+
- Nilai visual final selalu dibaca kembali dari `LayoutService`, sehingga child primitive tetap membaca state yang sama selama instance aktif.
|
|
211
|
+
- Menambahkan atribut host `data-surface`, `data-layout-appearance`, `data-layout-width`, dan `data-layout-type`.
|
|
212
|
+
- Root menyediakan input opsional `layout-type`. Bila di-set, input ini menjadi sumber kebenaran type aktif dan menimpa variant layout yang dirender (override in-memory tanpa menulis `localStorage`). Bila `null`, type aktif dikendalikan oleh variant layout yang dirender, atau oleh consumer melalui `LayoutService.registerDefaults({ type })` sebelum template mengevaluasi `layout.type()`.
|
|
213
|
+
- Selalu merender frame border.
|
|
214
|
+
- Jika `appearance="border-rail"`, root menambah rail dekoratif di empat sudut frame, rail inset horizontal, dan rail vertikal sekunder di luar sisi kiri-kanan frame sehingga frame terlihat seperti memiliki double rail.
|
|
215
|
+
- Jika `width="container"`, frame dipusatkan mulai breakpoint `lg` dengan container behavior.
|
|
216
|
+
- Jika `width="fluid"` dan variant aktif adalah `LayoutFluid`, frame akan shrink mengikuti tinggi dan lebar konten lalu dipusatkan terhadap viewport.
|
|
217
|
+
|
|
218
|
+
### `LayoutVerticalComponent`
|
|
219
|
+
|
|
220
|
+
Variant layout untuk shell dua kolom: nav di kiri, content di kanan.
|
|
221
|
+
|
|
222
|
+
Selector: `LayoutVertical`
|
|
223
|
+
|
|
224
|
+
Inputs:
|
|
225
|
+
|
|
226
|
+
| Input | Type | Default | Deskripsi |
|
|
227
|
+
| ------- | -------- | ------- | --------------------------------------------- |
|
|
228
|
+
| `class` | `string` | `''` | Menambahkan class pada host `LayoutVertical`. |
|
|
229
|
+
|
|
230
|
+
Behavior:
|
|
231
|
+
|
|
232
|
+
- Mengatur `LayoutService.type` menjadi `'vertical'` hanya untuk state aktif dan tidak menulis `localStorage`.
|
|
233
|
+
- Menggunakan grid `grid-cols-[auto_minmax(0,1fr)]`.
|
|
234
|
+
- Dalam mode `border-rail`, host dibuat `overflow-visible` agar rail nav/frame dapat mengekstensi keluar area frame.
|
|
235
|
+
|
|
236
|
+
### `LayoutHorizontalComponent`
|
|
237
|
+
|
|
238
|
+
Variant layout untuk shell bertumpuk vertikal: nav di atas, content mengisi sisa tinggi.
|
|
239
|
+
|
|
240
|
+
Selector: `LayoutHorizontal`
|
|
241
|
+
|
|
242
|
+
Inputs:
|
|
243
|
+
|
|
244
|
+
| Input | Type | Default | Deskripsi |
|
|
245
|
+
| ------- | -------- | ------- | ----------------------------------------------- |
|
|
246
|
+
| `class` | `string` | `''` | Menambahkan class pada host `LayoutHorizontal`. |
|
|
247
|
+
|
|
248
|
+
Behavior:
|
|
249
|
+
|
|
250
|
+
- Mengatur `LayoutService.type` menjadi `'horizontal'` hanya untuk state aktif dan tidak menulis `localStorage`.
|
|
251
|
+
- Menggunakan flex column untuk menyusun nav dan content.
|
|
252
|
+
- Tidak merender rail nav vertikal khusus.
|
|
253
|
+
|
|
254
|
+
### `LayoutEmptyComponent`
|
|
255
|
+
|
|
256
|
+
Variant layout tanpa nav, dipakai untuk halaman yang hanya memiliki satu area konten.
|
|
257
|
+
|
|
258
|
+
Selector: `LayoutEmpty`
|
|
259
|
+
|
|
260
|
+
Inputs:
|
|
261
|
+
|
|
262
|
+
| Input | Type | Default | Deskripsi |
|
|
263
|
+
| ------- | -------- | ------- | ------------------------------------------ |
|
|
264
|
+
| `class` | `string` | `''` | Menambahkan class pada host `LayoutEmpty`. |
|
|
265
|
+
|
|
266
|
+
Behavior:
|
|
267
|
+
|
|
268
|
+
- Mengatur `LayoutService.type` menjadi `'empty'` hanya untuk state aktif dan tidak menulis `localStorage`.
|
|
269
|
+
- Menyediakan wrapper penuh untuk satu area konten.
|
|
270
|
+
- `LayoutNavigation` akan tersembunyi jika tetap dirender di mode ini.
|
|
271
|
+
|
|
272
|
+
### `LayoutNavigationComponent`
|
|
273
|
+
|
|
274
|
+
Wrapper untuk slot navigasi.
|
|
275
|
+
|
|
276
|
+
Selector: `LayoutNavigation`
|
|
277
|
+
|
|
278
|
+
Inputs:
|
|
279
|
+
|
|
280
|
+
| Input | Type | Default | Deskripsi |
|
|
281
|
+
| ----------- | --------- | --------------------- | -------------------------------------------------------------------------------------------- |
|
|
282
|
+
| `ariaLabel` | `string` | `'Layout navigation'` | Label aksesibilitas untuk landmark `navigation`. |
|
|
283
|
+
| `landmark` | `boolean` | `true` | Set `false` bila child `<Navigation>` sudah menjadi satu-satunya landmark navigasi semantik. |
|
|
284
|
+
| `class` | `string` | `''` | Menambahkan class pada host `LayoutNavigation`. |
|
|
285
|
+
|
|
286
|
+
Behavior:
|
|
287
|
+
|
|
288
|
+
- Host memiliki `role="navigation"` dan `aria-label` hanya saat `landmark=true`.
|
|
289
|
+
- Menambahkan atribut host `data-layout-type` dan `data-layout-appearance`.
|
|
290
|
+
- Pada layout `horizontal`, nav menggunakan tinggi tetap `h-12`.
|
|
291
|
+
- Pada layout `vertical`, nav menggunakan `w-max max-w-full`, sehingga lebar nav mengikuti isi child.
|
|
292
|
+
- Pada layout `vertical` dengan `appearance="border-rail"`, komponen ini merender rail vertikal di sisi kanan nav, termasuk ekstensinya ke atas dan bawah viewport.
|
|
293
|
+
- Pada layout `empty`, nav disembunyikan.
|
|
294
|
+
|
|
295
|
+
Catatan penggunaan:
|
|
296
|
+
|
|
297
|
+
- Untuk mode `border-rail`, jangan tambahkan `border-r` manual pada konten nav bila yang diinginkan adalah rail bawaan primitive.
|
|
298
|
+
- Styling visual isi nav sebaiknya ditempatkan pada elemen child di dalam `LayoutNavigation`, bukan dengan mengandalkan border host.
|
|
299
|
+
|
|
300
|
+
### `LayoutContentComponent`
|
|
301
|
+
|
|
302
|
+
Wrapper untuk area konten utama yang scrollable.
|
|
303
|
+
|
|
304
|
+
Selector: `LayoutContent`
|
|
305
|
+
|
|
306
|
+
Inputs:
|
|
307
|
+
|
|
308
|
+
| Input | Type | Default | Deskripsi |
|
|
309
|
+
| --------------------- | --------- | ---------------- | --------------------------------------------------------------------------- |
|
|
310
|
+
| `class` | `string` | `''` | Menambahkan class pada host `LayoutContent`. |
|
|
311
|
+
| `content-id` | `string` | `'main-content'` | Id landmark utama dan target skip link. |
|
|
312
|
+
| `focus-on-navigation` | `boolean` | `false` | Jika aktif, fokuskan landmark utama setelah Angular Router `NavigationEnd`. |
|
|
313
|
+
|
|
314
|
+
Behavior:
|
|
315
|
+
|
|
316
|
+
- Selalu menggunakan `overflow-auto`.
|
|
317
|
+
- Selalu menjadi satu landmark `role="main"` dengan `tabindex="-1"` agar dapat difokuskan
|
|
318
|
+
secara programatik tanpa menambahkannya ke urutan Tab normal.
|
|
319
|
+
- Pada layout `horizontal`, konten memakai `flex-1` agar mengisi sisa tinggi setelah nav.
|
|
320
|
+
- Pada layout `vertical`, konten mengisi tinggi penuh kolom kanan.
|
|
321
|
+
- Pada layout `empty`, konten memakai `h-full w-full`.
|
|
322
|
+
- Jika `LayoutService.width()` adalah `'container'`, konten juga dipusatkan mulai `lg` dengan `lg:container lg:mx-auto`.
|
|
323
|
+
|
|
324
|
+
### `LayoutWrapperDefault`
|
|
325
|
+
|
|
326
|
+
Wrapper siap pakai menambahkan skip link, memastikan child `<Navigation>` menjadi satu-satunya
|
|
327
|
+
landmark `Primary navigation`, dan menyediakan drawer navigasi berbasis `Sheet` di bawah 640px.
|
|
328
|
+
State drawer mobile memakai `id="main-mobile"` (tidak dipersist) dan `data-id="main"` agar data
|
|
329
|
+
apps-launcher tetap konsisten tanpa berbagi state desktop.
|
|
330
|
+
|
|
331
|
+
| Input/model | Type | Default | Deskripsi |
|
|
332
|
+
| ------------------------ | --------- | ------------------------ | ---------------------------------------------------- |
|
|
333
|
+
| `content-id` | `string` | `'main-content'` | Id landmark utama dan target skip link. |
|
|
334
|
+
| `skip-link-label` | `string` | `'Skip to main content'` | Label skip link yang dapat dilokalkan. |
|
|
335
|
+
| `focus-on-navigation` | `boolean` | `false` | Meneruskan focus-on-route-change ke `LayoutContent`. |
|
|
336
|
+
| `mobile-nav-open` | `boolean` | `false` | Model two-way untuk state Sheet mobile. |
|
|
337
|
+
| `mobile-nav-label` | `string` | `'Open navigation'` | Accessible name tombol dan dialog mobile. |
|
|
338
|
+
| `close-mobile-nav-label` | `string` | `'Close navigation'` | Accessible name tombol close Sheet mobile. |
|
|
339
|
+
|
|
340
|
+
| Output | Type | Deskripsi |
|
|
341
|
+
| ---------- | ------ | ------------------------------------------------------------ |
|
|
342
|
+
| `(logout)` | `void` | Pengguna menekan logout pada footer navigation. Lihat bawah. |
|
|
343
|
+
|
|
344
|
+
`(logout)` diteruskan dari setiap nav type yang menampilkan identitas user
|
|
345
|
+
(`sidebar`, `dockbar`, `navbar`, `flyout`) termasuk drawer mobile, jadi consumer
|
|
346
|
+
cukup mengikat satu output. Dockbar memancarkan dari tombol rail maupun tombol
|
|
347
|
+
aside footer. Layout `empty` dan `fluid` bersifat brand-only, jadi tidak merender
|
|
348
|
+
kontrol logout sama sekali.
|
|
349
|
+
|
|
350
|
+
Library tidak memanggil endpoint dan tidak melakukan navigasi: endpoint, penanganan
|
|
351
|
+
cookie, dan target redirect berbeda tiap aplikasi, jadi efeknya milik consumer.
|
|
352
|
+
|
|
353
|
+
```html
|
|
354
|
+
<LayoutWrapperDefault [data]="nav" [brand]="brand" [user]="user" (logout)="signOut()">
|
|
355
|
+
<router-outlet />
|
|
356
|
+
</LayoutWrapperDefault>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Consumer yang tidak mengikat `(logout)` tetap merender tanpa error; tombolnya
|
|
360
|
+
sekadar tidak melakukan apa pun.
|
|
361
|
+
|
|
362
|
+
Saat viewport kembali ke desktop, Sheet ditutup otomatis. Pemilihan item mobile juga menutup
|
|
363
|
+
Sheet dan mengembalikan fokus melalui primitive Sheet.
|
|
364
|
+
|
|
365
|
+
`nav-type="desktop"` adalah mode shell content-focused khusus. Nilai ini hanya
|
|
366
|
+
valid ketika shell berada pada mode `desktop` dan `layout-type="horizontal"`.
|
|
367
|
+
Pada kombinasi tersebut, `desktop` adalah satu-satunya nav type yang valid;
|
|
368
|
+
consumer settings harus menormalkan `navbar` atau `flyout` menjadi `desktop`.
|
|
369
|
+
Wrapper mempertahankan `LayoutHorizontal` agar frame desktop tetap konsisten,
|
|
370
|
+
tetapi menyembunyikan `LayoutNavigation` dan app bar mobile, sama seperti
|
|
371
|
+
perilaku navigasi pada layout `empty`.
|
|
372
|
+
|
|
373
|
+
## Surface API
|
|
374
|
+
|
|
375
|
+
Nilai `surface` yang tersedia berasal dari `LAYOUT_SURFACES`.
|
|
376
|
+
|
|
377
|
+
Semua pattern memakai tiga tier semantik: LINE, HIGHLIGHT, dan NODE. Saat
|
|
378
|
+
`theme-neutral='base'`, hue pattern mengikuti accent aktif. Pada seluruh neutral
|
|
379
|
+
lainnya, pattern mengikuti keluarga neutral tersebut. Tonal anchor dan opacity
|
|
380
|
+
tetap dipisahkan agar tekstur terlihat tetapi tidak bersaing dengan konten. Chrome
|
|
381
|
+
yang memang accent tetap berada di luar aturan pattern: rail dan frame
|
|
382
|
+
`border-rail`, serta frame khusus `grid-line`. Frame flat lainnya tetap memakai
|
|
383
|
+
neutral `--border`.
|
|
384
|
+
|
|
385
|
+
| Nilai | Efek visual |
|
|
386
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
387
|
+
| `'flat'` | Background polos `bg-layout-canvas`, tanpa pattern. |
|
|
388
|
+
| `'grid'` | Pola grid tipis dua arah; warna garis memakai tier LINE melalui `--layout-grid-color`. |
|
|
389
|
+
| `'grid-line'` | Mosaik kotak: grid tipis + kotak highlight memakai tier HIGHLIGHT melalui `--layout-grid-highlight-color`. Memaksa sudut frame kotak (`rounded-none`) + border frame Accent. Pada appearance `border-rail`, garis rail + border frame (tebal `--layout-rail-width` = 1px) tetap Accent pada opacity `--layout-rail-opacity` = 0.666. |
|
|
390
|
+
| `'honeycomb'` | Outline honeycomb tipis memakai tier LINE yang sama dengan grid. |
|
|
391
|
+
| `'matrix'` | Field biner (0/1) acak tipis memakai tier NODE melalui `--layout-matrix-color`; edge glow memakai tier yang sama dengan opacity terpisah. |
|
|
392
|
+
| `'circuit'` | Tekstur PCB dua lapisan: trace memakai tier LINE (`--layout-circuit-trace-color`) dan node/pad memakai tier NODE (`--layout-circuit-node-color`). |
|
|
393
|
+
| `'line-vertical'` | Garis vertikal berulang memakai tier LINE pada opacity single-axis. |
|
|
394
|
+
| `'line-horizontal'` | Garis horizontal berulang memakai tier LINE pada opacity single-axis. |
|
|
395
|
+
|
|
396
|
+
## Appearance API
|
|
397
|
+
|
|
398
|
+
Nilai `appearance` yang tersedia berasal dari `LAYOUT_APPEARANCES`.
|
|
399
|
+
|
|
400
|
+
| Nilai | Efek visual |
|
|
401
|
+
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
402
|
+
| `'flat'` | Frame tetap memiliki border 1px tanpa rail luar. |
|
|
403
|
+
| `'border-rail'` | Frame memiliki border lebih tebal, rail dekoratif pada sudut frame, rail inset horizontal, serta rail vertikal sekunder di luar sisi kiri-kanan untuk efek double rail; untuk layout vertical, nav juga mendapat rail kanan yang mengekstensi ke atas dan bawah viewport. |
|
|
404
|
+
|
|
405
|
+
Gunakan `appearance` atau alias `layout-appearance` (simetris dengan `nav-appearance` di navigation; kosakata sama `flat | border-rail`) di template Angular. Nilai persisted untuk appearance disimpan dengan key local storage `layout-appearance`.
|
|
406
|
+
|
|
407
|
+
## Width API
|
|
408
|
+
|
|
409
|
+
Nilai `width` yang tersedia berasal dari `LAYOUT_WIDTHS`.
|
|
410
|
+
|
|
411
|
+
| Nilai | Perilaku |
|
|
412
|
+
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
413
|
+
| `'full'` | Root menggunakan padding `p-4`, frame dan content tetap full width. |
|
|
414
|
+
| `'wide'` | Di bawah `lg` tampil seperti `full`, mulai `lg` memakai padding `p-12` di root. |
|
|
415
|
+
| `'container'` | Di bawah `lg` tampil seperti `full`, mulai `lg` root memakai `py-16` tanpa padding horizontal, lalu frame/content dipusatkan dengan container behavior. |
|
|
416
|
+
| `'fluid'` | Dipakai untuk `LayoutFluid`: root dan rail menjadi kanvas centering, frame shrink mengikuti ukuran konten, lalu tetap dibatasi `max-width` dan `max-height` viewport. |
|
|
417
|
+
|
|
418
|
+
Ringkasnya:
|
|
419
|
+
|
|
420
|
+
- `wide` dan `container` sengaja collapse ke tampilan `full` di bawah breakpoint `lg`.
|
|
421
|
+
- Perbedaan utama `container` muncul mulai `lg`, saat frame dan content tidak lagi full bleed secara horizontal.
|
|
422
|
+
- `fluid` ditujukan untuk halaman tunggal seperti auth, splash, atau status page yang membutuhkan frame auto-centered di kedua sumbu.
|
|
423
|
+
|
|
424
|
+
## `LayoutService`
|
|
425
|
+
|
|
426
|
+
Service state kecil untuk menyimpan konteks layout aktif dan persistence ke local storage.
|
|
427
|
+
|
|
428
|
+
Import:
|
|
429
|
+
|
|
430
|
+
```ts
|
|
431
|
+
import { LayoutService } from '@ojiepermana/angular/theme/layout/services';
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Readonly signals:
|
|
435
|
+
|
|
436
|
+
| Properti | Type | Deskripsi |
|
|
437
|
+
| ------------ | -------------------------- | ------------------------ |
|
|
438
|
+
| `surface` | `Signal<LayoutSurface>` | Surface layout aktif. |
|
|
439
|
+
| `type` | `Signal<LayoutType>` | Type layout aktif. |
|
|
440
|
+
| `appearance` | `Signal<LayoutAppearance>` | Appearance layout aktif. |
|
|
441
|
+
| `width` | `Signal<LayoutWidth>` | Width mode aktif. |
|
|
442
|
+
|
|
443
|
+
Methods:
|
|
444
|
+
|
|
445
|
+
| Method | Signature | Deskripsi |
|
|
446
|
+
| --------------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
447
|
+
| `registerSurface` | `(surface: LayoutSurface) => void` | Mendaftarkan fallback `layout-surface` ke local storage hanya jika storage belum memiliki nilai valid. Jika sudah ada nilai valid, service tetap memakai nilai yang tersimpan. |
|
|
448
|
+
| `registerType` | `(type: LayoutType) => void` | Mendaftarkan fallback `layout-type` ke local storage hanya jika storage belum memiliki nilai valid. Jika sudah ada nilai valid, service tetap memakai nilai yang tersimpan. |
|
|
449
|
+
| `registerAppearance` | `(appearance: LayoutAppearance) => void` | Mendaftarkan fallback `layout-appearance` ke local storage hanya jika storage belum memiliki nilai valid. Jika sudah ada nilai valid, service tetap memakai nilai yang tersimpan. |
|
|
450
|
+
| `registerWidth` | `(width: LayoutWidth) => void` | Mendaftarkan fallback `layout-width` ke local storage hanya jika storage belum memiliki nilai valid. Jika sudah ada nilai valid, service tetap memakai nilai yang tersimpan. |
|
|
451
|
+
| `registerDefaults` | `(defaults: { surface?, appearance?, type?, width? }) => this` | Mendaftarkan beberapa fallback sekaligus. Ini adalah API yang direkomendasikan untuk page-level default karena consumer cukup memanggil satu method dan tetap menghormati nilai storage yang sudah valid. |
|
|
452
|
+
| `setSurface` | `(surface: LayoutSurface, options?: { persist?: boolean }) => void` | Menulis surface ke signal. Secara default juga menulis `localStorage`, tetapi consumer dapat memakai `persist: false` untuk override sementara. |
|
|
453
|
+
| `setType` | `(type: LayoutType, options?: { persist?: boolean }) => void` | Menulis type ke signal. Secara default juga menulis `localStorage`, tetapi consumer dapat memakai `persist: false` untuk override sementara. |
|
|
454
|
+
| `setAppearance` | `(appearance: LayoutAppearance, options?: { persist?: boolean }) => void` | Menulis appearance ke signal. Secara default juga menulis `layout-appearance`, tetapi consumer dapat memakai `persist: false` untuk override sementara. |
|
|
455
|
+
| `setWidth` | `(width: LayoutWidth, options?: { persist?: boolean }) => void` | Menulis width ke signal. Secara default juga menulis `localStorage`, tetapi consumer dapat memakai `persist: false` untuk override sementara. |
|
|
456
|
+
| `getStoredSurface` | `() => LayoutSurface` | Membaca surface yang valid dari storage atau default. |
|
|
457
|
+
| `getStoredType` | `() => LayoutType` | Membaca type yang valid dari storage atau default. |
|
|
458
|
+
| `getStoredAppearance` | `() => LayoutAppearance` | Membaca appearance yang valid dari storage atau default. |
|
|
459
|
+
| `getStoredWidth` | `() => LayoutWidth` | Membaca width yang valid dari storage atau default. |
|
|
460
|
+
|
|
461
|
+
Persistence behavior:
|
|
462
|
+
|
|
463
|
+
- Storage key: `layout-surface`, `layout-type`, `layout-appearance`, dan `layout-width`.
|
|
464
|
+
- Default value: `flat`, `vertical`, `flat`, dan `full`.
|
|
465
|
+
- `registerDefaults(...)` adalah API yang direkomendasikan untuk menetapkan default per halaman tanpa menimpa nilai valid yang sudah tersimpan sebelumnya.
|
|
466
|
+
- Manual template input pada `Layout` dan variant layout yang dirender consumer hanya mengubah state aktif; keduanya tidak lagi menulis `localStorage`.
|
|
467
|
+
- Method `registerSurface(...)`, `registerType(...)`, `registerAppearance(...)`, dan `registerWidth(...)` tetap tersedia bila consumer memang perlu registrasi yang lebih granular.
|
|
468
|
+
- Aman untuk SSR karena hanya mengakses `localStorage` saat runtime browser tersedia.
|
|
469
|
+
|
|
470
|
+
Contoh penggunaan:
|
|
471
|
+
|
|
472
|
+
```ts
|
|
473
|
+
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
|
474
|
+
import { LayoutService } from '@ojiepermana/angular/theme/layout/services';
|
|
475
|
+
|
|
476
|
+
@Component({
|
|
477
|
+
selector: 'demo-layout-toggle',
|
|
478
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
479
|
+
template: `
|
|
480
|
+
<button type="button" (click)="layout.setAppearance('flat')">Flat</button>
|
|
481
|
+
<button type="button" (click)="layout.setAppearance('border-rail')">Border rail</button>
|
|
482
|
+
`,
|
|
483
|
+
})
|
|
484
|
+
export class DemoLayoutToggleComponent {
|
|
485
|
+
readonly layout = inject(LayoutService);
|
|
486
|
+
}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## Types, constants, dan guards
|
|
490
|
+
|
|
491
|
+
Seluruh symbol berikut diekspor dari `@ojiepermana/angular/theme/layout/types`.
|
|
492
|
+
|
|
493
|
+
### Types
|
|
494
|
+
|
|
495
|
+
| Symbol | Nilai |
|
|
496
|
+
| -------------------- | -------------------------------------------------------------------------------------------------- |
|
|
497
|
+
| `LayoutType` | `vertical`, `horizontal`, `empty`, `fluid` |
|
|
498
|
+
| `LayoutSurface` | `flat`, `grid`, `grid-line`, `honeycomb`, `matrix`, `circuit`, `line-vertical`, `line-horizontal` |
|
|
499
|
+
| `LayoutAppearance` | `flat`, `border-rail` |
|
|
500
|
+
| `LayoutWidth` | `full`, `wide`, `container`, `fluid` |
|
|
501
|
+
| `LayoutContextValue` | Objekt berbentuk `{ surface, type, appearance, width }` yang masing-masing berupa readonly signal. |
|
|
502
|
+
|
|
503
|
+
### Constants
|
|
504
|
+
|
|
505
|
+
| Symbol | Nilai |
|
|
506
|
+
| ------------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
507
|
+
| `LAYOUT_TYPES` | `['vertical', 'horizontal', 'empty', 'fluid']` |
|
|
508
|
+
| `LAYOUT_SURFACES` | `['flat', 'grid', 'grid-line', 'honeycomb', 'matrix', 'circuit', 'line-vertical', 'line-horizontal']` |
|
|
509
|
+
| `LAYOUT_APPEARANCES` | `['flat', 'border-rail']` |
|
|
510
|
+
| `LAYOUT_WIDTHS` | `['full', 'wide', 'container', 'fluid']` |
|
|
511
|
+
| `LAYOUT_DEFAULT_SURFACE` | `'flat'` |
|
|
512
|
+
| `LAYOUT_DEFAULT_TYPE` | `'vertical'` |
|
|
513
|
+
| `LAYOUT_DEFAULT_APPEARANCE` | `'flat'` |
|
|
514
|
+
| `LAYOUT_DEFAULT_WIDTH` | `'full'` |
|
|
515
|
+
| `LAYOUT_SURFACE_STORAGE_KEY` | `'layout-surface'` |
|
|
516
|
+
| `LAYOUT_APPEARANCE_STORAGE_KEY` | `'layout-appearance'` |
|
|
517
|
+
| `LAYOUT_TYPE_STORAGE_KEY` | `'layout-type'` |
|
|
518
|
+
| `LAYOUT_WIDTH_STORAGE_KEY` | `'layout-width'` |
|
|
519
|
+
|
|
520
|
+
### Guards
|
|
521
|
+
|
|
522
|
+
- `isUiLayoutSurface(value: string | null): value is LayoutSurface`
|
|
523
|
+
Memvalidasi string terhadap daftar surface yang didukung.
|
|
524
|
+
- `isUiLayoutType(value: string | null): value is LayoutType`
|
|
525
|
+
Memvalidasi string terhadap daftar type yang didukung.
|
|
526
|
+
- `isUiLayoutAppearance(value: string | null): value is LayoutAppearance`
|
|
527
|
+
Memvalidasi string terhadap daftar style yang didukung.
|
|
528
|
+
- `isUiLayoutWidth(value: string | null): value is LayoutWidth`
|
|
529
|
+
Memvalidasi string terhadap daftar width yang didukung.
|
|
530
|
+
|
|
531
|
+
## Consumer guidance
|
|
532
|
+
|
|
533
|
+
- Gunakan `appearance` atau alias `layout-appearance` di template (kosakata sama dengan `nav-appearance` pada navigation).
|
|
534
|
+
- Untuk halaman yang punya default layout sendiri, utamakan `inject(LayoutService).registerDefaults({...})` sekali di level page daripada memanggil empat method `register...` terpisah.
|
|
535
|
+
- Jika halaman harus merender variant berdasarkan preferensi yang tersimpan, pakai `layout.type()` sebagai sumber branching dan bind root `Layout` ke `layout.surface()`, `layout.appearance()`, dan `layout.width()`.
|
|
536
|
+
- Tempatkan scroll page utama di `LayoutContent`, bukan di root `Layout`.
|
|
537
|
+
- Untuk `vertical + border-rail`, biarkan primitive yang merender rail kanan nav; hindari border manual yang menduplikasi garis itu.
|
|
538
|
+
- Semua primitive menerima input `class`, jadi styling tambahan paling aman diberikan lewat class host atau child content.
|
|
539
|
+
- Jika consumer perlu membaca state layout aktif dari komponen lain, inject `LayoutService` dan baca signal readonly-nya.
|