@yoot/yoot
Version:
The core library for yoot, providing a CDN-agnostic, chainable API for image URL transformations and adapter integration.
279 lines (278 loc) • 10 kB
TypeScript
import type { Directives, Yoot, YootState } from './yoot.ts';
import type { HTMLImageAttributes, HTMLSourceAttributes, Maybe, Prettify } from './types.ts';
export { buildSrcSet, defineSrcSetBuilder, getImgAttrs, getSourceAttrs, normalizeDirectives, withImgAttrs, withSourceAttrs, };
export type { BuildSrcSetOptions, ImgAttrs, ImgAttrsOptions, SourceAttrs, SourceAttrsOptions, WithSrcSetBuilder };
export { getAttrs, getMimeType, mustBeInRange, mustBeOneOf };
/**
* Options for `buildSrcSet` and `defineSrcSetBuilder`: target image widths or pixel densities.
*
* @remarks `widths` take precedence if both are provided.
* @public
*/
interface BuildSrcSetOptions {
/** Array of image widths (pixels) for 'w' descriptors. */
widths?: number[];
/** Array of pixel density multipliers (e.g., [1, 2]) for 'x' descriptors. */
densities?: number[];
}
/**
* Returns a function that generates a `srcset` string using the given configuration.
*
* @public
* @param options - Configuration for srcset variants.
* @returns A function accepting a `Yoot` object that returns a `srcset` string.
*
* @example
* ```ts
* // yoot-presets.ts
* import {yoot, defineSrcSetBuilder, withImgAttrs} from '@yoot/yoot';
*
* export const thumbnailPreset = yoot().width(96).aspectRatio(1);
*
* export const getThumbnailAttrs = withImgAttrs({
* loading: 'lazy',
* 'data-img': 'thumbnail',
* srcSetBuilder: defineSrcSetBuilder({widths: [96, 192]}) // Or, defineSrcSetBuilder({densities: [1, 2, 3]})
* });
*
* // somewhere else in your app
* import {getThumbnailAttrs, thumbnailPreset} from '@/yoot-presets';
*
* const thumbnail = thumbnailPreset({src: 'https://cdn.example.com/image.jpg', alt: 'Thumbnail'});
*
* <img {...getThumbnailAttrs(thumbnail)} />
* // Output (urls differ between adapters):
* // { src: 'https://cdn.example.com/image.jpg&w=96&h=96',
* // srcset: 'https://cdn.example.com/image.jpg&w=96&h=96 96w,
* // https://cdn.example.com/image.jpg&w=192&h=192 192w'
* // width: 96, height: 96, loading: 'lazy', 'data-img': 'thumbnail'}
* ```
*/
declare function defineSrcSetBuilder(options: BuildSrcSetOptions): (yoot: Yoot) => string;
/**
* Returns a `srcset` string from a `Yoot` object using the given configuration.
*
* @public
* @param options - Configuration for srcset variants.
* @param yoot - The configured `Yoot` object.
* @returns A `srcset` string.
*
* @example
* ```tsx
* import {yoot, buildSrcSet, getImgAttrs} from '@yoot/yoot';
*
* const thumbnail = yoot({src: 'https://cdn.example.com/image.jpg', alt: 'Thumbnail'}).width(96).aspectRatio(1);
* const thumbnailAttrs = getImgAttrs(thumbnail);
* // Output (urls differ between adapters):
* // { src: 'https://cdn.example.com/image.jpg&w=96&h=96', alt: 'Thumbnail', width: 96, height: 96 }
* const thumbnailSrcSet = buildSrcSet({widths: [96, 192]}, thumbnail);
* // 'https://cdn.example.com/image.jpg&w=96&h=96 96w, https://cdn.example.com/image.jpg&w=192&h=192 192w'
*
* <img {...thumbnailAttrs} srcset={thumbnailSrcSet} />
* ```
*/
declare function buildSrcSet(options: BuildSrcSetOptions, yoot: Yoot): string;
/**
* Extracts base attributes from a `Yoot` object's `toJSON()` state.
*
* @remarks Prefers `directives` for `width`/`height` over intrinsic values.
* Includes `src`, `alt`, calculated `width`/`height`, and other non-directive state properties.
* @internal
* @param yoot - A `Yoot` object.
* @returns Object of derived HTML attributes.
*/
declare function getAttrs(yoot: Yoot): Attrs;
/**
* Attributes derived by `getAttrs` from a `Yoot` object's state.
* @internal
*/
type Attrs = {
/** Source URL */
src: string;
/** Alt text */
alt?: Maybe<string>;
/** Natural height */
naturalHeight?: number;
/** Natural width */
naturalWidth?: number;
/** Derived width */
width?: Maybe<number>;
/** Derived height */
height?: Maybe<number>;
};
/**
* Returns `<img>` attributes generated from a `Yoot` object, merged with optional custom attributes.
*
* @public
* @param yoot - A `Yoot` object.
* @param options - Optional `<img>` attributes and `srcSetBuilder`.
* @returns HTML attributes for an `<img>` element.
*
* @example
* ```ts
* import {yoot, getImgAttrs} from '@yoot/yoot';
*
* const thumbnail = yoot({
* src: 'https://cdn.example.com/image.jpg',
* alt: 'Thumbnail'
* }).width(96).aspectRatio(1);
*
* const attrs = getImgAttrs(thumbnail);
* // Output (urls differ between adapters):
* // { src: 'https://cdn.example.com/image.jpg&w=96&h=96',
* // width: 96, height: 96}
* ```
*
* @example
* ```ts
* import {yoot, getImgAttrs} from '@yoot/yoot';
*
* const thumbnail = yoot({
* src: 'https://cdn.example.com/image.jpg',
* alt: 'Thumbnail'
* }).width(96).aspectRatio(1);
*
* const attrs = getImgAttrs(thumbnail, {loading: 'lazy', 'data-img': 'thumbnail'});
* // Output (urls differ between adapters):
* // { src: 'https://cdn.example.com/image.jpg&w=96&h=96',
* // width: 96, height: 96, loading: 'lazy', 'data-img': 'thumbnail'}
* ```
*/
declare function getImgAttrs(yoot: Yoot, options?: ImgAttrsOptions): ImgAttrs;
/**
* Return type for `getImgAttrs`.
* @public
*/
type ImgAttrs = Prettify<{
src: string;
} & {
[Key in keyof HTMLImageAttributes]?: NonNullable<HTMLImageAttributes[Key]>;
}>;
/**
* Options for `getImgAttrs` and `withImgAttrs`.
*
* @remarks Allows passthrough of `HTMLImgAttributes`.
* `srcSetBuilder` is used for `srcset`. `alt` acts as a fallback.
* @public
*/
type ImgAttrsOptions = Prettify<WithSrcSetBuilder & Omit<ImgAttrs, 'height' | 'src' | 'width'>>;
/**
* Returns a function that generates HTML attributes for an `<img>` tag.
*
* @remarks Merges provided attributes with derived ones. Supports fallback for `alt`.
*
* @public
* @param options - `<img>` attributes and optional `srcSetBuilder`.
* @returns A function that accepts a `Yoot` object and returns HTML `<img>` attributes.
*/
declare function withImgAttrs(options: ImgAttrsOptions): (yoot: Yoot, overrideOptions?: ImgAttrsOptions) => ImgAttrs;
/**
* Returns `<source>` attributes generated from a `Yoot` object, merged with optional custom attributes.
*
* @public
* @param yoot - A `Yoot` object.
* @param options - Optional `<source>` attributes and `srcSetBuilder`.
* @returns HTML attributes for a `<source>` element.
*/
declare function getSourceAttrs(yoot: Yoot, options?: SourceAttrsOptions): SourceAttrs;
/**
* Return type for `getSourceAttrs`.
* @public
*/
type SourceAttrs = {
[Key in keyof HTMLSourceAttributes]: NonNullable<HTMLSourceAttributes[Key]>;
};
/**
* Options for `getSourceAttrs` and `withSourceAttrs`.
*
* @remarks Allows `HTMLSourceAttributes` with an optional `srcSetBuilder` function.
* @public
*/
type SourceAttrsOptions = Prettify<Omit<SourceAttrs, 'height' | 'src' | 'width'> & WithSrcSetBuilder>;
/**
* Optional function to generate a `srcset` string.
* @public
*/
type WithSrcSetBuilder = {
/** Receives a Yoot object to generate a `srcset` string. */
srcSetBuilder?: (yoot: Yoot) => string;
};
/**
* Returns a function that generates HTML attributes for a `<source>` tag.
*
* @remarks Merges provided attributes with derived ones.
*
* @public
* @param options - `<source>` attributes and optional `srcSetBuilder`.
* @returns A function that accepts a `Yoot` object and returns HTML `<source>` attributes.
*
* @example
* ```tsx
* // yoot-presets.ts
* import {withSourceAttrs} from '@yoot/yoot';
*
* export const thumbnailPreset = yoot().width(96).aspectRatio(1);
*
* export const getThumbnailSourceAttrs = withSourceAttrs({
* srcSetBuilder: buildSrcSet({widths: [96, 192]}), // Or, buildSrcSet({densities: [1, 2, 3]})
* sizes: '96w',
* media:'(min-width: 1024px)'
* });
*
* // somewhere else in your app
* import {yoot, getImgAttrs} from '@yoot/yoot';
* import {thumbnailPreset, getThumbnailSourceAttrs} from '@/yoot-presets';
*
* const thumbnail = thumbnailPreset({src: 'https://cdn.example.com/image.jpg', alt: 'Thumbnail'});
*
* <picture>
* <source {...getThumbnailSourceAttrs(thumbnail)} />
* <img {...getImgAttrs(thumbnail)} />
* </picture>
* ```
*/
declare function withSourceAttrs(options: SourceAttrsOptions): (yoot: Yoot, overrideOptions?: SourceAttrsOptions) => SourceAttrs;
/**
* Normalizes dimension directives (width, height, aspectRatio) in YootState.
*
* @remarks Calculates explicit `width` and `height` based on the following priority:
* 1. Explicit `width` and `height` directives (ignores `aspectRatio`).
* 2. An `aspectRatio` directive, used with any existing width/height or intrinsics.
* 3. Intrinsic aspect ratio, used to compute missing dimensions.
* The `aspectRatio` directive is set to `undefined` after processing.
*
* @internal
* @param input - The YootState with current directives and (optional) intrinsic dimensions.
* @returns A new Directives object with normalized width and height.
*/
declare function normalizeDirectives(input: YootState): Directives;
/**
* MIME types supported directly by the `yoot` API
* @internal
*/
export declare const MIME_TYPES: {
readonly jpeg: "image/jpeg";
readonly jpg: "image/jpeg";
readonly png: "image/png";
readonly webp: "image/webp";
};
/**
* Type representing the supported MIME types.
* @internal
*/
type MimeType = (typeof MIME_TYPES)[keyof typeof MIME_TYPES];
/**
* Infers MIME type from the `format` directive otherwise falls back to image extension.
* @internal
*/
declare function getMimeType(yoot: Yoot): MimeType | undefined;
/**
* Returns a validator that asserts the value is a number within the specified range [start, end]
* @internal
*/
declare function mustBeInRange(start: number, end: number): (key: string, value: unknown) => void | never;
/**
* Returns a validator that asserts the value is a member of the allowed set.
* @internal
*/
declare function mustBeOneOf<T extends string>(allowed: Set<T>): (key: string, value: unknown) => void;