Skip to content

Commit

Permalink
fix: List.Item ref (#35321)
Browse files Browse the repository at this point in the history
* fix: list item ref

* add test

* improve
  • Loading branch information
hengkx committed May 7, 2022
1 parent 7873bf7 commit 5d2475a
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 30 deletions.
67 changes: 37 additions & 30 deletions components/list/Item.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,49 @@
import * as React from 'react';
import React, { Children, forwardRef, useContext } from 'react';
import type {
CSSProperties,
FC,
ForwardRefExoticComponent,
ForwardRefRenderFunction,
HTMLAttributes,
ReactElement,
ReactNode,
} from 'react';
import classNames from 'classnames';
import { ListGridType, ListContext } from './index';
import { Col } from '../grid';
import { ConfigContext } from '../config-provider';
import { cloneElement } from '../_util/reactNode';

export interface ListItemProps extends React.HTMLAttributes<HTMLDivElement> {
export interface ListItemProps extends HTMLAttributes<HTMLDivElement> {
className?: string;
children?: React.ReactNode;
children?: ReactNode;
prefixCls?: string;
style?: React.CSSProperties;
extra?: React.ReactNode;
actions?: React.ReactNode[];
style?: CSSProperties;
extra?: ReactNode;
actions?: ReactNode[];
grid?: ListGridType;
colStyle?: React.CSSProperties;
colStyle?: CSSProperties;
}

export interface ListItemMetaProps {
avatar?: React.ReactNode;
avatar?: ReactNode;
className?: string;
children?: React.ReactNode;
description?: React.ReactNode;
children?: ReactNode;
description?: ReactNode;
prefixCls?: string;
style?: React.CSSProperties;
title?: React.ReactNode;
style?: CSSProperties;
title?: ReactNode;
}

export const Meta: React.FC<ListItemMetaProps> = ({
export const Meta: FC<ListItemMetaProps> = ({
prefixCls: customizePrefixCls,
className,
avatar,
title,
description,
...others
}) => {
const { getPrefixCls } = React.useContext(ConfigContext);
const { getPrefixCls } = useContext(ConfigContext);

const prefixCls = getPrefixCls('list', customizePrefixCls);
const classString = classNames(`${prefixCls}-item-meta`, className);
Expand All @@ -54,30 +63,26 @@ export const Meta: React.FC<ListItemMetaProps> = ({
);
};

export interface ListItemTypeProps extends React.FC<ListItemProps> {
export interface ListItemTypeProps
extends ForwardRefExoticComponent<ListItemMetaProps & React.RefAttributes<HTMLElement>> {
Meta: typeof Meta;
}

const Item: ListItemTypeProps = ({
prefixCls: customizePrefixCls,
children,
actions,
extra,
className,
colStyle,
...others
}) => {
const { grid, itemLayout } = React.useContext(ListContext);
const { getPrefixCls } = React.useContext(ConfigContext);
const InternalItem: ForwardRefRenderFunction<HTMLDivElement, ListItemProps> = (
{ prefixCls: customizePrefixCls, children, actions, extra, className, colStyle, ...others },
ref,
) => {
const { grid, itemLayout } = useContext(ListContext);
const { getPrefixCls } = useContext(ConfigContext);

const isItemContainsTextNodeAndNotSingular = () => {
let result;
React.Children.forEach(children, (element: React.ReactElement<any>) => {
Children.forEach(children, (element: ReactElement<any>) => {
if (typeof element === 'string') {
result = true;
}
});
return result && React.Children.count(children) > 1;
return result && Children.count(children) > 1;
};

const isFlexMode = () => {
Expand All @@ -90,7 +95,7 @@ const Item: ListItemTypeProps = ({
const prefixCls = getPrefixCls('list', customizePrefixCls);
const actionsContent = actions && actions.length > 0 && (
<ul className={`${prefixCls}-item-action`} key="actions">
{actions.map((action: React.ReactNode, i: number) => (
{actions.map((action: ReactNode, i: number) => (
// eslint-disable-next-line react/no-array-index-key
<li key={`${prefixCls}-item-action-${i}`}>
{action}
Expand All @@ -103,6 +108,7 @@ const Item: ListItemTypeProps = ({
const itemChildren = (
<Element
{...(others as any)} // `li` element `onCopy` prop args is not same as `div`
{...(!grid ? { ref } : {})}
className={classNames(
`${prefixCls}-item`,
{
Expand All @@ -126,13 +132,14 @@ const Item: ListItemTypeProps = ({
);

return grid ? (
<Col flex={1} style={colStyle}>
<Col ref={ref} flex={1} style={colStyle}>
{itemChildren}
</Col>
) : (
itemChildren
);
};
const Item = forwardRef(InternalItem) as ListItemTypeProps;

Item.Meta = Meta;

Expand Down
19 changes: 19 additions & 0 deletions components/list/__tests__/Item.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { mount } from 'enzyme';
import List from '..';
import ConfigProvider from '../../config-provider';
import { render } from '../../../tests/utils';

describe('List Item Layout', () => {
const data = [
Expand Down Expand Up @@ -178,4 +179,22 @@ describe('List Item Layout', () => {
);
expect(wrapper.render()).toMatchSnapshot();
});

it('should ref', () => {
const ref = React.createRef();

render(<List.Item ref={ref}>Item</List.Item>);
expect(ref.current).toHaveClass('ant-list-item');
});

it('should grid ref', () => {
const ref = React.createRef();

render(
<List grid>
<List.Item ref={ref}>Item</List.Item>,
</List>,
);
expect(ref.current).toHaveClass('ant-col');
});
});

0 comments on commit 5d2475a

Please sign in to comment.