activator-oce-exporter
Version:
Extract Activator binder and convert it to valid OCE mono pacakge
369 lines (333 loc) • 9.62 kB
JavaScript
import { html } from '@polymer/lit-element';
import { FusionBase } from '../../base';
import {
applyMixins, BorderedElement, ModeTrackable, SlideComponent, Font,
} from '../../mixins';
import { getValueObject, intersectMap, isRgba } from '../../utils';
import { FusionStore } from '../../services/fusion-store';
const parseColor = (pattern, str) => {
const crop = pattern.exec(str)[1];
return crop.split(',');
};
/**
* @typedef {object} ColorPreset
* @property {string} 'background-color'
* @property {string} color
*/
/**
* @typedef {Object.<string, ColorPreset>} PresetsMap
*/
const lightenDarkenColor = (hslaStr, lighten) => {
const [h, s, l, a] = parseColor(/hsla\(([\d,.\s%]+)\)/g, hslaStr);
let lightness = parseInt(l.replace(/%/g, '').trim(), 10);
let alpha = a.trim();
if (lighten) {
alpha *= lighten;
}
const step = lightness <= 50 ? 10 : -10;
lightness = `${step + lightness}%`;
return `hsla(${h}, ${s}, ${lightness}, ${alpha})`;
};
const rgba2hsla = (rgbaStr, alpha) => {
let [r, g, b, a] = parseColor(/rgba\(([\d,.\s]+)\)/g, rgbaStr);
let h; let s; let
d;
r /= 255;
g /= 255;
b /= 255;
a *= 100;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let l = (max + min) / 2;
alpha ? a *= alpha / 100 : (a /= 100);
if (max === min) {
h = 0;
s = 0;
} else {
d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
default:
break;
}
h /= 6;
}
h = Math.floor(h * 360);
s = Math.floor(s * 100);
l = Math.floor(l * 100);
return `hsla(${h}, ${s}%, ${l}%, ${a})`;
};
const defaultTemplate = '<p>Button name</p>';
class FusionButton extends applyMixins(FusionBase, [Font, ModeTrackable, SlideComponent, BorderedElement]) {
static get properties() {
const { top, left, ...borderedProps } = super.properties;
return {
top,
left,
width: {
type: String,
fieldType: 'Number',
value: '100px',
},
height: {
type: String,
fieldType: 'Number',
value: '30px',
},
'style-type': {
type: String,
fieldType: 'Select',
value: 'Normal',
selectOptions: Object.keys(this.presetsMap),
},
'background-color': {
type: String,
fieldType: 'ColorPicker',
value: 'rgba(221, 221, 221, 1)',
},
color: {
type: String,
fieldType: 'ColorPicker',
value: 'rgba(0, 0, 0, 1)',
},
...borderedProps,
'enable-styling-effects': {
type: Boolean,
fieldType: 'Boolean',
value: true,
prop: true,
},
};
}
static get options() {
return {
componentName: 'fusion-button',
componentUIName: 'Button',
componentScope: 'standard',
componentType: 'static',
componentCategory: 'interaction',
componentDescription: 'Basic button for adding interactions',
componentDomain: 'slide',
isTextEdit: true,
isRootNested: true,
nestedTypes: [],
nestedComponents: [],
defaultTemplate,
resizable: 'all',
draggable: 'xy',
rotatable: true,
sortable: false,
};
}
/**
* @description get predefined colors by style-type property
* @returns {PresetsMap} predefined colors
*/
static get presetsMap() {
return {
Normal: {
'background-color': 'rgba(221, 221, 221, 1)',
color: 'rgba(0, 0, 0, 1)',
},
Primary: {
'background-color': 'rgba(0, 123, 255, 1)',
color: 'rgba(255, 255, 255, 1)',
},
Dark: {
'background-color': 'rgba(52, 58, 64, 1)',
color: 'rgba(255, 255, 255, 1)',
},
Link: {
'background-color': 'rgba(255, 255, 255, 0)',
color: 'rgba(0, 123, 255, 1)',
},
};
}
constructor() {
super();
this.alpha = 0.5;
}
setColors(attr, value) {
const presetColors = this.constructor.getPreset(this['style-type']);
const rgba = isRgba(value) ? value : presetColors[attr];
this.style.setProperty(`--${attr}`, value);
this.setAttribute(attr, rgba);
this.setColorEffects(attr, rgba);
}
getAdditionalColorEffects(value, attr, shadow) {
const effects = {
'background-color': {
'button-color-darken': lightenDarkenColor(rgba2hsla(value)),
'button-shadow': lightenDarkenColor(rgba2hsla(shadow), this.alpha),
},
color: {
'text-color-hover': lightenDarkenColor(rgba2hsla(value)),
},
};
return effects[attr];
}
/**
* @description Set color effects depend on border-color or background-color
* @param {string} prop - property which changes
* @param {string} value - rgba color value
*/
setColorEffects(prop, value) {
const shadow = this.getBorderColor(value);
const effects = this.getAdditionalColorEffects(value, prop, shadow);
Object.keys(effects).forEach(item => this.setElementProp(item, effects[item]));
}
getAttributeValue(property) {
return this.getAttribute(property);
}
checkPreset(changedProps) {
if (FusionButton.isPresetChanged(changedProps)) {
this.updatePresetColors();
}
}
checkColors(changedProps) {
if (FusionButton.isColorChanged(changedProps)) {
this.updateColors();
}
}
update(changedProps) {
super.update(changedProps);
if (this.isRendered) {
this.borderChanges(changedProps);
this.checkPreset(changedProps);
this.checkColors(changedProps);
}
}
checkSizes(changedProps) {
const properties = intersectMap(changedProps, this.constructor.sizeTriggers);
Array.from(properties.keys()).forEach(prop => this.setSize(prop));
}
borderChanges(props) {
if (this.constructor.isBorderChanged(props)) {
const isBorderEmpty = this.constructor.isBorderEmpty(...this.getBorderProps());
this.updateClassName(isBorderEmpty);
['background-color', 'color'].forEach(prop => this.setColors(prop, this[prop]));
this.constructor.sizeTriggers.forEach(prop => this.setSize(prop));
}
}
setSize(prop) {
const value = this.getValue(prop);
const size = this.getSizeByBorder(value);
this.updateProperty(prop, size);
}
updateProperty(prop, size) {
this.setElementProp(prop, size);
this.setAttribute(prop, size);
}
getValue(prop) {
return getValueObject(this[prop]).num;
}
static isPresetChanged(changedProps) {
return changedProps.has('style-type');
}
static isColorChanged(changedProps) {
return changedProps.has('background-color') || changedProps.has('color');
}
updateColors() {
this.setColors('background-color', this['background-color']);
this.setColors('color', this.color);
}
updatePresetColors() {
const preset = this.constructor.getPreset(this['style-type']);
Object.keys(preset).forEach(item => this.setColors(item, preset[item]));
}
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties);
this.updateColors();
}
static propagateFocus(event) {
if (!FusionStore.isEditMode) {
event.preventDefault();
event.currentTarget.focus();
}
}
/**
*
* @param {string} preset - button predefined style-type
* @returns {PresetsMap} predefined colors
*/
static getPreset(preset) {
return this.presetsMap[preset];
}
static getStyle() {
const styleRoot = super.getStyle();
return `
${styleRoot}
:host {
display: inline-block;
border-radius: var(--border-radius);
}
:host button {
width: 100%;
height: 100%;
text-align: center;
vertical-align: middle;
border: var(--border-width) var(--border-style) var(--border-color);
border-radius: var(--border-radius);
transition: color .15s ease-in-out,background-color .15s ease-in-out,box-shadow .15s ease-in-out;
background-color: var(--background-color);
color: var(--color);
user-select: none;
box-sizing: border-box;
cursor: pointer;
outline: 0;
}
:host([data-mo-editable]) {
color: black;
}
:host([enable-styling-effects]) button:focus {
box-shadow: 0 0 0 3px var(--button-shadow);
}
:host([enable-styling-effects]) button:hover,
:host([enable-styling-effects]) button:active {
background-color: var(--button-color-darken);
color: var(--text-color-hover);
}
:host([style-type='Link']) button:hover,
:host([style-type='Link']) button:active,
:host([style-type='Link']) button:focus {
text-decoration: underline;
box-shadow: none;
}
:host(.${ModeTrackable.EditModeClassName}) button {
cursor: auto;
}
:host(.border-empty) button {
border: none;
}
::slotted(.ql-editor),
::slotted(p) {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
:host([data-mo-editable]) ::slotted(p) {
white-space: normal;
}
`;
}
render() {
super.render();
return html`
<style>
${FusionButton.getStyle()}
</style>
<button ="${event => FusionButton.propagateFocus(event)}"><slot></slot></button>
${FusionButton.getSystemSlotTemplate()}
`;
}
}
export { FusionButton };