UNPKG

@wordpress/components

Version:
154 lines (132 loc) 6.67 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.KeyboardAwareFlatList = void 0; var _element = require("@wordpress/element"); var _reactNative = require("react-native"); var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated")); var _compose = require("@wordpress/compose"); var _useTextInputOffset = _interopRequireDefault(require("./use-text-input-offset")); var _useKeyboardOffset = _interopRequireDefault(require("./use-keyboard-offset")); var _useScrollToTextInput = _interopRequireDefault(require("./use-scroll-to-text-input")); var _useTextInputCaretPosition = _interopRequireDefault(require("./use-text-input-caret-position")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const AnimatedScrollView = _reactNativeReanimated.default.createAnimatedComponent(_reactNative.ScrollView); /** * React component that provides a FlatList that is aware of the keyboard state and can scroll * to the currently focused TextInput. * * @param {Object} props Component props. * @param {number} props.extraScrollHeight Extra scroll height for the content. * @param {Function} props.innerRef Function to pass the ScrollView ref to the parent component. * @param {Function} props.onScroll Function to be called when the list is scrolled. * @param {boolean} props.scrollEnabled Whether the list can be scrolled. * @param {Object} props.scrollViewStyle Additional style for the ScrollView component. * @param {boolean} props.shouldPreventAutomaticScroll Whether to prevent scrolling when there's a Keyboard offset set. * @param {Object} props... Other props to pass to the FlatList component. * @return {WPComponent} KeyboardAwareFlatList component. */ const KeyboardAwareFlatList = _ref => { let { extraScrollHeight, innerRef, onScroll, scrollEnabled, scrollViewStyle, shouldPreventAutomaticScroll, ...props } = _ref; const scrollViewRef = (0, _element.useRef)(); const scrollViewMeasurements = (0, _element.useRef)(); const scrollViewYOffset = (0, _reactNativeReanimated.useSharedValue)(-1); const { height: windowHeight, width: windowWidth } = (0, _reactNative.useWindowDimensions)(); const isLandscape = windowWidth >= windowHeight; const [keyboardOffset] = (0, _useKeyboardOffset.default)(scrollEnabled, shouldPreventAutomaticScroll); const [currentCaretData] = (0, _useTextInputCaretPosition.default)(scrollEnabled); const [getTextInputOffset] = (0, _useTextInputOffset.default)(scrollEnabled, scrollViewRef); const [scrollToTextInputOffset] = (0, _useScrollToTextInput.default)(extraScrollHeight, keyboardOffset, scrollEnabled, scrollViewMeasurements, scrollViewRef, scrollViewYOffset); const onScrollToTextInput = (0, _compose.useThrottle)((0, _element.useCallback)(async caret => { const textInputOffset = await getTextInputOffset(caret); const hasTextInputOffset = textInputOffset !== null; if (hasTextInputOffset) { scrollToTextInputOffset(caret, textInputOffset); } }, [getTextInputOffset, scrollToTextInputOffset]), 200, { leading: false }); (0, _element.useEffect)(() => { onScrollToTextInput(currentCaretData); }, [currentCaretData, onScrollToTextInput]); // When the orientation changes, the ScrollView measurements // need to be re-calculated. (0, _element.useEffect)(() => { scrollViewMeasurements.current = null; }, [isLandscape]); const scrollHandler = (0, _reactNativeReanimated.useAnimatedScrollHandler)({ onScroll: event => { const { contentOffset } = event; scrollViewYOffset.value = contentOffset.y; onScroll(event); } }); const measureScrollView = (0, _element.useCallback)(() => { if (scrollViewRef.current) { const scrollRef = scrollViewRef.current.getNativeScrollRef(); scrollRef.measureInWindow((_x, y, width, height) => { scrollViewMeasurements.current = { y, width, height }; }); } }, []); const onContentSizeChange = (0, _element.useCallback)(() => { onScrollToTextInput(currentCaretData); // Sets the first values when the content size changes. if (!scrollViewMeasurements.current) { measureScrollView(); } }, [measureScrollView, onScrollToTextInput, currentCaretData]); const getRef = (0, _element.useCallback)(ref => { scrollViewRef.current = ref; innerRef(ref); }, [innerRef]); // Adds content insets when the keyboard is opened to have // extra padding at the bottom. const contentInset = { bottom: keyboardOffset }; const style = [{ flex: 1 }, scrollViewStyle]; return (0, _element.createElement)(AnimatedScrollView, { automaticallyAdjustContentInsets: false, contentInset: contentInset, keyboardShouldPersistTaps: "handled", onContentSizeChange: onContentSizeChange, onScroll: scrollHandler, ref: getRef, scrollEnabled: scrollEnabled, scrollEventThrottle: 16, style: style }, (0, _element.createElement)(_reactNative.FlatList, props)); }; exports.KeyboardAwareFlatList = KeyboardAwareFlatList; var _default = KeyboardAwareFlatList; exports.default = _default; //# sourceMappingURL=index.ios.js.map