🛎️
【React】react-horizontal-scrolling-menuのライブラリを使って横スクロール
概要
Reactで横スクロールを実装する際に、何か良いライブラリないかなと探してみたところ、asmyshlyaev177/react-horizontal-scrolling-menuというのが良さげな感じがありました。
少し試してみましたので紹介します。
題材
以下のようなイメージで、横スクロールで日付を選択できる表示を実装します。
実装サンプル
サンプルでは、ReactNativeのコンポーネントをベースとしていますが、普通のReactでも同様の実装でいけるかなと思います。
以下がreact-horizontal-scrolling-menu
の使用した箇所です。
import { useContext } from "react";
import { StyleSheet, View, TouchableOpacity } from "react-native";
import { ScrollMenu, VisibilityContext } from "react-horizontal-scrolling-menu";
import Icon from "react-native-vector-icons/FontAwesome";
import {
dateDisplayFormattedStr,
dateKeyFormattedStr,
} from "../../../util/DateUtil";
import SampleDateComponent from "./SampleDateComponent";
export default function SampleDatesSelectComponent() {
let sampleDates = [];
// 表示する日付の設定部分
for (let i = 0; i < 14; i++) {
const targetDate = new Date();
if (i > 0) {
targetDate.setDate(targetDate.getDate() + i);
}
// 日付のフォーマット部分(メソッドのロジックについての記載は割愛)
sampleDates.push({
key: dateKeyFormattedStr(targetDate),
label: dateDisplayFormattedStr(targetDate),
});
}
const Arrow = ({ children, onClick, style }) => {
return (
<>
<TouchableOpacity onPress={onClick} style={style}>
{children}
</TouchableOpacity>
</>
);
};
const LeftArrow = () => {
const { isFirstItemVisible, scrollPrev } = useContext(VisibilityContext);
return (
<Arrow onClick={() => scrollPrev()} style={styles.leftArrow}>
<Icon
name="angle-left"
size={40}
color={isFirstItemVisible ? "white" : "black"}
/>
</Arrow>
);
};
const RightArrow = () => {
const { isLastItemVisible, scrollNext } = useContext(VisibilityContext);
return (
<Arrow onClick={() => scrollNext()} style={styles.rightArrow}>
<Icon
name="angle-right"
size={40}
color={isLastItemVisible ? "white" : "black"}
/>
</Arrow>
);
};
return (
<View style={styles.container}>
<View style={styles.menu}>
<ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
{sampleDates.map((d) => (
<SampleDateComponent
itemId={d.key}
dateKey={d.key}
dateLabel={d.label}
/>
))}
</ScrollMenu>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
alignItems: "center",
},
menu: {
width: "70%",
},
rightArrow: {
marginLeft: "15px",
},
leftArrow: {
marginRight: "15px",
},
});
おまけで日付を選択するコンポーネントは以下です。
import { useContext } from "react";
import { StyleSheet, TouchableOpacity, Text, View } from "react-native";
import { SampleContext } from "../../../context/SampleProvider";
export default function SampleDateComponent(prop) {
const { sampleDate, setSampleDate } = useContext(SampleContext);
const onPress = () => {
setSampleDate(prop.dateKey);
};
return (
<TouchableOpacity onPress={onPress}>
<View
style={
prop.dateKey === sampleDate
? styles.buttonSelected
: styles.buttonNotSelected
}
>
<Text>{prop.dateLabel}</Text>
</View>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
buttonNotSelected: {
borderRadius: 8,
paddingVertical: 10,
paddingHorizontal: 10,
backgroundColor: "#f8f8ff",
marginRight: "5px",
paddingBottom: "20px",
},
buttonSelected: {
borderRadius: 8,
paddingVertical: 10,
paddingHorizontal: 10,
backgroundColor: "#dcdcdc",
marginRight: "5px",
paddingBottom: "20px",
},
});
Discussion