How to get rid of shadows in the Material-UI theme - reactjs

I need to get rid of shadows in MuiPaper component.
I found some solution:
for example
but they didn't work.
I can override only root component (MuiPaper) but the shadow is set by the class MuiPaper-elevation1-24.
code that render component
const List = props => (
<List {...props} title="lists" filters={<Filter />} sort={{ field: 'timestamps.createdAt', order: 'DESC' }}>
<Datagrid rowClick="show" expand={<Edit />} >
<TextField source="attributes.campaignUuid" label="Campaign Uuid" />
<TextField source="attributes.affiliateId" label="Affiliate Id" />
<DateField source="attributes.createdAt" label="Created At" showTime locales="ru-RU" sortBy="timestamps.createdAt" />
<DateField source="attributes.updatedAt" label="Updated At" showTime locales="ru-RU" sortBy="timestamps.updatedAt" />
<DeleteButton />
</Datagrid>
</List>
);
And HTML that I receive:
<div class="list-page Component-root-904">
<div class="MuiPaper-root-21 MuiPaper-elevation1-24 MuiPaper-rounded-22 MuiCard-root-740 Component-card-905"></div>
</div>

Try this:
import { withStyles, createStyles } from '#material-ui/core/styles';
const listStyles = theme => createStyles({
card: {
boxShadow: 'none',
},
});
const List = withStyles(listStyles)(({ classes, ...props }) => (
<List classes={classes} title="lists" filters={<Filter />} sort={{ field: 'timestamps.createdAt', order: 'DESC' }} {...props}>
...
</List>
);

Related

Using HOC to wrap icon inside tooltip component

Using a higher order component to wrap icon, the issue is that the tooltip is not shown unless i click on the icon atleast once. Have added two tooltips the first one is w/o hoc and works as expected, unlike 2nd one in which i have to click once after which tooltip is shown.
Can someone please help??
function componentGenerator(WrappedComponent) {
function DynamicComponent(props, ref) {
return <WrappedComponent {...props} />;
}
return React.forwardRef(DynamicComponent);
}
const MyIcon = React.forwardRef((props, ref) => {
return (
<IconButton {...props}>
<Avatar alt="Not working" src="/static/images/avatar/2.jpg"/>
</IconButton>
);
});
const MyHoc = componentGenerator(MyIcon);
export default function App() {
return (
<div className="App">
<Tooltip title="Open settings" key="1">
<IconButton sx={{ p: 0 }}>
<Avatar alt="Working" src="/static/images/avatar/2.jpg"/>
</IconButton>
</Tooltip>
<Tooltip title="Open settings" key="2">
<MyHoc />
</Tooltip>
</div>
);
}
https://codesandbox.io/s/infallible-booth-2wfeq0?file=/src/App.js:515-521
From the official react documentation:
... ref is not a prop. Like key, it’s handled differently by React
That's why you need to pass in ref additionally to your spread props:
import "./styles.css";
import { Avatar, IconButton, Tooltip } from "#mui/material";
import React from "react";
function componentGenerator(WrappedComponent) {
function DynamicComponent(props, ref) {
return <WrappedComponent {...props} ref={ref} />;
}
return React.forwardRef(DynamicComponent);
}
const MyIcon = React.forwardRef((props, ref) => {
return (
<IconButton {...props} ref={ref}>
<Avatar alt="Not working" src="/static/images/avatar/2.jpg" />
</IconButton>
);
});
const MyHoc = componentGenerator(MyIcon);
export default function App() {
return (
<div className="App">
<Tooltip title="Open settings" key="1">
<IconButton sx={{ p: 0 }}>
<Avatar alt="Working" src="/static/images/avatar/2.jpg" />
</IconButton>
</Tooltip>
<br />
<br />
<Tooltip title="Open settings" key="2">
<MyHoc />
</Tooltip>
</div>
);
}
https://codesandbox.io/s/elegant-gates-nbvebo?fontsize=14&hidenavigation=1&theme=dark

How to make a reusable Material UI tabs component in React

I am working on a React project, and I divided some of the pages into tabs using the MUI Tab component, so I can have multiple components in one page and render each component accordingly, so I have created the Tabs component. However, I can only see one first index tab.
Reusable tab MUI component:
export default function useTabs(props) {
const { children, value, index, label, ...other } = props;
const [selectedValue, setSelectedValue] = React.useState(0);
const handleChange = (event, newValue) => {
setSelectedValue(newValue);
};
return (
<Box sx={{ width: "100%" }}>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<Tabs
value={selectedValue}
onChange={handleChange}
className={classes.tab}
textColor="primary"
indicatorColor="primary"
>
<Tab label={label} {...a11yProps(0)} className={classes.tabText} />
{/* <Tab className={classes.tabText} label={label} {...a11yProps(1)} /> */}
</Tabs>
</Box>
<TabPanel value={selectedValue} index={index}>
{children} // Rendering tab children here, but getting only the first component
</TabPanel>
</Box>
);
}
Here is how I am using it:
// Import the reusable component
import Tab from "../common/Tabs";
export default function JobsRecruitments() {
return (
<>
<Tab label="tab name" index={0}>
<MyComponent />
</Tab>
</>
)
}
I don't think it's a good idea to use children if you want reusable tabs. That's because your tabs have to be consistent: if you have 3 child nodes, you should also have 3 tab labels. If you're using children, you can easily lose track of that.
However, if you want to make a reusable tab component, I would suggest passing an array of objects containing the tab label and Component as a property to your custom Tab component. Here's an example of what I mean:
export default function BasicTabs({ tabs }) {
const [value, setValue] = React.useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box sx={{ width: "100%" }}>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<Tabs
value={value}
onChange={handleChange}
aria-label="basic tabs example"
>
{tabs.map(({ label }, i) => (
<Tab label={label} key={i} />
))}
</Tabs>
</Box>
{tabs.map(({ Component }, i) => (
<TabPanel value={value} index={i} key={i}>
{Component}
</TabPanel>
))}
</Box>
);
}
And then you can use this component like this:
import Tabs from "./MyTabs";
const tabs = [
{
label: "Tab 1",
Component: <div>Hello, I am tab 1</div>
},
{
label: "Tab 2",
Component: <div>Hello, I am tab 2</div>
},
{
label: "Tab 3",
Component: (
<div>
<h1>Tab with heading</h1>
<p>Hello I am a tab with a heading</p>
</div>
)
}
];
export default function App() {
return (
<div>
<Tabs tabs={tabs} />
</div>
);
}
Here's the Codesandbox with the full example

