feat: List grid support more column count (#23630)

* list grid

* 🎬 update demo/useBreakpoint.md

* List grid support all number

* refactor object entries

* docs: update List grid API

*  fix snapshot

* fix ci

* use max-width instead of flex %
This commit is contained in:
偏右 2020-04-27 16:59:33 +08:00 committed by GitHub
parent 2da7e29198
commit 053497724d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 102 additions and 95 deletions

View File

@ -1227,14 +1227,4 @@ exports[`renders ./components/grid/demo/sort.md correctly 1`] = `
</div>
`;
exports[`renders ./components/grid/demo/useBreakpoint.md correctly 1`] = `
<div
class="ant-row"
>
<div
class="ant-col"
>
Current break point: 
</div>
</div>
`;
exports[`renders ./components/grid/demo/useBreakpoint.md correctly 1`] = `null`;

View File

@ -12,23 +12,23 @@ title: useBreakpoint Hook
Use `useBreakpoint` Hook povide personalized layout.
```jsx
import { Row, Col, Grid } from 'antd';
import { Grid, Tag } from 'antd';
const { useBreakpoint } = Grid;
function UseBreakpointDemo() {
const screens = useBreakpoint();
return (
<Row>
<Col>
Current break point:&nbsp;
{Object.entries(screens)
.filter(screen => !!screen[1])
.map(screen => screen[0])
.join(' ')}
</Col>
</Row>
<>
Current break point:{' '}
{Object.entries(screens)
.filter(screen => !!screen[1])
.map(screen => (
<Tag color="blue" key={screen[0]}>
{screen[0]}
</Tag>
))}
</>
);
}

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import classNames from 'classnames';
import { ListGridType, ColumnType, ListContext } from './index';
import { ListGridType, ListContext } from './index';
import { Col } from '../grid';
import { ConfigContext } from '../config-provider';
import { cloneElement } from '../_util/reactNode';
@ -14,6 +14,7 @@ export interface ListItemProps extends React.HTMLAttributes<HTMLDivElement> {
extra?: React.ReactNode;
actions?: React.ReactNode[];
grid?: ListGridType;
colStyle?: React.CSSProperties;
}
export interface ListItemMetaProps {
@ -54,10 +55,6 @@ export const Meta: React.FC<ListItemMetaProps> = ({
);
};
function getGrid(grid: ListGridType, t: ColumnType) {
return grid[t] && Math.floor(24 / grid[t]!);
}
export interface ListItemTypeProps extends React.FC<ListItemProps> {
Meta: typeof Meta;
}
@ -85,7 +82,15 @@ const Item: ListItemTypeProps = props => {
return !isItemContainsTextNodeAndNotSingular();
};
const { prefixCls: customizePrefixCls, children, actions, extra, className, ...others } = props;
const {
prefixCls: customizePrefixCls,
children,
actions,
extra,
className,
colStyle,
...others
} = props;
const prefixCls = getPrefixCls('list', customizePrefixCls);
const actionsContent = actions && actions.length > 0 && (
<ul className={`${prefixCls}-item-action`} key="actions">
@ -98,9 +103,9 @@ const Item: ListItemTypeProps = props => {
))}
</ul>
);
const Tag = grid ? 'div' : 'li';
const Element = grid ? 'div' : 'li';
const itemChildren = (
<Tag
<Element
{...(others as any)} // `li` element `onCopy` prop args is not same as `div`
className={classNames(`${prefixCls}-item`, className, {
[`${prefixCls}-item-no-flex`]: !isFlexMode(),
@ -117,19 +122,11 @@ const Item: ListItemTypeProps = props => {
</div>,
]
: [children, actionsContent, cloneElement(extra, { key: 'extra' })]}
</Tag>
</Element>
);
return grid ? (
<Col
span={getGrid(grid, 'column')}
xs={getGrid(grid, 'xs')}
sm={getGrid(grid, 'sm')}
md={getGrid(grid, 'md')}
lg={getGrid(grid, 'lg')}
xl={getGrid(grid, 'xl')}
xxl={getGrid(grid, 'xxl')}
>
<Col flex={1} style={colStyle}>
{itemChildren}
</Col>
) : (

View File

@ -182,8 +182,8 @@ exports[`renders ./components/list/demo/grid.md correctly 1`] = `
style="margin-left:-8px;margin-right:-8px"
>
<div
class="ant-col ant-col-6"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;width:25%;max-width:25%;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -213,8 +213,8 @@ exports[`renders ./components/list/demo/grid.md correctly 1`] = `
</div>
</div>
<div
class="ant-col ant-col-6"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;width:25%;max-width:25%;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -244,8 +244,8 @@ exports[`renders ./components/list/demo/grid.md correctly 1`] = `
</div>
</div>
<div
class="ant-col ant-col-6"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;width:25%;max-width:25%;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -275,8 +275,8 @@ exports[`renders ./components/list/demo/grid.md correctly 1`] = `
</div>
</div>
<div
class="ant-col ant-col-6"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;width:25%;max-width:25%;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -451,8 +451,8 @@ exports[`renders ./components/list/demo/resposive.md correctly 1`] = `
style="margin-left:-8px;margin-right:-8px"
>
<div
class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-md-6 ant-col-lg-6 ant-col-xl-4 ant-col-xxl-8"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -482,8 +482,8 @@ exports[`renders ./components/list/demo/resposive.md correctly 1`] = `
</div>
</div>
<div
class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-md-6 ant-col-lg-6 ant-col-xl-4 ant-col-xxl-8"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -513,8 +513,8 @@ exports[`renders ./components/list/demo/resposive.md correctly 1`] = `
</div>
</div>
<div
class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-md-6 ant-col-lg-6 ant-col-xl-4 ant-col-xxl-8"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -544,8 +544,8 @@ exports[`renders ./components/list/demo/resposive.md correctly 1`] = `
</div>
</div>
<div
class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-md-6 ant-col-lg-6 ant-col-xl-4 ant-col-xxl-8"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -575,8 +575,8 @@ exports[`renders ./components/list/demo/resposive.md correctly 1`] = `
</div>
</div>
<div
class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-md-6 ant-col-lg-6 ant-col-xl-4 ant-col-xxl-8"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;flex:1 1 auto"
>
<div
class="ant-list-item"
@ -606,8 +606,8 @@ exports[`renders ./components/list/demo/resposive.md correctly 1`] = `
</div>
</div>
<div
class="ant-col ant-col-xs-24 ant-col-sm-12 ant-col-md-6 ant-col-lg-6 ant-col-xl-4 ant-col-xxl-8"
style="padding-left:8px;padding-right:8px"
class="ant-col"
style="padding-left:8px;padding-right:8px;flex:1 1 auto"
>
<div
class="ant-list-item"

View File

@ -44,16 +44,16 @@ More about pagination, please check [`Pagination`](/components/pagination/).
### List grid props
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| column | column of grid, [optional number](https://github.com/ant-design/ant-design/blob/a7f17b4cdebbca07b3b9ce5698de61e772d46237/components/list/index.tsx#L16) | number | - | |
| gutter | spacing between grid | number | 0 | |
| xs | `<576px` column of grid | number | - | |
| sm | `≥576px` column of grid | number | - | |
| md | `≥768px` column of grid | number | - | |
| lg | `≥992px` column of grid | number | - | |
| xl | `≥1200px` column of grid | number | - | |
| xxl | `≥1600px` column of grid | number | - | |
| Property | Description | Type | Default | Version |
| -------- | ------------------------ | ------ | ------- | ------- |
| column | column of grid | number | - | |
| gutter | spacing between grid | number | 0 | |
| xs | `<576px` column of grid | number | - | |
| sm | `≥576px` column of grid | number | - | |
| md | `≥768px` column of grid | number | - | |
| lg | `≥992px` column of grid | number | - | |
| xl | `≥1200px` column of grid | number | - | |
| xxl | `≥1600px` column of grid | number | - | |
### List.Item

View File

@ -2,16 +2,16 @@ import * as React from 'react';
import classNames from 'classnames';
import omit from 'omit.js';
import Spin, { SpinProps } from '../spin';
import useBreakpoint from '../grid/hooks/useBreakpoint';
import { Breakpoint, responsiveArray } from '../_util/responsiveObserve';
import { RenderEmptyHandler, ConfigContext } from '../config-provider';
import Pagination, { PaginationConfig } from '../pagination';
import { Row } from '../grid';
import Item from './Item';
export { ListItemProps, ListItemMetaProps } from './Item';
export type ColumnCount = 1 | 2 | 3 | 4 | 6 | 8 | 12 | 24;
export type ColumnCount = number;
export type ColumnType = 'gutter' | 'column' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl';
@ -218,20 +218,40 @@ function List<T>({ pagination, ...props }: ListProps<T>) {
}
}
let childrenContent;
childrenContent = isLoading && <div style={{ minHeight: 53 }} />;
const screens = useBreakpoint();
const currentBreakpoint = React.useMemo(() => {
for (let i = 0; i < responsiveArray.length; i += 1) {
const breakpoint: Breakpoint = responsiveArray[i];
if (screens[breakpoint]) {
return breakpoint;
}
}
return undefined;
}, [screens]);
const colStyle = React.useMemo(() => {
if (!grid) {
return undefined;
}
const columnCount =
currentBreakpoint && grid[currentBreakpoint] ? grid[currentBreakpoint] : grid.column;
if (columnCount) {
return {
width: `${100 / columnCount}%`,
maxWidth: `${100 / columnCount}%`,
};
}
}, [grid?.column, currentBreakpoint]);
let childrenContent = isLoading && <div style={{ minHeight: 53 }} />;
if (splitDataSource.length > 0) {
const items = splitDataSource.map((item: any, index: number) => renderItem(item, index));
const childrenList: Array<React.ReactNode> = [];
React.Children.forEach(items, (child: any, index) => {
childrenList.push(
React.cloneElement(child, {
key: keys[index],
}),
);
});
const childrenList = React.Children.map(items, (child: any, index) =>
React.cloneElement(child, {
key: keys[index],
colStyle,
}),
);
childrenContent = grid ? (
<Row gutter={grid.gutter}>{childrenList}</Row>
) : (

View File

@ -44,16 +44,16 @@ cols: 1
### List grid props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| column | 列数[可选值](https://github.com/ant-design/ant-design/blob/a7f17b4cdebbca07b3b9ce5698de61e772d46237/components/list/index.tsx#L16) | number | - | |
| gutter | 栅格间隔 | number | 0 | |
| xs | `<576px` 展示的列数 | number | - | |
| sm | `≥576px` 展示的列数 | number | - | |
| md | `≥768px` 展示的列数 | number | - | |
| lg | `≥992px` 展示的列数 | number | - | |
| xl | `≥1200px` 展示的列数 | number | - | |
| xxl | `≥1600px` 展示的列数 | number | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------ | -------------------- | ------ | ------ | ---- |
| column | 列数 | number | - | |
| gutter | 栅格间隔 | number | 0 | |
| xs | `<576px` 展示的列数 | number | - | |
| sm | `≥576px` 展示的列数 | number | - | |
| md | `≥768px` 展示的列数 | number | - | |
| lg | `≥992px` 展示的列数 | number | - | |
| xl | `≥1200px` 展示的列数 | number | - | |
| xxl | `≥1600px` 展示的列数 | number | - | |
### List.Item