Skip to content

Commit

Permalink
Update orientation of annotations, search method.
Browse files Browse the repository at this point in the history
  • Loading branch information
mathewjordan committed Nov 18, 2024
1 parent b186d99 commit 48cb271
Show file tree
Hide file tree
Showing 19 changed files with 468 additions and 202 deletions.
44 changes: 40 additions & 4 deletions src/components/Scroll/Annotation/Body.styled.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { styled } from "src/styles/stitches.config";
import { text } from "stream/consumers";

const highlightColor = "255, 197, 32"; // #FFC520

const TextualBody = styled("div", {
"&[dir=rtl]": {
textAlign: "right",
},

ul: {
padding: "1rem",
},
Expand All @@ -15,10 +20,41 @@ const TextualBody = styled("div", {
},
},

"span.highlight": {
"span.clover-scroll-highlight": {
position: "relative",
fontWeight: "bold",

"&.active": {
"&::before": {
top: "0",
position: "absolute",
display: "inline",
content: "",
width: "calc(100% + 4px)",
height: "calc(100% + 2px) ",
marginLeft: "-2px",
borderRadius: "3px",
border: `1px solid rgba(${highlightColor}, 0.2)`,
borderBottom: `1px solid rgba(${highlightColor}, 0.618)`,
boxShadow: `1px 1px 1px #6661`,
},

"&::after": {
left: "0",
top: "0",
position: "absolute",
display: "inline",
content: "",
width: "calc(100% + 4px)",
height: "calc(100% + 2px) ",
marginLeft: "-2px",
marginTop: "-1px",
borderRadius: "3px",
backgroundColor: `rgba(${highlightColor}, 0.2)`,
zIndex: -1,
},
},

"&::before": {
top: "0",
position: "absolute",
Expand All @@ -28,8 +64,8 @@ const TextualBody = styled("div", {
height: "calc(100% + 2px) ",
marginLeft: "-2px",
borderRadius: "3px",
border: `1px solid rgba(${highlightColor}, 0.2)`,
borderBottom: `1px solid rgba(${highlightColor}, 0.618)`,
border: `1px solid #6663`,
borderBottom: `1px solid #6664`,
boxShadow: `1px 1px 1px #6661`,
},

Expand All @@ -44,7 +80,7 @@ const TextualBody = styled("div", {
marginLeft: "-2px",
marginTop: "-1px",
borderRadius: "3px",
backgroundColor: `rgba(${highlightColor}, 0.2)`,
backgroundColor: `#6661`,
zIndex: -1,
},
},
Expand Down
53 changes: 38 additions & 15 deletions src/components/Scroll/Annotation/Body.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext } from "react";
import React, { useContext, useEffect } from "react";

import { EmbeddedResource } from "@iiif/presentation-3";
import { ScrollContext } from "src/context/scroll-context";
Expand All @@ -8,15 +8,17 @@ import useMarkdown from "@nulib/use-markdown";

const ScrollAnnotationBody = ({
body,
numItems = 1,
stringLength,
type = "content",
}: {
body: EmbeddedResource;
numItems?: number;
stringLength?: number;
type?: string;
}) => {
const { state } = useContext(ScrollContext);
const { searchString } = state;
const { searchActiveMatch, searchString } = state;

let value = String(body.value);

Expand Down Expand Up @@ -48,30 +50,51 @@ const ScrollAnnotationBody = ({
}

// Highlighting the searchString
if (searchString && innerHtml) {
if (String(searchString) && innerHtml) {
let matchCount = 1;
const regex = new RegExp(`(${searchString})`, "gi");
innerHtml = innerHtml?.replace(
regex,
(match) => `<span class="highlight">${match}</span>`,
);
innerHtml = innerHtml?.replace(regex, (match) => {
const matchId = `${body.id}/${matchCount}`;
const isActive = searchActiveMatch === matchId;
matchCount += 1;
return `<span class="clover-scroll-highlight${isActive ? ` active` : ``}" data-index="${matchId}">${match}</span>`;
});
}

const id = [body.id, type].join("-");
const isRtl = ["ar"].includes(String(body.language));
const dir = isRtl ? "rtl" : "ltr";
const fontSize = isRtl ? "1.3em" : "1em";

useEffect(() => {
// Scroll to the active match
if (searchActiveMatch) {
const activeElement = document.querySelector(
`[data-index="${searchActiveMatch}"]`,
) as HTMLElement;
if (activeElement)
activeElement.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "center",
});
}
}, [searchActiveMatch]);

if (!innerHtml) return null;

return (
<TextualBody
dangerouslySetInnerHTML={{ __html: innerHtml }}
data-body-id={id}
data-testid="scroll-item-body"
id={id}
dir={dir}
css={{ fontSize }}
/>
<>
<TextualBody
dangerouslySetInnerHTML={{ __html: innerHtml }}
data-body-id={id}
data-testid="scroll-item-body"
style={{ "--num-items": numItems } as React.CSSProperties}
id={id}
dir={dir}
css={{ fontSize }}
/>
</>
);
};

Expand Down
1 change: 1 addition & 0 deletions src/components/Scroll/Figure/Figure.styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const StyledFigure = styled("figure", {
flexDirection: "column",
margin: "1.618rem 0 0",
opacity: 0.9,
gap: "0.382rem",

em: {
fontSize: "0.9em",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Scroll/Figure/ImageViewer.styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { styled } from "src/styles/stitches.config";

const StyledImageViewer = styled("div", {
width: "100%",
height: "400px",
height: "360px",
background: "#6662",
backgroundSize: "contain",
color: "white",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Scroll/Figure/ImageViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ const ImageViewer: React.FC<ImageViewerProps> = ({ body, label }) => {
);
};

export default ImageViewer;
export default React.memo(ImageViewer);
40 changes: 20 additions & 20 deletions src/components/Scroll/Items/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,18 @@ const ScrollItem: React.FC<ScrollItemProps> = ({

const canvas: CanvasNormalized | undefined = vault?.get(item);

const numItems = annotations?.filter(
(annotation) => annotation.target === item.id,
).length;

const annotationBody = annotations
?.filter((annotation) => annotation.target === item.id)
?.map((annotation) => {
return annotation?.body?.map((body, index) => (
<ScrollItemBody
body={body as unknown as EmbeddedResource}
key={index}
numItems={numItems}
/>
));
});
Expand All @@ -55,26 +60,21 @@ const ScrollItem: React.FC<ScrollItemProps> = ({
};

return (
<StyledItem
data-page-break={hasItemBreak}
data-page-number={itemNumber}
data-last-item={isLastItem}
>
<StyledItemFigure>
{canvas && <ScrollFigure canvas={canvas} canvasInfo={canvasInfo} />}
</StyledItemFigure>
<StyledItemTextualBodies>
{canvas?.label && (
<strong>
<Label label={canvas?.label} />{" "}
{`(${canvasInfo.current} / ${canvasInfo.total})`}
</strong>
)}
<div>{annotationBody ? annotationBody : <p>[Blank]</p>}</div>

{hasItemBreak && <PageBreak aria-label="Page Break" />}
</StyledItemTextualBodies>
</StyledItem>
<>
<StyledItem
data-page-break={hasItemBreak}
data-page-number={itemNumber}
data-last-item={isLastItem}
>
<StyledItemFigure>
{canvas && <ScrollFigure canvas={canvas} canvasInfo={canvasInfo} />}
</StyledItemFigure>
<StyledItemTextualBodies>
<div>{annotationBody?.length ? annotationBody : <p>[Blank]</p>}</div>
</StyledItemTextualBodies>
</StyledItem>
{hasItemBreak && <PageBreak aria-label="Page Break" />}
</>
);
};

Expand Down
25 changes: 16 additions & 9 deletions src/components/Scroll/Items/Items.styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,37 @@ const StyledItem = styled("article", {

const StyledItemFigure = styled("div", {
transition: "$all",
width: "50%",
opacity: 0,
transform: "translateX(2.618rem)",
zIndex: -1,
width: "38.2%",
});

const StyledItemTextualBodies = styled("div", {
width: "50%",
width: "61.8%",
display: "flex",
flexDirection: "column",
justifyContent: "flex-start",

"> div": {
display: "flex",
flexDirection: "row",
gap: "2.618rem",

"> div": {
width: "calc(100% / var(--num-items))",
boxSizing: "border-box",
},
},
});

const PageBreak = styled("hr", {
margin: "0",
borderColor: "transparent",
height: "1.618rem",
position: "relative",
width: "61.8%",
zIndex: 0,
marginLeft: "38.2%",
display: "flex",
justifyContent: "flex-end",
marginTop: "2.618rem",

"&::before": {
content: "attr(aria-label)",
Expand All @@ -49,7 +58,7 @@ const PageBreak = styled("hr", {

"&::after": {
content: "",
width: "100%",
width: "calc(100% - 2.618em)",
position: "absolute",
zIndex: 0,
height: "1px",
Expand All @@ -58,8 +67,6 @@ const PageBreak = styled("hr", {
});

const StyledScrollItems = styled("div", {
position: "relative",
zIndex: "1",
display: "flex",
flexDirection: "column",
gap: "2.618rem",
Expand Down
10 changes: 1 addition & 9 deletions src/components/Scroll/Items/Items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,12 @@ import React, { useState } from "react";

import { Reference } from "@iiif/presentation-3";
import ScrollItem from "src/components/Scroll/Items/Item";
import ScrollPanel from "src/components/Scroll/Panel/Panel";
import { StyledScrollItems } from "src/components/Scroll/Items/Items.styled";

const ScrollItems = ({ items }: { items: Reference<"Canvas">[] }) => {
const [isPanelExpanded, setIsPanelExpanded] = useState(false);

const handlePanel = (status) => setIsPanelExpanded(status);
return (
<>
<ScrollPanel
isPanelExpanded={isPanelExpanded}
handlePanel={handlePanel}
/>
<StyledScrollItems data-figures-visible={!isPanelExpanded}>
<StyledScrollItems>
{items.map((item, index) => {
const itemNumber = index + 1;
const isLastItem = itemNumber === items.length;
Expand Down
Loading

0 comments on commit 48cb271

Please sign in to comment.