UNPKG

@silexlabs/grapesjs-data-source

Version:
256 lines 10.2 kB
"use strict"; /* * Silex website builder, free/libre no-code tool for makers. * Copyright (c) 2023 lexoyo and Silex Labs foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PropertiesEditor = void 0; const lit_1 = require("lit"); const ref_js_1 = require("lit/directives/ref.js"); const decorators_js_1 = require("lit/decorators.js"); require("./state-editor"); const defaultStyles_1 = require("./defaultStyles"); const token_1 = require("../model/token"); const types_1 = require("../types"); const state_1 = require("../model/state"); const utils_1 = require("../utils"); /** * Editor for selected element's properties * * Usage: * * ``` * <properties-editor disabled> * <style> / * Custom styles * / </style> * </properties-editor> * ``` * */ class PropertiesEditor extends lit_1.LitElement { constructor() { super(...arguments); this.disabled = false; this.defaultFixed = false; this.inputs = { innerHTML: undefined, condition: undefined, condition2: undefined, __data: undefined, }; this.editor = null; this.redrawing = false; } setEditor(editor) { if (this.editor) { console.warn('property-editor setEditor already set'); return; } this.editor = editor; // Update the UI when a page is added/renamed/removed this.editor.on('page', () => this.requestUpdate()); // Update the UI on component selection change this.editor.on('component:selected', () => this.requestUpdate()); // Update the UI on component change this.editor.on('component:update', () => this.requestUpdate()); } render() { var _a; super.render(); this.redrawing = true; const selected = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.getSelected(); const head = (0, lit_1.html) ` <style> ${defaultStyles_1.PROPERTY_STYLES} </style> <slot></slot> `; const empty = (0, lit_1.html) ` ${head} <p class="ds-empty">Select an element to edit its properties</p> `; if (!this.editor || this.disabled) { this.resetInputs(); this.redrawing = false; return (0, lit_1.html) ``; } if (!selected || selected.get('tagName') === 'body') { this.resetInputs(); this.redrawing = false; return empty; } const result = (0, lit_1.html) ` ${head} <section class="ds-section"> <div> <div class="gjs-traits-label"> Properties <details class="ds-states__help"> <summary>Help</summary> <div class="ds-states__help--tooltip"> Elements properties are expressions that can replace the HTML attributes of the element or it's whole content (innerHTML). <a target="_blank" href="https://docs.silex.me/en/user/cms-concepts#properties">Learn more about element properties</a> </div> </details> </div> </div> <main> ${[ { label: 'HTML content', name: types_1.Properties.innerHTML, publicState: false }, ].map(({ label, name, publicState }) => this.renderStateEditor(selected, label, name, publicState))} </main> </section> <section class="ds-section"> <main> ${this.renderStateEditor(selected, 'Visibility Condition', types_1.Properties.condition, false)} <div> <span>... is</span> <select class="ds-visibility__condition-operator" @change=${(e) => { const select = e.target; const value = select.value; if (!value) throw new Error('Selection required for operator select element'); selected.set('conditionOperator', value); this.requestUpdate(); }} > </div> ${Object.values(types_1.UnariOperator) .concat(Object.values(types_1.BinaryOperator)) .map(operator => (0, lit_1.html) ` <option value="${operator}" .selected=${selected.get('conditionOperator') === operator} >${operator}</option> `)} </select> ${this.renderStateEditor(selected, '', types_1.Properties.condition2, false, false, selected.has('conditionOperator') && Object.values(types_1.BinaryOperator).includes(selected.get('conditionOperator')))} </main> </section> <section class="ds-section"> <main> ${this.renderStateEditor(selected, 'Loop Data', types_1.Properties.__data, false, true)} </main> </section> `; this.redrawing = false; return result; } resetInputs() { this.inputs = { innerHTML: undefined, condition: undefined, condition2: undefined, __data: undefined, }; } renderStateEditor(selected, label, name, publicState, hideLoopData = false, visible = true) { return (0, lit_1.html) ` <state-editor .style=${visible ? '' : 'display: none;'} .selected=${selected} .editor=${this.editor} id="${name}" name=${name} default-fixed=${this.defaultFixed} ?hide-loop-data=${hideLoopData} ${(0, ref_js_1.ref)(el => { // Get the stateEditor ref if (el) { // Set the editor - we could do this only once const stateEditor = el; // Store the stateEditor ref and the component it is representing if (!this.inputs[name]) { this.inputs[name] = { stateEditor, selected: undefined, // clear the selected component so that we update the data }; } } // Finally update the data if (this.inputs[name]) { const stateEditorFinally = this.inputs[name].stateEditor; this.redrawing = true; try { stateEditorFinally.data = this.getTokens(selected, name, publicState); } catch (e) { console.error('Error setting data', e); stateEditorFinally.data = [(0, utils_1.getFixedToken)(`Error setting data: ${e}`)]; } this.redrawing = false; // Store the selected component this.inputs[name].selected = selected; } })} @change=${() => this.onChange(selected, name, publicState)} ?disabled=${this.disabled} > <label slot="label">${label}</label> </state-editor> `; } onChange(component, name, publicState) { const { stateEditor } = this.inputs[name]; if (this.redrawing) return; if (name === types_1.Properties.__data) { // Handle the case when data is empty (after clearing) if (stateEditor.data.length === 0) { (0, state_1.setState)(component, name, { expression: [], }, publicState); } else { (0, state_1.setState)(component, name, { expression: stateEditor.data.slice(0, -1).concat(Object.assign(Object.assign({}, stateEditor.data[stateEditor.data.length - 1]), { previewIndex: 0 })), }, publicState); } } else { (0, state_1.setState)(component, name, { expression: stateEditor.data, }, publicState); } } getTokens(component, name, publicState) { const state = (0, state_1.getState)(component, name, publicState); if (!state || !state.expression) return []; return state.expression .filter(token => token && typeof token === 'object' && token.type) // Filter out invalid tokens .map(token => (0, token_1.fromStored)(token, component.getId())); } } exports.PropertiesEditor = PropertiesEditor; __decorate([ (0, decorators_js_1.property)({ type: Boolean }), __metadata("design:type", Object) ], PropertiesEditor.prototype, "disabled", void 0); __decorate([ (0, decorators_js_1.property)({ type: Boolean, attribute: 'default-fixed' }), __metadata("design:type", Object) ], PropertiesEditor.prototype, "defaultFixed", void 0); if (!window.customElements.get('properties-editor')) { window.customElements.define('properties-editor', PropertiesEditor); } //# sourceMappingURL=properties-editor.js.map