UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

203 lines (202 loc) 9.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "Tabs", { enumerable: true, get: function() { return Tabs; } }); var _interop_require_default = require("@swc/helpers/_/_interop_require_default"); var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); var _define_property = require("@swc/helpers/_/_define_property"); var _object_spread = require("@swc/helpers/_/_object_spread"); var _object_spread_props = require("@swc/helpers/_/_object_spread_props"); var _object_without_properties = require("@swc/helpers/_/_object_without_properties"); var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array"); var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames")); var _iconsreact = require("@nutui/icons-react"); var _typings = require("../../utils/typings"); var _tabpane = /*#__PURE__*/ _interop_require_default._(require("../tabpane")); var _raf = /*#__PURE__*/ _interop_require_default._(require("../../utils/raf")); var _usepropsvalue = require("../../hooks/use-props-value"); var _useforceupdate = require("../../hooks/use-force-update"); var _configprovider = require("../configprovider"); var defaultProps = (0, _object_spread_props._)((0, _object_spread._)({}, _typings.ComponentDefaults), { tabStyle: {}, activeColor: '', direction: 'horizontal', activeType: 'line', duration: 300, autoHeight: false }); var classPrefix = 'nut-tabs'; var Tabs = function Tabs(props) { var rtl = (0, _configprovider.useRtl)(); var _ref = (0, _object_spread._)({}, defaultProps, props), activeColor = _ref.activeColor, tabStyle = _ref.tabStyle, direction = _ref.direction, activeType = _ref.activeType, duration = _ref.duration, align = _ref.align, title = _ref.title, children = _ref.children, onClick = _ref.onClick, onChange = _ref.onChange, className = _ref.className, autoHeight = _ref.autoHeight, outerValue = _ref.value, outerDefaultValue = _ref.defaultValue, rest = (0, _object_without_properties._)(_ref, [ "activeColor", "tabStyle", "direction", "activeType", "duration", "align", "title", "children", "onClick", "onChange", "className", "autoHeight", "value", "defaultValue" ]); var _usePropsValue = (0, _sliced_to_array._)((0, _usepropsvalue.usePropsValue)({ value: outerValue, defaultValue: outerDefaultValue, onChange: onChange }), 2), value = _usePropsValue[0], setValue = _usePropsValue[1]; var titleItemsRef = (0, _react.useRef)([]); var navRef = (0, _react.useRef)(null); var scrollDirection = function scrollDirection(nav, to, duration) { var from = direction === 'horizontal' ? nav.scrollLeft : nav.scrollTop; var frames = duration === 0 ? 1 : Math.round(duration * 1000 / 16); var count = 0; var animate = function animate1() { if (direction === 'horizontal') nav.scrollLeft += (to - from) / frames; else nav.scrollTop += (to - from) / frames; if (++count < frames) (0, _raf.default)(animate); }; animate(); }; var scrollIntoView = function scrollIntoView(index, immediate) { var nav = navRef.current; var titleItem = titleItemsRef.current; var titlesLength = titles.current.length; var itemLength = titleItem.length; if (!nav || !titleItem || !titleItem[itemLength - titlesLength + index]) { return; } var title = titleItem[itemLength - titlesLength + index]; var to = 0; if (direction === 'vertical') { var runTop = title.offsetTop - nav.offsetTop + 10; to = runTop - (nav.offsetHeight - title.offsetHeight) / 2; } else { to = title.offsetLeft - (nav.offsetWidth - title.offsetWidth) / 2; } scrollDirection(nav, to, immediate ? 0 : 0.3); }; var getTitles = function getTitles() { var titles = []; _react.default.Children.forEach(children, function(child, idx) { if (/*#__PURE__*/ _react.default.isValidElement(child)) { var _$props = child.props; if ((_$props === null || _$props === void 0 ? void 0 : _$props.title) || (_$props === null || _$props === void 0 ? void 0 : _$props.value)) { titles.push({ title: _$props.title, value: _$props.value || idx, disabled: _$props.disabled }); } } }); return titles; }; var titles = (0, _react.useRef)(getTitles()); var forceUpdate = (0, _useforceupdate.useForceUpdate)(); (0, _react.useEffect)(function() { titles.current = getTitles(); var current = ''; titles.current.forEach(function(title) { if (title.value === value) { current = value; } }); if (current !== '' && current !== value) { setValue(current); } else { forceUpdate(); } }, [ children ]); var classes = (0, _classnames.default)(classPrefix, "".concat(classPrefix, "-").concat(direction), className); var _obj; var classesTitle = (0, _classnames.default)("".concat(classPrefix, "-titles"), (_obj = {}, (0, _define_property._)(_obj, "".concat(classPrefix, "-titles-").concat(activeType), activeType), (0, _define_property._)(_obj, "".concat(classPrefix, "-titles-scrollable"), true), (0, _define_property._)(_obj, "".concat(classPrefix, "-titles-").concat(align), align), _obj)); var getContentStyle = function getContentStyle() { var index = titles.current.findIndex(function(t) { return t.value === value; }); index = index < 0 ? 0 : index; return { transform: direction === 'horizontal' ? "translate3d(".concat(rtl ? '' : '-').concat(index * 100, "%, 0, 0)") : "translate3d( 0, -".concat(index * 100, "%, 0)"), transitionDuration: "".concat(duration, "ms") }; }; (0, _react.useEffect)(function() { var index = titles.current.findIndex(function(t) { return t.value === value; }); index = index < 0 ? 0 : index; setTimeout(function() { scrollIntoView(index); }); }, [ value ]); var tabChange = function tabChange(item) { onClick && onClick(item.value); if (!item.disabled) { setValue(item.value); } }; return /*#__PURE__*/ _react.default.createElement("div", (0, _object_spread._)({ className: classes }, rest), /*#__PURE__*/ _react.default.createElement("div", { className: classesTitle, style: tabStyle, ref: navRef }, !!title && typeof title === 'function' ? title() : titles.current.map(function(item) { var _obj; return /*#__PURE__*/ _react.default.createElement("div", { key: item.value, ref: function ref(ref) { return titleItemsRef.current.push(ref); }, onClick: function onClick() { return tabChange(item); }, className: (0, _classnames.default)("".concat(classPrefix, "-titles-item"), (_obj = {}, (0, _define_property._)(_obj, "nut-tabs-titles-item-active", !item.disabled && String(item.value) === String(value)), (0, _define_property._)(_obj, "nut-tabs-titles-item-disabled", item.disabled), (0, _define_property._)(_obj, "nut-tabs-titles-item-".concat(align), align), _obj)) }, activeType === 'line' && /*#__PURE__*/ _react.default.createElement("div", { className: (0, _classnames.default)("".concat(classPrefix, "-titles-item-line"), "".concat(classPrefix, "-titles-item-line-").concat(direction)), style: { background: activeColor } }), activeType === 'smile' && /*#__PURE__*/ _react.default.createElement("div", { className: "".concat(classPrefix, "-titles-item-smile") }, /*#__PURE__*/ _react.default.createElement(_iconsreact.JoySmile, { color: activeColor, width: 40, height: 20 })), /*#__PURE__*/ _react.default.createElement("div", { className: (0, _classnames.default)((0, _define_property._)({}, "".concat(classPrefix, "-ellipsis"), direction === 'vertical'), "".concat(classPrefix, "-titles-item-text")), style: { color: activeColor } }, item.title)); })), /*#__PURE__*/ _react.default.createElement("div", { className: "".concat(classPrefix, "-content-wrap") }, /*#__PURE__*/ _react.default.createElement("div", { className: "".concat(classPrefix, "-content"), style: getContentStyle() }, _react.default.Children.map(children, function(child, idx) { if (!/*#__PURE__*/ _react.default.isValidElement(child)) return null; return /*#__PURE__*/ _react.default.cloneElement(child, (0, _object_spread_props._)((0, _object_spread._)({}, child.props), { active: value === child.props.value, autoHeightClassName: autoHeight && String(value) !== String(child.props.value || idx) ? 'inactive' : '' })); })))); }; Tabs.displayName = 'NutTabs'; Tabs.TabPane = _tabpane.default;