test-nut-ui
Version:
<p align="center"> <img alt="logo" src="https://img11.360buyimg.com/imagetools/jfs/t1/211965/25/7152/22022/61b16785E433119bb/aa41d7a9f7e823f3.png" width="150" style="margin-bottom: 10px;"> </p>
394 lines (393 loc) • 20.6 kB
JavaScript
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
var _excluded = ["activeColor", "tabStyle", "direction", "activeType", "duration", "isSticky", "stickyThreshold", "align", "type", "underlineType", "sliderMode", "title", "line", "children", "onClick", "onChange", "className", "autoHeight", "dividerType", "menu"];
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
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 = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), true).forEach(function(key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function(key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
import React__default, { useState, useRef, useEffect } from "react";
import classNames from "classnames";
import { JoySmile } from "@nutui/icons-react";
import { C as ComponentDefaults } from "./typings.js";
import TabPane from "./TabPane.js";
import { r as requestAniFrame } from "./raf.js";
import { u as usePropsValue } from "./use-props-value.js";
import Sticky from "./Sticky.js";
import Divider from "./Divider.js";
import { b as br } from "./index.js";
import Radio from "./Radio.js";
function useForceUpdate() {
var _React__default$useSt = React__default.useState(), _React__default$useSt2 = _slicedToArray(_React__default$useSt, 2), updateState = _React__default$useSt2[1];
return React__default.useCallback(function() {
return updateState({});
}, []);
}
var defaultProps = _objectSpread(_objectSpread({}, ComponentDefaults), {}, {
tabStyle: {},
activeColor: "",
type: "normal",
sliderMode: "normal",
underlineType: "normal",
isSticky: false,
stickyThreshold: 0,
direction: "horizontal",
activeType: "line",
duration: 300,
autoHeight: false,
dividerType: "none",
menu: false
});
var classPrefix = "nut-tabs";
var Tabs = function Tabs2(props) {
var _classNames2;
var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props), activeColor = _defaultProps$props.activeColor, tabStyle = _defaultProps$props.tabStyle, direction = _defaultProps$props.direction, activeType = _defaultProps$props.activeType, duration = _defaultProps$props.duration, isSticky = _defaultProps$props.isSticky, stickyThreshold = _defaultProps$props.stickyThreshold, align = _defaultProps$props.align, type = _defaultProps$props.type, underlineType = _defaultProps$props.underlineType, sliderMode = _defaultProps$props.sliderMode, title = _defaultProps$props.title, line = _defaultProps$props.line, children = _defaultProps$props.children, onClick = _defaultProps$props.onClick, onChange = _defaultProps$props.onChange, className = _defaultProps$props.className, autoHeight = _defaultProps$props.autoHeight, dividerType = _defaultProps$props.dividerType, menu = _defaultProps$props.menu, rest = _objectWithoutProperties(_defaultProps$props, _excluded);
var _usePropsValue = usePropsValue({
value: props.value,
defaultValue: props.defaultValue,
finalValue: 0,
onChange
}), _usePropsValue2 = _slicedToArray(_usePropsValue, 2), value = _usePropsValue2[0], setValue = _usePropsValue2[1];
var _useState = useState({}), _useState2 = _slicedToArray(_useState, 2), contentStyle = _useState2[0], setContentStyle = _useState2[1];
var titleItemsRef = useRef([]);
var navRef = useRef(null);
var scrollDirection = function scrollDirection2(nav, to, duration2, direction2) {
var count = 0;
var from = direction2 === "horizontal" ? nav.scrollLeft : nav.scrollTop;
var frames = duration2 === 0 ? 1 : Math.round(duration2 * 1e3 / 16);
function animate() {
if (direction2 === "horizontal") {
nav.scrollLeft += (to - from) / frames;
} else {
nav.scrollTop += (to - from) / frames;
}
if (++count < frames) {
requestAniFrame(animate);
} else {
onSetOverIndex();
}
}
animate();
};
var scrollIntoView = function scrollIntoView2(index, immediate) {
var nav = navRef.current;
var titleItem = titleItemsRef.current;
if (!nav || !titleItem || !titleItem[index]) {
return;
}
var title2 = titleItem[index];
var to = 0;
if (props.direction === "vertical") {
var runTop = title2.offsetTop - nav.offsetTop + 10;
to = runTop - (nav.offsetHeight - title2.offsetHeight) / 2;
} else {
to = title2.offsetLeft - (nav.offsetWidth - title2.offsetWidth) / 2;
}
scrollDirection(nav, to, immediate ? 0 : 0.3, props.direction);
};
var getTitles = function getTitles2() {
var titles2 = [];
React__default.Children.forEach(children, function(child, idx) {
if (React__default.isValidElement(child)) {
var props2 = child === null || child === void 0 ? void 0 : child.props;
if (props2 !== null && props2 !== void 0 && props2.title || props2 !== null && props2 !== void 0 && props2.value) {
titles2.push({
title: props2.title,
value: props2.value || idx,
disabled: props2.disabled
});
}
}
});
return titles2;
};
var titles = useRef(getTitles());
var forceUpdate = useForceUpdate();
useEffect(function() {
titles.current = getTitles();
var current = "";
titles.current.forEach(function(title2) {
if (title2.value == value) {
current = value;
}
});
if (current !== "" && current !== value) {
setValue(current);
} else {
forceUpdate();
}
}, [children]);
var classes = classNames(classPrefix, "".concat(classPrefix, "--").concat(direction), "".concat(classPrefix, "--").concat(type), "".concat(classPrefix, "--").concat(type, "-").concat(sliderMode), _defineProperty({}, "".concat(classPrefix, "--menu"), menu), className);
var _useState3 = useState(generateRandomId()), _useState4 = _slicedToArray(_useState3, 1), timeStamp = _useState4[0];
var classesTitle = classNames("".concat(classPrefix, "__titles"), "".concat(classPrefix, "__titles-").concat(timeStamp), (_classNames2 = {}, _defineProperty(_classNames2, "".concat(classPrefix, "__titles--").concat(activeType), activeType), _defineProperty(_classNames2, "".concat(classPrefix, "__titles--scrollable"), true), _defineProperty(_classNames2, "".concat(classPrefix, "__titles--").concat(align), align), _defineProperty(_classNames2, "".concat(classPrefix, "__titles--shadow-").concat(direction), dividerType === "shadow"), _classNames2));
var tabsActiveStyle = {
color: activeType === "smile" ? activeColor : "",
background: activeType === "line" ? activeColor : ""
};
function generateRandomId() {
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var uniqueId = "";
var idLength = 10;
for (var i = 0; i < idLength; i++) {
var randomIndex = Math.floor(Math.random() * characters.length);
uniqueId += characters.charAt(randomIndex);
}
return uniqueId;
}
var _useState5 = useState(0), _useState6 = _slicedToArray(_useState5, 2), activeItemWidth = _useState6[0], setActiveItemWidth = _useState6[1];
var _useState7 = useState({}), _useState8 = _slicedToArray(_useState7, 2), activeItemStyle = _useState8[0], setActiveItemStyle = _useState8[1];
var _useState9 = useState(0), _useState10 = _slicedToArray(_useState9, 2), lineWidth = _useState10[0], setLineWidth = _useState10[1];
var _useState11 = useState(-1), _useState12 = _slicedToArray(_useState11, 2), overIndex = _useState12[0], setOverIndex = _useState12[1];
var onSetOverIndex = function onSetOverIndex2() {
if (!menu)
return false;
var scrollItem = document.querySelector(".".concat(classPrefix, "__titles-").concat(timeStamp));
var titleItems = document.querySelectorAll(".nut-tabs__titles-item-".concat(timeStamp));
var totalWidth = 0;
var flag = true;
titleItems.forEach && titleItems.forEach(function(item, index) {
var _navRef$current;
totalWidth += item.clientWidth;
if (totalWidth - (((_navRef$current = navRef.current) === null || _navRef$current === void 0 ? void 0 : _navRef$current.scrollLeft) || 0) + 50 > ((scrollItem === null || scrollItem === void 0 ? void 0 : scrollItem.clientWidth) || 0) && flag) {
setOverIndex(index);
flag = false;
}
});
return true;
};
useEffect(function() {
var index = titles.current.findIndex(function(t) {
return t.value == value;
});
setContentStyle({
transform: direction === "horizontal" ? "translate3d(-".concat(index * 100, "%, 0, 0)") : "translate3d( 0,-".concat(index * 100, "%, 0)"),
transitionDuration: "".concat(duration, "ms")
});
setTimeout(function() {
scrollIntoView(index);
var activeItem = document.querySelector(".nut-tabs__titles-item--active-".concat(timeStamp));
var lineItem = document.querySelector(".nut-tabs__titles-item--active-text-".concat(timeStamp));
document.querySelectorAll(".nut-tabs__titles-item-".concat(timeStamp));
setActiveItemWidth((activeItem === null || activeItem === void 0 ? void 0 : activeItem.clientWidth) || 82);
setActiveItemStyle(activeItem === null || activeItem === void 0 ? void 0 : activeItem.offsetLeft);
setLineWidth((lineItem === null || lineItem === void 0 ? void 0 : lineItem.clientWidth) || 40);
if (direction === "horizontal") {
var scrollItem = document.querySelector(".".concat(classPrefix, "__titles-").concat(timeStamp));
if (scrollItem && (scrollItem === null || scrollItem === void 0 ? void 0 : scrollItem.scrollWidth) > (scrollItem === null || scrollItem === void 0 ? void 0 : scrollItem.clientWidth)) {
setScrollX(true);
} else {
setScrollX(false);
}
}
});
}, [value]);
var tabChange = function tabChange2(item) {
onClick && onClick(item.value);
if (item.disabled) {
return;
}
setValue(item.value);
};
var _useState13 = useState(true), _useState14 = _slicedToArray(_useState13, 2), showScreen = _useState14[0], setShowScreen = _useState14[1];
var _useState15 = useState(false), _useState16 = _slicedToArray(_useState15, 2), scrollX = _useState16[0], setScrollX = _useState16[1];
var onScroll = function onScroll2() {
if (direction === "horizontal") {
var scrollItem = document.querySelector(".".concat(classPrefix, "__titles-").concat(timeStamp));
if (scrollItem && (scrollItem === null || scrollItem === void 0 ? void 0 : scrollItem.scrollWidth) - 1 > (scrollItem === null || scrollItem === void 0 ? void 0 : scrollItem.clientWidth) + (scrollItem === null || scrollItem === void 0 ? void 0 : scrollItem.scrollLeft)) {
onSetOverIndex();
setShowScreen(true);
} else {
setShowScreen(false);
}
}
};
var dividerStyle = function dividerStyle2() {
var dividerStyle22 = {};
dividerStyle22.position = "absolute";
dividerStyle22.margin = 0;
if (direction === "horizontal") {
dividerStyle22.left = 0;
dividerStyle22.width = "100%";
} else {
dividerStyle22.top = 0;
dividerStyle22.height = "100%";
}
return dividerStyle22;
};
var _useState17 = useState(false), _useState18 = _slicedToArray(_useState17, 2), showWrap = _useState18[0], setShowWrap = _useState18[1];
var renderTitles = function renderTitles2() {
return React__default.createElement("div", {
className: classesTitle,
style: _objectSpread({}, tabStyle),
ref: navRef,
onScroll
}, scrollX && showScreen ? React__default.createElement(React__default.Fragment, null, React__default.createElement("div", {
className: "".concat(classPrefix, "__scroll--screen ").concat(menu ? "scroll--screen_menu" : "")
}), React__default.createElement("div", {
onClick: function onClick2() {
return onSetOverIndex() && setShowWrap(!showWrap);
},
className: "".concat(classPrefix, "__scroll--block ").concat(menu ? "scroll--block_menu" : "")
}, menu && React__default.createElement(br, {
className: "".concat(classPrefix, "__scroll--block-icon-").concat(showWrap ? "up" : "down")
}))) : null, showWrap && showScreen ? React__default.createElement("div", {
className: "".concat(classPrefix, "__extra-title")
}, React__default.createElement(Radio.Group, {
style: {
padding: "0 16px",
marginBottom: "16px !important"
},
value,
direction: "horizontal"
}, titles.current.slice(overIndex).map(function(item, index) {
return React__default.createElement(Radio, {
className: "".concat(classPrefix, "__extra-title-radio"),
key: item.value,
onClick: function onClick2() {
return tabChange(item);
},
shape: "button",
value: item.value
}, item.title);
}))) : React__default.createElement(React__default.Fragment, null), !!title && typeof title === "function" ? title() : type === "normal" ? titles.current.map(function(item) {
var _classNames3;
return React__default.createElement("div", {
onClick: function onClick2() {
tabChange(item);
},
className: classNames("".concat(classPrefix, "__titles-item"), "nut-tabs__titles-item-".concat(timeStamp), (_classNames3 = {}, _defineProperty(_classNames3, "nut-tabs__titles-item--active-".concat(timeStamp), !item.disabled && String(item.value) === String(value)), _defineProperty(_classNames3, "nut-tabs__titles-item--active", !item.disabled && String(item.value) === String(value)), _defineProperty(_classNames3, "nut-tabs__titles-item--last", String(item.value) === String(+value - 1)), _defineProperty(_classNames3, "nut-tabs__titles-item--next", String(item.value) === String(+value + 1)), _defineProperty(_classNames3, "nut-tabs__titles-item--disabled", item.disabled), _defineProperty(_classNames3, "nut-tabs__titles-item--".concat(align), align), _classNames3)),
ref: function ref(_ref) {
return titleItemsRef.current.push(_ref);
},
key: item.value
}, activeType === "line" && !line && React__default.createElement("div", {
className: "".concat(classPrefix, "__titles-item__line ").concat(classPrefix, "__titles-item__line-").concat(underlineType),
style: _objectSpread(_objectSpread({}, tabsActiveStyle), {}, {
"--nutui-tabs-horizontal-titles-item-active-line-width": underlineType === "normal" ? "" : underlineType === "adaptive" ? lineWidth + "px" : "100%"
})
}), activeType === "smile" && !line && React__default.createElement("div", {
className: "".concat(classPrefix, "__titles-item__smile"),
style: _objectSpread({}, tabsActiveStyle)
}, React__default.createElement(JoySmile, {
color: activeColor,
width: 40,
height: 20
})), React__default.createElement("div", {
className: classNames(_defineProperty({
ellipsis: true
}, "nut-tabs__titles-item--active-text-".concat(timeStamp), !item.disabled && String(item.value) === String(value)), "".concat(classPrefix, "__titles-item__text"))
}, item.title));
}) : type === "tag" ? titles.current.map(function(item) {
var _classNames5;
return React__default.createElement("div", {
onClick: function onClick2() {
tabChange(item);
},
className: classNames("".concat(classPrefix, "__titles-tag-item"), "nut-tabs__titles-item", (_classNames5 = {}, _defineProperty(_classNames5, "nut-tabs__titles-item--active-".concat(timeStamp), !item.disabled && String(item.value) === String(value)), _defineProperty(_classNames5, "nut-tabs__titles-tag-item--active", !item.disabled && String(item.value) === String(value)), _classNames5)),
key: item.value
}, React__default.createElement("div", {
className: classNames({
ellipsis: true
}, "".concat(classPrefix, "__titles-item__text"))
}, item.title));
}) : type === "slider" ? titles.current.map(function(item) {
var _classNames6;
return React__default.createElement("div", {
onClick: function onClick2() {
tabChange(item);
},
className: classNames("".concat(classPrefix, "__titles-slider-item"), "nut-tabs__titles-item", (_classNames6 = {}, _defineProperty(_classNames6, "nut-tabs__titles-item--active-".concat(timeStamp), !item.disabled && String(item.value) === String(value)), _defineProperty(_classNames6, "nut-tabs__titles-slider-item--active", !item.disabled && String(item.value) === String(value)), _classNames6)),
key: item.value
}, React__default.createElement("div", {
className: classNames({
ellipsis: true
}, "".concat(classPrefix, "__titles-item__text"))
}, item.title));
}) : type === "card" ? titles.current.map(function(item) {
var _classNames7;
return React__default.createElement("div", {
onClick: function onClick2() {
tabChange(item);
},
className: classNames("".concat(classPrefix, "__titles-card-item"), "nut-tabs__titles-item", (_classNames7 = {}, _defineProperty(_classNames7, "nut-tabs__titles-item--active-".concat(timeStamp), !item.disabled && String(item.value) === String(value)), _defineProperty(_classNames7, "nut-tabs__titles-card-item--active", !item.disabled && String(item.value) === String(value)), _classNames7)),
key: item.value
}, React__default.createElement("div", {
className: classNames({
ellipsis: true
}, "".concat(classPrefix, "__titles-item__text"))
}, item.title));
}) : type === "radio" ? React__default.createElement(Radio.Group, {
className: "nut-tabs--radio-group",
value,
direction: "horizontal"
}, titles.current.map(function(item, index) {
return React__default.createElement(Radio, {
style: {
"--nutui-radiogroup-radio-margin": "9px 16px 9px 0"
},
key: item.value,
onClick: function onClick2() {
return tabChange(item);
},
shape: "button",
value: item.value
}, item.title);
})) : React__default.createElement(React__default.Fragment, null), !!line && typeof line === "function" ? line() : type === "tag" || type === "slider" ? React__default.createElement("div", {
className: "nut-tabs__titles-item--active-line",
style: {
"--nutui-tabs__titles-item--active-line-width": activeItemWidth + "px",
left: activeItemStyle + "px"
}
}) : React__default.createElement(React__default.Fragment, null), dividerType === "line" && React__default.createElement(Divider, {
className: "nut-tabs__divider--".concat(direction),
style: dividerStyle(),
direction
}));
};
return React__default.createElement("div", _objectSpread({
className: classes
}, rest), isSticky ? React__default.createElement(Sticky, {
threshold: stickyThreshold
}, renderTitles()) : renderTitles(), React__default.createElement("div", {
className: "".concat(classPrefix, "__content__wrap")
}, React__default.createElement("div", {
className: "".concat(classPrefix, "__content"),
style: contentStyle
}, React__default.Children.map(children, function(child, idx) {
if (!React__default.isValidElement(child)) {
return null;
}
var childProps = _objectSpread(_objectSpread({}, child.props), {}, {
active: value === child.props.value
});
if (String(value) !== String(child.props.value || idx) && autoHeight) {
childProps = _objectSpread(_objectSpread({}, childProps), {}, {
autoHeightClassName: "inactive"
});
}
return React__default.cloneElement(child, childProps);
}))));
};
Tabs.defaultProps = defaultProps;
Tabs.displayName = "NutTabs";
Tabs.TabPane = TabPane;
export {
Tabs as T
};