UNPKG

activator-oce-exporter

Version:

Extract Activator binder and convert it to valid OCE mono pacakge

369 lines (333 loc) 9.62 kB
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 @mousedown="${event => FusionButton.propagateFocus(event)}"><slot></slot></button> ${FusionButton.getSystemSlotTemplate()} `; } } export { FusionButton };