Skip to content

Commit d394943

Browse files
authored
fix: unique popup missing className (#570)
1 parent 48ac48e commit d394943

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

src/UniqueProvider/index.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { isDOM } from '@rc-component/util/lib/Dom/findDOMNode';
1515
import FloatBg from './FloatBg';
1616
import classNames from 'classnames';
1717
import MotionContent from './MotionContent';
18+
import { getAlignPopupClassName } from '../util';
1819

1920
export interface UniqueProviderProps {
2021
children: React.ReactNode;
@@ -93,6 +94,26 @@ const UniqueProvider = ({ children }: UniqueProviderProps) => {
9394
false, // isMobile
9495
);
9596

97+
const alignedClassName = React.useMemo(() => {
98+
if (!options) {
99+
return '';
100+
}
101+
102+
const baseClassName = getAlignPopupClassName(
103+
options.builtinPlacements || {},
104+
options.prefixCls || '',
105+
alignInfo,
106+
false, // alignPoint is false for UniqueProvider
107+
);
108+
109+
return classNames(baseClassName, options.getPopupClassNameFromAlign?.(alignInfo));
110+
}, [
111+
alignInfo,
112+
options?.getPopupClassNameFromAlign,
113+
options?.builtinPlacements,
114+
options?.prefixCls,
115+
]);
116+
96117
const contextValue = React.useMemo<UniqueContextProps>(
97118
() => ({
98119
show,
@@ -141,6 +162,7 @@ const UniqueProvider = ({ children }: UniqueProviderProps) => {
141162
}
142163
className={classNames(
143164
options.popupClassName,
165+
alignedClassName,
144166
`${prefixCls}-unique-controlled`,
145167
)}
146168
style={options.popupStyle}

src/context.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export interface UniqueShowOptions {
3131
maskMotion?: CSSMotionProps;
3232
arrow?: ArrowTypeOuter;
3333
getPopupContainer?: TriggerProps['getPopupContainer'];
34+
getPopupClassNameFromAlign?: (align: AlignType) => string;
3435
}
3536

3637
export interface UniqueContextProps {

src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ export function generateTrigger(
331331
maskMotion,
332332
arrow: innerArrow,
333333
getPopupContainer,
334+
getPopupClassNameFromAlign,
334335
id,
335336
}));
336337

tests/unique.test.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,56 @@ describe('Trigger.Unique', () => {
103103
// FloatBg open prop should not have changed during transition (no close animation)
104104
expect(global.openChangeLog).toHaveLength(0);
105105
});
106+
107+
it('should add aligned className to UniqueProvider popup', async () => {
108+
const getPopupClassNameFromAlign = (align: any) => {
109+
return `custom-align-${align.points?.[0] || 'default'}`;
110+
};
111+
112+
const { container } = render(
113+
<UniqueProvider>
114+
<Trigger
115+
action={['click']}
116+
popup={<strong className="x-content">tooltip</strong>}
117+
unique
118+
popupPlacement="bottomLeft"
119+
builtinPlacements={{
120+
bottomLeft: {
121+
points: ['tl', 'bl'],
122+
offset: [0, 4],
123+
overflow: {
124+
adjustX: 0,
125+
adjustY: 1,
126+
},
127+
},
128+
}}
129+
getPopupClassNameFromAlign={getPopupClassNameFromAlign}
130+
>
131+
<div className="target">click me</div>
132+
</Trigger>
133+
</UniqueProvider>,
134+
);
135+
136+
// Initially no popup should be visible
137+
expect(document.querySelector('.rc-trigger-popup')).toBeFalsy();
138+
139+
// Click trigger to show popup
140+
fireEvent.click(container.querySelector('.target'));
141+
await awaitFakeTimer();
142+
143+
// Wait a bit more for alignment to complete
144+
await awaitFakeTimer();
145+
146+
// Check that popup exists
147+
const popup = document.querySelector('.rc-trigger-popup');
148+
expect(popup).toBeTruthy();
149+
expect(popup.querySelector('.x-content').textContent).toBe('tooltip');
150+
151+
// Check that custom className from getPopupClassNameFromAlign is applied
152+
expect(popup.className).toContain('custom-align');
153+
expect(popup.className).toContain('rc-trigger-popup-unique-controlled');
154+
155+
// The base placement className might not be available immediately due to async alignment
156+
// but the custom className should always be applied
157+
});
106158
});

0 commit comments

Comments
 (0)