@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
162 lines (161 loc) • 6.86 kB
JavaScript
import { _ as _define_property } from "@swc/helpers/_/_define_property";
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import React, { useEffect, useRef } from "react";
import classNames from "classnames";
import { ComponentDefaults } from "../../utils/typings";
import SideBarItem from "../sidebaritem";
import raf from "../../utils/raf";
import { usePropsValue } from "../../hooks/use-props-value";
import { useForceUpdate } from "../../hooks/use-force-update";
import { mergeProps } from "../../utils/merge-props";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
contentDuration: 0,
sidebarDuration: 0
});
var classPrefix = 'nut-sidebar';
export var SideBar = function(props) {
var _mergeProps = mergeProps(defaultProps, props), contentDuration = _mergeProps.contentDuration, sidebarDuration = _mergeProps.sidebarDuration, children = _mergeProps.children, onClick = _mergeProps.onClick, onChange = _mergeProps.onChange, className = _mergeProps.className, rest = _object_without_properties(_mergeProps, [
"contentDuration",
"sidebarDuration",
"children",
"onClick",
"onChange",
"className"
]);
var _usePropsValue = _sliced_to_array(usePropsValue({
value: props.value,
defaultValue: props.defaultValue,
finalValue: 0,
onChange: onChange
}), 2), value = _usePropsValue[0], setValue = _usePropsValue[1];
var titleItemsRef = useRef([]);
var navRef = useRef(null);
var scroll = function(nav, to) {
var count = 0;
var from = nav.scrollTop;
var frames = sidebarDuration === 0 ? 1 : Math.round(sidebarDuration / 16);
function animate() {
nav.scrollTop += (to - from) / frames;
if (++count < frames) {
raf(animate);
}
}
animate();
};
var scrollIntoView = function(index) {
var nav = navRef.current;
var titleItem = titleItemsRef.current;
var titlesLength = titles.current.length;
var itemLength = titleItemsRef.current.length;
if (!nav || !titleItem || !titleItem[itemLength - titlesLength + index]) {
return;
}
var title = titleItem[itemLength - titlesLength + index];
var runTop = title.offsetTop - nav.offsetTop + 10;
var to = runTop - (nav.offsetHeight - title.offsetHeight) / 2 + title.offsetHeight;
scroll(nav, to);
};
var getTitles = function() {
var titles = [];
React.Children.forEach(children, function(child, idx) {
if (/*#__PURE__*/ React.isValidElement(child)) {
var _$props = child === null || child === void 0 ? void 0 : child.props;
if ((_$props === null || _$props === void 0 ? void 0 : _$props.title) || (_$props === null || _$props === void 0 ? void 0 : _$props.value)) {
var _props_value;
titles.push({
title: _$props.title,
value: (_props_value = _$props.value) !== null && _props_value !== void 0 ? _props_value : idx,
disabled: _$props.disabled
});
}
}
});
return titles;
};
var titles = useRef(getTitles());
var forceUpdate = useForceUpdate();
useEffect(function() {
titles.current = getTitles();
var current = '';
titles.current.forEach(function(title) {
if (title.value === value) {
current = value;
}
});
forceUpdate();
}, [
children
]);
var classes = classNames(classPrefix, className);
var classesTitle = classNames("".concat(classPrefix, "-titles"), "".concat(classPrefix, "-titles-scrollable"));
var getContentStyle = function() {
var index = titles.current.findIndex(function(t) {
return t.value === value;
});
index = index < 0 ? 0 : index;
return {
transform: "translate3d( 0,-".concat(index * 100, "%, 0)"),
transitionDuration: "".concat(contentDuration, "ms")
};
};
useEffect(function() {
var index = titles.current.findIndex(function(t) {
return t.value === value;
});
index = index < 0 ? 0 : index;
var rafId = requestAnimationFrame(function() {
scrollIntoView(index);
});
return function() {
return cancelAnimationFrame(rafId);
};
}, [
value
]);
var tabChange = function(item) {
if (item.disabled) return;
onClick === null || onClick === void 0 ? void 0 : onClick(item.value);
setValue(item.value);
};
return /*#__PURE__*/ React.createElement("div", _object_spread({
className: classes
}, rest), /*#__PURE__*/ React.createElement("div", {
className: classesTitle,
ref: navRef
}, titles.current.map(function(item) {
var _obj;
return /*#__PURE__*/ React.createElement("div", {
onClick: function() {
tabChange(item);
},
className: classNames("".concat(classPrefix, "-titles-item"), (_obj = {}, _define_property(_obj, "".concat(classPrefix, "-titles-item-active"), !item.disabled && String(item.value) === String(value)), _define_property(_obj, "".concat(classPrefix, "-titles-item-disabled"), item.disabled), _obj)),
ref: function(ref) {
return titleItemsRef.current.push(ref);
},
key: item.value
}, /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-titles-item-text")
}, item.title));
})), /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-content-wrap")
}, /*#__PURE__*/ React.createElement("div", {
className: "".concat(classPrefix, "-content"),
style: getContentStyle()
}, React.Children.map(children, function(child, idx) {
if (!/*#__PURE__*/ React.isValidElement(child)) {
return null;
}
var childProps = _object_spread_props(_object_spread({}, child.props), {
active: value === child.props.value
});
if (String(value) !== String(child.props.value || idx)) {
childProps = _object_spread({}, childProps);
}
return /*#__PURE__*/ React.cloneElement(child, childProps);
}))));
};
SideBar.displayName = 'NutSideBar';
SideBar.Item = SideBarItem;