Touchable: add support for 'style' and keyboard

This commit is contained in:
Nicolas Gallagher
2015-09-07 14:40:37 -07:00
parent 38e4de76cd
commit 77fd21ea44
5 changed files with 67 additions and 26 deletions

View File

@@ -1,5 +1,9 @@
# Touchable
A wrapper for making views respond to mouse, keyboard, and touch presses. On
press in, the touchable area can display a highlight color, and the opacity of
the wrapped view can be decreased.
## Props
**activeHighlight** string
@@ -12,9 +16,9 @@ highlight is removed when `onPressOut` is called. Default: `transparent`.
Sets the opacity of the child view when `onPressIn` is called. The opacity is
reset when `onPressOut` is called. Default: `1`.
**component** function or string
**children** element
The backing component. Default: `div`.
A single child element.
**delayLongPress** number
@@ -36,6 +40,10 @@ Delay in ms, from the release of the touch, before `onPressOut` is called. Defau
**onPressOut** function
**style** style
[View](View.md) style
## Examples
```js

View File

@@ -57,6 +57,7 @@ therefore `pointerEvents` is excluded from `style`.
+ `bottom`
+ `boxShadow`
+ `boxSizing`
+ `cursor`
+ `flexBasis`
+ `flexDirection`
+ `flexGrow`

View File

@@ -49,6 +49,7 @@ export default {
boxSizing: string,
clear: string,
color: string,
cursor: string,
direction: string,
display: string,
flexBasis: string,

View File

@@ -1,5 +1,6 @@
import React, { PropTypes } from 'react'
import Tappable from 'react-tappable'
import View from '../View'
class Touchable extends React.Component {
constructor(props, context) {
@@ -7,23 +8,25 @@ class Touchable extends React.Component {
this.state = {
isActive: false
}
this._onLongPress = this._onLongPress.bind(this)
this._onPress = this._onPress.bind(this)
this._onPressIn = this._onPressIn.bind(this)
this._onPressOut = this._onPressOut.bind(this)
}
static propTypes = {
activeHighlight: PropTypes.string,
activeOpacity: PropTypes.number,
children: PropTypes.element,
component: PropTypes.oneOfType([
PropTypes.func,
PropTypes.string
]),
delayLongPress: PropTypes.number,
delayPressIn: PropTypes.number,
delayPressOut: PropTypes.number,
onLongPress: PropTypes.func,
onPress: PropTypes.func,
onPressIn: PropTypes.func,
onPressOut: PropTypes.func
onPressOut: PropTypes.func,
style: View.propTypes.style
}
static defaultProps = {
@@ -32,11 +35,30 @@ class Touchable extends React.Component {
component: 'div',
delayLongPress: 1000,
delayPressIn: 0,
delayPressOut: 0
delayPressOut: 0,
style: View.defaultProps.style
}
_getChildren() {
const { activeOpacity, children } = this.props
return React.cloneElement(React.Children.only(children), {
style: {
...children.props.style,
...(this.state.isActive ? { opacity: activeOpacity } : {})
}
})
}
_onKeyEnter(e, callback) {
var ENTER = 13
if (e.keyCode === ENTER) {
callback(e)
}
}
_onLongPress(e) {
if (this.props.onLongPress) this.props.onLongPress(e)
const event = e
if (this.props.onLongPress) this.props.onLongPress(event)
}
_onPress(e) {
@@ -53,33 +75,41 @@ class Touchable extends React.Component {
if (this.props.onPressOut) this.props.onPressOut(e)
}
_getChildren() {
const { activeOpacity, children } = this.props
return React.cloneElement(React.Children.only(children), {
style: { ...children.props.style, ...(this.state.isActive ? { opacity: activeOpacity } : {}) }
})
}
render() {
const {
activeHighlight,
component,
delayLongPress
delayLongPress,
style
} = this.props
/**
* Creates a wrapping element that can receive beyboard focus. The
* highlight is applied as a background color on this wrapper. The opacity
* is set on the child element, allowing it to have its own background
* color.
*/
return (
<Tappable
children={this._getChildren()}
component={component}
onMouseDown={this._onPressIn.bind(this)}
onMouseUp={this._onPressOut.bind(this)}
onPress={this._onLongPress.bind(this)}
onTap={this._onPress.bind(this)}
onTouchEnd={this._onPressOut.bind(this)}
onTouchStart={this._onPressIn.bind(this)}
component={View}
onKeyDown={(e) => { this._onKeyEnter(e, this._onPressIn) }}
onKeyPress={this._onPress}
onKeyUp={(e) => { this._onKeyEnter(e, this._onPressOut) }}
onMouseDown={this._onPressIn}
onMouseUp={this._onPressOut}
onPress={this._onLongPress}
onTap={this._onPress}
onTouchEnd={this._onPressOut}
onTouchStart={this._onPressIn}
pressDelay={delayLongPress}
pressMoveThreshold={5}
style={{ backgroundColor: this.state.isActive ? activeHighlight : null }}
style={{
...style,
backgroundColor: this.state.isActive ? activeHighlight : null,
cursor: 'pointer',
userSelect: undefined
}}
tabIndex='0'
/>
)
}

View File

@@ -43,6 +43,7 @@ export default {
'bottom',
'boxShadow',
'boxSizing',
'cursor',
'flexBasis',
'flexDirection',
'flexGrow',