-
Notifications
You must be signed in to change notification settings - Fork 2
/
SwipeableTabs.tsx
123 lines (112 loc) · 3.14 KB
/
SwipeableTabs.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"use client";
import * as React from "react";
import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}
function CustomTabPanel(props: TabPanelProps & React.ComponentProps<"div">) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box sx={{ p: 3, bgcolor: "#e5e7eb", py: 5 }}>
<Typography>{children} (swipe here)</Typography>
</Box>
)}
</div>
);
}
function a11yProps(index: number) {
return {
id: `simple-tab-${index}`,
"aria-controls": `simple-tabpanel-${index}`,
};
}
export default function SwipeableTabs() {
const [value, setValue] = React.useState(0);
const handleChange = (event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};
const pointerEnterCoordinates = React.useRef(0);
const handleTouchStart = (e: React.TouchEvent) => {
pointerEnterCoordinates.current = e.touches[0].clientX;
};
const handleTouchMove = (e: React.TouchEvent, tabIndex: number) => {
switch (tabIndex) {
case 0:
if (pointerEnterCoordinates.current - e.touches[0].clientX > 8) {
setValue(1);
pointerEnterCoordinates.current = 0;
}
break;
case 1:
if (pointerEnterCoordinates.current - e.touches[0].clientX > 8) {
setValue(2);
pointerEnterCoordinates.current = 0;
} else if (
pointerEnterCoordinates.current - e.touches[0].clientX <
-8
) {
setValue(0);
pointerEnterCoordinates.current = 0;
}
break;
case 2:
if (pointerEnterCoordinates.current - e.touches[0].clientX < -8) {
setValue(1);
pointerEnterCoordinates.current = 0;
}
break;
}
};
return (
<Box sx={{ width: "100%" }}>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<Tabs
value={value}
onChange={handleChange}
aria-label="basic tabs example"
>
<Tab label="Item One" {...a11yProps(0)} />
<Tab label="Item Two" {...a11yProps(1)} />
<Tab label="Item Three" {...a11yProps(2)} />
</Tabs>
</Box>
<CustomTabPanel
value={value}
index={0}
onTouchStart={(e) => handleTouchStart(e)}
onTouchMove={(e) => handleTouchMove(e, 0)}
>
Item One
</CustomTabPanel>
<CustomTabPanel
value={value}
index={1}
onTouchStart={(e) => handleTouchStart(e)}
onTouchMove={(e) => handleTouchMove(e, 1)}
>
Item Two
</CustomTabPanel>
<CustomTabPanel
value={value}
index={2}
onTouchStart={(e) => handleTouchStart(e)}
onTouchMove={(e) => handleTouchMove(e, 2)}
>
Item Three
</CustomTabPanel>
</Box>
);
}