GrapesJS / grapesjs

Free and Open source Web Builder Framework. Next generation tool for building templates without coding
https://grapesjs.com
Other
22.61k stars 4.09k forks source link

Integrating React components #1970

Closed rodenp closed 5 years ago

rodenp commented 5 years ago

Firstly what a great tool you have here.

I'm sorry if i ask questions that have been asked before. I have tried to read through the documentation and googled posts but am still a bit stuck.

I am like a few people trying to integrate React components into grapesjs.

https://github.com/artf/grapesjs/issues/170 mentions custom render logic. How would i implement custom render logic?

and i found this -> https://www.npmjs.com/package/grapesjs-react which does not contain any actual draggable components that i could see.

Are there any examples that actually have a sample react component that can be dragged onto the canvas?

Can you outline the areas that will need to be addressed when integrating react components.

Thanks again for an awesome project.

artf commented 5 years ago

Hi @rodenp unfortunately at the moment my answer would be the same as before. To create what you're asking you have to write a custom render logic and the only available example is from the MJML preset: https://github.com/artf/grapesjs-mjml/blob/master/src/components/index.js

rodenp commented 5 years ago

Hi Artur,

Thanks for your response.

There is little documentation on rendering and this is a very important and potentially powerful means of creating cross platform applications.

I will look into the code as suggested but before that it would be helpful if you could provide some guidance on rendering and how grapesjs uses it to render to the canvas.

How would i ensure that a component renders once using the most appropriate rendering engine? I need to ensure that for example react nodes are also not rendered outside of react.

regards Peter


From: Artur Arseniev notifications@github.com Sent: Tuesday, 23 April 2019 6:29 AM To: artf/grapesjs Cc: rodenp; Mention Subject: Re: [artf/grapesjs] Integrating React components (#1970)

Hi @rodenphttps://github.com/rodenp unfortunately at the moment my answer would be the same as beforehttps://github.com/artf/grapesjs/issues/170#issuecomment-316530325. To create what you're asking you have to write a custom render logic and the only available example is from the MJML preset: https://github.com/artf/grapesjs-mjml/blob/master/src/components/index.js

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/artf/grapesjs/issues/1970#issuecomment-485574573, or mute the threadhttps://github.com/notifications/unsubscribe-auth/ABHGD7MHYD46P2COF22GXITPRY36LANCNFSM4HHMKGRQ.

rathahin commented 5 years ago

It is really useful tool. It will add more value If we can use Angular or React component

beepsoft commented 5 years ago

Hi,

I created a poof of concept implementation/example of the integration of a React component as a GrapesJS block/component here:

https://github.com/beepsoft/grapesjs-react-component-example

Although "integrating with React" could mean many things here's the use case I tried to solve:

For all this to work I had to implement a custom HTML parser and replace the built-in parser somehow, but the way I did is kind of hackish. @artf Could you please add a public API to be able to provide a custom HTML parser the same way as it is possible to provide a custom CSS parser?

artf commented 5 years ago

Really cool @beepsoft especially all the explanation of the process

Could you please add a public API to be able to provide a custom HTML parser the same way as it is possible to provide a custom CSS parser?

I'll see if I'll be able to add something quickly without too much refactoring but from what I see your way is quite safe even if you're using not public methods.

Anyway, the project you've made is able to render one only component, the <Timer/>, I hardly believe anyone will ever jump in such a journey just to add one React component. I think that we have to create a kind of generic React component renderer that will be able to display automatically any React component.

An example of what I'd expect as an API

import grapesjs from 'grapesjs';
import ReactRenderer from 'grapesjs-react-renderer';

grapesjs.init({
    ...
    plugins: [
        // this could contain the custom HTML parser, code generator, commands, etc.
        ReactRenderer,
    ],
});

// ...
// somewhere in the code or another plugin
import ReactComponent from 'some/react/component';
import { addComponent } from 'grapesjs-react-renderer';

// ...
addComponent(editor, ReactComponent, {
    name: 'Component name',
    block: { // eg. add also a block
        label: 'Block name',
        media: '<svg ...',
    },
    traits: [ ... ], // Add custom traits or build them by reading the component propTypes
    // ... other options
});
beepsoft commented 5 years ago

@artf Thanks for your feedback!

... I hardly believe anyone will ever jump in such a journey just to add one React component. I think that we have to create a kind of generic React component renderer that will be able to display automatically any React component.

I'm not sure what you mean by that. There can many blocks with a React component displayed by each, or one block could be built from many React components. Or am I wrong about that?

ReactRenderer sounds really interesting, I just cannot imagine with my limited GrapseJS knowledge how this would work in the end.

beepsoft commented 5 years ago

And I know this is far fetched, but I can imagine grapedrop.com to be become something like this: https://builderx.io/

verdverm commented 5 years ago

or builder without the "x" https://builder.io/

artf commented 5 years ago

I've seen them already, the all-in-one flow provided be BuilderX is quite outstanding

ReactRenderer sounds really interesting, I just cannot imagine with my limited GrapseJS knowledge how this would work in the end.

@beepsoft Well more or less you're there, just stick with the idea to have one-to-one relation between React and GrapesJS components (in your project you're mixing some of them, like <Timer.Days />, <Timer.Hours />, etc.).

