UNPKG

@auraxy/react-tabs

Version:

tabs component for react app

302 lines (258 loc) 11.2 kB
/** * Bundle of @auraxy/react-tabs * Generated: 2020-02-05 * Version: 1.4.2 * License: MIT * Author: houyuxuan */ import React, { useState, useEffect, useMemo, useRef } from 'react'; import useStateTrackProp from 'use-state-track-prop'; import useWatch from 'use-watch'; 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 _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function combineClassNames() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var classes = args.reduce(function (pre, arg) { return "".concat(pre).concat(arg ? " ".concat(arg) : ''); }, ''); return classes ? classes.trim() : ''; } var TabBar = function TabBar(_ref) { var allTabs = _ref.allTabs, currentIndex = _ref.currentIndex; var _useState = useState(0), _useState2 = _slicedToArray(_useState, 2), tabBarWidth = _useState2[0], setTabBarWidth = _useState2[1]; var _useState3 = useState(0), _useState4 = _slicedToArray(_useState3, 2), tabBarLeft = _useState4[0], setTabBarLeft = _useState4[1]; var getWidth = function getWidth() { return allTabs[currentIndex].offsetWidth || 0; }; var getLeft = function getLeft() { return allTabs.reduce(function () { var width = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var curr = arguments.length > 1 ? arguments[1] : undefined; var index = arguments.length > 2 ? arguments[2] : undefined; return index < currentIndex ? width + curr.offsetWidth : width; }, 0) || 0; }; useEffect(function () { setTabBarWidth(getWidth()); setTabBarLeft(getLeft()); // eslint-disable-next-line react-hooks/exhaustive-deps }, [currentIndex]); return React.createElement("div", { className: "au-tab-bar", style: { width: tabBarWidth, left: tabBarLeft } }); }; function styleInject(css, ref) { if (ref === void 0) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css = ".au-tabs-box{font-size:14px}.au-tabs-box.au-tabs-hide-over{overflow:hidden}.au-tabs-box *{box-sizing:border-box}.au-tabs-box li,.au-tabs-box ul{padding:0;margin:0;list-style-type:none}.au-tabs-box.card>.au-tabs-nav-list{background:#f2f8fe;padding-top:10px}.au-tabs-box.card>.au-tabs-nav-list .au-tabs-tab{position:relative;bottom:-1px;border:1px solid transparent}.au-tabs-box.card>.au-tabs-nav-list .au-tabs-tab.active-tab{background:#fff;border:1px solid #bfd4eb;border-bottom-color:#fff;border-radius:5px 5px 0 0;z-index:1}.au-tabs-box.card>.au-tabs-nav-list .au-tab-bar{display:none}.au-tabs-box .au-tabs-nav-list,.au-tabs-box.line>.au-tabs-nav-list{display:flex;position:relative}.au-tabs-box .au-tabs-nav-list:after,.au-tabs-box.line>.au-tabs-nav-list:after{content:\"\";position:absolute;top:100%;left:0;width:100%;height:0;border-bottom:1px solid #ccc}.au-tabs-box .au-tabs-nav-list .au-tabs-tab,.au-tabs-box.line>.au-tabs-nav-list .au-tabs-tab{padding:0 20px;height:40px;line-height:40px;text-align:center;font-weight:500;cursor:pointer;color:#bfd4eb;transition:all .3s linear}.au-tabs-box .au-tabs-nav-list .au-tabs-tab.active-tab,.au-tabs-box .au-tabs-nav-list .au-tabs-tab:hover,.au-tabs-box.line>.au-tabs-nav-list .au-tabs-tab.active-tab,.au-tabs-box.line>.au-tabs-nav-list .au-tabs-tab:hover{color:#125fb2}.au-tabs-box .au-tabs-nav-list .au-tabs-tab.disabled,.au-tabs-box.line>.au-tabs-nav-list .au-tabs-tab.disabled{color:#ccc;cursor:not-allowed}.au-tabs-box .au-tabs-nav-list .au-tab-bar,.au-tabs-box.line>.au-tabs-nav-list .au-tab-bar{position:absolute;top:calc(100% - 1px);left:0;height:2px;background:#125fb2;transition:all .2s linear;z-index:1}.au-tabs-box .au-tabs-content{display:flex;align-items:flex-start}.au-tabs-box .au-tabs-content .au-tab-panel{padding:20px;width:100%}.au-tabs-box .au-tabs-content .au-tab-panel.au-tab-show{visibility:visible;opacity:1;pointer-events:all}.au-tabs-box .au-tabs-content .au-tab-panel.au-tab-hide{visibility:hidden;opacity:0;pointer-events:none}"; styleInject(css); 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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function useGetSize() { var boxRef = useRef(null); var tabsRef = useRef([]); var _useState = useState({ boxWidth: 0 }), _useState2 = _slicedToArray(_useState, 2), size = _useState2[0], setSize = _useState2[1]; useEffect(function () { var setWidth = function setWidth() { return setSize(function (pre) { return _objectSpread({}, pre, { boxWidth: boxRef.current.clientWidth }); }); }; setWidth(); window.addEventListener('resize', setWidth); return function () { return window.removeEventListener('resize', setWidth); }; }, []); return { boxRef: boxRef, tabsRef: tabsRef, size: size }; } var Tabs = function Tabs(_ref) { var onChange = _ref.onChange, tabs = _ref.tabs, value = _ref.value, className = _ref.className, _ref$animation = _ref.animation, animation = _ref$animation === void 0 ? true : _ref$animation, optionsForTab = _ref.optionsForTab; var _useGetSize = useGetSize(), boxRef = _useGetSize.boxRef, tabsRef = _useGetSize.tabsRef, size = _useGetSize.size; var _useStateTrackProp = useStateTrackProp(value), _useStateTrackProp2 = _slicedToArray(_useStateTrackProp, 2), $value = _useStateTrackProp2[0], setValue = _useStateTrackProp2[1]; var currentIndex = useMemo(function () { return Math.max(0, tabs.findIndex(function (t) { return t.value === $value; })); }, [tabs, $value]); var tabContentNodes = useRef(tabs.map(function (tab) { return tab.content || ''; })); var updateTabContentNodes = function updateTabContentNodes(currContent, index) { tabContentNodes.current[index] = typeof currContent !== 'function' ? currContent || '' : currContent(tabs[index], optionsForTab || {}); }; var _useState3 = useState(function () { return tabs.some(function (item) { return !!item.content; }); }), _useState4 = _slicedToArray(_useState3, 1), hasContent = _useState4[0]; updateTabContentNodes(tabContentNodes.current[currentIndex], currentIndex); useWatch(tabs, function (val, oldVal) { var len = Math.max(val.length, oldVal.length); for (var i = 0; i < len; i += 1) { var content = val[i] ? val[i].content : NaN; var oldContent = oldVal[i] ? oldVal[i].content : NaN; if (content !== oldContent) { updateTabContentNodes(content || '', i); } } }); var _onClick = function onClick(_ref2) { var key = _ref2.key, index = _ref2.index; setValue(key); onChange && onChange({ key: key, index: index }); }; var transition = animation ? '0.3s all ease-in-out' : 'none'; return React.createElement("div", { className: combineClassNames('au-tabs-box', className || '', animation ? 'au-tabs-hide-over au-tabs-has-animation' : 'au-tabs-no-animation'), ref: boxRef }, React.createElement("ul", { className: "au-tabs-nav-list" }, tabs.length && tabs.map(function (item, index) { return React.createElement("li", { key: "tab".concat(index), className: combineClassNames('au-tabs-tab', currentIndex === index ? 'active-tab' : '', item.disabled ? 'disabled' : ''), onClick: function onClick() { !item.disabled && _onClick({ key: item.value, index: index }); }, ref: function ref(_ref3) { return tabsRef.current[index] = _ref3; } }, typeof item.title === 'function' ? item.title(item, optionsForTab) : item.title); }), React.createElement(TabBar, { allTabs: tabsRef.current, currentIndex: currentIndex })), hasContent && React.createElement("div", { className: "au-tabs-content", style: { width: tabs.length * 100 + '%', // transform 会影响子元素的 position fixed 定位和 tr 样式 // transform: `translate(${(-currentIndex * 100) / // tabs.length}%)`, position: 'relative', left: "".concat(-currentIndex * size.boxWidth, "px"), transition: transition, padding: '0 !important' } }, tabs.length && tabs.map(function (item, index) { return React.createElement("div", { className: combineClassNames('au-tab-panel', currentIndex === index ? 'au-tab-show' : 'au-tab-hide'), key: "tab-panel-".concat(index), style: { width: 1 / tabs.length * 100 + '%', transition: transition } }, typeof tabContentNodes.current[index] === 'function' ? React.createElement(React.Fragment, null) : tabContentNodes.current[index]); }))); }; export default Tabs;