I'm very new to react draggable and beaitiful-dnd, I want to be able to drag my table headers around, which I managed! But the styling "pops out" while an item is selected like so:
the item that is being dragged it seems to change the size of the entire table until I place it down again. I'm not sure what property I should add/change for the table to stay put while the item itself is being moved around? Here's the code for the movable header:
// React-Beautiful-dnd code
const getItemStyle = (isDragging, draggableStyle) => ({
userSelect: "none",
paddingBottom: 8,
// change background colour if dragging
background: isDragging ? "grey" : "none",
// styles we need to apply on draggables
...draggableStyle
});
class EnhancedTableHead extends React.Component {
render() {
const { columnData, handleReorderColumnData } = this.props;
return (
<DragDropContext onDragEnd={handleReorderColumnData}>
<TableHead>
<TableRow
component={Droppable}
droppableId="droppable"
direction="horizontal"
sx={{ padding: 0 }}
>
{(provided, snapshot) => (
<tr
key={snapshot.toString()}
ref={provided.innerRef}
{...provided.droppableProps}
>
{columnData.map((item, index) => (
<Draggable
key={item.id}
draggableId={item.id}
index={index}
>
{(provided, snapshot) => (
<TableCell
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(snapshot.isDragging, {
...provided.draggableProps.style,
width: '10%',
paddingTop: ".25rem"
})}
padding="checkbox"
sx={{ borderStyle: "solid", borderWidth: '1px 2px 1px 0px', borderColor: 'rgba(0, 0, 0, 0.2)' }}
key={item.id}
>
{item.label}
</TableCell>
)}
</Draggable>
))}
{provided.placeholder}
</tr>
)}
</TableRow>
</TableHead>
</DragDropContext>
);
}
}
this is based on a codesandbox I found with draggable headers. Did I accidentally remove an important styling?
New discovery:
turns out if I add display: 'inline-block' to getItemStyle it doesn't shift things around... but my table header becomes tiny instead of filling up the actual width of the table like this:
what do I need to set?
Related
I have a react component that dynamically loads a widget component using react lazy, with the component path passed as a prop.
It renders fine, but when I drag it, the component flickers between its Suspense fallback and the fully rendered component. How can I prevent the Suspense fallback from being shown while dragging?
The draggable list looks like this:
<DragDropContext
onDragEnd={result => {
console.log(result);
reorder({ result, previousData: dashboard.data });
}}
>
<Title title={`Dashboard`} />
<Droppable droppableId={"dashboard"}>
{(
provided
// snapshot
) => {
return (
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={{
display: "flex",
flexDirection: "column"
}}
>
{Array.isArray(dashboardItems.data) && dashboardItems.data.length > 0 ? (
dashboardItems.data.map((item: any, index: number) => {
return (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided, snapshot) => {
return (
<div ref={provided.innerRef} {...provided.draggableProps}>
<WidgetCard item={item} dragHandleProps={provided.dragHandleProps} />
{!snapshot.isDragging && <AddWidgetControl />}
</div>
);
}}
</Draggable>
);
})
) : (
<Button
onClick={() =>
addDashboardItem.mutate({
index: 0,
dashboardItem: widgets.overview
})
}
>
<Typography variant="body2">Add</Typography>
</Button>
)}
{provided.placeholder}
</div>
);
}}
</Droppable>
</DragDropContext>
and the WidgetCard component that conditionally renders the widgets using lazy looks like this:
const WidgetCard = ({
item,
dragHandleProps
}: {
item: DashboardItemEntity,
dragHandleProps?: any
}) => {
{...}
const renderLoader = () => <p>Loading</p>;
const WidgetComponent = lazy(() => import(`../${item.component}`));
{...}
return (
{...}
<CardContent sx={{ marginTop: 0, paddingTop: 0 }}>
{/* {description} */}
<Box sx={{ marginLeft: 2 }}>
<Suspense fallback={renderLoader()}>
<WidgetComponent item={item} />
</Suspense>
</Box>
</CardContent>
{...}
);
};
const useRowStyles = makeStyles({
root: ({ open }) => ({
backgroundColor: open ? "#F5F6FF" : "white",
backgroundOrigin: "border-box",
spacing: 8,
"& > *": {
height: "64px",
borderSpacing: "10px 10px ",
borderCollapse: "separate",
},
}),
});
<TableRow className={classes.root}>
cell content will comes here
<TableRow>
this is the CSS I am using with TableRow Material-UI but it is not working
Can anybody tell me how I can add space between rows in Material-UI TableRows
I have found many similar question but they are not working in my case
here I have recreated this issue
https://codesandbox.io/s/winter-leftpad-7jnhv?file=/src/App.js
You need to put your TableRow inside Table component and in your TableRow container, add the following styles, it will set the border bottom in every row except the last one:
const useRowStyles = makeStyles({
tableBody: {
"& > :not(:last-child)": {
borderBottom: "25px solid red"
}
}
});
<TableBody className={classes.tableBody}>
<TableRow>
{...}
</TableRow>
<TableRow>
{...}
</TableRow>
</TableBody>
Live Demo
Here is the styling and the table inside the render function.
const style = theme => ({
table: {
maxHeight: '90vh',
},
tableCell: {
textAlign: 'center',
border: "solid",
borderColor: '#000',
borderWidth: 1,
padding: 0,
}
})
<TableContainer component={Paper}>
<Table className={classes.table} aria-label="simple table">
<TableBody>
<TableRow>
<TableCell colSpan={2} className={classes.tableCell}>
{
this.getOilIndicator(data)
}
</TableCell>
And this is the function:
getOilIndicator(data) {
return (
<>
<Typography variant="subtitle1" align="center" >{"OIL LEVEL"}</Typography>
<div>
<Grid xs
item>
{
this.getDevice(_.find(this.state.devices, { "id": 5 }), data)
}
</Grid>
</div>
</>
The problem here is that there's an unnecessary padding at the top even after setting the padding to 0. How to remove this padding. I want to place the text 'Oil Level' at the topmost part of the table cell but because of the padding, I'm unable to do so.
Here is the codesandbox link
function InlineDatePickerDemo(props) {
const [selectedDate, handleDateChange] = useState(new Date());
return (
<Fragment>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
style={{ padding: "20px" }}
autoOk
variant="inline"
inputVariant="outlined"
label="With keyboard"
format="MM/dd/yyyy"
value={selectedDate}
InputAdornmentProps={{ position: "start" }}
onChange={(date) => handleDateChange(date)}
/>
</MuiPickersUtilsProvider>
</Fragment>
);
}
I want to reduce the gapping inside the date-picker box but giving custom styles is not affecting.
I am curious to know why style is not working and what could be the solution for such problem.
What you did is styling the parent component. In order to change the spacing between the components inside the picker, you need to override the following classes in the sub-components:
const useStyles = makeStyles({
root: {
"& .MuiInputBase-root": {
padding: 0,
"& .MuiButtonBase-root": {
padding: 0,
paddingLeft: 10
},
"& .MuiInputBase-input": {
padding: 15,
paddingLeft: 0
}
}
}
});
const classes = useStyles();
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<KeyboardDatePicker
className={classes.root}
{...}
/>
</MuiPickersUtilsProvider>
);
Live Demo
I'm using Material UI with a drawer.
Inside the drawer, is a set of Collapsible lists. When I expand the list, the list text items can be quite long, and the drawer jumps out much wider.
I would like the drawer to have a width that is 30% of the window size, but when I try to set the classes on the drawer, neither root nor modal classNames seem to hold the drawer width in place.
This is the Drawer code:
<Drawer classes={drawerClasses} open={showStandardDrawer} anchor={"right"} onClose={closeDrawer}>
{Array.from(items).map((item, index) => {
return (
<List
key={`list-${index}`}
component="div"
aria-labelledby="nested-list-subheader"
subheader={
<ListSubheader component="div" id="nested-list-subheader">
{item.title}
</ListSubheader>
}
className={classes.root}
>
{ item.elements.map((el, index) => {
return (
<React.Fragment key={index}>
<ListItem key={index} button onClick={() => handleExpand(index)}>
<ListItemText primary={el.name} />
{open[index] ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open[index]} timeout="auto" unmountOnExit>
{ el.descriptions.map((description, index) => {
return (
<List key={`l-${index}`} component="div" disablePadding>
<ListItem button className={classes.nested} >
<ListItemIcon>
<StarBorder />
</ListItemIcon>
<ListItemText primary={description} primaryTypographyProps={{noWrap:true, width:'200px'} } />
</ListItem>
</List>
)})
}
</Collapse>
</React.Fragment>
)
})}
</List>
)
})}
</Drawer>
and these are the classes applied to the drawer ('drawerClasses'):
{
root: {
maxWidth: '200px',
minWidth: '50%',
width: '50%',
overflow: 'hidden'
},
modal: {
maxWidth: '50%',
minWidth: '50%',
width: '50%'
}
}
These aren't the styles I necessarily want, I'm just trying to see if I can get Drawer to size itself instead of sizing around its children.
Instead of modal, use the paper class. The Paper element within the drawer is the main visible container. The root and modal classes are applied to wrapper elements that are positioned in such a manner that their widths won't necessarily affect the Paper width.
Here's a code excerpt from the Permanent drawer demo:
const useStyles = makeStyles(theme => ({
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
}));
...
<Drawer
className={classes.drawer}
variant="permanent"
classes={{
paper: classes.drawerPaper,
}}
anchor="left"
>
https://codesandbox.io/s/zxljh