UNPKG

react-native-animateable-text

Version:

A fork of React Native's <Text/> component that supports Animated Values

282 lines (226 loc) 8.21 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * * @format */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnimateableText = void 0; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } const DeprecatedTextPropTypes = require('deprecated-react-native-prop-types/DeprecatedTextPropTypes'); const React = require('react'); const ReactNativeViewAttributes = require('react-native/Libraries/Components/View/ReactNativeViewAttributes'); const Touchable = require('react-native/Libraries/Components/Touchable/Touchable'); const createReactNativeComponentClass = require('react-native/Libraries/Renderer/shims/createReactNativeComponentClass'); const nullthrows = require('nullthrows'); const processColor = require('react-native/Libraries/StyleSheet/processColor'); const PRESS_RECT_OFFSET = { top: 20, left: 20, right: 20, bottom: 30 }; const viewConfig = { validAttributes: { ...ReactNativeViewAttributes.UIView, isHighlighted: true, numberOfLines: true, ellipsizeMode: true, allowFontScaling: true, maxFontSizeMultiplier: true, disabled: true, selectable: true, selectionColor: true, adjustsFontSizeToFit: true, minimumFontScale: true, textBreakStrategy: true, onTextLayout: true, onInlineViewLayout: true, dataDetectorType: true, android_hyphenationFrequency: true, text: true }, directEventTypes: { topTextLayout: { registrationName: 'onTextLayout' }, topInlineViewLayout: { registrationName: 'onInlineViewLayout' } }, uiViewClassName: 'JBAnimatedText' }; /** * A React component for displaying text. * * See https://reactnative.dev/docs/text.html */ class TouchableText extends React.Component { constructor(...args) { super(...args); _defineProperty(this, "touchableGetPressRectOffset", void 0); _defineProperty(this, "touchableHandleActivePressIn", void 0); _defineProperty(this, "touchableHandleActivePressOut", void 0); _defineProperty(this, "touchableHandleLongPress", void 0); _defineProperty(this, "touchableHandlePress", void 0); _defineProperty(this, "touchableHandleResponderGrant", void 0); _defineProperty(this, "touchableHandleResponderMove", void 0); _defineProperty(this, "touchableHandleResponderRelease", void 0); _defineProperty(this, "touchableHandleResponderTerminate", void 0); _defineProperty(this, "touchableHandleResponderTerminationRequest", void 0); _defineProperty(this, "state", { ...Touchable.Mixin.touchableGetInitialState(), isHighlighted: false, createResponderHandlers: this._createResponseHandlers.bind(this), responseHandlers: null }); } static getDerivedStateFromProps(nextProps, prevState) { return prevState.responseHandlers == null && isTouchable(nextProps) ? { responseHandlers: prevState.createResponderHandlers() } : null; } render() { let props = this.props; if (isTouchable(props)) { props = { ...props, ...this.state.responseHandlers, isHighlighted: this.state.isHighlighted }; } if (props.selectionColor != null) { props = { ...props, selectionColor: processColor(props.selectionColor) }; } if (__DEV__) { if (Touchable.TOUCH_TARGET_DEBUG && props.onPress != null) { props = { ...props, style: [props.style, { color: 'magenta' }] }; } } return /*#__PURE__*/React.createElement(RCTText, _extends({}, props, { ref: props.forwardedRef })); } _createResponseHandlers() { return { onStartShouldSetResponder: () => { const { onStartShouldSetResponder } = this.props; const shouldSetResponder = (onStartShouldSetResponder == null ? false : onStartShouldSetResponder()) || isTouchable(this.props); if (shouldSetResponder) { this._attachTouchHandlers(); } return shouldSetResponder; }, onResponderGrant: event => { nullthrows(this.touchableHandleResponderGrant)(event); if (this.props.onResponderGrant != null) { this.props.onResponderGrant.call(this, event); } }, onResponderMove: event => { nullthrows(this.touchableHandleResponderMove)(event); if (this.props.onResponderMove != null) { this.props.onResponderMove.call(this, event); } }, onResponderRelease: event => { nullthrows(this.touchableHandleResponderRelease)(event); if (this.props.onResponderRelease != null) { this.props.onResponderRelease.call(this, event); } }, onResponderTerminate: event => { nullthrows(this.touchableHandleResponderTerminate)(event); if (this.props.onResponderTerminate != null) { this.props.onResponderTerminate.call(this, event); } }, onResponderTerminationRequest: () => { const { onResponderTerminationRequest } = this.props; if (!nullthrows(this.touchableHandleResponderTerminationRequest)()) { return false; } if (onResponderTerminationRequest == null) { return true; } return onResponderTerminationRequest(); } }; } /** * Lazily attaches Touchable.Mixin handlers. */ _attachTouchHandlers() { if (this.touchableGetPressRectOffset != null) { return; } for (const key in Touchable.Mixin) { if (typeof Touchable.Mixin[key] === 'function') { this[key] = Touchable.Mixin[key].bind(this); } } this.touchableHandleActivePressIn = () => { if (!this.props.suppressHighlighting && isTouchable(this.props)) { this.setState({ isHighlighted: true }); } }; this.touchableHandleActivePressOut = () => { if (!this.props.suppressHighlighting && isTouchable(this.props)) { this.setState({ isHighlighted: false }); } }; this.touchableHandlePress = event => { if (this.props.onPress != null) { this.props.onPress(event); } }; this.touchableHandleLongPress = event => { if (this.props.onLongPress != null) { this.props.onLongPress(event); } }; this.touchableGetPressRectOffset = () => this.props.pressRetentionOffset == null ? PRESS_RECT_OFFSET : this.props.pressRetentionOffset; } } _defineProperty(TouchableText, "defaultProps", { accessible: true, allowFontScaling: true, ellipsizeMode: 'tail' }); _defineProperty(TouchableText, "viewConfig", viewConfig); const isTouchable = props => props.onPress != null || props.onLongPress != null || // @ts-expect-error props.onStartShouldSetResponder != null; const RCTText = createReactNativeComponentClass(viewConfig.uiViewClassName, () => viewConfig); const Text = (props, forwardedRef) => { // @ts-expect-error return /*#__PURE__*/React.createElement(TouchableText, _extends({}, props, { forwardedRef: forwardedRef })); }; const TextToExport = React.forwardRef(Text); TextToExport.displayName = 'Animateable'; // TODO: Deprecate this. /* $FlowFixMe(>=0.89.0 site=react_native_fb) This comment suppresses an error * found when Flow v0.89 was deployed. To see the error, delete this comment * and run Flow. */ TextToExport.propTypes = DeprecatedTextPropTypes; const AnimateableText = TextToExport; exports.AnimateableText = AnimateableText; //# sourceMappingURL=AnimateableText.js.map