Skip to content

Commit 25aa6e2

Browse files
committed
chore: clean up
1 parent 5cc8708 commit 25aa6e2

File tree

4 files changed

+251
-43
lines changed

4 files changed

+251
-43
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"test": "rc-test"
4242
},
4343
"dependencies": {
44-
"@rc-component/trigger": "^3.6.0",
44+
"@rc-component/trigger": "^3.6.4",
4545
"@rc-component/util": "^1.3.0",
4646
"classnames": "^2.3.1"
4747
},

src/Popup.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const Popup: React.FC<ContentProps> = (props) => {
1717
<div
1818
id={id}
1919
className={cls(`${prefixCls}-body`, classNames?.body)}
20-
style={styles.body}
20+
style={styles?.body}
2121
role="tooltip"
2222
>
2323
{typeof children === 'function' ? children() : children}

src/Tooltip.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,10 @@ const Tooltip = React.forwardRef<TooltipRef, TooltipProps>((props, ref) => {
107107
return {
108108
...arrowConfig,
109109
className: cls(arrowConfig.className, classNames?.arrow),
110-
content: arrowConfig.content || arrowContent,
110+
style: { ...arrowConfig.style, ...styles?.arrow },
111+
content: arrowConfig.content ?? arrowContent,
111112
};
112-
}, [showArrow, classNames?.arrow, arrowContent]);
113+
}, [showArrow, classNames?.arrow, styles?.arrow, arrowContent]);
113114

114115
// ======================== Children ========================
115116
const getChildren = () => {

tests/index.test.tsx

Lines changed: 246 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,7 @@ describe('rc-tooltip', () => {
5959
verifyContent(container, 'Tooltip content');
6060
});
6161

62-
// https://github.com/ant-design/ant-design/pull/23155
63-
it('using style inner style', () => {
64-
const { container } = render(
65-
<Tooltip
66-
trigger={['click']}
67-
placement="left"
68-
overlay={() => <strong className="x-content">Tooltip content</strong>}
69-
overlayInnerStyle={{ background: 'red' }}
70-
>
71-
<div className="target">Click this</div>
72-
</Tooltip>,
73-
);
74-
fireEvent.click(container.querySelector('.target'));
75-
expect(
76-
(container.querySelector('.rc-tooltip-body') as HTMLElement).style.background,
77-
).toEqual('red');
78-
});
62+
7963

8064
it('access of ref', () => {
8165
const domRef = React.createRef<TooltipRef>();
@@ -216,6 +200,87 @@ describe('rc-tooltip', () => {
216200
);
217201
expect(container.querySelector('.rc-tooltip-arrow')).toBeFalsy();
218202
});
203+
204+
it('should merge arrow className from showArrow and classNames.arrow', () => {
205+
const { container } = render(
206+
<Tooltip
207+
trigger={['click']}
208+
placement="left"
209+
overlay={<strong className="x-content">Tooltip content</strong>}
210+
showArrow={{
211+
className: 'from-showArrow',
212+
}}
213+
classNames={{
214+
arrow: 'from-classNames',
215+
}}
216+
visible
217+
>
218+
<div className="target">Click this</div>
219+
</Tooltip>,
220+
);
221+
222+
const arrowElement = container.querySelector('.rc-tooltip-arrow');
223+
expect(arrowElement).toHaveClass('from-showArrow');
224+
expect(arrowElement).toHaveClass('from-classNames');
225+
});
226+
227+
it('should use arrowContent from showArrow object', () => {
228+
const { container } = render(
229+
<Tooltip
230+
trigger={['click']}
231+
placement="left"
232+
overlay={<strong className="x-content">Tooltip content</strong>}
233+
showArrow={{
234+
content: <span className="custom-arrow-content"></span>,
235+
}}
236+
visible
237+
>
238+
<div className="target">Click this</div>
239+
</Tooltip>,
240+
);
241+
242+
expect(container.querySelector('.custom-arrow-content')).toBeTruthy();
243+
expect(container.querySelector('.custom-arrow-content').textContent).toBe('↑');
244+
});
245+
246+
it('should use arrowContent prop when showArrow has no content', () => {
247+
const { container } = render(
248+
<Tooltip
249+
trigger={['click']}
250+
placement="left"
251+
overlay={<strong className="x-content">Tooltip content</strong>}
252+
showArrow
253+
arrowContent={<span className="prop-arrow-content"></span>}
254+
visible
255+
>
256+
<div className="target">Click this</div>
257+
</Tooltip>,
258+
);
259+
260+
expect(container.querySelector('.prop-arrow-content')).toBeTruthy();
261+
expect(container.querySelector('.prop-arrow-content').textContent).toBe('→');
262+
});
263+
264+
it('should prioritize showArrow.content over arrowContent prop', () => {
265+
const { container } = render(
266+
<Tooltip
267+
trigger={['click']}
268+
placement="left"
269+
overlay={<strong className="x-content">Tooltip content</strong>}
270+
showArrow={{
271+
content: <span className="showArrow-content"></span>,
272+
}}
273+
arrowContent={<span className="prop-content"></span>}
274+
visible
275+
>
276+
<div className="target">Click this</div>
277+
</Tooltip>,
278+
);
279+
280+
expect(container.querySelector('.showArrow-content')).toBeTruthy();
281+
expect(container.querySelector('.prop-content')).toBeFalsy();
282+
expect(container.querySelector('.showArrow-content').textContent).toBe('↑');
283+
});
219284
});
220285

