mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 14:13:37 +08:00
feat(tooltip): tooltip support arrow prop (#40234)
* feat: tooltip support arrow props * docs: update docs * chore: update rc-tooltip version * feat: update snapshots * feat: update snapshots * style: format code * Update components/tooltip/index.tsx Co-authored-by: MadCcc <1075746765@qq.com> * Update components/tooltip/index.zh-CN.md Co-authored-by: MadCcc <1075746765@qq.com> * Update components/tooltip/demo/arrow.md Co-authored-by: MadCcc <1075746765@qq.com> * Update components/tooltip/demo/arrow.md Co-authored-by: MadCcc <1075746765@qq.com> * feat: code optimize * docs: update docs * feat: code optimize * feat: del doc * feat: update snapshots * feat: update snapshots * feat: update snapshots * feat: refactor dropdown arrow style * feat: comment * Update components/tooltip/demo/arrow.tsx Co-authored-by: MadCcc <1075746765@qq.com> * feat: popover support arrow prop * feat: tour arrow style optimize * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code * feat: update test case * feat: update test case * feat: update test case * Update components/popover/index.tsx Co-authored-by: MadCcc <1075746765@qq.com> * Update components/tooltip/index.zh-CN.md Co-authored-by: MadCcc <1075746765@qq.com> * feat: optimize code * feat: optimize code * feat: optimize code * feat: optimize code Co-authored-by: MadCcc <1075746765@qq.com>
This commit is contained in:
parent
ede5121d5f
commit
8b3868ac63
@ -19,11 +19,12 @@ export interface AdjustOverflow {
|
||||
}
|
||||
|
||||
export interface PlacementsConfig {
|
||||
arrowWidth?: number;
|
||||
arrowWidth: number;
|
||||
horizontalArrowShift?: number;
|
||||
verticalArrowShift?: number;
|
||||
arrowPointAtCenter?: boolean;
|
||||
autoAdjustOverflow?: boolean | AdjustOverflow;
|
||||
offset: number;
|
||||
}
|
||||
|
||||
export function getOverflowOptions(autoAdjustOverflow?: boolean | AdjustOverflow) {
|
||||
@ -36,73 +37,114 @@ export function getOverflowOptions(autoAdjustOverflow?: boolean | AdjustOverflow
|
||||
};
|
||||
}
|
||||
|
||||
type PlacementType = keyof BuildInPlacements;
|
||||
|
||||
function getArrowOffset(type: PlacementType, arrowWidth: number, offset: number): number[] {
|
||||
switch (type) {
|
||||
case 'top':
|
||||
case 'topLeft':
|
||||
case 'topRight':
|
||||
return [0, -(arrowWidth / 2 + offset)];
|
||||
case 'bottom':
|
||||
case 'bottomLeft':
|
||||
case 'bottomRight':
|
||||
return [0, arrowWidth / 2 + offset];
|
||||
case 'left':
|
||||
case 'leftTop':
|
||||
case 'leftBottom':
|
||||
return [-(arrowWidth / 2 + offset), 0];
|
||||
case 'right':
|
||||
case 'rightTop':
|
||||
case 'rightBottom':
|
||||
return [arrowWidth / 2 + offset, 0];
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
return [0, 0];
|
||||
}
|
||||
}
|
||||
|
||||
function vertexCalc(point1: number[], point2: number[]): number[] {
|
||||
return [point1[0] + point2[0], point1[1] + point2[1]];
|
||||
}
|
||||
|
||||
export default function getPlacements(config: PlacementsConfig) {
|
||||
const {
|
||||
arrowWidth = 4,
|
||||
arrowWidth,
|
||||
horizontalArrowShift = 16,
|
||||
verticalArrowShift = 8,
|
||||
autoAdjustOverflow,
|
||||
arrowPointAtCenter,
|
||||
offset,
|
||||
} = config;
|
||||
const halfArrowWidth = arrowWidth / 2;
|
||||
|
||||
const placementMap: BuildInPlacements = {
|
||||
left: {
|
||||
points: ['cr', 'cl'],
|
||||
offset: [-4, 0],
|
||||
offset: [-offset, 0],
|
||||
},
|
||||
right: {
|
||||
points: ['cl', 'cr'],
|
||||
offset: [4, 0],
|
||||
offset: [offset, 0],
|
||||
},
|
||||
top: {
|
||||
points: ['bc', 'tc'],
|
||||
offset: [0, -4],
|
||||
offset: [0, -offset],
|
||||
},
|
||||
bottom: {
|
||||
points: ['tc', 'bc'],
|
||||
offset: [0, 4],
|
||||
offset: [0, offset],
|
||||
},
|
||||
topLeft: {
|
||||
points: ['bl', 'tc'],
|
||||
offset: [-(horizontalArrowShift + arrowWidth), -4],
|
||||
offset: [-(horizontalArrowShift + halfArrowWidth), -offset],
|
||||
},
|
||||
leftTop: {
|
||||
points: ['tr', 'cl'],
|
||||
offset: [-4, -(verticalArrowShift + arrowWidth)],
|
||||
offset: [-offset, -(verticalArrowShift + halfArrowWidth)],
|
||||
},
|
||||
topRight: {
|
||||
points: ['br', 'tc'],
|
||||
offset: [horizontalArrowShift + arrowWidth, -4],
|
||||
offset: [horizontalArrowShift + halfArrowWidth, -offset],
|
||||
},
|
||||
rightTop: {
|
||||
points: ['tl', 'cr'],
|
||||
offset: [4, -(verticalArrowShift + arrowWidth)],
|
||||
offset: [offset, -(verticalArrowShift + halfArrowWidth)],
|
||||
},
|
||||
bottomRight: {
|
||||
points: ['tr', 'bc'],
|
||||
offset: [horizontalArrowShift + arrowWidth, 4],
|
||||
offset: [horizontalArrowShift + halfArrowWidth, offset],
|
||||
},
|
||||
rightBottom: {
|
||||
points: ['bl', 'cr'],
|
||||
offset: [4, verticalArrowShift + arrowWidth],
|
||||
offset: [offset, verticalArrowShift + halfArrowWidth],
|
||||
},
|
||||
bottomLeft: {
|
||||
points: ['tl', 'bc'],
|
||||
offset: [-(horizontalArrowShift + arrowWidth), 4],
|
||||
offset: [-(horizontalArrowShift + halfArrowWidth), offset],
|
||||
},
|
||||
leftBottom: {
|
||||
points: ['br', 'cl'],
|
||||
offset: [-4, verticalArrowShift + arrowWidth],
|
||||
offset: [-offset, verticalArrowShift + halfArrowWidth],
|
||||
},
|
||||
};
|
||||
Object.keys(placementMap).forEach((key) => {
|
||||
placementMap[key] = arrowPointAtCenter
|
||||
? {
|
||||
...placementMap[key],
|
||||
offset: vertexCalc(
|
||||
placementMap[key].offset!,
|
||||
getArrowOffset(key as PlacementType, arrowWidth, offset),
|
||||
),
|
||||
overflow: getOverflowOptions(autoAdjustOverflow),
|
||||
targetOffset,
|
||||
}
|
||||
: {
|
||||
...placements[key],
|
||||
offset: vertexCalc(
|
||||
placements[key].offset!,
|
||||
getArrowOffset(key as PlacementType, arrowWidth, offset),
|
||||
),
|
||||
overflow: getOverflowOptions(autoAdjustOverflow),
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,7 @@ import warning from '../_util/warning';
|
||||
import { NoCompactStyle } from '../space/Compact';
|
||||
import DropdownButton from './dropdown-button';
|
||||
import useStyle from './style';
|
||||
import theme from '../theme';
|
||||
|
||||
const Placements = [
|
||||
'topLeft',
|
||||
@ -183,6 +184,8 @@ const Dropdown: CompoundedComponent = (props) => {
|
||||
const prefixCls = getPrefixCls('dropdown', customizePrefixCls);
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
|
||||
const { token } = theme.useToken();
|
||||
|
||||
const child = React.Children.only(children) as React.ReactElement<any>;
|
||||
|
||||
const dropdownTrigger = cloneElement(child, {
|
||||
@ -221,6 +224,8 @@ const Dropdown: CompoundedComponent = (props) => {
|
||||
const builtinPlacements = getPlacements({
|
||||
arrowPointAtCenter: typeof arrow === 'object' && arrow.pointAtCenter,
|
||||
autoAdjustOverflow,
|
||||
offset: token.marginXXS,
|
||||
arrowWidth: arrow ? token.sizePopupArrow : 0,
|
||||
});
|
||||
|
||||
const onMenuClick = React.useCallback(() => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { getArrowOffset } from '../../style/placementArrow';
|
||||
import getArrowStyle, { getArrowOffset } from '../../style/placementArrow';
|
||||
import {
|
||||
initMoveMotion,
|
||||
initSlideMotion,
|
||||
@ -12,7 +12,7 @@ import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import genButtonStyle from './button';
|
||||
import genStatusStyle from './status';
|
||||
import { genFocusStyle, resetComponent, roundedArrow } from '../../style';
|
||||
import { genFocusStyle, resetComponent } from '../../style';
|
||||
|
||||
export interface ComponentToken {
|
||||
zIndexPopup: number;
|
||||
@ -34,7 +34,6 @@ const genBaseStyle: GenerateStyle<DropdownToken> = (token) => {
|
||||
menuCls,
|
||||
zIndexPopup,
|
||||
dropdownArrowDistance,
|
||||
dropdownArrowOffset,
|
||||
sizePopupArrow,
|
||||
antCls,
|
||||
iconCls,
|
||||
@ -46,7 +45,6 @@ const genBaseStyle: GenerateStyle<DropdownToken> = (token) => {
|
||||
fontSizeIcon,
|
||||
controlPaddingHorizontal,
|
||||
colorBgElevated,
|
||||
boxShadowPopoverArrow,
|
||||
} = token;
|
||||
|
||||
return [
|
||||
@ -99,103 +97,6 @@ const genBaseStyle: GenerateStyle<DropdownToken> = (token) => {
|
||||
display: 'none',
|
||||
},
|
||||
|
||||
// =============================================================
|
||||
// == Arrow ==
|
||||
// =============================================================
|
||||
// Offset the popover to account for the dropdown arrow
|
||||
[`
|
||||
&-show-arrow&-placement-topLeft,
|
||||
&-show-arrow&-placement-top,
|
||||
&-show-arrow&-placement-topRight
|
||||
`]: {
|
||||
paddingBottom: dropdownArrowDistance,
|
||||
},
|
||||
|
||||
[`
|
||||
&-show-arrow&-placement-bottomLeft,
|
||||
&-show-arrow&-placement-bottom,
|
||||
&-show-arrow&-placement-bottomRight
|
||||
`]: {
|
||||
paddingTop: dropdownArrowDistance,
|
||||
},
|
||||
|
||||
// Note: .popover-arrow is outer, .popover-arrow:after is inner
|
||||
[`${componentCls}-arrow`]: {
|
||||
position: 'absolute',
|
||||
zIndex: 1, // lift it up so the menu wouldn't cask shadow on it
|
||||
display: 'block',
|
||||
|
||||
...roundedArrow(
|
||||
sizePopupArrow,
|
||||
token.borderRadiusXS,
|
||||
token.borderRadiusOuter,
|
||||
colorBgElevated,
|
||||
boxShadowPopoverArrow,
|
||||
),
|
||||
},
|
||||
|
||||
[`
|
||||
&-placement-top > ${componentCls}-arrow,
|
||||
&-placement-topLeft > ${componentCls}-arrow,
|
||||
&-placement-topRight > ${componentCls}-arrow
|
||||
`]: {
|
||||
bottom: dropdownArrowDistance,
|
||||
transform: 'translateY(100%) rotate(180deg)',
|
||||
},
|
||||
|
||||
[`&-placement-top > ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
},
|
||||
transform: 'translateX(-50%) translateY(100%) rotate(180deg)',
|
||||
},
|
||||
|
||||
[`&-placement-topLeft > ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
},
|
||||
},
|
||||
|
||||
[`&-placement-topRight > ${componentCls}-arrow`]: {
|
||||
right: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
},
|
||||
},
|
||||
|
||||
[`
|
||||
&-placement-bottom > ${componentCls}-arrow,
|
||||
&-placement-bottomLeft > ${componentCls}-arrow,
|
||||
&-placement-bottomRight > ${componentCls}-arrow
|
||||
`]: {
|
||||
top: dropdownArrowDistance,
|
||||
transform: `translateY(-100%)`,
|
||||
},
|
||||
|
||||
[`&-placement-bottom > ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
},
|
||||
transform: `translateY(-100%) translateX(-50%)`,
|
||||
},
|
||||
|
||||
[`&-placement-bottomLeft > ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
},
|
||||
},
|
||||
|
||||
[`&-placement-bottomRight > ${componentCls}-arrow`]: {
|
||||
right: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
},
|
||||
},
|
||||
|
||||
// =============================================================
|
||||
// == Motion ==
|
||||
// =============================================================
|
||||
@ -233,6 +134,15 @@ const genBaseStyle: GenerateStyle<DropdownToken> = (token) => {
|
||||
},
|
||||
},
|
||||
|
||||
// =============================================================
|
||||
// == Arrow style ==
|
||||
// =============================================================
|
||||
getArrowStyle<DropdownToken>(token, {
|
||||
colorBg: colorBgElevated,
|
||||
limitVerticalRadius: true,
|
||||
arrowPlacement: { top: true, bottom: true },
|
||||
}),
|
||||
|
||||
{
|
||||
// =============================================================
|
||||
// == Menu ==
|
||||
|
@ -1,100 +1,687 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/popover/demo/arrow-point-at-center.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
exports[`renders ./components/popover/demo/arrow.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="demo"
|
||||
>
|
||||
<div
|
||||
class="ant-segmented"
|
||||
>
|
||||
<span>
|
||||
Align edge / 边缘对齐
|
||||
</span>
|
||||
</button>,
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
class="ant-segmented-group"
|
||||
>
|
||||
<label
|
||||
class="ant-segmented-item ant-segmented-item-selected"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Show"
|
||||
>
|
||||
Show
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
class="ant-segmented-item"
|
||||
>
|
||||
<input
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Hide"
|
||||
>
|
||||
Hide
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
class="ant-segmented-item"
|
||||
>
|
||||
<input
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Center"
|
||||
>
|
||||
Center
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center"
|
||||
role="separator"
|
||||
>
|
||||
<span
|
||||
class="ant-divider-inner-text"
|
||||
>
|
||||
Content
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
style="margin-left:70px;white-space:nowrap"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
TL
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
Title
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Arrow points to center / 箭头指向中心
|
||||
</span>
|
||||
</button>,
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Top
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
Title
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
TR
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width:70px;float:left"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
LT
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Left
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
LB
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width:70px;margin-left:304px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
RT
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Right
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
RB
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="margin-left:70px;clear:both;white-space:nowrap"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
BL
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Bottom
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
BR
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-popover"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-content"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-popover-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<div
|
||||
class="ant-popover-title"
|
||||
>
|
||||
<span>
|
||||
Title
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="ant-popover-inner-content"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
<p>
|
||||
Content
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/popover/demo/basic.tsx extend context correctly 1`] = `
|
||||
|
@ -1,24 +1,183 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/popover/demo/arrow-point-at-center.tsx correctly 1`] = `
|
||||
Array [
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
exports[`renders ./components/popover/demo/arrow.tsx correctly 1`] = `
|
||||
<div
|
||||
class="demo"
|
||||
>
|
||||
<div
|
||||
class="ant-segmented"
|
||||
>
|
||||
<span>
|
||||
Align edge / 边缘对齐
|
||||
</span>
|
||||
</button>,
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-segmented-group"
|
||||
>
|
||||
<label
|
||||
class="ant-segmented-item ant-segmented-item-selected"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Show"
|
||||
>
|
||||
Show
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
class="ant-segmented-item"
|
||||
>
|
||||
<input
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Hide"
|
||||
>
|
||||
Hide
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
class="ant-segmented-item"
|
||||
>
|
||||
<input
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Center"
|
||||
>
|
||||
Center
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center"
|
||||
role="separator"
|
||||
>
|
||||
<span>
|
||||
Arrow points to center / 箭头指向中心
|
||||
<span
|
||||
class="ant-divider-inner-text"
|
||||
>
|
||||
Content
|
||||
</span>
|
||||
</button>,
|
||||
]
|
||||
</div>
|
||||
<div
|
||||
style="margin-left:70px;white-space:nowrap"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
TL
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Top
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
TR
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style="width:70px;float:left"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
LT
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Left
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
LB
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style="width:70px;margin-left:304px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
RT
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Right
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
RB
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style="margin-left:70px;clear:both;white-space:nowrap"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
BL
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Bottom
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
BR
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/popover/demo/basic.tsx correctly 1`] = `
|
||||
|
@ -1,7 +0,0 @@
|
||||
## zh-CN
|
||||
|
||||
设置了 `arrowPointAtCenter` 后,箭头将指向目标元素的中心。
|
||||
|
||||
## en-US
|
||||
|
||||
The arrow points to the center of the target element, which set `arrowPointAtCenter`.
|
@ -1,22 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Button, Popover } from 'antd';
|
||||
|
||||
const content = (
|
||||
<>
|
||||
<p>Content</p>
|
||||
<p>Content</p>
|
||||
</>
|
||||
);
|
||||
|
||||
const App: React.FC = () => (
|
||||
<>
|
||||
<Popover placement="topLeft" title="Title" content={content}>
|
||||
<Button>Align edge / 边缘对齐</Button>
|
||||
</Popover>
|
||||
<Popover placement="topLeft" title="Title" content={content} arrowPointAtCenter>
|
||||
<Button>Arrow points to center / 箭头指向中心</Button>
|
||||
</Popover>
|
||||
</>
|
||||
);
|
||||
|
||||
export default App;
|
27
components/popover/demo/arrow.md
Normal file
27
components/popover/demo/arrow.md
Normal file
@ -0,0 +1,27 @@
|
||||
## zh-CN
|
||||
|
||||
通过 `arrow` 属性隐藏箭头。
|
||||
|
||||
## en-US
|
||||
|
||||
Hide arrow by `arrow`.
|
||||
|
||||
<style>
|
||||
.code-box-demo .demo {
|
||||
overflow: auto;
|
||||
}
|
||||
.code-box-demo .ant-btn {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.code-box-demo .ant-btn-rtl {
|
||||
margin-right: 0;
|
||||
margin-left: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
#components-popover-demo-arrow .ant-btn {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
81
components/popover/demo/arrow.tsx
Normal file
81
components/popover/demo/arrow.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Button, Divider, Popover, Segmented } from 'antd';
|
||||
|
||||
const text = <span>Title</span>;
|
||||
const content = (
|
||||
<div>
|
||||
<p>Content</p>
|
||||
<p>Content</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
const buttonWidth = 70;
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [showArrow, setShowArrow] = useState(true);
|
||||
const [arrowAtCenter, setArrowAtCenter] = useState(false);
|
||||
|
||||
const mergedArrow = useMemo(() => {
|
||||
if (arrowAtCenter) return { arrowPointAtCenter: true };
|
||||
return showArrow;
|
||||
}, [showArrow, arrowAtCenter]);
|
||||
|
||||
return (
|
||||
<div className="demo">
|
||||
<Segmented
|
||||
options={['Show', 'Hide', 'Center']}
|
||||
onChange={(val) => {
|
||||
setShowArrow(val !== 'Hide');
|
||||
setArrowAtCenter(val === 'Center');
|
||||
}}
|
||||
/>
|
||||
<Divider orientation="center">Content</Divider>
|
||||
<div style={{ marginLeft: buttonWidth, whiteSpace: 'nowrap' }}>
|
||||
<Popover placement="topLeft" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>TL</Button>
|
||||
</Popover>
|
||||
<Popover placement="top" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>Top</Button>
|
||||
</Popover>
|
||||
<Popover placement="topRight" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>TR</Button>
|
||||
</Popover>
|
||||
</div>
|
||||
<div style={{ width: buttonWidth, float: 'left' }}>
|
||||
<Popover placement="leftTop" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>LT</Button>
|
||||
</Popover>
|
||||
<Popover placement="left" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>Left</Button>
|
||||
</Popover>
|
||||
<Popover placement="leftBottom" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>LB</Button>
|
||||
</Popover>
|
||||
</div>
|
||||
<div style={{ width: buttonWidth, marginLeft: buttonWidth * 4 + 24 }}>
|
||||
<Popover placement="rightTop" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>RT</Button>
|
||||
</Popover>
|
||||
<Popover placement="right" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>Right</Button>
|
||||
</Popover>
|
||||
<Popover placement="rightBottom" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>RB</Button>
|
||||
</Popover>
|
||||
</div>
|
||||
<div style={{ marginLeft: buttonWidth, clear: 'both', whiteSpace: 'nowrap' }}>
|
||||
<Popover placement="bottomLeft" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>BL</Button>
|
||||
</Popover>
|
||||
<Popover placement="bottom" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>Bottom</Button>
|
||||
</Popover>
|
||||
<Popover placement="bottomRight" title={text} content={content} arrow={mergedArrow}>
|
||||
<Button>BR</Button>
|
||||
</Popover>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
@ -21,8 +21,8 @@ Comparing with `Tooltip`, besides information `Popover` card can also provide ac
|
||||
<code src="./demo/basic.tsx">Basic</code>
|
||||
<code src="./demo/triggerType.tsx">Three ways to trigger</code>
|
||||
<code src="./demo/placement.tsx">Placement</code>
|
||||
<code src="./demo/arrow.tsx">Arrow</code>
|
||||
<code src="./demo/control.tsx">Controlling the close of the dialog</code>
|
||||
<code src="./demo/arrow-point-at-center.tsx">Arrow pointing</code>
|
||||
<code src="./demo/hover-with-click.tsx">Hover with click popover</code>
|
||||
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
<code src="./demo/wireframe.tsx" debug>Wireframe</code>
|
||||
|
@ -44,6 +44,8 @@ const Popover = React.forwardRef<unknown, PopoverProps>((props, ref) => {
|
||||
mouseEnterDelay = 0.1,
|
||||
mouseLeaveDelay = 0.1,
|
||||
overlayStyle = {},
|
||||
arrowPointAtCenter,
|
||||
arrow,
|
||||
...otherProps
|
||||
} = props;
|
||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||
@ -54,9 +56,14 @@ const Popover = React.forwardRef<unknown, PopoverProps>((props, ref) => {
|
||||
|
||||
const overlayCls = classNames(overlayClassName, hashId);
|
||||
|
||||
const mergedArrowPointAtCenter =
|
||||
(typeof arrow !== 'boolean' && arrow?.arrowPointAtCenter) ?? arrowPointAtCenter ?? false;
|
||||
const mergedArrow = arrow ?? { arrowPointAtCenter: mergedArrowPointAtCenter };
|
||||
|
||||
return wrapSSR(
|
||||
<Tooltip
|
||||
placement={placement}
|
||||
arrow={mergedArrow}
|
||||
trigger={trigger}
|
||||
mouseEnterDelay={mouseEnterDelay}
|
||||
mouseLeaveDelay={mouseLeaveDelay}
|
||||
|
@ -22,8 +22,8 @@ demo:
|
||||
<code src="./demo/basic.tsx">基本</code>
|
||||
<code src="./demo/triggerType.tsx">三种触发方式</code>
|
||||
<code src="./demo/placement.tsx">位置</code>
|
||||
<code src="./demo/arrow.tsx">箭头展示</code>
|
||||
<code src="./demo/control.tsx">从浮层内关闭</code>
|
||||
<code src="./demo/arrow-point-at-center.tsx">箭头指向</code>
|
||||
<code src="./demo/hover-with-click.tsx">悬停点击弹出窗口</code>
|
||||
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
<code src="./demo/wireframe.tsx" debug>线框风格</code>
|
||||
|
@ -84,7 +84,9 @@ const genBaseStyle: GenerateStyle<PopoverToken> = (token) => {
|
||||
},
|
||||
|
||||
// Arrow Style
|
||||
getArrowStyle(token, { colorBg: 'var(--antd-arrow-background-color)' }),
|
||||
getArrowStyle(token, {
|
||||
colorBg: 'var(--antd-arrow-background-color)',
|
||||
}),
|
||||
|
||||
// Pure Render
|
||||
{
|
||||
|
@ -1,12 +1,8 @@
|
||||
import type { CSSInterpolation } from '@ant-design/cssinjs';
|
||||
import type { CSSInterpolation, CSSObject } from '@ant-design/cssinjs';
|
||||
import type { AliasToken } from '../theme/internal';
|
||||
import type { TokenWithCommonCls } from '../theme/util/genComponentStyleHook';
|
||||
import { roundedArrow } from './roundedArrow';
|
||||
|
||||
function connectArrowCls(classList: string[], showArrowCls: string = '') {
|
||||
return classList.map((cls) => `${showArrowCls}${cls}`).join(',');
|
||||
}
|
||||
|
||||
export const MAX_VERTICAL_CONTENT_RADIUS = 8;
|
||||
|
||||
export function getArrowOffset(options: {
|
||||
@ -25,6 +21,11 @@ export function getArrowOffset(options: {
|
||||
return { dropdownArrowOffset, dropdownArrowOffsetVertical };
|
||||
}
|
||||
|
||||
function isInject(valid: boolean, code: CSSObject): CSSObject {
|
||||
if (!valid) return {};
|
||||
return code;
|
||||
}
|
||||
|
||||
export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToken>>(
|
||||
token: Token,
|
||||
options: {
|
||||
@ -32,22 +33,29 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
|
||||
showArrowCls?: string;
|
||||
contentRadius?: number;
|
||||
limitVerticalRadius?: boolean;
|
||||
arrowDistance?: number;
|
||||
arrowPlacement?: {
|
||||
left?: boolean;
|
||||
right?: boolean;
|
||||
top?: boolean;
|
||||
bottom?: boolean;
|
||||
};
|
||||
},
|
||||
): CSSInterpolation {
|
||||
const {
|
||||
componentCls,
|
||||
sizePopupArrow,
|
||||
marginXXS,
|
||||
borderRadiusXS,
|
||||
borderRadiusOuter,
|
||||
boxShadowPopoverArrow,
|
||||
} = token;
|
||||
const { componentCls, sizePopupArrow, borderRadiusXS, borderRadiusOuter, boxShadowPopoverArrow } =
|
||||
token;
|
||||
|
||||
const {
|
||||
colorBg,
|
||||
showArrowCls,
|
||||
contentRadius = token.borderRadiusLG,
|
||||
limitVerticalRadius,
|
||||
arrowDistance = 0,
|
||||
arrowPlacement = {
|
||||
left: true,
|
||||
right: true,
|
||||
top: true,
|
||||
bottom: true,
|
||||
},
|
||||
} = options;
|
||||
|
||||
const { dropdownArrowOffsetVertical, dropdownArrowOffset } = getArrowOffset({
|
||||
@ -56,7 +64,6 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
|
||||
borderRadiusOuter,
|
||||
limitVerticalRadius,
|
||||
});
|
||||
const dropdownArrowDistance = sizePopupArrow / 2 + marginXXS;
|
||||
|
||||
return {
|
||||
[componentCls]: {
|
||||
@ -84,166 +91,134 @@ export default function getArrowStyle<Token extends TokenWithCommonCls<AliasToke
|
||||
// ========================== Placement ==========================
|
||||
// Here handle the arrow position and rotate stuff
|
||||
// >>>>> Top
|
||||
[[
|
||||
`&-placement-top ${componentCls}-arrow`,
|
||||
`&-placement-topLeft ${componentCls}-arrow`,
|
||||
`&-placement-topRight ${componentCls}-arrow`,
|
||||
].join(',')]: {
|
||||
bottom: 0,
|
||||
transform: 'translateY(100%) rotate(180deg)',
|
||||
},
|
||||
|
||||
[`&-placement-top ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
...isInject(!!arrowPlacement.top, {
|
||||
[[
|
||||
`&-placement-top ${componentCls}-arrow`,
|
||||
`&-placement-topLeft ${componentCls}-arrow`,
|
||||
`&-placement-topRight ${componentCls}-arrow`,
|
||||
].join(',')]: {
|
||||
bottom: arrowDistance,
|
||||
transform: 'translateY(100%) rotate(180deg)',
|
||||
},
|
||||
transform: 'translateX(-50%) translateY(100%) rotate(180deg)',
|
||||
},
|
||||
|
||||
[`&-placement-topLeft ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
[`&-placement-top ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
},
|
||||
transform: 'translateX(-50%) translateY(100%) rotate(180deg)',
|
||||
},
|
||||
},
|
||||
|
||||
[`&-placement-topRight ${componentCls}-arrow`]: {
|
||||
right: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
[`&-placement-topLeft ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[`&-placement-topRight ${componentCls}-arrow`]: {
|
||||
right: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
// >>>>> Bottom
|
||||
[[
|
||||
`&-placement-bottom ${componentCls}-arrow`,
|
||||
`&-placement-bottomLeft ${componentCls}-arrow`,
|
||||
`&-placement-bottomRight ${componentCls}-arrow`,
|
||||
].join(',')]: {
|
||||
top: 0,
|
||||
transform: `translateY(-100%)`,
|
||||
},
|
||||
|
||||
[`&-placement-bottom ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
...isInject(!!arrowPlacement.bottom, {
|
||||
[[
|
||||
`&-placement-bottom ${componentCls}-arrow`,
|
||||
`&-placement-bottomLeft ${componentCls}-arrow`,
|
||||
`&-placement-bottomRight ${componentCls}-arrow`,
|
||||
].join(',')]: {
|
||||
top: arrowDistance,
|
||||
transform: `translateY(-100%)`,
|
||||
},
|
||||
transform: `translateX(-50%) translateY(-100%)`,
|
||||
},
|
||||
|
||||
[`&-placement-bottomLeft ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
[`&-placement-bottom ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
},
|
||||
transform: `translateX(-50%) translateY(-100%)`,
|
||||
},
|
||||
},
|
||||
|
||||
[`&-placement-bottomRight ${componentCls}-arrow`]: {
|
||||
right: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
[`&-placement-bottomLeft ${componentCls}-arrow`]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[`&-placement-bottomRight ${componentCls}-arrow`]: {
|
||||
right: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowOffset,
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
// >>>>> Left
|
||||
[[
|
||||
`&-placement-left ${componentCls}-arrow`,
|
||||
`&-placement-leftTop ${componentCls}-arrow`,
|
||||
`&-placement-leftBottom ${componentCls}-arrow`,
|
||||
].join(',')]: {
|
||||
right: {
|
||||
_skip_check_: true,
|
||||
value: 0,
|
||||
...isInject(!!arrowPlacement.left, {
|
||||
[[
|
||||
`&-placement-left ${componentCls}-arrow`,
|
||||
`&-placement-leftTop ${componentCls}-arrow`,
|
||||
`&-placement-leftBottom ${componentCls}-arrow`,
|
||||
].join(',')]: {
|
||||
right: {
|
||||
_skip_check_: true,
|
||||
value: arrowDistance,
|
||||
},
|
||||
transform: 'translateX(100%) rotate(90deg)',
|
||||
},
|
||||
transform: 'translateX(100%) rotate(90deg)',
|
||||
},
|
||||
|
||||
[`&-placement-left ${componentCls}-arrow`]: {
|
||||
top: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
[`&-placement-left ${componentCls}-arrow`]: {
|
||||
top: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
},
|
||||
transform: 'translateY(-50%) translateX(100%) rotate(90deg)',
|
||||
},
|
||||
transform: 'translateY(-50%) translateX(100%) rotate(90deg)',
|
||||
},
|
||||
|
||||
[`&-placement-leftTop ${componentCls}-arrow`]: {
|
||||
top: dropdownArrowOffsetVertical,
|
||||
},
|
||||
[`&-placement-leftTop ${componentCls}-arrow`]: {
|
||||
top: dropdownArrowOffsetVertical,
|
||||
},
|
||||
|
||||
[`&-placement-leftBottom ${componentCls}-arrow`]: {
|
||||
bottom: dropdownArrowOffsetVertical,
|
||||
},
|
||||
[`&-placement-leftBottom ${componentCls}-arrow`]: {
|
||||
bottom: dropdownArrowOffsetVertical,
|
||||
},
|
||||
}),
|
||||
|
||||
// >>>>> Right
|
||||
[[
|
||||
`&-placement-right ${componentCls}-arrow`,
|
||||
`&-placement-rightTop ${componentCls}-arrow`,
|
||||
`&-placement-rightBottom ${componentCls}-arrow`,
|
||||
].join(',')]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: 0,
|
||||
...isInject(!!arrowPlacement.right, {
|
||||
[[
|
||||
`&-placement-right ${componentCls}-arrow`,
|
||||
`&-placement-rightTop ${componentCls}-arrow`,
|
||||
`&-placement-rightBottom ${componentCls}-arrow`,
|
||||
].join(',')]: {
|
||||
left: {
|
||||
_skip_check_: true,
|
||||
value: arrowDistance,
|
||||
},
|
||||
transform: 'translateX(-100%) rotate(-90deg)',
|
||||
},
|
||||
transform: 'translateX(-100%) rotate(-90deg)',
|
||||
},
|
||||
|
||||
[`&-placement-right ${componentCls}-arrow`]: {
|
||||
top: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
[`&-placement-right ${componentCls}-arrow`]: {
|
||||
top: {
|
||||
_skip_check_: true,
|
||||
value: '50%',
|
||||
},
|
||||
transform: 'translateY(-50%) translateX(-100%) rotate(-90deg)',
|
||||
},
|
||||
transform: 'translateY(-50%) translateX(-100%) rotate(-90deg)',
|
||||
},
|
||||
|
||||
[`&-placement-rightTop ${componentCls}-arrow`]: {
|
||||
top: dropdownArrowOffsetVertical,
|
||||
},
|
||||
|
||||
[`&-placement-rightBottom ${componentCls}-arrow`]: {
|
||||
bottom: dropdownArrowOffsetVertical,
|
||||
},
|
||||
|
||||
// =========================== Offset ============================
|
||||
// Offset the popover to account for the dropdown arrow
|
||||
// >>>>> Top
|
||||
[connectArrowCls(
|
||||
[`&-placement-topLeft`, `&-placement-top`, `&-placement-topRight`],
|
||||
showArrowCls,
|
||||
)]: {
|
||||
paddingBottom: dropdownArrowDistance,
|
||||
},
|
||||
|
||||
// >>>>> Bottom
|
||||
[connectArrowCls(
|
||||
[`&-placement-bottomLeft`, `&-placement-bottom`, `&-placement-bottomRight`],
|
||||
showArrowCls,
|
||||
)]: {
|
||||
paddingTop: dropdownArrowDistance,
|
||||
},
|
||||
|
||||
// >>>>> Left
|
||||
[connectArrowCls(
|
||||
[`&-placement-leftTop`, `&-placement-left`, `&-placement-leftBottom`],
|
||||
showArrowCls,
|
||||
)]: {
|
||||
paddingRight: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowDistance,
|
||||
[`&-placement-rightTop ${componentCls}-arrow`]: {
|
||||
top: dropdownArrowOffsetVertical,
|
||||
},
|
||||
},
|
||||
|
||||
// >>>>> Right
|
||||
[connectArrowCls(
|
||||
[`&-placement-rightTop`, `&-placement-right`, `&-placement-rightBottom`],
|
||||
showArrowCls,
|
||||
)]: {
|
||||
paddingLeft: {
|
||||
_skip_check_: true,
|
||||
value: dropdownArrowDistance,
|
||||
[`&-placement-rightBottom ${componentCls}-arrow`]: {
|
||||
bottom: dropdownArrowOffsetVertical,
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1,72 +1,495 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/tooltip/demo/arrow-point-at-center.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
exports[`renders ./components/tooltip/demo/arrow.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="demo"
|
||||
>
|
||||
<div
|
||||
class="ant-segmented"
|
||||
>
|
||||
<span>
|
||||
Align edge / 边缘对齐
|
||||
</span>
|
||||
</button>,
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
class="ant-segmented-group"
|
||||
>
|
||||
<label
|
||||
class="ant-segmented-item ant-segmented-item-selected"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Show"
|
||||
>
|
||||
Show
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
class="ant-segmented-item"
|
||||
>
|
||||
<input
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Hide"
|
||||
>
|
||||
Hide
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
class="ant-segmented-item"
|
||||
>
|
||||
<input
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Center"
|
||||
>
|
||||
Center
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center"
|
||||
role="separator"
|
||||
>
|
||||
<span
|
||||
class="ant-divider-inner-text"
|
||||
>
|
||||
Content
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
style="margin-left:70px;white-space:nowrap"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
TL
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
Prompt Text
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Arrow points to center / 箭头指向中心
|
||||
</span>
|
||||
</button>,
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Top
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
Prompt Text
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
TR
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width:70px;float:left"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
LT
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Left
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
LB
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="width:70px;margin-left:304px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
RT
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Right
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
RB
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="margin-left:70px;clear:both;white-space:nowrap"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
BL
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Bottom
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
BR
|
||||
</span>
|
||||
</button>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
>
|
||||
<span>
|
||||
prompt text
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tooltip/demo/auto-adjust-overflow.tsx extend context correctly 1`] = `
|
||||
|
@ -1,24 +1,183 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/tooltip/demo/arrow-point-at-center.tsx correctly 1`] = `
|
||||
Array [
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
exports[`renders ./components/tooltip/demo/arrow.tsx correctly 1`] = `
|
||||
<div
|
||||
class="demo"
|
||||
>
|
||||
<div
|
||||
class="ant-segmented"
|
||||
>
|
||||
<span>
|
||||
Align edge / 边缘对齐
|
||||
</span>
|
||||
</button>,
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
<div
|
||||
class="ant-segmented-group"
|
||||
>
|
||||
<label
|
||||
class="ant-segmented-item ant-segmented-item-selected"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Show"
|
||||
>
|
||||
Show
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
class="ant-segmented-item"
|
||||
>
|
||||
<input
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Hide"
|
||||
>
|
||||
Hide
|
||||
</div>
|
||||
</label>
|
||||
<label
|
||||
class="ant-segmented-item"
|
||||
>
|
||||
<input
|
||||
class="ant-segmented-item-input"
|
||||
type="radio"
|
||||
/>
|
||||
<div
|
||||
class="ant-segmented-item-label"
|
||||
title="Center"
|
||||
>
|
||||
Center
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center"
|
||||
role="separator"
|
||||
>
|
||||
<span>
|
||||
Arrow points to center / 箭头指向中心
|
||||
<span
|
||||
class="ant-divider-inner-text"
|
||||
>
|
||||
Content
|
||||
</span>
|
||||
</button>,
|
||||
]
|
||||
</div>
|
||||
<div
|
||||
style="margin-left:70px;white-space:nowrap"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
TL
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Top
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
TR
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style="width:70px;float:left"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
LT
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Left
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
LB
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style="width:70px;margin-left:304px"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
RT
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Right
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
RB
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
style="margin-left:70px;clear:both;white-space:nowrap"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
BL
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Bottom
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
BR
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/tooltip/demo/auto-adjust-overflow.tsx correctly 1`] = `
|
||||
|
@ -45,3 +45,60 @@ exports[`Tooltip should hide when mouse leave antd disabled component Switch 1`]
|
||||
</button>
|
||||
</span>
|
||||
`;
|
||||
|
||||
exports[`Tooltip support arrow props by default 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="target ant-tooltip-open"
|
||||
>
|
||||
target
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast"
|
||||
style="opacity: 0;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Tooltip support arrow props pass false to hide arrow 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="target ant-tooltip-open"
|
||||
>
|
||||
target
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast"
|
||||
style="opacity: 0;"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -16,6 +16,13 @@ import { resetWarned } from '../../_util/warning';
|
||||
describe('Tooltip', () => {
|
||||
mountTest(Tooltip);
|
||||
rtlTest(Tooltip);
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.useRealTimers();
|
||||
jest.clearAllTimers();
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
spyElementPrototype(HTMLElement, 'offsetParent', {
|
||||
@ -188,6 +195,7 @@ describe('Tooltip', () => {
|
||||
const arrowWidth = 5;
|
||||
const horizontalArrowShift = 16;
|
||||
const triggerWidth = 200;
|
||||
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
const suit = () => {
|
||||
const { container } = render(
|
||||
@ -227,13 +235,39 @@ describe('Tooltip', () => {
|
||||
);
|
||||
fireEvent.click(container2.getElementsByTagName('button')[0]);
|
||||
const popupLeftArrowPointAtCenter = parseInt(
|
||||
container.querySelector<HTMLDivElement>('.point-center-element')?.style?.left!,
|
||||
container2.querySelector<HTMLDivElement>('.point-center-element')?.style?.left!,
|
||||
10,
|
||||
);
|
||||
|
||||
expect(popupLeftArrowPointAtCenter - popupLeftDefault).toBe(
|
||||
triggerWidth / 2 - horizontalArrowShift - arrowWidth,
|
||||
);
|
||||
|
||||
const { container: container3 } = render(
|
||||
<Tooltip
|
||||
title="xxxxx"
|
||||
trigger="click"
|
||||
mouseEnterDelay={0}
|
||||
mouseLeaveDelay={0}
|
||||
placement="bottomLeft"
|
||||
arrow={{ arrowPointAtCenter: true }}
|
||||
overlayClassName="point-center-element"
|
||||
>
|
||||
<button type="button" style={{ width: triggerWidth }}>
|
||||
Hello world!
|
||||
</button>
|
||||
</Tooltip>,
|
||||
);
|
||||
fireEvent.click(container3.getElementsByTagName('button')[0]);
|
||||
const popupLeftArrowPointAtCenter2 = parseInt(
|
||||
container3.querySelector<HTMLDivElement>('.point-center-element')?.style?.left!,
|
||||
10,
|
||||
);
|
||||
|
||||
expect(popupLeftArrowPointAtCenter2 - popupLeftDefault).toBe(
|
||||
triggerWidth / 2 - horizontalArrowShift - arrowWidth,
|
||||
);
|
||||
expect(warnSpy).toHaveBeenCalledTimes(1);
|
||||
};
|
||||
|
||||
(jest.dontMock as any)('rc-trigger', suit);
|
||||
@ -567,4 +601,22 @@ describe('Tooltip', () => {
|
||||
expect(container.querySelector('.bamboo')).toBeTruthy();
|
||||
expect(container.querySelector('.ant-tooltip')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('support arrow props pass false to hide arrow', () => {
|
||||
const { container } = render(
|
||||
<Tooltip open arrow={false}>
|
||||
<div className="target">target</div>
|
||||
</Tooltip>,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('support arrow props by default', () => {
|
||||
const { container } = render(
|
||||
<Tooltip open>
|
||||
<div className="target">target</div>
|
||||
</Tooltip>,
|
||||
);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +0,0 @@
|
||||
## zh-CN
|
||||
|
||||
设置了 `arrowPointAtCenter` 后,箭头将指向目标元素的中心。
|
||||
|
||||
## en-US
|
||||
|
||||
By specifying `arrowPointAtCenter` prop, the arrow will point to the center of the target element.
|
@ -1,15 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
|
||||
const App: React.FC = () => (
|
||||
<>
|
||||
<Tooltip placement="topLeft" title="Prompt Text">
|
||||
<Button>Align edge / 边缘对齐</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="topLeft" title="Prompt Text" arrowPointAtCenter>
|
||||
<Button>Arrow points to center / 箭头指向中心</Button>
|
||||
</Tooltip>
|
||||
</>
|
||||
);
|
||||
|
||||
export default App;
|
27
components/tooltip/demo/arrow.md
Normal file
27
components/tooltip/demo/arrow.md
Normal file
@ -0,0 +1,27 @@
|
||||
## zh-CN
|
||||
|
||||
通过 `arrow` 属性隐藏箭头。
|
||||
|
||||
## en-US
|
||||
|
||||
Hide arrow by `arrow`.
|
||||
|
||||
<style>
|
||||
.code-box-demo .demo {
|
||||
overflow: auto;
|
||||
}
|
||||
.code-box-demo .ant-btn {
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.code-box-demo .ant-btn-rtl {
|
||||
margin-right: 0;
|
||||
margin-left: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
#components-tooltip-demo-arrow .ant-btn {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
75
components/tooltip/demo/arrow.tsx
Normal file
75
components/tooltip/demo/arrow.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { Button, Divider, Segmented, Tooltip } from 'antd';
|
||||
|
||||
const text = <span>prompt text</span>;
|
||||
|
||||
const buttonWidth = 70;
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [showArrow, setShowArrow] = useState(true);
|
||||
const [arrowAtCenter, setArrowAtCenter] = useState(false);
|
||||
|
||||
const mergedArrow = useMemo(() => {
|
||||
if (arrowAtCenter) return { arrowPointAtCenter: true };
|
||||
return showArrow;
|
||||
}, [showArrow, arrowAtCenter]);
|
||||
|
||||
return (
|
||||
<div className="demo">
|
||||
<Segmented
|
||||
options={['Show', 'Hide', 'Center']}
|
||||
onChange={(val) => {
|
||||
setShowArrow(val !== 'Hide');
|
||||
setArrowAtCenter(val === 'Center');
|
||||
}}
|
||||
/>
|
||||
<Divider orientation="center">Content</Divider>
|
||||
<div style={{ marginLeft: buttonWidth, whiteSpace: 'nowrap' }}>
|
||||
<Tooltip placement="topLeft" title={text} arrow={mergedArrow}>
|
||||
<Button>TL</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="top" title={text} arrow={mergedArrow}>
|
||||
<Button>Top</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="topRight" title={text} arrow={mergedArrow}>
|
||||
<Button>TR</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div style={{ width: buttonWidth, float: 'left' }}>
|
||||
<Tooltip placement="leftTop" title={text} arrow={mergedArrow}>
|
||||
<Button>LT</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="left" title={text} arrow={mergedArrow}>
|
||||
<Button>Left</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="leftBottom" title={text} arrow={mergedArrow}>
|
||||
<Button>LB</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div style={{ width: buttonWidth, marginLeft: buttonWidth * 4 + 24 }}>
|
||||
<Tooltip placement="rightTop" title={text} arrow={mergedArrow}>
|
||||
<Button>RT</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="right" title={text} arrow={mergedArrow}>
|
||||
<Button>Right</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="rightBottom" title={text} arrow={mergedArrow}>
|
||||
<Button>RB</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div style={{ marginLeft: buttonWidth, clear: 'both', whiteSpace: 'nowrap' }}>
|
||||
<Tooltip placement="bottomLeft" title={text} arrow={mergedArrow}>
|
||||
<Button>BL</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="bottom" title={text} arrow={mergedArrow}>
|
||||
<Button>Bottom</Button>
|
||||
</Tooltip>
|
||||
<Tooltip placement="bottomRight" title={text} arrow={mergedArrow}>
|
||||
<Button>BR</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
@ -19,7 +19,7 @@ A simple text popup tip.
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/basic.tsx">Basic</code>
|
||||
<code src="./demo/placement.tsx">Placement</code>
|
||||
<code src="./demo/arrow-point-at-center.tsx">Arrow pointing at the center</code>
|
||||
<code src="./demo/arrow.tsx">Arrow</code>
|
||||
<code src="./demo/auto-adjust-overflow.tsx" debug>Adjust placement automatically</code>
|
||||
<code src="./demo/destroy-tooltip-on-hide.tsx" debug>Destroy tooltip when hidden</code>
|
||||
<code src="./demo/colorful.tsx">Colorful Tooltip</code>
|
||||
@ -38,7 +38,7 @@ The following APIs are shared by Tooltip, Popconfirm, Popover.
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| align | This value will be merged into placement's config, please refer to the settings [rc-tooltip](https://github.com/react-component/tooltip) | object | - | |
|
||||
| arrowPointAtCenter | Whether the arrow is pointed at the center of target | boolean | false | |
|
||||
| arrow | Change arrow's visible state and change whether the arrow is pointed at the center of target. | boolean \| { arrowPointAtCenter: boolean } | true | 5.2.0 |
|
||||
| autoAdjustOverflow | Whether to adjust popup placement automatically when popup is off screen | boolean | true | |
|
||||
| color | The background color | string | - | 4.3.0 |
|
||||
| defaultOpen | Whether the floating tooltip card is open by default | boolean | false | 4.23.0 |
|
||||
|
@ -17,6 +17,9 @@ import warning from '../_util/warning';
|
||||
import PurePanel from './PurePanel';
|
||||
import useStyle from './style';
|
||||
import { parseColor } from './util';
|
||||
import theme from '../theme';
|
||||
|
||||
const { useToken } = theme;
|
||||
|
||||
export type { AdjustOverflow, PlacementsConfig };
|
||||
|
||||
@ -76,7 +79,9 @@ export interface AbstractTooltipProps extends LegacyTooltipProps {
|
||||
placement?: TooltipPlacement;
|
||||
builtinPlacements?: typeof Placements;
|
||||
openClassName?: string;
|
||||
/** @deprecated Please use `arrow` instead. */
|
||||
arrowPointAtCenter?: boolean;
|
||||
arrow?: boolean | { arrowPointAtCenter: boolean };
|
||||
autoAdjustOverflow?: boolean | AdjustOverflow;
|
||||
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
||||
children?: React.ReactNode;
|
||||
@ -170,8 +175,13 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
children,
|
||||
afterOpenChange,
|
||||
afterVisibleChange,
|
||||
arrow = true,
|
||||
} = props;
|
||||
|
||||
const mergedShowArrow = !!arrow;
|
||||
|
||||
const { token } = useToken();
|
||||
|
||||
const {
|
||||
getPopupContainer: getContextPopupContainer,
|
||||
getPrefixCls,
|
||||
@ -184,6 +194,7 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
['defaultVisible', 'defaultOpen'],
|
||||
['onVisibleChange', 'onOpenChange'],
|
||||
['afterVisibleChange', 'afterOpenChange'],
|
||||
['arrowPointAtCenter', 'arrow'],
|
||||
].forEach(([deprecatedName, newName]) => {
|
||||
warning(
|
||||
!(deprecatedName in props),
|
||||
@ -214,11 +225,17 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
|
||||
const getTooltipPlacements = () => {
|
||||
const { builtinPlacements, arrowPointAtCenter = false, autoAdjustOverflow = true } = props;
|
||||
|
||||
const mergedArrowPointAtCenter =
|
||||
(typeof arrow !== 'boolean' && arrow?.arrowPointAtCenter) ?? arrowPointAtCenter;
|
||||
|
||||
return (
|
||||
builtinPlacements ||
|
||||
getPlacements({
|
||||
arrowPointAtCenter,
|
||||
arrowPointAtCenter: mergedArrowPointAtCenter,
|
||||
autoAdjustOverflow,
|
||||
arrowWidth: mergedShowArrow ? token.sizePopupArrow : 0,
|
||||
offset: token.marginXXS,
|
||||
})
|
||||
);
|
||||
};
|
||||
@ -313,6 +330,7 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||
return wrapSSR(
|
||||
<RcTooltip
|
||||
{...otherProps}
|
||||
showArrow={mergedShowArrow}
|
||||
placement={placement}
|
||||
mouseEnterDelay={mouseEnterDelay}
|
||||
mouseLeaveDelay={mouseLeaveDelay}
|
||||
|
@ -21,7 +21,7 @@ demo:
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/basic.tsx">基本</code>
|
||||
<code src="./demo/placement.tsx">位置</code>
|
||||
<code src="./demo/arrow-point-at-center.tsx">箭头指向</code>
|
||||
<code src="./demo/arrow.tsx">箭头展示</code>
|
||||
<code src="./demo/auto-adjust-overflow.tsx" debug>自动调整位置</code>
|
||||
<code src="./demo/destroy-tooltip-on-hide.tsx" debug>隐藏后销毁</code>
|
||||
<code src="./demo/colorful.tsx">多彩文字提示</code>
|
||||
@ -40,7 +40,7 @@ demo:
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| align | 该值将合并到 placement 的配置中,设置参考 [rc-tooltip](https://github.com/react-component/tooltip) | object | - | |
|
||||
| arrowPointAtCenter | 箭头是否指向目标元素中心 | boolean | false | |
|
||||
| arrow | 修改箭头的显示状态以及修改箭头是否指向目标元素中心 | boolean \| { arrowPointAtCenter: boolean } | true | 5.2.0 |
|
||||
| autoAdjustOverflow | 气泡被遮挡时自动调整位置 | boolean | true | |
|
||||
| color | 背景颜色 | string | - | 4.3.0 |
|
||||
| defaultOpen | 默认是否显隐 | boolean | false | 4.23.0 |
|
||||
|
@ -107,7 +107,6 @@ const genTooltipStyle: GenerateStyle<TooltipToken> = (token) => {
|
||||
}),
|
||||
{
|
||||
colorBg: 'var(--antd-arrow-background-color)',
|
||||
showArrowCls: '',
|
||||
contentRadius: tooltipBorderRadius,
|
||||
limitVerticalRadius: true,
|
||||
},
|
||||
|
@ -7,6 +7,8 @@ import { ConfigContext } from '../config-provider';
|
||||
import useStyle from './style';
|
||||
import type { TourProps, TourStepProps } from './interface';
|
||||
import PurePanel from './PurePanel';
|
||||
import theme from '../theme';
|
||||
import getPlacements from '../_util/placements';
|
||||
|
||||
const Tour: React.FC<TourProps> & { _InternalPanelDoNotUseOrYouWillBeFired: typeof PurePanel } = (
|
||||
props,
|
||||
@ -22,6 +24,14 @@ const Tour: React.FC<TourProps> & { _InternalPanelDoNotUseOrYouWillBeFired: type
|
||||
const { getPrefixCls, direction } = useContext<ConfigConsumerProps>(ConfigContext);
|
||||
const prefixCls = getPrefixCls('tour', customizePrefixCls);
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
const { token } = theme.useToken();
|
||||
|
||||
const builtinPlacements = getPlacements({
|
||||
arrowPointAtCenter: true,
|
||||
autoAdjustOverflow: true,
|
||||
offset: token.marginXXS,
|
||||
arrowWidth: token.sizePopupArrow,
|
||||
});
|
||||
|
||||
const customClassName = classNames(
|
||||
{
|
||||
@ -43,6 +53,7 @@ const Tour: React.FC<TourProps> & { _InternalPanelDoNotUseOrYouWillBeFired: type
|
||||
current={current}
|
||||
animated
|
||||
renderPanel={mergedRenderPanel}
|
||||
builtinPlacements={builtinPlacements}
|
||||
/>,
|
||||
);
|
||||
};
|
||||
|
@ -230,7 +230,6 @@ const genBaseStyle: GenerateStyle<TourToken> = (token) => {
|
||||
// ============================= Arrow ===========================
|
||||
getArrowStyle<TourToken>(token, {
|
||||
colorBg: 'var(--antd-arrow-background-color)',
|
||||
showArrowCls: '',
|
||||
contentRadius: tourBorderRadius,
|
||||
limitVerticalRadius: true,
|
||||
}),
|
||||
|
@ -113,7 +113,7 @@
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@ctrl/tinycolor": "^3.4.0",
|
||||
"@rc-component/mutate-observer": "^1.0.0",
|
||||
"@rc-component/tour": "~1.5.0",
|
||||
"@rc-component/tour": "~1.6.0",
|
||||
"classnames": "^2.2.6",
|
||||
"copy-to-clipboard": "^3.2.0",
|
||||
"dayjs": "^1.11.1",
|
||||
@ -145,7 +145,7 @@
|
||||
"rc-table": "~7.30.2",
|
||||
"rc-tabs": "~12.5.1",
|
||||
"rc-textarea": "~1.0.0",
|
||||
"rc-tooltip": "~5.2.0",
|
||||
"rc-tooltip": "~5.3.1",
|
||||
"rc-tree": "~5.7.0",
|
||||
"rc-tree-select": "~5.6.0",
|
||||
"rc-trigger": "^5.3.4",
|
||||
|
Loading…
Reference in New Issue
Block a user