From cccd165d75fe2c2d17058facd3ec7991cd29b32a Mon Sep 17 00:00:00 2001 From: Princesseuh Date: Thu, 21 Sep 2023 19:05:45 +0200 Subject: [PATCH] feat(assets): Add a Picture component --- packages/astro/client.d.ts | 11 ++----- packages/astro/components/Picture.astro | 44 +++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 packages/astro/components/Picture.astro diff --git a/packages/astro/client.d.ts b/packages/astro/client.d.ts index 5f396b522..13de80e16 100644 --- a/packages/astro/client.d.ts +++ b/packages/astro/client.d.ts @@ -53,6 +53,7 @@ declare module 'astro:assets' { imageConfig: import('./dist/@types/astro.js').AstroConfig['image']; getConfiguredImageService: typeof import('./dist/assets/index.js').getConfiguredImageService; Image: typeof import('./components/Image.astro').default; + Picture: typeof import('./components/Picture.astro').default; }; type ImgAttributes = import('./dist/type-utils.js').WithRequired< @@ -66,17 +67,11 @@ declare module 'astro:assets' { export type RemoteImageProps = import('./dist/type-utils.js').Simplify< import('./dist/assets/types.js').RemoteImageProps >; - export const { getImage, getConfiguredImageService, imageConfig, Image }: AstroAssets; + export const { getImage, getConfiguredImageService, imageConfig, Image, Picture }: AstroAssets; } type InputFormat = import('./dist/assets/types.js').ImageInputFormat; - -interface ImageMetadata { - src: string; - width: number; - height: number; - format: InputFormat; -} +type ImageMetadata = import('./dist/assets/types.js').ImageMetadata; declare module '*.gif' { const metadata: ImageMetadata; diff --git a/packages/astro/components/Picture.astro b/packages/astro/components/Picture.astro new file mode 100644 index 000000000..506f72ea0 --- /dev/null +++ b/packages/astro/components/Picture.astro @@ -0,0 +1,44 @@ +--- +import { LocalImageProps, RemoteImageProps, getImage } from 'astro:assets'; +import { GetImageResult, ImageOutputFormat } from '../dist/@types/astro'; +import { isESMImportedImage } from '../dist/assets/internal'; +import { AstroError, AstroErrorData } from '../dist/core/errors/index.js'; +import { HTMLAttributes } from '../types'; + +type Props = (LocalImageProps | RemoteImageProps) & { + formats: ImageOutputFormat[]; + fallbackFormat: ImageOutputFormat; + pictureAttributes: HTMLAttributes<'picture'>; +}; + +const props = Astro.props; +const optimizedImages: Record< + ImageOutputFormat, + GetImageResult +> = await Promise.all( + props.formats.map(async (format) => await getImage({ ...props, format: format, widths: props.widths, densities: props.densities })) +); + +const fallbackFormat = + props.fallbackFormat ?? isESMImportedImage(props.src) + ? ['svg', 'gif'].includes(props.src.format) + ? props.src.format + : 'png' + : 'png'; + +const originalImage = await getImage({ ...props, format: fallbackFormat, widths: props.widths, densities: props.densities }); + +if (props.alt === undefined || props.alt === null) { + throw new AstroError(AstroErrorData.ImageMissingAlt); +} +--- + + + {Object.entries(optimizedImages).map(([format, image]) => ( + + ))} + +