Skip to content

Commit

Permalink
fix: tooltip behaviour on web (#4158)
Browse files Browse the repository at this point in the history
Co-authored-by: Luke Walczak <[email protected]>
  • Loading branch information
artus9033 and lukewalczak authored Nov 23, 2023
1 parent 333da92 commit 47bf28d
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 12 deletions.
40 changes: 40 additions & 0 deletions example/src/Examples/TooltipExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Banner,
Chip,
FAB,
IconButton,
List,
ToggleButton,
Tooltip,
Expand All @@ -23,6 +24,23 @@ type Props = {

const MORE_ICON = Platform.OS === 'ios' ? 'dots-horizontal' : 'dots-vertical';

const DURATION_MEDIUM = 1500;
const DURATION_LONG = 3000;

const formOfTransport = [
{ title: 'Car - default delays' },
{ title: 'Airplane - default delays' },
{ title: 'Taxi - long enter delay', enterTouchDelay: DURATION_MEDIUM },
{ title: 'Train - long enter delay', enterTouchDelay: DURATION_MEDIUM },
{ title: 'Ferry - long leave delay', leaveTouchDelay: DURATION_MEDIUM },
{ title: 'Bus - long leave delay', leaveTouchDelay: DURATION_MEDIUM },
{
title: 'Walk - long both delays',
enterTouchDelay: DURATION_MEDIUM,
leaveTouchDelay: DURATION_LONG,
},
];

const TooltipExample = ({ navigation }: Props) => {
React.useLayoutEffect(() => {
navigation.setOptions({
Expand Down Expand Up @@ -57,6 +75,24 @@ const TooltipExample = ({ navigation }: Props) => {
. Continuously display the tooltip as long as the user long-presses or
hovers over the element.
</Banner>
<List.Section title="Icon Buttons">
<View style={styles.iconButtonContainer}>
{formOfTransport.map((transport, index) => (
<Tooltip
key={index}
title={transport.title}
enterTouchDelay={transport.enterTouchDelay}
leaveTouchDelay={transport.leaveTouchDelay}
>
<IconButton
icon={transport.title.split(' ')[0].toLowerCase()}
size={24}
onPress={() => {}}
/>
</Tooltip>
))}
</View>
</List.Section>
<List.Section title="Toggle Buttons">
<ToggleButton.Row
value="bold"
Expand Down Expand Up @@ -144,4 +180,8 @@ const styles = StyleSheet.create({
toggleButtonRow: {
paddingHorizontal: 16,
},
iconButtonContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
},
});
30 changes: 18 additions & 12 deletions src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,21 @@ const Tooltip = ({
tooltip: {},
measured: false,
});
const showTooltipTimer = React.useRef<NodeJS.Timeout>();
const hideTooltipTimer = React.useRef<NodeJS.Timeout>();
const showTooltipTimer = React.useRef<NodeJS.Timeout[]>([]);
const hideTooltipTimer = React.useRef<NodeJS.Timeout[]>([]);
const childrenWrapperRef = React.useRef() as React.MutableRefObject<View>;
const touched = React.useRef(false);

React.useEffect(() => {
return () => {
if (showTooltipTimer.current) {
clearTimeout(showTooltipTimer.current);
if (showTooltipTimer.current.length) {
showTooltipTimer.current.forEach((t) => clearTimeout(t));
showTooltipTimer.current = [];
}

if (hideTooltipTimer.current) {
clearTimeout(hideTooltipTimer.current);
if (hideTooltipTimer.current.length) {
hideTooltipTimer.current.forEach((t) => clearTimeout(t));
hideTooltipTimer.current = [];
}
};
}, []);
Expand All @@ -120,15 +122,17 @@ const Tooltip = ({
};

const handleTouchStart = () => {
if (hideTooltipTimer.current) {
clearTimeout(hideTooltipTimer.current);
if (hideTooltipTimer.current.length) {
hideTooltipTimer.current.forEach((t) => clearTimeout(t));
hideTooltipTimer.current = [];
}

if (isWeb) {
showTooltipTimer.current = setTimeout(() => {
let id = setTimeout(() => {
touched.current = true;
setVisible(true);
}, enterTouchDelay) as unknown as NodeJS.Timeout;
showTooltipTimer.current.push(id);
} else {
touched.current = true;
setVisible(true);
Expand All @@ -137,14 +141,16 @@ const Tooltip = ({

const handleTouchEnd = () => {
touched.current = false;
if (showTooltipTimer.current) {
clearTimeout(showTooltipTimer.current);
if (showTooltipTimer.current.length) {
showTooltipTimer.current.forEach((t) => clearTimeout(t));
showTooltipTimer.current = [];
}

hideTooltipTimer.current = setTimeout(() => {
let id = setTimeout(() => {
setVisible(false);
setMeasurement({ children: {}, tooltip: {}, measured: false });
}, leaveTouchDelay) as unknown as NodeJS.Timeout;
hideTooltipTimer.current.push(id);
};

const mobilePressProps = {
Expand Down

0 comments on commit 47bf28d

Please sign in to comment.