widgetti / ipyreact

React for ipywidgets that just works. No webpack, no npm, no hassle
BSD 3-Clause "New" or "Revised" License
118 stars 8 forks source link

Project idea: React Flow Widget #32

Closed kolibril13 closed 1 year ago

kolibril13 commented 1 year ago

It would be interesting to see if it was possible to use React Flow in an ipyreact Widget. That would be really nice to have!

image

Copy+Pasting this minimal example https://reactflow.dev/docs/getting-started/building-a-flow/#getting-started

%load_ext ipyreact
%%react
import React from 'react';
import ReactFlow, { Controls, Background } from 'reactflow';

function Flow() {
  return (
    <div style={{ height: '100%' }}>
      <ReactFlow>
        <Background />
        <Controls />
      </ReactFlow>
    </div>
  );
}

export default Flow;

gives this error:

Error
;
[React Flow]: Seems like you have not used zustand provider as an ancestor. Help: https://reactflow.dev/error#001

and some further debugging did also not lead to any working result.

@maartenbreddels : You're very welcome to not interact with this issue, you invested so much time already in this awesome project, and I don't want to overstretch your bandwidth.

@paddymul : As you already worked with react and in case that you currently have time and motivation for this, would you like to give this a try and see if you can get this to work? That would be awesome!

I also found some CSS that might be needed for this at: https://github.com/wbkd/react-flow/tree/2e1f360817915f84743b6e0ca390f57f1bb2a57a/packages/core/src/styles

kolibril13 commented 1 year ago

https://github.com/widgetti/ipyreact/assets/44469195/952e1f2d-0bd7-4c7a-9b9e-4f7c096d8581

this works now with anywidget! more will follow soon! 🎉

cpbotha commented 7 months ago

@kolibril13 Did you get any further with this, and/or publish anything more about your efforts?

I think I know how I can solve the zustand issue (you must wrap in <ReactFlowProvider>), but I am running into other issues when I try to pre-build my reactflow component using esbuild for inclusion as an ipyreact widget.

maartenbreddels commented 7 months ago

@cpbotha how do you build? Using esbuild? Can you provide more details?

cpbotha commented 7 months ago

Wow @maartenbreddels thank you!

I am using esbuild as per the readme. However, I'm running into react issues on ipyreact.define_module in spite of having excluded the react modules as per the docs.

I can partially reproduce these issues using the threejs-fiber example from this repo, so I think it will make more sense to create a new issue in the coming few minutes.

Update: Just created #59

kolibril13 commented 7 months ago

@kolibril13 Did you get any further with this, and/or publish anything more about your efforts?

yes, I've made this with anywidget: https://github.com/kolibril13/ipyreactflow

and here's another project you might be interested in: https://github.com/kolibril13/ipy-react-three-fiber

cpbotha commented 7 months ago

Aaah this is great, thank you very much @kolibril13 !!

I only discovered later that npm create anywidget@latest supports react, and now your ipyreactflow confirms that this is one neat way of getting reactflow into jupyter notebooks.

maartenbreddels commented 7 months ago

I think if you can use anywidget or ipyreact depends on how you need to use the library. With ipyreact you can compose your widgets into a full react tree. Currently with react+anywidget you need to compose the full react tree from the data, AFAIK you cannot compose multiple widgets together using anywidget without having a separate react tree.

All depends on the use case and the complexity you need or are willing to accept. In our case, we need this for antd (or MUI) where we want to create widgets, and put them together in a single react tree (with a share react complex and no extra divs in between).

That said, I think anywidget + esbuild is probably easier and has less chances on issues (like the one you encountered in #59)

cpbotha commented 7 months ago

Thank you Maarten that makes a lot of sense.

All depends on the use case and the complexity you need or are willing to accept. In our case, we need this for antd (or MUI) where we want to create widgets, and put them together in a single react tree (with a share react complex and no extra divs in between).

That said, I think anywidget + esbuild is probably easier and has less chances on issues (like the one you encountered in #59)

Once one has ipyreact working, it's short iterative cycles (with your react straight in the notebook cell), including composable widget trees, does look compelling.

In this case, I did indeed get it working in AnyWidget, which for my case is sufficient, with the added benefit that I can use the more conventional frontend tooling to fine-tune the react stuff.