Осваиваем react-beautiful-dnd (часть 2)
В прошлый раз мы с вами реализовали базовую дран-н-дроп функциональность для списка, и сейчас наше приложение выглядит примерно так:
А что если мы хотим сделать наш список более кастомизируемым? Именно на этот вопрос и ответит данная статья, мы разберем с вами как нам при помощи библиотеки react-beautiful-dnd сделать наш список таким, чтобы он радовал глаз!
Внешний вид во время перетаскивания
Самым простым способом показать, какой в данный момент элемент перетаскивается - это немного изменить его фон, для этого нам нужно открыть наш компонент Task и добавить в функцию колбека snapshot:
const Container = styled.div`
padding: 8px;
border: 1px solid lightgray;
border-radius: 4px;
margin-bottom: 8px;
background-color: ${props => (props.isDragging ? '#a699f2' : 'white')};
`;
export const Task = ({ index, ...props }) => {
const { id, content } = props.taskData;
return (
<Draggable draggableId={id} index={index}>
{(provided, snapshot /* Добавляем snapshot */) => (
<Container
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
isDragging={snapshot.isDragging} // Прокидываем в качестве пропса в styled-components
>
{content}
</Container>
)}
</Draggable>
);
}snapshot - содержит в себе свойства, которые мы можем использовать для добавления стилизации к нашему компоненту при перетаскивании.
const draggableSnapshot = {
isDragging: true,
draggingOver: 'column-1',
};isDragging- флаг, которые позволяет нам понять, перетаскивается ли объект сейчасdraggingOver- показывает относительно какой droppable области перетаскивается объект
Но останавливаться на этом я не хочу, давайте еще добавим стилей при активном перетаскивании и колонке, для этого мы воспользуемся так же объектом snapshot, но для области дропа, этот объект выглядит примерно так:
const draggableSnapshot = {
isDraggingOver: true,
draggingOverWith: 'task-1',
};isDraggingOver- флаг, которые позволяет нам понять, перетаскивается ли над областью объект сейчасdraggingOverWith- показывает объект перетаскивается над областью
Далее нам с вами нужно немного доработать компонент Column, чтобы воспользоваться этими данными:
const Container = styled.div`
margin: 12px;
padding: 4px;
border: 1px solid lightgray;
border-radius: 4px;
`;
const Title = styled.h2`
padding: 8px;
`;
const TaskList = styled.div`
padding: 8px;
transition: background-color 0.2s ease;
background-color: ${props => props.isDraggingOver ? '#e6e6fa' : 'white'}
`;
export const Column = ({tasks, ...props}) => {
const {id, title} = props.columnData;
return (
<Container>
<Title>{title}</Title>
<Droppable droppableId={id}>
{(provided, snapshot /* Добавляем snapshot */) => (
<TaskList
ref={provided.innerRef}
{...provided.droppableProps}
isDraggingOver={snapshot.isDraggingOver} // Прокидываем в качестве пропса в styled-components
>
{tasks.map((task, idx) => <Task key={task.id} taskData={task} index={idx} />)}
{provided.placeholder}
</TaskList>
)}
</Droppable>
</Container>
);
}Внешний вид с помощью onDragStart и onDragEnd
Так же у нас есть и другая информация, которую мы можем использовать для добавления стилизации нашего приложения. Напомню, что у DragDropContext есть три колбека:
Если объект, который прилетает в onDragEnd мы разобрали раньше, то давайте посмотрим на то, что прилетает в два оставшихся колбека:
// onDragStart
const start = {
draggableId: 'task-1',
type: 'TYPE',
source: {
droppableId: 'column-1',
index: 0,
},
};
// onDragUpdate
const update = {
draggableId: 'task-1',
type: 'TYPE',
source: {
droppableId: 'column-1',
index: 0,
},
destination: {
droppableId: 'column-1',
index: 1,
},
};Давайте просто поиграемся с цветом и будем на обновление менять цвет фона документа, а на начало драга - цвет текста, выглядеть эти функции будут примерно так:
const handleDragStart = result => {
// Меняем цвет шрифта
document.body.style.color = 'purple';
// Накинем плавное изменение цвета
document.body.style.transition = 'background-color 0.2s ease'
};
const handleDragUpdate = result => {
const { destination } = result;
// Вычислим прозрачность фона исходя из
// текущего положение перетаскиваемого элемента
const opacity = destination
? destination.index / Object.keys(data.tasks).length
: 0;
// Покрасим фон
document.body.style.background = `rgba(153, 141, 217, ${opacity})`;
};Но так же как мы добавляем какие-то стили - их надо убрать, поэтому давайте добавим их сброс в handleDragEnd:
const handleDragEnd = result => {
document.body.style.color = 'inherit';
document.body.style.backgroundColor = 'inherit';
// Остальной код функции...
};И вот что мы получаем (я добавили еще немного элементов, чтобы было наглядней изменение фона):
Как видите такой подход тоже возможен, но мне больше по душе тот, который мы реализовали в первую очередь через объекты snapshot, поэтому второй вариант я уберу из своего кода)
Итоги
Вот мы с вами и разобрали как стилизовать компонент перетаскивани при помощи библиотеки react-beautiful-dnd, надеюсь вам это было полезно, я планирую дальше выпустить еще пару статей, где мы разберем другие интересные нюансы этой библиотеки!
Подпишитесь на телеграм канал, чтобы не пропустить выход новых интересных заметок