@wordpress/components
Version:
UI components for WordPress.
154 lines (132 loc) • 6.67 kB
JavaScript
;
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