UNPKG

@quidone/react-native-wheel-picker

Version:

Picker is a UI component for selecting an item from a list of options.

155 lines 4.61 kB
function _extends() { _extends = Object.assign ? Object.assign.bind() : 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); } import React, { useCallback, useMemo, useRef } from 'react'; import { Animated, StyleSheet, View } from 'react-native'; import PickerItemComponent from '../item/PickerItem'; import { ScrollContentOffsetContext } from '../contexts/ScrollContentOffsetContext'; import { PickerItemHeightContext } from '../contexts/PickerItemHeightContext'; import useValueEventsEffect from './hooks/useValueEventsEffect'; import useSyncScrollEffect from './hooks/useSyncScrollEffect'; import Overlay from '../overlay/Overlay'; import { calcPickerHeight, createFaces } from '../item/faces'; import PickerItemContainer from '../item/PickerItemContainer'; import { useBoolean } from '../../utils/react'; import { useInit } from '@rozhkov/react-useful-hooks'; import List from '../list/List'; const defaultKeyExtractor = (_, index) => index.toString(); const defaultRenderItem = _ref => { let { item: { value, label }, itemTextStyle } = _ref; return /*#__PURE__*/React.createElement(PickerItemComponent, { value: value, label: label, itemTextStyle: itemTextStyle }); }; const defaultRenderItemContainer = _ref2 => { let { key, ...props } = _ref2; return /*#__PURE__*/React.createElement(PickerItemContainer, _extends({ key: key }, props)); }; const defaultRenderOverlay = props => /*#__PURE__*/React.createElement(Overlay, props); const defaultRenderList = props => { return /*#__PURE__*/React.createElement(List, props); }; const useValueIndex = (data, value) => { return useMemo(() => { const index = data.findIndex(x => x.value === value); return index >= 0 ? index : 0; }, [data, value]); }; const Picker = _ref3 => { let { data, value, width = 'auto', itemHeight = 48, visibleItemCount = 5, readOnly = false, testID, onValueChanged, onValueChanging, keyExtractor = defaultKeyExtractor, renderItem = defaultRenderItem, renderItemContainer = defaultRenderItemContainer, renderOverlay = defaultRenderOverlay, renderList = defaultRenderList, style, itemTextStyle, overlayItemStyle, contentContainerStyle, ...restProps } = _ref3; const valueIndex = useValueIndex(data, value); const initialIndex = useInit(() => valueIndex); const offsetY = useRef(new Animated.Value(valueIndex * itemHeight)).current; const listRef = useRef(null); const touching = useBoolean(false); const [faces, pickerHeight] = useMemo(() => { const items = createFaces(itemHeight, visibleItemCount); const height = calcPickerHeight(items, itemHeight); return [items, height]; }, [itemHeight, visibleItemCount]); const renderPickerItem = useCallback(_ref4 => { let { item, index, key } = _ref4; return renderItemContainer({ key, item, index, faces, renderItem, itemTextStyle }); }, [faces, itemTextStyle, renderItem, renderItemContainer]); const { activeIndexRef, onScrollEnd } = useValueEventsEffect({ data, valueIndex, itemHeight, offsetYAv: offsetY }, { onValueChanging, onValueChanged }); useSyncScrollEffect({ listRef, valueIndex, activeIndexRef, touching: touching.value }); return /*#__PURE__*/React.createElement(ScrollContentOffsetContext.Provider, { value: offsetY }, /*#__PURE__*/React.createElement(PickerItemHeightContext.Provider, { value: itemHeight }, /*#__PURE__*/React.createElement(View, { testID: testID, style: [styles.root, style, { height: pickerHeight, width }] }, renderList({ ...restProps, ref: listRef, data, initialIndex, itemHeight, pickerHeight, visibleItemCount, readOnly, keyExtractor, renderItem: renderPickerItem, scrollOffset: offsetY, onTouchStart: touching.setTrue, onTouchEnd: touching.setFalse, onTouchCancel: touching.setFalse, onScrollEnd, contentContainerStyle }), renderOverlay && renderOverlay({ itemHeight, pickerWidth: width, pickerHeight, overlayItemStyle })))); }; const styles = StyleSheet.create({ root: { justifyContent: 'center', alignItems: 'center' } }); export default Picker; //# sourceMappingURL=Picker.js.map