@blinkk/editor
Version:
Structured content editor with live previews.
140 lines • 5.5 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.ExampleFieldField = void 0;
const selective_edit_1 = require("@blinkk/selective-edit");
const deepClean_1 = require("../../utility/deepClean");
const prioritySort_1 = require("../../utility/prioritySort");
const js_yaml_1 = __importDefault(require("js-yaml"));
class ExampleFieldField extends selective_edit_1.Field {
constructor(types, config, globalConfig, fieldType = 'exampleField') {
super(types, config, globalConfig, fieldType);
this.config = config;
// Copy the config to show the original before the field makes changes.
this.originalFieldConfig = Object.assign({}, config.field);
this.originalFieldConfig.validation = [
...(this.originalFieldConfig.validation || []),
];
if (!this.originalFieldConfig.validation.length) {
this.originalFieldConfig.validation = undefined;
}
this.cleaner = new deepClean_1.DeepClean({
removeKeys: (this.config.cleanerKeys || []).concat([
'isGuessed',
'parentKey',
]),
});
}
handleExpandClick(evt) {
evt.preventDefault();
evt.stopPropagation();
this.isExpanded = true;
this.render();
}
get isClean() {
return this.field?.isClean === undefined ? true : this.field?.isClean;
}
get isValid() {
return this.field?.isValid === undefined ? true : this.field?.isValid;
}
/**
* No original value update for the example.
*
* @param editor Selective editor used to render the template.
* @param data Data provided to render the template.
*/
template(editor, data) {
return this.templateWrapper(editor, data);
}
/**
* Show the field, but also show the config that is used to
* generate the field.
*
* @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
templateStructure(editor, data) {
if (!this.field) {
this.field = this.types.fields.newFromKey(this.config.field.type, this.types, this.config.field, this.globalConfig);
}
if (!this.isExpanded) {
return selective_edit_1.html `${this.field?.template(editor, data) || ''}
<div
class="le__clickable selective__example_field__expand"
=${this.handleExpandClick.bind(this)}
>
Show config…
</div>`;
}
return selective_edit_1.html `${this.field?.template(editor, data) || ''}
<div class="selective__example_field__code">
<pre><code>${selective_edit_1.unsafeHTML(formatCodeSample(js_yaml_1.default.dump(replaceProjectType(this.cleaner.clean(this.originalFieldConfig)), {
noArrayIndent: true,
noCompatMode: true,
sortKeys: prioritySort_1.createPriorityKeySort(['type', 'key', 'label']),
})))}</code></pre>
</div>
${this.config.docUrls
? selective_edit_1.html `<div class="selective__example_field__doc_url">
${selective_edit_1.repeat(this.config.docUrls, docUrl => docUrl.label, docUrl => selective_edit_1.html `<a href=${docUrl.url} target="_blank">${docUrl.label}</a>`)}
</div>`
: ''}`;
}
get value() {
return this.field?.value;
}
}
exports.ExampleFieldField = ExampleFieldField;
function formatCodeSample(code) {
code = code.replace(/\</g, '<');
code = code.replace(/\>/g, '>');
const cleanLines = [];
let indentLength = -1;
for (const line of code.split('\n')) {
if (!line.trim()) {
continue;
}
if (indentLength < 0) {
indentLength = line.length - line.trim().length;
}
// Remove the same indent length off all lines based on first line.
cleanLines.push(line.slice(indentLength));
}
return cleanLines.join('\n');
}
/**
* The example page loads all the project type fields at once.
*
* For the example page the field configs for the project type fields
* are prefixed. But when the fields are used in a project type project,
* the field type is not prefixed.
*
* Since we want the code snippet to be copyable for projects, we need
* to clean up the type shown for the code snippet to make it easy for
* developers to copy to their projects as a starting point.
*
* @param fieldConfig Field config with example field configuration.
* @returns Updated field config with correct type.
*/
function replaceProjectType(fieldConfig) {
let isModified = false;
// Amagaki fields.
if (fieldConfig.type.startsWith('amagaki')) {
fieldConfig.type = fieldConfig.type.replace(/^amagaki/, '');
isModified = true;
}
// Grow fields.
if (fieldConfig.type.startsWith('grow')) {
fieldConfig.type = fieldConfig.type.replace(/^grow/, '');
isModified = true;
}
// If modified, lowercase the first letter of the type.
if (isModified && fieldConfig.type.length) {
fieldConfig.type = `${fieldConfig.type[0].toLowerCase()}${fieldConfig.type.slice(1)}`;
}
return fieldConfig;
}
//# sourceMappingURL=exampleField.js.map