UNPKG

@blinkk/selective-edit

Version:
152 lines 6.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OptionMixin = exports.ColorsOrientation = void 0; const lit_html_1 = require("lit-html"); const class_map_js_1 = require("lit-html/directives/class-map.js"); const if_defined_js_1 = require("lit-html/directives/if-defined.js"); const repeat_js_1 = require("lit-html/directives/repeat.js"); const style_map_js_1 = require("lit-html/directives/style-map.js"); /** * Orientation for colors gradient. */ var ColorsOrientation; (function (ColorsOrientation) { ColorsOrientation["Vertical"] = "vertical"; ColorsOrientation["Horizontal"] = "horizontal"; ColorsOrientation["Slope"] = "slope"; })(ColorsOrientation = exports.ColorsOrientation || (exports.ColorsOrientation = {})); function OptionMixin(Base) { return class OptionClass extends Base { ariaLabelForOptionDot(config, option) { if (option.color) { return option.color; } if (!option.gradient || !option.gradient.colors.length) { return option.label; } return option.gradient.colors.join(', '); } classesForOptions(config, options) { return { selective__options: true, 'selective__options--color-hint': this.hasColorHints(options), 'selective__options--few': options.length > 4, 'selective__options--many': options.length > 11, 'selective__options--multi': config.isMulti || false, }; } classesForOption(config, option) { return { selective__options__option: true, 'selective__options__option--selected': config.isOptionSelected(option), 'selective__options__option--color-hint': Boolean(option.color), 'selective__options__option--color-hint-gradient': Boolean(option.gradient), }; } /** * Are there color hints? */ hasColorHints(options) { for (const option of options) { if (option.color || option.gradient) { return true; } } return false; } stylesForOptionDot(config, option) { if (option.color) { return { backgroundColor: option.color, }; } if (!option.gradient || !option.gradient.colors.length) { return {}; } const gradient = option.gradient; let orientationAngle = '0deg'; if (gradient.orientation === ColorsOrientation.Horizontal) { orientationAngle = '90deg'; } else if (gradient.orientation === ColorsOrientation.Slope) { orientationAngle = '45deg'; } const isSmooth = gradient.isSmooth || false; const breakpoints = [`${gradient.colors[0]} 0%`]; const numBreakpoints = isSmooth ? gradient.colors.length - 1 : gradient.colors.length; let breakpoint = Math.floor(100 / numBreakpoints); let lastColor = null; for (const color of gradient.colors) { if (!lastColor) { lastColor = color; continue; } if (!isSmooth) { breakpoints.push(`${lastColor} ${breakpoint}%`); } breakpoints.push(`${color} ${breakpoint}%`); breakpoint += breakpoint; lastColor = color; } if (!isSmooth) { breakpoints.push(`${gradient.colors[gradient.colors.length - 1]} 100%`); } return { backgroundImage: `linear-gradient(${orientationAngle}, ${breakpoints.join(', ')})`, }; } templateColorSwatch(editor, data, config, option) { if (!option.color && !option.gradient) { return (0, lit_html_1.html) ``; } return (0, lit_html_1.html) `<div class="selective__swatch" aria-label=${this.ariaLabelForOptionDot(config, option)} style=${(0, style_map_js_1.styleMap)(this.stylesForOptionDot(config, option))} ></div>`; } templateOption(editor, data, config, option) { let icon = ''; if (config.isOptionSelected(option)) { icon = config.isMulti ? 'check_box' : 'radio_button_checked'; } else { icon = config.isMulti ? 'check_box_outline_blank' : 'radio_button_unchecked'; } return (0, lit_html_1.html) `<div class=${(0, class_map_js_1.classMap)(this.classesForOption(config, option))} aria-checked=${config.isOptionSelected(option)} data-value=${option.value} tabindex="0" role=${config.isMulti ? 'checkbox' : 'radio'} @blur=${config.handleBlur} @click=${config.handleInput} @keypress=${(evt) => { if (evt.code === 'Space') { evt.preventDefault(); config.handleInput(evt); } }} > <span class="material-icons">${icon}</span> ${this.templateColorSwatch(editor, data, config, option)} <label>${option.label || option.value || '(Empty)'}</label> </div>`; } templateOptions(editor, data, config, options) { // TODO: Convert to a different UI when there are a lot of options. return (0, lit_html_1.html) `<div class=${(0, class_map_js_1.classMap)(this.classesForOptions(config, options))} role=${(0, if_defined_js_1.ifDefined)(config.isMulti ? undefined : 'radiogroup')} > ${(0, repeat_js_1.repeat)(options, option => option.value, option => this.templateOption(editor, data, config, option))} </div>`; } }; } exports.OptionMixin = OptionMixin; //# sourceMappingURL=option.js.map