UNPKG

@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
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;