diff --git a/src/components/Viewer/Media/Media.test.tsx b/src/components/Viewer/Media/Media.test.tsx
index 25886cb4..811585ce 100644
--- a/src/components/Viewer/Media/Media.test.tsx
+++ b/src/components/Viewer/Media/Media.test.tsx
@@ -1,12 +1,53 @@
+import { render, screen } from "@testing-library/react";
+
+import { Canvas } from "@iiif/presentation-3";
import Media from "src/components/Viewer/Media/Media";
import React from "react";
-import { render, screen } from "@testing-library/react";
+
+const items = [
+ {
+ id: "https://example.org/manifest/1/canvas/1",
+ type: "Canvas",
+ height: 600,
+ width: 800,
+ label: { none: ["Canvas 1"] },
+ thumbnail: [
+ {
+ id: "https://example.org/item/1/default.jpg",
+ type: "Image",
+ height: 75,
+ width: 100,
+ format: "image/jpeg",
+ },
+ ],
+ },
+ {
+ id: "https://example.org/manifest/1/canvas/2",
+ type: "Canvas",
+ height: 600,
+ width: 800,
+ label: { none: ["Canvas 2"] },
+ thumbnail: [
+ {
+ id: "https://example.org/item/2/default.jpg",
+ type: "Image",
+ height: 75,
+ width: 100,
+ format: "image/jpeg",
+ },
+ ],
+ },
+] as unknown as Canvas[];
describe("Media component", () => {
it("renders", () => {
- render();
+ render();
const media = screen.getByTestId("media");
expect(media);
expect(media.hasAttribute("aria-label")).toBe(true);
+ expect(media.getAttribute("data-active-canvas")).toBe(
+ "https://example.org/manifest/1/canvas/1",
+ );
+ expect(media.getAttribute("data-canvas-length")).toBe("2");
});
});
diff --git a/src/components/Viewer/Media/Media.tsx b/src/components/Viewer/Media/Media.tsx
index 970f1e18..2c134ba0 100644
--- a/src/components/Viewer/Media/Media.tsx
+++ b/src/components/Viewer/Media/Media.tsx
@@ -95,25 +95,33 @@ const Media: React.FC = ({ items }) => {
handleFilter={handleFilter}
handleCanvasToggle={handleCanvasToggle}
activeIndex={activeIndex}
- canvasLength={mediaItems.length}
+ canvasLength={items.length}
/>
{mediaItems
- .filter((item) => {
+ .filter((item, key) => {
+ if (!filter) return true;
+
if (item.canvas?.label) {
const label = getLabel(item.canvas.label);
if (Array.isArray(label))
return label[0].toLowerCase().includes(filter.toLowerCase());
+ } else {
+ const label = (key + 1).toString();
+ return label.includes(filter);
}
})
.map((item, index) => (
el === item)}
handleChange={handleChange}
isActive={activeCanvas === item?.canvas?.id ? true : false}
key={item?.canvas?.id}
diff --git a/src/components/Viewer/Media/Thumbnail.test.tsx b/src/components/Viewer/Media/Thumbnail.test.tsx
index 9f57c2dc..cfd2e76a 100644
--- a/src/components/Viewer/Media/Thumbnail.test.tsx
+++ b/src/components/Viewer/Media/Thumbnail.test.tsx
@@ -92,6 +92,20 @@ describe("Thumbnail component", () => {
});
});
+ describe("figure missing a label", () => {
+ const newProps = { ...props, canvas: { ...props.canvas, label: null } };
+
+ it("renders a fallback label for item index + 1", () => {
+ render(
+
+
+ ,
+ );
+ expect(screen.getByTestId("fig-caption")).toHaveTextContent("2");
+ expect(screen.getByAltText("2"));
+ });
+ });
+
describe("audio and video thumbnail types", () => {
it("renders a duration value in the tag for audio type", () => {
const newProps = { ...props, type: "Sound" };
diff --git a/src/components/Viewer/Media/Thumbnail.tsx b/src/components/Viewer/Media/Thumbnail.tsx
index 7e98cf94..7428fe04 100644
--- a/src/components/Viewer/Media/Thumbnail.tsx
+++ b/src/components/Viewer/Media/Thumbnail.tsx
@@ -55,6 +55,10 @@ const Thumbnail: React.FC = ({
type,
handleChange,
}) => {
+ const label = canvas?.label
+ ? getLabel(canvas.label)
+ : (canvasIndex + 1).toString();
+
return (
- = ({
>
);