UNPKG

@fruits-chain/react-native-xiaoshu

Version:
178 lines (158 loc) 5.84 kB
import isNil from 'lodash/isNil'; import React, { useMemo, useEffect, useState, useRef, memo } from 'react'; import { View } from 'react-native'; import Divider from '../divider'; import { useControllableValue } from '../hooks'; import Loading from '../loading'; import Theme from '../theme'; import { getDataType, findDefaultValue, buildOptions, findNextAllColumns, buildSelectedValue } from './helper/picker'; import PickerColumn from './picker-view-column'; import { varCreator, styleCreator } from './style'; /** * 选择器视图 */ const PickerView = _ref => { let { visibleItemCount = 5, itemHeight = 50, loading = false, columns, ...restProps } = _ref; /** 选项的高度 */ const columnsHeight = visibleItemCount * itemHeight; /** 居中选中的偏移量 */ const markMargin = itemHeight / 2; const TOKENS = Theme.useThemeTokens(); const CV = Theme.createVar(TOKENS, varCreator); const STYLES = Theme.createStyle(CV, styleCreator); /** * 数据类型 * @description cascade 联级选择,multiple 多列选择,single 单列选择 */ const dataType = useMemo(() => getDataType(columns), [columns]); const isControlled = ('value' in restProps); const isNoDefaultValue = ('defaultValue' in restProps); const [value, onChange] = useControllableValue(restProps, { defaultValue: [] }); const [options, setOptions] = useState([]); const ColumnDefaultValues = useRef([]); // 初始化数据 useEffect(() => { if (dataType !== 'cascade') { const [_options, defaultValues] = buildOptions(dataType, columns); ColumnDefaultValues.current = defaultValues; setOptions(_options); // 非受控的情况、并且没有默认值才去同步数据 // 既然有默认数据了,由外面自己负责 // 把数据同步到内部状态,初始化的时候看起来是选中默认数据或第一个数据的样子 if (!isControlled && !isNoDefaultValue) { const [v, o] = buildSelectedValue(defaultValues, _options); onChange(v, o); } } }, [columns, dataType, onChange, isControlled, isNoDefaultValue]); // 联级依赖 value 单独处理 useEffect(() => { if (dataType === 'cascade') { const [_options,, _values] = buildOptions(dataType, columns, value); const [v, o] = buildSelectedValue(_values, _options); setOptions(_options); // 当 if (value !== _values) { onChange(v, o); } } }, [columns, value, dataType, onChange]); const bodyStyle = { height: columnsHeight, backgroundColor: CV.picker_view_background_color, flexDirection: 'row', overflow: 'hidden' }; const maskTopStyles = [STYLES.mask, { top: 0, bottom: '50%', flexDirection: 'column-reverse', transform: [{ translateY: -markMargin }] }]; const maskBottomStyles = [STYLES.mask, { top: '50%', bottom: 0, transform: [{ translateY: markMargin }] }]; return /*#__PURE__*/React.createElement(View, { style: STYLES.picker }, loading ? /*#__PURE__*/React.createElement(Loading, { style: STYLES.loading }) : null, /*#__PURE__*/React.createElement(View, { style: bodyStyle }, /*#__PURE__*/React.createElement(View, { style: maskTopStyles, pointerEvents: "none" }, /*#__PURE__*/React.createElement(Divider, null)), /*#__PURE__*/React.createElement(View, { style: maskBottomStyles, pointerEvents: "none" }, /*#__PURE__*/React.createElement(Divider, null)), options.map((optionItem, optionIndex) => { const _value = (() => { if (!isNil(value[optionIndex])) { return value[optionIndex]; } // 默认值 // 非受控的情况才去同步数据 // 并且没有默认值 if (!isControlled && !isNoDefaultValue) { if (dataType === 'multiple') { return ColumnDefaultValues.current[optionIndex]; } // 真的没有就默认第一个选项 return findDefaultValue(options[optionIndex][0].value, optionItem); } return null; })(); return /*#__PURE__*/React.createElement(PickerColumn, { key: optionIndex, itemHeight: itemHeight, visibleItemCount: visibleItemCount, options: optionItem, value: _value, onChange: column => { switch (dataType) { // 联级选择 // 如果是 cascade 需要重置选项 case 'cascade': { const nextAll = findNextAllColumns((column === null || column === void 0 ? void 0 : column.children) || []); const _options = options.slice(0, optionIndex + 1).concat(nextAll.options); const values = value.slice(0, optionIndex).concat(column === null || column === void 0 ? void 0 : column.value).concat(nextAll.values); const [v, o] = buildSelectedValue(values, _options); onChange(v, o); break; } // 多选 case 'multiple': { const newValues = value.concat([]); // 先从默认数据中拼凑好数据 ColumnDefaultValues.current.forEach((cdv, cdvIndex) => { if (isNil(newValues[cdvIndex])) { newValues[cdvIndex] = cdv; } }); newValues[optionIndex] = column.value; const [v, o] = buildSelectedValue(newValues, options); onChange(v, o); break; } // 单选 default: { const columnsIndex = columns.findIndex(c => c.value === column.value); onChange([column.value], [columns[columnsIndex]]); break; } } } }); }))); }; export default /*#__PURE__*/memo(PickerView); //# sourceMappingURL=index.js.map