UNPKG

zarm

Version:

基于 React 的移动端UI库

307 lines (249 loc) 11.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _bem = require("@zarm-design/bem"); var React = _interopRequireWildcard(require("react")); var _carousel = _interopRequireDefault(require("../carousel")); var _configProvider = require("../config-provider"); var _deprecationWarning = require("../utils/deprecationWarning"); var _dom = require("../utils/dom"); var _TabPanel = _interopRequireDefault(require("./TabPanel")); var _index = require("./util/index"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) { if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } } return n.default = e, t && t.set(e, n), n; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var getChildChecked = function getChildChecked(children) { var selectIndex; React.Children.forEach(children, function (item, index) { if ( /*#__PURE__*/React.isValidElement(item) && item.props && item.props.selected) { selectIndex = index; } }); return selectIndex; }; var parseValueBoundary = function parseValueBoundary(inputValue, children) { var count = React.Children.count(children); if (inputValue <= 0) { return 0; } if (inputValue > count - 1) { return count - 1; } return inputValue; }; var getValue = function getValue(props, defaultValue) { if (typeof props.value !== 'undefined') { return parseValueBoundary(props.value, props.children); } if (typeof props.defaultValue !== 'undefined') { return parseValueBoundary(props.defaultValue, props.children); } if (getChildChecked(props.children)) { return parseValueBoundary(getChildChecked(props.children), props.children); } return parseValueBoundary(defaultValue, props.children); }; var Tabs = /*#__PURE__*/React.forwardRef(function (props, ref) { var _ref; var className = props.className, style = props.style, value = props.value, defaultValue = props.defaultValue, disabled = props.disabled, swipeable = props.swipeable, scrollable = props.scrollable, direction = props.direction, lineWidth = props.lineWidth, onChange = props.onChange, children = props.children; // TODO: DeprecationWarning - remove this warning in next major version (0, _deprecationWarning.useTypeChangeWarning)(['vertical', 'horizontal'].includes(direction), 'Tabs', 'direction', direction, "'top' | 'right' | 'bottom' | 'left'"); var carouselRef = React.useRef(null); var tablistRef = React.useRef(null); var _React$useState = React.useState(0), _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2), itemWidth = _React$useState2[0], setItemWidth = _React$useState2[1]; var _React$useState3 = React.useState(getValue({ value: value, defaultValue: defaultValue, children: children }, 0)), _React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2), currentValue = _React$useState4[0], setCurrentValue = _React$useState4[1]; var _React$useContext = React.useContext(_configProvider.ConfigContext), prefixCls = _React$useContext.prefixCls; var bem = (0, _bem.createBEM)('tabs', { prefixCls: prefixCls }); // TODO: direction='vertical' 暂作兼容 var isVertical = ['left', 'right', 'vertical'].includes(direction); var parseValue = React.useCallback(function (inputValue) { return parseValueBoundary(inputValue, children); }, [children]); var classes = bem([(_ref = {}, (0, _defineProperty2.default)(_ref, "".concat(direction), true), (0, _defineProperty2.default)(_ref, "scroll", scrollable), _ref), className]); // 计算 line 大小和位置 var caclLineSizePos = function caclLineSizePos() { var newValue = parseValue(currentValue); var ChildCount = React.Children.count(children); var pos = 100 * newValue; if (scrollable && tablistRef.current) { var el = tablistRef.current.children[newValue]; var _ref2 = el, _ref2$offsetLeft = _ref2.offsetLeft, offsetLeft = _ref2$offsetLeft === void 0 ? 0 : _ref2$offsetLeft, _ref2$offsetTop = _ref2.offsetTop, offsetTop = _ref2$offsetTop === void 0 ? 0 : _ref2$offsetTop; pos = isVertical ? offsetTop : offsetLeft; } var size = scrollable ? "".concat(itemWidth, "px") : "".concat(100 / ChildCount, "%"); var transformValue = scrollable ? (0, _index.getPxStyle)(pos, 'px', isVertical) : (0, _index.getPxStyle)(pos, '%', isVertical); var styleUl = (0, _index.getTransformPropValue)(transformValue); var itemSize = isVertical ? { height: "".concat(size) } : { width: "".concat(size) }; return _objectSpread(_objectSpread({}, styleUl), itemSize); }; var onTabChange = React.useCallback(function (newValue) { if (typeof value === 'undefined') { setCurrentValue(newValue); } typeof onChange === 'function' && onChange(newValue); }, [value, onChange]); var onTabClick = function onTabClick(tab, index) { if (disabled || tab.props.disabled) { return; } if (swipeable) { carouselRef.current && carouselRef.current.onSlideTo(index); return; } onTabChange(index); }; var lineStyle = caclLineSizePos(); var lineInnerRender; if (lineWidth) { lineStyle.backgroundColor = 'transparent'; lineInnerRender = /*#__PURE__*/React.createElement("span", { className: bem('line__inner'), style: { width: lineWidth } }); } // 渲染内容 var contentRender; if (swipeable) { contentRender = /*#__PURE__*/React.createElement(_carousel.default, { swipeable: !disabled, direction: isVertical ? 'vertical' : 'horizontal', showPagination: false, activeIndex: parseValue(currentValue), ref: carouselRef, onChange: onTabChange }, React.Children.map(children, function (item, index) { return /*#__PURE__*/React.createElement("div", { key: +index }, item.props.children); })); } else { contentRender = React.Children.map(children, function (item, index) { return /*#__PURE__*/React.createElement(_TabPanel.default, (0, _extends2.default)({}, item.props, { selected: parseValue(currentValue) === index })); }); } var renderTabs = function renderTabs(tab, index) { var itemCls = bem('tab', [{ disabled: disabled || tab.props.disabled, active: parseValue(currentValue) === index }, tab.props.className]); return /*#__PURE__*/React.createElement("li", { role: "tab", key: +index, className: itemCls, onClick: function onClick() { return onTabClick(tab, index); } }, tab.props.title); }; // 渲染选项 var tabsRender = React.Children.map(children, renderTabs); var getItemStyle = function getItemStyle(el, prop) { var newValue = '0'; if (prop in el.style) { newValue = el.style[prop] || window.getComputedStyle(el).getPropertyValue(prop) || '0'; } return newValue; }; var calculateLineWidth = React.useCallback(function () { if (!scrollable) { return; } var newValue = parseValue(currentValue); var el = tablistRef.current.children[newValue]; var size = isVertical ? getItemStyle(el, 'height') : getItemStyle(el, 'width'); setItemWidth(parseInt(size.toString(), 10)); }, [parseValue, currentValue, isVertical, scrollable]); var calculateScorllLeftLocation = React.useCallback(function () { if (!scrollable) { return false; } var newValue = parseValue(currentValue); var prevTabItem = tablistRef.current.childNodes[newValue]; if (scrollable && tablistRef.current && prevTabItem) { var _tablistRef$current = tablistRef.current, _tablistRef$current$o = _tablistRef$current.offsetWidth, layoutOffsetWidth = _tablistRef$current$o === void 0 ? 0 : _tablistRef$current$o, _tablistRef$current$o2 = _tablistRef$current.offsetHeight, layoutOffsetHeight = _tablistRef$current$o2 === void 0 ? 0 : _tablistRef$current$o2; var left = prevTabItem.offsetLeft + prevTabItem.offsetWidth / 2 - layoutOffsetWidth / 2; var top = prevTabItem.offsetTop + prevTabItem.offsetHeight / 2 - layoutOffsetHeight / 2; (0, _dom.scrollTo)(tablistRef.current, top, left, 0.3); } }, [parseValue, currentValue, scrollable]); React.useEffect(function () { if (React.Children.count(children)) { calculateLineWidth(); calculateScorllLeftLocation(); } }, [calculateLineWidth, calculateScorllLeftLocation, children]); React.useEffect(function () { setCurrentValue(getValue({ value: value, defaultValue: defaultValue, children: children }, 0)); }, [value, defaultValue, children]); return /*#__PURE__*/React.createElement("div", { ref: ref, className: classes, style: style }, /*#__PURE__*/React.createElement("div", { className: bem('header') }, /*#__PURE__*/React.createElement("ul", { className: bem('tablist'), role: "tablist", ref: tablistRef }, tabsRender, /*#__PURE__*/React.createElement("div", { className: bem('line'), style: lineStyle }, lineInnerRender))), /*#__PURE__*/React.createElement("div", { className: bem('body') }, contentRender)); }); Tabs.displayName = 'Tabs'; Tabs.defaultProps = { disabled: false, swipeable: false, scrollable: false, direction: 'top' }; var _default = Tabs; exports.default = _default;