Skip to content

Commit fe3a58c

Browse files
authored
feat: add arrow css var (#379)
* feat: add arrow css var * chore: clean up * chore: fix arrow * feat: support content * test: add test case
1 parent 30235ad commit fe3a58c

File tree

7 files changed

+76
-30
lines changed

7 files changed

+76
-30
lines changed

assets/index.less

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,35 +41,35 @@
4141
}
4242

4343
&-arrow {
44+
z-index: 1;
4445
width: 0px;
4546
height: 0px;
4647
background: #000;
4748
border-radius: 100vw;
4849
box-shadow: 0 0 0 3px black;
49-
z-index: 1;
5050
}
5151

5252
@keyframes rcTriggerZoomIn {
5353
0% {
5454
transform: scale(0, 0);
55-
transform-origin: 50% 50%;
55+
transform-origin: var(--arrow-x, 50%) var(--arrow-y, 50%);
5656
opacity: 0;
5757
}
5858
100% {
5959
transform: scale(1, 1);
60-
transform-origin: 50% 50%;
60+
transform-origin: var(--arrow-x, 50%) var(--arrow-y, 50%);
6161
opacity: 1;
6262
}
6363
}
6464
@keyframes rcTriggerZoomOut {
6565
0% {
6666
transform: scale(1, 1);
67-
transform-origin: 50% 50%;
67+
transform-origin: var(--arrow-x, 50%) var(--arrow-y, 50%);
6868
opacity: 1;
6969
}
7070
100% {
7171
transform: scale(0, 0);
72-
transform-origin: 50% 50%;
72+
transform-origin: var(--arrow-x, 50%) var(--arrow-y, 50%);
7373
opacity: 0;
7474
}
7575
}

docs/examples/container.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const builtinPlacements = {
5555
},
5656
};
5757

58-
const popupPlacement = 'right';
58+
const popupPlacement = 'top';
5959

