UNPKG

25.5 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _extends2 = require('babel-runtime/helpers/extends');
8
9var _extends3 = _interopRequireDefault(_extends2);
10
11var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
12
13var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
14
15var _createClass2 = require('babel-runtime/helpers/createClass');
16
17var _createClass3 = _interopRequireDefault(_createClass2);
18
19var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
20
21var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
22
23var _inherits2 = require('babel-runtime/helpers/inherits');
24
25var _inherits3 = _interopRequireDefault(_inherits2);
26
27var _react = require('react');
28
29var _react2 = _interopRequireDefault(_react);
30
31var _reactDom = require('react-dom');
32
33var _reactDom2 = _interopRequireDefault(_reactDom);
34
35var _PressEvent = require('./PressEvent');
36
37var _PressEvent2 = _interopRequireDefault(_PressEvent);
38
39function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
40
41function keyMirror(obj) {
42 Object.keys(obj).forEach(function (k) {
43 return obj[k] = k;
44 });
45 return obj;
46} // inspired by react-native
47
48function copy(from, list) {
49 var to = {};
50 list.forEach(function (k) {
51 to[k] = from[k];
52 });
53 return to;
54}
55function extractSingleTouch(_nativeEvent) {
56 var nativeEvent = _nativeEvent;
57 if (nativeEvent.nativeEvent) {
58 nativeEvent = nativeEvent.nativeEvent;
59 }
60 var touches = nativeEvent.touches;
61 var changedTouches = nativeEvent.changedTouches;
62 var hasTouches = touches && touches.length > 0;
63 var hasChangedTouches = changedTouches && changedTouches.length > 0;
64 return !hasTouches && hasChangedTouches ? changedTouches[0] : hasTouches ? touches[0] : nativeEvent;
65}
66/**
67 * Touchable states.
68 */
69var States = keyMirror({
70 NOT_RESPONDER: null,
71 RESPONDER_INACTIVE_PRESS_IN: null,
72 RESPONDER_INACTIVE_PRESS_OUT: null,
73 RESPONDER_ACTIVE_PRESS_IN: null,
74 RESPONDER_ACTIVE_PRESS_OUT: null,
75 RESPONDER_ACTIVE_LONG_PRESS_IN: null,
76 RESPONDER_ACTIVE_LONG_PRESS_OUT: null,
77 ERROR: null
78});
79/**
80 * Quick lookup map for states that are considered to be "active"
81 */
82var IsActive = {
83 RESPONDER_ACTIVE_PRESS_OUT: true,
84 RESPONDER_ACTIVE_PRESS_IN: true
85};
86/**
87 * Quick lookup for states that are considered to be "pressing" and are
88 * therefore eligible to result in a "selection" if the press stops.
89 */
90var IsPressingIn = {
91 RESPONDER_INACTIVE_PRESS_IN: true,
92 RESPONDER_ACTIVE_PRESS_IN: true,
93 RESPONDER_ACTIVE_LONG_PRESS_IN: true
94};
95var IsLongPressingIn = {
96 RESPONDER_ACTIVE_LONG_PRESS_IN: true
97};
98/**
99 * Inputs to the state machine.
100 */
101var Signals = keyMirror({
102 DELAY: null,
103 RESPONDER_GRANT: null,
104 RESPONDER_RELEASE: null,
105 RESPONDER_TERMINATED: null,
106 ENTER_PRESS_RECT: null,
107 LEAVE_PRESS_RECT: null,
108 LONG_PRESS_DETECTED: null
109});
110/**
111 * Mapping from States x Signals => States
112 */
113var Transitions = {
114 NOT_RESPONDER: {
115 DELAY: States.ERROR,
116 RESPONDER_GRANT: States.RESPONDER_INACTIVE_PRESS_IN,
117 RESPONDER_RELEASE: States.ERROR,
118 RESPONDER_TERMINATED: States.ERROR,
119 ENTER_PRESS_RECT: States.ERROR,
120 LEAVE_PRESS_RECT: States.ERROR,
121 LONG_PRESS_DETECTED: States.ERROR
122 },
123 RESPONDER_INACTIVE_PRESS_IN: {
124 DELAY: States.RESPONDER_ACTIVE_PRESS_IN,
125 RESPONDER_GRANT: States.ERROR,
126 RESPONDER_RELEASE: States.NOT_RESPONDER,
127 RESPONDER_TERMINATED: States.NOT_RESPONDER,
128 ENTER_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_IN,
129 LEAVE_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_OUT,
130 LONG_PRESS_DETECTED: States.ERROR
131 },
132 RESPONDER_INACTIVE_PRESS_OUT: {
133 DELAY: States.RESPONDER_ACTIVE_PRESS_OUT,
134 RESPONDER_GRANT: States.ERROR,
135 RESPONDER_RELEASE: States.NOT_RESPONDER,
136 RESPONDER_TERMINATED: States.NOT_RESPONDER,
137 ENTER_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_IN,
138 LEAVE_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_OUT,
139 LONG_PRESS_DETECTED: States.ERROR
140 },
141 RESPONDER_ACTIVE_PRESS_IN: {
142 DELAY: States.ERROR,
143 RESPONDER_GRANT: States.ERROR,
144 RESPONDER_RELEASE: States.NOT_RESPONDER,
145 RESPONDER_TERMINATED: States.NOT_RESPONDER,
146 ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_IN,
147 LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_OUT,
148 LONG_PRESS_DETECTED: States.RESPONDER_ACTIVE_LONG_PRESS_IN
149 },
150 RESPONDER_ACTIVE_PRESS_OUT: {
151 DELAY: States.ERROR,
152 RESPONDER_GRANT: States.ERROR,
153 RESPONDER_RELEASE: States.NOT_RESPONDER,
154 RESPONDER_TERMINATED: States.NOT_RESPONDER,
155 ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_IN,
156 LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_OUT,
157 LONG_PRESS_DETECTED: States.ERROR
158 },
159 RESPONDER_ACTIVE_LONG_PRESS_IN: {
160 DELAY: States.ERROR,
161 RESPONDER_GRANT: States.ERROR,
162 RESPONDER_RELEASE: States.NOT_RESPONDER,
163 RESPONDER_TERMINATED: States.NOT_RESPONDER,
164 ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_IN,
165 LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_OUT,
166 LONG_PRESS_DETECTED: States.RESPONDER_ACTIVE_LONG_PRESS_IN
167 },
168 RESPONDER_ACTIVE_LONG_PRESS_OUT: {
169 DELAY: States.ERROR,
170 RESPONDER_GRANT: States.ERROR,
171 RESPONDER_RELEASE: States.NOT_RESPONDER,
172 RESPONDER_TERMINATED: States.NOT_RESPONDER,
173 ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_IN,
174 LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_OUT,
175 LONG_PRESS_DETECTED: States.ERROR
176 },
177 error: {
178 DELAY: States.NOT_RESPONDER,
179 RESPONDER_GRANT: States.RESPONDER_INACTIVE_PRESS_IN,
180 RESPONDER_RELEASE: States.NOT_RESPONDER,
181 RESPONDER_TERMINATED: States.NOT_RESPONDER,
182 ENTER_PRESS_RECT: States.NOT_RESPONDER,
183 LEAVE_PRESS_RECT: States.NOT_RESPONDER,
184 LONG_PRESS_DETECTED: States.NOT_RESPONDER
185 }
186};
187// ==== Typical Constants for integrating into UI components ====
188// const HIT_EXPAND_PX = 20;
189// const HIT_VERT_OFFSET_PX = 10;
190var HIGHLIGHT_DELAY_MS = 130;
191var PRESS_EXPAND_PX = 20;
192var LONG_PRESS_THRESHOLD = 500;
193var LONG_PRESS_DELAY_MS = LONG_PRESS_THRESHOLD - HIGHLIGHT_DELAY_MS;
194var LONG_PRESS_ALLOWED_MOVEMENT = 10;
195var lastClickTime = 0;
196var pressDelay = 200;
197function isAllowPress() {
198 // avoid click penetration
199 return Date.now() - lastClickTime >= pressDelay;
200}
201
202var Touchable = function (_React$Component) {
203 (0, _inherits3['default'])(Touchable, _React$Component);
204
205 function Touchable() {
206 (0, _classCallCheck3['default'])(this, Touchable);
207
208 var _this = (0, _possibleConstructorReturn3['default'])(this, (Touchable.__proto__ || Object.getPrototypeOf(Touchable)).apply(this, arguments));
209
210 _this.state = {
211 active: false
212 };
213 _this.onTouchStart = function (e) {
214 _this.callChildEvent('onTouchStart', e);
215 _this.lockMouse = true;
216 if (_this.releaseLockTimer) {
217 clearTimeout(_this.releaseLockTimer);
218 }
219 _this.touchableHandleResponderGrant(e.nativeEvent);
220 };
221 _this.onTouchMove = function (e) {
222 _this.callChildEvent('onTouchMove', e);
223 _this.touchableHandleResponderMove(e.nativeEvent);
224 };
225 _this.onTouchEnd = function (e) {
226 _this.callChildEvent('onTouchEnd', e);
227 _this.releaseLockTimer = setTimeout(function () {
228 _this.lockMouse = false;
229 }, 300);
230 _this.touchableHandleResponderRelease(new _PressEvent2['default'](e.nativeEvent));
231 };
232 _this.onTouchCancel = function (e) {
233 _this.callChildEvent('onTouchCancel', e);
234 _this.releaseLockTimer = setTimeout(function () {
235 _this.lockMouse = false;
236 }, 300);
237 _this.touchableHandleResponderTerminate(e.nativeEvent);
238 };
239 _this.onMouseDown = function (e) {
240 _this.callChildEvent('onMouseDown', e);
241 if (_this.lockMouse) {
242 return;
243 }
244 _this.touchableHandleResponderGrant(e.nativeEvent);
245 document.addEventListener('mousemove', _this.touchableHandleResponderMove, false);
246 document.addEventListener('mouseup', _this.onMouseUp, false);
247 };
248 _this.onMouseUp = function (e) {
249 document.removeEventListener('mousemove', _this.touchableHandleResponderMove, false);
250 document.removeEventListener('mouseup', _this.onMouseUp, false);
251 _this.touchableHandleResponderRelease(new _PressEvent2['default'](e));
252 };
253 _this.touchableHandleResponderMove = function (e) {
254 if (!_this.touchable.startMouse) {
255 return;
256 }
257 // Measurement may not have returned yet.
258 if (!_this.touchable.dimensionsOnActivate || _this.touchable.touchState === States.NOT_RESPONDER) {
259 return;
260 }
261 // Not enough time elapsed yet, wait for highlight -
262 // this is just a perf optimization.
263 if (_this.touchable.touchState === States.RESPONDER_INACTIVE_PRESS_IN) {
264 return;
265 }
266 var touch = extractSingleTouch(e);
267 var pageX = touch && touch.pageX;
268 var pageY = touch && touch.pageY;
269 if (_this.pressInLocation) {
270 var movedDistance = _this._getDistanceBetweenPoints(pageX, pageY, _this.pressInLocation.pageX, _this.pressInLocation.pageY);
271 if (movedDistance > LONG_PRESS_ALLOWED_MOVEMENT) {
272 _this._cancelLongPressDelayTimeout();
273 }
274 }
275 if (_this.checkTouchWithinActive(e)) {
276 _this._receiveSignal(Signals.ENTER_PRESS_RECT, e);
277 var curState = _this.touchable.touchState;
278 if (curState === States.RESPONDER_INACTIVE_PRESS_IN) {
279 _this._cancelLongPressDelayTimeout();
280 }
281 } else {
282 _this._cancelLongPressDelayTimeout();
283 _this._receiveSignal(Signals.LEAVE_PRESS_RECT, e);
284 }
285 };
286 return _this;
287 }
288
289 (0, _createClass3['default'])(Touchable, [{
290 key: 'componentWillMount',
291 value: function componentWillMount() {
292 this.touchable = { touchState: undefined };
293 }
294 }, {
295 key: 'componentDidMount',
296 value: function componentDidMount() {
297 this.root = _reactDom2['default'].findDOMNode(this);
298 }
299 }, {
300 key: 'componentDidUpdate',
301 value: function componentDidUpdate() {
302 this.root = _reactDom2['default'].findDOMNode(this);
303 // disabled auto clear active state
304 if (this.props.disabled && this.state.active) {
305 this.setState({
306 active: false
307 });
308 }
309 }
310 }, {
311 key: 'componentWillUnmount',
312 value: function componentWillUnmount() {
313 if (this.releaseLockTimer) {
314 clearTimeout(this.releaseLockTimer);
315 }
316 if (this.touchableDelayTimeout) {
317 clearTimeout(this.touchableDelayTimeout);
318 }
319 if (this.longPressDelayTimeout) {
320 clearTimeout(this.longPressDelayTimeout);
321 }
322 if (this.pressOutDelayTimeout) {
323 clearTimeout(this.pressOutDelayTimeout);
324 }
325 }
326 }, {
327 key: 'callChildEvent',
328 value: function callChildEvent(event, e) {
329 var childHandle = _react2['default'].Children.only(this.props.children).props[event];
330 if (childHandle) {
331 childHandle(e);
332 }
333 }
334 }, {
335 key: '_remeasureMetricsOnInit',
336 value: function _remeasureMetricsOnInit(e) {
337 var root = this.root;
338
339 var touch = extractSingleTouch(e);
340 var boundingRect = root.getBoundingClientRect();
341 this.touchable = {
342 touchState: this.touchable.touchState,
343 startMouse: {
344 pageX: touch.pageX,
345 pageY: touch.pageY
346 },
347 positionOnGrant: {
348 left: boundingRect.left + window.pageXOffset,
349 top: boundingRect.top + window.pageYOffset,
350 width: boundingRect.width,
351 height: boundingRect.height,
352 clientLeft: boundingRect.left,
353 clientTop: boundingRect.top
354 }
355 };
356 }
357 }, {
358 key: 'touchableHandleResponderGrant',
359 value: function touchableHandleResponderGrant(e) {
360 var _this2 = this;
361
362 this.touchable.touchState = States.NOT_RESPONDER;
363 if (this.pressOutDelayTimeout) {
364 clearTimeout(this.pressOutDelayTimeout);
365 this.pressOutDelayTimeout = null;
366 }
367 if (this.props.fixClickPenetration && !isAllowPress()) {
368 return;
369 }
370 this._remeasureMetricsOnInit(e);
371 this._receiveSignal(Signals.RESPONDER_GRANT, e);
372 var _props = this.props,
373 delayMS = _props.delayPressIn,
374 longDelayMS = _props.delayLongPress;
375
376 if (delayMS) {
377 this.touchableDelayTimeout = setTimeout(function () {
378 _this2._handleDelay(e);
379 }, delayMS);
380 } else {
381 this._handleDelay(e);
382 }
383 var longPressEvent = new _PressEvent2['default'](e);
384 this.longPressDelayTimeout = setTimeout(function () {
385 _this2._handleLongDelay(longPressEvent);
386 }, longDelayMS + delayMS);
387 }
388 }, {
389 key: 'checkScroll',
390 value: function checkScroll(e) {
391 var positionOnGrant = this.touchable.positionOnGrant;
392 // container or window scroll
393 var boundingRect = this.root.getBoundingClientRect();
394 if (boundingRect.left !== positionOnGrant.clientLeft || boundingRect.top !== positionOnGrant.clientTop) {
395 this._receiveSignal(Signals.RESPONDER_TERMINATED, e);
396 return false;
397 }
398 }
399 }, {
400 key: 'touchableHandleResponderRelease',
401 value: function touchableHandleResponderRelease(e) {
402 if (!this.touchable.startMouse) {
403 return;
404 }
405 var touch = extractSingleTouch(e);
406 if (Math.abs(touch.pageX - this.touchable.startMouse.pageX) > 30 || Math.abs(touch.pageY - this.touchable.startMouse.pageY) > 30) {
407 this._receiveSignal(Signals.RESPONDER_TERMINATED, e);
408 return;
409 }
410 if (this.checkScroll(e) === false) {
411 return;
412 }
413 this._receiveSignal(Signals.RESPONDER_RELEASE, e);
414 }
415 }, {
416 key: 'touchableHandleResponderTerminate',
417 value: function touchableHandleResponderTerminate(e) {
418 if (!this.touchable.startMouse) {
419 return;
420 }
421 this._receiveSignal(Signals.RESPONDER_TERMINATED, e);
422 }
423 }, {
424 key: 'checkTouchWithinActive',
425 value: function checkTouchWithinActive(e) {
426 var positionOnGrant = this.touchable.positionOnGrant;
427 var _props2 = this.props,
428 _props2$pressRetentio = _props2.pressRetentionOffset,
429 pressRetentionOffset = _props2$pressRetentio === undefined ? {} : _props2$pressRetentio,
430 hitSlop = _props2.hitSlop;
431
432 var pressExpandLeft = pressRetentionOffset.left;
433 var pressExpandTop = pressRetentionOffset.top;
434 var pressExpandRight = pressRetentionOffset.right;
435 var pressExpandBottom = pressRetentionOffset.bottom;
436 if (hitSlop) {
437 pressExpandLeft += hitSlop.left;
438 pressExpandTop += hitSlop.top;
439 pressExpandRight += hitSlop.right;
440 pressExpandBottom += hitSlop.bottom;
441 }
442 var touch = extractSingleTouch(e);
443 var pageX = touch && touch.pageX;
444 var pageY = touch && touch.pageY;
445 return pageX > positionOnGrant.left - pressExpandLeft && pageY > positionOnGrant.top - pressExpandTop && pageX < positionOnGrant.left + positionOnGrant.width + pressExpandRight && pageY < positionOnGrant.top + positionOnGrant.height + pressExpandBottom;
446 }
447 }, {
448 key: 'callProp',
449 value: function callProp(name, e) {
450 if (this.props[name] && !this.props.disabled) {
451 this.props[name](e);
452 }
453 }
454 }, {
455 key: 'touchableHandleActivePressIn',
456 value: function touchableHandleActivePressIn(e) {
457 this.setActive(true);
458 this.callProp('onPressIn', e);
459 }
460 }, {
461 key: 'touchableHandleActivePressOut',
462 value: function touchableHandleActivePressOut(e) {
463 this.setActive(false);
464 this.callProp('onPressOut', e);
465 }
466 }, {
467 key: 'touchableHandlePress',
468 value: function touchableHandlePress(e) {
469 if ((0, _PressEvent.shouldFirePress)(e)) {
470 this.callProp('onPress', e);
471 }
472 lastClickTime = Date.now();
473 }
474 }, {
475 key: 'touchableHandleLongPress',
476 value: function touchableHandleLongPress(e) {
477 if ((0, _PressEvent.shouldFirePress)(e)) {
478 this.callProp('onLongPress', e);
479 }
480 }
481 }, {
482 key: 'setActive',
483 value: function setActive(active) {
484 if (this.props.activeClassName || this.props.activeStyle) {
485 this.setState({
486 active: active
487 });
488 }
489 }
490 }, {
491 key: '_remeasureMetricsOnActivation',
492 value: function _remeasureMetricsOnActivation() {
493 this.touchable.dimensionsOnActivate = this.touchable.positionOnGrant;
494 }
495 }, {
496 key: '_handleDelay',
497 value: function _handleDelay(e) {
498 this.touchableDelayTimeout = null;
499 this._receiveSignal(Signals.DELAY, e);
500 }
501 }, {
502 key: '_handleLongDelay',
503 value: function _handleLongDelay(e) {
504 this.longPressDelayTimeout = null;
505 var curState = this.touchable.touchState;
506 if (curState !== States.RESPONDER_ACTIVE_PRESS_IN && curState !== States.RESPONDER_ACTIVE_LONG_PRESS_IN) {
507 console.error('Attempted to transition from state `' + curState + '` to `' + States.RESPONDER_ACTIVE_LONG_PRESS_IN + '`, which is not supported. This is ' + 'most likely due to `Touchable.longPressDelayTimeout` not being cancelled.');
508 } else {
509 this._receiveSignal(Signals.LONG_PRESS_DETECTED, e);
510 }
511 }
512 }, {
513 key: '_receiveSignal',
514 value: function _receiveSignal(signal, e) {
515 var curState = this.touchable.touchState;
516 var nextState = Transitions[curState] && Transitions[curState][signal];
517 if (!nextState) {
518 return;
519 }
520 if (nextState === States.ERROR) {
521 return;
522 }
523 if (curState !== nextState) {
524 this._performSideEffectsForTransition(curState, nextState, signal, e);
525 this.touchable.touchState = nextState;
526 }
527 }
528 }, {
529 key: '_cancelLongPressDelayTimeout',
530 value: function _cancelLongPressDelayTimeout() {
531 if (this.longPressDelayTimeout) {
532 clearTimeout(this.longPressDelayTimeout);
533 this.longPressDelayTimeout = null;
534 }
535 }
536 }, {
537 key: '_isHighlight',
538 value: function _isHighlight(state) {
539 return state === States.RESPONDER_ACTIVE_PRESS_IN || state === States.RESPONDER_ACTIVE_LONG_PRESS_IN;
540 }
541 }, {
542 key: '_savePressInLocation',
543 value: function _savePressInLocation(e) {
544 var touch = extractSingleTouch(e);
545 var pageX = touch && touch.pageX;
546 var pageY = touch && touch.pageY;
547 this.pressInLocation = { pageX: pageX, pageY: pageY };
548 }
549 }, {
550 key: '_getDistanceBetweenPoints',
551 value: function _getDistanceBetweenPoints(aX, aY, bX, bY) {
552 var deltaX = aX - bX;
553 var deltaY = aY - bY;
554 return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
555 }
556 }, {
557 key: '_performSideEffectsForTransition',
558 value: function _performSideEffectsForTransition(curState, nextState, signal, e) {
559 var curIsHighlight = this._isHighlight(curState);
560 var newIsHighlight = this._isHighlight(nextState);
561 var isFinalSignal = signal === Signals.RESPONDER_TERMINATED || signal === Signals.RESPONDER_RELEASE;
562 if (isFinalSignal) {
563 this._cancelLongPressDelayTimeout();
564 }
565 if (!IsActive[curState] && IsActive[nextState]) {
566 this._remeasureMetricsOnActivation();
567 }
568 if (IsPressingIn[curState] && signal === Signals.LONG_PRESS_DETECTED) {
569 this.touchableHandleLongPress(e);
570 }
571 if (newIsHighlight && !curIsHighlight) {
572 this._startHighlight(e);
573 } else if (!newIsHighlight && curIsHighlight) {
574 this._endHighlight(e);
575 }
576 if (IsPressingIn[curState] && signal === Signals.RESPONDER_RELEASE) {
577 var hasLongPressHandler = !!this.props.onLongPress;
578 var pressIsLongButStillCallOnPress = IsLongPressingIn[curState] && (!hasLongPressHandler || !this.props.longPressCancelsPress // or we're told to ignore it.
579 );
580 var shouldInvokePress = !IsLongPressingIn[curState] || pressIsLongButStillCallOnPress;
581 if (shouldInvokePress) {
582 if (!newIsHighlight && !curIsHighlight) {
583 // we never highlighted because of delay, but we should highlight now
584 this._startHighlight(e);
585 this._endHighlight(e);
586 }
587 this.touchableHandlePress(e);
588 }
589 }
590 if (this.touchableDelayTimeout) {
591 clearTimeout(this.touchableDelayTimeout);
592 this.touchableDelayTimeout = null;
593 }
594 }
595 }, {
596 key: '_startHighlight',
597 value: function _startHighlight(e) {
598 this._savePressInLocation(e);
599 this.touchableHandleActivePressIn(e);
600 }
601 }, {
602 key: '_endHighlight',
603 value: function _endHighlight(e) {
604 var _this3 = this;
605
606 if (this.props.delayPressOut) {
607 this.pressOutDelayTimeout = setTimeout(function () {
608 _this3.touchableHandleActivePressOut(e);
609 }, this.props.delayPressOut);
610 } else {
611 this.touchableHandleActivePressOut(e);
612 }
613 }
614 }, {
615 key: 'render',
616 value: function render() {
617 var _props3 = this.props,
618 children = _props3.children,
619 disabled = _props3.disabled,
620 activeStyle = _props3.activeStyle,
621 activeClassName = _props3.activeClassName;
622
623 var events = disabled ? undefined : copy(this, ['onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel', 'onMouseDown']);
624 var child = _react2['default'].Children.only(children);
625 if (!disabled && this.state.active) {
626 var _child$props = child.props,
627 style = _child$props.style,
628 className = _child$props.className;
629
630 if (activeStyle) {
631 style = (0, _extends3['default'])({}, style, activeStyle);
632 }
633 if (activeClassName) {
634 if (className) {
635 className += ' ' + activeClassName;
636 } else {
637 className = activeClassName;
638 }
639 }
640 return _react2['default'].cloneElement(child, (0, _extends3['default'])({ className: className,
641 style: style }, events));
642 }
643 return _react2['default'].cloneElement(child, events);
644 }
645 }]);
646 return Touchable;
647}(_react2['default'].Component);
648
649exports['default'] = Touchable;
650
651Touchable.defaultProps = {
652 fixClickPenetration: false,
653 disabled: false,
654 delayPressIn: HIGHLIGHT_DELAY_MS,
655 delayLongPress: LONG_PRESS_DELAY_MS,
656 delayPressOut: 100,
657 pressRetentionOffset: {
658 left: PRESS_EXPAND_PX,
659 right: PRESS_EXPAND_PX,
660 top: PRESS_EXPAND_PX,
661 bottom: PRESS_EXPAND_PX
662 },
663 hitSlop: undefined,
664 longPressCancelsPress: true
665};
666module.exports = exports['default'];
\No newline at end of file