Skip to content

Commit 1702c03

Browse files
authored
Merge pull request #153 from istex/fix/148-pane
Fix(sidePanel): Open sidepanel if closed when clicking on a sidenote
2 parents 4fd27b7 + 5f2d97f commit 1702c03

2 files changed

Lines changed: 111 additions & 28 deletions

File tree

packages/react-tei/src/navigation/DocumentNavigationContext.spec.tsx

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,96 @@ describe("DocumentNavigationContextProvider", () => {
344344
);
345345
expect(scrollIntoView).toHaveBeenCalled();
346346
});
347+
348+
it("should open the side panel if it is closed when navigating to a footnote", async () => {
349+
const toggleSection = vi.fn();
350+
const togglePanel = vi.fn();
351+
const { sidePaneElement, wrapper } = createSidePaneWrapper({
352+
state: {
353+
isOpen: false,
354+
sections: {
355+
footnotes: true,
356+
authors: false,
357+
keywords: false,
358+
source: false,
359+
},
360+
},
361+
toggleSection,
362+
togglePanel,
363+
});
364+
const scrollIntoView = vi.fn();
365+
const querySelectorAll = vi.fn().mockImplementation(() => {
366+
const span = document.createElement("span");
367+
span.scrollIntoView = scrollIntoView;
368+
369+
return [span];
370+
});
371+
372+
vi.spyOn(sidePaneElement, "querySelectorAll").mockImplementation(
373+
querySelectorAll,
374+
);
375+
const { result } = await renderHook(() => useDocumentNavigation(), {
376+
wrapper,
377+
});
378+
379+
act(() => {
380+
result.current.navigateToFootnote("footnote-1");
381+
});
382+
expect(togglePanel).toHaveBeenCalled();
383+
expect(querySelectorAll).not.toHaveBeenCalled();
384+
expect(scrollIntoView).not.toHaveBeenCalled();
385+
await new Promise((r) => setTimeout(r, 700)); // wait for the panel and section animation
386+
expect(querySelectorAll).toHaveBeenCalledWith(
387+
'[data-fn-id~="footnote-1"]',
388+
);
389+
expect(scrollIntoView).toHaveBeenCalled();
390+
});
391+
392+
it('should open the side panel and the "footnotes" section if both are closed when navigating to a footnote', async () => {
393+
const toggleSection = vi.fn();
394+
const togglePanel = vi.fn();
395+
const { sidePaneElement, wrapper } = createSidePaneWrapper({
396+
state: {
397+
isOpen: false,
398+
sections: {
399+
footnotes: false,
400+
authors: false,
401+
keywords: false,
402+
source: false,
403+
},
404+
},
405+
toggleSection,
406+
togglePanel,
407+
});
408+
const scrollIntoView = vi.fn();
409+
const querySelectorAll = vi.fn().mockImplementation(() => {
410+
const span = document.createElement("span");
411+
span.scrollIntoView = scrollIntoView;
412+
413+
return [span];
414+
});
415+
416+
vi.spyOn(sidePaneElement, "querySelectorAll").mockImplementation(
417+
querySelectorAll,
418+
);
419+
const { result } = await renderHook(() => useDocumentNavigation(), {
420+
wrapper,
421+
});
422+
423+
act(() => {
424+
result.current.navigateToFootnote("footnote-1");
425+
});
426+
// toggleSection will open both the panel and the section
427+
expect(toggleSection).toHaveBeenCalledWith("footnotes");
428+
expect(togglePanel).not.toHaveBeenCalled();
429+
expect(querySelectorAll).not.toHaveBeenCalled();
430+
expect(scrollIntoView).not.toHaveBeenCalled();
431+
await new Promise((r) => setTimeout(r, 1000)); // wait for the panel and section animation
432+
expect(querySelectorAll).toHaveBeenCalledWith(
433+
'[data-fn-id~="footnote-1"]',
434+
);
435+
expect(scrollIntoView).toHaveBeenCalled();
436+
});
347437
});
348438

349439
describe("navigateToBibliographicReferenceRef", () => {

packages/react-tei/src/navigation/DocumentNavigationContext.tsx

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { createContext, useCallback, useEffect, useMemo, useRef } from "react";
2-
import { useDocumentContext } from "../DocumentContextProvider";
2+
import {
3+
type PanelSection,
4+
useDocumentContext,
5+
} from "../DocumentContextProvider";
36

47
export const DIRECTION_NEXT = "next";
58
export const DIRECTION_PREVIOUS = "previous";
@@ -169,52 +172,42 @@ export function DocumentNavigationContextProvider({
169172
);
170173

171174
const navigateToPanelTargetSelector = useCallback(
172-
(querySelector: string) => {
175+
async (section: PanelSection, querySelector: string) => {
173176
const sidePanelElement = sidePanelRef.current;
174177

175178
if (!sidePanelElement) {
176179
console.error("Side panel element not found");
177180
return;
178181
}
179182

183+
if (!panel.state.sections[section]) {
184+
panel.toggleSection(section);
185+
await new Promise((resolve) => setTimeout(resolve, 600));
186+
} else if (!panel.state.isOpen) {
187+
panel.togglePanel();
188+
await new Promise((resolve) => setTimeout(resolve, 600));
189+
}
190+
180191
navigateToTargetLoop(sidePanelElement, querySelector);
181192
},
182-
[sidePanelRef, navigateToTargetLoop],
193+
[sidePanelRef, navigateToTargetLoop, panel],
183194
);
184195

185196
const navigateToFootnote = useCallback(
186197
(n: string) => {
187-
const selector = buildDataSelector(n, "fn");
188-
189-
if (!panel.state.isOpen || !panel.state.sections.footnotes) {
190-
panel.toggleSection("footnotes");
191-
setTimeout(() => {
192-
navigateToPanelTargetSelector(selector);
193-
}, 600);
194-
return;
195-
}
196-
return navigateToPanelTargetSelector(selector);
198+
navigateToPanelTargetSelector("footnotes", buildDataSelector(n, "fn"));
197199
},
198-
[navigateToPanelTargetSelector, panel],
200+
[navigateToPanelTargetSelector],
199201
);
200202

201203
const navigateToBibliographicReference = useCallback(
202204
(id: string) => {
203-
const selector = buildDataSelector(id, "bibref");
204-
205-
if (
206-
!panel.state.isOpen ||
207-
!panel.state.sections.bibliographicReferences
208-
) {
209-
panel.toggleSection("bibliographicReferences");
210-
setTimeout(() => {
211-
navigateToPanelTargetSelector(selector);
212-
}, 600);
213-
return;
214-
}
215-
return navigateToPanelTargetSelector(selector);
205+
return navigateToPanelTargetSelector(
206+
"bibliographicReferences",
207+
buildDataSelector(id, "bibref"),
208+
);
216209
},
217-
[navigateToPanelTargetSelector, panel],
210+
[navigateToPanelTargetSelector],
218211
);
219212

220213
const navigateToFootnoteRef = useCallback(

0 commit comments

Comments
 (0)