UNPKG

@silexlabs/silex

Version:

Free and easy website builder for everyone.

115 lines (108 loc) 3.5 kB
/* * 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/>. */ import {html, render} from 'lit-html' import {map} from 'lit-html/directives/map.js' // constants const pluginName = 'semantic' const tags = [ 'DIV', 'P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'SPAN', 'MAIN', 'ASIDE', 'SECTION', 'ADDRESS', 'ARTICLE', 'BUTTON', 'NAV', 'HEADER', 'FOOTER', 'DETAILS', 'SUMMARY', 'PRE', 'BLOCKQUOTE', ] // plugin code export const semanticPlugin = (editor, opts) => { // Add the new trait to all component types editor.DomComponents.getTypes().map(type => { editor.DomComponents.addType(type.id, { model: { defaults: { traits: [ // Keep the type original traits ...editor.DomComponents.getType(type.id).model.prototype.defaults.traits, // Add the new trait { label: 'Tag name', type: 'tag-name', name: 'tag-name', }, ] } } }) }) function doRender(el: HTMLElement, tagName: string) { const tagsWithCurrent = tags.includes(tagName.toUpperCase()) ? tags : tags.concat(tagName.toUpperCase()) render(html` <label for="semantic__select" class="gjs-one-bg silex-label">Type</label> <select id="semantic__select" @change=${event => doRender(el, event.target.value)}> ${map<string>(tagsWithCurrent, tag => html` <option value="${tag}" ?selected=${tagName.toUpperCase() === tag}>${tag}</option> `)} </select> `, el) } function doRenderCurrent(el: HTMLElement) { doRender(el, editor.getSelected()?.get('tagName') || '') } // Add semantic traits // inspired by https://github.com/olivmonnier/grapesjs-plugin-header/blob/master/src/components.js editor.TraitManager.addType('tag-name', { createInput({ trait }) { // Create a new element container and add some content const el = document.createElement('div') // update the UI when a page is added/renamed/removed editor.on('page', () => doRenderCurrent(el)) doRenderCurrent(el) // this will be the element passed to onEvent and onUpdate return el }, // Update the component based on UI changes // `elInput` is the result HTMLElement you get from `createInput` onEvent({ elInput, component, event }) { const value = elInput.querySelector('#semantic__select').value if(component.get('tagName').toUpperCase() === value.toUpperCase()){ // Already done } else { component.set('tagName', value) } }, // Update UI on the component change onUpdate({ elInput, component }) { const tagName = component.get('tagName') doRender(elInput, tagName) }, }) }