@cainiaofe/cn-ui-m
Version:
182 lines (181 loc) • 8.01 kB
JavaScript
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';