Skip to content

Commit

Permalink
fix(SanityImage): support image assets from shared Sanity project
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiazom committed Sep 23, 2024
1 parent f3b6e47 commit aae9da7
Show file tree
Hide file tree
Showing 15 changed files with 131 additions and 131 deletions.
7 changes: 3 additions & 4 deletions src/blog/components/postCard/PostCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";
import { SanityImage } from "src/components/image/SanityImage";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { Post } from "studio/lib/interfaces/pages";

import styles from "./postCard.module.css";
Expand All @@ -14,14 +14,13 @@ export const PostCard = ({
slug: string;
focusRef?: React.Ref<HTMLAnchorElement>;
}) => {
const renderedImage = useConvertSanityImageToNextImage(post.lead.image);
const postLink = `/${slug}/${post.slug.current}`;
return (
<li className={styles.cardWrapper}>
<a href={postLink} className={styles.card} ref={focusRef}>
{renderedImage && (
{post.lead.image && (
<div className={styles.image} aria-hidden={true}>
{renderedImage}
<SanityImage image={post.lead.image} />
</div>
)}
<Text type="caption">{post.category}</Text>
Expand Down
14 changes: 9 additions & 5 deletions src/blog/components/postPreview/PostPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"use client";
import { PortableTextBlock } from "sanity";

import { SanityImage } from "src/components/image/SanityImage";
import CustomLink from "src/components/link/CustomLink";
import { RichText } from "src/components/richText/RichText";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { LinkType } from "studio/lib/interfaces/navigation";
import { Post } from "studio/lib/interfaces/pages";

Expand All @@ -21,8 +21,6 @@ const PostPreview = ({
alignImageToRight = true,
slug,
}: PostPreviewProps) => {
const renderedImage = useConvertSanityImageToNextImage(post.lead.image);

const link = {
_key: "string",
_type: "string",
Expand Down Expand Up @@ -60,14 +58,20 @@ const PostPreview = ({

const truncatedText = truncateFirstBlock(post.lead.richText, 400);

const hasImage = post.lead.image !== undefined;

return (
<article className={styles.wrapper}>
<div
className={`${styles.postPreview} ${alignImageToRight ? styles.right : ""}`}
>
{renderedImage && <div className={styles.image}>{renderedImage}</div>}
{hasImage && (
<div className={styles.image}>
<SanityImage image={post.lead.image} />
</div>
)}
<div
className={`${styles.content} ${renderedImage ? styles.maxWidthSmall : styles.maxWidthLarge}`}
className={`${styles.content} ${hasImage ? styles.maxWidthSmall : styles.maxWidthLarge}`}
>
<div>
<Text type="caption">{post.category}</Text>
Expand Down
76 changes: 76 additions & 0 deletions src/components/image/SanityImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"use client";

import { SanityImageSource } from "@sanity/image-url/lib/types/types";
import Image from "next/image";
import { UseNextSanityImageProps, useNextSanityImage } from "next-sanity-image";
import { useEffect, useState } from "react";

import { client } from "studio/lib/client";
import { IImage } from "studio/lib/interfaces/media";
import { sharedClient } from "studioShared/lib/client";

/**
* Builds Next.js props for a given Sanity image from an unknown Sanity project.
*
* Each generated image source is checked for existence in order to pick the correct source project.
*
* NOTE: It is assumed that an image id is only valid for a single project.
* The result of providing an id that resolves to a valid image in multiple projects is therefore not well-defined.
*
* @param image asset props for image from unknown Sanity project
*/
const useNextSanityGlobalImage = (
image: SanityImageSource,
): UseNextSanityImageProps | null => {
const studioImage = useNextSanityImage(client, image);
const sharedImage = useNextSanityImage(sharedClient, image);

const [globalImage, setGlobalImage] =
useState<UseNextSanityImageProps | null>(null);

useEffect(() => {
fetch(studioImage.src).then((r) => r.ok && setGlobalImage(studioImage));
fetch(sharedImage.src).then((r) => r.ok && setGlobalImage(sharedImage));
}, [studioImage, sharedImage]);

return globalImage;
};

const SanityAssetImage = ({ image }: { image: IImage }) => {
const imageProps = useNextSanityGlobalImage(image);
const objectPosition = image.hotspot
? `${image.hotspot.x * 100}% ${image.hotspot.y * 100}%`
: "50% 50%"; // Default to center if no hotspot is defined
if (!imageProps) {
return null;
}
return (
<Image
alt={image?.alt || ""}
{...imageProps}
width={imageProps.width}
height={imageProps.height}
style={{
objectFit: "cover",
objectPosition,
maxWidth: "100%",
maxHeight: "100%",
height: "auto",
width: "auto",
}}
/>
);
};

export function SanityImage({ image }: { image: IImage }) {
if (image?.src) {
return (
<Image
alt={image?.alt || ""}
src={image.src.src}
style={{ objectFit: "cover", width: "100%", height: "100%" }}
/>
);
}
return <SanityAssetImage image={image} />;
}
12 changes: 6 additions & 6 deletions src/components/navigation/footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import { ReactNode } from "react";

import { SanityImage } from "src/components/image/SanityImage";
import CustomLink from "src/components/link/CustomLink";
import SoMeLink from "src/components/link/SoMeLink";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { BrandAssets } from "studio/lib/interfaces/brandAssets";
import { CompanyInfo } from "studio/lib/interfaces/companyDetails";
import { LegalDocument } from "studio/lib/interfaces/legalDocuments";
Expand All @@ -32,15 +32,15 @@ const Footer = ({
soMeData,
legalData,
}: IFooter) => {
const renderedLogo = useConvertSanityImageToNextImage(
brandAssets?.secondaryLogo,
);

const currentYear = new Date().getFullYear();

return (
<footer className={styles.footer}>
<div className={styles.logo}>{renderedLogo}</div>
{brandAssets?.secondaryLogo && (
<div className={styles.logo}>
<SanityImage image={brandAssets.secondaryLogo} />
</div>
)}
<nav className={styles.nav}>
{renderLinks(navigationData)}
{soMeData && renderSoMe(navigationData, soMeData)}
Expand Down
5 changes: 2 additions & 3 deletions src/components/navigation/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { usePathname } from "next/navigation";
import { useEffect, useState } from "react";
import { FocusOn } from "react-focus-on";

import { SanityImage } from "src/components/image/SanityImage";
import CustomLink from "src/components/link/CustomLink";
import LinkButton from "src/components/linkButton/LinkButton";
import { getHref } from "src/utils/get";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { BrandAssets } from "studio/lib/interfaces/brandAssets";
import { ILink, Navigation } from "studio/lib/interfaces/navigation";
import { callToActionFieldID } from "studio/schemas/fields/callToActionFields";
Expand All @@ -28,7 +28,6 @@ export const Header = ({ data, assets }: IHeader) => {
const pathname = usePathname();
const [isOpen, setIsOpen] = useState(false);
const [isScrolled, setIsScrolled] = useState(false);
const renderedLogo = useConvertSanityImageToNextImage(assets?.primaryLogo);
const sidebarData = data.sidebar || data.main;

const links = filterLinks(data.main, linkID);
Expand Down Expand Up @@ -79,7 +78,7 @@ export const Header = ({ data, assets }: IHeader) => {
{assets?.primaryLogo && (
<div className={styles.logo}>
<Link href="/" aria-label="Home">
{renderedLogo}
<SanityImage image={assets.primaryLogo} />
</Link>
</div>
)}
Expand Down
13 changes: 6 additions & 7 deletions src/components/richText/RichText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { PortableText, PortableTextReactComponents } from "@portabletext/react";
import { ReactNode } from "react";
import { PortableTextBlock } from "sanity";

import { SanityImage } from "src/components/image/SanityImage";
import Text from "src/components/text/Text";
import textStyles from "src/components/text/text.module.css";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { getReactNodeTextContent } from "src/utils/reactNode";

import styles from "./richText.module.css";
Expand All @@ -20,11 +20,6 @@ const formatId = (children: ReactNode): string => {
.replace(/[^\w-]+/g, "");
};

const SanityImage = ({ value }: { value: PortableTextBlock }) => {
const ImageElement = useConvertSanityImageToNextImage(value);
return <div className={styles.image}>{ImageElement}</div>;
};

const myPortableTextComponents: Partial<PortableTextReactComponents> = {
block: {
h2: ({ children }) => (
Expand Down Expand Up @@ -53,7 +48,11 @@ const myPortableTextComponents: Partial<PortableTextReactComponents> = {
number: ({ children }) => <li className={textStyles.body}>{children}</li>,
},
types: {
image: SanityImage,
image: ({ value }) => (
<div className={styles.image}>
<SanityImage image={value} />
</div>
),
},
};

Expand Down
12 changes: 6 additions & 6 deletions src/components/sections/article/Article.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client";
import { SanityImage } from "src/components/image/SanityImage";
import CustomLink from "src/components/link/CustomLink";
import { RichText } from "src/components/richText/RichText";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { ArticleSection } from "studio/lib/interfaces/pages";

import styles from "./article.module.css";
Expand All @@ -12,16 +12,16 @@ interface ArticleProps {
}

const Article = ({ article }: ArticleProps) => {
const renderedImage = useConvertSanityImageToNextImage(
article?.imageExtended,
);

return (
<article className={styles.wrapper} id={article._key}>
<div
className={`${styles.article} ${article.imageExtended.imageAlignment == "right" ? styles.right : ""}`}
>
<div className={styles.image}>{renderedImage}</div>
{article?.imageExtended && (
<div className={styles.image}>
<SanityImage image={article.imageExtended} />
</div>
)}
<div className={styles.content}>
<div>
<Text type="caption">{article.tag}</Text>
Expand Down
9 changes: 6 additions & 3 deletions src/components/sections/grid/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import { PortableText, PortableTextReactComponents } from "@portabletext/react";
import { PortableTextBlock } from "sanity";

import { SanityImage } from "src/components/image/SanityImage";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { IImage } from "studio/lib/interfaces/media";
import { GridSection } from "studio/lib/interfaces/pages";

Expand Down Expand Up @@ -39,10 +39,13 @@ const Element = ({
image: IImage;
};
}) => {
const renderImage = useConvertSanityImageToNextImage(item.image);
return (
<li className={styles.listItem}>
{renderImage && <div className={styles.image}>{renderImage}</div>}
{item.image && (
<div className={styles.image}>
<SanityImage image={item.image} />
</div>
)}
<Text>{item.basicTitle}</Text>
{item.richText && (
<PortableText
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
"use client";
import { SanityImage } from "src/components/image/SanityImage";
import Text from "src/components/text/Text";
import { useConvertSanityImageToNextImage } from "src/utils/hooks/useConvertImage";
import { ImageSection } from "studio/lib/interfaces/pages";

import styles from "./imageSectionComponent.module.css";

const ImageSectionComponent = ({ section }: { section: ImageSection }) => {
const renderedImage = useConvertSanityImageToNextImage(section.image);
return (
<article className={styles.article}>
<Text type="h2">{section.basicTitle}</Text>
{renderedImage && <div className={styles.image}>{renderedImage}</div>}
{section.image && (
<div className={styles.image}>
<SanityImage image={section.image} />
</div>
)}
</article>
);
};
Expand Down
9 changes: 0 additions & 9 deletions src/components/sections/logoSalad/LogoRender.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/components/sections/logoSalad/LogoSalad.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { PortableText, PortableTextReactComponents } from "@portabletext/react";

import { SanityImage } from "src/components/image/SanityImage";
import Text from "src/components/text/Text";
import { LogoSaladSection } from "studio/lib/interfaces/pages";

import { RenderLogo } from "./LogoRender";
import styles from "./logoSalad.module.css";

interface LogoSaladProps {
Expand Down Expand Up @@ -32,7 +32,7 @@ export const LogoSalad = ({ logoSalad }: LogoSaladProps) => {
(logo) =>
logo && (
<li key={logo._key}>
<RenderLogo asset={logo} />
<SanityImage image={logo} />
</li>
),
)}
Expand Down
10 changes: 0 additions & 10 deletions src/components/sections/testimonials/RenderAvatar.tsx

This file was deleted.

Loading

0 comments on commit aae9da7

Please sign in to comment.