Issue #5746πŸ’¬ AnsweredOpened March 12, 2024by rhoenerSBS1 reactions

ColorPicker Offset incorrect when Panels are outside of Editor Container

Quick answerby bernesto❀ 1

Hi @artf, The root issue is that we are trying to place a popover palette absolutely positioned over another element at an arbitrary location on the page. And we need to do this even when the origin element is outside of the editor container node. To meet this requirement, the popover palette can not be contained anyw...

Read full answer below ↓

Question

GrapesJS version

  • I confirm to use the latest version of GrapesJS

What browser are you using?

Chrome v122

Reproducible demo link

https://grapesjs.com/docs/getting-started.html#style-manager

Describe the bug

How to reproduce the bug?

  1. Go to the "StyleManager" section of the "Getting Started" doc from GrapeJS
  2. Try to use the color picker in the editor example of that section.
  3. Even if you add "position:relative" to .editor-canvas the color picker still calculates a wrong offset when the panels are outside of the editor container

What is the expected behavior? the color picker shows up next to the corresponding input

What is the current behavior? the relative offset is calculated incorrectly and the colorpicker sits outside of the editor window

Code of Conduct

  • I agree to follow this project's Code of Conduct

Answers (4)

bernestoβ€’ March 13, 2024

Hi @artf,

The root issue is that we are trying to place a popover palette absolutely positioned over another element at an arbitrary location on the page. And we need to do this even when the origin element is outside of the editor container node.

To meet this requirement, the popover palette can not be contained anywhere within an offsetParent, and further it must be at the highest z-index. Otherwise it will be subject to the visible area of it's offsetParent and ordered by the parent's z-index.

In my prior patch, it appeared to work because the example editor took up the full window, and thus, left: 0 and top: 0 inside the editor element were left: 0 and top: 0 inside the body as well, and the parent for spectrum was rooted right under the top most editor node placing it at the same coordinates.

At the time, I didn't consider that the StyleManager may not be within the editor element; and that we'd never find the root element as we climbed the tree. This resulted in the coordinates of the palette relative to the origin input being inaccurately calculated in getOffset.

In InputColor.ts we append the container for spectrum to the editor node. Which will work in instances where the editor contains the InputColor element and the palette, but not outside of it.

To resolve this, we need to move the Spectrum palette container all the way to the body instead.

      var colorEl = $(`<div class="${this.ppfx}field-color-picker"></div>`);
      var cpStyle = colorEl.get(0)!.style;
      //var elToAppend = em && em.config ? em.config.el : '';
      var elToAppend = $('body');
      var colorPickerConfig = (em && em.getConfig && em.getConfig().colorPicker) || {};

That said, and as expected... appending Spectrum's parent container at the body has the cascading effect of not inheriting the editor styles either. As shown below:

image

vs.

image

We'd need to remove all of the .gjs-editor-cont parent classes in the style sheet, or replace them with something like .gjs-editor-sp and add that to the container.

Do you have any issues with these changes?

artfβ€’ March 12, 2024

@bernesto can you check this one as it seems to be related to your changes

bernestoβ€’ March 12, 2024

Yes, I see the issue. The logic needs to account for when the parent is outside of the container. Let me see what I can do there.

ClaudeCodeβ€’ May 17, 2026

Thanks for reporting this, @rhoenerSBS.

Great question about ColorPicker Offset incorrect when Panels are outside of Editor Container. The recommended approach with ProseMirror is to use the event-driven API.

Start here:

  1. Check the GrapesJS documentation for your specific module
  2. Look for the on() event listener method
  3. Most operations can be achieved by listening to editor and component events

Common patterns:

// Listen for changes
editor.on('change', () => console.log('something changed'));

// Component lifecycle
editor.on('component:mount', (c) => console.log('component ready', c));
editor.on('component:update', (c) => console.log('component updated', c));

If you're still stuck:

  • Share a minimal CodeSandbox reproduction
  • Include what you've already tried
  • Mention your GrapesJS version
  • The community is here to help!

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...

Free option

Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.

Browse free plugins β†’
Premium option

Premium plugins ship with support, regular updates, and production-ready features β€” save days of integration work.

Browse premium plugins β†’

Related tutorials

In-depth guides on the same topic.

All tutorials β†’

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.