6060
export default () => {
6161
console.log('Demo Render!');
@@ -136,7 +136,7 @@ export default () => {
136136
}}
137137
>
138138
<Trigger
139-
arrow
139+
arrow={{ content: 'Arrow' }}
140140
// forceRender
141141
action="click"
142142
popup={
@@ -152,12 +152,16 @@ export default () => {
152152
Popup
153153
</div>
154154
}
155+
popupTransitionName="rc-trigger-popup-zoom"
155156
popupStyle={{ boxShadow: '0 0 5px red' }}
156157
// popupVisible
157158
// getPopupContainer={() => popHolderRef.current}
158159
popupPlacement={popupPlacement}
159160
builtinPlacements={builtinPlacements}
160161
stretch="minWidth"
162+
onPopupAlign={(domNode, align) => {
163+
console.log('onPopupAlign:', domNode, align);
164+
}}
161165
>
162166
<span
163167
style={{

src/Popup/Arrow.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
import * as React from 'react';
21
import classNames from 'classnames';
3-
import type { AlignType, ArrowType } from '../interface';
2+
import * as React from 'react';
3+
import type { AlignType, ArrowPos, ArrowTypeOuter } from '../interface';
44

55
export interface ArrowProps {
66
prefixCls: string;
77
align: AlignType;
8-
arrow: ArrowType;
8+
arrow: ArrowTypeOuter;
9+
arrowPos: ArrowPos;
910
}
1011

1112
export default function Arrow(props: ArrowProps) {
12-
const { prefixCls, align, arrow } = props;
13+
const { prefixCls, align, arrow, arrowPos } = props;
1314

14-
const { x = 0, y = 0, className } = arrow || {};
15+
const { className, content } = arrow || {};
16+
const { x = 0, y = 0 } = arrowPos;
1517

1618
const arrowRef = React.useRef<HTMLDivElement>();
1719

@@ -53,6 +55,12 @@ export default function Arrow(props: ArrowProps) {
5355
}
5456

5557
return (
56-
<div ref={arrowRef} className={classNames(`${prefixCls}-arrow`, className)} style={alignStyle} />
58+
<div
59+
ref={arrowRef}
60+
className={classNames(`${prefixCls}-arrow`, className)}
61+
style={alignStyle}
62+
>
63+
{content}
64+
</div>
5765
);
5866
}

src/Popup/index.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
66
import { composeRef } from 'rc-util/lib/ref';
77
import * as React from 'react';
88
import type { TriggerProps } from '../';
9-
import type { AlignType, ArrowType } from '../interface';
9+
import type { AlignType, ArrowPos, ArrowTypeOuter } from '../interface';
1010
import Arrow from './Arrow';
1111
import Mask from './Mask';
1212
import PopupContent from './PopupContent';
@@ -26,7 +26,8 @@ export interface PopupProps {
2626

2727
// Arrow
2828
align?: AlignType;
29-
arrow?: ArrowType;
29+
arrow?: ArrowTypeOuter;
30+
arrowPos: ArrowPos;
3031

3132
// Open
3233
open: boolean;
@@ -81,6 +82,7 @@ const Popup = React.forwardRef<HTMLDivElement, PopupProps>((props, ref) => {
8182

8283
// Arrow
8384
arrow,
85+
arrowPos,
8486
align,
8587

8688
// Motion
@@ -206,14 +208,18 @@ const Popup = React.forwardRef<HTMLDivElement, PopupProps>((props, ref) => {
206208
<div
207209
ref={composeRef(resizeObserverRef, ref, motionRef)}
208210
className={cls}
209-
style={{
210-
...offsetStyle,
211-
...miscStyle,
212-
...motionStyle,
213-
boxSizing: 'border-box',
214-
zIndex,
215-
...style,
216-
}}
211+
style={
212+
{
213+
'--arrow-x': `${arrowPos.x || 0}px`,
214+
'--arrow-y': `${arrowPos.y || 0}px`,
215+
...offsetStyle,
216+
...miscStyle,
217+
...motionStyle,
218+
boxSizing: 'border-box',
219+
zIndex,
220+
...style,
221+
} as React.CSSProperties
222+
}
217223
onMouseEnter={onMouseEnter}
218224
onMouseLeave={onMouseLeave}
219225
onClick={onClick}
@@ -222,6 +228,7 @@ const Popup = React.forwardRef<HTMLDivElement, PopupProps>((props, ref) => {
222228
<Arrow
223229
prefixCls={prefixCls}
224230
arrow={arrow}
231+
arrowPos={arrowPos}
225232
align={align}
226233
/>
227234
)}

src/index.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import type {
1818
ActionType,
1919
AlignType,
2020
AnimationType,
21-
ArrowType,
21+
ArrowPos,
2222
ArrowTypeOuter,
2323
BuildInPlacements,
2424
TransitionNameType,
@@ -650,12 +650,15 @@ export function generateTrigger(
650650
...passedProps,
651651
});
652652

653-
const innerArrow: ArrowType = arrow
653+
const arrowPos: ArrowPos = {
654+
x: arrowX,
655+
y: arrowY,
656+
};
657+
658+
const innerArrow: ArrowTypeOuter = arrow
654659
? {
655660
// true and Object likely
656661
...(arrow !== true ? arrow : {}),
657-
x: arrowX,
658-
y: arrowY,
659662
}
660663
: null;
661664

@@ -702,6 +705,7 @@ export function generateTrigger(
702705
// Arrow
703706
align={alignInfo}
704707
arrow={innerArrow}
708+
arrowPos={arrowPos}
705709
// Align
706710
ready={ready}
707711
offsetX={offsetX}

src/interface.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,13 @@ export interface AlignType {
7474

7575
export interface ArrowTypeOuter {
7676
className?: string;
77+
content?: React.ReactNode;
7778
}
7879

79-
export type ArrowType = ArrowTypeOuter & {
80+
export type ArrowPos = {
8081
x?: number;
8182
y?: number;
82-
}
83+
};
8384

8485
export type BuildInPlacements = Record<string, AlignType>;
8586

@@ -106,4 +107,4 @@ export interface MobileConfig {
106107
popupClassName?: string;
107108
popupStyle?: React.CSSProperties;
108109
popupRender?: (originNode: React.ReactNode) => React.ReactNode;
109-
}
110+
}

tests/arrow.test.jsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,26 @@ describe('Trigger.Arrow', () => {
187187
expect(arrowDom.classList.contains('abc')).toBeTruthy();
188188
});
189189
});
190+
191+
it('content', async () => {
192+
render(
193+
<Trigger
194+
popupVisible
195+
popupAlign={{
196+
points: ['cl', 'cr'],
197+
autoArrow: false,
198+
}}
199+
popup={<strong>trigger</strong>}
200+
arrow={{
201+
content: <span className="my-content" />,
202+
}}
203+
>
204+
<div />
205+
</Trigger>,
206+
);
207+
208+
await awaitFakeTimer();
209+
210+
expect(document.querySelector('.my-content')).toBeTruthy();
211+
});
190212
});

0 commit comments

Comments
 (0)