mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-01-12 22:51:09 +08:00
Touchable: add support for 'style' and keyboard
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -57,6 +57,7 @@ therefore `pointerEvents` is excluded from `style`.
|
||||
+ `bottom`
|
||||
+ `boxShadow`
|
||||
+ `boxSizing`
|
||||
+ `cursor`
|
||||
+ `flexBasis`
|
||||
+ `flexDirection`
|
||||
+ `flexGrow`
|
||||
|
||||
@@ -49,6 +49,7 @@ export default {
|
||||
boxSizing: string,
|
||||
clear: string,
|
||||
color: string,
|
||||
cursor: string,
|
||||
direction: string,
|
||||
display: string,
|
||||
flexBasis: string,
|
||||
|
||||
@@ -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'
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ export default {
|
||||
'bottom',
|
||||
'boxShadow',
|
||||
'boxSizing',
|
||||
'cursor',
|
||||
'flexBasis',
|
||||
'flexDirection',
|
||||
'flexGrow',
|
||||
|
||||
Reference in New Issue
Block a user