feat: columnsCount 支持手动控制每行显示列数 (#3719)

* feat: checkboxes/radios 的 columnsCount 支持手动分配每行的列数

* 改成以最大列作为列数保证对齐效果

* 改成以最大列作为列数保证对齐效果
This commit is contained in:
吴多益 2022-03-10 15:34:07 +08:00 committed by GitHub
parent 1c8db2a682
commit 0a2c5e76a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 113 additions and 35 deletions

View File

@ -145,6 +145,51 @@ order: 9
}
```
> 1.8.0 及以上版本
`columnsCount` 还有一种数组形式,可以手动控制每行显示的列数
```schema: scope="body"
{
"type": "form",
"api": "/api/mock2/form/saveForm",
"body": [
{
"name": "checkboxes1",
"type": "checkboxes",
"label": "默认的复选框",
"columnsCount": [1, 2, 3],
"options": [
{
"label": "OptionA",
"value": "a"
},
{
"label": "OptionB",
"value": "b"
},
{
"label": "OptionC",
"value": "c"
},
{
"label": "OptionD",
"value": "d"
},
{
"label": "OptionE",
"value": "e"
},
{
"label": "OptionF",
"value": "f"
}
]
}
]
}
```
## 分组显示
`"inline": false` 下,选项中配置 `children` 字段可以实现分组展示效果。

View File

@ -21,11 +21,12 @@ import Button from './Button';
import {value2array, OptionProps, Option} from './Select';
import chunk from 'lodash/chunk';
import {ClassNamesFn, themeable} from '../theme';
import {columnsSplit} from '../utils/columnsSplit';
interface RadioProps extends OptionProps {
id?: string;
type: string;
optionType?: string,
optionType?: string;
value?: string;
className?: string;
style?: React.CSSProperties;
@ -34,7 +35,7 @@ interface RadioProps extends OptionProps {
btnActiveLevel?: string;
disabled?: boolean;
onChange?: Function;
columnsCount: number;
columnsCount: number | number[];
itemClassName?: string;
labelField?: string;
labelClassName?: string;
@ -78,7 +79,7 @@ export class Radios extends React.Component<RadioProps, any> {
}
renderGroup(option: Option, index: number, valueArray: Array<Option>) {
const {classnames: cx, optionType, classPrefix: ns,} = this.props;
const {classnames: cx, optionType, classPrefix: ns} = this.props;
return (
<div key={index} className={cx('RadiosControl-group', option.className)}>
@ -178,20 +179,8 @@ export class Radios extends React.Component<RadioProps, any> {
);
}
if (!inline && columnsCount > 1) {
let weight = 12 / (columnsCount as number);
let cellClassName = `Grid-col--sm${
weight === Math.round(weight) ? weight : ''
}`;
body = chunk(body, columnsCount).map((group, groupIndex) => (
<div className={cx('Grid')} key={groupIndex}>
{Array.from({length: columnsCount as number}).map((_, index) => (
<div key={index} className={cx(cellClassName)}>
{group[index]}
</div>
))}
</div>
));
if (!inline) {
body = columnsSplit(body, cx, columnsCount);
}
return (

View File

@ -7,10 +7,11 @@ import {
} from './Options';
import cx from 'classnames';
import Checkbox from '../../components/Checkbox';
import chunk from 'lodash/chunk';
import {Icon} from '../../components/icons';
import {Api} from '../../types';
import {autobind, hasAbility} from '../../utils/helper';
import {columnsSplit} from '../../utils/columnsSplit';
/**
*
@ -32,7 +33,7 @@ export interface CheckboxesControlSchema extends FormOptionsControl {
/**
*
*/
columnsCount?: number;
columnsCount?: number | number[];
}
export interface CheckboxesProps
@ -47,7 +48,7 @@ export interface CheckboxesProps
> {
placeholder?: any;
itemClassName?: string;
columnsCount?: number;
columnsCount?: number | number[];
labelClassName?: string;
onAdd?: () => void;
addApi?: Api;
@ -221,21 +222,7 @@ export default class CheckboxesControl extends React.Component<
);
}
if ((columnsCount as number) > 1) {
let weight = 12 / (columnsCount as number);
let cellClassName = `Grid-col--sm${
weight === Math.round(weight) ? weight : ''
}`;
body = chunk(body, columnsCount).map((group, groupIndex) => (
<div className={cx('Grid')} key={groupIndex}>
{Array.from({length: columnsCount as number}).map((_, index) => (
<div key={index} className={cx(cellClassName)}>
{group[index]}
</div>
))}
</div>
));
}
body = columnsSplit(body, cx, columnsCount);
return (
<div className={cx(`CheckboxesControl`, className)}>

View File

@ -0,0 +1,57 @@
/**
* columnsCount
*/
import React from 'react';
import chunk from 'lodash/chunk';
export function columnsSplit(
body: any[],
cx: any,
columnsCount?: number | number[]
) {
if (Array.isArray(columnsCount) && columnsCount.length) {
let bodyIndex = 0;
const bodyList: JSX.Element[] = [];
const maxSize = Math.max(Math.round(12 / Math.max(...columnsCount)), 1);
let cellClassName = `Grid-col--sm${maxSize}`;
columnsCount.forEach((columnSize, groupIndex) => {
if (columnSize) {
bodyList.push(
<div className={cx('Grid')} key={groupIndex}>
{Array.from({length: columnSize}).map((_, index) => {
if (bodyIndex + index < body.length) {
// 避免溢出
return (
<div key={index} className={cx(cellClassName)}>
{body[bodyIndex + index]}
</div>
);
} else {
return null;
}
})}
</div>
);
bodyIndex = bodyIndex + columnSize;
}
});
body = bodyList;
} else if (typeof columnsCount === 'number' && columnsCount > 1) {
let weight = 12 / (columnsCount as number);
let cellClassName = `Grid-col--sm${
weight === Math.round(weight) ? weight : ''
}`;
body = chunk(body, columnsCount).map((group, groupIndex) => (
<div className={cx('Grid')} key={groupIndex}>
{Array.from({length: columnsCount as number}).map((_, index) => (
<div key={index} className={cx(cellClassName)}>
{group[index]}
</div>
))}
</div>
));
}
return body;
}