style: model list buttons

This commit is contained in:
jialin
2025-03-12 10:43:59 +08:00
parent a7cfa05504
commit 5edbc1a7b5
24 changed files with 460 additions and 157 deletions
+54 -16
View File
@@ -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>
]}
+8 -3
View File
@@ -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)
+12 -3
View File
@@ -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>}
+2
View File
@@ -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}
+1
View File
@@ -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;
+4 -1
View File
@@ -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;
+1 -1
View File
@@ -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}
+9 -1
View File
@@ -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);
}
}
+24 -2
View File
@@ -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>
);
+73 -10
View File
@@ -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;