created: 2020-10-31T07:54:36.000Z
React/Formikでファイルのドラッグアンドドロップ
Formikに渡すコンポーネントはこんな感じのをつくる
- ドラッグアンドドロップを捕捉するためのイベントは
onDragOver
,onDragLeave
- Formikは
input[type=file]
に対応していないのでonChange
で捕捉する
const { setStatus, status } = props;
const { isFileDragging } = status;
return (
<label
className={classNames("dropzone", { isFileDragging })}
onDragOver={() =>
setStatus({ ...status, isFileDragging: true })
}
onDragLeave={() =>
setStatus({ ...status, isFileDragging: false })
}
>
<input
name="file"
type="file"
onChange={async (event: any) => {
if (event.currentTarget.files) {
await props.setFieldValue(
"file",
event.currentTarget.files[0]
);
await props.submitForm();
}
}}
/>
</label>
)
css
ドラッグアンドドロップできる領域を作るcssについては以下の記事が参考になった
.dropzone {
width: 600px;
height: 180px;
line-height: 180px;
border-style: dotted;
border-width: 2px;
border-color: #ccc;
color: #ccc;
text-align: center;
position: relative;
input[type=file] {
opacity: 0;
height: 100%;
width: 100%;
display: block;
}
}
こんなロジックでCSSを定義するようだ
- labelの中にinput要素を入れる
- label要素を
- position: relative;
- 子要素で100%を指定しても親要素を超えなくなる
- position: relative;
- input要素を
- labelの領域 = input[type=file]の領域 となるようする
- height: 100%;
- width: 100%;
- labelの領域 = input[type=file]の領域 となるようする
classNames
動的にclassNameを変更するときは classNames
パッケージが使いやすい