This is a tiny example of what I'd expect from addComponent

import React from 'react';
import ReactDOM from 'react-dom';
import ReactComponent from 'some/react/component';

const addComponent = (editor, component, opts = {}) => {
  const { id, name, tag, block } = opts;
  const type = `react-${id}`;

  editor.DomComponents.addType(type, {
    model: {
      defaults: {
        tagName: tag,
        // Traits should reflect React component props
        traits: [ ... ],
      }
    },
    view: {
      render() {
        const { model, el } = this;
        const reactEl = React.createElement(
          ReactComponent,
          model.getAttributes(),
          // TODO return children components as react elements
        );
        ReactDOM.render(reactEl, el);
        return this;
      }
    }
  });

  block && editor.BlockManager.add(type, {
    label: name || tag,
    content: { type },
    ...block,
  });
};
beepsoft commented 5 years ago

@artf OK, I get it. I may try to do something in that direction.

rodenp commented 5 years ago

Hi @beepsoft I'm very glad to see this thread still active. How are you going with your implementation? I also see the potential of adding react components to grapesjs. I would really like to see this implemented and am wondering what it would take to get this done.

beepsoft commented 5 years ago

@rodenp Nothing yet, trying to find the time to do it.

rodenp commented 5 years ago

@artf/grapesjsmailto:reply@reply.github.com that would be awesome. 🙏

Peter Roden


