@paperbits/core
Version:
Paperbits core components.
158 lines (128 loc) • 6.29 kB
text/typescript
import * as ko from "knockout";
import template from "./menuEditor.html";
import { Component, Event, OnMounted, Param } from "@paperbits/common/ko/decorators";
import { NavigationItemModel } from "@paperbits/common/navigation";
import { ViewManager } from "@paperbits/common/ui";
import { SelectOption } from "@paperbits/common/ui/selectOption";
import { StyleHelper, StyleService } from "@paperbits/styles";
import { BoxStylePluginConfig, Display, MarginStylePluginConfig, SizeStylePluginConfig } from "@paperbits/styles/plugins";
import { MenuModel } from "../menuModel";
const emptySelectionLabel = "Click to select navigation item...";
export class MenuEditor {
public readonly navigationItemTitle: ko.Observable<string>;
public readonly showHeadings: ko.Observable<boolean>;
public readonly headingLevelOptions: ko.ObservableArray<SelectOption>;
public readonly minHeadingLevel: ko.Observable<number>;
public readonly maxHeadingLevel: ko.Observable<number>;
public readonly layout: ko.Observable<string>;
public readonly layoutOptions: ko.ObservableArray<SelectOption>;
public readonly menuVariations: ko.ObservableArray<any>;
public readonly menuVariationKey: ko.Observable<any>;
public readonly displayStyle: ko.Observable<string>;
public readonly boxConfig: ko.Observable<BoxStylePluginConfig>;
public readonly sizeConfig: ko.Observable<SizeStylePluginConfig>;
public displayOptions: SelectOption[] = [
{ value: null, text: "(Inherit)" },
{ value: Display.Inline, text: "Visible" },
{ value: Display.None, text: "Hidden" }
];
constructor(
private readonly styleService: StyleService,
private readonly viewManager: ViewManager
) {
this.showHeadings = ko.observable();
this.minHeadingLevel = ko.observable();
this.maxHeadingLevel = ko.observable();
this.layout = ko.observable();
this.menuVariations = ko.observableArray<any>();
this.menuVariationKey = ko.observable<any>();
this.boxConfig = ko.observable<BoxStylePluginConfig>();
this.sizeConfig = ko.observable<SizeStylePluginConfig>();
this.headingLevelOptions = ko.observableArray<SelectOption>([
{ text: "Heading 1", value: 1 },
{ text: "Heading 2", value: 2 },
{ text: "Heading 3", value: 3 },
{ text: "Heading 4", value: 4 },
{ text: "Heading 5", value: 5 },
{ text: "Heading 6", value: 6 }
]);
this.layoutOptions = ko.observableArray<SelectOption>([
{ text: "Horizontal menu", value: "horizontal" },
{ text: "Vertical menu", value: "vertical" }
]);
this.navigationItemTitle = ko.observable();
this.displayStyle = ko.observable<string>();
}
public model: MenuModel;
public onChange: (model: MenuModel) => void;
public async initialize(): Promise<void> {
const localStyles = this.model.styles;
this.showHeadings(!!this.model.minHeading || !!this.model.maxHeading);
this.minHeadingLevel(this.model.minHeading || 1);
this.maxHeadingLevel(this.model.maxHeading || 6);
const variations = await this.styleService.getComponentVariations("menu");
this.menuVariations(variations.filter(x => x.category === "appearance"));
this.menuVariationKey(this.model.styles?.appearance);
this.navigationItemTitle(this.model.navigationItem?.label || emptySelectionLabel);
this.layout(this.model.layout);
const marginConfig = <MarginStylePluginConfig>StyleHelper.getPluginConfigForLocalStyles(localStyles, "margin");
this.boxConfig({ margin: marginConfig });
const sizeConfig = <SizeStylePluginConfig>StyleHelper.getPluginConfigForLocalStyles(localStyles, "size");
this.sizeConfig(sizeConfig);
this.minHeadingLevel.subscribe(this.applyChanges);
this.maxHeadingLevel.subscribe(this.applyChanges);
this.layout.subscribe(this.applyChanges);
this.showHeadings.subscribe(this.applyChanges);
this.menuVariationKey.subscribe(this.applyChanges);
}
public onNavigationItemChange(navigationItem: NavigationItemModel): void {
this.model.navigationItem = navigationItem;
this.navigationItemTitle(navigationItem?.label || emptySelectionLabel);
this.applyChanges();
}
public onDisplayChange(): void {
const viewport = this.viewManager.getViewport();
const newViewportValue = this.displayStyle();
StyleHelper.setVisibility(this.model.styles, newViewportValue, viewport, this.viewManager);
this.onChange(this.model);
}
public onVariationChange(): void {
this.onChange(this.model);
}
public onSizeChange(sizeConfig: SizeStylePluginConfig): void {
this.sizeConfig(sizeConfig);
this.applyChanges();
}
public onBoxUpdate(pluginConfig: BoxStylePluginConfig): void {
this.boxConfig(pluginConfig);
this.applyChanges();
}
public applyChanges(): void {
if (this.showHeadings()) {
this.model.minHeading = this.minHeadingLevel();
this.model.maxHeading = this.maxHeadingLevel();
}
else {
this.model.minHeading = null;
this.model.maxHeading = null;
}
this.model.layout = this.layout();
this.model.styles = {
appearance: this.menuVariationKey()
};
const marginStyle = this.boxConfig().margin;
const paddingStyle = this.boxConfig().padding;
const sizeConfig: SizeStylePluginConfig = this.sizeConfig();
StyleHelper.setPluginConfigForLocalStyles(this.model.styles, "size", sizeConfig);
StyleHelper.setPluginConfigForLocalStyles(this.model.styles, "margin", marginStyle);
StyleHelper.setPluginConfigForLocalStyles(this.model.styles, "padding", paddingStyle)
this.onChange(this.model);
}
}