221286
it('visible', () => {
@@ -251,33 +316,175 @@ describe('rc-tooltip', () => {
251316

252317
expect(nodeRef.current.nativeElement).toBe(container.querySelector('button'));
253318
});
254-
it('should apply custom styles to Tooltip', () => {
255-
const customClassNames = {
256-
body: 'custom-body',
257-
root: 'custom-root',
258-
};
319+
describe('classNames and styles', () => {
320+
it('should apply custom classNames to all semantic elements', () => {
321+
const customClassNames = {
322+
root: 'custom-root',
323+
body: 'custom-body',
324+
arrow: 'custom-arrow',
325+
};
259326

260-
const customStyles = {
261-
body: { color: 'red' },
262-
root: { backgroundColor: 'blue' },
263-
};
327+
const { container } = render(
328+
<Tooltip
329+
classNames={customClassNames}
330+
overlay={<div>Tooltip content</div>}
331+
visible
332+
showArrow
333+
>
334+
<button>Trigger</button>
335+
</Tooltip>,
336+
);
264337

265-
const { container } = render(
266-
<Tooltip classNames={customClassNames} overlay={<div />} styles={customStyles} visible>
267-
<button />
268-
</Tooltip>,
269-
);
338+
const tooltipElement = container.querySelector('.rc-tooltip') as HTMLElement;
339+
const tooltipBodyElement = container.querySelector('.rc-tooltip-body') as HTMLElement;
340+
const tooltipArrowElement = container.querySelector('.rc-tooltip-arrow') as HTMLElement;
341+
342+
// 验证 classNames
343+
expect(tooltipElement).toHaveClass('custom-root');
344+
expect(tooltipBodyElement).toHaveClass('custom-body');
345+
expect(tooltipArrowElement).toHaveClass('custom-arrow');
346+
});
347+
348+
it('should apply custom styles to all semantic elements', () => {
349+
const customStyles = {
350+
root: { backgroundColor: 'blue', zIndex: 1000 },
351+
body: { color: 'red', fontSize: '14px' },
352+
arrow: { borderColor: 'green' },
353+
};
354+
355+
const { container } = render(
356+
<Tooltip
357+
styles={customStyles}
358+
overlay={<div>Tooltip content</div>}
359+
visible
360+
showArrow
361+
>
362+
<button>Trigger</button>
363+
</Tooltip>,
364+
);
365+
366+
const tooltipElement = container.querySelector('.rc-tooltip') as HTMLElement;
367+
const tooltipBodyElement = container.querySelector('.rc-tooltip-body') as HTMLElement;
368+
const tooltipArrowElement = container.querySelector('.rc-tooltip-arrow') as HTMLElement;
369+
370+
// 验证 styles
371+
expect(tooltipElement.style.backgroundColor).toBe('blue');
372+
expect(tooltipElement.style.zIndex).toBe('1000');
373+
expect(tooltipBodyElement.style.color).toBe('red');
374+
expect(tooltipBodyElement.style.fontSize).toBe('14px');
375+
expect(tooltipArrowElement.style.borderColor).toBe('green');
376+
});
270377

271-
const tooltipElement = container.querySelector('.rc-tooltip') as HTMLElement;
272-
const tooltipBodyElement = container.querySelector('.rc-tooltip-body') as HTMLElement;
378+
it('should apply both classNames and styles simultaneously', () => {
379+
const customClassNames = {
380+
root: 'custom-root',
381+
body: 'custom-body',
382+
arrow: 'custom-arrow',
383+
};
273384

274-
// 验证 classNames
275-
expect(tooltipElement).toHaveClass('custom-root');
276-
expect(tooltipBodyElement).toHaveClass('custom-body');
385+
const customStyles = {
386+
root: { backgroundColor: 'blue' },
387+
body: { color: 'red' },
388+
arrow: { borderColor: 'green' },
389+
};
277390

278-
// 验证 styles
279-
expect(tooltipElement.style.backgroundColor).toBe('blue');
280-
expect(tooltipBodyElement.style.color).toBe('red');
391+
const { container } = render(
392+
<Tooltip
393+
classNames={customClassNames}
394+
styles={customStyles}
395+
overlay={<div>Tooltip content</div>}
396+
visible
397+
showArrow
398+
>
399+
<button>Trigger</button>
400+
</Tooltip>,
401+
);
402+
403+
const tooltipElement = container.querySelector('.rc-tooltip') as HTMLElement;
404+
const tooltipBodyElement = container.querySelector('.rc-tooltip-body') as HTMLElement;
405+
const tooltipArrowElement = container.querySelector('.rc-tooltip-arrow') as HTMLElement;
406+
407+
// 验证 classNames 和 styles 同时生效
408+
expect(tooltipElement).toHaveClass('custom-root');
409+
expect(tooltipElement.style.backgroundColor).toBe('blue');
410+
expect(tooltipBodyElement).toHaveClass('custom-body');
411+
expect(tooltipBodyElement.style.color).toBe('red');
412+
expect(tooltipArrowElement).toHaveClass('custom-arrow');
413+
expect(tooltipArrowElement.style.borderColor).toBe('green');
414+
});
415+
416+
it('should work with partial classNames and styles', () => {
417+
const partialClassNames = {
418+
body: 'custom-body',
419+
};
420+
421+
const partialStyles = {
422+
root: { backgroundColor: 'blue' },
423+
};
424+
425+
const { container } = render(
426+
<Tooltip
427+
classNames={partialClassNames}
428+
styles={partialStyles}
429+
overlay={<div>Tooltip content</div>}
430+
visible
431+
showArrow
432+
>
433+
<button>Trigger</button>
434+
</Tooltip>,
435+
);
436+
437+
const tooltipElement = container.querySelector('.rc-tooltip') as HTMLElement;
438+
const tooltipBodyElement = container.querySelector('.rc-tooltip-body') as HTMLElement;
439+
const tooltipArrowElement = container.querySelector('.rc-tooltip-arrow') as HTMLElement;
440+
441+
// 验证部分配置生效
442+
expect(tooltipElement.style.backgroundColor).toBe('blue');
443+
expect(tooltipBodyElement).toHaveClass('custom-body');
444+
445+
// 验证未配置的不会有自定义类名或样式
446+
expect(tooltipElement).not.toHaveClass('custom-root');
447+
expect(tooltipArrowElement).not.toHaveClass('custom-arrow');
448+
});
449+
450+
it('should not break when showArrow is false', () => {
451+
const customClassNames = {
452+
root: 'custom-root',
453+
body: 'custom-body',
454+
arrow: 'custom-arrow', // 即使配置了arrow,但不显示箭头时不应该报错
455+
};
456+
457+
const customStyles = {
458+
root: { backgroundColor: 'blue' },
459+
body: { color: 'red' },
460+
arrow: { borderColor: 'green' },
461+
};
462+
463+
const { container } = render(
464+
<Tooltip
465+
classNames={customClassNames}
466+
styles={customStyles}
467+
overlay={<div>Tooltip content</div>}
468+
visible
469+
showArrow={false}
470+
>
471+
<button>Trigger</button>
472+
</Tooltip>,
473+
);
474+
475+
const tooltipElement = container.querySelector('.rc-tooltip') as HTMLElement;
476+
const tooltipBodyElement = container.querySelector('.rc-tooltip-body') as HTMLElement;
477+
const tooltipArrowElement = container.querySelector('.rc-tooltip-arrow');
478+
479+
// 验证没有箭头时
480+
expect(tooltipArrowElement).toBeFalsy();
481+
482+
// 其他样式仍然生效
483+
expect(tooltipElement).toHaveClass('custom-root');
484+
expect(tooltipElement.style.backgroundColor).toBe('blue');
485+
expect(tooltipBodyElement).toHaveClass('custom-body');
486+
expect(tooltipBodyElement.style.color).toBe('red');
487+
});
281488
});
282489

283490
describe('children handling', () => {

0 commit comments

Comments
 (0)