UNPKG

@nutui/nutui-react

Version:

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

162 lines (161 loc) 6.86 kB
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;