Skip to content

Commit

Permalink
[types] Add JSDoc based on website docs (#436)
Browse files Browse the repository at this point in the history
  • Loading branch information
MysteryBlokHed authored Feb 18, 2024
1 parent ccb3164 commit 9c3c65b
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 15 deletions.
8 changes: 7 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,13 @@ module.exports = {
"@typescript-eslint/ban-ts-comment": 1,
// Disallow certain built-in types
// https://typescript-eslint.io/rules/ban-types
"@typescript-eslint/ban-types": 1,
"@typescript-eslint/ban-types": [
1,
{
extendDefaults: true,
types: { "{}": false },
},
],
// Disallow generic `Array` constructors
// https://typescript-eslint.io/rules/no-array-constructor
"@typescript-eslint/no-array-constructor": 1,
Expand Down
6 changes: 6 additions & 0 deletions types/src/display.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import ColorSpace from "./space.js";

export type Display = string & { color: PlainColorObject };

/**
* Returns a serialization of the color that can actually be displayed in the browser.
* If the default serialization can be displayed, it is returned.
* Otherwise, the color is converted to Lab, REC2020, or P3, whichever is the widest supported.
* In Node.js, this is basically equivalent to `serialize()` but returns a `String` object instead
*/
export default function display (
color: ColorTypes,
options?: {
Expand Down
36 changes: 36 additions & 0 deletions types/src/hooks.d.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
/**
* This is for plugin authors.
* If you're not interested in writing plugins for Color.js, you can skip this.
*
* Hooks afford extensibility far beyond what can be achieved
* by overriding properties and methods, or using functions.
* Hooks allow plugin authors to change how Color.js’ internal code works,
* by adding custom callbacks to predefined points in the execution.
*
* You can find available hooks by searching the source code for `hooks.run(` in color.js.
* If you need a hook that is not present, we typically accept pull requests for new hooks pretty easily!
*
* The Hooks module exports both a hooks object that is used throughout Color.js (as a default export),
* as well as a Hooks class (as a named export) that can be used to create new sets of hooks.
*/
export class Hooks {
// Can't find a way to type this more specifically
// without conflicting with the types of add and run
[name: string]: any;

/**
* Schedule a callback to be executed at a certain point in the source code
* @param name The name of the hook to add the callback to
* @param callback The code to run at the given hook.
* The callback will be callewd with (typically) the same context as the calling code,
* and a single object as its only argument (typically called `env`)
* with writeable properties for various aspects of the calling environment
* @param [first=false] Whether to prepend instead of append this callback to any existing callbacks
* on the same hook. Defaults to `false`
*/
add (
name: string | string[],
callback: (env: Record<string, any>) => void,
first?: boolean
): void;
/**
* Creates a hook for plugin authors to add code to
* @param name The name of the hook to create.
* By convention, it's in the form `[class-name]-[function name]-[location in function body]`.
* Class name can be omitted if it's in `color.js`.
* Location in function body is typically something like `"start"`, `"end'`,
* `"before-conversion"`, `"after-init"`, etc.
* @param env Object with properties to be passed to the hook's callback.
* This will also be used as the function context, unless it has a `context` property,
* in which case that is used as the function context
*/
run (name: string, env?: { context?: Record<string, any> }): void;
}

Expand Down
16 changes: 16 additions & 0 deletions types/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,20 @@ declare module "./color" {
// interpolation
// These signatures should always match those in interpolation.d.ts,
// including the static versions
/** Create color mixtures in any desired proportion between two colors */
mix (color2: ColorTypes, options?: MixOptions): Color;
mix (color2: ColorTypes, p: number, options?: MixOptions): Color;
/**
* Creates a function that accepts a number and returns a color.
* For numbers in the range 0 to 1, the function interpolates;
* for numbers outside that range, the function extrapolates
* (and thus may not return the results you expect)
*/
range: ToColorPrototype<typeof range>;
/** Get an array of discrete steps */
steps (color2: ColorTypes, options?: StepsOptions): Color[];

/** Create color mixtures in any desired proportion between two colors */
static mix (
color1: ColorTypes,
color2: ColorTypes,
Expand All @@ -85,7 +94,14 @@ declare module "./color" {
p: number,
options?: MixOptions
): Color;
/**
* Creates a function that accepts a number and returns a color.
* For numbers in the range 0 to 1, the function interpolates;
* for numbers outside that range, the function extrapolates
* (and thus may not return the results you expect)
*/
static range: typeof range;
/** Get an array of discrete steps */
static steps (
color1: ColorTypes,
color2: ColorTypes,
Expand Down
27 changes: 27 additions & 0 deletions types/src/interpolation.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,34 @@ export type Range = ((percentage: number) => Color) & {
export function isRange (val: any): val is Range;

export interface RangeOptions {
/**
* The interpolation space.
* Colors do not need to be in this space; they will be converted for interpolation
* @see {@link <https://colorjs.io/docs/interpolation#ranges>}
*/
space?: string | ColorSpace | undefined;
outputSpace?: string | ColorSpace | undefined;
/**
* Used to customize the progression and make in nonlinear
* @example
* let r = new Color("lch(50 50 0)").range("lch(90 50 20)");
* Color.range(r, { progression: p => p ** 3 });
*/
progression?: ((percentage: number) => number) | undefined;
premultiplied?: boolean | undefined;
/**
* Inspired by the
* {@link https://drafts.csswg.org/css-color-5/#hue-adjuster hue-adjuster in CSS Color 5}.
*/
hue?: "longer" | "shorter" | "increasing" | "decreasing" | "raw" | undefined;
}

/**
* Creates a function that accepts a number and returns a color.
* For numbers in the range 0 to 1, the function interpolates;
* for numbers outside that range, the function extrapolates
* (and thus may not return the results you expect)
*/
export function range (range: Range, options?: RangeOptions): Range;
export function range (
color1: ColorTypes,
Expand All @@ -25,6 +46,7 @@ export function range (

export type MixOptions = RangeOptions;

/** Create color mixtures in any desired proportion between two colors */
export function mix (
color1: ColorTypes,
color2: ColorTypes,
Expand All @@ -38,12 +60,17 @@ export function mix (
): PlainColorObject;

export interface StepsOptions extends RangeOptions {
/** max deltaE between consecutive steps */
maxDeltaE?: number | undefined;
/** @see {@link Methods} */
deltaEMethod?: Methods | undefined;
/** The minimum number of steps */
steps?: number | undefined;
/** The maximum number of steps */
maxSteps?: number | undefined;
}

/** Get an array of discrete steps */
export function steps (color1: ColorTypes, color2: ColorTypes, options?: StepsOptions): PlainColorObject[];
export function steps (range: Range, options?: StepsOptions): PlainColorObject[];

Expand Down
6 changes: 6 additions & 0 deletions types/src/parse.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ export interface Options {
meta?: object | undefined;
}

/**
* Parse a string as a color.
* Understands all {@link https://www.w3.org/TR/css-color-4/ CSS Color 4} functions.
* Uses the DOM if present to parse hex colors and color names,
* so that will not available in non-DOM environments such as Node.js
*/
export default function parse (
str: string,
options?: Options & Record<string, any>
Expand Down
33 changes: 33 additions & 0 deletions types/src/space.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,31 @@ import { White } from "./adapt.js";
import Color, { ColorConstructor, ColorObject, Coords } from "./color.js";

export interface Format {
/** @default "function" */
type?: string | undefined;
/** @default "color" */
name?: string | undefined;
id?: string | undefined;
coords?: string[] | undefined;
coordGrammar?: (string & { range?: [number, number] })[] | undefined;
serializeCoords?:
| ((coords: Coords, precision: number) => [string, string, string])
| undefined;
/** Whether to adjust the coordinates to fit in the gamut */
toGamut?: boolean | undefined;
/** Whether commas should separate arguments for a format */
commas?: boolean | undefined;
/** Whether the last coordinate is the alpha coordinate */
lastAlpha?: boolean | undefined;
/** Whether the format has an alpha channel */
noAlpha?: boolean | undefined;
test?: ((str: string) => boolean) | undefined;
/** Function to parse a string into a color */
parse?: ((str: string) => ColorConstructor) | undefined;
/**
* Serialize coordinates and an alpha channel into a string.
* Must be defined for a format to support serialization
*/
serialize?: ((coords: Coords, alpha: number, opts?: Record<string, any>) => string) | undefined;
}

Expand All @@ -27,15 +38,35 @@ export interface CoordMeta {
}

export interface Options {
/** Id of this space, used in things such as conversions */
id: string;
/** The readable name of the space, used in user-facing UI */
name: string;
/** The base color space */
base?: string | ColorSpace | null | undefined;
/**
* Function that converts coords in the base color space to coords in this color space.
* Must perform chromatic adaptation if needed
*/
fromBase?: ((coords: Coords) => number[]) | undefined;
/**
* Function that converts coords in this color space to coords in the base color space.
* Must perform chromatic adaptation if needed
*/
toBase?: ((coords: Coords) => number[]) | undefined;
/**
* Object mapping coord ids to coord metadata
* @see {@link CoordMeta}
*/
coords?: Record<string, CoordMeta> | undefined;
white?: string | White | undefined;
/** The ID used by CSS, such as `display-p3` or `--cam16-jmh` */
cssId?: string | undefined;
referred?: string | undefined;
/**
* Details about string formats to parse from / serialize to
* @see {@link Format}
*/
formats?: Record<string, Format> | undefined;
gamutSpace?: "self" | string | ColorSpace | null | undefined;
}
Expand All @@ -45,6 +76,7 @@ export type Ref =
| [string | ColorSpace, string]
| { space: string | ColorSpace; coordId: string };

/** Class for color spaces. Each color space corresponds to a `ColorSpace` instance */
export default class ColorSpace {
constructor (options: Options);

Expand Down Expand Up @@ -79,6 +111,7 @@ export default class ColorSpace {
static registry: Record<string, ColorSpace>;

get all (): Set<ColorSpace>;
/** The ID used by CSS, such as `display-p3` or `--cam16-jmh` */
get cssId (): string;
get isPolar (): boolean;

Expand Down
49 changes: 35 additions & 14 deletions types/src/toGamut.d.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,45 @@
import { ColorTypes, PlainColorObject } from "./color.js";
import { Methods } from "./deltaE/index.js";
import ColorSpace, { Ref } from "./space.js";

export interface Options {
/**
* How to force into gamut.
*
* If `"clip"`, coordinates are just clipped to their reference range.\
* If `"css"`, coordinates are reduced according to the CSS 4 Gamut Mapping Algorithm.\
* If in the form `[colorSpaceId].[coordName]`, that coordinate is reduced
* until the color is in gamut. Please note that this may produce nonsensical
* results for certain coordinates (e.g. hue) or infinite loops
* if reducing the coordinate never brings the color in gamut
* @default "css"
*/
method?: "css" | "clip" | (string & {}) | undefined;
/** The color whose space is being mapped to. Defaults to the current space */
space?: string | ColorSpace | undefined;
deltaEMethod?: Methods | undefined;
/** The "just noticeable difference" to target */
jnd?: number | undefined;
/**
* Used to configure SDR black and clamping.
* `channel` indicates the `space.channel` to use for determining when to clamp.
* `min` indicates the lower limit for black clamping and `max` indicates the upper
* limit for white clamping
*/
blackWhiteClamp?:
| {

Check warning on line 30 in types/src/toGamut.d.ts

View workflow job for this annotation

GitHub Actions / Lint & Test Types

Expected indentation of 1 tab but found 2
channel: Ref;

Check warning on line 31 in types/src/toGamut.d.ts

View workflow job for this annotation

GitHub Actions / Lint & Test Types

Expected indentation of 2 tabs but found 3
min: number;

Check warning on line 32 in types/src/toGamut.d.ts

View workflow job for this annotation

GitHub Actions / Lint & Test Types

Expected indentation of 2 tabs but found 3
max: number;

Check warning on line 33 in types/src/toGamut.d.ts

View workflow job for this annotation

GitHub Actions / Lint & Test Types

Expected indentation of 2 tabs but found 3
}
| undefined;

Check warning on line 35 in types/src/toGamut.d.ts

View workflow job for this annotation

GitHub Actions / Lint & Test Types

Expected indentation of 1 tab but found 2
}

declare namespace toGamut {
let returns: "color";
}

declare function toGamut (
color: ColorTypes,
options?: {
method?: string | undefined;
space?: string | ColorSpace | undefined;
deltaEMethod?: string | undefined;
jnd?: number | undefined;
blackWhiteClamp?: {
channel: Ref;
min: number;
max: number;
} | undefined;
} | string
): PlainColorObject;
declare function toGamut (color: ColorTypes, options?: Options | string): PlainColorObject;

export default toGamut;

Expand Down

0 comments on commit 9c3c65b

Please sign in to comment.