こんにちは、Gaji-Labo アシスタントエンジニアの石垣です。
今回は、前回の記事に引き続き、ドラッグ&ドロップが可能なリストコンポーネントを作成する React 用ライブラリ react-beautiful-dnd でドラッグ&ドロップ中のスタイルを実装する方法についてまとめてみます。
react-beautiful-dnd の基本的な使用方法については前回の記事をご覧いただければと思います。
今回の記事の実装も CodeSandbox で実際に触れることができますので、こちらも是非ご覧ください。
Droppable で snapshot を使ってスタイリングをする
react-beautiful-dnd で使用するコンポーネント Droppable
と Draggable
には、前回ご紹介した provided に加えてもう一つ snapshot
という引数も用意されています。
こちらの引数は、それぞれドラッグ&ドロップ中のコンポーネントの状態を返してくれるものです。
Droppable
の snapshot
は以下のプロパティを持っています。ref: 公式ドキュメント
- isDraggingOver: boolean
リスト上でアイテムがドラッグ中かどうか - draggingOverWith: ?DraggableId
リスト上でドラッグ中のアイテムの id - draggingFromThisWith: ?DraggableId
ドラッグ中のアイテムの id - isUsingPlaceholder: boolean
前回ご紹介した placeholder が使用されているかどうか
draggingOverWith
と draggingFromThisWith
の使い分けが少し分かりづらいですが、draggingFromThisWith
は常にドラッグ中のアイテムの id を返すのに対し、 draggingOverWith
はリストの外にアイテムを持っていくと null を返します。isDraggingOver
も draggingOverWith
と同様、リストからアイテムが外れると false になります。
そのため、draggingFromThisWith
が null かそうでないかを判定することで、リストをアクティブにしたり非アクティブにするようなスタイルの切り替えをすることができます。
以下のサンプルは、ドラッグ中かつリスト上にアイテムがある際は背景色を lightgreen にし、リストからアイテムが外れた際は背景色を lightgrey にするスタイルを追加したものです。
<Droppable droppableId="items">
{(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => {
return (
<ul
{...provided.droppableProps}
ref={provided.innerRef}
style={{
listStyleType: "none",
background: snapshot.isDraggingOver
? "lightgreen"
: snapshot.draggingFromThisWith !== null
? "lightgrey"
: "white"
}}
>
{state.map(({ id, content }, index) => {
return (
<Draggable key={id} draggableId={id} index={index}>
{(provided: DraggableProvided) => {
return (
<li
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<div
style={{
borderBottom: "1px solid black"
}}
>
{content}
</div>
</li>
);
}}
</Draggable>
);
})}
{provided.placeholder}
</ul>
);
}}
</Droppable>
Draggable で snapshot を使ってスタイリングをする
Draggable
の snapshot
は以下のプロパティを持っています。ref: 公式ドキュメント
- isDragging: boolean,
アイテムがドラッグ中かどうか - isDropAnimating: boolean,
アイテムがアニメーションしているかどうか - dropAnimation: ?DropAnimation
ドラッグ&ドロップ用のアニメーションについての情報 - draggingOver: ?DroppableId,
ドラッグしているリストの id - combineWith: ?DraggableId,
アイテムが結合可能な場合、ドラッグしているアイテムの id - combineTargetFor: ?DraggableId,
アイテムが結合可能な場合、結合先のアイテムの id - mode: ?MovementMode,
どのモードでドラッグ&ドロップしているか
マウス操作の際はFLUID
、キーボード操作の際はSNAP
が返ります
この中でドラッグ&ドロップのスタイルを行うにあたり使うのは isDragging
です。isDragging
を判定することで、アイテムがドラッグ中のスタイルを追加することができます。
以下のサンプルは、先程のスタイルに加え、ドラッグ中のアイテムの背景色を lightblue にするスタイルを追加したものです。
注意点として、draggableProps
が渡されている要素には react-beautiful-dnd が持つスタイルが適用されているため、インラインスタイルを追加すると動かなくなってしまいます。そのため、draggableProps
が渡されている要素の子にスタイルを追加しています。
<Droppable droppableId="items">
{(provided: DroppableProvided, snapshot: DroppableStateSnapshot) => {
return (
<ul
{...provided.droppableProps}
ref={provided.innerRef}
style={{
listStyleType: "none",
background: snapshot.isDraggingOver
? "lightgreen"
: snapshot.draggingFromThisWith !== null
? "lightgrey"
: "white"
}}
>
{state.map(({ id, content }, index) => {
return (
<Draggable key={id} draggableId={id} index={index}>
{(
provided: DraggableProvided,
snapshot: DraggableStateSnapshot
) => {
return (
<li
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<div
style={{
borderBottom: "1px solid black",
backgroundColor: snapshot.isDragging
? "lightblue"
: "white"
}}
>
{content}
</div>
</li>
);
}}
</Draggable>
);
})}
{provided.placeholder}
</ul>
);
}}
</Droppable>
これで react-beautiful-dnd でドラッグ&ドロップ中にスタイルを付与することが出来るようになりました。
まとめ
今回は、前回の記事に引き続き react-beautiful-dnd でドラッグ&ドロップ中のスタイルを実装する方法についてまとめました。
react-beautiful-dnd を使っている方の参考になれば幸いです。
Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています
弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?
もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!