Skip to content

Override main views and buttons styles and props using MUI themes #10771

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

Open
wants to merge 17 commits into
base: customizable-components
Choose a base branch
from

Conversation

Madeorsk
Copy link
Contributor

@Madeorsk Madeorsk commented Jun 9, 2025

Problem

Overriding React-admin defaults is cumbersome for many components, especially the most important ones: views and important actions such as <DeleteButton>.

Concrete use cases (to be implemented as stories and used for documentation):

  • Make all mutations pessimistic
  • Replace all button icons for a custom theme

Solution

In ra-ui-materialui there's a mechanism for that already: the theme. Although we use it for some components (see #10655), we now do it for views such as <List>, <Edit>, <Create>, <Show> and buttons that has variants such as <DeleteButton>, <UpdateButton>, <BulkDeleteButton> and <BulkUpdateButton>.

How To Test

From Storybook

View a list, detail view or button you want to test with and try to change the default theme.

export const defaultLightTheme: ThemeOptions = deepmerge(
    defaultThemeInvariants,
    {
        //...
        components: {
            //...

+           RaCreate: {
+               defaultProps: {
+                    className: 'custom-class',
+                    mutationMode: 'optimistic',
+                },
+           },
        },
    }
);

From simple example

To set the creation as undoable in every Create:

// ...
root.render(
    <React.StrictMode>
        <Admin
            authProvider={authProvider}
            dataProvider={dataProvider}
            i18nProvider={i18nProvider}
            queryClient={queryClient}
            title="Example Admin"
            layout={Layout}
+           theme={deepmerge(defaultLightTheme, {
+               components: {
+                   RaCreate: {
+                       defaultProps: {
+                           mutationMode: 'undoable',
+                       },
+                   },
+               },
+           } as ThemeOptions)}
        >
// ...

Additional Checks

  • The PR targets master for a bugfix or a documentation fix, or next for a feature
  • The PR includes unit tests (if not possible, describe why)
  • The PR includes one or several stories (if not possible, describe why)
  • The documentation is up to date

@djhi djhi changed the title Override style and props using MUI themes Override main views and buttons styles and props using MUI themes Jun 10, 2025
Copy link
Collaborator

@djhi djhi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome :)

Comment on lines +19 to +46
<AdminContext
dataProvider={dataProvider}
theme={deepmerge(defaultLightTheme, {
components: {
RaBulkDeleteButton: {
defaultProps: {
label: 'Bulk Delete',
className: 'custom-class',
'data-testid': 'themed-button',
},
},
},
} as ThemeOptions)}
>
<ListContextProvider
value={
{
selectedIds: [123],
onUnselectItems: () => {},
} as any
}
>
<BulkDeleteButton
resource="books"
mutationMode="pessimistic"
/>
</ListContextProvider>
</AdminContext>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a story

Comment on lines +53 to +77
<CoreAdminContext dataProvider={dataProvider}>
<ThemeProvider
theme={deepmerge(theme, {
components: {
RaBulkExportButton: {
defaultProps: {
label: 'Bulk Export',
className: 'custom-class',
'data-testid': 'themed-button',
},
},
},
} as ThemeOptions)}
>
<ListContextProvider
value={{ selectedIds: ['selectedId'] }}
>
<BulkExportButton
resource="test"
exporter={exporter}
meta={{ pass: 'meta' }}
/>
</ListContextProvider>
</ThemeProvider>
</CoreAdminContext>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a story.


declare module '@mui/material/styles' {
interface ComponentsPropsList {
[PREFIX]: Partial<BulkUpdateButtonProps>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't expect referring to PREFIX would work here but it does. TIL 👍
We could simplify some other components I worked on.

Comment on lines +51 to +68
<AdminContext
theme={deepmerge(defaultLightTheme, {
components: {
RaCloneButton: {
defaultProps: {
label: 'Clone',
className: 'custom-class',
'data-testid': 'themed-button',
},
},
},
} as ThemeOptions)}
>
<CloneButton
resource="posts"
record={{ id: 123, foo: 'bar' }}
/>
</AdminContext>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a story.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFR Ready For Review
Development

Successfully merging this pull request may close these issues.

2 participants