style: model list buttons
This commit is contained in:
@@ -10,6 +10,11 @@ interface DropdownButtonsProps {
|
||||
items: MenuProps['items'];
|
||||
size?: 'small' | 'middle' | 'large';
|
||||
trigger?: Trigger[];
|
||||
showText?: boolean;
|
||||
disabled?: boolean;
|
||||
variant?: 'filled' | 'outlined';
|
||||
color?: string;
|
||||
extra?: React.ReactNode;
|
||||
onSelect: (val: any, item?: any) => void;
|
||||
}
|
||||
|
||||
@@ -17,9 +22,16 @@ const DropdownButtons: React.FC<DropdownButtonsProps> = ({
|
||||
items,
|
||||
size = 'middle',
|
||||
trigger = ['hover'],
|
||||
showText,
|
||||
disabled,
|
||||
variant,
|
||||
color,
|
||||
extra,
|
||||
onSelect
|
||||
}) => {
|
||||
const headItem = _.head(items);
|
||||
const intl = useIntl();
|
||||
|
||||
const handleMenuClick = (item: any) => {
|
||||
const selectItem = _.find(items, { key: item.key });
|
||||
onSelect(item.key, selectItem);
|
||||
@@ -37,19 +49,20 @@ const DropdownButtons: React.FC<DropdownButtonsProps> = ({
|
||||
return (
|
||||
<>
|
||||
{items?.length === 1 ? (
|
||||
<Tooltip title={intl.formatMessage({ id: _.head(items)?.label })}>
|
||||
<Tooltip title={intl.formatMessage({ id: headItem?.label })}>
|
||||
<Button
|
||||
className={classNames('dropdown-button', size)}
|
||||
{..._.head(items)}
|
||||
icon={_.get(items, '0.icon')}
|
||||
icon={headItem?.icon}
|
||||
size={size}
|
||||
{..._.get(items, '0.props')}
|
||||
{...headItem?.props}
|
||||
onClick={handleButtonClick}
|
||||
></Button>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Dropdown.Button
|
||||
disabled={disabled}
|
||||
trigger={trigger}
|
||||
type="primary"
|
||||
dropdownRender={(menus: any) => {
|
||||
return (
|
||||
<div
|
||||
@@ -67,9 +80,10 @@ const DropdownButtons: React.FC<DropdownButtonsProps> = ({
|
||||
<Button
|
||||
{...item.props}
|
||||
type="text"
|
||||
size="middle"
|
||||
size={size}
|
||||
icon={item.icon}
|
||||
key={item.key}
|
||||
disabled={item.disabled}
|
||||
onClick={() => handleMenuClick(item)}
|
||||
style={{ width: '100%', justifyContent: 'flex-start' }}
|
||||
>
|
||||
@@ -81,21 +95,45 @@ const DropdownButtons: React.FC<DropdownButtonsProps> = ({
|
||||
);
|
||||
}}
|
||||
buttonsRender={([leftButton, rightButton]) => [
|
||||
<Tooltip
|
||||
title={intl.formatMessage({ id: _.head(items)?.label })}
|
||||
key="leftButton"
|
||||
>
|
||||
<Button
|
||||
className={classNames('dropdown-button', size)}
|
||||
onClick={handleButtonClick}
|
||||
size={size}
|
||||
icon={_.head(items)?.icon}
|
||||
></Button>
|
||||
</Tooltip>,
|
||||
<>
|
||||
{showText ? (
|
||||
<Button
|
||||
{...headItem?.props}
|
||||
disabled={headItem?.disabled || disabled}
|
||||
className={classNames('dropdown-button', size)}
|
||||
onClick={handleButtonClick}
|
||||
size={size}
|
||||
icon={headItem?.icon}
|
||||
variant={variant}
|
||||
color={color}
|
||||
>
|
||||
{intl.formatMessage({
|
||||
id: headItem?.label
|
||||
})}
|
||||
{extra}
|
||||
</Button>
|
||||
) : (
|
||||
<Tooltip
|
||||
title={intl.formatMessage({ id: headItem?.label })}
|
||||
key="leftButton"
|
||||
>
|
||||
<Button
|
||||
{...headItem?.props}
|
||||
className={classNames('dropdown-button', size)}
|
||||
onClick={handleButtonClick}
|
||||
size={size}
|
||||
icon={headItem?.icon}
|
||||
disabled={headItem?.disabled}
|
||||
></Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</>,
|
||||
<Button
|
||||
icon={<MoreOutlined />}
|
||||
size={size}
|
||||
key="menu"
|
||||
variant={variant}
|
||||
color="default"
|
||||
className={classNames('dropdown-button', size)}
|
||||
></Button>
|
||||
]}
|
||||
|
||||
@@ -3,15 +3,20 @@ import React from 'react';
|
||||
import styles from './styles/wrapper.less';
|
||||
|
||||
const Wrapper: React.FC<{
|
||||
label?: string;
|
||||
label?: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
labelExtra?: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
}> = ({ children, label, description, ...rest }) => {
|
||||
}> = ({ children, label, description, labelExtra, ...rest }) => {
|
||||
return (
|
||||
<div className={styles['wrapper']}>
|
||||
{label && (
|
||||
<span className="label">
|
||||
<LabelInfo label={label} description={description}></LabelInfo>
|
||||
<LabelInfo
|
||||
label={label}
|
||||
description={description}
|
||||
labelExtra={labelExtra}
|
||||
></LabelInfo>
|
||||
</span>
|
||||
)}
|
||||
{React.isValidElement(children)
|
||||
|
||||
@@ -8,17 +8,26 @@ import ListItem from './list-item';
|
||||
|
||||
interface ListInputProps {
|
||||
dataList: string[];
|
||||
label: string;
|
||||
label: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
btnText?: string;
|
||||
options?: Global.HintOptions[];
|
||||
placeholder?: string;
|
||||
labelExtra?: React.ReactNode;
|
||||
onChange: (data: string[]) => void;
|
||||
}
|
||||
|
||||
const ListInput: React.FC<ListInputProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const { dataList, label, description, onChange, btnText, options } = props;
|
||||
const {
|
||||
dataList,
|
||||
label,
|
||||
description,
|
||||
onChange,
|
||||
btnText,
|
||||
options,
|
||||
labelExtra
|
||||
} = props;
|
||||
const [list, setList] = React.useState<{ value: string; uid: number }[]>([]);
|
||||
const countRef = React.useRef(0);
|
||||
const buttonRef = React.useRef<HTMLButtonElement>(null);
|
||||
@@ -71,7 +80,7 @@ const ListInput: React.FC<ListInputProps> = (props) => {
|
||||
}, [dataList]);
|
||||
|
||||
return (
|
||||
<Wrapper label={label} description={description}>
|
||||
<Wrapper label={label} description={description} labelExtra={labelExtra}>
|
||||
<>
|
||||
{_.map(list, (item: any, index: number) => {
|
||||
return (
|
||||
|
||||
@@ -7,9 +7,10 @@ interface NoteInfoProps {
|
||||
required?: boolean;
|
||||
label: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
labelExtra?: React.ReactNode;
|
||||
}
|
||||
const NoteInfo: React.FC<NoteInfoProps> = (props) => {
|
||||
const { required, description, label } = props || {};
|
||||
const { required, description, label, labelExtra } = props || {};
|
||||
if (!label) return null;
|
||||
|
||||
return (
|
||||
@@ -43,6 +44,7 @@ const NoteInfo: React.FC<NoteInfoProps> = (props) => {
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
{labelExtra}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@ interface WrapperProps {
|
||||
variant?: string;
|
||||
hasPrefix?: boolean;
|
||||
classList?: string;
|
||||
labelExtra?: React.ReactNode;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
@@ -35,6 +36,7 @@ const Wrapper: React.FC<WrapperProps> = ({
|
||||
hasPrefix,
|
||||
noWrapperStyle,
|
||||
classList,
|
||||
labelExtra,
|
||||
onClick
|
||||
}) => {
|
||||
return (
|
||||
@@ -74,6 +76,7 @@ const Wrapper: React.FC<WrapperProps> = ({
|
||||
label={label}
|
||||
required={required}
|
||||
description={description}
|
||||
labelExtra={labelExtra}
|
||||
></LabelInfo>
|
||||
</label>
|
||||
{extra && <div className={wrapperStyle.extra}>{extra}</div>}
|
||||
|
||||
@@ -20,6 +20,7 @@ const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
|
||||
checkStatus,
|
||||
trim = true,
|
||||
loading,
|
||||
labelExtra,
|
||||
...rest
|
||||
} = props;
|
||||
const [isFocus, setIsFocus] = useState(false);
|
||||
@@ -74,6 +75,7 @@ const SealInput: React.FC<InputProps & SealFormItemProps> = (props) => {
|
||||
<Wrapper
|
||||
status={checkStatus || status}
|
||||
label={label}
|
||||
labelExtra={labelExtra}
|
||||
isFocus={isFocus}
|
||||
required={required}
|
||||
description={description}
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface SealFormItemProps {
|
||||
addAfter?: React.ReactNode;
|
||||
allowNull?: boolean;
|
||||
loading?: React.ReactNode;
|
||||
labelExtra?: React.ReactNode;
|
||||
trim?: boolean;
|
||||
checkStatus?: 'success' | 'error' | 'warning' | '';
|
||||
}
|
||||
|
||||
@@ -53,12 +53,12 @@ const TableRow: React.FC<
|
||||
childrenDataRef.current = childrenData;
|
||||
const axiosToken = useRef<any>(null);
|
||||
const [updateChild, setUpdateChild] = useState(true);
|
||||
const [currentExpand, setCurrentExpand] = useState(false);
|
||||
|
||||
const { updateChunkedList, cacheDataListRef } = useUpdateChunkedList({
|
||||
dataList: childrenData,
|
||||
limit: 100,
|
||||
setDataList: setChildrenData
|
||||
// callback: (list) => renderChildren?.(list)
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -92,7 +92,10 @@ const TableRow: React.FC<
|
||||
></Empty>
|
||||
);
|
||||
}
|
||||
return renderChildren?.(childrenData, record);
|
||||
return renderChildren?.(childrenData, {
|
||||
parent: record,
|
||||
currentExpanded: currentExpand
|
||||
});
|
||||
};
|
||||
|
||||
const handlePolling = async () => {
|
||||
@@ -163,6 +166,7 @@ const TableRow: React.FC<
|
||||
|
||||
const handleRowExpand = async () => {
|
||||
onExpand?.(!expanded, record, record[rowKey]);
|
||||
setCurrentExpand(!expanded);
|
||||
|
||||
if (pollTimer.current) {
|
||||
clearInterval(pollTimer.current);
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 54px;
|
||||
padding-block: 5px;
|
||||
height: 54px;
|
||||
border-radius: var(--border-radius-mdium);
|
||||
transition: all 0.2s ease;
|
||||
|
||||
|
||||
@@ -59,7 +59,10 @@ export interface SealTableProps {
|
||||
onSort?: (dataIndex: string, order: 'ascend' | 'descend') => void;
|
||||
onExpand?: (expanded: boolean, record: any, rowKey: any) => void;
|
||||
onExpandAll?: (expanded: boolean) => void;
|
||||
renderChildren?: (data: any, parent?: any) => React.ReactNode;
|
||||
renderChildren?: (
|
||||
data: any,
|
||||
options: { parent?: any; [key: string]: any }
|
||||
) => React.ReactNode;
|
||||
loadChildren?: (record: any, options?: any) => Promise<any[]>;
|
||||
loadChildrenAPI?: (record: any) => string;
|
||||
contentRendered?: () => void;
|
||||
|
||||
@@ -14,7 +14,7 @@ const TableHeader = ({ columns }: TableHeaderProps) => {
|
||||
{columns.map((column: any, index: number) => {
|
||||
return (
|
||||
<th key={index}>
|
||||
<span className="cell-span">
|
||||
<span className="cell-span cell-header">
|
||||
{column.locale
|
||||
? intl.formatMessage({ id: column.title })
|
||||
: column.title}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
}
|
||||
|
||||
tr:last-child td {
|
||||
border-bottom: none;
|
||||
// border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,17 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
td {
|
||||
color: var(--color-white-quaternary);
|
||||
}
|
||||
|
||||
.cell-span {
|
||||
display: flex;
|
||||
padding: 4px 6px;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.cell-header {
|
||||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,31 @@ import TableHeader from './header';
|
||||
import './index.less';
|
||||
import TableRow from './row';
|
||||
|
||||
interface ColumnProps {
|
||||
export interface ColumnProps {
|
||||
title: string;
|
||||
key: string;
|
||||
render?: (data: { dataIndex: string; row: any }) => any;
|
||||
render?: (data: {
|
||||
dataIndex: string;
|
||||
dataList?: any[];
|
||||
row: any;
|
||||
rowIndex?: number;
|
||||
colIndex?: number;
|
||||
}) => any;
|
||||
locale?: boolean;
|
||||
colSpan?: (params: {
|
||||
row: any;
|
||||
rowIndex: number;
|
||||
colIndex: number;
|
||||
dataIndex: string;
|
||||
dataList: any[];
|
||||
}) => number;
|
||||
rowSpan?: (params: {
|
||||
row: any;
|
||||
rowIndex: number;
|
||||
colIndex: number;
|
||||
dataIndex: string;
|
||||
dataList: any[];
|
||||
}) => number;
|
||||
}
|
||||
|
||||
interface SimpleTableProps {
|
||||
@@ -42,7 +62,9 @@ const SimpleTabel: React.FC<SimpleTableProps> = (props) => {
|
||||
return (
|
||||
<TableRow
|
||||
row={item}
|
||||
rowIndex={index}
|
||||
columns={columns}
|
||||
dataList={dataSource}
|
||||
key={rowKey ? item[rowKey] : index}
|
||||
></TableRow>
|
||||
);
|
||||
|
||||
@@ -1,25 +1,88 @@
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
interface TableRowProps {
|
||||
row: any;
|
||||
columns: any;
|
||||
rowIndex: number;
|
||||
dataList: any[];
|
||||
}
|
||||
const TableRow = ({ row, columns }: TableRowProps) => {
|
||||
|
||||
interface TableCellProps {
|
||||
row: any;
|
||||
column: any;
|
||||
rowIndex: number;
|
||||
colIndex: number;
|
||||
dataList: any[];
|
||||
}
|
||||
const TableCell: React.FC<TableCellProps> = (props: TableCellProps) => {
|
||||
const { row, column, rowIndex, colIndex, dataList } = props;
|
||||
|
||||
const renderContent = useMemo(() => {
|
||||
return column.render
|
||||
? column.render({
|
||||
dataIndex: column.key,
|
||||
dataList: dataList,
|
||||
row: row,
|
||||
rowIndex,
|
||||
colIndex: colIndex
|
||||
})
|
||||
: row[column.key];
|
||||
}, [column, row, rowIndex, colIndex, dataList]);
|
||||
|
||||
if (renderContent === null && (column.colSpan || column.rowSpan)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<td
|
||||
key={colIndex}
|
||||
rowSpan={column.rowSpan?.({
|
||||
row,
|
||||
rowIndex,
|
||||
colIndex: colIndex,
|
||||
dataIndex: column.key,
|
||||
dataList: dataList
|
||||
})}
|
||||
colSpan={column.colSpan?.({
|
||||
row,
|
||||
rowIndex,
|
||||
colIndex: colIndex,
|
||||
dataIndex: column.key,
|
||||
dataList: dataList
|
||||
})}
|
||||
>
|
||||
<span className="cell-span">
|
||||
{column.render
|
||||
? column.render({
|
||||
dataIndex: column.key,
|
||||
dataList: dataList,
|
||||
row: row,
|
||||
rowIndex,
|
||||
colIndex: colIndex
|
||||
})
|
||||
: row[column.key]}
|
||||
</span>
|
||||
</td>
|
||||
);
|
||||
};
|
||||
|
||||
const TableRow = ({ row, columns, rowIndex, dataList }: TableRowProps) => {
|
||||
return (
|
||||
<tr>
|
||||
{columns.map((column: any, index: number) => {
|
||||
return (
|
||||
<td key={index}>
|
||||
<span className="cell-span">
|
||||
{column.render
|
||||
? column.render({ dataIndex: column.key, row: row })
|
||||
: row[column.key]}
|
||||
</span>
|
||||
</td>
|
||||
<TableCell
|
||||
key={index}
|
||||
rowIndex={rowIndex}
|
||||
colIndex={index}
|
||||
dataList={dataList}
|
||||
row={row}
|
||||
column={column}
|
||||
></TableCell>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(TableRow);
|
||||
export default TableRow;
|
||||
|
||||
Reference in New Issue
Block a user