Skip to content

Commit 0c57d4f

Browse files
committed
Fix spacing and tests from react-window Grid change
1 parent 1a93d6b commit 0c57d4f

5 files changed

Lines changed: 59 additions & 105 deletions

File tree

__tests__/src/components/CompanionWindowFactory.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ describe('CompanionWindowFactory', () => {
6262
content: 'thumbnailNavigation',
6363
});
6464

65-
expect(screen.getByRole('grid')).toHaveAccessibleName('Thumbnails');
65+
expect(screen.getByLabelText('Thumbnails')).toBeInTheDocument();
6666
});
6767
});
6868

__tests__/src/components/ThumbnailCanvasGrouping.test.js

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ describe('ThumbnailCanvasGrouping', () => {
3838
setCanvas = vi.fn();
3939
wrapper = createWrapper({ setCanvas });
4040
});
41-
const spyCurrentCanvasClass = vi.spyOn(
42-
ThumbnailCanvasGrouping.prototype,
43-
'currentCanvasClass',
44-
);
41+
const spyCurrentCanvasClass = vi.spyOn(ThumbnailCanvasGrouping.prototype, 'currentCanvasClass');
4542
afterEach(() => {
4643
spyCurrentCanvasClass.mockClear();
4744
});
@@ -55,19 +52,15 @@ describe('ThumbnailCanvasGrouping', () => {
5552
wrapper.unmount();
5653
const user = userEvent.setup();
5754
wrapper = createWrapper({ index: 0, setCanvas });
58-
await user.click(
59-
wrapper.container.querySelector('.mirador-thumbnail-nav-canvas-0'), // eslint-disable-line testing-library/no-node-access
60-
);
55+
await user.click(wrapper.container.querySelector('.mirador-thumbnail-nav-canvas-0')); // eslint-disable-line testing-library/no-node-access
6156
expect(spyCurrentCanvasClass).toHaveBeenCalledWith([0]);
6257
expect(spyCurrentCanvasClass).toHaveReturnedWith('current-canvas-grouping');
63-
expect(setCanvas).toHaveBeenCalledWith(
64-
'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json',
65-
);
58+
expect(setCanvas).toHaveBeenCalledWith('http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json');
6659
});
6760
describe('attributes based off far-bottom position', () => {
6861
it('in button div', () => {
6962
expect(screen.getByRole('button', { name: 'Image 1' })).toHaveStyle({
70-
height: '123px',
63+
height: '119px',
7164
width: 'auto',
7265
});
7366
});

__tests__/src/components/ThumbnailNavigation.test.js

Lines changed: 37 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -42,36 +42,49 @@ describe('ThumbnailNavigation', () => {
4242
expect(screen.getAllByRole('gridcell').length).toEqual(3);
4343
});
4444

45+
it('uses Grid component for horizontal (far-bottom) layout', () => {
46+
render(<Subject position="far-bottom" />);
47+
// Grid component renders with role="grid" inside the Thumbnails wrapper
48+
const thumbnailWrapper = screen.getByLabelText('Thumbnails');
49+
const grid = thumbnailWrapper.querySelector('[role="grid"]');
50+
expect(grid).toBeInTheDocument();
51+
// Grid should have 3 gridcells (all in one row)
52+
expect(screen.getAllByRole('gridcell')).toHaveLength(3);
53+
});
54+
55+
it('uses List component for vertical (far-right) layout', () => {
56+
render(<Subject position="far-right" />);
57+
// List component renders with role="list" inside the Thumbnails wrapper
58+
const thumbnailWrapper = screen.getByLabelText('Thumbnails');
59+
const list = thumbnailWrapper.querySelector('[role="list"]');
60+
expect(list).toBeInTheDocument();
61+
// List should have 3 gridcells (each as a separate item)
62+
expect(screen.getAllByRole('gridcell')).toHaveLength(3);
63+
});
64+
4565
// TODO: Test that we recalculate dimensions when the view changes (resetAfterIndex)
4666
// TODO: Test that the window scrolls when the canvasIndex prop changes (scorllToItem)
4767

4868
it('gives the grid a size', () => {
4969
const { rerender } = render(<Subject />);
50-
expect(screen.getByRole('grid')).toHaveStyle({
51-
height: '150px',
52-
width: '100%',
53-
});
70+
expect(screen.getByLabelText('Thumbnails')).toHaveStyle({ height: '150px', width: '100%' });
5471

5572
rerender(<Subject position="far-right" />);
56-
expect(screen.getByRole('grid')).toHaveStyle({
57-
height: '100%',
58-
minHeight: 0,
59-
width: '123px',
60-
});
73+
expect(screen.getByLabelText('Thumbnails')).toHaveStyle({ height: '100%', minHeight: 0, width: '127px' });
6174
});
6275

6376
it('roughly doubles the width of the grid in book view', () => {
6477
const { rerender } = render(<Subject position="far-right" />);
65-
expect(screen.getByRole('grid')).toHaveStyle({ width: '123px' });
78+
expect(screen.getByLabelText('Thumbnails')).toHaveStyle({ width: '127px' });
6679

6780
rerender(<Subject position="far-right" view="book" />);
68-
expect(screen.getByRole('grid')).toHaveStyle({ width: '223px' });
81+
expect(screen.getByLabelText('Thumbnails')).toHaveStyle({ width: '227px' });
6982
});
7083

7184
it('calculates the scaled width of each cell', () => {
7285
render(<Subject />);
7386

74-
expect(screen.getAllByRole('gridcell')[0]).toHaveStyle({ width: '74px' });
87+
expect(screen.getAllByRole('gridcell')[0]).toHaveStyle({ width: '111px' });
7588
});
7689

7790
it('calculates the scaled height of each cell when on the right', () => {
@@ -82,7 +95,7 @@ describe('ThumbnailNavigation', () => {
8295
it('keeps a minimum size for each cell', () => {
8396
render(<Subject fixture={zeroWidthFixture} />);
8497

85-
expect(screen.getAllByRole('gridcell')[0]).toHaveStyle({ width: '100px' });
98+
expect(screen.getAllByRole('gridcell')[0]).toHaveStyle({ width: '111px' });
8699
});
87100

88101
it('keeps a minimum size for each cell when on the right', () => {
@@ -97,69 +110,31 @@ describe('ThumbnailNavigation', () => {
97110

98111
describe('handleKeyUp', () => {
99112
it('handles right arrow by advancing the current canvas', async () => {
100-
render(
101-
<Subject
102-
canvasIndex={1}
103-
hasNextCanvas
104-
setNextCanvas={setNextCanvas}
105-
/>,
106-
);
113+
render(<Subject canvasIndex={1} hasNextCanvas setNextCanvas={setNextCanvas} />);
107114

108115
screen.getByRole('grid').focus();
109-
fireEvent.keyDown(screen.getByRole('grid'), {
110-
code: 'ArrowRight',
111-
key: 'ArrowRight',
112-
});
116+
fireEvent.keyDown(screen.getByRole('grid'), { code: 'ArrowRight', key: 'ArrowRight' });
113117
expect(setNextCanvas).toHaveBeenCalled();
114118
});
115119
it('handles down arrow by advancing the current canvas when the canvas is on the right', () => {
116-
render(
117-
<Subject
118-
canvasIndex={1}
119-
hasNextCanvas
120-
position="far-right"
121-
setNextCanvas={setNextCanvas}
122-
/>,
123-
);
120+
render(<Subject canvasIndex={1} hasNextCanvas position="far-right" setNextCanvas={setNextCanvas} />);
124121

125-
screen.getByRole('grid').focus();
126-
fireEvent.keyDown(screen.getByRole('grid'), {
127-
code: 'ArrowDown',
128-
key: 'ArrowDown',
129-
});
122+
screen.getByLabelText('Thumbnails').focus();
123+
fireEvent.keyDown(screen.getByLabelText('Thumbnails'), { code: 'ArrowDown', key: 'ArrowDown' });
130124
expect(setNextCanvas).toHaveBeenCalled();
131125
});
132126
it('handles left arrow by selecting the previous canvas', () => {
133-
render(
134-
<Subject
135-
canvasIndex={2}
136-
hasPreviousCanvas
137-
setPreviousCanvas={setPreviousCanvas}
138-
/>,
139-
);
127+
render(<Subject canvasIndex={2} hasPreviousCanvas setPreviousCanvas={setPreviousCanvas} />);
140128

141-
screen.getByRole('grid').focus();
142-
fireEvent.keyDown(screen.getByRole('grid'), {
143-
code: 'ArrowLeft',
144-
key: 'ArrowLeft',
145-
});
129+
screen.getByLabelText('Thumbnails').focus();
130+
fireEvent.keyDown(screen.getByLabelText('Thumbnails'), { code: 'ArrowLeft', key: 'ArrowLeft' });
146131
expect(setPreviousCanvas).toHaveBeenCalled();
147132
});
148133
it('handles up arrow by selecting the previous canvas when the canvas is on the right', () => {
149-
render(
150-
<Subject
151-
canvasIndex={2}
152-
hasPreviousCanvas
153-
position="far-right"
154-
setPreviousCanvas={setPreviousCanvas}
155-
/>,
156-
);
134+
render(<Subject canvasIndex={2} hasPreviousCanvas position="far-right" setPreviousCanvas={setPreviousCanvas} />);
157135

158-
screen.getByRole('grid').focus();
159-
fireEvent.keyDown(screen.getByRole('grid'), {
160-
code: 'ArrowUp',
161-
key: 'ArrowUp',
162-
});
136+
screen.getByLabelText('Thumbnails').focus();
137+
fireEvent.keyDown(screen.getByLabelText('Thumbnails'), { code: 'ArrowUp', key: 'ArrowUp' });
163138
expect(setPreviousCanvas).toHaveBeenCalled();
164139
});
165140
});

src/components/ThumbnailCanvasGrouping.jsx

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ export class ThumbnailCanvasGrouping extends PureComponent {
5353
const currentGroupings = canvasGroupings[itemIndex];
5454
const SPACING = 12;
5555

56-
// In react-window v2 horizontal lists, width is not provided in style
57-
// The height value in style is actually the width for horizontal lists
56+
// In react-window v2 Grid (horizontal layout), columnWidth is passed as style.height
57+
// For List (vertical layout), rowHeight is passed as style.height
5858
const isHorizontal = position === 'far-bottom';
5959
let calculatedWidth = null;
6060
if (isHorizontal && style.height) {
@@ -72,9 +72,7 @@ export class ThumbnailCanvasGrouping extends PureComponent {
7272
style={{
7373
...style,
7474
boxSizing: 'content-box',
75-
height: Number.isInteger(style.height)
76-
? style.height - SPACING
77-
: null,
75+
height: Number.isInteger(style.height) ? style.height - SPACING : null,
7876
left: Number.isInteger(style.left) ? style.left + SPACING / 2 : null,
7977
padding: SPACING / 2,
8078
top: Number.isInteger(style.top) ? style.top + SPACING / 2 : null,
@@ -109,25 +107,15 @@ export class ThumbnailCanvasGrouping extends PureComponent {
109107
width: position === 'far-bottom' ? 'auto' : `${style.width}px`,
110108
})}
111109
className={classNames(
112-
ns([
113-
'thumbnail-nav-canvas',
114-
`thumbnail-nav-canvas-${itemIndex}`,
115-
this.currentCanvasClass(
116-
currentGroupings.map(canvas => canvas.index),
117-
),
118-
]),
110+
ns(['thumbnail-nav-canvas', `thumbnail-nav-canvas-${itemIndex}`, this.currentCanvasClass( currentGroupings.map(canvas => canvas.index))]),
119111
)}
120112
>
121113
{currentGroupings.map((canvas, i) => (
122114
<IIIFThumbnail
123115
key={canvas.id}
124116
resource={canvas}
125117
labelled={showThumbnailLabels}
126-
maxHeight={
127-
position === 'far-right'
128-
? style.height - 1.5 * SPACING
129-
: height - 1.5 * SPACING
130-
}
118+
maxHeight={(position === 'far-right') ? style.height - (1.5 * SPACING) : height - (1.5 * SPACING)}
131119
variant="inside"
132120
/>
133121
))}

src/components/ThumbnailNavigation.jsx

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export function ThumbnailNavigation({
2424
}) {
2525
const { t } = useTranslation();
2626
const scrollbarSize = 15;
27-
const spacing = 8; // 2 * (2px margin + 2px border + 2px padding + 2px padding)
27+
const spacing = 12; // 2 * (2px margin + 2px border + 2px padding + 2px padding)
2828
const gridRef = useRef();
2929
const previousView = useRef(view);
3030
const canvasWorlds = useCanvasWorldService();
@@ -68,7 +68,7 @@ export function ThumbnailNavigation({
6868
}, [canvasIndex]);
6969

7070
/** */
71-
const handleKeyDown = e => {
71+
const handleKeyDown = (e) => {
7272
let nextKey = 'ArrowRight';
7373
let previousKey = 'ArrowLeft';
7474
if (position === 'far-right') {
@@ -91,7 +91,7 @@ export function ThumbnailNavigation({
9191
* When on right, row height
9292
* When on bottom, column width
9393
*/
94-
const calculateScaledSize = index => {
94+
const calculateScaledSize = (index) => {
9595
const canvases = canvasGroupings[index];
9696
if (!canvases) return thumbnailNavigation.width + spacing;
9797

@@ -100,7 +100,7 @@ export function ThumbnailNavigation({
100100
switch (position) {
101101
case 'far-right': {
102102
const calc = Math.floor(
103-
(calculatingWidth(canvases.length) * bounds[3]) / bounds[2],
103+
calculatingWidth(canvases.length) * bounds[3] / bounds[2]
104104
);
105105
if (!Number.isInteger(calc)) return thumbnailNavigation.width + spacing;
106106
return calc + spacing;
@@ -109,17 +109,16 @@ export function ThumbnailNavigation({
109109
default: {
110110
if (bounds[3] === 0) return thumbnailNavigation.width + spacing;
111111
const calc = Math.ceil(
112-
((thumbnailNavigation.height - scrollbarSize - spacing - 4)
113-
* bounds[2])
114-
/ bounds[3],
112+
(thumbnailNavigation.height - scrollbarSize - spacing - 4)
113+
* bounds[2] / bounds[3],
115114
);
116115
return calc;
117116
}
118117
}
119118
};
120119

121120
/** */
122-
const calculatingWidth = canvasesLength => {
121+
const calculatingWidth = (canvasesLength) => {
123122
if (canvasesLength === 1) {
124123
return thumbnailNavigation.width;
125124
}
@@ -128,9 +127,7 @@ export function ThumbnailNavigation({
128127

129128
/** */
130129
const style = useCallback(() => {
131-
const width = view === 'book'
132-
? thumbnailNavigation.width * 2
133-
: thumbnailNavigation.width;
130+
const width = view === 'book' ? thumbnailNavigation.width * 2 : thumbnailNavigation.width;
134131

135132
switch (position) {
136133
case 'far-right':
@@ -172,7 +169,9 @@ export function ThumbnailNavigation({
172169
};
173170
return (
174171
<Paper
175-
className={classNames(ns('thumb-navigation'))}
172+
className={classNames(
173+
ns('thumb-navigation'),
174+
)}
176175
sx={{
177176
'&:focus': {
178177
boxShadow: 0,
@@ -185,10 +184,9 @@ export function ThumbnailNavigation({
185184
style={style()}
186185
tabIndex={0}
187186
onKeyDown={handleKeyDown}
188-
role="grid"
189187
ref={paperRef}
190188
>
191-
<div role="row" style={{ height: '100%', width: '100%' }}>
189+
<div style={{ height: '100%', width: '100%' }}>
192190
{canvasGroupings.length > 0 && position === 'far-bottom' && (
193191
<Grid
194192
columnCount={canvasGroupings.length}

0 commit comments

Comments
 (0)