-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[data grid] Add recipe using a Portal to render components from the DataGrid outside its context #2522
Comments
Looking at the source: mui-x/packages/storybook/src/stories/playground/customize-components.stories.tsx Lines 411 to 441 in 34c38ca
I can think of three options:
|
On this point, how do you solve this ?
|
diff --git a/packages/storybook/src/stories/playground/customize-components.stories.tsx b/packages/storybook/src/stories/playground/customize-components.stories.tsx
index bfa51b08..ceadde52 100644
--- a/packages/storybook/src/stories/playground/customize-components.stories.tsx
+++ b/packages/storybook/src/stories/playground/customize-components.stories.tsx
@@ -410,7 +410,6 @@ const CustomPanel2 = (props) => {
export const OutsideColumnsPanel = () => {
const data = useData(500, 50);
- const apiRef = useGridApiRef();
const [open, setOpen] = React.useState(false);
const handleStateChange = React.useCallback((state: GridState) => {
@@ -420,22 +419,31 @@ export const OutsideColumnsPanel = () => {
setOpen(isColumnsTabOpen);
}, []);
+ const props = useDataGridProProps({
+ ...data,
+ ...data,
+ onStateChange: handleStateChange,
+ components: {
+ Panel: CustomPanel2,
+ Header: GridToolbar,
+ },
+ });
+ const apiRef = useGridApiRef();
+ useDataGridProComponent(apiRef, props);
+
return (
<div style={{ display: 'flex', flexDirection: 'row', flex: 1 }}>
- <GridApiContext.Provider value={apiRef}>
+ <GridContextProvider apiRef={apiRef} props={props}>
<SidePanel open={open} />
<div className="grid-container">
- <DataGridPro
- {...data}
- apiRef={apiRef}
- onStateChange={handleStateChange}
- components={{
- Panel: CustomPanel2,
- Header: GridToolbar,
- }}
- />
+ <GridRoot>
+ <GridErrorHandler>
+ <GridHeaderPlaceholder />
+ <GridBody />
+ <GridFooterPlaceholder />
+ </GridErrorHandler>
+ </GridRoot>
</div>
- </GridApiContext.Provider>
+ </GridContextProvider>
</div>
); |
We could have a component wrapping the |
I agree that we can make the story work by copy pasting most of the code of For your 2nd comment, are you thinking about something like this ? const MyCustomDataGridPro = () => {
const { props, apiRef } = useDataGridPro(inputProps);
return (
<GridContextProvider props={props} apiRef={apiRef}>
<GridPreferencesPanel />
<DataGridProContent />
</GridContextProvider>
} With
Maybe we should only do this for the paid version if we don't want user to do this with the free version const MyCustomDataGrid = () => {
const { props, apiRef } = useDataGrid(inputProps);
props.disableColumnReorder = false;
return (
<GridContextProvider props={props} apiRef={apiRef}>
<DataGridContent />
</GridContextProvider>
} |
cc @DanailH for thoughts on this discussion around the product direction. I would personally +1 for the option 3. Of #2522 (comment) and what @m4theushw suggested in #2522 (comment). If we are uncomfortable with making the API public at this point, we could prefix it as The value I see in this option is making a step toward allowing the developers to have more control of what's rendered, by breaking the big component monolith. It gets us closer to the headless hook API of react-table. It also resonates with a thread I opened around should we make the backbone of the apiRef in the MIT plan, so that the community can build around it? It would make our initiative more likely to take shares in react-table's audience, which might lead to more upsells. |
I read all the comments. I guess we never asked or more like answered the question if we want to support that behaviour in the first place. Previously we discussed the idea of supporting the React Table way (hooks all the way and ability for developers to compose their own grid) as one of the directions we can take with the If we say we would like to have that one day then supporting the described behaviour in this ticket makes sense. Regarding the suggested options here #2522 (comment) Maybe I'm missing something but if we expose the API what would be the definitive feature of the |
100% agree on that.
If we just expose the But I do agree that we should clarify what should be the specificity of the Pro version. |
@flaviendelangle Yes, but I think that the license verification should be on this new hook too. Currently, the license is only verified if the
There're some ways to force the props and prevent developers from enabling Pro features.
@DanailH In the Pro version, everything is tied together and we guarantee it will work. The "definitive feature" is not to have to understand the grid's internals to have a Pro functionality. However, I think that by exposing the API, some of the features could be easily recreated only by disabling the default behavior of a couple of events and copying the code from GitHub. Take as example the multiple selection, where it listens only one event, it's easy to hack and have this feature for free. To prevent this from happening, should we make the possibility to cancel the default behavior a Pro feature? The problem I see is that the component tree is the same between the two plans, so all events are already in the free version. With complex features yet-to-be-developed, we could have different structures and make it harder to copy features from the Pro version. |
That sounds logical indeed. |
I just tried to use Exposing the apiRef and calling this hook with the ref would have been useful. |
Not everything is in the ref. And not everything can be in it if we want to take advantage of React lifecycle. We are currently trying to find a way to cleanly call components outside of the Grid scope. |
Here's an example rendering the filter and columns panels outside the DataGrid using Portals: https://codesandbox.io/s/inspiring-monad-tee4qi?file=/demo.tsx |
Having a receipt is great, but it uses a portal, this feels more like a workaround than a dedicated solution, e.g. no SSR possible. I would maybe suggest to reopen and undo this issue title change:
But we can wait more user inputs. |
We can undo and reopen. The main challenge is that implementing this is quite a challenge and it might already be planned for the future (post v7). |
@DanailH is there an issue open with this plan? Referencing this issue in that one sounds like a great option as well. We could frame it around the struggle with the lack of SSR support, cascading rendering, and the unintuitive React tree structure of the current portal based receipt. |
I would imagine that this would be closely tied to the "compose your own grid" end goal so I'm not sure if there is an existing issue but I'll check. I tagged @joserodolfofreitas, maybe he keeps track of this already somewhere. |
Hi, thanks for the demo however in this demo filter is not outside of the DataGrid, nor the footer. |
Summary 💡
This RFC aims at deciding whether or not we want to allow users to use our components outside of the scope of the
DataGrid
, and if so how could we make it work.We currently have one example in our internal Storybook with a
GridPreferencesPanel
used outside of the grid scope. But it is not working anymore due to the introduction of theuseGridRootProps
hook which is not accessible outside of the grid scope.mui-x/packages/storybook/src/stories/playground/customize-components.stories.tsx
Line 411 in af50a4a
If we want to allow this pattern, how could we make the
rootProps
correctly accessible ? If we just export the provider and the user gives the input props to it, our component will have access to the unprocessed props (meaning it won't have the built in classnames for instance, or theDataGrid
free version forced props).And as we move away from the single ref with everything in-it, this problem will probably occur a lot more.
The text was updated successfully, but these errors were encountered: