New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

what's the idiomatic way to apply an onHover handler? #205

Closed
faceyspacey opened this Issue Sep 16, 2016 · 6 comments

Comments

Projects
None yet
6 participants
@faceyspacey
Copy link

faceyspacey commented Sep 16, 2016

It seems to me that React Native Web should have an onHover prop just as <View> and <Text> support onPress. Perhaps I'm missing something.

@MoOx

This comment has been minimized.

Copy link
Contributor

MoOx commented Sep 16, 2016

The thing is you need 2 callbacks to know on and off. But yeah, onMouseEnter & onMouseLeave are related to mouse...

@faceyspacey

This comment has been minimized.

Copy link
Author

faceyspacey commented Sep 16, 2016

excellent thanks @MoOx that solves my problem--didn't know those callbacks were available. it's not available on Touchable components if anyone's wondering, but on <Text> and probably I assume <View as well.

It's starting to seem like a library of web-specific react components should emerge, similar to how the tvOS efforts require components for their unique way of "focusing" elements. For example, <TouchableOpacityHover> would have 2 different opacity based on if it's pressed or simply hovered.

@dsernst

This comment has been minimized.

Copy link

dsernst commented Apr 25, 2017

I created a utility component to make it easy to add a hover style:

HoverableOpacity.js

import React, { Component } from 'react'
import { TouchableOpacity } from 'react-native'

export default class HoverableOpacity extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  render() {
    const { outerStyle, hoverStyle } = this.props

    return (
      <TouchableOpacity
        activeOpacity={1}
        style={[{ cursor: 'inherit' }, outerStyle, this.state.hover ? hoverStyle : {}]}
        onMouseEnter={() => this.setState({ hover: true })}
        onMouseLeave={() => this.setState({ hover: false })}
      >
        <TouchableOpacity {...this.props} />
      </TouchableOpacity>
    )
  }
}

HoverableOpacity.propTypes = {
  hoverStyle: React.PropTypes.shape({}),
  outerStyle: React.PropTypes.shape({}),
}

Usage

Use HoverableOpacity in place of TouchableOpacity.

It can take two new props:

hoverStyle

Style to apply while component is hovered.

E.g.:
hoverStyle={{ backgroundColor: 'hsla(0,0%,100%,0.1)' }}

outerStyle

Style applied to the Hoverable container.

Useful for adding margins outside the hover.

E.g.:
outerStyle={{ margin: 30 }}
@necolas

This comment has been minimized.

Copy link
Owner

necolas commented Apr 25, 2017

You should use setNativeProps (like the touchables do) to update the style without triggering a render of the sub tree.

@lotap

This comment has been minimized.

Copy link

lotap commented Jun 29, 2017

I wrote a component that uses setNativeProps to set styles on hover in case anyone wants to see what that looks like:

import React from 'react'
import { View } from 'react-native'

class HoverableView extends React.Component {
  setStyles = (styles) => {
    this.root.setNativeProps({
      style: styles,
    })
  }

  render() {
    const { onHover, style, ...passThrough } = this.props
    return (
      <View
        ref={(component) => { this.root = component }}
        onMouseEnter={() => this.setStyles(onHover)}
        onMouseLeave={() => this.setStyles(style)}
        style={style}
        {...passThrough}
      />
    )
  }
}

export default HoverableView

Called like this:

<HoverableView
  style={{ backgroundColor: 'transparent', flex: 1 }}
  onHover={{ backgroundColor: '#ff0000' }}
>
  <Text>Foo</Text>
</HoverableView>

One thing to be aware of is that if a style attribute is passed through onHover but is not in the style prop, it will not be overwritten onMouseLeave. (That's why backgroundColor: 'transparent' is set in the style prop of the example)

@Shagamii

This comment has been minimized.

Copy link

Shagamii commented Sep 20, 2018

I created an example that also implements pseudo classes other than hover.
As an example, please try it.
https://github.com/Shagamii/pseudo-class-example/blob/master/src/AccessibleComponent.js

Repository owner locked as resolved and limited conversation to collaborators Sep 20, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.