GrapesJS / studio

GrapesJS Studio repo for discussion and issue tracking
MIT License
7 stars 0 forks source link

BUG: Padding does not work on some elements (e.g Sections, Text) #7

Open jasontkh opened 2 weeks ago

jasontkh commented 2 weeks ago

What browser are you using?

Firefox

Describe the bug

How to reproduce the bug?

  1. Set the padding of an element
  2. Save the project using "onSave" callback
  3. Load the project using "onLoad" callback or editor.loadData

What is the expected behavior? After save and load the padding remains the same

What is the current behavior? After save and load, the padding is reset to default. The bug happens only on some elements (Section, Text), some are fine (Column, Hero)

Investigation

The bug comes from different css attributes used. Here's a snippet from the saved data:

{
  "tagName": "mj-section",
  "type": "mj-section",
  "style": {
    "text-align": "center",
    "padding": "10px 0px 108px 0px",
    "padding-left": "0px",
    "padding-right": "0px",
    "padding-top": "10px",
    "padding-bottom": "10px"
  },
  "attributes": {
    "text-align": "center",
    "padding": "10px 0px 108px 0px",
    "padding-left": "0px",
    "padding-right": "0px",
    "padding-top": "10px",
    "padding-bottom": "10px",
    "style": "text-align:center;padding:10px 0px 108px 0px;padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;"
  }
...
}

Whenever I change the padding of a Section (yes, Section has a problem, but Columns are fine), then save. 5 CSS attributes are exported: padding and padding-*. While padding contains the right CSS, padding-* contains the default ones. Problem comes when the saved object is loaded again: the loading apparently reads padding-* instead of padding.


Here's my code:

<StudioEditor
    options={{
        licenseKey: '...',
        project: {
            type: 'email',
            id: "an-id"
        },
        identity: {
            id: "an-id"
        },
        assets: {
            storageType: 'cloud'
        },
        storage: {
            type: 'self',
            onSave: async ({ project, editor }: { project: ProjectData, editor: Editor }) => {
                axios.post(....)
            },
            onLoad: async ({ editor }) => {
                editorRef.current = editor;
                return {
                    project: emailTemplateInfo.savedData
                };
            }
        }
    }}
/>

Code of Conduct

jasontkh commented 2 weeks ago

To also share my temporary fix:

basically I try to make sure the padding-* properties sync with the padding property when saving.


const fixComponent = useCallback((component: any) => {
    if (component.style) {
        if (component.style.padding) {
            const parts = component.style.padding.split(' ');
            component.style["padding-top"] = parts[0];
            component.style["padding-right"] = parts[1];
            component.style["padding-bottom"] = parts[2];
            component.style["padding-left"] = parts[3];
        }
    }
    if (component.attributes) {
        if (component.attributes.padding) {
            const parts = component.attributes.padding.split(' ');
            component.attributes["padding-top"] = parts[0];
            component.attributes["padding-right"] = parts[1];
            component.attributes["padding-bottom"] = parts[2];
            component.attributes["padding-left"] = parts[3];

            component.attributes.style = Object.entries(component.attributes).filter(([key, value]) => key !== 'style').map(([key, value]) => `${key}:${value};`).join("");
        }
    }
    if (component.components) {
        component.components.forEach(fixComponent);
    }
}, []);

const onSave = useCallback(async ({ project, editor }: { project: ProjectData, editor: Editor }) => {

    project.pages.forEach((page: any) => {
        page.frames.forEach((frame: any) => {
            const component = frame.component;
            fixComponent(component);
        })
    })

    axios.post(....)
}, [campaignId, fixComponent]);