UNPKG

@vnmfify/core

Version:

```shell npm i @vnmfify/core -S ```

203 lines (181 loc) 8.12 kB
import _isEmpty from "lodash/isEmpty"; import _get from "lodash/get"; import _clamp from "lodash/clamp"; import _isEqual from "lodash/isEqual"; import _find from "lodash/find"; import _map from "lodash/map"; import _slice from "lodash/slice"; import _size from "lodash/size"; var _excluded = ["value"], _excluded2 = ["onClick", "value", "children"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } 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; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } import { useUncontrolled } from "@vnmfify/hooks"; import { View } from "@vnxjs/components"; import { nextTick } from "@vnxjs/vnmf"; import classNames from "classnames"; import * as React from "react"; import { Children, isValidElement, useCallback, useEffect, useMemo, useState } from "react"; import { prefixClassname } from "../styles"; import Tabs from "../tabs"; import CascaderHeader from "./cascader-header"; import CascaderOption from "./cascader-option"; import CascaderOptionBase from "./cascader-option-base"; import CascaderTab from "./cascader-tab"; import { isActiveOption } from "./cascader.shared"; function getCascaderOptions(children, tabIndex) { var options = []; Children.forEach(children, child => { if ( /*#__PURE__*/isValidElement(child)) { var element = child; var { key, props, type } = element; var { value } = props, restProps = _objectWithoutProperties(props, _excluded); if (type === CascaderOption) { var index = _size(options); options.push(_objectSpread({ key: key !== null && key !== void 0 ? key : index, tabIndex, value: value !== null && value !== void 0 ? value : index }, restProps)); } } }); return options; } function useCascaderChildren(children) { return useMemo(() => { var __children__ = { header: undefined, tabs: [] }; Children.forEach(children, child => { if ( /*#__PURE__*/isValidElement(child)) { var element = child; var { props, type } = element; if (type === CascaderHeader) { __children__.header = element; } else if (type === CascaderTab) { var { children: _children } = props; __children__.tabs.push({ options: getCascaderOptions(_children, _size(__children__.tabs)) }); } } }); return __children__; }, [children]); } function Cascader(props) { var { className, defaultValue, value: valueProp, placeholder = "Please choose.", swipeable = false, children: childrenProp, onChange, onSelect, onTabClick } = props; var { header, tabs } = useCascaderChildren(childrenProp); var { value: values = [], setValue: setValues } = useUncontrolled({ defaultValue, value: valueProp }); var [activeTab, setActiveTab] = useState(0); var lastTab = useMemo(() => _size(tabs) - 1, [tabs]); var activeTabs = useMemo(() => _slice(tabs, 0, _size(values) + 1), [tabs, values]); var findOptions = useCallback(aValues => _map(tabs, _ref => { var { options } = _ref; return _find(options, option => option.value === aValues[option.tabIndex]); }), [tabs]); var activeOptions = useMemo(() => findOptions(values), [findOptions, values]); var emitChange = useCallback(newValues => { var newActiveOptions = findOptions(newValues); onSelect === null || onSelect === void 0 ? void 0 : onSelect(newValues, newActiveOptions); if (!_isEqual(newValues, valueProp) && _size(tabs) === _size(newValues)) { onChange === null || onChange === void 0 ? void 0 : onChange(newValues, newActiveOptions); } }, [findOptions, onChange, onSelect, tabs, valueProp]); var handleSelect = useCallback(option => { var { disabled, tabIndex, value } = option; if (disabled) { return; } var newValues = _slice(values, 0, tabIndex + 1); newValues[tabIndex] = value; setValues(newValues); emitChange(newValues); }, [emitChange, setValues, values]); useEffect(() => nextTick(() => setActiveTab(_clamp(_size(values), lastTab))), [lastTab, values]); var panes = useMemo(() => _map(activeTabs, (tab, index) => { var _get$children, _get2, _get3; return /*#__PURE__*/React.createElement(Tabs.TabPane, { key: index, value: index, title: (_get$children = (_get2 = _get(activeOptions, index)) === null || _get2 === void 0 ? void 0 : _get2.children) !== null && _get$children !== void 0 ? _get$children : placeholder, classNames: { title: classNames(prefixClassname("cascader__tab"), { [prefixClassname("cascader__tab--inactive")]: _isEmpty((_get3 = _get(activeOptions, index)) === null || _get3 === void 0 ? void 0 : _get3.children) }) } }, /*#__PURE__*/React.createElement(View, { className: prefixClassname("cascader__options") }, _map(tab.options, option => { var { onClick: _onClick, value, children } = option, restProps = _objectWithoutProperties(option, _excluded2); return /*#__PURE__*/React.createElement(CascaderOptionBase, _objectSpread(_objectSpread({}, restProps), {}, { children: children !== null && children !== void 0 ? children : value, onClick: event => { _onClick === null || _onClick === void 0 ? void 0 : _onClick(event); handleSelect(option); }, active: isActiveOption(option, values) })); }))); }), [activeOptions, activeTabs, handleSelect, placeholder, values]); return /*#__PURE__*/React.createElement(View, { className: classNames(prefixClassname("cascader"), className) }, header, /*#__PURE__*/React.createElement(Tabs, { className: prefixClassname("cascader__tabs"), value: activeTab, animated: true, swipeable: swipeable, onChange: value => setActiveTab(value), onTabClick: onTabClick, children: panes })); } export default Cascader; //# sourceMappingURL=cascader.js.map