Replies: 3 comments 5 replies
-
There is an example here showing you exactly what you're asking. |
Beta Was this translation helpful? Give feedback.
2 replies
-
Hi, this is my code in React. This is the code from the documentation, I converted it to Next.js React. Hope it helps import { useEditor } from "@grapesjs/react";
import { CanvasSpot, Component } from "grapesjs";
import { useEffect, useState } from "react";
import './canvas-spot.css';
const CanvasSpots = () => {
const editor = useEditor();
const { Canvas } = editor;
const [spots, setSpots] = useState<CanvasSpot[]>([]);
const customSpotType = 'my-text-spot';
useEffect(() => {
const onCanvasSpot = () => {
setSpots(Canvas.getSpots());
};
const onComponentToggled = (component: Component) => {
// Remove all spots related to our custom type
Canvas.removeSpots({ type: customSpotType });
if (component === editor.getSelected() && component.is('text')) {
Canvas.addSpot({ type: customSpotType, component });
}
};
const onEditorReady = () => {
// Once the editor is ready, append our custom elements to GrapesJS spots container
Canvas.getSpotsEl()?.appendChild(document.querySelector('.canvas-spots') as HTMLElement);
console.log('Canvas spots container appended to GrapesJS spots container');
};
// Catch-all event for any spot update
editor.on('canvas:spot', onCanvasSpot);
// Add a new custom canvas spot for the last selected text component.
editor.on('component:toggled', onComponentToggled);
// Editor ready event
editor.onReady(onEditorReady);
// Cleanup listeners on unmount
return () => {
editor.off('canvas:spot', onCanvasSpot);
editor.off('component:toggled', onComponentToggled);
// editor.onReady(onEditorReady);
};
}, [customSpotType]);
const onBtnAdd = () => {
const selected = editor.getSelected();
if (!selected) return;
const parent = selected.parent();
if (parent) {
parent.append(
{ type: 'text', components: 'New text component' },
{ at: selected.index() + 1 }
);
}
};
const isTextSelectedSpot = (spot: CanvasSpot) => {
return spot.type === customSpotType;
};
const isHoverSpot = (spot: CanvasSpot) => {
return spot.type === 'hover';
};
const isSpotToShow = (spot: CanvasSpot) => {
return isTextSelectedSpot(spot) || isHoverSpot(spot);
};
return (
<div className="canvas-spots">
{spots.map((spot) => (
isSpotToShow(spot) && (
<div
key={spot.id}
className={`spot ${isHoverSpot(spot) ? 'spot-hover' : ''}`}
style={spot.getStyle() as any}
>
{isTextSelectedSpot(spot) && (
<button className="spot-text-btn" type="button" onClick={onBtnAdd}>
+ Add
</button>
)}
{isHoverSpot(spot) && (
<span className="spot-hover-tag">
Name: {spot.component?.getName()}
</span>
)}
</div>
)
))}
</div>
);
};
export default CanvasSpots; the CSS should be .spot-text-btn {
background-color: #3b97e3;
border: none;
color: white;
padding: 4px 8px;
border-radius: 3px;
cursor: pointer;
position: absolute;
left: 50%;
bottom: 0;
translate: -50% 120%;
pointer-events: auto;
}
.spot-hover {
border: 2px solid #d23be3;
}
.spot-hover-tag {
background-color: #d23be3;
color: white;
padding: 4px 8px;
position: absolute;
left: 0;
bottom: 0;
translate: 0% 100%;
white-space: nowrap;
} |
Beta Was this translation helpful? Give feedback.
1 reply
-
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi there, I want to add a button in between every
<section>
that says (+ Add Section).I know I should be able to do this with Canvas Spots, but I can't get the button to show up.
Beta Was this translation helpful? Give feedback.
All reactions