@blinkk/selective-edit
Version:
Selective structured text editor.
179 lines • 6.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VariantField = void 0;
const deepObject_1 = require("../../utility/deepObject");
const field_1 = require("../field");
const lit_html_1 = require("lit-html");
const dataType_1 = require("../../utility/dataType");
const dom_1 = require("../../utility/dom");
const lodash_merge_1 = __importDefault(require("lodash.merge"));
const repeat_js_1 = require("lit-html/directives/repeat.js");
class VariantField extends field_1.Field {
constructor(types, config, globalConfig, fieldType = 'variant') {
super(types, config, globalConfig, fieldType);
this.config = config;
this.usingAutoFields = false;
}
createFields() {
const variant = this.variant || this.originalValue?._variant || this.config.default;
// If we don't know which variant to use, then skip it.
if (!variant) {
return undefined;
}
// Use the found variant if it is undefined.
if (this.variant === undefined) {
this.variant = variant;
}
const variantConfig = this.config.variants[variant] || {};
const fieldConfigs = variantConfig.fields || [];
return new this.types.globals.FieldsCls(this.types, {
fields: fieldConfigs,
isGuessed: this.usingAutoFields,
parentKey: this.fullKey,
}, this.globalConfig);
}
ensureFields() {
if (!this.fields) {
this.fields = this.createFields();
}
}
handleVariantClick(evt) {
const target = evt.target;
const variantTarget = (0, dom_1.findParentByClassname)(target, 'selective__variant__variant');
const variant = variantTarget?.dataset.variant;
if (!variant || variant === this.variant) {
return;
}
this.variant = variant;
// Reset the fields so they can be recreated next render.
this.fields = undefined;
this.render();
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
handleVariantClear(evt) {
this.variant = undefined;
// Reset the fields so they can be recreated next render.
this.fields = undefined;
this.render();
}
get isClean() {
// If there are no fields, nothing has changed.
if (!this.fields) {
return true;
}
// Check for changes to the variant.
if (this.originalValue && this.originalValue._variant !== this.variant) {
return false;
}
return this.fields.isClean;
}
/**
* Check if the data format is invalid for what the field expects to edit.
*/
get isDataFormatValid() {
if (this.originalValue === undefined || this.originalValue === null) {
return true;
}
return dataType_1.DataType.isObject(this.originalValue);
}
get isValid() {
// If there are no fields, nothing has changed.
if (!this.fields) {
return true;
}
return this.fields.isValid;
}
/**
* Template for rendering the field input.
*
* The help text is part of the input template so complex inputs can
* use zones for the help text.
*
* @param editor Selective editor used to render the template.
* @param data Data provided to render the template.
*/
templateInput(editor, data) {
this.ensureFields();
return (0, lit_html_1.html) `${this.templateHelp(editor, data)}${this.fields?.template(editor, (0, deepObject_1.autoDeepObject)(this.originalValue)) || ''}`;
}
/**
* Template for rendering the field input structure.
*
* @param editor Selective editor used to render the template.
* @param data Data provided to render the template.
*/
templateInputStructure(editor, data) {
const parts = [];
if (!this.isDataFormatValid) {
parts.push(this.templateDataFormatInvalid(editor, data));
}
else {
parts.push(this.templateVariants(editor, data));
parts.push(this.templateInput(editor, data));
}
return (0, lit_html_1.html) `<div class="selective__field__input__structure">${parts}</div>`;
}
/**
* Template for rendering the variant options.
*
* @param editor Selective editor used to render the template.
* @param data Data provided to render the template.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
templateVariants(editor, data) {
const variants = this.config.variants;
const variantKeys = Object.keys(variants).sort();
return (0, lit_html_1.html) `<div class="selective__variant__variants">
${this.config.variantLabel
? (0, lit_html_1.html) `<label>${this.config.variantLabel}:</label>`
: ''}
${(0, repeat_js_1.repeat)(variantKeys, variantKey => variantKey, variantKey => (0, lit_html_1.html) `
<button
?disabled=${this.variant !== variantKey &&
this.fields &&
!this.fields.isClean}
class="selective__variant__variant ${this.variant === variantKey
? 'selective__variant__variant--selected selective__button--primary'
: ''}"
data-variant=${variantKey}
=${this.handleVariantClick.bind(this)}
>
<span>${variants[variantKey].label || variantKey}</span>
</button>
`)}
${this.variant
? (0, lit_html_1.html) `<div
class="selective__variant__clear"
data-tip="Clear"
=${this.handleVariantClear.bind(this)}
>
<span class="material-icons">clear</span>
</div>`
: ''}
</div>`;
}
/**
* Template for rendering the field wrapper.
*
* @param editor Selective editor used to render the template.
* @param data Data provided to render the template.
*/
templateWrapper(editor, data) {
// Need to ensure the fields exists before we check for the clean status.
this.ensureFields();
return super.templateWrapper(editor, data);
}
get value() {
if (!this.fields) {
return this.originalValue;
}
return (0, lodash_merge_1.default)({}, this.originalValue, this.fields.value, {
_variant: this.variant,
});
}
}
exports.VariantField = VariantField;
//# sourceMappingURL=variant.js.map