Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Hover styles in React Native for Web
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
/**
* Touch devices emulate mouse events. This functions makes it possible to know
* if the current modality supports hover (including for multi-modality
* devices).
*/
const createHoverMonitor = () => {
let isHoverEnabled = false;
let lastTouchTime = 0;
function enableHover() {
if (isHoverEnabled || Date.now() - lastTouchTime < 500) {
return;
}
isHoverEnabled = true;
}
function disableHover() {
lastTouchTime = new Date();
if (isHoverEnabled) {
isHoverEnabled = false;
}
}
if (canUseDOM) {
document.addEventListener('touchstart', disableHover, true);
document.addEventListener('mousemove', enableHover, true);
}
return {
get isEnabled() {
return isHoverEnabled;
}
};
};
export default createHoverMonitor;
import createHoverMonitor from './createHoverMonitor';
import { element, func, oneOfType } from 'prop-types';
import React, { Component } from 'react';
const hover = createHoverMonitor();
/**
* Use:
* <Hoverable>
* {(hover) => <View style={hover && styles.hovered} />}
* </Hoverable>
*
* Example: https://imaginary-lycra.glitch.me/
* Example source: https://glitch.com/edit/#!/imaginary-lycra
*/
class Hoverable extends Component {
static displayName = 'Hoverable';
static propTypes = {
children: oneOfType([func, element]).isRequired,
onHoverIn: func,
onHoverOut: func
};
state = { isHovered: false };
_handleMouseEnter = e => {
if (hover.isEnabled && !this.state.isHovered) {
const { onHoverIn } = this.props;
if (onHoverIn) {
onHoverIn();
}
this.setState(() => ({ isHovered: true }));
}
};
_handleMouseLeave = e => {
if (this.state.isHovered) {
const { onHoverOut } = this.props;
if (onHoverOut) {
onHoverOut();
}
this.setState(() => ({ isHovered: false }));
}
};
render() {
const {
children,
/* eslint-disable */
onHoverIn,
onHoverOut
/* eslint-enable */
} = this.props;
const child = typeof children === 'function' ? children(this.state.isHovered) : children;
return React.cloneElement(React.Children.only(child), {
onMouseEnter: this._handleMouseEnter,
onMouseLeave: this._handleMouseLeave
});
}
}
export default Hoverable;
@brunolemos

This comment has been minimized.

Copy link

brunolemos commented Aug 17, 2018

Updated version on CodeSandbox: https://codesandbox.io/s/o9q8vy70l5

@horacioh

This comment has been minimized.

Copy link

horacioh commented Dec 13, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.