feat(images): Set up Image component
This commit is contained in:
parent
d714a7a7e9
commit
1f7c4a95e8
10 changed files with 147 additions and 5 deletions
|
@ -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">
|
||||
|
|
12
packages/astro/client-base.d.ts
vendored
12
packages/astro/client-base.d.ts
vendored
|
@ -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'];
|
||||
|
|
17
packages/astro/components/Image.astro
Normal file
17
packages/astro/components/Image.astro
Normal 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} />
|
|
@ -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';
|
||||
|
||||
|
||||
|
|
|
@ -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/*",
|
||||
|
|
2
packages/astro/src/assets/index.ts
Normal file
2
packages/astro/src/assets/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export { getImage } from './internal.js';
|
||||
export { type LocalImageProps, type RemoteImageProps } from './types.js';
|
3
packages/astro/src/assets/internal.ts
Normal file
3
packages/astro/src/assets/internal.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function getImage() {
|
||||
return 'Hello';
|
||||
}
|
98
packages/astro/src/assets/types.ts
Normal file
98
packages/astro/src/assets/types.ts
Normal 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;
|
||||
}
|
|
@ -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";
|
||||
`;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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.',
|
||||
|
|
Loading…
Reference in a new issue