From: beep notifications@github.com Sent: Monday, November 4, 2019 9:35:10 AM To: artf/grapesjs grapesjs@noreply.github.com Cc: rodenp rodenp@hotmail.com; Mention mention@noreply.github.com Subject: Re: [artf/grapesjs] Integrating React components (#1970)

@rodenphttps://github.com/rodenp Nothing yet, trying to find the time to do it.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/artf/grapesjs/issues/1970?email_source=notifications&email_token=ABHGD7PR2KQGZMLFKYMM3PDQR7UE5A5CNFSM4HHMKGR2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEC6UZ4I#issuecomment-549276913, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABHGD7II57I6YPTWQJ7N4ODQR7UE5ANCNFSM4HHMKGRQ.

beepsoft commented 5 years ago

I proceeded some with the idea to have 1:1 mapping of react components and grapesjs components.

https://github.com/beepsoft/grapesjs-react-component-example/tree/experiment/oneToOneComponentMapping

This is still the Timer example, where now Timer.Days, Timer.Hours etc. are handled by their matching type/component added using addReactComponent. Also added support for builtin HTML tags that appear inside react components (via ReactDefaultType) and some hack to also have textnodes inside a react component tree.

@artf m I on the right track with these?

What I am missing and cannot figure out:

  1. How can I have the individual react components really act in the editor as individual grapesjs components, ie. to be able to select them individually (the Timer.Hours or the span above it, which appear as of type ReactDefaultType in the Layout Manager) and have the blue line and controls around them?
  2. In the Layout Manager I can move around the Timer elements, however I need a mechanism (an on() event) where I could rerender the react component tree (unmount the current one and rerender again). What event should I subscribe to? Or is there any other lifecycle method I should override in the components?

Thanks!

artf commented 5 years ago

@artf m I on the right track with these?

yeah, definitely is what I was talking about

How can I have the individual react components really act in the editor as individual grapesjs components, ie. to be able to select them individually (the Timer.Hours or the span above it, which appear as of type ReactDefaultType in the Layout Manager) and have the blue line and controls around them?

When you hover/click any HTMLElement in the canvas, GrapesJS just tries to see if the DOM element has the component Model (this is when it happens on click) and the value is actually written in ComponentView I think the problem with React is ReactDOM.render(reactEl, el) actually replaces el with another element so the model value is lost and you have to reset it again. And be careful in isComponent because of this one

if (el.tagName == config.tagName) {

eg. with <Timer.Hours/> you will get

if ('TIMER.HOURSE' == 'Timer.Hours') { // and obviously is false

this is how tagName works in HTML

In the Layout Manager I can move around the Timer elements, however I need a mechanism (an on() event) where I could rerender the react component tree (unmount the current one and rerender again). What event should I subscribe to? Or is there any other lifecycle method I should override in the components?

You should be able listen to children changes (add and remove) in this way

componentModel.components().on('add remove', () => console.log('changed'))
alatella87 commented 5 years ago

Hi @artf, I am also trying to render some React components through GrapesJS blocks. In the documentation (https://grapesjs.com/docs/modules/Components.html#tips) it is mentioned that

By default, GrapesJS understands objects generated from React JSX preset, so, if you're working in the React app probably you're already using JSX and you don't need to do anything else, your environment is already configured to parse JSX in javascript files.

..does that mean "in a React app"?

and then a method that shows a possible lowercase component (probably a JSX/React component)

editor.addComponents(<div>
  <custom-component data-gjs-prop="someValue" title="foo">
    Hello!
  </custom-component>
</div>);

I am confused regarding the conversation in this thread as in the docs it says it is already 'possible'?

How would we go about importing that ?

Best,

alatella87 commented 5 years ago

I just saw @beepsoft implementation and the Timer renders fine. Maybe we could work out simple boilerplate steps to implement another simpler component (such as react-card-preview)?

alatella87 commented 5 years ago

Ok, I added react-card-preview in the dependencies of @beepsoft project and duplicated the 'timer' folder with a 'card' folder, replaced all the plugin references and I can render the component! Here is the react-card-preview (as you can see I was quite happy)

image

Thanks for this @beepsoft !!

rodenp commented 5 years ago

Fantastic work @beepsoft Integrating React properly into the core would be a great step and could make way for the support of other frameworks. This will raise the bar for grapesjs to another level.

beepsoft commented 5 years ago

@rodenp Thanks! These are just toy examples for now but at least they show that it is doable.

beepsoft commented 4 years ago

Yet another JSX editor/generator in town: https://blocks-ui.com/

rodenp commented 4 years ago

I just had a quick look. It's very very basic. I'm also discovering new things like grommet -> https://v2.grommet.io/ which is backed by HP. Grommet has a visual designer, which looks very promising. Again it is under development with bugs and stuff. I'd really like to find a smart intuitive drag and drop (react) editor where i can just drag components without having to constantly adjust the properties. Something that can handle pseudo absolute positioning nicely.

artf commented 4 years ago

There is a guy from Discord who showed how he reached a good point of React component integration in GrapesJS https://codesandbox.io/s/immutable-river-f43bt He said he'll try to polish it and bring this to a more stable state. I've invited him to post here, I think he got the point, hope to hear more from him (it's also a really good starting point for others)

beepsoft commented 4 years ago

Wow, it looks cool and it's neat he "hacked" toHtml with the React tag name instead of overriding the HTML parser. It is much cleaner this way :-)

2 things are missing, I think:

  1. CSS cannot be set on the React component, but this maybe OK, because ...
  2. CSS classes can be set, but then they will appear in the template as the "class" attribute but for React/JSX it should be "className". @artf can this be handled somehow at toHTML() time?

And I didn't know about the Discord channel, going to join.

artf commented 4 years ago

@beepsoft you can extend getAttrToHTML for that case and replace class with className

emilsedgh commented 4 years ago

Hey guys. I'm the author of that code sandbox. Regarding CSS, there are several css-in-js approaches. I managed to get material-ui and styled-jsx working (Although I had to patch styled-jsx, but it was upstramed)

Can you get me examples of what is css solution is not working right now?

beepsoft commented 4 years ago

Hi @emilsedgh,

Can you get me examples of what is css solution is not working right now?

I just tried to use GrapesJS's CSS panel to set some css values on your react component and that didn't work. I could only set a css class, see screenshot below. I don't really know, though, whether general css editing should work or not out of the box.

Screen Shot 2019-12-10 at Dec 10, 20 00 23 PM

Do you maybe have a newer example of your react integration with GrapesJS's CSS panel working on your components?

emilsedgh commented 4 years ago

Oh. The CSS panel is not supposed to work on all react components as most react components simply don't accept a css style or anything.

Of course, if the react component you're writing does accept CSS input as one of it's props, then I suppose we can enable it for that.

My approach does support passing Grapes Attributes as React props. For example in the example you can see that you can change outline of an MUI component.

Screenshot_20191210_200109

The base component automatically translates Grapes attributes to React props. Therefore all you have to do to get more editing options is to define attributes and then define the traits:

editor.DomComponents.addType("MuiButton", {
    model: {
      ...model,
      attributes: {
        color: "primary",      // These are the attributes that will be sent over to
        variant: "contained" // the React component with their default values.
      },
      defaults: {
        component: Button, // This is the React Component
        stylable: false,  // If your React component does support styling, you can just set this to true.
        editable: true,
        traits: [  // Defining traits will cause UI elements to allow manipulating it
          {
            type: "select",
            label: "Variant",
            name: "variant",
            options: [
              { value: "contained", name: "Contained" },
              { value: "outlined", name: "Outlined" }
            ]
          },

          {
            type: "checkbox",
            label: "Disabled",
            name: "disabled"
          },

          {
            type: "select",
            label: "Color",
            name: "color",
            options: [
              { value: "primary", name: "Primary" },
              { value: "secondary", name: "Secondary" }
            ]
          }
        ]
      }
    },
    view,
    isComponent: el => el.tagName === "MUIBUTTON"
  });
}
beepsoft commented 4 years ago

There is a guy from Discord who showed how he reached a good point of React component integration in GrapesJS https://codesandbox.io/s/immutable-river-f43bt

@emilsedgh, @artf this sandbox doesn't work anymore. Do you have any idea what went wrong?

klaussa commented 4 years ago

+1 for the sandbox

megarg commented 4 years ago

I am trying to integrate "reactstrap" with Grapejs but without luck. I tried following the example of @beepsoft but i am stuck at one place. I can render a React component (in view using "Reactdom.render") and created jsx/html parser as @beepsoft explained. All this is working for simple React components such as "Button" etc.

Challenge is when you need nested components such as "Layout".

  1. I want to drag "Layout component) - working fine as explained below
  2. Then, I want to drag another component inside "Layout" component. There does not seem to any way to drop a component inside another React component (as react components are only in view and not in model).

Am I thinking it correctly. Has someone figured this out? I am struggling with this for many days now and this will be of great help

@emilsedgh codepen is not working so not able to figure that part out...

artf commented 3 years ago

I don't know exactly why the sandbox provided by @emilsedgh stopped working but I've tried to refactor it slightly and now it seems to work properly https://codesandbox.io/s/grapesjs-react-components-n6sff For sure there is still a bunch of stuff to improve, but for anyone who wants to explore the integration of react components, that is the proper way.

beepsoft commented 2 years ago

Thanks @artf, it works great! 🎉

Narinderg commented 2 years ago

Hi @artf, thanks for sharing this approach to render react components. However we are figuring out on one thing.

Based on some actions by user within the react component, need to change the attribute passed to that react component. Any pointers there?

megasapp commented 2 years ago

Nice work @artf of integration with React!!! 🎉 🎉 However I am wondering how it can be passed to the compilers such as next.js to generate the final static sites?? (as a static site generator)

megasapp commented 2 years ago

Once again, in you Listing component, it's like a black box. How to expose its 3 child div to the Layer manager, canvas, and style manager so that we can edit their styles?? I wonder it requires a lot of workload......

jenespeyia commented 2 years ago

Hey,

I know this issue is closed, but I'm trying to use GrapesJS with Mui v5, and it seems there was some refactor and deprecation.. so the sandbox does not work anymore.. StylesProvider & JSS have been deprecated and I don't know how to fix the createReactEl function. If you have any idea or already did it somewhere, I'd love to hear from it! Thanks for your help!

dmitrysurkin commented 2 years ago

Hi! @artf this is best demo for react components https://codesandbox.io/s/grapesjs-react-components-n6sff, but i have a small question

I trying to create a react text component. When i click on text, default rich rext editor not showing. What to do?

iamqinglong commented 2 years ago

Hello @artf! hope you doing well. Is this https://codesandbox.io/s/grapesjs-react-components-n6sff also possible using vuejs?

Dearest commented 2 years ago

I am trying to integrate "reactstrap" with Grapejs but without luck. I tried following the example of @beepsoft but i am stuck at one place. I can render a React component (in view using "Reactdom.render") and created jsx/html parser as @beepsoft explained. All this is working for simple React components such as "Button" etc.

Challenge is when you need nested components such as "Layout".

  1. I want to drag "Layout component) - working fine as explained below
  2. Then, I want to drag another component inside "Layout" component. There does not seem to any way to drop a component inside another React component (as react components are only in view and not in model).

Am I thinking it correctly. Has someone figured this out? I am struggling with this for many days now and this will be of great help

@emilsedgh codepen is not working so not able to figure that part out...

@megarg Can I see the code you wrote for jsx to html? Did you rewrite ToHTML()?

Thank you very much!

AylanBoscarino commented 1 year ago

Hey,

I know this issue is closed, but I'm trying to use GrapesJS with Mui v5, and it seems there was some refactor and deprecation.. so the sandbox does not work anymore.. StylesProvider & JSS have been deprecated and I don't know how to fix the createReactEl function. If you have any idea or already did it somewhere, I'd love to hear from it! Thanks for your help!

@dmitrysurkin I am facing the same problem, were you able to find some solution for it so far?

navdeep1897 commented 1 year ago

Hi @artf , I am Trying to add custom tabs and accordian in grapejs but when I want to add multiple tabs or accordian they have same id which is statically defined. is there any way to update statically define id with dynamic id when I drag and drop my custom block to canvas ? I unable to update content in table cells. is There any possible way for changing content of table ?

173303-WebConcepts commented 1 year ago

hi, @dmitrysurkin i am using same example like https://codesandbox.io/s/grapesjs-react-components-n6sff but i am not getting the proper html instead i got: <body><DigitalSignature mlsid="Default MLSID" editable="" id="ieyp"></DigitalSignature></body>

Here is my code:

 import DigitalSignature from "./DigitalSignature";

export default (editor) => {
  editor.Components.addType("DigitalSignature", {
    extend: "react-component",
    model: {
      defaults: {
        component: DigitalSignature,
        stylable: true,
        resizable: true,
        editable: true,
        draggable: true,
        droppable: true,
        attributes: {
          mlsid: "Default MLSID",
          editable: true,
        },
        traits: [
          {
            type: "number",
            label: "MLS ID",
            name: "mlsid",
          },
        ],
      },

      // Define the HTML exporter for the component
      export: function () {
        const imageUrl = this.getImageUrl();
        return `<img src="${imageUrl}"/>`;
      },

      // Define a helper method to get the image URL
      getImageUrl: function () {
        // Get the trimmed canvas image as data URL
        const dataUrl = sigCanvas.current
          .getTrimmedCanvas()
          .toDataURL("image/png");
        return dataUrl;
      },
    },

    isComponent: (el) => el.tagName === "DIGITALSIGNATURE",
  });

  editor.BlockManager.add("DigitalSignature", {
    label: "<div class='gjs-fonts gjs-f-b1'>Signature</div>",
    category: "Form",
    content: `<DigitalSignature />`,
  });
};

Editor Code:

import React, { useEffect, useState } from "react";
import * as ReactDOM from "react-dom";
import { useLocation } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";

import grapesjs from "grapesjs";
import gjsBlockBasic from "grapesjs-blocks-basic";
import "grapesjs/dist/css/grapes.min.css";

import { postThunk } from "../redux/GPPDSlice";
import { setResponseV2 } from "../redux/layoutSlice";
import SocialModal from "../models/SocialModal";
import BaseReactComponent from "./base-react-component";
import ReactComponents from "./react-components";

function ProposalEditor() {
  // Hooks
  const dispatch = useDispatch();
  const { state } = useLocation();
  const { user } = useSelector((State) => State.user);
  const {
    fetchedData: {
      data: { proposal },
    },
  } = useSelector((State) => State.GPPD);

  const [OTPModal, setOTPModal] = useState(false);
  const [editor, setEditor] = useState(null);
  const [runOnce, setRunOnce] = useState(true);

  useEffect(() => {
    if (runOnce) {
      const editor = grapesjs.init({
        container: "#gjs",
        width: "auto",

        storageManager: false,

        fromElement: true,

        plugins: [gjsBlockBasic, BaseReactComponent, ReactComponents],

        pluginsOpts: {
          gjsBlockBasic: {},
        },
      });

      setEditor(editor);
    }
    setRunOnce(false);
  }, []);

  useEffect(() => {
    console.log("QQQQQQQQQQQQQQQQQQQQQQQQQAA", editor?.getHtml());

    // Add some more blocks
    editor?.BlockManager.add("my-button", {
      id: "my-button",
      label: "Button",
      category: "Form",
      media: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22 9c0-.6-.5-1-1.3-1H3.4C2.5 8 2 8.4 2 9v6c0 .6.5 1 1.3 1h17.4c.8 0 1.3-.4 1.3-1V9zm-1 6H3V9h18v6z"></path><path d="M4 11.5h16v1H4z"></path></svg>`,
      content: {
        type: "button",
        content: '<button class="btn">Button</button>',
        style: {
          padding: "10px",
          border: "1px solid #ccc",
        },
      },
    });

    editor?.BlockManager.add("my-page-break", {
      id: "my-page-break",
      label: "Page Break",
      category: "Form",
      media: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path d="M5 5h14v2h-2v10h2v2H5v-2h2V7H5z"/>
      <path d="M7 7h10v10H7z"/>
    </svg>
    `,
      content: {
        // type: "text",
        content:
          '<div class="page-break">----------------Page Break----------------</div>',
        style: {
          "text-align": "center",
        },
      },
    });

    editor?.BlockManager.add("my-checkbox", {
      id: "my-checkbox",
      label: "Checkbox",
      category: "Form",
      media: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <rect x="3" y="3" width="18" height="18" rx="2" ry="2" fill="none" stroke="currentColor" stroke-width="2"/>
      <path d="M9 13l2 2 4-4"/>
    </svg>

    `,
      content: {
        type: "checkbox",
        content: '<input type="checkbox" class="my-checkbox" />',
      },
    });

    // Load the page
    editor?.setComponents(proposal?.proposalPage.pageHtmlData);
    editor?.setStyle(proposal?.proposalPage.pageCssData);

    // Remove multiple blocks
    const blocksToRemove = ["link", "map", "column3-7"];
    blocksToRemove.forEach((blockId) => {
      editor?.BlockManager.remove(blockId);
    });

    // Styling the convas
    const canvas = editor?.Canvas.getElement();

    if (canvas) {
      canvas.style.height = "90vh";
      canvas.style.width = "65%";
      canvas.style.backgroundColor = "red !important";
      canvas.style.border = "1px solid black";
      canvas.style.margin = "30px 90px";
    }

    // Add a save button to the editor
    const saveButton = document.createElement("button");
    saveButton.textContent = "Save & Publish";
    saveButton.addEventListener("click", () => {
      const pageHtmlData = editor?.getHtml();
      const pageCssData = editor?.getCss();
      savePage(pageHtmlData, pageCssData, `/addProposal/${user?._id}`);
    });

    editor?.Panels.addButton("options", {
      id: "save",
      className: "saveAndPublish",
      el: saveButton,
    });
  }, [editor]);

  // Function to save the page data to the server
  const savePage = (pageHtmlData, pageCssData, api_url) => {
    console.log("WWWWWWWWWWWW", pageHtmlData);
    dispatch(
      postThunk({
        proposalName: state?.proposalName,
        projectName: state?.projectName,
        proposalPage: { pageHtmlData, pageCssData },
        api_url,
      })
    )
      .then((res) => {
        if (res?.payload?.data?.status == 200) {
          setOTPModal(true);
        } else if (res?.payload?.response.data != 200) {
          dispatch(setResponseV2(res.payload.response.data));
        }
      })
      .catch((err) => {
        console.log("Fornt end server crash", err);
      });
  };

  return (
    <React.Fragment>
      <div id="gjs">
        <h1>Hello World Component!!!!!!!!!!!!</h1>
      </div>

      <SocialModal displayModal={OTPModal} setDisplayModal={setOTPModal} />
    </React.Fragment>
  );
}
export default ProposalEditor;
SwapnilSoni1999 commented 1 year ago

Anybody made this working ?

emilsedgh commented 1 year ago

https://codesandbox.io/s/grapesjs-react-components-n6sff is a properly working example that integrates React (as well as Material UI) inside Grapes.

rahulrajpal2911 commented 1 year ago

hi, thank you for this awesome library. I am trying to integrate Prime React component and I tried all the ways that are mentioned in this thread however I didn't got any success yet. Please can anyone help me?

Thanks in advance.

reyren18 commented 5 months ago

Hey, I know this issue is closed, but I'm trying to use GrapesJS with Mui v5, and it seems there was some refactor and deprecation.. so the sandbox does not work anymore.. StylesProvider & JSS have been deprecated and I don't know how to fix the createReactEl function. If you have any idea or already did it somewhere, I'd love to hear from it! Thanks for your help!

@dmitrysurkin I am facing the same problem, were you able to find some solution for it so far?

hey @AylanBoscarino facing the same issue right now, have u found a workaround yet?