From 006405d33c2b8eb1307cb84161659428e43efa51 Mon Sep 17 00:00:00 2001 From: Happydev <81974850+MoustaphaDev@users.noreply.github.com> Date: Wed, 18 Jan 2023 03:41:50 +0100 Subject: [PATCH] Refactor `Props` of `Image` and `Picture` component to support type checking (#5788) * correct props type * refactor Picture and Image typings * add missing `alt` property * add changeset * apply suggestions * correct `astro/types` import Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com> * apply suggestions * convert to type import Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com> --- .changeset/mean-suits-cover.md | 6 ++ .../integrations/image/components/Image.astro | 24 +------- .../image/components/Picture.astro | 34 ++--------- .../integrations/image/components/index.ts | 59 ++++++++++++++++--- .../basic-image/src/pages/index.astro | 2 +- 5 files changed, 66 insertions(+), 59 deletions(-) create mode 100644 .changeset/mean-suits-cover.md diff --git a/.changeset/mean-suits-cover.md b/.changeset/mean-suits-cover.md new file mode 100644 index 000000000..f19a642d4 --- /dev/null +++ b/.changeset/mean-suits-cover.md @@ -0,0 +1,6 @@ +--- +'@astrojs/image': patch +--- + +- Refactor types to support props auto-completion for the `Image` and `Picture` components. +- Pass previously missing `alt` prop to the `getPicture` function diff --git a/packages/integrations/image/components/Image.astro b/packages/integrations/image/components/Image.astro index 254d24777..dea492de0 100644 --- a/packages/integrations/image/components/Image.astro +++ b/packages/integrations/image/components/Image.astro @@ -2,29 +2,11 @@ // @ts-ignore import { getImage } from '../dist/index.js'; import { warnForMissingAlt } from './index.js'; -import type { ImgHTMLAttributes } from './index.js'; -import type { ImageMetadata, TransformOptions, OutputFormat } from '../dist/index.js'; +import type { ImageComponentLocalImageProps, ImageComponentRemoteImageProps } from './index.js'; -interface LocalImageProps - extends Omit, - Omit { - src: ImageMetadata | Promise<{ default: ImageMetadata }>; - /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ - alt: string; -} +export type Props = ImageComponentLocalImageProps | ImageComponentRemoteImageProps; -interface RemoteImageProps extends TransformOptions, astroHTML.JSX.ImgHTMLAttributes { - src: string; - /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ - alt: string; - format?: OutputFormat; - width: number; - height: number; -} - -export type Props = LocalImageProps | RemoteImageProps; - -const { loading = 'lazy', decoding = 'async', ...props } = Astro.props as Props; +const { loading = 'lazy', decoding = 'async', ...props } = Astro.props; if (props.alt === undefined || props.alt === null) { warnForMissingAlt(); diff --git a/packages/integrations/image/components/Picture.astro b/packages/integrations/image/components/Picture.astro index c9633c3de..f099eae23 100644 --- a/packages/integrations/image/components/Picture.astro +++ b/packages/integrations/image/components/Picture.astro @@ -1,36 +1,9 @@ --- import { getPicture } from '../dist/index.js'; import { warnForMissingAlt } from './index.js'; -import type { ImgHTMLAttributes, HTMLAttributes } from './index.js'; -import type { ImageMetadata, OutputFormat, TransformOptions } from '../dist/index.js'; +import type { PictureComponentLocalImageProps, PictureComponentRemoteImageProps } from './index.js'; -interface LocalImageProps - extends Omit, - Omit, - Pick { - src: ImageMetadata | Promise<{ default: ImageMetadata }>; - /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ - alt: string; - sizes: HTMLImageElement['sizes']; - widths: number[]; - formats?: OutputFormat[]; -} - -interface RemoteImageProps - extends Omit, - TransformOptions, - Pick { - src: string; - /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ - alt: string; - sizes: HTMLImageElement['sizes']; - widths: number[]; - aspectRatio: TransformOptions['aspectRatio']; - formats?: OutputFormat[]; - background: TransformOptions['background']; -} - -export type Props = LocalImageProps | RemoteImageProps; +export type Props = PictureComponentLocalImageProps | PictureComponentRemoteImageProps; const { src, @@ -45,7 +18,7 @@ const { loading = 'lazy', decoding = 'async', ...attrs -} = Astro.props as Props; +} = Astro.props; if (alt === undefined || alt === null) { warnForMissingAlt(); @@ -59,6 +32,7 @@ const { image, sources } = await getPicture({ fit, background, position, + alt, }); delete image.width; diff --git a/packages/integrations/image/components/index.ts b/packages/integrations/image/components/index.ts index e60494398..c4f41123f 100644 --- a/packages/integrations/image/components/index.ts +++ b/packages/integrations/image/components/index.ts @@ -1,15 +1,60 @@ /// export { default as Image } from './Image.astro'; export { default as Picture } from './Picture.astro'; +import type { HTMLAttributes } from 'astro/types'; -// TODO: should these directives be removed from astroHTML.JSX? -export type ImgHTMLAttributes = Omit< - astroHTML.JSX.ImgHTMLAttributes, - 'client:list' | 'set:text' | 'set:html' | 'is:raw' ->; -export type HTMLAttributes = Omit< +import type { TransformOptions, OutputFormat } from '../dist/loaders/index.js'; +import type { ImageMetadata } from '../dist/vite-plugin-astro-image.js'; +import type { AstroBuiltinAttributes } from 'astro'; + +export interface ImageComponentLocalImageProps + extends Omit, + Omit { + src: ImageMetadata | Promise<{ default: ImageMetadata }>; + /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ + alt: string; +} + +export interface ImageComponentRemoteImageProps extends TransformOptions, ImgHTMLAttributes { + src: string; + /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ + alt: string; + format?: OutputFormat; + width: number; + height: number; +} + +export interface PictureComponentLocalImageProps + extends GlobalHTMLAttributes, + Omit, + Pick { + src: ImageMetadata | Promise<{ default: ImageMetadata }>; + /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ + alt: string; + sizes: HTMLImageElement['sizes']; + widths: number[]; + formats?: OutputFormat[]; +} + +export interface PictureComponentRemoteImageProps + extends GlobalHTMLAttributes, + TransformOptions, + Pick { + src: string; + /** Defines an alternative text description of the image. Set to an empty string (alt="") if the image is not a key part of the content (it's decoration or a tracking pixel). */ + alt: string; + sizes: HTMLImageElement['sizes']; + widths: number[]; + aspectRatio: TransformOptions['aspectRatio']; + formats?: OutputFormat[]; + background: TransformOptions['background']; +} + +export type ImgHTMLAttributes = HTMLAttributes<'img'>; + +export type GlobalHTMLAttributes = Omit< astroHTML.JSX.HTMLAttributes, - 'client:list' | 'set:text' | 'set:html' | 'is:raw' + keyof Omit >; let altWarningShown = false; diff --git a/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro b/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro index cac182c39..4a808e0ac 100644 --- a/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro +++ b/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro @@ -10,7 +10,7 @@ const publicImage = new URL('./hero.jpg', Astro.url); - hero + hero
spaces