Слияние кода завершено, страница обновится автоматически
import React, { Children, cloneElement, FunctionComponent, isValidElement, ReactElement, ReactNode, useContext, useMemo, useRef } from 'react';
import { action, observable, ObservableMap } from 'mobx';
import { observer } from 'mobx-react-lite';
import Trigger from 'choerodon-ui/lib/trigger';
import { Action } from 'choerodon-ui/lib/trigger/enum';
import ConfigContext from 'choerodon-ui/lib/config-provider/ConfigContext';
import BUILT_IN_PLACEMENTS from '../trigger-field/placements';
import { ButtonColor, FuncType } from '../button/enum';
import Button, { ButtonProps } from '../button/Button';
import { $l } from '../locale-context';
import isFragment from '../_util/isFragment';
import Attachment, { AttachmentProps } from './Attachment';
import { iteratorReduce } from '../_util/iteratorUtils';
export interface AttachmentGroupProps extends ButtonProps {
viewMode: 'list' | 'popup';
label?: ReactNode;
colSpan?: number;
rowSpan?: number;
text?: ReactNode;
count?: number;
}
type GetRef = (attachment: Attachment | null, index: number) => void;
function getRefCallback(callback, index) {
return item => callback(item, index);
}
function normalizeAttachments(children: ReactNode, getRef?: GetRef, index = { count: 0 }): ReactNode {
return Children.map(children, (child) => {
if (isFragment(child)) {
return normalizeAttachments(child.props.children, getRef, index);
}
if (isValidElement<AttachmentProps>(child) && (child.type as any).__PRO_ATTACHMENT) {
const props: AttachmentProps & { ref?: GetRef } = { viewMode: 'list', readOnly: true, __inGroup: true };
if (getRef) {
const { count } = index;
props.ref = getRefCallback(getRef, count);
index.count = count + 1;
}
return cloneElement<AttachmentProps>(child, props);
}
return undefined;
});
}
const AttachmentGroup: FunctionComponent<AttachmentGroupProps> = function AttachmentGroup(props) {
const { viewMode, children, hidden, text, count, ...buttonProps } = props;
const hasCount = count !== undefined;
const { getProPrefixCls, getConfig } = useContext(ConfigContext);
const listRef = useRef<ObservableMap<number, Attachment>>(observable.map());
const prefixCls = getProPrefixCls('attachment');
const computedCount = hasCount ? count : iteratorReduce<Attachment, number>(listRef.current.values(), (sum, attachment) => sum + (attachment.count || 0), 0);
const attachments = useMemo((): ReactElement | undefined => children ? (
<div className={`${prefixCls}-group`}>
{
normalizeAttachments(children, hasCount ? undefined : action((attachment, index) => {
if (attachment) {
listRef.current.set(index, attachment);
} else {
listRef.current.delete(index);
}
}))
}
</div>
) : undefined, [children, hasCount, viewMode, prefixCls]);
const renderEmpty = (): ReactElement | undefined => {
if (computedCount === 0) {
return (
<div className={`${prefixCls}-empty`}>
{getConfig('renderEmpty')('Attachment')}
</div>
);
}
};
const content: ReactElement = (
<>
{renderEmpty()}
{attachments}
</>
);
const renderGroup = (): ReactElement | null => {
if (hidden) {
return null;
}
if (viewMode === 'list') {
return content;
}
return (
<Trigger
prefixCls={prefixCls}
popupContent={content}
action={[Action.hover, Action.focus]}
builtinPlacements={BUILT_IN_PLACEMENTS}
popupPlacement="bottomLeft"
forceRender={!hasCount}
>
<Button
icon="attach_file"
funcType={FuncType.link}
color={ButtonColor.primary}
{...buttonProps}
>
{text || $l('Attachment', 'view_attachment')} {computedCount || undefined}
</Button>
</Trigger>
);
};
return renderGroup();
};
AttachmentGroup.defaultProps = {
viewMode: 'popup',
};
AttachmentGroup.displayName = 'AttachmentGroup';
export default observer(AttachmentGroup);
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )