mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 03:59:01 +08:00
refactor: reimplement Typography code (#50561)
Co-authored-by: lijianan <574980606@qq.com>
This commit is contained in:
parent
1cd79e3b0a
commit
9f274a0884
@ -19,32 +19,26 @@ export interface CopyBtnProps extends Omit<CopyConfig, 'onCopy'> {
|
|||||||
loading: boolean;
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CopyBtn: React.FC<CopyBtnProps> = (props) => {
|
const CopyBtn: React.FC<CopyBtnProps> = ({
|
||||||
const {
|
prefixCls,
|
||||||
prefixCls,
|
copied,
|
||||||
copied,
|
locale,
|
||||||
locale,
|
iconOnly,
|
||||||
iconOnly,
|
tooltips,
|
||||||
tooltips,
|
icon,
|
||||||
icon,
|
tabIndex,
|
||||||
loading: btnLoading,
|
onCopy,
|
||||||
tabIndex,
|
loading: btnLoading,
|
||||||
onCopy,
|
}) => {
|
||||||
} = props;
|
|
||||||
|
|
||||||
const tooltipNodes = toList(tooltips);
|
const tooltipNodes = toList(tooltips);
|
||||||
const iconNodes = toList(icon);
|
const iconNodes = toList(icon);
|
||||||
|
|
||||||
const { copied: copiedText, copy: copyText } = locale ?? {};
|
const { copied: copiedText, copy: copyText } = locale ?? {};
|
||||||
|
|
||||||
const copyTitle = copied
|
|
||||||
? getNode(tooltipNodes[1], copiedText)
|
|
||||||
: getNode(tooltipNodes[0], copyText);
|
|
||||||
const systemStr = copied ? copiedText : copyText;
|
const systemStr = copied ? copiedText : copyText;
|
||||||
|
const copyTitle = getNode(tooltipNodes[copied ? 1 : 0], systemStr);
|
||||||
const ariaLabel = typeof copyTitle === 'string' ? copyTitle : systemStr;
|
const ariaLabel = typeof copyTitle === 'string' ? copyTitle : systemStr;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip key="copy" title={copyTitle}>
|
<Tooltip title={copyTitle}>
|
||||||
<TransButton
|
<TransButton
|
||||||
className={classNames(`${prefixCls}-copy`, {
|
className={classNames(`${prefixCls}-copy`, {
|
||||||
[`${prefixCls}-copy-success`]: copied,
|
[`${prefixCls}-copy-success`]: copied,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import toArray from 'rc-util/lib/Children/toArray';
|
import toArray from 'rc-util/lib/Children/toArray';
|
||||||
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
|
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
|
||||||
|
import { isValidText } from './util';
|
||||||
|
|
||||||
interface MeasureTextProps {
|
interface MeasureTextProps {
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
@ -44,24 +45,8 @@ const MeasureText = React.forwardRef<MeasureTextRef, MeasureTextProps>(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
function cuttable(node: React.ReactElement) {
|
const getNodesLen = (nodeList: React.ReactElement[]) =>
|
||||||
const type = typeof node;
|
nodeList.reduce((totalLen, node) => totalLen + (isValidText(node) ? String(node).length : 1), 0);
|
||||||
return type === 'string' || type === 'number';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNodesLen(nodeList: React.ReactElement[]) {
|
|
||||||
let totalLen = 0;
|
|
||||||
|
|
||||||
nodeList.forEach((node) => {
|
|
||||||
if (cuttable(node)) {
|
|
||||||
totalLen += String(node).length;
|
|
||||||
} else {
|
|
||||||
totalLen += 1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return totalLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sliceNodes(nodeList: React.ReactElement[], len: number) {
|
function sliceNodes(nodeList: React.ReactElement[], len: number) {
|
||||||
let currLen = 0;
|
let currLen = 0;
|
||||||
@ -74,7 +59,7 @@ function sliceNodes(nodeList: React.ReactElement[], len: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const node = nodeList[i];
|
const node = nodeList[i];
|
||||||
const canCut = cuttable(node);
|
const canCut = isValidText(node);
|
||||||
const nodeLen = canCut ? String(node).length : 1;
|
const nodeLen = canCut ? String(node).length : 1;
|
||||||
const nextLen = currLen + nodeLen;
|
const nextLen = currLen + nodeLen;
|
||||||
|
|
||||||
@ -97,7 +82,6 @@ export interface EllipsisProps {
|
|||||||
enableMeasure?: boolean;
|
enableMeasure?: boolean;
|
||||||
text?: React.ReactNode;
|
text?: React.ReactNode;
|
||||||
width: number;
|
width: number;
|
||||||
// fontSize: number;
|
|
||||||
rows: number;
|
rows: number;
|
||||||
children: (
|
children: (
|
||||||
cutChildren: React.ReactNode[],
|
cutChildren: React.ReactNode[],
|
||||||
@ -142,9 +126,7 @@ export default function EllipsisMeasure(props: EllipsisProps) {
|
|||||||
|
|
||||||
// ========================= NeedEllipsis =========================
|
// ========================= NeedEllipsis =========================
|
||||||
const measureWhiteSpaceRef = React.useRef<HTMLElement>(null);
|
const measureWhiteSpaceRef = React.useRef<HTMLElement>(null);
|
||||||
|
|
||||||
const needEllipsisRef = React.useRef<MeasureTextRef>(null);
|
const needEllipsisRef = React.useRef<MeasureTextRef>(null);
|
||||||
|
|
||||||
// Measure for `rows-1` height, to avoid operation exceed the line height
|
// Measure for `rows-1` height, to avoid operation exceed the line height
|
||||||
const descRowsEllipsisRef = React.useRef<MeasureTextRef>(null);
|
const descRowsEllipsisRef = React.useRef<MeasureTextRef>(null);
|
||||||
const symbolRowEllipsisRef = React.useRef<MeasureTextRef>(null);
|
const symbolRowEllipsisRef = React.useRef<MeasureTextRef>(null);
|
||||||
@ -187,9 +169,11 @@ export default function EllipsisMeasure(props: EllipsisProps) {
|
|||||||
// Get the height of `rows - 1` + symbol height
|
// Get the height of `rows - 1` + symbol height
|
||||||
const descRowsEllipsisHeight = rows === 1 ? 0 : descRowsEllipsisRef.current?.getHeight() || 0;
|
const descRowsEllipsisHeight = rows === 1 ? 0 : descRowsEllipsisRef.current?.getHeight() || 0;
|
||||||
const symbolRowEllipsisHeight = symbolRowEllipsisRef.current?.getHeight() || 0;
|
const symbolRowEllipsisHeight = symbolRowEllipsisRef.current?.getHeight() || 0;
|
||||||
const rowsWithEllipsisHeight = descRowsEllipsisHeight + symbolRowEllipsisHeight;
|
const maxRowsHeight = Math.max(
|
||||||
|
baseRowsEllipsisHeight,
|
||||||
const maxRowsHeight = Math.max(baseRowsEllipsisHeight, rowsWithEllipsisHeight);
|
// height of rows with ellipsis
|
||||||
|
descRowsEllipsisHeight + symbolRowEllipsisHeight,
|
||||||
|
);
|
||||||
|
|
||||||
setEllipsisHeight(maxRowsHeight + 1);
|
setEllipsisHeight(maxRowsHeight + 1);
|
||||||
|
|
||||||
@ -209,16 +193,10 @@ export default function EllipsisMeasure(props: EllipsisProps) {
|
|||||||
|
|
||||||
const isOverflow = midHeight > ellipsisHeight;
|
const isOverflow = midHeight > ellipsisHeight;
|
||||||
let targetMidIndex = cutMidIndex;
|
let targetMidIndex = cutMidIndex;
|
||||||
|
|
||||||
if (maxIndex - minIndex === 1) {
|
if (maxIndex - minIndex === 1) {
|
||||||
targetMidIndex = isOverflow ? minIndex : maxIndex;
|
targetMidIndex = isOverflow ? minIndex : maxIndex;
|
||||||
}
|
}
|
||||||
|
setEllipsisCutIndex(isOverflow ? [minIndex, targetMidIndex] : [targetMidIndex, maxIndex]);
|
||||||
if (isOverflow) {
|
|
||||||
setEllipsisCutIndex([minIndex, targetMidIndex]);
|
|
||||||
} else {
|
|
||||||
setEllipsisCutIndex([targetMidIndex, maxIndex]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, [ellipsisCutIndex, cutMidIndex]);
|
}, [ellipsisCutIndex, cutMidIndex]);
|
||||||
|
|
||||||
@ -235,26 +213,21 @@ export default function EllipsisMeasure(props: EllipsisProps) {
|
|||||||
ellipsisCutIndex[0] !== ellipsisCutIndex[1]
|
ellipsisCutIndex[0] !== ellipsisCutIndex[1]
|
||||||
) {
|
) {
|
||||||
const content = children(nodeList, false);
|
const content = children(nodeList, false);
|
||||||
|
// Limit the max line count to avoid scrollbar blink unless no need ellipsis
|
||||||
// Limit the max line count to avoid scrollbar blink
|
|
||||||
// https://github.com/ant-design/ant-design/issues/42958
|
// https://github.com/ant-design/ant-design/issues/42958
|
||||||
if (
|
if ([STATUS_MEASURE_NO_NEED_ELLIPSIS, STATUS_MEASURE_NONE].includes(needEllipsis)) {
|
||||||
needEllipsis !== STATUS_MEASURE_NO_NEED_ELLIPSIS &&
|
return content;
|
||||||
needEllipsis !== STATUS_MEASURE_NONE
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
...lineClipStyle,
|
|
||||||
WebkitLineClamp: rows,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{content}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
return (
|
||||||
return content;
|
<span
|
||||||
|
style={{
|
||||||
|
...lineClipStyle,
|
||||||
|
WebkitLineClamp: rows,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return children(expanded ? nodeList : sliceNodes(nodeList, ellipsisCutIndex[0]), canEllipsis);
|
return children(expanded ? nodeList : sliceNodes(nodeList, ellipsisCutIndex[0]), canEllipsis);
|
||||||
|
@ -4,7 +4,7 @@ import classNames from 'classnames';
|
|||||||
import ResizeObserver from 'rc-resize-observer';
|
import ResizeObserver from 'rc-resize-observer';
|
||||||
import type { AutoSizeType } from 'rc-textarea';
|
import type { AutoSizeType } from 'rc-textarea';
|
||||||
import toArray from 'rc-util/lib/Children/toArray';
|
import toArray from 'rc-util/lib/Children/toArray';
|
||||||
import useIsomorphicLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
|
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
|
||||||
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
||||||
import omit from 'rc-util/lib/omit';
|
import omit from 'rc-util/lib/omit';
|
||||||
import { composeRef } from 'rc-util/lib/ref';
|
import { composeRef } from 'rc-util/lib/ref';
|
||||||
@ -19,13 +19,13 @@ import Editable from '../Editable';
|
|||||||
import useCopyClick from '../hooks/useCopyClick';
|
import useCopyClick from '../hooks/useCopyClick';
|
||||||
import useMergedConfig from '../hooks/useMergedConfig';
|
import useMergedConfig from '../hooks/useMergedConfig';
|
||||||
import usePrevious from '../hooks/usePrevious';
|
import usePrevious from '../hooks/usePrevious';
|
||||||
import useUpdatedEffect from '../hooks/useUpdatedEffect';
|
import useTooltipProps from '../hooks/useTooltipProps';
|
||||||
import type { TypographyProps } from '../Typography';
|
import type { TypographyProps } from '../Typography';
|
||||||
import Typography from '../Typography';
|
import Typography from '../Typography';
|
||||||
import CopyBtn from './CopyBtn';
|
import CopyBtn from './CopyBtn';
|
||||||
import Ellipsis from './Ellipsis';
|
import Ellipsis from './Ellipsis';
|
||||||
import EllipsisTooltip from './EllipsisTooltip';
|
import EllipsisTooltip from './EllipsisTooltip';
|
||||||
import { isEleEllipsis } from './util';
|
import { isEleEllipsis, isValidText } from './util';
|
||||||
|
|
||||||
export type BaseType = 'secondary' | 'success' | 'warning' | 'danger';
|
export type BaseType = 'secondary' | 'success' | 'warning' | 'danger';
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
|||||||
|
|
||||||
// Focus edit icon when back
|
// Focus edit icon when back
|
||||||
const prevEditing = usePrevious(editing);
|
const prevEditing = usePrevious(editing);
|
||||||
useUpdatedEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (!editing && prevEditing) {
|
if (!editing && prevEditing) {
|
||||||
editIconRef.current?.focus();
|
editIconRef.current?.focus();
|
||||||
}
|
}
|
||||||
@ -223,7 +223,7 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
|||||||
[mergedEnableEllipsis, ellipsisConfig, enableEdit, enableCopy],
|
[mergedEnableEllipsis, ellipsisConfig, enableEdit, enableCopy],
|
||||||
);
|
);
|
||||||
|
|
||||||
useIsomorphicLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (enableEllipsis && !needMeasureEllipsis) {
|
if (enableEllipsis && !needMeasureEllipsis) {
|
||||||
setIsLineClampSupport(isStyleSupport('webkitLineClamp'));
|
setIsLineClampSupport(isStyleSupport('webkitLineClamp'));
|
||||||
setIsTextOverflowSupport(isStyleSupport('textOverflow'));
|
setIsTextOverflowSupport(isStyleSupport('textOverflow'));
|
||||||
@ -246,7 +246,7 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
|||||||
|
|
||||||
// We use effect to change from css ellipsis to js ellipsis.
|
// We use effect to change from css ellipsis to js ellipsis.
|
||||||
// To make SSR still can see the ellipsis.
|
// To make SSR still can see the ellipsis.
|
||||||
useIsomorphicLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
setCssEllipsis(canUseCssEllipsis && mergedEnableEllipsis);
|
setCssEllipsis(canUseCssEllipsis && mergedEnableEllipsis);
|
||||||
}, [canUseCssEllipsis, mergedEnableEllipsis]);
|
}, [canUseCssEllipsis, mergedEnableEllipsis]);
|
||||||
|
|
||||||
@ -314,40 +314,13 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
|||||||
}, [cssEllipsis, mergedEnableEllipsis]);
|
}, [cssEllipsis, mergedEnableEllipsis]);
|
||||||
|
|
||||||
// ========================== Tooltip ===========================
|
// ========================== Tooltip ===========================
|
||||||
let tooltipProps: TooltipProps = {};
|
const tooltipProps = useTooltipProps(ellipsisConfig.tooltip, editConfig.text, children);
|
||||||
if (ellipsisConfig.tooltip === true) {
|
|
||||||
tooltipProps = { title: editConfig.text ?? children };
|
|
||||||
} else if (React.isValidElement(ellipsisConfig.tooltip)) {
|
|
||||||
tooltipProps = { title: ellipsisConfig.tooltip };
|
|
||||||
} else if (typeof ellipsisConfig.tooltip === 'object') {
|
|
||||||
tooltipProps = { title: editConfig.text ?? children, ...ellipsisConfig.tooltip };
|
|
||||||
} else {
|
|
||||||
tooltipProps = { title: ellipsisConfig.tooltip };
|
|
||||||
}
|
|
||||||
const topAriaLabel = React.useMemo(() => {
|
|
||||||
const isValid = (val: any): val is string | number => ['string', 'number'].includes(typeof val);
|
|
||||||
|
|
||||||
|
const topAriaLabel = React.useMemo(() => {
|
||||||
if (!enableEllipsis || cssEllipsis) {
|
if (!enableEllipsis || cssEllipsis) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
return [editConfig.text, children, title, tooltipProps.title].find(isValidText);
|
||||||
if (isValid(editConfig.text)) {
|
|
||||||
return editConfig.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValid(children)) {
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValid(title)) {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValid(tooltipProps.title)) {
|
|
||||||
return tooltipProps.title;
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}, [enableEllipsis, cssEllipsis, title, tooltipProps.title, isMergedEllipsis]);
|
}, [enableEllipsis, cssEllipsis, title, tooltipProps.title, isMergedEllipsis]);
|
||||||
|
|
||||||
// =========================== Render ===========================
|
// =========================== Render ===========================
|
||||||
|
@ -35,16 +35,15 @@ export function isEleEllipsis(ele: HTMLElement): boolean {
|
|||||||
ele.removeChild(childDiv);
|
ele.removeChild(childDiv);
|
||||||
|
|
||||||
// Range checker
|
// Range checker
|
||||||
if (
|
return (
|
||||||
// Horizontal in range
|
// Horizontal out of range
|
||||||
rect.left <= childRect.left &&
|
rect.left > childRect.left ||
|
||||||
childRect.right <= rect.right &&
|
childRect.right > rect.right ||
|
||||||
// Vertical in range
|
// Vertical out of range
|
||||||
rect.top <= childRect.top &&
|
rect.top > childRect.top ||
|
||||||
childRect.bottom <= rect.bottom
|
childRect.bottom > rect.bottom
|
||||||
) {
|
);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isValidText = (val: any): val is string | number =>
|
||||||
|
['string', 'number'].includes(typeof val);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import EnterOutlined from '@ant-design/icons/EnterOutlined';
|
import EnterOutlined from '@ant-design/icons/EnterOutlined';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type { AutoSizeType } from 'rc-textarea';
|
import type { TextAreaProps } from 'rc-textarea';
|
||||||
import KeyCode from 'rc-util/lib/KeyCode';
|
import KeyCode from 'rc-util/lib/KeyCode';
|
||||||
|
|
||||||
import { cloneElement } from '../_util/reactNode';
|
import { cloneElement } from '../_util/reactNode';
|
||||||
@ -21,7 +21,7 @@ interface EditableProps {
|
|||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
direction?: DirectionType;
|
direction?: DirectionType;
|
||||||
maxLength?: number;
|
maxLength?: number;
|
||||||
autoSize?: boolean | AutoSizeType;
|
autoSize?: TextAreaProps['autoSize'];
|
||||||
enterIcon?: React.ReactNode;
|
enterIcon?: React.ReactNode;
|
||||||
component?: string;
|
component?: string;
|
||||||
}
|
}
|
||||||
@ -94,19 +94,20 @@ const Editable: React.FC<EditableProps> = (props) => {
|
|||||||
}) => {
|
}) => {
|
||||||
// Check if it's a real key
|
// Check if it's a real key
|
||||||
if (
|
if (
|
||||||
lastKeyCode.current === keyCode &&
|
lastKeyCode.current !== keyCode ||
|
||||||
!inComposition.current &&
|
inComposition.current ||
|
||||||
!ctrlKey &&
|
ctrlKey ||
|
||||||
!altKey &&
|
altKey ||
|
||||||
!metaKey &&
|
metaKey ||
|
||||||
!shiftKey
|
shiftKey
|
||||||
) {
|
) {
|
||||||
if (keyCode === KeyCode.ENTER) {
|
return;
|
||||||
confirmChange();
|
}
|
||||||
onEnd?.();
|
if (keyCode === KeyCode.ENTER) {
|
||||||
} else if (keyCode === KeyCode.ESC) {
|
confirmChange();
|
||||||
onCancel();
|
onEnd?.();
|
||||||
}
|
} else if (keyCode === KeyCode.ESC) {
|
||||||
|
onCancel();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -114,8 +115,6 @@ const Editable: React.FC<EditableProps> = (props) => {
|
|||||||
confirmChange();
|
confirmChange();
|
||||||
};
|
};
|
||||||
|
|
||||||
const textClassName = component ? `${prefixCls}-${component}` : '';
|
|
||||||
|
|
||||||
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
|
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
|
||||||
|
|
||||||
const textAreaClassName = classNames(
|
const textAreaClassName = classNames(
|
||||||
@ -123,9 +122,9 @@ const Editable: React.FC<EditableProps> = (props) => {
|
|||||||
`${prefixCls}-edit-content`,
|
`${prefixCls}-edit-content`,
|
||||||
{
|
{
|
||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
|
[`${prefixCls}-${component}`]: !!component,
|
||||||
},
|
},
|
||||||
className,
|
className,
|
||||||
textClassName,
|
|
||||||
hashId,
|
hashId,
|
||||||
cssVarCls,
|
cssVarCls,
|
||||||
);
|
);
|
||||||
|
@ -19,7 +19,6 @@ const Text: React.ForwardRefRenderFunction<HTMLSpanElement, TextProps> = (
|
|||||||
if (ellipsis && typeof ellipsis === 'object') {
|
if (ellipsis && typeof ellipsis === 'object') {
|
||||||
return omit(ellipsis as EllipsisConfig, ['expandable', 'rows']);
|
return omit(ellipsis as EllipsisConfig, ['expandable', 'rows']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ellipsis;
|
return ellipsis;
|
||||||
}, [ellipsis]);
|
}, [ellipsis]);
|
||||||
|
|
||||||
|
@ -17,8 +17,6 @@ export interface TitleProps
|
|||||||
|
|
||||||
const Title = React.forwardRef<HTMLElement, TitleProps>((props, ref) => {
|
const Title = React.forwardRef<HTMLElement, TitleProps>((props, ref) => {
|
||||||
const { level = 1, ...restProps } = props;
|
const { level = 1, ...restProps } = props;
|
||||||
let component: keyof JSX.IntrinsicElements;
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
const warning = devUseWarning('Typography.Title');
|
const warning = devUseWarning('Typography.Title');
|
||||||
|
|
||||||
@ -28,13 +26,9 @@ const Title = React.forwardRef<HTMLElement, TitleProps>((props, ref) => {
|
|||||||
'Title only accept `1 | 2 | 3 | 4 | 5` as `level` value. And `5` need 4.6.0+ version.',
|
'Title only accept `1 | 2 | 3 | 4 | 5` as `level` value. And `5` need 4.6.0+ version.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const component: keyof JSX.IntrinsicElements = TITLE_ELE_LIST.includes(level)
|
||||||
if (TITLE_ELE_LIST.includes(level)) {
|
? `h${level}`
|
||||||
component = `h${level}`;
|
: `h1`;
|
||||||
} else {
|
|
||||||
component = 'h1';
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Base ref={ref} {...restProps} component={component} />;
|
return <Base ref={ref} {...restProps} component={component} />;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { composeRef } from 'rc-util/lib/ref';
|
import { composeRef } from 'rc-util/lib/ref';
|
||||||
|
|
||||||
import { devUseWarning } from '../_util/warning';
|
import { devUseWarning } from '../_util/warning';
|
||||||
import type { ConfigConsumerProps, DirectionType } from '../config-provider';
|
import type { ConfigConsumerProps, DirectionType } from '../config-provider';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
@ -42,6 +41,7 @@ const Typography = React.forwardRef<
|
|||||||
style,
|
style,
|
||||||
...restProps
|
...restProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
getPrefixCls,
|
getPrefixCls,
|
||||||
direction: contextDirection,
|
direction: contextDirection,
|
||||||
@ -49,23 +49,16 @@ const Typography = React.forwardRef<
|
|||||||
} = React.useContext<ConfigConsumerProps>(ConfigContext);
|
} = React.useContext<ConfigConsumerProps>(ConfigContext);
|
||||||
|
|
||||||
const direction = typographyDirection ?? contextDirection;
|
const direction = typographyDirection ?? contextDirection;
|
||||||
|
const mergedRef = setContentRef ? composeRef(ref, setContentRef) : ref;
|
||||||
let mergedRef = ref;
|
const prefixCls = getPrefixCls('typography', customizePrefixCls);
|
||||||
if (setContentRef) {
|
|
||||||
mergedRef = composeRef(ref, setContentRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
const warning = devUseWarning('Typography');
|
const warning = devUseWarning('Typography');
|
||||||
|
|
||||||
warning.deprecated(!setContentRef, 'setContentRef', 'ref');
|
warning.deprecated(!setContentRef, 'setContentRef', 'ref');
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefixCls = getPrefixCls('typography', customizePrefixCls);
|
|
||||||
|
|
||||||
// Style
|
// Style
|
||||||
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
|
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
|
||||||
|
|
||||||
const componentClassName = classNames(
|
const componentClassName = classNames(
|
||||||
prefixCls,
|
prefixCls,
|
||||||
typography?.className,
|
typography?.className,
|
||||||
@ -92,5 +85,4 @@ if (process.env.NODE_ENV !== 'production') {
|
|||||||
Typography.displayName = 'Typography';
|
Typography.displayName = 'Typography';
|
||||||
}
|
}
|
||||||
|
|
||||||
// es default export should use const instead of let
|
|
||||||
export default Typography;
|
export default Typography;
|
||||||
|
22
components/typography/hooks/useTooltipProps.ts
Normal file
22
components/typography/hooks/useTooltipProps.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { isValidElement, useMemo } from 'react';
|
||||||
|
import type { TooltipProps } from '../../tooltip';
|
||||||
|
|
||||||
|
const useTooltipProps = (
|
||||||
|
tooltip: React.ReactNode | TooltipProps,
|
||||||
|
editConfigText: React.ReactNode,
|
||||||
|
children: React.ReactNode,
|
||||||
|
) =>
|
||||||
|
useMemo(() => {
|
||||||
|
if (tooltip === true) {
|
||||||
|
return { title: editConfigText ?? children };
|
||||||
|
}
|
||||||
|
if (isValidElement(tooltip)) {
|
||||||
|
return { title: tooltip };
|
||||||
|
}
|
||||||
|
if (typeof tooltip === 'object') {
|
||||||
|
return { title: editConfigText ?? children, ...tooltip };
|
||||||
|
}
|
||||||
|
return { title: tooltip };
|
||||||
|
}, [typeof tooltip === 'object' ? JSON.stringify(tooltip) : tooltip, editConfigText, children]);
|
||||||
|
|
||||||
|
export default useTooltipProps;
|
@ -1,16 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
/** Similar with `useEffect` but only trigger after mounted */
|
|
||||||
const useUpdatedEffect = (callback: () => void, conditions?: React.DependencyList) => {
|
|
||||||
const mountRef = React.useRef(false);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (mountRef.current) {
|
|
||||||
callback();
|
|
||||||
} else {
|
|
||||||
mountRef.current = true;
|
|
||||||
}
|
|
||||||
}, conditions);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default useUpdatedEffect;
|
|
Loading…
Reference in New Issue
Block a user