import {html, render} from 'lit-html'
import {map} from 'lit-html/directives/map.js'
import grapesjs from 'grapesjs/dist/grapes.min.js'
// constants
const pluginName = 'semantic'
const tags = [
'DIV',
'P',
'H1',
'H2',
'H3',
'H4',
'H5',
'H6',
'SPAN',
'MAIN',
'ASIDE',
'SECTION',
'ADDRESS',
'ARTICLE',
'NAV',
'HEADER',
'FOOTER',
'DETAILS',
'SUMMARY',
'PRE',
'BLOCKQUOTE',
]
// plugin code
export const semanticPlugin = grapesjs.plugins.add(pluginName, (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',
},
]
}
}
})
})
function doRender(el: HTMLElement, tagName: string) {
const tagsWithCurrent = tags.includes(tagName.toUpperCase()) ? tags : tags.concat(tagName.toUpperCase())
render(html`
`, 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)
},
})
})