Skip to content

Commit 5cf3dc6

Browse files
authored
fix: Trigger additional force align for target change (#581)
* chore: re-align when target changed * test: add test case
1 parent 3597803 commit 5cf3dc6

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

src/UniqueProvider/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ export interface UniqueProviderProps {
2222
postTriggerProps?: (options: UniqueShowOptions) => UniqueShowOptions;
2323
}
2424

25-
const UniqueProvider = ({ children, postTriggerProps }: UniqueProviderProps) => {
25+
const UniqueProvider = ({
26+
children,
27+
postTriggerProps,
28+
}: UniqueProviderProps) => {
2629
const [trigger, open, options, onTargetVisibleChanged] = useTargetState();
2730

2831
// ========================== Options ===========================
@@ -144,6 +147,11 @@ const UniqueProvider = ({ children, postTriggerProps }: UniqueProviderProps) =>
144147
[],
145148
);
146149

150+
// =========================== Align ============================
151+
React.useEffect(() => {
152+
onAlign();
153+
}, [mergedOptions?.target]);
154+
147155
// =========================== Motion ===========================
148156
const onPrepare = useEvent(() => {
149157
onAlign();

tests/unique.test.tsx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ describe('Trigger.Unique', () => {
6666
afterEach(() => {
6767
cleanup();
6868
jest.useRealTimers();
69+
jest.restoreAllMocks();
6970
});
7071

7172
it('moving will not hide the popup', async () => {
@@ -285,4 +286,82 @@ describe('Trigger.Unique', () => {
285286
'custom-post-options-class',
286287
);
287288
});
289+
290+
it('should call onAlign when target changes', async () => {
291+
const mockOnAlign = jest.fn();
292+
293+
// Mock useAlign to return our mock onAlign function
294+
const useAlignModule = require('../src/hooks/useAlign');
295+
const originalUseAlign = useAlignModule.default;
296+
297+
jest.spyOn(useAlignModule, 'default').mockImplementation((...args) => {
298+
const originalResult = originalUseAlign(...args);
299+
// Replace onAlign with our mock
300+
return [
301+
originalResult[0], // ready
302+
originalResult[1], // offsetX
303+
originalResult[2], // offsetY
304+
originalResult[3], // offsetR
305+
originalResult[4], // offsetB
306+
originalResult[5], // arrowX
307+
originalResult[6], // arrowY
308+
originalResult[7], // scaleX
309+
originalResult[8], // scaleY
310+
originalResult[9], // alignInfo
311+
mockOnAlign, // onAlign - our mock function
312+
];
313+
});
314+
315+
// Test component with two controlled triggers
316+
const TestComponent = () => {
317+
const [trigger1Open, setTrigger1Open] = React.useState(true);
318+
const [trigger2Open, setTrigger2Open] = React.useState(false);
319+
320+
return (
321+
<div>
322+
<button
323+
className="switch-trigger-btn"
324+
onClick={() => {
325+
// Switch which trigger is open - this changes the target
326+
setTrigger1Open(!trigger1Open);
327+
setTrigger2Open(!trigger2Open);
328+
}}
329+
>
330+
Switch Trigger
331+
</button>
332+
<UniqueProvider>
333+
<Trigger
334+
popupVisible={trigger1Open}
335+
popup={<div>Trigger 1 Popup</div>}
336+
unique
337+
>
338+
<div className="trigger-1">Trigger 1</div>
339+
</Trigger>
340+
<Trigger
341+
popupVisible={trigger2Open}
342+
popup={<div>Trigger 2 Popup</div>}
343+
unique
344+
>
345+
<div className="trigger-2">Trigger 2</div>
346+
</Trigger>
347+
</UniqueProvider>
348+
</div>
349+
);
350+
};
351+
352+
const { container } = render(<TestComponent />);
353+
354+
// Wait for initial render
355+
await awaitFakeTimer();
356+
357+
// Clear any initial calls
358+
mockOnAlign.mockClear();
359+
360+
// Switch triggers - this should change the target and call onAlign
361+
fireEvent.click(container.querySelector('.switch-trigger-btn'));
362+
await awaitFakeTimer();
363+
364+
// Verify onAlign was called due to target change
365+
expect(mockOnAlign).toHaveBeenCalled();
366+
});
288367
});

0 commit comments

Comments
 (0)