Skip to content

Commit

Permalink
Improvements to figure modal.
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvarner committed Aug 6, 2024
1 parent 8d37d6f commit bd78dfe
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 101 deletions.
2 changes: 1 addition & 1 deletion app/components/ScrollytellWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export default function ScrollytellWrapper({
try {
scrollerRef.current?.resize();
} catch (error) {
console.error("file: Consent.tsx:38 ~ useEffect ~ error:", error);
return;
}
}, [documentSize]);

Expand Down
2 changes: 1 addition & 1 deletion app/components/figures/Figure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface Props {
export const Caption = ({ figure, className }: Props) => {
return (
<figcaption
className={`font-neueMontreal text-sm leading-5 text-left mt-3 md:mt-6 mb-6 md:mb-12 col-span-full ${
className={`font-neueMontreal text-xs md:text-sm leading-5 text-left mt-3 md:mt-6 mb-6 md:mb-12 col-span-full ${
className ?? ""
}`}
dangerouslySetInnerHTML={{
Expand Down
153 changes: 69 additions & 84 deletions app/components/figures/FigureModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import {
Disclosure,
DisclosureButton,
DisclosurePanel,
Transition,
TransitionChild,
} from "@headlessui/react";
import { classNames } from "~/utils";
import { Caption } from "./Figure";
Expand Down Expand Up @@ -38,7 +36,7 @@ export default function FigureModal({
}: Props) {
const { backgroundColor, accentColor, hideSensitiveState } =
useContext(ChapterContext);
const [open, setOpen] = useState(false);
const [isOpen, setIsOpen] = useState(false);
const [interactiveOptions, setInteractiveOptions] = useState<object>({});
const figureRef = useRef<HTMLDivElement>(null);
// FIXME: There has to be better way?
Expand All @@ -50,113 +48,100 @@ export default function FigureModal({
setInteractiveOptions({
onClick: ({ target }: { target: HTMLElement }) => {
if (target.classList.contains("modal-backdrop")) {
setOpen(false);
setIsOpen(false);
} else {
setOpen(true);
setIsOpen(true);
}
},
onKeyDown: ({ key }: { key: string }) => {
if (key === "Enter") setOpen(true);
if (key === "Enter") setIsOpen(true);
},
role: "button",
tabIndex: 0,
});
} else {
setInteractiveOptions({});
}
}, [hideSensitiveState, figure, setOpen, setInteractiveOptions]);

const handleClose = () => {
setOpen(false);
};
}, [hideSensitiveState, figure, setIsOpen, setInteractiveOptions]);

return (
<div
ref={figureRef}
id={id}
className={classNames(
"md:mx-auto relative z-10",
"md:mx-auto relative",
inColumn ? "md:ml-24" : "md:mt-8",
className
)}
{...interactiveOptions}
>
{children}

<Transition appear show={open}>
<Dialog as="div" className="relative z-50" onClose={handleClose}>
<div className="fixed inset-0 bg-black/30" aria-hidden="true" />
<div className="fixed inset-0 z-40 overflow-y-auto">
<div className="flex min-h-full justify-center p-2 md:p-4 text-center items-center modal-backdrop">
<TransitionChild
enter="ease-out duration-300"
enterFrom="opacity-0 transform-[scale(95%)]"
enterTo="opacity-100 transform-[scale(100%)]"
leave="ease-in duration-200"
leaveFrom="opacity-100 transform-[scale(100%)]"
leaveTo="opacity-0 transform-[scale(95%)]"
>
<DialogPanel className="space-y-4 w-screen md:w-1/2 lg:w-[66vw] border bg-white p-6 rounded-xl">
<DialogTitle as="div" className="flex justify-end">
{figure?.title && (
<div
className="text-lg font-medium leading-6 text-gray-900 grow self-center px-3"
dangerouslySetInnerHTML={{
__html: figure.title,
}}
/>
<Dialog
as="div"
className="fixed inset-0 flex w-screen items-center justify-center bg-black/30 p-4 transition duration-300 ease-out data-[closed]:opacity-0 z-50"
open={isOpen}
transition
onClose={() => setIsOpen(false)}
>
<div className="fixed inset-0 w-screen overflow-y-auto p-4">
<div className="flex min-h-full items-center justify-center modal-backdrop">
<DialogPanel className="space-y-4 w-screen md:w-1/2 lg:w-[66vw] border bg-offblack text-white p-6 rounded-xl">
<DialogTitle as="div" className="flex justify-end">
{figure?.title && (
<div
className="text-sm md:text-lg font-medium leading-6 grow self-center px-3"
dangerouslySetInnerHTML={{
__html: figure.title,
}}
/>
)}
<Button onClick={() => setIsOpen(false)} className="self-start">
<Close className="hover:text-offwhite text-offwhite hover:fill-offblack" />
</Button>
</DialogTitle>
<div className="flex flex-col justify-between">
<ClientOnly>
{() => <IIIFViewer figure={figure} modalOpen={isOpen} />}
</ClientOnly>
<Caption figure={figure} className="md:mb-2" />
<div className="mx-auto w-full rounded-2xl bg-white p-2">
<Disclosure>
{({ open }) => (
<>
<DisclosureButton
className={classNames(
"flex w-full justify-between rounded-lg text-offblack",
`bg-${accentColor}`,
"px-4 py-2 text-left text-sm font-medium",
// `text-${backgroundColor}`,
`hover:bg-${backgroundColor}/75`
)}
>
<span>Alt Text</span>
<ChevronUp
className={classNames(
`text-${backgroundColor}`,
"transition-transform",
open ? "rotate-180 transform" : ""
)}
/>
</DisclosureButton>
<DisclosurePanel
className="px-4 pb-2 pt-4 text-sm text-left text-offblack"
dangerouslySetInnerHTML={{
__html: figure?.altText ?? "",
}}
/>
</>
)}
<Button
onClick={() => setOpen(false)}
className="self-start"
>
<Close className="hover:text-offwhite text-offblack hover:fill-offblack" />
</Button>
</DialogTitle>
<div className="flex flex-col justify-between">
<ClientOnly>
{() => <IIIFViewer figure={figure} />}
</ClientOnly>
<Caption figure={figure} className="md:mb-2" />
<div className="mx-auto w-full rounded-2xl bg-white p-2">
<Disclosure>
{({ open }) => (
<>
<DisclosureButton
className={classNames(
"flex w-full justify-between rounded-lg",
`bg-${accentColor}`,
"px-4 py-2 text-left text-sm font-medium",
`text-${backgroundColor}`,
`hover:bg-${backgroundColor}/75`
)}
>
<span>Alt Text</span>
<ChevronUp
className={classNames(
`text-${backgroundColor}`,
"transition-transform",
open ? "rotate-180 transform" : ""
)}
/>
</DisclosureButton>
<DisclosurePanel
className="px-4 pb-2 pt-4 text-sm text-left"
dangerouslySetInnerHTML={{
__html: figure?.altText ?? "",
}}
/>
</>
)}
</Disclosure>
</div>
</div>
</DialogPanel>
</TransitionChild>
</div>
</Disclosure>
</div>
</div>
</DialogPanel>
</div>
</Dialog>
</Transition>
</div>
</Dialog>
</div>
);
}
9 changes: 4 additions & 5 deletions app/components/figures/IIIFViewer.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const fetchTileSource = async (figure: TFigure) => {
);
const result = await response.json();
result.service[0].id = result.id;
console.log("🚀 ~ fetchTileSource ~ result:", result);
return { ...result, tileFormat: "png" };
};

Expand All @@ -28,9 +27,10 @@ const openSeadragonConfig: Options = {

interface Props {
figure: TFigure;
modalOpen: boolean;
}

const IIIFViewer = ({ figure }: Props) => {
const IIIFViewer = ({ figure, modalOpen = true }: Props) => {
const [tileSource, setTileSource] = useState<
LabeledIIIFExternalWebResource | undefined
>(undefined);
Expand All @@ -45,10 +45,9 @@ const IIIFViewer = ({ figure }: Props) => {
}
}, [figure]);

if (tileSource) {
console.log("🚀 ~ IIIFViewer ~ tileSource:", tileSource);
if (tileSource && modalOpen) {
return (
<div className="h-[66vh] bg-offblack">
<div className="h-full bg-offblack w-full aspect-[1.75]">
<CloverImage
body={tileSource}
isTiledImage
Expand Down
29 changes: 19 additions & 10 deletions app/components/layout/ChapterBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ interface Props {

export default function ChapterBody({ children, className }: Props) {
const scrollerRef = useRef<ScrollamaInstance | undefined>(undefined);
const containerRef = useRef<HTMLElement>(null);
const [chapterProgressState, setChapterProgressState] = useState<number>(0.0);
const [fixedNav, setFixedNav] = useState<boolean>(false);
const { mainContentSize, windowSize } = useResizeObserver();
Expand All @@ -29,17 +30,24 @@ export default function ChapterBody({ children, className }: Props) {
// the image containers the size of the image. Maybe later...
// https://github.com/russellsamora/scrollama/issues/145
scrollerRef.current.resize();
} else {
} else if (
containerRef.current &&
document.body.contains(containerRef.current)
) {
scrollerRef.current = scrollama();
scrollerRef.current
.setup({
step: ".chapter-body",
progress: true,
debug: false,
// @ts-ignore Maybe a bug in Scrollama type. String is acceptable.
offset: `${mainContentSize.topOffset}px`,
})
.onStepProgress(({ progress }) => setChapterProgressState(progress));
try {
scrollerRef.current
.setup({
step: `#${containerRef.current.id}`,
progress: true,
debug: false,
// @ts-ignore Maybe a bug in Scrollama type. String is acceptable.
offset: `${mainContentSize.topOffset}px`,
})
.onStepProgress(({ progress }) => setChapterProgressState(progress));
} catch {
scrollerRef.current = undefined;
}
}

return () => {
Expand All @@ -54,6 +62,7 @@ export default function ChapterBody({ children, className }: Props) {

return (
<main
ref={containerRef}
className={`chapter-body w-screen selection:bg-${backgroundColor} selection:text-white ${
className ?? ""
}`}
Expand Down
1 change: 1 addition & 0 deletions app/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export function useResizeObserver() {
useEffect(() => {
// Handler to call on window resize
function handleResize() {
if (document.fullscreenElement) return;
const mainContentElement = document.getElementById("main-content");
// Set window width/height to state
setViewportSize({
Expand Down

0 comments on commit bd78dfe

Please sign in to comment.