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>
This commit is contained in:
parent
28556a89fe
commit
006405d33c
5 changed files with 66 additions and 59 deletions
6
.changeset/mean-suits-cover.md
Normal file
6
.changeset/mean-suits-cover.md
Normal file
|
@ -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
|
|
@ -2,29 +2,11 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { getImage } from '../dist/index.js';
|
import { getImage } from '../dist/index.js';
|
||||||
import { warnForMissingAlt } from './index.js';
|
import { warnForMissingAlt } from './index.js';
|
||||||
import type { ImgHTMLAttributes } from './index.js';
|
import type { ImageComponentLocalImageProps, ImageComponentRemoteImageProps } from './index.js';
|
||||||
import type { ImageMetadata, TransformOptions, OutputFormat } from '../dist/index.js';
|
|
||||||
|
|
||||||
interface LocalImageProps
|
export type Props = ImageComponentLocalImageProps | ImageComponentRemoteImageProps;
|
||||||
extends Omit<TransformOptions, 'src'>,
|
|
||||||
Omit<ImgHTMLAttributes, 'src' | 'width' | 'height'> {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RemoteImageProps extends TransformOptions, astroHTML.JSX.ImgHTMLAttributes {
|
const { loading = 'lazy', decoding = 'async', ...props } = Astro.props;
|
||||||
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;
|
|
||||||
|
|
||||||
if (props.alt === undefined || props.alt === null) {
|
if (props.alt === undefined || props.alt === null) {
|
||||||
warnForMissingAlt();
|
warnForMissingAlt();
|
||||||
|
|
|
@ -1,36 +1,9 @@
|
||||||
---
|
---
|
||||||
import { getPicture } from '../dist/index.js';
|
import { getPicture } from '../dist/index.js';
|
||||||
import { warnForMissingAlt } from './index.js';
|
import { warnForMissingAlt } from './index.js';
|
||||||
import type { ImgHTMLAttributes, HTMLAttributes } from './index.js';
|
import type { PictureComponentLocalImageProps, PictureComponentRemoteImageProps } from './index.js';
|
||||||
import type { ImageMetadata, OutputFormat, TransformOptions } from '../dist/index.js';
|
|
||||||
|
|
||||||
interface LocalImageProps
|
export type Props = PictureComponentLocalImageProps | PictureComponentRemoteImageProps;
|
||||||
extends Omit<HTMLAttributes, 'src' | 'width' | 'height'>,
|
|
||||||
Omit<TransformOptions, 'src'>,
|
|
||||||
Pick<astroHTML.JSX.ImgHTMLAttributes, 'loading' | 'decoding'> {
|
|
||||||
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<HTMLAttributes, 'src' | 'width' | 'height'>,
|
|
||||||
TransformOptions,
|
|
||||||
Pick<ImgHTMLAttributes, 'loading' | 'decoding'> {
|
|
||||||
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;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
src,
|
src,
|
||||||
|
@ -45,7 +18,7 @@ const {
|
||||||
loading = 'lazy',
|
loading = 'lazy',
|
||||||
decoding = 'async',
|
decoding = 'async',
|
||||||
...attrs
|
...attrs
|
||||||
} = Astro.props as Props;
|
} = Astro.props;
|
||||||
|
|
||||||
if (alt === undefined || alt === null) {
|
if (alt === undefined || alt === null) {
|
||||||
warnForMissingAlt();
|
warnForMissingAlt();
|
||||||
|
@ -59,6 +32,7 @@ const { image, sources } = await getPicture({
|
||||||
fit,
|
fit,
|
||||||
background,
|
background,
|
||||||
position,
|
position,
|
||||||
|
alt,
|
||||||
});
|
});
|
||||||
|
|
||||||
delete image.width;
|
delete image.width;
|
||||||
|
|
|
@ -1,15 +1,60 @@
|
||||||
/// <reference types="astro/astro-jsx" />
|
/// <reference types="astro/astro-jsx" />
|
||||||
export { default as Image } from './Image.astro';
|
export { default as Image } from './Image.astro';
|
||||||
export { default as Picture } from './Picture.astro';
|
export { default as Picture } from './Picture.astro';
|
||||||
|
import type { HTMLAttributes } from 'astro/types';
|
||||||
|
|
||||||
// TODO: should these directives be removed from astroHTML.JSX?
|
import type { TransformOptions, OutputFormat } from '../dist/loaders/index.js';
|
||||||
export type ImgHTMLAttributes = Omit<
|
import type { ImageMetadata } from '../dist/vite-plugin-astro-image.js';
|
||||||
astroHTML.JSX.ImgHTMLAttributes,
|
import type { AstroBuiltinAttributes } from 'astro';
|
||||||
'client:list' | 'set:text' | 'set:html' | 'is:raw'
|
|
||||||
>;
|
export interface ImageComponentLocalImageProps
|
||||||
export type HTMLAttributes = Omit<
|
extends Omit<TransformOptions, 'src'>,
|
||||||
|
Omit<ImgHTMLAttributes, 'src' | 'width' | 'height'> {
|
||||||
|
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<TransformOptions, 'src'>,
|
||||||
|
Pick<ImgHTMLAttributes, 'loading' | 'decoding'> {
|
||||||
|
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<ImgHTMLAttributes, 'loading' | 'decoding'> {
|
||||||
|
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,
|
astroHTML.JSX.HTMLAttributes,
|
||||||
'client:list' | 'set:text' | 'set:html' | 'is:raw'
|
keyof Omit<AstroBuiltinAttributes, 'class:list'>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
let altWarningShown = false;
|
let altWarningShown = false;
|
||||||
|
|
|
@ -10,7 +10,7 @@ const publicImage = new URL('./hero.jpg', Astro.url);
|
||||||
<!-- Head Stuff -->
|
<!-- Head Stuff -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<Image id="hero" src={publicImage.pathname} width={768} height={414} format="webp" alt="hero" />
|
<Image id="hero" src={publicImage.pathname} width={768} height={414} format="webp" alt="hero" />
|
||||||
<br />
|
<br />
|
||||||
<Image id="spaces" src={introJpg} width={768} height={414} format="webp" alt="spaces" />
|
<Image id="spaces" src={introJpg} width={768} height={414} format="webp" alt="spaces" />
|
||||||
<br />
|
<br />
|
||||||
|
|
Loading…
Reference in a new issue