Skip to content

Commit 4154850

Browse files
committed
click to open and maximize
1 parent 069d6e3 commit 4154850

1 file changed

Lines changed: 69 additions & 23 deletions

File tree

src/sidebar/BottomSheet.tsx

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import React, {useState, useRef, ReactNode, useEffect, FC, useCallback} from 'react';
1+
import React, {FC, ReactNode, useEffect, useRef, useState} from 'react';
22
import styles from './BottomSheet.module.css'
3-
import {useMediaQuery} from "react-responsive";
4-
import {set} from "ol/transform";
53

64
interface BottomSheetProps {
75
children?: ReactNode;
86
}
97

10-
const BottomSheet: FC<BottomSheetProps> = ({ children }) => {
8+
const BottomSheet: FC<BottomSheetProps> = ({children}) => {
9+
const [isMouseDownOnBottomSheet, setMouseDownOnBottomSheet] = useState(false)
1110
const [isDragging, setIsDragging] = useState(false)
1211
const [childrenHeight, setChildrenHeight] = useState(-1)
1312
const offsetYRef = useRef(0)
@@ -17,30 +16,40 @@ const BottomSheet: FC<BottomSheetProps> = ({ children }) => {
1716
const defaultHeight = useRef(0);
1817

1918
const setHeight = (y: number) => {
20-
if(bottomSheetRef.current)
19+
if (bottomSheetRef.current)
2120
bottomSheetRef.current.style.top = `${y}px`
2221
}
2322

2423
const handleMouseDown = (e: MouseEvent | TouchEvent) => {
25-
if(!bottomSheetRef.current) return
24+
if (!bottomSheetRef.current) return
2625

27-
const clickInside = e.target instanceof Node && bottomSheetRef.current.contains(e.target)
26+
const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY
27+
// negative value means above the edge
28+
offsetYRef.current = clientY - (bottomSheetRef.current.getBoundingClientRect().top || 0)
29+
const clickInside = offsetYRef.current >= 0 // e.target instanceof Node && bottomSheetRef.current.contains(e.target)
2830
if (!clickInside) {
31+
// TODO: why hiding bottom sheet does not work with mouse?
2932
setHeight(window.innerHeight - minHeight)
3033
return
3134
}
3235

33-
const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY
34-
setIsDragging(true)
35-
offsetYRef.current = clientY - (bottomSheetRef.current.getBoundingClientRect().top || 0)
36+
setMouseDownOnBottomSheet(true)
3637
}
3738

3839
const handleMouseMove = (e: MouseEvent | TouchEvent) => {
39-
if (bottomSheetRef.current && isDragging) {
40+
const clickInsideChildren = e.target instanceof Node && childrenRef.current?.contains(e.target)
41+
if (clickInsideChildren && childrenHeight > defaultHeight.current) {
42+
// if scrolling avoid dragging
43+
return
44+
}
45+
46+
if (bottomSheetRef.current && isMouseDownOnBottomSheet) {
47+
setIsDragging(true)
48+
4049
const clientY = 'touches' in e ? e.touches[0].clientY : e.clientY
4150
let y = clientY - offsetYRef.current
42-
if(y < 0) y = 0 // top border
43-
else if(y > (window.innerHeight - minHeight)) y = window.innerHeight - minHeight
51+
if (y < 0) y = 0 // top border
52+
else if (y > (window.innerHeight - minHeight)) y = window.innerHeight - minHeight
4453

4554
setHeight(y)
4655

@@ -50,13 +59,37 @@ const BottomSheet: FC<BottomSheetProps> = ({ children }) => {
5059
}
5160
const handleTouchStart = (e: MouseEvent | TouchEvent) => handleMouseDown(e)
5261
const handleTouchMove = (e: MouseEvent | TouchEvent) => handleMouseMove(e)
53-
const handleMouseUp = () => setIsDragging(false)
62+
const handleMouseUp = (e: MouseEvent | TouchEvent) => {
63+
const clickInsideChildren = e.target instanceof Node && childrenRef.current?.contains(e.target)
64+
if (clickInsideChildren) return
65+
if (!isMouseDownOnBottomSheet) return
66+
67+
if (bottomSheetRef.current && !isDragging) {
68+
// use changedTouches as e.touches[0] is empty on iOS (does it make sense as the 'touch gesture' was already finished?)
69+
const clientY = 'changedTouches' in e ? e.changedTouches[0]?.clientY : e.clientY
70+
let y = clientY - offsetYRef.current
71+
72+
// alert('mouseUp, y=' + clientY + '-' + offsetYRef.current + ', ' + (window.innerHeight - defaultHeight.current))
73+
// if clicked
74+
if (y > (window.innerHeight - defaultHeight.current) || y <= 0) {
75+
// ... and closed (or max) then medium size
76+
setHeight(window.innerHeight - defaultHeight.current)
77+
} else {
78+
// ... and medium then maximum size
79+
setHeight(0)
80+
}
81+
}
82+
setIsDragging(false)
83+
setMouseDownOnBottomSheet(false)
84+
85+
// prevent us from clicking on elements in the bottom pane directly after we e.g. maximized it (happened only on Android)
86+
e.preventDefault()
87+
}
5488

5589
useEffect(() => {
5690
if (childrenRef.current) {
57-
if(defaultHeight.current <= 0)
58-
defaultHeight.current = childrenRef.current.offsetHeight + 80 /* +80 for one routing result */
59-
console.log("height:"+defaultHeight.current)
91+
if (defaultHeight.current <= 0)
92+
defaultHeight.current = childrenRef.current.offsetHeight + 80 // TODO use dynamic value instead of 80 for one routing result
6093
setHeight(window.innerHeight - defaultHeight.current)
6194
}
6295
}, []);
@@ -75,7 +108,7 @@ const BottomSheet: FC<BottomSheetProps> = ({ children }) => {
75108
document.removeEventListener('mousemove', handleMouseMove)
76109
document.removeEventListener('mouseup', handleMouseUp)
77110
};
78-
}, [isDragging])
111+
}, [isMouseDownOnBottomSheet, isDragging])
79112

80113
return (
81114
<div ref={bottomSheetRef} className={styles.bottomSheet}>
@@ -84,12 +117,25 @@ const BottomSheet: FC<BottomSheetProps> = ({ children }) => {
84117
onMouseDown={(e: React.MouseEvent) => handleMouseDown(e as any)}
85118
onTouchStart={(e: React.TouchEvent) => handleTouchStart(e as any)}
86119
>
87-
<span style={{width: '18px', height: '4px', borderRadius: '99px', backgroundColor: 'rgb(221, 221, 221)', transform: 'translateX(2px) rotate(0deg)'}}></span>
88-
<span style={{width: '18px', height: '4px', borderRadius: '99px', backgroundColor: 'rgb(221, 221, 221)', transform: 'translateX(-2px) rotate(0deg)'}}></span>
89-
90-
{/*<span style={{}} onClick={() => setHeight(window.innerHeight - minHeight)}>X</span>*/}
120+
<span style={{
121+
width: '18px',
122+
height: '4px',
123+
borderRadius: '99px',
124+
backgroundColor: 'rgb(221, 221, 221)',
125+
transform: 'translateX(2px) rotate(0deg)'
126+
}}></span>
127+
<span style={{
128+
width: '18px',
129+
height: '4px',
130+
borderRadius: '99px',
131+
backgroundColor: 'rgb(221, 221, 221)',
132+
transform: 'translateX(-2px) rotate(0deg)'
133+
}}></span>
91134
</div>
92-
<div ref={childrenRef} style={childrenHeight > defaultHeight.current ? {overflowY: 'scroll', height: childrenHeight + 'px'}: {}}>
135+
<div ref={childrenRef} style={childrenHeight > defaultHeight.current ? {
136+
overflowY: 'scroll',
137+
height: childrenHeight + 'px'
138+
} : {}}>
93139
{children}
94140
</div>
95141
</div>

0 commit comments

Comments
 (0)