UNPKG

@cainiaofe/cn-ui-m

Version:
182 lines (181 loc) 8.01 kB
import { __spreadArray } from "tslib"; import * as React from 'react'; import { useEffect, useMemo, useRef, useState } from 'react'; import cx from 'classnames'; import { guid, useGuid } from "../../utils/use-guid"; import { CnButton } from "../cn-button"; import { CnIcon } from "../cn-icon"; import { CnActionSheet } from "../cn-action-sheet"; import { getWidth, MORE_BUTTON_WIDTH, remToPx } from './utils'; import './cn-button-group.scss'; import { withNativeProps } from '@cainiaofe/cn-ui-common'; /** * @category 组件 * 按钮组,用于排列多个按钮 */ export var CnButtonGroup = function (props) { var children = props.children, fullWidth = props.fullWidth, _a = props.size, size = _a === void 0 ? 'medium' : _a, isReverse = props.isReverse, containerId = props.containerId, propsHiddenIdx = props.hiddenIdx, shape = props.shape; var _b = useState(propsHiddenIdx || 0), hiddenIdx = _b[0], setHiddenIdx = _b[1]; var containerUid = useGuid('tab-scroll-'); var curContainerId = containerId || containerUid; var buttonWidthMap = useRef({}); var _c = useMemo(function () { var newHiddenChildren = []; var newButtonChildren = []; if (isReverse) { React.Children.forEach(children, function (item, idx) { if (React.isValidElement(item)) { if (hiddenIdx !== 0 && idx >= hiddenIdx) { newHiddenChildren.push(item); } else { newButtonChildren.push(item); } } }); newButtonChildren = newButtonChildren.reverse(); } else { React.Children.forEach(children, function (item, idx) { if (React.isValidElement(item)) { if (hiddenIdx !== 0 && idx < React.Children.count(children) - hiddenIdx) { newHiddenChildren.push(item); } else { newButtonChildren.push(item); } } }); newHiddenChildren = newHiddenChildren.reverse(); } newButtonChildren = React.Children.map(newButtonChildren, function (item, idx) { var isLast = newButtonChildren.length === idx + 1; var type = item === null || item === void 0 ? void 0 : item.props.type; if (isLast && shape === 'card') { type = 'secondary'; } var uid = guid('cn-ui-m-button-group-idx-'); return React.cloneElement(item, { key: uid, id: uid, fullWidth: fullWidth, size: size, type: type }); }); return { buttonChildren: newButtonChildren, hiddenChildren: newHiddenChildren, }; }, [children, fullWidth, hiddenIdx, isReverse, shape, size]), buttonChildren = _c.buttonChildren, hiddenChildren = _c.hiddenChildren; useEffect(function () { if (propsHiddenIdx) return; var containerWidth = getWidth(curContainerId); var totalWidth = 0; var orderedButtonChildren = isReverse ? buttonChildren : __spreadArray([], buttonChildren, true).reverse(); var marginRight = remToPx(0.08); React.Children.forEach(orderedButtonChildren, function (item, idx) { var uid = item.props.id; if (uid) { var itemWidth = getWidth(uid); if (!itemWidth) totalWidth -= marginRight; if (idx !== 0) { itemWidth += marginRight; } buttonWidthMap.current[idx] = itemWidth; totalWidth += itemWidth; } }); var hiddenButtonWidth = remToPx(MORE_BUTTON_WIDTH[size] * 0.01); // overflow 开始进行隐藏 if (totalWidth > containerWidth) { var displayWidth = 0; var lastDisplayIdx = 0; // 只要显示的宽度 + more按钮宽度 while (displayWidth + hiddenButtonWidth + buttonWidthMap.current[lastDisplayIdx] < containerWidth) { displayWidth += buttonWidthMap.current[lastDisplayIdx]; lastDisplayIdx += 1; } setHiddenIdx(lastDisplayIdx); } }, [ buttonChildren, children, curContainerId, isReverse, propsHiddenIdx, size, ]); var classes = cx(CN_UI_HASH_CLASS_NAME, 'cn-ui-m-button-group', { 'cn-ui-m-button-group-fullwidth': fullWidth }, props.className); var hiddenButtonRender = React.useCallback(function () { var disabledIndexes = []; var options = React.Children.map(hiddenChildren, function (item, index) { var _a, _b, _c; if ((_a = item.props) === null || _a === void 0 ? void 0 : _a.disabled) { disabledIndexes.push(index); } var option = (_b = item.props) === null || _b === void 0 ? void 0 : _b.children; // 处理 Button 中 含有 icon 组件的情况 if (Array.isArray(option)) { var currentBtn = item; if (((_c = currentBtn.props) === null || _c === void 0 ? void 0 : _c.optType) === 'buttonGroup') { var _d = currentBtn.props || {}, label_1 = _d.label, buttonList_1 = _d.children; option = { text: label_1, menu: true, }; // 给菜单按钮添加 onClick 事件 hiddenChildren[index].props.onClick = function () { CnActionSheet.show({ options: buttonList_1, showCancel: false, mode: 'menu', message: label_1, onClick: function (_, idx, v) { var _a, _b; if (typeof idx !== 'undefined') { (_b = (_a = buttonList_1[idx].props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, v); } }, }); }; } else { React.Children.forEach(option, function (textItem) { if (textItem && typeof textItem === 'string') { option = textItem; } }); } } return option; }); var hiddenButtonSheet = function () { return CnActionSheet.show({ disabledIndexes: disabledIndexes, options: options, onClick: function (option, index, e) { var _a, _b; if (typeof index !== 'undefined') { (_b = (_a = hiddenChildren[index].props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, e); } }, }); }; return (hiddenIdx !== 0 && (hiddenChildren === null || hiddenChildren === void 0 ? void 0 : hiddenChildren.length) > 0 && (React.createElement(CnButton, { size: size, onClick: hiddenButtonSheet, className: "cn-ui-m-button-group-more" }, React.createElement(CnIcon, { size: size, type: "ellipsis-more", className: "more-icon" })))); }, [hiddenChildren, hiddenIdx, size]); return withNativeProps(props, React.createElement("div", { className: classes, id: containerUid }, hiddenButtonRender(), buttonChildren)); }; CnButtonGroup.defaultProps = { fullWidth: false, isReverse: false, size: 'medium', shape: 'form', }; CnButtonGroup.displayName = 'CnButtonGroup';