Unable to set the content of the box in an appropraite way using reactjs

I'm new to material UI, i was going through few of the links and then i could built the content of the message.
Here is the Code:
class Data extends React.Component {
render() {
const { classes } = this.props;
return (
<Card>
<CardHeader
avatar={<Avatar aria-label="recipe">S</Avatar>}
title={
// <TextField placeholder="Search" margin="normal" />
<>
<InputBase placeholder="Search Google Maps" margin="normal" />
<IconButton type="submit" aria-label="search">
<SearchIcon />
</IconButton>
</>
}
/>
<Divider />
<CardContent className={classes.contentHeight} >
<Message isSender content="Hello" />
<Message content="Hello back" />
<Message isSender content="Anyone there" />
<Message content="Yes" />
<Message isSender content="Thank you for replying" />
</CardContent>
</Card>
);
}
}
Can anyone help me in this? Thanks in advance
You can add a div to bottom of your Card content component and scroll to it whenever your component is updated.Check here CodeSandBox
<div
style={{ float: "left", clear: "both" }}
ref={el => {
this.messagesEnd = el;
}}
/>
componentDidMount() {
this.scrollToBottom();
}
scrollToBottom = () => {
this.messagesEnd.scrollIntoView({ behavior: "smooth" });
};
componentDidUpdate() {
this.scrollToBottom();
}

Using Grid with SortableJS

I am using SortableJS for React and I am trying to implement horizontal Grid, so that the final result would look like this:
I managed to do that, however the sort function does not work at all. I think it has something to do with the tag attribute. When I try tag={Grid} I get following error:
Sortable: el must be an HTMLElement, not [object Object]
Any ideas how can I implement Grid to the tag attribute? Here is my code:
<Grid container>
<Sortable options={{ fallbackOnBody: true, group: "items", handle: reorderHandle }} tag={Grid} onChange={handleChange}>
{items.map((item, index) =>
<Paper key={index} data-id={index} className={classes.item} elevation={0}>
<ButtonHelper {...getHandleClass(editable)} key={index} icon={
<Badge badgeContent={index + 1} color="default">
{editable && <ReorderIcon />}
</Badge>}
/>
<Grid item xs={4} key={index}>
<div className={classes.gridItem}>
<GalleryInput className={classes.image} style={{ width: '300px' }} label="image" source={`${source}[${index}].image`} />
<br></br>
<TextInput label="desc" source={`${source}[${index}].desc`} />
{editable && <ButtonHelper icon={<RemoveIcon />} onClick={handleRemove(index)} className={classes.left} />}
</div>
</Grid>
</Paper>
)}
</Sortable>
</Grid>
Thank you for any help.
Since you are using a custom component, the tag prop accepts it as a forwarRef component only.
So you need to update in that way.
Sample Snippet
// This is just like a normal component, but now has a ref.
const CustomComponent = forwardRef<HTMLDivElement, any>((props, ref) => {
return <div ref={ref}>{props.children}</div>;
});
export const BasicFunction: FC = props => {
const [state, setState] = useState([
{ id: 1, name: "shrek" },
{ id: 2, name: "fiona" }
]);
return (
<ReactSortable tag={CustomComponent} list={state} setList={setState}>
{state.map(item => (
<div key={item.id}>{item.name}</div>
))}
</ReactSortable>
);
};

Bulk action in admin-on-rest

I used bulkActions props for Admin-on-rest List but don't show anything when I select rows. How to can I use the bulk action?
const AccountingBulkActions = props => (
<BulkActions {...props}>
<BulkDeleteAction />
</BulkActions>
);
export const AccountingList = (props) => (
<List
{...props}
bulkActions={<AccountingBulkActions />}
title="Accounting">
<Datagrid
headerOptions={{ adjustForCheckbox: true, displaySelectAll: true }}
bodyOptions={{ displayRowCheckbox: true }}
rowOptions={{ selectable: true }}
options={{ multiSelectable: true }}>
<DateField source="createdAt" />
<TypeLabel source="type" />
<GenderLabel source="gender" />
<NumberField source="paymentPrice" />
<NumberField source="totalPrice" />
</Datagrid>
</List>
);
Bulk actions are a new feature only available on react-admin. You'll have to upgrade your admin-in-rest app.

Resources