Осваиваем 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, надеюсь вам это было полезно, я планирую дальше выпустить еще пару статей, где мы разберем другие интересные нюансы этой библиотеки!
Подпишитесь на телеграм канал, чтобы не пропустить выход новых интересных заметок