Fix: Expose contexts in DataTableBase loading and empty states#11144
Fix: Expose contexts in DataTableBase loading and empty states#11144dreglad wants to merge 1 commit intomarmelab:masterfrom
Conversation
This change ensures that custom loading and empty components in DataTable have access to ResourceContext and other standard contexts. Also added comprehensive unit tests for DataTableBase to verify context availability and correct rendering behavior for empty and refreshing states.
slax57
left a comment
There was a problem hiding this comment.
Thanks for your contribution.
This looks interesting, but could you share real-life examples of empty or loading components which require accessing the DataTable contexts? Apart from the ResourceContext (which in most cases is already defined by the parent List component) I cannot think of good examples where this would be needed.
Hi @slax57, great question! The main reason for keeping these contexts available during loading and empty states is to allow custom components to stay perfectly aligned with the table configuration without needing manual prop-drilling or direct access to the memory store (internal details). Here are a few real-life examples where this is useful: Custom Loading SkeletonsTo avoid layout shifts, a skeleton needs to know exactly how many columns to render. It needs access to Context-Aware empty ComponentsDepending on the context, an empty state might want to display different calls to action. For instance, an empty component might want to provide a "Reset filters" button that clears filters when the table was empty due to filters being applied. Overall architectural consistencyIn React-admin, we generally follow the pattern of providing configuration via context to allow for highly customizable and pluggable sub-components. Treating loading and empty states as "first-class citizens" that have access to the table's context ensures they can be as rich and integrated as the data rows themselves. |
|
Thanks for your reply. You convinced me! I was also asking to see if we should update the documentation with an example leveraging these new possibilities, but I figure the code example (e.g. with a skeleton) would probably be too complex to be comprehensive, so let's forget about this for now. Besides your PR to shadcn-admin-kit will probably be a good example too! |
slax57
left a comment
There was a problem hiding this comment.
Other than that the code LGTM!
| it('should display the empty component instead of the table header when loaded with no data', () => { | ||
| render( | ||
| <ResourceContextProvider value="posts"> | ||
| <ListContextProvider | ||
| value={ | ||
| { | ||
| ...defaultListContext, | ||
| data: [], | ||
| total: 0, | ||
| isPending: false, | ||
| } as any | ||
| } | ||
| > | ||
| <DataTableBase | ||
| empty={<div>Empty Component</div>} | ||
| loading={<div>Loading</div>} | ||
| hasBulkActions={false} | ||
| > | ||
| <div>Table Header and Body</div> | ||
| </DataTableBase> | ||
| </ListContextProvider> | ||
| </ResourceContextProvider> | ||
| ); | ||
|
|
||
| expect(screen.queryByText('Empty Component')).not.toBeNull(); | ||
| expect(screen.queryByText('Table Header and Body')).toBeNull(); | ||
| }); |
There was a problem hiding this comment.
This test looks duplicate of test at line 46. If confirmed can you remove it?
This change ensures that custom loading and empty components in
DataTableBasehave access to relevant table contexts.This should be fully backwards compatible.
Problem
When providing custom
loadingoremptycomponents toDataTableBase, these components did not have access to any contexts. Some of these contexts, namely resource, table store, and table config, might be valuable when rendering Empty/Loading states. This lack of access forced developers to pass props manually or duplicate logic if they wanted to use this context within their components.Solution
Updated
DataTableBaseinpackages/ra-coreto wrap theloadingandemptyrendering logic with the following context providers:DataTableStoreContext.ProviderDataTableConfigContext.ProviderOptionalResourceContextProviderThis ensures that any component rendered in these slots can access the current resource and configuration from context.
How To Test
I have added a new test file
packages/ra-core/src/dataTable/DataTableBase.spec.tsxwhich covers:loadingandemptyslots.loadingcomponent is rendered when pending.emptycomponent is rendered when no data is present (hiding headers).