refactor: Full token tooltip (#35896)

* refactor: full token

* refactor: full token

* test: Udpate snapshot
This commit is contained in:
二货机器人 2022-06-02 22:15:54 +08:00 committed by GitHub
parent 276ff37d83
commit fb322cd70e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 119 additions and 285 deletions

View File

@ -17,12 +17,14 @@ import formatToken from './util/alias';
import type { FullToken } from './util/genComponentStyleHook';
import genComponentStyleHook from './util/genComponentStyleHook';
import statisticToken, { merge as mergeToken, statistic } from './util/statistic';
import getArrowStyle from './util/placementArrow';
export {
resetComponent,
resetIcon,
clearFix,
roundedArrow,
getArrowStyle,
operationUnit,
// colors
PresetColors,

View File

@ -35,6 +35,7 @@ import type { ComponentToken as SpinComponentToken } from '../../spin/style';
import type { ComponentToken as StepsComponentToken } from '../../steps/style';
import type { ComponentToken as TabsComponentToken } from '../../tabs/style';
import type { ComponentToken as TimelineComponentToken } from '../../timeline/style';
import type { ComponentToken as TooltipComponentToken } from '../../tooltip/style';
import type { ComponentToken as TransferComponentToken } from '../../transfer/style';
import type { ComponentToken as TypographyComponentToken } from '../../typography/style';
import type { ComponentToken as UploadComponentToken } from '../../upload/style';
@ -123,7 +124,7 @@ export interface OverrideToken {
Modal?: ModalComponentToken;
Message?: MessageComponentToken;
Upload?: UploadComponentToken;
Tooltip?: {};
Tooltip?: TooltipComponentToken;
Table?: {};
Space?: SpaceComponentToken;
Progress?: ProgressComponentToken;
@ -350,6 +351,7 @@ export interface AliasToken extends Omit<DerivativeToken, OmitDerivativeKey> {
colorBgComponent: string;
colorBgComponentSecondary: string;
colorBgComponentDisabled: string;
colorBgContainerWeak: string;
// =============== Legacy: should be remove ===============
colorLoadingOpacity: number;

View File

@ -97,6 +97,7 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
controlItemBgActiveHover: new TinyColor(primaryColors[0]).darken(2).toRgbString(),
controlItemBgActiveDisabled: new TinyColor('#000').tint(90).toRgbString(),
fontWeightStrong: 600,
colorBgContainerWeak: new TinyColor('#000').setAlpha(0.75).toRgbString(),
// 🔥🔥🔥🔥🔥🔥🔥🔥🔥 All TMP Token leaves here 🔥🔥🔥🔥🔥🔥🔥🔥🔥
// FIXME: Handle this when derivative is ready

View File

@ -1,7 +1,7 @@
import type { CSSInterpolation } from '@ant-design/cssinjs';
import type { AliasToken } from '../../_util/theme';
import { roundedArrow } from '../../_util/theme';
import type { TokenWithCommonCls } from '../../_util/theme/util/genComponentStyleHook';
import type { AliasToken } from '../interface';
import type { TokenWithCommonCls } from './genComponentStyleHook';
import { roundedArrow } from './roundedArrow';
function connectArrowCls(classList: string[], showArrowCls: string = '') {
return classList.map(cls => `${showArrowCls}${cls}`).join(',');
@ -11,6 +11,7 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
token: Token,
colorBg: string,
showArrowCls?: string,
linearGradient: boolean = true,
): CSSInterpolation {
const { componentCls, sizePopupArrow, marginXXS } = token;
@ -20,17 +21,27 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
return {
[componentCls]: {
// ============================ Basic ============================
[`${componentCls}-arrow`]: {
position: 'absolute',
zIndex: 1, // lift it up so the menu wouldn't cask shadow on it
display: 'block',
width: sizePopupArrow,
height: sizePopupArrow,
// Use linear-gradient to prevent arrow from covering text
background: `linear-gradient(135deg, transparent 40%, ${colorBg} 40%)`,
[`${componentCls}-arrow`]: [
linearGradient
? {
// Use linear-gradient to prevent arrow from covering text
background: `linear-gradient(135deg, transparent 49%, ${colorBg} 50%)`,
}
: {},
{
position: 'absolute',
zIndex: 1, // lift it up so the menu wouldn't cask shadow on it
display: 'block',
width: sizePopupArrow,
height: sizePopupArrow,
...roundedArrow(sizePopupArrow, 5, colorBg),
},
...roundedArrow(sizePopupArrow, 5, colorBg),
'&:before': {
background: colorBg,
},
},
],
// ========================== Placement ==========================
// Here handle the arrow position and rotate stuff

View File

@ -1,7 +1,12 @@
// deps-lint-skip-all
import type { FullToken, GenerateStyle, PresetColorType } from '../../_util/theme';
import { genComponentStyleHook, mergeToken, PresetColors, resetComponent } from '../../_util/theme';
import getArrowStyle from './arrow';
import {
genComponentStyleHook,
mergeToken,
PresetColors,
resetComponent,
getArrowStyle,
} from '../../_util/theme';
export interface ComponentToken {
zIndexPopup: number;

View File

@ -625,7 +625,7 @@ Array [
<div>
<div
class="ant-tooltip"
style="opacity:0"
style="opacity:0;--antd-arrow-background-color:#f50"
>
<div
class="ant-tooltip-content"
@ -635,7 +635,6 @@ Array [
>
<span
class="ant-tooltip-arrow-content"
style="--antd-arrow-background-color:#f50"
/>
</div>
<div
@ -659,7 +658,7 @@ Array [
<div>
<div
class="ant-tooltip"
style="opacity:0"
style="opacity:0;--antd-arrow-background-color:#2db7f5"
>
<div
class="ant-tooltip-content"
@ -669,7 +668,6 @@ Array [
>
<span
class="ant-tooltip-arrow-content"
style="--antd-arrow-background-color:#2db7f5"
/>
</div>
<div
@ -693,7 +691,7 @@ Array [
<div>
<div
class="ant-tooltip"
style="opacity:0"
style="opacity:0;--antd-arrow-background-color:#87d068"
>
<div
class="ant-tooltip-content"
@ -703,7 +701,6 @@ Array [
>
<span
class="ant-tooltip-arrow-content"
style="--antd-arrow-background-color:#87d068"
/>
</div>
<div
@ -727,7 +724,7 @@ Array [
<div>
<div
class="ant-tooltip"
style="opacity:0"
style="opacity:0;--antd-arrow-background-color:#108ee9"
>
<div
class="ant-tooltip-content"
@ -737,7 +734,6 @@ Array [
>
<span
class="ant-tooltip-arrow-content"
style="--antd-arrow-background-color:#108ee9"
/>
</div>
<div

View File

@ -203,7 +203,7 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
return overlay || title || '';
};
const { getPopupContainer, ...otherProps } = props;
const { getPopupContainer, overlayStyle, ...otherProps } = props;
const {
prefixCls: customizePrefixCls,
@ -259,6 +259,10 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
{...otherProps}
prefixCls={prefixCls}
overlayClassName={customOverlayClassName}
overlayStyle={{
...arrowContentStyle,
...overlayStyle,
}}
getTooltipContainer={getPopupContainer || getTooltipContainer || getContextPopupContainer}
ref={ref}
builtinPlacements={getTooltipPlacements()}
@ -267,7 +271,7 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
onVisibleChange={onVisibleChange}
onPopupAlign={onPopupAlign}
overlayInnerStyle={formattedOverlayInnerStyle}
arrowContent={<span className={`${prefixCls}-arrow-content`} style={arrowContentStyle} />}
arrowContent={<span className={`${prefixCls}-arrow-content`} />}
motion={{
motionName: getTransitionName(rootPrefixCls, 'zoom-big-fast', props.transitionName),
motionDeadline: 1000,

View File

@ -1,8 +1,5 @@
// deps-lint-skip-all
// import '../../style/index.less';
// import './index.less';
import type { CSSObject } from '@ant-design/cssinjs';
import { TinyColor } from '@ctrl/tinycolor';
import type {
FullToken,
GenerateStyle,
@ -14,25 +11,19 @@ import {
mergeToken,
PresetColors,
resetComponent,
roundedArrow,
getArrowStyle,
} from '../../_util/theme';
export interface TooltipToken extends FullToken<'Tooltip'> {
export interface ComponentToken {
zIndexPopup: number;
}
interface TooltipToken extends FullToken<'Tooltip'> {
// default variables
tooltipMaxWidth: number;
tooltipColor: string;
tooltipBg: string;
tooltipArrowWidth: number;
tooltipDistance: number;
tooltipArrowColor: string;
tooltipBorderRadius: number;
// component variables
tooltipArrowShadowWidth: number;
tooltipArrowRotateWidth: number;
tooltipArrowOffsetVertical: number;
tooltipArrowOffsetHorizontal: number;
zIndexTooltip: number;
tooltipShadowColor: string;
}
const generatorTooltipPresetColor: GenerateStyle<TooltipToken, CSSObject> = token => {
@ -44,285 +35,107 @@ const generatorTooltipPresetColor: GenerateStyle<TooltipToken, CSSObject> = toke
[`${componentCls}-inner`]: {
backgroundColor: lightColor,
},
[`${componentCls}-arrow-content::before`]: {
[`${componentCls}-arrow`]: {
background: lightColor,
'--antd-arrow-background-color': lightColor,
},
};
return previousValue;
}, {});
};
const genTooltipStyle: GenerateStyle<TooltipToken, CSSObject> = token => {
const genTooltipStyle: GenerateStyle<TooltipToken> = token => {
const {
componentCls, // ant-tooltip
tooltipArrowOffsetHorizontal,
tooltipArrowOffsetVertical,
tooltipMaxWidth,
tooltipColor,
tooltipBg,
tooltipArrowWidth,
tooltipDistance,
tooltipBorderRadius,
tooltipShadowColor,
tooltipArrowRotateWidth,
tooltipArrowShadowWidth,
zIndexTooltip,
zIndexPopup,
controlHeight,
boxShadow,
paddingSM,
paddingXS,
} = token;
const tooltipBgColor = new TinyColor(tooltipBg);
return {
[componentCls]: {
...resetComponent(token),
position: 'absolute',
zIndex: zIndexTooltip,
display: 'block',
'&': [{ width: 'max-content' }, { width: 'intrinsic' }],
maxWidth: tooltipMaxWidth,
visibility: 'visible',
'&-hidden': {
display: 'none',
},
'&-placement-top, &-placement-topLeft, &-placement-topRight': {
paddingBottom: tooltipDistance,
},
'&-placement-right, &-placement-rightTop, &-placement-rightBottom': {
paddingLeft: {
_skip_check_: true,
value: tooltipDistance,
},
},
'&-placement-bottom, &-placement-bottomLeft, &-placement-bottomRight': {
paddingTop: tooltipDistance,
},
'&-placement-left, &-placement-leftTop, &-placement-leftBottom': {
paddingRight: {
_skip_check_: true,
value: tooltipDistance,
},
},
// Wrapper for the tooltip content
[`${componentCls}-inner`]: {
minWidth: 30, // FIXME: hardcode in v4
minHeight: 32, // FIXME: hardcode in v4
padding: '6px 8px', // FIXME: hardcode in v4
color: tooltipColor,
textAlign: 'start',
textDecoration: 'none',
wordWrap: 'break-word',
backgroundColor: tooltipBg,
borderRadius: tooltipBorderRadius,
boxShadow,
},
[`${componentCls}-content`]: {
position: 'relative',
},
// Arrows
[`${componentCls}-arrow`]: {
return [
{
[componentCls]: {
...resetComponent(token),
position: 'absolute',
zIndex: 2,
zIndex: zIndexPopup,
display: 'block',
width: tooltipArrowRotateWidth,
height: tooltipArrowRotateWidth,
overflow: 'hidden',
background: 'transparent',
pointerEvents: 'none',
'&-content': {
'--antd-arrow-background-color': `linear-gradient(to right bottom, ${new TinyColor(
tooltipBgColor,
).setAlpha(tooltipBgColor.getAlpha() - 0.1)}, ${tooltipBg})`,
position: 'absolute',
top: 0, // FIXME: hardcode in v4
insetInlineEnd: 0, // FIXME: hardcode in v4
bottom: 0, // FIXME: hardcode in v4
insetInlineStart: 0, // FIXME: hardcode in v4
display: 'block',
width: tooltipArrowWidth,
height: tooltipArrowWidth,
margin: 'auto',
backgroundColor: 'transparent',
content: '""',
pointerEvents: 'auto',
...roundedArrow(tooltipArrowWidth, 5, 'var(--antd-arrow-background-color)'), // FIXME: hardcode in v4
},
},
[`&-placement-top ${componentCls}-arrow,
&-placement-topLeft ${componentCls}-arrow,
&-placement-topRight ${componentCls}-arrow`]: {
bottom: 0, // FIXME: hardcode in v4
transform: 'translateY(100%)',
'&-content': {
boxShadow: `${tooltipArrowShadowWidth}px ${tooltipArrowShadowWidth}px 7px ${tooltipShadowColor}`, // FIXME: hardcode in v4
transform: `translateY(${-tooltipArrowRotateWidth / 2}px) rotate(45deg)`, // FIXME: hardcode in v4
},
},
[`&-placement-top ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: '50%', // FIXME: hardcode in v4
},
transform: 'translateX(-50%) translateY(100%)',
},
[`&-placement-topLeft ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: tooltipArrowOffsetHorizontal,
},
},
[`&-placement-topRight ${componentCls}-arrow`]: {
right: {
_skip_check_: true,
value: tooltipArrowOffsetHorizontal,
},
},
[`&-placement-right ${componentCls}-arrow,
&-placement-rightTop ${componentCls}-arrow,
&-placement-rightBottom ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: 0, // FIXME: hardcode in v4
},
transform: 'translateX(-100%)',
'&-content': {
boxShadow: `-${tooltipArrowShadowWidth}px ${tooltipArrowShadowWidth}px 7px ${tooltipShadowColor}`, // FIXME: hardcode in v4
transform: `translateX(${tooltipArrowRotateWidth / 2}px) rotate(135deg)`, // FIXME: hardcode in v4
},
},
[`&-placement-right ${componentCls}-arrow`]: {
top: '50%', // FIXME: hardcode in v4
transform: 'translateX(-100%) translateY(-50%)', // FIXME: hardcode in v4
},
[`&-placement-rightTop ${componentCls}-arrow`]: {
top: tooltipArrowOffsetVertical,
},
[`&-placement-rightBottom ${componentCls}-arrow`]: {
bottom: tooltipArrowOffsetVertical,
},
[`&-placement-left ${componentCls}-arrow, &-placement-leftTop ${componentCls}-arrow, &-placement-leftBottom ${componentCls}-arrow`]:
{
right: {
_skip_check_: true,
value: 0, // FIXME: hardcode in v4
},
transform: 'translateX(100%)',
'&-content': {
boxShadow: `${tooltipArrowShadowWidth}px -${tooltipArrowShadowWidth}px 7px ${tooltipShadowColor}`, // FIXME: hardcode in v4
transform: `translateX(${-tooltipArrowRotateWidth / 2}px) rotate(315deg)`, // FIXME: hardcode in v4
},
'&': [{ width: 'max-content' }, { width: 'intrinsic' }],
maxWidth: tooltipMaxWidth,
visibility: 'visible',
'&-hidden': {
display: 'none',
},
[`&-placement-left ${componentCls}-arrow`]: {
top: '50%', // FIXME: hardcode in v4
transform: 'translateX(100%) translateY(-50%)', // FIXME: hardcode in v4
},
'--antd-arrow-background-color': tooltipBg,
[`&-placement-leftTop ${componentCls}-arrow`]: {
top: tooltipArrowOffsetVertical,
},
[`&-placement-leftBottom ${componentCls}-arrow`]: {
bottom: tooltipArrowOffsetVertical,
},
[`&-placement-bottom ${componentCls}-arrow, &-placement-bottomLeft ${componentCls}-arrow, &-placement-bottomRight ${componentCls}-arrow`]:
{
top: 0, // FIXME: hardcode in v4
transform: 'translateY(-100%)',
'&-content': {
boxShadow: `-${tooltipArrowShadowWidth}px -${tooltipArrowShadowWidth}px 7px ${tooltipShadowColor}`, // FIXME: hardcode in v4
transform: `translateY(${tooltipArrowRotateWidth / 2}px) rotate(225deg)`, // FIXME: hardcode in v4
},
// Wrapper for the tooltip content
[`${componentCls}-inner`]: {
minWidth: controlHeight,
minHeight: controlHeight,
padding: `${paddingSM / 2}px ${paddingXS}px`,
color: tooltipColor,
textAlign: 'start',
textDecoration: 'none',
wordWrap: 'break-word',
backgroundColor: tooltipBg,
borderRadius: tooltipBorderRadius,
boxShadow,
},
[`&-placement-bottom ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: '50%', // FIXME: hardcode in v4
[`${componentCls}-content`]: {
position: 'relative',
},
transform: 'translateY(-100%) translateX(-50%)', // FIXME: hardcode in v4
},
[`&-placement-bottomLeft ${componentCls}-arrow`]: {
left: {
_skip_check_: true,
value: tooltipArrowOffsetHorizontal,
// generator for preset color
...generatorTooltipPresetColor(token),
// RTL
'&-rtl': {
direction: 'rtl',
},
},
[`&-placement-bottomRight ${componentCls}-arrow`]: {
right: {
_skip_check_: true,
value: tooltipArrowOffsetHorizontal,
},
},
// generator for preset color
...generatorTooltipPresetColor(token),
// RTL
'&-rtl': {
direction: 'rtl',
},
},
};
// Arrow Style
getArrowStyle(token, 'var(--antd-arrow-background-color)', '', false),
];
};
// ============================== Export ==============================
export default (prefixCls: string, injectStyle: boolean): UseComponentStyleResult => {
const useOriginHook = genComponentStyleHook('Tooltip', token => {
// Popover use Tooltip as internal component. We do not need to handle this.
if (injectStyle === false) {
return [];
}
const useOriginHook = genComponentStyleHook(
'Tooltip',
token => {
// Popover use Tooltip as internal component. We do not need to handle this.
if (injectStyle === false) {
return [];
}
const { radiusBase, zIndexPopupBase } = token;
const tooltipArrowShadowWidth = 3; // FIXME: hardcode in v4
const tooltipArrowWidth = 8 * Math.sqrt(2); // FIXME: hardcode in v4
const tooltipShadowColor = new TinyColor('#000').setAlpha(0.07).toRgbString(); // FIXME: hardcode in v4
const tooltipBg = new TinyColor('#000').setAlpha(0.75).toRgbString(); // FIXME: hardcode in v4
const tooltipArrowRotateWidth =
Math.sqrt(tooltipArrowWidth * tooltipArrowWidth * 2) + tooltipArrowShadowWidth * 2; // FIXME: hardcode in v4
const { radiusBase, colorTextLightSolid, colorBgContainerWeak } = token;
const TooltipToken = mergeToken<TooltipToken>(token, {
// default variables
tooltipMaxWidth: 250, // FIXME: hardcode in v4
tooltipColor: '#fff', // FIXME: hardcode in v4
tooltipBg,
tooltipArrowWidth,
tooltipDistance: tooltipArrowWidth - 1 + 4, // FIXME: hardcode in v4
tooltipArrowColor: tooltipBg,
tooltipBorderRadius: radiusBase,
// component variables
tooltipShadowColor,
tooltipArrowShadowWidth,
tooltipArrowRotateWidth,
tooltipArrowOffsetVertical: 5, // FIXME: hardcode in v4
tooltipArrowOffsetHorizontal: 13, // FIXME: hardcode in v4
zIndexTooltip: zIndexPopupBase + 70, // FIXME: hardcode in v4
});
const tooltipBg = colorBgContainerWeak;
return [genTooltipStyle(TooltipToken)];
});
const TooltipToken = mergeToken<TooltipToken>(token, {
// default variables
tooltipMaxWidth: 250,
tooltipColor: colorTextLightSolid,
tooltipBg,
tooltipBorderRadius: radiusBase,
});
return [genTooltipStyle(TooltipToken)];
},
({ zIndexPopupBase }) => ({
zIndexPopup: zIndexPopupBase + 70,
}),
);
return useOriginHook(prefixCls);
};