add reusable ImageFigure component

This commit is contained in:
2024-07-07 17:43:19 +02:00
parent e03e2624db
commit ada7d25083
15 changed files with 70 additions and 58 deletions

View File

@ -1,6 +1,6 @@
import { getClient } from "@/app/client"; import { getClient } from "@/app/client";
import { Blocks } from "@/components/blocks/Blocks"; import { Blocks } from "@/components/blocks/Blocks";
import Image from "@/components/general/Image"; import { ImageFigure } from "@/components/general/Image";
import { graphql } from "@/gql"; import { graphql } from "@/gql";
import { NewsFragment } from "@/gql/graphql"; import { NewsFragment } from "@/gql/graphql";
import { formatDate, formatExtendedDateTime } from "@/lib/date"; import { formatDate, formatExtendedDateTime } from "@/lib/date";
@ -56,18 +56,14 @@ export default async function Page({ params }: { params: { slug: string } }) {
</p> </p>
<h1 className="news-title">{news.title}</h1> <h1 className="news-title">{news.title}</h1>
{featuredImage && ( {featuredImage && (
<figure key={featuredImage.id}> <ImageFigure
<Image
src={featuredImage.url} src={featuredImage.url}
alt={featuredImage.alt ?? ""} alt={featuredImage.alt ?? ""}
width={featuredImage.width} width={featuredImage.width}
height={featuredImage.height} height={featuredImage.height}
attribution={featuredImage.attribution}
sizes="100vw" sizes="100vw"
/> />
{featuredImage.attribution && (
<figcaption>{featuredImage.attribution}</figcaption>
)}
</figure>
)} )}
</section> </section>
<section className="pageContent"> <section className="pageContent">

View File

@ -1,7 +1,7 @@
import { getClient } from "@/app/client"; import { getClient } from "@/app/client";
import { Blocks } from "@/components/blocks/Blocks"; import { Blocks } from "@/components/blocks/Blocks";
import Icon from "@/components/general/Icon"; import Icon from "@/components/general/Icon";
import Image from "@/components/general/Image"; import { Image } from "@/components/general/Image";
import { graphql } from "@/gql"; import { graphql } from "@/gql";
import { AssociationFragment } from "@/gql/graphql"; import { AssociationFragment } from "@/gql/graphql";
import Link from "next/link"; import Link from "next/link";

View File

@ -1,7 +1,7 @@
import { getClient } from "@/app/client"; import { getClient } from "@/app/client";
import { Blocks } from "@/components/blocks/Blocks"; import { Blocks } from "@/components/blocks/Blocks";
import { ImageSliderBlock } from "@/components/blocks/ImageSliderBlock"; import { ImageSliderBlock } from "@/components/blocks/ImageSliderBlock";
import Image from "@/components/general/Image"; import { Image } from "@/components/general/Image";
import { NeufMap } from "@/components/venues/NeufMap"; import { NeufMap } from "@/components/venues/NeufMap";
import { VenueInfo } from "@/components/venues/VenueInfo"; import { VenueInfo } from "@/components/venues/VenueInfo";
import { graphql } from "@/gql"; import { graphql } from "@/gql";

View File

@ -1,7 +1,7 @@
import { AssociationFragment } from "@/gql/graphql"; import { AssociationFragment } from "@/gql/graphql";
import styles from "./associationItem.module.scss"; import styles from "./associationItem.module.scss";
import Link from "next/link"; import Link from "next/link";
import Image from "../general/Image"; import { Image } from "@/components/general/Image";
export const AssociationItem = ({ export const AssociationItem = ({
association, association,

View File

@ -1,6 +1,6 @@
import { FeaturedBlock as FeaturedBlockType } from "@/gql/graphql"; import { FeaturedBlock as FeaturedBlockType } from "@/gql/graphql";
import Link from "next/link"; import Link from "next/link";
import Image from "../general/Image"; import { Image } from "@/components/general/Image";
import styles from "./featuredBlock.module.scss"; import styles from "./featuredBlock.module.scss";
// the 'text' field has been aliased to 'featuredBlockText' and i'm // the 'text' field has been aliased to 'featuredBlockText' and i'm

View File

@ -1,5 +1,5 @@
import { HorizontalRuleBlock as HorizontalRuleBlockType } from "@/gql/graphql"; import { HorizontalRuleBlock as HorizontalRuleBlockType } from "@/gql/graphql";
import Image from "../general/Image"; import { Image } from "@/components/general/Image";
import styles from "./horizontalRuleBlock.module.scss"; import styles from "./horizontalRuleBlock.module.scss";
export const HorizontalRuleBlock = ({ export const HorizontalRuleBlock = ({

View File

@ -1,6 +1,6 @@
"use client"; "use client";
import { ImageSliderBlock as ImageSliderBlockType } from "@/gql/graphql"; import { ImageSliderBlock as ImageSliderBlockType } from "@/gql/graphql";
import Image from "../general/Image"; import { ImageFigure } from "@/components/general/Image";
import styles from "./imageSliderBlock.module.scss"; import styles from "./imageSliderBlock.module.scss";
// import swiper modules & styles // import swiper modules & styles
@ -31,18 +31,16 @@ export const ImageSliderBlock = ({
{block.images && {block.images &&
block.images.map((imageItem: any, index: number) => ( block.images.map((imageItem: any, index: number) => (
<SwiperSlide key={index}> <SwiperSlide key={index}>
<figure key={imageItem.image.id}> <ImageFigure
<Image key={imageItem.image.id}
src={imageItem.image.url} src={imageItem.image.url}
alt={imageItem.image.alt ?? ""} alt={imageItem.image.alt ?? ""}
width={imageItem.image.width} width={imageItem.image.width}
height={imageItem.image.height} height={imageItem.image.height}
// width={0} attribution={imageItem.image.attribution}
// height={0} caption={imageItem.text}
// sizes="20vw" sizes="100vw"
/> />
{imageItem.text && <figcaption>{imageItem.text}</figcaption>}
</figure>
</SwiperSlide> </SwiperSlide>
))} ))}
</Swiper> </Swiper>

View File

@ -1,26 +1,20 @@
import { ImageWithTextBlock as ImageWithTextBlockType } from "@/gql/graphql"; import { ImageWithTextBlock as ImageWithTextBlockType } from "@/gql/graphql";
import Image from "../general/Image"; import { ImageFigure } from "@/components/general/Image";
import styles from "./imageWithTextBlock.module.scss";
export const ImageWithTextBlock = ({ export function ImageWithTextBlock({
block, block,
}: { }: {
block: ImageWithTextBlockType; block: ImageWithTextBlockType;
}) => { }) {
return ( return (
<figure <ImageFigure
className={`${styles.imageWithTextBlock} ${styles[block.imageFormat]}`}
>
<Image
src={block.image.url} src={block.image.url}
alt={block.image.alt ?? ""} alt={block.image.alt ?? ""}
width={block.image.width} width={block.image.width}
height={block.image.height} height={block.image.height}
// width={0} attribution={block.image.attribution}
// height={0} caption={block.text}
// sizes="20vw" imageFormat={block.imageFormat}
/> />
{block.text && <figcaption>{block.text}</figcaption>}
</figure>
); );
}; }

View File

@ -1,6 +1,6 @@
import { EventFragment } from "@/lib/event"; import { EventFragment } from "@/lib/event";
import styles from "./eventHeader.module.scss"; import styles from "./eventHeader.module.scss";
import Image from "@/components/general/Image"; import { Image } from "@/components/general/Image";
import Link from "next/link"; import Link from "next/link";
import { OrganizerList } from "./OrganizerList"; import { OrganizerList } from "./OrganizerList";
import Icon from "../general/Icon"; import Icon from "../general/Icon";
@ -17,6 +17,8 @@ function formatPrice(price: number): string {
} }
export const EventHeader = ({ event }: { event: EventFragment }) => { export const EventHeader = ({ event }: { event: EventFragment }) => {
// TODO: where should we show image attribution for the featured image?
const featuredImage: any = event.featuredImage; const featuredImage: any = event.featuredImage;
return ( return (

View File

@ -2,7 +2,7 @@
import styles from "./eventItem.module.scss"; import styles from "./eventItem.module.scss";
import Link from "next/link"; import Link from "next/link";
import Image from "../general/Image"; import { Image } from "@/components/general/Image";
import { import {
SingularEvent, SingularEvent,
EventFragment, EventFragment,

View File

@ -1,7 +1,25 @@
import NextImage, { ImageProps as NextImageProps } from "next/image"; import NextImage, { ImageProps as NextImageProps } from "next/image";
import styles from "./image.module.scss";
type ImageProps = NextImageProps; type ImageProps = NextImageProps & {
attribution?: string | null;
caption?: string | null;
imageFormat?: string | null; // "original" | "bleed" | "fullWidth"
};
export default function Image(props: ImageProps) { export function ImageFigure(props: ImageProps) {
const { attribution, caption, imageFormat, ...nextImageProps } = props;
return (
<figure
className={`${styles.image} ${imageFormat ? styles[imageFormat] : ""}`}
>
<NextImage {...nextImageProps} />
{attribution && <div className={styles.attribution}>{attribution}</div>}
{caption && <figcaption>{caption}</figcaption>}
</figure>
);
}
export function Image(props: NextImageProps) {
return <NextImage {...props} />; return <NextImage {...props} />;
} }

View File

@ -1,4 +1,4 @@
.imageWithTextBlock { .image {
width: 100%; width: 100%;
margin: 0; margin: 0;
@ -53,3 +53,7 @@
} }
} }
} }
.attribution {
border: 1px dotted mediumpurple;
}

View File

@ -1,5 +1,5 @@
import styles from "./newsItem.module.scss"; import styles from "./newsItem.module.scss";
import Image from "../general/Image"; import { Image } from "@/components/general/Image";
import { NewsFragment } from "@/lib/news"; import { NewsFragment } from "@/lib/news";
import { formatDate } from "@/lib/date"; import { formatDate } from "@/lib/date";
import Link from "next/link"; import Link from "next/link";

View File

@ -1,7 +1,7 @@
import { VenueFragment } from "@/gql/graphql"; import { VenueFragment } from "@/gql/graphql";
import styles from "./venueInfo.module.scss"; import styles from "./venueInfo.module.scss";
import Link from "next/link"; import Link from "next/link";
import Image from "../general/Image"; import { Image } from "@/components/general/Image";
import Icon from "../general/Icon"; import Icon from "../general/Icon";
export const VenueInfo = ({ venue }: { venue: VenueFragment }) => { export const VenueInfo = ({ venue }: { venue: VenueFragment }) => {

View File

@ -1,7 +1,7 @@
import { VenueFragment } from "@/gql/graphql"; import { VenueFragment } from "@/gql/graphql";
import styles from "./venueItem.module.scss"; import styles from "./venueItem.module.scss";
import Link from "next/link"; import Link from "next/link";
import Image from "../general/Image"; import { Image } from "@/components/general/Image";
export const VenueItem = ({ venue }: { venue: VenueFragment }) => { export const VenueItem = ({ venue }: { venue: VenueFragment }) => {
const featuredImage: any = venue.featuredImage; const featuredImage: any = venue.featuredImage;