feat(images): Set up Image component

This commit is contained in:
Princesseuh 2023-02-03 14:14:16 +01:00
parent d714a7a7e9
commit 1f7c4a95e8
No known key found for this signature in database
GPG key ID: 105BBD6D57F2B0C0
10 changed files with 147 additions and 5 deletions

View file

@ -1,6 +1,8 @@
---
import { getImage } from 'astro:assets';
import { getImage, Image } from 'astro:assets';
import Test from '../components/Test.astro';
console.log(getImage());
---
<html lang="en">

View file

@ -1,5 +1,17 @@
/// <reference path="./import-meta.d.ts" />
declare module 'astro:assets' {
// Exporting things one by one is a bit cumbersome, not sure if there's a better way - erika, 2023-02-03
type AstroAssets = {
getImage: typeof import('./dist/assets/index.js').getImage;
Image: typeof import('./components/index.js').Image;
};
export type LocalImageProps = import('./dist/assets/types.js').LocalImageProps;
export type RemoteImageProps = import('./dist/assets/types.js').RemoteImageProps;
export const { getImage, Image }: AstroAssets;
}
type MD = import('./dist/@types/astro').MarkdownInstance<Record<string, any>>;
interface ExportedMarkdownModuleEntities {
frontmatter: MD['frontmatter'];

View file

@ -0,0 +1,17 @@
---
import { AstroError, AstroErrorData } from "../dist/core/errors/index.js"
import type { LocalImageProps, RemoteImageProps } from 'astro:assets';
import { getImage } from "astro:assets";
type Props = LocalImageProps | RemoteImageProps;
const { loading = 'lazy', decoding = 'async', ...props } = Astro.props;
if (props.alt === undefined || props.alt === null) {
throw new AstroError(AstroErrorData.ImageMissingAlt)
}
const attrs = await getImage();
---
<img {...attrs} {loading} {decoding} />

View file

@ -1,2 +1,5 @@
export { default as Code } from './Code.astro';
export { default as Debug } from './Debug.astro';
export { default as Image } from './Image.astro';

View file

@ -47,6 +47,7 @@
"./client/*": "./dist/runtime/client/*",
"./components": "./components/index.ts",
"./components/*": "./components/*",
"./assets": "./dist/assets/index.js",
"./content/internal": "./dist/content/internal.js",
"./debug": "./components/Debug.astro",
"./internal/*": "./dist/runtime/server/*",

View file

@ -0,0 +1,2 @@
export { getImage } from './internal.js';
export { type LocalImageProps, type RemoteImageProps } from './types.js';

View file

@ -0,0 +1,3 @@
export function getImage() {
return 'Hello';
}

View file

@ -0,0 +1,98 @@
import { HTMLAttributes } from '../../types.js';
export interface ImageMetadata {
src: string;
width: number;
height: number;
format: InputFormat;
}
type ImageQualityPreset = 'low' | 'mid' | 'high' | 'max';
export type ImageQuality = ImageQualityPreset | number | `${number}`;
export type InputFormat =
| 'heic'
| 'heif'
| 'avif'
| 'jpeg'
| 'jpg'
| 'png'
| 'tiff'
| 'webp'
| 'gif';
export type OutputFormat = 'avif' | 'png' | 'webp' | 'jpeg' | 'jpg' | 'gif';
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
interface ImageSharedProps
extends WithRequired<Omit<HTMLAttributes<'img'>, 'src' | 'width' | 'height'>, 'alt'> {
/**
* Width of the image, the value of this property will be used to assign the `width` property on the final `img` element.
*
* For local images, this value will additionally be used to resize the image to the desired width, taking into account the original aspect ratio of the image.
*
* **Example**:
* ```astro
* <Image src={...} width={300} alt="..." />
* ```
* **Result**:
* ```html
* <img src="..." width="300" height="..." alt="..." />
* ```
*/
width?: number | `${number}`;
height?: number | `${number}`;
}
export interface LocalImageProps extends ImageSharedProps {
/**
* A reference to a local image imported through an ESM import.
*
* **Example**:
* ```js
* import myImage from "~/assets/my_image.png";
* ```
* And then refer to the image, like so:
* ```astro
* <Image src={myImage} alt="..."></Image>
* ```
*/
src: ImageMetadata;
/**
* Desired output format for the image. Defaults to `webp`.
*
* **Example**:
* ```astro
* <Image src={...} format="avif" alt="..." />
* ```
*/
format?: OutputFormat;
/**
* Desired quality for the image. Value can either be a preset such as `low` or `high`, or a numeric value from 0 to 100.
*
* Ultimately, the ending perceivable quality is loader-specific.
* For instance, a certain service might decide that `high` results in a very beautiful image, but another could choose for it to be at best passable.
*
* **Example**:
* ```astro
* <Image src={...} quality='high' alt="..." />
* <Image src={...} quality={300} alt="..." />
* ```
*/
quality?: ImageQuality;
}
export interface RemoteImageProps extends WithRequired<ImageSharedProps, 'width' | 'height'> {
/**
* URL of a remote image. Can start with a protocol (ex: `https://`) or alternatively `/`, or `Astro.url`, for images in the `public` folder
*
* Remote images are not optimized, and require both `width` and `height` to be set.
*
* **Example**:
* ```
* <Image src="https://example.com/image.png" width={450} height={300} alt="..." />
* ```
*/
src: string;
}

View file

@ -12,12 +12,10 @@ export default function assets({ settings, logging }: AstroPluginOptions): vite.
return resolvedVirtualModuleId;
}
},
load(id, options) {
load(id) {
if (id === resolvedVirtualModuleId) {
return `
export function getImage() {
return "this will be an image one day!";
}
export { getImage, Image } from "astro/assets";
`;
}
},

View file

@ -429,6 +429,12 @@ See https://docs.astro.build/en/guides/server-side-rendering/ for more informati
message: (name: string) => `Invalid arguments passed to${name ? ` <${name}>` : ''} component.`,
hint: 'Astro components cannot be rendered directly via function call, such as `Component()` or `{items.map(Component)}`.',
},
ImageMissingAlt: {
title: 'Missing alt property',
code: 3021,
message: 'The alt property is required.',
hint: "The `alt` property is important for the purpose of accessibility, without it users using screen readers or other assistive technologies won't be able to understand what your image is supposed to represent. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-alt for more information.",
},
// Vite Errors - 4xxx
UnknownViteError: {
title: 'Unknown Vite Error.',