React: react-beautiful-dnd
Tags: react, react-beauriful-dnd
react-beautiful-dnd
Step by step~~
-
npx create-react-app task-app
-
style package (optional)
npm install styled-components
npm install @atlaskit/css-reset
-
install: react-beautiful-dnd
npm install react-beautiful-dnd
-
主要長這樣
實作後 希望可以越來越熟悉~~~
- initial-data.js
const initialData = {
tasks: {
'task-1': { id: 'task-1', content: 'Take out the garbage'},
'task-2': { id: 'task-2', content: 'Watc my favorite show'},
'task-3': { id: 'task-3', content: 'Charge my phone'},
'task-4': { id: 'task-4', content: 'Cook dinner'},
},
columns: {
'column-1': {
id: 'column-1',
title: 'To do',
taskIds: ['task-1', 'task-2', 'task-3', 'task-4',],
}
},
columnOrder: ['column-1'],
};
export default initialData;
- index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { DragDropContext } from 'react-beautiful-dnd';
import initialData from './initial-data';
import Column from './column';
// const App = () => 'Hello World';
class App extends React.Component {
state = initialData;
onDragEnd = result => {
const { destination, source, draggableId } = result;
if (!destination) {
return;
}
if (
destination.droppableId === source.droppableId &&
destination.index === source.index
) {
return;
}
const column = this.state.columns[source.droppableId];
const newTaskIds = Array.from(column.taskIds);
newTaskIds.splice(source.index, 1);
newTaskIds.splice(destination.index, 0, draggableId);
const newColumn = {
...column,
taskIds: newTaskIds,
}
const newState = {
...this.state,
columns: {
...this.state.columns,
[newColumn.id]: newColumn,
}
}
this.setState(newState);
}
/* result example
const result = {
draggabledId: 'task-1',
type: 'Type',
reason: 'DROP'
source: { // location info
droppableId: 'column-1',
index: 0,
},
destination: { // location info
droppableId: 'column-1',
index:1
}
}
*/
render() {
return (
<DragDropContext onDragEnd={this.onDragEnd}>
{this.state.columnOrder.map((columnId) => {
const column = this.state.columns[columnId];
const tasks = column.taskIds.map(taskId => this.state.tasks[taskId])
return <Column key={column.id} column={column} tasks={tasks} />
})}
</DragDropContext>
);
}
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
- column.jsx
import React, { Component } from 'react'
import styled from 'styled-components';
import Task from './task';
import { Droppable } from 'react-beautiful-dnd';
const Container = styled.div`
margin: 8px;
border: 1px solid lightgrey;
border-raduis: 2px;
`;
const Title = styled.h3`
padding: 8px;
`;
const TaskList = styled.div`
padding: 8px;
`;
export class column extends Component {
render() {
return (
<Container>
<Title>{this.props.column.title}</Title>
<Droppable droppableId={this.props.column.id}>
{(provided) => (
<TaskList
ref={provided.innerRef}
{...provided.droppableProps}
>
{this.props.tasks.map((task, index) => <Task key={task.id} task={task} index={index}/>)}
{provided.placeholder}
</TaskList>
)}
</Droppable>
</Container>
);
}
}
export default column
- task.jsx
import React, { Component } from 'react'
import styled from 'styled-components';
import { Draggable } from 'react-beautiful-dnd';
const Container = styled.div`
border: 1px solid lightgrey;
border-raduis:2px;
padding: 8px;
margin-bottom: 8px;
`;
export class Task extends Component {
render() {
return (
<Draggable draggableId={this.props.task.id} index={this.props.index}>
{provided=> (
<Container
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
>
{this.props.task.content}
</Container>
)}
</Draggable>
)
}
}
export default Task