UNPKG

grapesjs-plugin-toolbox

Version:
363 lines (341 loc) 10.1 kB
import { gridCompId, gridChildId } from './consts'; import { store } from './utils'; export default (editor, opts = {}) => { const domc = editor.DomComponents; const pfx = editor.Config.stylePrefix; const { gridComponent, cellComponent, gridClass, gridCellClass, cellItemClass } = opts; const idTrait = { name: 'id', label: 'Id' }; const titleTrait = { name: 'title', label: 'Title' }; const privateCls = [`.${gridClass}`, `.${cellItemClass}`, `.${gridCellClass}`]; editor.on( 'selector:add', selector => privateCls.indexOf(selector.getFullName()) >= 0 && selector.set('private', 1) ); const showGrid = (ed) => { if (!ed.getSelected().get('auto')) { const st = ed.Grid.selected.get('store'); if (!editor.Grid.container?.length) editor.Grid.render(`#${pfx}tools`, st); ed.Grid.visible = !ed.Grid.visible; ed.Grid.update(st); } } const addCellTrait = { name: 'addCell', type: 'button', full: true, text: 'Add Cell', command: editor => { const comp = editor.getSelected(); comp && comp.components().add(`<div data-${pfx}name="cell-item" class="${cellItemClass}" data-${pfx}resizable='${JSON.stringify({ tl: 0, tc: 0, tr: 0, cl: 0, cr: 1, bl: 0, br: 0, bc: 0, keyWidth: 'flex-basis', minDim: 1, step: 0.2, currentUnit: 1 })}'></div>`); const cc = editor.Css; cc.getRule(`.${cellItemClass}`) || cc.setRule(`.${cellItemClass}`, { 'min-height': '75px', 'flex-grow': 1, 'flex-basis': '100%' }); } } const autoTrait = { name: 'auto', label: 'Auto Fill', type: 'checkbox', changeProp: 1, } const columnsTrait = { name: 'columns', label: 'Columns', type: 'number', changeProp: 1, placeholder: '6', min: 1, } const rowsTrait = { name: 'rows', label: 'Rows', type: 'number', changeProp: 1, placeholder: '6', min: 1, } const columnGapTrait = { name: 'columngap', label: 'Column Gap(px)', type: 'number', changeProp: 1, placeholder: '0', min: 0, } const rowGapTrait = { name: 'rowgap', label: 'Row Gap(px)', type: 'number', changeProp: 1, placeholder: '0', min: 0, } const minTrait = { name: 'min', label: 'Min(px)', type: 'number', changeProp: 1, placeholder: '0', min: 1, } const toggleTrait = { name: 'toggle', label: 'Guides', type: 'button', full: true, text: 'Toggle', command: e => showGrid(e) } const clearTrait = { name: 'clear', label: 'Cells', type: 'button', full: true, text: 'Clear', command: editor => editor.getSelected().components.reset() } const resetTrait = { name: 'reset', label: 'Guides', type: 'button', full: true, text: 'Reset', command: editor => { const store = editor.Grid.selected.get('store'); store.mutations.resetGrid(store.state); editor.Grid.updateChildren(store); } } const updateTrait = { name: 'update', label: 'Cells', type: 'button', full: true, text: 'Update', command: editor => { //Generate html and css const sel = editor.getSelected(); const { state, getters } = sel.get('store'); let grid = state.auto ? Array(state.rows * state.columns).fill().map(i => { return `<div data-${pfx}type="${gridChildId}"></div>` }).join("") : state.childarea.map((area, i) => { return `<div data-${pfx}type="${gridChildId}" class="${sel.getId() + '-div' + i}"></div>` }).join(""); const css = state.childarea.map((area, i) => { return `.${sel.getId() + '-div' + i}{grid-area:${area}}` }).join(""); !sel.components().length > 0 && sel.components().reset(grid); editor.addStyle(generateMedia(css)); (editor.Grid.visible = false) || (editor.Grid.getEl().style.display = 'none'); sel.addStyle({ 'grid-template-columns': getters.colTemplate(state) }); } } const generateMedia = (css) => { const deviceId = editor.getDevice(); const device = editor.Devices.get(deviceId); if (device.get('widthMedia')) { return `@media (${editor.Config.mediaCondition}: ${device.get('widthMedia')}){ ${css} }` } return css; } const toConfigState = (state) => { return state && Object.keys(state).length ? { state } : undefined; } domc.addType(gridChildId, { model: { defaults: { icon: '<i class="fa fa-square-o"></i>', traits: [idTrait, titleTrait, addCellTrait], }, init() { const cc = editor.Css; this.get('classes').pluck('name').indexOf(gridCellClass) < 0 && this.addClass(gridCellClass); cc.getRule(`.${gridCellClass}`) || cc.setRule(`.${gridCellClass}`, { display: 'flex', 'justify-content': 'flex-start', 'align-items': 'stretch', padding: '5px' }); }, ...cellComponent } }); const toolbar = [{ attributes: { class: 'fa fa-table' }, command: e => showGrid(e) }, { attributes: { class: 'fa fa-arrow-up' }, command: e => e.runCommand('core:component-exit', { force: 1 }) }, { attributes: { class: 'fa fa-arrows gjs-no-touch-actions', draggable: true }, command: 'tlb-move' }, { attributes: { class: 'fa fa-clone' }, command: 'tlb-clone' }, { attributes: { class: 'fa fa-trash-o' }, command: 'tlb-delete' }] domc.addType(gridCompId, { model: { defaults: { // Default props icon: '<i class="fa fa-table"></i>', toolbar, traits: [ idTrait, titleTrait, autoTrait, minTrait, columnsTrait, rowsTrait, columnGapTrait, rowGapTrait, toggleTrait, resetTrait, clearTrait, updateTrait ], resizable: { tl: 0, tc: 0, tr: 0, cl: 0, cr: 0, bl: 0, br: 0, minDim: 5 }, min: 200, auto: false }, init() { const cc = editor.Css; const storedState = this.get('store')?.state; const st = { ...store(opts), ...toConfigState(storedState || {}) }; !storedState && st.mutations.initialArrIndex(st.state, ''); this.set('rows', st.state.rows); this.set('columns', st.state.columns); this.set('rowgap', st.state.rowgap); this.set('columngap', st.state.columngap); this.set('store', st); this.addStyle({ 'grid-template-rows': st.getters.rowTemplate(st.state), 'grid-template-columns': st.getters.colTemplate(st.state), }); this.get('classes').pluck('name').indexOf(gridClass) < 0 && this.addClass(gridClass); cc.getRule(`.${gridClass}`) || cc.setRule(`.${gridClass}`, { display: 'grid', padding: '10px', height: '95%', width: '100%', }); this.on("change:auto", this.updateAuto); this.on("change:rows", this.updateRows); this.on("change:columns", this.updateColumns); this.on("change:rowgap", this.updateRowgap); this.on("change:columngap", this.updateColumngap); this.on("change:min", this.updateMin); this.on("change:status", this.onStatusChange); }, updateRows() { const rows = parseInt(this.get('rows')); const store = this.get('store'); const payload = { newVal: rows, oldVal: store.state.rows, direction: "rowArr" }; store.mutations.updateRows(store.state, rows); store.mutations.adjustArr(store.state, payload); editor.Grid.update(store); this.addStyle({ 'grid-template-rows': store.getters.rowTemplate(store.state) }); }, updateColumns() { const columns = parseInt(this.get('columns')); const store = this.get('store'); const payload = { newVal: columns, oldVal: store.state.columns, direction: "colArr" }; store.mutations.updateColumns(store.state, columns); store.mutations.adjustArr(store.state, payload); editor.Grid.update(store); this.addStyle({ 'grid-template-columns': store.getters.colTemplate(store.state) }); }, updateRowgap() { const rowgap = this.get('rowgap'); const store = this.get('store'); store.mutations.updateRowGap(store.state, parseInt(rowgap)); editor.Grid.updateChildren(store); this.addStyle({ 'grid-row-gap': `${rowgap}px` }); }, updateColumngap() { const columngap = this.get('columngap'); const store = this.get('store'); store.mutations.updateColumnGap(store.state, parseInt(columngap)); editor.Grid.updateChildren(store); this.addStyle({ 'grid-column-gap': `${columngap}px` }); }, updateMin() { const min = parseInt(this.get('min')); const store = this.get('store'); store.mutations.updateMin(store.state, min); }, updateAuto() { const auto = !!this.get('auto'); const store = this.get('store'); store.mutations.updateAuto(store.state, auto); if (auto) (editor.Grid.visible = false) || (editor.Grid.getEl().style.display = 'none'); }, onStatusChange() { const status = this.get('status'); if (!editor.Grid.container?.length) editor.Grid.render(`#${pfx}tools`, this.get('store')); if (status === 'selected') editor.Grid.select(editor.getSelected()); else (editor.Grid.visible = false) || (editor.Grid.getEl().style.display = 'none'); }, ...gridComponent } }); };