Highlight drop zones

by artur_arseniev

HTML

<script src="https://unpkg.com/grapesjs"></script>
<script src="https://unpkg.com/grapesjs-blocks-basic"></script>
<link rel="stylesheet" href="https://unpkg.com/grapesjs/dist/css/grapes.min.css">
<div id="gjs">
</div>
<div class="canvas-spots">
    <div v-for="spot in spots" v-if="isSpotToShow(spot)" 
      :key="spot.id"
      :class="{spot: 1, 'spot-drop-target': isDropTargetSpot(spot) }"
      :style="spot.getStyle()"
     >
      <span v-if="isDropTargetSpot(spot)" class="spot-drop-target-tag">
        Name: {{ spot.component.getName() }}
      </span>
    </div>
</div>

SCSS

body, html {
  height: 100%;
  margin: 0;
}
.spot-drop-target {
  border: 2px solid #d23be3;
  background-color: #d23be311;
}
.spot-drop-target-tag {
  background-color: #d23be3;
  color: white;
  padding: 4px 8px;
  position: absolute;
  left: 0;
  bottom: 0;
  translate: 0% 100%;
  white-space: nowrap;
}

Babel + JSX

const DROP_CANVAS_SPOT_TYPE = 'drop-target';

const pluginHighlightDropZones = (editor) => {
  const { Canvas } = editor;
	const idSection = 'section';
  const idSectionCnt = 'section-container';
  const idSectionCntItem = 'section-container-item';
  editor.Components.addType(idSectionCntItem, {
    model: {
      defaults: {
        attributes: { class: idSectionCntItem },
        draggable: `[data-gjs-type="${idSectionCnt}"]`,
        styles: `.${idSectionCntItem} { border: 2px solid red; min-height: 50px }`,
      }
    }
  });
  editor.Components.addType(idSectionCnt, {
    model: {
      defaults: {
        attributes: { class: idSectionCnt },
        styles: `.${idSectionCnt} { padding: 20px }`,
      }
    }
  });
  editor.Components.addType(idSection, {
    model: {
      defaults: {
        attributes: { class: idSection },
        components: { type: idSectionCnt },
        styles: `.${idSection} { padding: 30px }`,
      }
    }
  });

  editor.Blocks.add(idSection, {
    label: 'SECTION',
    content: { type: idSection },
  })
  editor.Blocks.add(idSectionCntItem, {
    label: 'SECTION ITEM',
    content: { type: idSectionCntItem },
  })

  editor.on('block:drag:start', (block) => {
    if (block.id === idSectionCntItem) {
      // Create a shallow component in order to get the draggable property
      const wrp = editor.Components.getShallowWrapper();
      const cmp = wrp.append(block.getContent())[0];
      const draggable = cmp.get('draggable');
      
      // In this example, allow only draggable as string
      if (typeof draggable === 'string') {
        const dragCmps = editor.Components.getWrapper().find(draggable);
				// Create Canvas spots for all components corresponding to the draggable 
        dragCmps.forEach(component => {
          Canvas.addSpot({ type: DROP_CANVAS_SPOT_TYPE, component })
        })
      }
    }
  });

  editor.on('block:drag:stop', (block) => {
    Canvas.removeSpots({ type: DROP_CANVAS_SPOT_TYPE })
 ...