React-Admin新手求助:如何自定义按钮CSS样式?
Hey there! Since you're new to react-admin, let's break down the best ways to customize those button styles properly—you're already on the right track with makeStyles, so we'll build on that to cover all your button types:
1. Customizing Datagrid Action Buttons (Your EditButton)
You’ve already added className={classes.btn_edit} to your EditButton, which is correct. Sometimes react-admin’s default Material UI styles have higher priority, so we can tweak your style to ensure it overrides properly:
const useStyles = makeStyles((theme) => ({ userCard: { padding: "20px", borderRadius: "12px", }, btn_edit: { background: "#5E35B1", color: "#fff", fontSize: "10px", // Add hover state for better UX "&:hover": { background: "#4527A0", // Darker shade for hover }, // Target the Material UI button class to ensure priority (avoids !important when possible) "&.MuiButton-contained": { boxShadow: "none", }, }, mainList: { boxShadow: "none !important", borderRadius: "0px", }, listCreateIcon: { padding: "0px !important", }, }));
This nested selector (&.MuiButton-contained) targets the exact Material UI button variant, making your style take precedence without relying on !important unless absolutely necessary.
2. Customizing Create/Edit Page Top Buttons (Save/Cancel)
The save and cancel buttons in Create/Edit live in the default toolbar. To style them, you’ll need to create a custom toolbar component and pass it to the toolbar prop of Create/Edit:
First, add styles for these buttons to your useStyles:
const useStyles = makeStyles((theme) => ({ // ... your existing styles saveBtn: { background: "#2E7D32", color: "#fff", "&:hover": { background: "#1B5E20", }, }, cancelBtn: { borderColor: "#D32F2F", color: "#D32F2F", "&:hover": { background: "rgba(211, 47, 47, 0.1)", }, }, }));
Then create your custom toolbar:
import { Toolbar, SaveButton, CancelButton } from "react-admin"; const CustomFormToolbar = ({ classes, ...props }) => ( <Toolbar {...props}> <SaveButton className={classes.saveBtn} /> <CancelButton className={classes.cancelBtn} /> </Toolbar> );
Update your UserCreate and UserEdit components to use this toolbar:
export const UserCreate = (props) => { const classes = useStyles(); return ( <Create {...props} toolbar={<CustomFormToolbar classes={classes} />}> <SimpleForm style={{ padding: "0px !important" }}> <TextInput source="username" /> <TextInput type="password" source="password" /> <ReferenceArrayInput source="roles" reference="_roles" allowEmpty> <SelectArrayInput optionText="name" /> </ReferenceArrayInput> <BooleanInput source="enabled" defaultValue={true} /> </SimpleForm> </Create> ); }; export const UserEdit = (props) => { const classes = useStyles(); return ( <Edit {...props} toolbar={<CustomFormToolbar classes={classes} />}> <SimpleForm> <TextField source="username" /> <ReferenceArrayInput source="roles" reference="_roles"> <SelectArrayInput optionText="name" /> </ReferenceArrayInput> <BooleanInput source="enabled" /> </SimpleForm> </Edit> ); };
3. Customizing the Export Button
If your export button is part of the List’s toolbar, you’ll use a similar approach to the form toolbar. First add an export button style:
const useStyles = makeStyles((theme) => ({ // ... your existing styles exportBtn: { marginLeft: theme.spacing(2), background: "#FF9800", color: "#fff", "&:hover": { background: "#F57C00", }, }, }));
Create a custom List toolbar:
import { ListToolbar, ExportButton, SearchInput } from "react-admin"; const CustomListToolbar = ({ classes, ...props }) => ( <ListToolbar {...props}> <ExportButton className={classes.exportBtn} /> {/* Keep the default search input if you need it */} <SearchInput /> </ListToolbar> );
Pass this to your List component:
export const UserList = (props) => { const classes = useStyles(); return ( <Card className={classes.userCard}> <List {...props} pagination={null} perPage={9999} className={classes.mainList} toolbar={<CustomListToolbar classes={classes} />} > <Datagrid className={classes.listCard}> <TextField source="username" /> <BooleanField source="enabled" /> <ReferenceArrayField reference="_roles" source="roles"> <SingleFieldList> <ChipField source="name" /> </SingleFieldList> </ReferenceArrayField> <EditButton className={classes.btn_edit} /> </Datagrid> </List> </Card> ); };
Quick Pro Tips
- Avoid overusing
!important—use Material UI’s built-in class names (likeMuiButton-contained) to target elements precisely instead. - Leverage the
themeobject for consistent spacing and colors (e.g.,theme.spacing(2)instead of hardcoding16px). - If you want to apply styles globally to all buttons of a type, you can customize Material UI’s theme in your app’s root component, but this affects the entire app—great for brand consistency.
内容的提问来源于stack exchange,提问作者Joe

