Issue #2733Opened April 23, 2020by randohinn1 reactions

[Question]: Seeing weird behaviours when implementing grapes on my site

Question

I'm trying out a very simplistic implementation of grapes.

import 'grapesjs/dist/css/grapes.min.css';
import grapesjs from 'grapesjs';

let blockElements = [];

const files = require.context('./blocks', true, /\.js$/i)
files.keys().map(key => blockElements.push(require('./blocks/'+key.split('./')[1]).default));

window.editor = grapesjs.init({
  // Indicate where to init the editor. You can also pass an HTMLElement
  container: '#gjs',
  // Get the content for the canvas directly from the element
  // As an alternative we could use: `components: '<h1>Hello World Component!</h1>'`,
  fromElement: true,
  
  // Disable the storage manager for the moment
  storageManager: false,
  // Avoid any default panel
  panels: { defaults: [{
    id: 'panel-switcher',
    el: '.panel__switcher',
    buttons: [{
      id: 'show-blocks',
      active: true,
      label: 'Blocks',
      command: 'show-blocks',
      togglable: false,
    }, {
      id: 'show-layers',
      active: false,
      label: 'Layers',
      command: 'show-layers',
      // Once activated disable the possibility to turn it off
      togglable: false,
    }, {
      id: 'show-style',
      active: false,
      label: 'Styles',
      command: 'show-styles',
      // Once activated disable the possibility to turn it off
      togglable: false,
    }
  ],
}]},
blockManager: {
  appendTo: '.blocks-container',
  blocks: blockElements,
},
layerManager: {
  appendTo: '.layers-container',
},
selectorManager: {
  appendTo: '.styles-container'
},
styleManager: {
  appendTo: '.styles-container',
  sectors: [{
    name: 'Dimension',
    open: false,
    // Use built-in properties
    buildProps: ['width', 'height', 'padding', 'margin'],
    // Use `properties` to define/override single property
    properties: [
      {
        // Type of the input,
        // options: integer | radio | select | color | slider | file | composite | stack
        type: 'integer',
        name: 'Width', // Label for the property
        property: 'width', // CSS property (if buildProps contains it will be extended)
        units: ['px', '%', 'vw'], // Units, available only for 'integer' types
        defaults: 'auto', // Default value
        min: 0, // Min value, available only for 'integer' types
      },
      {
        // Type of the input,
        // options: integer | radio | select | color | slider | file | composite | stack
        type: 'integer',
        name: 'Height', // Label for the property
        property: 'height', // CSS property (if buildProps contains it will be extended)
        units: ['px', '%', 'vh'], // Units, available only for 'integer' types
        defaults: 'auto', // Default value
        min: 0, // Min value, available only for 'integer' types
      }
    ]
  },{
    name: 'Extra',
    open: false,
    buildProps: ['background', 'box-shadow', 'custom-prop'],
    properties: [
      {
        id: 'custom-prop',
        name: 'Custom Label',
        property: 'font-size',
        type: 'select',
        defaults: '32px',
        // List of options, available only for 'select' and 'radio'  types
        options: [
          { value: '12px', name: 'Tiny' },
          { value: '18px', name: 'Medium' },
          { value: '32px', name: 'Big' },
        ],
      }
    ]
  }]
},
});

const panelManager = editor.Panels;
editor.Commands.add('show-layers', {
  getRowEl(editor) { return editor.getContainer().closest('.editor-row'); },
  getLayersEl(row) { return row.querySelector('.layers-container') },
  
  run(editor, sender) {
    const lmEl = this.getLayersEl(this.getRowEl(editor));
    lmEl.style.display = '';
  },
  stop(editor, sender) {
    const lmEl = this.getLayersEl(this.getRowEl(editor));
    lmEl.style.display = 'none';
  },
});

editor.Commands.add('show-blocks', {
  getRowEl(editor) { return editor.getContainer().closest('.editor-row'); },
  getLayersEl(row) { return row.querySelector('.blocks-container') },
  
  run(editor, sender) {
    const lmEl = this.getLayersEl(this.getRowEl(editor));
    lmEl.style.display = '';
  },
  stop(editor, sender) {
    const lmEl = this.getLayersEl(this.getRowEl(editor));
    lmEl.style.display = 'none';
  },
});

editor.Commands.add('show-styles', {
  getRowEl(editor) { return editor.getContainer().closest('.editor-row'); },
  getLayersEl(row) { return row.querySelector('.styles-container') },
  
  run(editor, sender) {
    const lmEl = this.getLayersEl(this.getRowEl(editor));
    lmEl.style.display = '';
  },
  stop(editor, sender) {
    const lmEl = this.getLayersEl(this.getRowEl(editor));
    lmEl.style.display = 'none';
  },
});

//panelManager.addPanel();

And the only block required by the automatic require at the end is:

export default {
    'id': 'full-height-section',
    'label': 'Full height section',
    'content': `
        <section data-gjs-type="default" class="w-full h-full bg-red-500">
        </section>
    `
}

Having two issues and a question:

  1. Removing a class from the style editor, wipes the rest of the style...
  2. Adding a second block, after changing the first block's properties.. does not add an unstyled block, it duplicates the already existing one
  3. Is there a way to mark a block as non-nestable' eg, it can only be on the top layer?

What could I do to fix these up?

Answers (3)

Ju99ernautApril 26, 20201 reactions

Hi @randohinn,

  1. I assume removing the class isn't wiping the style but it removes the styles associated with that class from the block, try adding back the class and see if the styles come back
  2. By default if a block has a class, all the style properties you edit are added to the class,

This is indicated by the color of the labels on the style properties.

• so the other blocks you add with that class will
also have the same changes. If you want to apply styles to a single block you have to disable the classes first.

To ensure properties you change are only applied to the block you're editing by default add this to your config

window.editor = grapesjs.init({
   //...
   selectorManager : { componentFirst: true},
   //...
});
  1. I think you'll have to define a new component for that. Take a look at grapesjs-plugin-forms for reference. The blocks in the forms category are made such that they can only be dropped inside a form block.
arretnetApril 24, 20200 reactions

Hi, I've the same issue since this morning. Yesterday, and previous days all was right.

Best regards

arretnetApril 24, 20200 reactions

Sorry, nothing is wrong. I've made a modification on a component generating the issue

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.