我想實(shí)現(xiàn)面板,其中的項(xiàng)目放置使用以下布局:
我嘗試了以下代碼:
import React, { useCallback, useEffect } from "react";
import { Box, Grid, Tab, Tabs, Typography } from "@material-ui/core";
import { makeStyles, Theme } from "@material-ui/core/styles";
import { sizing } from "@material-ui/system";
const useStyles1 = makeStyles((theme: Theme) => ({
color: {
backgroundColor: "green",
border: "1px solid black"
}
}));
const useStyles2 = makeStyles((theme: Theme) => ({
color: {
backgroundColor: "mediumvioletred",
border: "1px solid black"
}
}));
const useStyles3 = makeStyles((theme: Theme) => ({
color: {
backgroundColor: "orange",
border: "1px solid black"
}
}));
export default function Hello() {
const classes1 = useStyles1();
const classes2 = useStyles2();
const classes3 = useStyles3();
return (
<>
<Grid
spacing={0}
container
direction="row"
justifyContent="flex-start"
xs={12}
alignItems={"stretch"}
style={{ height: "100vh", overflow: "auto", flexGrow: 1 }}
>
<Grid
// spacing={0}
// container
// direction="row"
// xs={3}
// style={{ height: "100%", overflow: "auto" }}
>
<Grid item xs={12}>
<Grid
className={classes1.color}
container
direction="column"
justifyContent="flex-start"
alignItems="center"
>
<Grid item xs={12}>
<Box m={2}>item link 1</Box>
</Grid>
<Grid item xs={12}>
<Box m={2}>item link 2</Box>
</Grid>
<Grid item xs={12}>
<Box m={2}>item link 3</Box>
</Grid>
<Grid item xs={12}>
<Box m={2}>item link 4</Box>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid
spacing={0}
container
direction="row"
xs={2}
className={classes2.color}
style={{ height: "100%", overflow: "auto" }}
>
<Grid item xs={12}>
<Box m={10}>item 11</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 11</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 13</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 14</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 15</Box>
</Grid>
<Grid item xs={12}>
<Box m={10}>item 16</Box>
</Grid>
</Grid>
<Grid
container
direction="row"
xs={4}
alignItems={"stretch"}
style={{ height: "100%", overflow: "auto" }}
>
<Grid item xs={12}>
<Grid
className={classes3.color}
container
direction="row"
justifyContent="space-around"
alignItems="center"
style={{ width: "100%", overflow: "auto" }}
>
<Grid item xs={12}>
<Box m={2}>item area 1</Box>
</Grid>
<Grid item xs={12}>
<Box m={2}>item area 2</Box>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</>
);
}
完整代碼:https://stackblitz.com/edit/react-ts-k6hpuf?文件=Hello.tsx
你知道我如何使用typescript實(shí)現(xiàn)邊框和正確布局的拖動嗎?
這里有一個使用材質(zhì)UI和react-beautiful-dnd的工作示例
基于像吉拉這樣的基于票的系統(tǒng)使用拖放
App.js
import React, { useState } from "react";
import makeStyles from "@material-ui/core/styles/makeStyles";
import Grid from "@material-ui/core/Grid";
import { DragDropContext } from "react-beautiful-dnd";
import Column from "./Column";
const App = () => {
function range(start, end) {
return Array(end - start + 1)
.fill()
.map((_, idx) => start + idx);
}
const initialColumns = {
links: {
id: "links",
list: [
{ id: "1", text: "text1" },
{ id: "2", text: "text2" },
{ id: "3", text: "text3" }
]
},
items: {
id: "items",
list: []
},
area1: {
id: "area1",
list: []
},
area2: {
id: "area2",
list: [
{ id: "7", text: "text7" },
{ id: "8", text: "text8" },
{ id: "9", text: "text9" }
]
}
};
range(4, 25).forEach((idx) => {
initialColumns.area1.list.push({
id: idx.toString(),
text: "text" + idx.toString()
});
});
range(24, 60).forEach((idx) => {
initialColumns.items.list.push({
id: idx.toString(),
text: "text" + idx.toString()
});
});
const [columns, setColumns] = useState(initialColumns);
const onDragEnd = ({ source, destination }) => {
// Make sure we have a valid destination
if (destination === undefined || destination === null) return null;
// Make sure we're actually moving the item
if (
source.droppableId === destination.droppableId &&
destination.index === source.index
)
return null;
// Set start and end variables
const start = columns[source.droppableId];
const end = columns[destination.droppableId];
// If start is the same as end, we're in the same column
if (start === end) {
// Move the item within the list
// Start by making a new list without the dragged item
console.log(start);
const newList = start.list.filter((_, idx) => idx !== source.index);
// Then insert the item at the right location
newList.splice(destination.index, 0, start.list[source.index]);
// Then create a new copy of the column object
const newCol = {
id: start.id,
list: newList
};
// Update the state
setColumns((state) => ({ ...state, [newCol.id]: newCol }));
return null;
} else {
// If start is different from end, we need to update multiple columns
// Filter the start list like before
const newStartList = start.list.filter((_, idx) => idx !== source.index);
// Create a new start column
const newStartCol = {
id: start.id,
list: newStartList
};
// Make a new end list array
const newEndList = end.list;
// Insert the item into the end list
newEndList.splice(destination.index, 0, start.list[source.index]);
// Create a new end column
const newEndCol = {
id: end.id,
list: newEndList
};
// Update the state
setColumns((state) => ({
...state,
[newStartCol.id]: newStartCol,
[newEndCol.id]: newEndCol
}));
return null;
}
};
return (
<DragDropContext onDragEnd={onDragEnd}>
<Grid
container
direction="row"
justifyContent="space-around"
alignItems="stretch"
>
<Grid item xs={1}>
<Column
isLinks={true}
backgroundColor={"lightgreen"}
height={"90vh"}
width={"100%"}
column={columns.links}
key={columns.links.id}
/>
</Grid>
<Grid item xs={1}>
<Column
backgroundColor={"salmon"}
height={"90vh"}
width={"100%"}
column={columns.items}
key={columns.items.id}
/>
</Grid>
<Grid item xs={9}>
<Column
className={"flex-col-scroll"}
height={"42vh"}
width={"100%"}
backgroundColor={"darkorange"}
column={columns.area1}
key={columns.area1.id}
/>
<Column
className={"flex-col-scroll"}
height={"42vh"}
width={"100%"}
backgroundColor={"darkorange"}
column={columns.area2}
key={columns.area2.id}
/>
</Grid>
</Grid>
</DragDropContext>
);
};
export default App;
const useStyles = makeStyles((theme) => ({}));
專欄. js
import React from "react";
import { Droppable } from "react-beautiful-dnd";
import RootRef from "@material-ui/core/RootRef";
import List from "@material-ui/core/List";
import ListItemCustom from "./ListItemCustom";
import Typography from "@material-ui/core/Typography";
const Column = ({ isLinks, height, width, backgroundColor, column }) => {
const linksStyle = !isLinks
? {
maxHeight: "85%",
overflow: "auto"
}
: {};
return (
<div
style={{
height: height,
width: width,
backgroundColor: backgroundColor,
margin: 10,
padding: 20,
color: "white"
}}
>
<Typography variant={"h4"}>{column.id}</Typography>
<Droppable droppableId={column.id}>
{(provided) => (
<RootRef rootRef={provided.innerRef}>
<List style={linksStyle}>
{column.list.map((itemObject, index) => {
return <ListItemCustom index={index} itemObject={itemObject} />;
})}
{provided.placeholder}
</List>
</RootRef>
)}
</Droppable>
</div>
);
};
export default Column;
ListItemCustom.js
import React from "react";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction";
import IconButton from "@material-ui/core/IconButton";
import { Draggable } from "react-beautiful-dnd";
const ListItemCustom = ({ itemObject, index }) => {
return (
<Draggable draggableId={itemObject.id} key={itemObject.id} index={index}>
{(provided) => (
<ListItem
key={itemObject.id}
role={undefined}
dense
button
ContainerComponent="li"
ContainerProps={{ ref: provided.innerRef }}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<ListItemText
sytles={{ fontFamily: "Quicksand" }}
primary={`${itemObject.text}`}
/>
<ListItemSecondaryAction>
<IconButton
edge="end"
aria-label="comments"
question-uid={itemObject.id}
>
{/* <DeleteIcon /> */}
</IconButton>
</ListItemSecondaryAction>
</ListItem>
)}
</Draggable>
);
};
export default ListItemCustom;
更新1:增加了糟糕的滾動
更新2:增加了滾動和另一個類似于架構(gòu)中的垂直側(cè)邊欄
更新3:使用材質(zhì)UI網(wǎng)格API重新排序布局間距
更新4:增加了主代碼,以防代碼沙盒鏈接中斷