activator-oce-exporter
Version:
Extract Activator binder and convert it to valid OCE mono pacakge
315 lines (288 loc) • 8.54 kB
JavaScript
import { html } from '@polymer/lit-element';
import { FusionButton } from '../button';
import { FusionGroup } from '../group';
import {
applyMixins, ItemsWrapper, ChildrenStylist, Font,
} from '../../mixins';
import {
getValueObject,
intersectMap,
} from '../../utils';
import { FusionApi } from '../../api';
class FusionSideMenuButton extends FusionButton {
static get properties() {
const {
width, height, top, left,
...filteredProp
} = FusionButton.properties;
return filteredProp;
}
static get options() {
return {
...FusionButton.options,
componentName: 'fusion-side-menu-button',
componentUIName: 'Side Menu Button',
componentDescription: 'Button for side menu',
isRootNested: false,
resizable: false,
draggable: false,
rotatable: false,
};
}
disconnectedCallback() {
super.disconnectedCallback();
this.emitCustomEvent(`${this.constructor.options.componentName}:removed`);
}
connectedCallback() {
super.connectedCallback();
this.emitCustomEvent(`${this.constructor.options.componentName}:added`);
}
static getStyle(styleRoot = super.getStyle()) {
return `
${styleRoot}
:host {
position: relative;
}`;
}
render() {
super.render();
return html`
<style>
${FusionSideMenuButton.getStyle()}
</style>
<button ="${event => FusionSideMenuButton.propagateFocus(event)}"><slot></slot></button>
${FusionSideMenuButton.getSystemSlotTemplate()}
`;
}
}
class FusionSideMenu extends applyMixins(FusionGroup, [ItemsWrapper, ChildrenStylist, Font]) {
static get properties() {
const {
top, left, width, height, items, 'background-color': bgColor,
...rest
} = super.properties;
return {
top: {
type: String,
fieldType: 'Number',
value: '210px',
min: '0',
},
left: {
type: String,
fieldType: 'Number',
value: '0px',
min: '0',
},
width: {
type: String,
fieldType: 'Number',
value: '100px',
min: '30',
},
height: {
type: String,
fieldType: 'Number',
value: '310px',
min: '30',
},
items: {
type: String,
fieldType: 'Number',
value: '3',
min: '1',
prop: true,
},
'font-size': {
type: String,
fieldType: 'Number',
value: '16px',
},
color: {
type: String,
fieldType: 'ColorPicker',
value: 'rgba(0, 0, 0, 1)',
},
'background-color': {
type: String,
fieldType: 'ColorPicker',
value: 'rgba(221, 221, 221, 1)',
},
placing: {
type: String,
fieldType: 'Select',
value: 'vertical',
selectOptions: [
'vertical',
'horizontal',
],
prop: true,
},
'space-between-buttons': {
type: String,
fieldType: 'Number',
value: '5',
min: '0',
prop: true,
},
...rest,
};
}
// @todo elements aligner will be applied after columns aligner implementation, please see https://trello.com/c/c3GTkPEr
static get options() {
const {
alignConfig,
...otherOptions
} = super.options;
return {
...otherOptions,
componentName: 'fusion-side-menu',
componentCategory: 'interaction',
componentUIName: 'Side Menu',
componentDescription: 'Side menu component for navigation',
nestedTypes: [],
nestedComponents: ['fusion-side-menu-button'],
};
}
static get synchronizableProperties() {
const {
width, height, items, placing, 'space-between-buttons': space, top, left,
...filteredProp
} = this.properties;
return filteredProp;
}
constructor() {
super();
this.item = FusionSideMenu.createObjectItem(FusionSideMenuButton);
this.wrapperClassName = 'menu-items';
this.minButtonValue = 30;
}
checkSizes(changedProps) {
super.checkSizes(changedProps);
const properties = intersectMap(changedProps, [...this.constructor.sizeTriggers, 'space-between-buttons', 'placing']);
if (properties.size) {
this.applyCorrectSizes();
}
}
applyCorrectSizes() {
const preset = this.getSizePresets(this.placing);
this.updateParentSize(preset.parentSizes);
this.updateChildrenSize(preset.buttonSizes);
}
/**
* @description Update parent sizes
* @param {object.<string, string>} properties
*/
updateParentSize(properties) {
FusionApi.setAttributes({ properties, element: this });
}
/**
* @description Update sizes for each buttons
* @param {object.<string, string>} properties
*/
updateChildrenSize(properties) {
const children = this.constructor.getExistingItems(this.item.name, this);
children.forEach(element => FusionApi.setAttributes({ properties, element }));
}
/**
* @description Get sizes by buttons placing
* @param {string} placing - buttons placing
* @returns {object<string>} calculated sizes for elements
*/
getSizePresets(placing) {
const props = this.isHorizontalPlacing(placing)
? this.constructor.sizeTriggers.slice().reverse()
: this.constructor.sizeTriggers.slice();
return this.getCalculatedSizes(props);
}
isHorizontalPlacing(placing) {
return placing !== this.constructor.properties.placing.value;
}
/**
* @description Get calculated sizes for main wrapper and buttons by the count of items and space between them
* @param {string} firstProp - can be width or height, depending on placing
* @param {string} secondProp - can be height or width, also depends on placing
* @returns {object<string>} calculated sizes for elements
*/
getCalculatedSizes([firstProp, secondProp]) {
const firstPropValue = this.getCommonSize(firstProp);
const secondPropButtonValue = this.getCalculatedButtonSize(secondProp);
return {
parentSizes: {
[firstProp]: { value: firstPropValue },
[secondProp]: { value: this.getCalculatedSize(secondPropButtonValue) },
},
buttonSizes: {
[secondProp]: { value: secondPropButtonValue },
[firstProp]: { value: firstPropValue },
},
};
}
/**
* @description Get simple size
* @param {string} property - name of property
* @returns {string} calculated size by property
*/
getCommonSize(property) {
const { num, unit } = getValueObject(this[property]);
return `${Math.max(num, this.minButtonValue)}${unit}`;
}
/**
* @description Get calculated size by position, spaces and items quantity
* @param {string} property - name of property
* @returns {string} calculated size by property
*/
getCalculatedSize(property) {
const { num, unit } = getValueObject(property);
const value = num * this.items + this['space-between-buttons'] * (this.items - 1);
return `${value}${unit}`;
}
/**
* @description Get button sizes by items count and space between they
* @param {string} property - name of property
* @returns {string} calculated size by property
*/
getCalculatedButtonSize(property) {
const { num, unit } = getValueObject(this[property]);
const buttonSize = (num - this['space-between-buttons'] * (this.items - 1)) / this.items;
const calculatedValueByBorder = getValueObject(this.getSizeByBorder(buttonSize)).num;
return `${Math.max(this.minButtonValue, calculatedValueByBorder)}${unit}`;
}
async generateItem() {
await super.generateItem();
this.applyCorrectSizes();
}
async removeContent(count) {
await super.removeContent(count);
this.applyCorrectSizes();
}
firstUpdated(changedProps) {
super.firstUpdated(changedProps);
this.applyCorrectSizes();
}
static getStyle(wrapper, styleRoot = super.getStyle()) {
return `
${styleRoot}
.${wrapper} {
display: flex;
justify-content: space-between;
height: var(--height);
width: var(--width);
}
:host([placing='vertical']) .${wrapper} {
flex-direction: column;
}
`;
}
render() {
super.render();
return html`
<style>
${FusionSideMenu.getStyle(this.wrapperClassName)}
</style>
<div class=${this.wrapperClassName}></div>
${FusionSideMenu.getSystemSlotTemplate()}
`;
}
}
export { FusionSideMenuButton, FusionSideMenu };