@vnmfify/core
Version:
```shell npm i @vnmfify/core -S ```
203 lines (181 loc) • 8.12 kB
JavaScript
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