以下のおもちゃ React component が有って、右に swipe したら右に fade out、左に swipe したら左に fade out したいとしよう。
import React, { useState } from "react";
const items = [
{id: 1, content: "item 1"},
{id: 2, content: "item 2"},
];
export function Example() {
const [currentItemId, setCurrentItemId] = useState(1);
const currentItem = items[currentItemId];
return (
<div className="Example">
{currentItem.content}
</div>
);
}
先づ swipe event を設定しよう。react-swipeable を入れる。
npm install --save react-swipeable
import React, { useCallback, useState } from "react";
import { useSwipeable } from "react-swipeable";
const items = [
{id: 0, content: "item 1"},
{id: 1, content: "item 2"},
];
export function Example() {
const [currentItemId, setCurrentItemId] = useState(0);
const handlers = useSwipable({
onSwipedLeft: useCallback(
(event) => {
setCurrentItemId(currentItemId + 1);
}
),
onSwipedRight: useCallback(
(event) => {
setCurrentItemId(currentItemId - 1);
}
),
});
const currentItem = items[currentItemId];
return (
<div className="Example" {...handlers}>
{currentItem.content}
</div>
);
}
これで .exemple
要素を左に swipe したら次の、右に swipe したら前の item に切り替へられる。(item が無い時の error を處理してゐないので盛大に bug ってはゐるが!)
次に swipe animation を設定しよう。react-transition-group を入れる。
npm install --save react-transition-group
npm install --save-dev @types/react-transition-group
SwitchTransaction が目的に適ふ。
import React, { useCallback, useState } from "react";
import { useSwipeable } from "react-swipeable";
import { CSSTransition, SwitchTransition } from "react-transition-group";
import "./Example.css";
const items = [
{id: 0, content: "item 1"},
{id: 1, content: "item 2"},
];
export function Example() {
const [currentItemId, setCurrentItemId] = useState(0);
const [swipeoutDirection, setSwipeoutDirection] = useState<string | undefined>(undefined);
const handlers = useSwipable({
onSwipedLeft: useCallback(
(event) => {
setCurrentItemId(currentItemId + 1);
setSwipeoutDirection("left");
}
),
onSwipedRight: useCallback(
(event) => {
setCurrentItemId(currentItemId - 1);
setSwipeoutDirection("right");
}
),
});
const currentItem = items[currentItemId];
return (
<SwitchTransition mode="out-in">
<CSSTransition
className="{`swipeout-${swipeoutDirection}`}"
key={currentItem.id}
timeout={300}
>
<div className="Example" {...handlers}>
{currentItem.content}
</div>
</CSSTransition>
</SwitchTransition>
);
}
讀み込ませる CSS を作る。
.Example.swipeout-left-exit {
transform: translateX(0);
}
.Example.swipeout-left-exit-active {
transform: translateX(-800px);
transition: transform 0.3s ease-in-out;
}
.Example.swipeout-right-exit {
transform: translateX(0);
}
.Example.swipeout-right-exit-active {
transform: translateX(800px);
transition: transform 0.3s ease-in-out;
}
これで完成。