feat: Typography ellipsis.tooltip could be a object (#36099)

* feat: add tooltipProps

* feat: doc

* feat: props

* feat: props

* feat: props

* feat: docs

* feat: review

* feat: add tooltipProps

* feat: doc

* feat: props

* feat: props

* feat: props

* feat: docs

* feat: review
This commit is contained in:
叶枫 2022-07-25 13:09:39 +08:00 committed by GitHub
parent 3920a724cc
commit 00c891ac05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 75 additions and 33 deletions

View File

@ -189,8 +189,7 @@ const InternalButton: React.ForwardRefRenderFunction<unknown, ButtonProps> = (pr
}; };
// =============== Update Loading =============== // =============== Update Loading ===============
const loadingOrDelay: Loading = const loadingOrDelay: Loading = typeof loading === 'boolean' ? loading : loading?.delay || true;
typeof loading === 'boolean' ? loading : (loading?.delay || true);
React.useEffect(() => { React.useEffect(() => {
let delayTimer: number | null = null; let delayTimer: number | null = null;

View File

@ -40,8 +40,8 @@ const App: React.FC = () => {
}; };
const remove = (targetKey: string) => { const remove = (targetKey: string) => {
const targetIndex = panes.findIndex((pane) => pane.key === targetKey); const targetIndex = panes.findIndex(pane => pane.key === targetKey);
const newPanes = panes.filter((pane) => pane.key !== targetKey); const newPanes = panes.filter(pane => pane.key !== targetKey);
if (newPanes.length && targetKey === activeKey) { if (newPanes.length && targetKey === activeKey) {
const { key } = newPanes[targetIndex === newPanes.length ? targetIndex - 1 : targetIndex]; const { key } = newPanes[targetIndex === newPanes.length ? targetIndex - 1 : targetIndex];
setActiveKey(key); setActiveKey(key);

View File

@ -57,7 +57,7 @@ export type RenderFunction = () => React.ReactNode;
export interface TooltipPropsWithOverlay extends AbstractTooltipProps { export interface TooltipPropsWithOverlay extends AbstractTooltipProps {
title?: React.ReactNode | RenderFunction; title?: React.ReactNode | RenderFunction;
overlay: React.ReactNode | RenderFunction; overlay?: React.ReactNode | RenderFunction;
} }
export interface TooltipPropsWithTitle extends AbstractTooltipProps { export interface TooltipPropsWithTitle extends AbstractTooltipProps {

View File

@ -1,25 +1,26 @@
import * as React from 'react'; import * as React from 'react';
import Tooltip from '../../tooltip'; import Tooltip from '../../tooltip';
import type { TooltipProps } from '../../tooltip';
export interface EllipsisTooltipProps { export interface EllipsisTooltipProps {
title?: React.ReactNode; tooltipProps?: TooltipProps;
enabledEllipsis: boolean; enabledEllipsis: boolean;
isEllipsis?: boolean; isEllipsis?: boolean;
children: React.ReactElement; children: React.ReactElement;
} }
const EllipsisTooltip = ({ const EllipsisTooltip = ({
title,
enabledEllipsis, enabledEllipsis,
isEllipsis, isEllipsis,
children, children,
tooltipProps,
}: EllipsisTooltipProps) => { }: EllipsisTooltipProps) => {
if (!title || !enabledEllipsis) { if (!tooltipProps?.title || !enabledEllipsis) {
return children; return children;
} }
return ( return (
<Tooltip title={title} visible={isEllipsis ? undefined : false}> <Tooltip visible={isEllipsis ? undefined : false} {...tooltipProps}>
{children} {children}
</Tooltip> </Tooltip>
); );

View File

@ -13,9 +13,10 @@ import { composeRef } from 'rc-util/lib/ref';
import * as React from 'react'; import * as React from 'react';
import { ConfigContext } from '../../config-provider'; import { ConfigContext } from '../../config-provider';
import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver'; import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver';
import Tooltip from '../../tooltip';
import { isStyleSupport } from '../../_util/styleChecker';
import TransButton from '../../_util/transButton'; import TransButton from '../../_util/transButton';
import { isStyleSupport } from '../../_util/styleChecker';
import type { TooltipProps } from '../../tooltip';
import Tooltip from '../../tooltip';
import Editable from '../Editable'; import Editable from '../Editable';
import useMergedConfig from '../hooks/useMergedConfig'; import useMergedConfig from '../hooks/useMergedConfig';
import useUpdatedEffect from '../hooks/useUpdatedEffect'; import useUpdatedEffect from '../hooks/useUpdatedEffect';
@ -55,7 +56,7 @@ export interface EllipsisConfig {
symbol?: React.ReactNode; symbol?: React.ReactNode;
onExpand?: React.MouseEventHandler<HTMLElement>; onExpand?: React.MouseEventHandler<HTMLElement>;
onEllipsis?: (ellipsis: boolean) => void; onEllipsis?: (ellipsis: boolean) => void;
tooltip?: React.ReactNode; tooltip?: React.ReactNode | TooltipProps;
} }
export interface BlockProps extends TypographyProps { export interface BlockProps extends TypographyProps {
@ -309,7 +310,16 @@ const Base = React.forwardRef((props: InternalBlockProps, ref: any) => {
}, [enableEllipsis, cssEllipsis, children, cssLineClamp]); }, [enableEllipsis, cssEllipsis, children, cssLineClamp]);
// ========================== Tooltip =========================== // ========================== Tooltip ===========================
const tooltipTitle = ellipsisConfig.tooltip === true ? children : ellipsisConfig.tooltip; let tooltipProps: TooltipProps = {};
if (ellipsisConfig.tooltip === true) {
tooltipProps = { title: children };
} else if (React.isValidElement(ellipsisConfig.tooltip)) {
tooltipProps = { title: ellipsisConfig.tooltip };
} else if (typeof ellipsisConfig.tooltip === 'object') {
tooltipProps = { title: children, ...ellipsisConfig.tooltip };
} else {
tooltipProps = { title: ellipsisConfig.tooltip };
}
const topAriaLabel = React.useMemo(() => { const topAriaLabel = React.useMemo(() => {
const isValid = (val: any) => ['string', 'number'].includes(typeof val); const isValid = (val: any) => ['string', 'number'].includes(typeof val);
@ -325,12 +335,12 @@ const Base = React.forwardRef((props: InternalBlockProps, ref: any) => {
return title; return title;
} }
if (isValid(tooltipTitle)) { if (isValid(tooltipProps.title)) {
return tooltipTitle; return tooltipProps.title;
} }
return undefined; return undefined;
}, [enableEllipsis, cssEllipsis, title, tooltipTitle, isMergedEllipsis]); }, [enableEllipsis, cssEllipsis, title, tooltipProps.title, isMergedEllipsis]);
// =========================== Render =========================== // =========================== Render ===========================
// >>>>>>>>>>> Editing input // >>>>>>>>>>> Editing input
@ -452,7 +462,7 @@ const Base = React.forwardRef((props: InternalBlockProps, ref: any) => {
<ResizeObserver onResize={onResize} disabled={!mergedEnableEllipsis || cssEllipsis}> <ResizeObserver onResize={onResize} disabled={!mergedEnableEllipsis || cssEllipsis}>
{resizeRef => ( {resizeRef => (
<EllipsisTooltip <EllipsisTooltip
title={tooltipTitle} tooltipProps={tooltipProps}
enabledEllipsis={mergedEnableEllipsis} enabledEllipsis={mergedEnableEllipsis}
isEllipsis={isMergedEllipsis} isEllipsis={isMergedEllipsis}
> >

View File

@ -292,6 +292,38 @@ describe('Typography.Ellipsis', () => {
expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull(); expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull();
}); });
}); });
it('tooltip props', async () => {
const { container, baseElement } = await getWrapper({
title: 'This is tooltip',
className: 'tooltip-class-name',
});
fireEvent.mouseEnter(container.firstChild);
await waitFor(() => {
expect(container.querySelector('.tooltip-class-name')).toBeTruthy();
expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull();
});
});
it('tooltip title true', async () => {
const { container, baseElement } = await getWrapper({
title: true,
className: 'tooltip-class-name',
});
fireEvent.mouseEnter(container.firstChild);
await waitFor(() => {
expect(container.querySelector('.tooltip-class-name')).toBeTruthy();
expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull();
});
});
it('tooltip element', async () => {
const { container, baseElement } = await getWrapper(
<div className="tooltip-class-name">title</div>,
);
fireEvent.mouseEnter(container.firstChild);
await waitFor(() => {
expect(container.querySelector('.tooltip-class-name')).toBeTruthy();
expect(baseElement.querySelector('.ant-tooltip-open')).not.toBeNull();
});
});
}); });
it('js ellipsis should show aria-label', () => { it('js ellipsis should show aria-label', () => {

View File

@ -122,7 +122,7 @@ Basic text writing, including headings, body text, lists, and more.
expandable: boolean, expandable: boolean,
suffix: string, suffix: string,
symbol: ReactNode, symbol: ReactNode,
tooltip: boolean | ReactNode, tooltip: boolean | ReactNode | TooltipProps,
onExpand: function(event), onExpand: function(event),
onEllipsis: function(ellipsis), onEllipsis: function(ellipsis),
} }
@ -133,7 +133,7 @@ Basic text writing, including headings, body text, lists, and more.
| rows | Max rows of content | number | - | | | rows | Max rows of content | number | - | |
| suffix | Suffix of ellipsis content | string | - | | | suffix | Suffix of ellipsis content | string | - | |
| symbol | Custom description of ellipsis | ReactNode | `Expand` | | | symbol | Custom description of ellipsis | ReactNode | `Expand` | |
| tooltip | Show tooltip when ellipsis | boolean \| ReactNode | - | 4.11.0 | | tooltip | Show tooltip when ellipsis | boolean \| ReactNode \| [TooltipProps](/components/tooltip/#API) | - | 4.11.0 |
| onEllipsis | Called when enter or leave ellipsis state | function(ellipsis) | - | 4.2.0 | | onEllipsis | Called when enter or leave ellipsis state | function(ellipsis) | - | 4.2.0 |
| onExpand | Called when expand content | function(event) | - | | | onExpand | Called when expand content | function(event) | - | |

View File

@ -123,20 +123,20 @@ cover: https://gw.alipayobjects.com/zos/alicdn/GOM1KQ24O/Typography.svg
expandable: boolean, expandable: boolean,
suffix: string, suffix: string,
symbol: ReactNode, symbol: ReactNode,
tooltip: boolean | ReactNode, tooltip: boolean | ReactNode | TooltipProps,
onExpand: function(event), onExpand: function(event),
onEllipsis: function(ellipsis), onEllipsis: function(ellipsis),
} }
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| ---------- | -------------------- | -------------------- | ------ | ------ | | --- | --- | --- | --- | --- |
| expandable | 是否可展开 | boolean | - | | | expandable | 是否可展开 | boolean | - | |
| rows | 最多显示的行数 | number | - | | | rows | 最多显示的行数 | number | - | |
| suffix | 自定义省略内容后缀 | string | - | | | suffix | 自定义省略内容后缀 | string | - | |
| symbol | 自定义展开描述文案 | ReactNode | `展开` | | | symbol | 自定义展开描述文案 | ReactNode | `展开` | |
| tooltip | 省略时,展示提示信息 | boolean \| ReactNode | - | 4.11.0 | | tooltip | 省略时,展示提示信息 | boolean \| ReactNode \| [TooltipProps](/components/tooltip/#API) | - | 4.11.0 |
| onEllipsis | 触发省略时的回调 | function(ellipsis) | - | 4.2.0 | | onEllipsis | 触发省略时的回调 | function(ellipsis) | - | 4.2.0 |
| onExpand | 点击展开时的回调 | function(event) | - | | | onExpand | 点击展开时的回调 | function(event) | - | |
## FAQ ## FAQ

View File

@ -110,8 +110,8 @@ export function previewImage(file: File | Blob): Promise<string> {
resolve(dataURL); resolve(dataURL);
}; };
img.crossOrigin = "anonymous"; img.crossOrigin = 'anonymous';
if (file.type.startsWith("image/svg+xml")) { if (file.type.startsWith('image/svg+xml')) {
const reader = new FileReader(); const reader = new FileReader();
reader.addEventListener('load', () => { reader.addEventListener('load', () => {
if (reader.result) img.src = reader.result as string; if (reader.result) img.src = reader.result as string;