@glyph-cat/swiss-army-knife
Version:
GlyphCat's set of common utilities.
1,391 lines (1,310 loc) • 140 kB
TypeScript
import { DateTime } from 'luxon';
import { Properties } from 'csstype';
import { Property } from 'csstype';
import { ReadOnlyStateManager } from 'cotton-box';
import { SimpleStateManager } from 'cotton-box';
/**
* Appends styles to [`document.head`](https://developer.mozilla.org/docs/Web/HTML/Element/head)
* using the [`<style>`](https://developer.mozilla.org/docs/Web/HTML/Element/style) element.
* @param styles - Styles written as plain CSS string. Consider using `StyleMap.toString` to generate the string from a JavaScript object for better readability and code maintainability.
* @param precedenceLevel - Precedence level of the stylesheet.
* @returns A callback function that when called, removes the appended styles.
* @public
*/
export declare function addStyles(styles: string, precedenceLevel?: PrecedenceLevel, styleElementRef?: RefObject<HTMLStyleElement>): CleanupFunction;
/**
* Create an empty promise that is resolved after a specified time. The delay
* can be cancelled at any time. If your application does not require such
* flexibility, use `delay` instead, which consumes less system resources.
* @public
*/
export declare class AdjustableDelay {
private readonly time;
/**
* @param time - The delay time in milliseconds.
* @example
* const myAdjustableDelay = new AdjustableDelay()
*/
constructor(time: number);
/**
* Run the delay.
* @example
* await myAdjustableDelay.now()
*/
now(): Promise<void>;
/**
* ## Placeholder method - not actually available yet.
* Add time to the delay. Only effective if the delay has not yet resolved.
* @example
* await myAdjustableDelay.add(1000)
*/
add(time: number): void;
/**
* Cancel the delay.
* @example
* myAdjustableDelay.cancel()
*/
cancel(): void;
}
/**
* @public
*/
export declare class AggregateWatcher<A extends Array<unknown>> extends Watcher<A> {
private watchers;
private unwatchList;
private _refresh;
constructor(watchers: Array<Watcher<A>>);
unwatchAll(): void;
}
/**
* @public
*/
export declare function AnimationTiming(durationInMilliseconds: number): any;
/**
* Regular expression to check against user agent strings to determine if they
* indicate the client is running on an Apple platform.
*
* This has been tested on the following platforms:
* - macOS 15.3
* - iOS 18.3
* - iPadOS 18.3
* - visionOS 2.3
*
* @public
*/
export declare const APPLE_PLATFORM_REGEX: RegExp;
/**
* @public
*/
export declare class AppUtils {
readonly internalAppIdentifier: string;
constructor(internalAppIdentifier: string);
createStorageKey(key: string): string;
clearStorage(storage: Storage): void;
clearLocalStorage(): void;
clearSessionStorage(): void;
clearAllStorage(): void;
}
/**
* A equality checking function similar to React's.
* @param deps1 - First set of dependencies
* @param deps2 - Second set of dependencies
* @returns A boolean indicating whether both sets of dependencies are equal.
* @example
* const deps1 = [42, true, 'foo']
* const deps2 = [42, false, 'bar']
* const areEqual = areDepsEqual(deps1, deps2)
* @public
*/
export declare function areDepsEqual(deps1: Array<unknown>, deps2: Array<unknown>): boolean;
/**
* @public
*/
export declare type Awaitable<T> = T | Promise<T>;
/**
* @author Gerrit0
* @see https://stackoverflow.com/a/49889856/5810737
* @example
* async function getString(): Promise<string> {
* return 'Hello, world!'
* }
* let myString: Awaited<Promise<string>>
* myString = await getString()
* @public
*/
declare type Awaited_2<T> = T extends PromiseLike<infer U> ? {
0: Awaited_2<U>;
1: U;
}[U extends PromiseLike<any> ? 0 : 1] : T;
export { Awaited_2 as Awaited }
/**
* @example
* async function getString(): Promise<string> {
* return 'Hello, world!'
* }
* let myString: AwaitedReturnType<typeof getString>
* myString = await getString()
* @public
*/
export declare type AwaitedReturnType<T extends TypedFunction> = Awaited_2<ReturnType<T>>;
/**
* A base class hash factory for unique hash generation.
* @public
*/
export declare class BaseHashFactory<GeneratorArg = unknown> {
constructor(
/**
* @internal
*/
generator: HashGenerator);
/**
* Creates a new hash.
*/
create(...customArgs: Array<GeneratorArg>): string;
/**
* Removes the hash from the history. Once removed, it becomes possible again
* for that hash to be returned by the {@link BaseHashFactory.prototype.create | `.create`}
* method.
*/
untrack(hash: string): void;
/**
* The list of hashes generated so far.
*/
get history(): Array<string>;
/**
* Resets the history of generated hashes. Once reset, it becomes possible again
* for all previously generated hashes to be returned by the
* {@link BaseHashFactory.prototype.create | `.create`} method.
*/
reset(): void;
/**
* Feeds an array of hashes that are supposedly already in use so that they
* will be avoided when creating new hashes.
* @param hashes - The array of hashes that are somehow already in use and
* should not be generated.
*/
track(...hashes: Array<string>): void;
/**
* Check if a hash has already been generated by this hash factory.
* @param hash - The hash to check against
* @returns `true` if the hash has already been generated, otherwise `false`.
*/
has(hash: string): boolean;
}
/**
* Hash of the Git commit in which the package's version is built.
* @public
*/
export declare const BUILD_HASH: string;
/**
* The package's build type.
* @public
*/
export declare const BUILD_TYPE: BuildType;
/**
* The available build types of the package.
* @public
*/
export declare enum BuildType {
/**
* Common JS
*/
CJS = "CJS",
/**
* EcmaScript
*/
ES = "ES",
/**
* EcmaScript (minified)
*/
MJS = "MJS",
/**
* React Native
*/
RN = "RN",
/**
* Universal Module Definition
*/
UMD = "UMD",
/**
* Universal Module Definition (Minified)
*/
UMD_MIN = "UMD_MIN"
}
/**
* An alias for {@link concatClassNames}.
* @public
*/
export declare const c: typeof concatClassNames;
/**
* Simple case conversion utility that only takes a limited range of characters
* into consideration:
* - Alphabets (A-Z, a-z)
* - Numbers (0-9)
* - Dashes (`-`)
* - Underscores (`_`)
* - Spaces (` `)
*
* Latin, Greek and Cyrillic characters are not taken into consideration.
* @public
*/
export declare class Casing {
readonly value: string;
static getWords(value: string): Array<string>;
static capitalizeFirstLetter(value: string, forceLowerCaseOnOtherLetters?: boolean): string;
readonly words: Array<string>;
constructor(value: string);
private isWordOriginatedFromMacroCase;
/**
* @example 'LoremIpsumDolorSitAmet'
*/
toPascalCase(): string;
/**
* @example 'loremIpsumDolorSitAmet'
*/
toCamelCase(): string;
/**
* @example 'LOREM_IPSUM_DOLOR_SIT_AMET'
*/
toMacroCase(): string;
/**
* @example 'lorem_ipsum_dolor_sit_amet'
*/
toSnakeCase(): string;
/**
* @example 'lorem-ipsum-dolor-sit-amet'
*/
toKebabCase(): string;
/**
* @example 'Lorem Ipsum Dolor Sit Amet'
*/
toTitleCase(): string;
/**
* @example 'LoReM IpSuM DoLoR SiT AmEt'
*/
toSpongeCase(options?: SpongeCaseOptions): string;
}
/**
* @public
*/
export declare const Charset: {
readonly DEFAULT: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
readonly NUMERIC: "0123456789";
readonly HEX_LOWER: "0123456789abcdef";
readonly HEX_UPPER: "0123456789ABCDEF";
readonly ALPHABET_LOWER: "abcdefghijklmnopqrstuvwxyz";
readonly ALPHABET_UPPER: "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
readonly ALPHANUMERIC_LOWER: "abcdefghijklmnopqrstuvwxyz0123456789";
readonly ALPHANUMERIC_UPPER: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
};
/**
* Checks if the current platform is an Apple platform based on
* the user agent string. This method should only be run on client side.
* @public
*/
export declare function checkIsApplePlatform(): boolean;
/**
* @public
* @example
* const newArray = chunk(['a', 'b', 'c', 'd', 'e', 'f', 'g'], 3)
* console.log(newArray) // [['a', 'b', 'c'], ['d', 'e', 'f'], ['g']]
*/
export declare function chunk<T>(array: Array<T>, size: number): Array<Array<T>>;
/**
* Makes sure a number stays within a given range.
* @param value - The value to be clamped.
* @param lowerBound - The minimum value allowed.
* @param upperBound - The maximum value allowed.
* @returns The clamped number.
* @example
* clamp(5, 0, 10) // 5
* clamp(-5, 0, 10) // 0
* clamp(15, 0, 10) // 10
* @public
*/
export declare function clamp(value: number, lowerBound: number, upperBound: number): number;
/**
* Add new items to the end of an array and removes old items from the front if
* its length exceeds the specified limit.
* @param maxSize - Maximum size of array allowed.
* @param items - The items to push.
* @param array - The original array.
* @returns A new array containing the new items.
* @example
* const array = [1, 2, 3, 4]
* const output = clampedPush(7, [5, 6, 7, 8], array)
* console.log(output) // [2, 3, 4, 5, 6, 7, 8]
* @public
*/
export declare function clampedPush<T>(maxSize: number, items: Array<T>, array: Array<T>): Array<T>;
/**
* Add new items to the front of an array and removes old items from the end if
* its length exceeds the specified limit.
* @param maxSize - Maximum size of array allowed.
* @param items - The items to unshift.
* @param array - The original array.
* @returns A new array containing the new items.
* @example
* const array = [1, 2, 3, 4]
* const output = clampedUnshift(7, [5, 6, 7, 8], array)
* console.log(output) // [8, 7, 6, 5, 1, 2, 3]
* @example
* const array = [1, 2, 3, 4]
* const output = clampedUnshift(7, [5, 6, 7, 8], array)
* console.log(output) // [5, 6, 7, 8, 1, 2, 3]
* @public
*/
export declare function clampedUnshift<T>(maxSize: number, items: Array<T>, array: Array<T>, options?: ClampedUnshiftOptions): Array<T>;
/**
* @public
*/
export declare interface ClampedUnshiftOptions {
/**
* @defaultValue `false`
*/
harshJoin?: boolean;
}
/**
* @public
*/
export declare type CleanupFunction<T = unknown> = (object?: T) => void;
/**
* Only invoke the callback in client environment only.
* @param callback - The callback to run in client only.
* @returns The payload of the callback, if any.
* @public
*/
export declare function clientOnly<F extends TypedFunction>(callback: F): PossiblyUndefined<ReturnType<F>>;
/**
* @public
*/
export declare class Color {
static readonly MIN_ALPHA_VALUE = 0;
static readonly MAX_ALPHA_VALUE = 1;
static readonly MIN_RGB_VALUE = 0;
static readonly MAX_RGB_VALUE = 255;
static readonly MIN_HUE_VALUE = 0;
static readonly MAX_HUE_VALUE = 360;
static readonly MIN_SATURATION_VALUE = 0;
static readonly MAX_SATURATION_VALUE = 100;
static readonly MIN_LIGHTNESS_VALUE = 0;
static readonly MAX_LIGHTNESS_VALUE = 100;
/**
* Creates a {@link Color} from a string that represents a color in RGB format.
* @param value - A case-insensitive string representing the color.
* Leading and trailing spaces are not allowed.
* @returns A {@link Color} instance with the given values.
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb
* @example
* Color.fromRGB('rgb(255, 0, 0)')
*/
static fromRGB(string: string): Color;
/**
* Creates a {@link Color} from a JavaScript object that contains the RGB values of a color.
* @param value - The JavaScript object representing the color.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromRGB({ red: 255, blue: 0, green: 0 })
*/
static fromRGB(json: WithAlphaAsOptional<SerializedRGB>): Color;
/**
* Creates a {@link Color} from the given RGB values.
* @param red - The red value represented by an integer between `0` to `255`.
* @param green - The green value represented by an integer between `0` to `255`.
* @param blue - The blue value represented by an integer between `0` to `255`.
* @param alpha - The alpha value represented by a decimal between `0.0` to `1.0`.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromRGB(255, 0, 0)
*/
static fromRGB(red: number, green: number, blue: number, alpha?: number): Color;
/**
* Creates a {@link Color} from a string that represents a color in RGB format.
* @param value - A case-insensitive string representing the color.
* Leading and trailing spaces are not allowed.
* @returns A {@link Color} instance with the given values.
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb
* @example
* Color.fromRGB('rgb(255, 0, 0)')
*/
static fromRGBString(value: string): Color;
/**
* Creates a {@link Color} from a JavaScript object that contains the RGB values of a color.
* @param value - The JavaScript object representing the color.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromRGBObject({ red: 255, blue: 0, green: 0 })
*/
static fromRGBObject(value: WithAlphaAsOptional<SerializedRGB>): Color;
/**
* Creates a {@link Color} from the given RGB values.
* @param red - The red value represented by an integer between `0` to `255`.
* @param green - The green value represented by an integer between `0` to `255`.
* @param blue - The blue value represented by an integer between `0` to `255`.
* @param alpha - The alpha value represented by a decimal between `0.0` to `1.0`.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromRGBValues(255, 0, 0)
*/
static fromRGBValues(red: number, green: number, blue: number, alpha?: number): Color;
/**
* Creates a {@link Color} from a string that represents a color in HSL format.
* @param value - A case-insensitive string representing the color.
* Leading and trailing spaces are not allowed.
* @returns A {@link Color} instance with the given values.
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl
* @example
* Color.fromHSL('hsl(0, 100%, 50%)')
*/
static fromHSL(string: string): Color;
/**
* Creates a {@link Color} from a JavaScript object that contains the HSL values of a color.
* @param value - The JavaScript object representing the color.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromHSL({ hue: 0, saturation: 100, lightness: 50 })
*/
static fromHSL(json: WithAlphaAsOptional<SerializedHSL>): Color;
/**
* Creates a {@link Color} from the given HSL values.
* @param hue - The hue, in degrees, represented by an integer between `0` to `360`.
* @param saturation - The saturation, in percentage, represented by an integer between `0` to `100`.
* @param lightness - The lightness, in percentage, represented by an integer between `0` to `100`.
* @param alpha - The alpha value represented by a decimal between `0.0` to `1.0`.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromHSL(0, 100, 50)
*/
static fromHSL(hue: number, saturation: number, lightness: number, alpha?: number): Color;
/**
* Creates a {@link Color} from a string that represents a color in HSL format.
* @param value - A case-insensitive string representing the color.
* Leading and trailing spaces are not allowed.
* @returns A {@link Color} instance with the given values.
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl
* @example
* Color.fromHSLString('hsl(0, 100%, 50%)')
*/
static fromHSLString(value: string): Color;
/**
* Creates a {@link Color} from a JavaScript object that contains the HSL values of a color.
* @param value - The JavaScript object representing the color.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromHSLObject({ hue: 0, saturation: 100, lightness: 50 })
*/
static fromHSLObject(value: WithAlphaAsOptional<SerializedHSL>): Color;
/**
* Creates a {@link Color} from the given HSL values.
* @param hue - The hue, in degrees, represented by an integer between `0` to `360`.
* @param saturation - The saturation, in percentage, represented by an integer between `0` to `100`.
* @param lightness - The lightness, in percentage, represented by an integer between `0` to `100`.
* @param alpha - The alpha value represented by a decimal between `0.0` to `1.0`.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromHSLValues(0, 100, 50)
*/
static fromHSLValues(hue: number, saturation: number, lightness: number, alpha?: number): Color;
/**
* Creates a {@link Color} from a string that represents a color in hex format.
* @param value - A hex formatted string (not case-sensitive).
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromHex('#ff0000)
*/
static fromHex(value: string): Color;
/**
* Creates a {@link Color} from a string that represents a color either in hex/rgb/hsl format.
* @param value - A hex/rgb/hsl formatted string (not case-sensitive).
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromString('#ff0000')
* Color.fromString('rgb(255, 0, 0)')
* Color.fromString('hsl(0, 100%, 50%)')
*/
static fromString(value: string): Color;
/**
* Creates a {@link Color} from a JavaScript object that contains either the
* RGB or HSL values of a color.
* @param value - The JavaScript object representing the color.
* @returns A {@link Color} instance with the given values.
* @example
* Color.fromJSON({ red: 255, blue: 0, green: 0 })
* Color.fromJSON({ hue: 0, saturation: 100, lightness: 50 })
*/
static fromJSON(value: WithAlphaAsOptional<SerializedRGB> | WithAlphaAsOptional<SerializedHSL>): Color;
private constructor();
/**
* A flag indicating whether the color has invalid values.
*/
get isInvalid(): boolean;
/**
* The red value represented by an integer between `0` to `255`.
*/
get red(): number;
/**
* The green value represented by an integer between `0` to `255`.
*/
get green(): number;
/**
* The blue value represented by an integer between `0` to `255`.
*/
get blue(): number;
/**
* The alpha value represented by a decimal between `0.0` to `1.0`.
*/
get alpha(): number;
/**
* The hue, in degrees, represented by an integer between `0` to `360`.
*/
get hue(): number;
/**
* The saturation, in percentage, represented by an integer between `0` to `100`.
*/
get saturation(): number;
/**
* The lightness, in percentage, represented by an integer between `0` to `100`.
*/
get lightness(): number;
/**
* The perceived brightness of the color, in percentage, represented by a number
* between `0` to `100`.
*/
get luminance(): number;
/**
* Serializes the color into a JavaScript object.
* @returns A plain JavaScript object representing the color.
*/
toJSON(): SerializedColor;
/**
* Converts the color into a string representation.
* @param format - The {@link ColorFormat}.
* @param options - Additional formatting options.
* @returns A string representation of the color.
* @example
* const color = Color.fromString('#00ff00')
*
* console.log(color.toString(ColorFormat.RGB))
* console.log(color.toString(ColorFormat.HSL))
* console.log(color.toString())
*
* // The equivalent of calling `toString` without any parameters:
* console.log(`The hex color code for green is ${color}`)
*/
toString(format?: ColorFormat, options?: ToStringOptions): string;
/**
* Shorthand of {@link Color.prototype.toString | `.toString()`} without any parameters.
* @returns A string representation of the color.
*/
valueOf(): string;
}
/**
* @public
*/
export declare enum ColorFormat {
/**
* red-green-blue.
* @example
* `'RGB(255, 255, 255)'`
*/
RGB = "RGB",
/**
* red-green-blue-alpha.
* @example
* `'RGBA(255, 255, 255, 1)'`
*/
RGBA = "RGBA",
/**
* hue-saturation-lightness
* @example
* `'HSL(0, 0%, 100%)'`
*/
HSL = "HSL",
/**
* hue-saturation-lightness-alpha.
* @example `'HSLA(0, 0%, 100%, 1)'`
*/
HSLA = "HSLA",
/**
* Short hex string.
* @example `'#FFF'`
*/
FFF = "FFF",
/**
* Short hex string including alpha.
* @example `'#FFFF'`
*/
FFFF = "FFFF",
/**
* Long hex string.
* @example `'#FFFFFF'`
*/
FFFFFF = "FFFFFF",
/**
* Long hex string including alpha.
* @example `'#FFFFFFFF'`
*/
FFFFFFFF = "FFFFFFFF"
}
/**
* @public
*/
export declare namespace ColorLookup {
/**
* Get a {@link Color} from the CSS color name.
* @param name - Name of the color.
* @returns A {@link Color} object if it is a valid CSS color name, otherwise `null`.
* @example
* ColorLookup.fromCSSName('red')
* ColorLookup.fromCSSName('blue')
* ColorLookup.fromCSSName('aquamarine')
* ColorLookup.fromCSSName('peachpuff')
* @public
*/
export function fromCSSName(name: LenientString<CSSColor>): Color;
/**
* Get the CSS color name from a color.
* @param color - A color string or {@link Color} object.
* @returns A string representing the name of the color if it happens to have a
* @example
* const color = Color.fromString('#556b2f')
* ColorLookup.toCSSName(color) // 'darkolivegreen'
* ColorLookup.toCSSName('#7fffd4') // 'aquamarine'
* name, otherwise `null`.
* @public
*/
export function toCSSName(color: string | Color): Nullable<CSSColor>;
}
/**
* @public
*/
export declare enum ColorScheme {
dark = "dark",
light = "light"
}
/**
* @public
*/
export declare namespace ColorUtil {
/**
* Converts HSL values to RGB values.
*
* References:
* - ✅ https://www.30secondsofcode.org/js/s/rgb-hex-hsl-hsb-color-format-conversion/#hsl-to-rgb
* - ✅ https://css-tricks.com/converting-color-spaces-in-javascript/#aa-hsl-to-rgb
* - ❌ https://stackoverflow.com/a/9493060/5810737
*
* @param hue - The hue, in degrees, represented by an integer between `0` to `360`.
* @param saturation - The saturation, in percentage, represented by an integer between `0` to `100`.
* @param lightness - The lightness, in percentage, represented by an integer between `0` to `100`.
* @returns A tuple containing 3 numbers (each between `0` to `255`) that represent
* the `[red, green, blue]` values.
* @public
*/
export function fromHSLToRGB(hue: number, saturation: number, lightness: number): NumericValues3;
/**
* Converts RGB values to HSL values.
* @param red - The red value represented by an integer between `0` to `255`.
* @param green - The green value represented by an integer between `0` to `255`.
* @param blue - The blue value represented by an integer between `0` to `255`.
* @returns A tuple containing 3 numbers that represent the `[hue, saturation, lightness]`
* where hue is an integer between `0` to `360`, and saturation and lightness
* are each integers between `0` to `100`.
* @public
*/
export function fromRGBToHSL(red: number, green: number, blue: number): NumericValues3;
/**
* Determine the perceived brightness of a color.
* @param red - The red value represented either by an integer between `0` to `255`
* or a decimal between `0.0` to `1.0`, but this must be consistent across
* all three parameters.
* @param green - The green value represented either by an integer between `0` to `255`
* or a decimal between `0.0` to `1.0`, but this must be consistent across
* all three parameters.
* @param blue - The blue value represented either by an integer between `0` to `255`
* or a decimal between `0.0` to `1.0`, but this must be consistent across
* all three parameters.
* @returns An integer representing the luminance between `0` to `100`.
* @public
*/
export function getLuminance(red: number, green: number, blue: number): number;
/**
* @returns A function that accepts a color and returns the corresponding
* light or dark values based on the threshold set.
* @example
* const getColorFromBg = createContrastingValue({
* light: '#000000',
* dark: '#FFFFFF',
* })
* getColorFromBg('#115522') // '#FFFFFF'
* getColorFromBg('#AACCFF') // '#000000'
* @example
* const checkIfBgIsDark = createContrastingValue({
* light: false,
* dark: true,
* })
* @public
*/
export function createContrastingValue<T>({ light: lightValue, dark: darkValue, threshold, }: ContrastingValueSpecifications<T>): ((bgColor: string) => T);
}
/**
* Transforms an object containing values that are assumed to be CSS variables,
* into a one-line string.
* @param values - An object containing the custom values.
* @param identifier - Can be a CSS class name or ID or selectors such as `':root'`. The leading dot can be omitted when it is a CSS class name.
* @example
* // Without identifier
* compileCSSVariables({ size: 36, duration: '300ms', color: '#00ff00' })
* // --size:36px;--duration:300ms;--color:#00ff00
*
* // Without identifier:
* compileCSSVariables({ size: 36, duration: '300ms', color: '#00ff00' }, 'foo')
* // .foo{--size:36px;--duration:300ms;--color:#00ff00}
* @public
*/
export declare function compileCSSVariables(values: CustomCSSVariablesRecord, identifier?: string): string;
/**
* Uses {@link compileStyleObjectToString} to compile a complete CSS syntax string
* for one CSS class/selector.
* @param key - The CSS class/selector.
* @param styles - The style object.
* @example
* compileStyle('.foo', { backgroundColor: '#ffffff' })
* // Output: '.foo{background-color:#ffffff}'
* @public
*/
export declare function compileStyle(key: string, styles: ExtendedCSSProperties): string;
/**
* Similar to {@link convertStyleObjectPropertyKeys}, but this takes it a step
* further by compiling the styles into a CSS syntax string.
* @param styles - The style object.
* @example
* compileStyleObjectToString({
* backgroundColor: '#ffffff',
* fontSize: '14pt',
* })
* // Output: '{background-color:#ffffff;font-size:14pt}'
* @public
*/
export declare function compileStyleObjectToString(styles: ExtendedCSSProperties): string;
/**
* Creates a new object with the deeply nested property modified.
* This does not mutate the original object.
* This is similar to {@link deepSet} except the value is modified using a function
* where the function will have context to the current value of the property that
* it is about to replace.
* @param object - The object to modify.
* @param pathSegments - Path to the property in the object.
* @param setter - A function that receives two parameters (the current value if
* the property exists, else undefined, and a boolean indicating whether the property
* exists (NOTE: a property can exist while having `undefined` as value)).
* @returns A new object with the modified property.
* @example
* const sourceObject = { foo: { bar: 1 } }
* const output = deepSet(sourceObject, 'foo.bar', (value) => value + 1)
* // sourceObject: { foo: { bar: 1 } }
* // output: { foo: { bar: 2 } }
* @public
*/
export declare function complexDeepSet<T, K = unknown>(object: T, pathSegments: ObjectPathSegments, setter: (value: K, exists: boolean) => unknown): T;
/**
* Concatenates CSS class names into a string. Falsy values will be ignored.
* @public
*/
export declare function concatClassNames(...classNames: Array<string | null | undefined | false>): string;
/**
* @public
*/
export declare interface ContrastingValueSpecifications<T> {
/**
* Value to return if color is considered 'light'.
*/
light: T;
/**
* Value to return if color is considered 'dark'.
*/
dark: T;
/**
* A value between `0` to `255`.
* A color is considered 'dark' once its brightness exceeds this value.
* @defaultValue `127`
*/
threshold?: number;
}
/**
* Organizes key-value pairs such that multiple different keys would eventually
* resolve into a commonly shared value.
* @public
*/
export declare class ConvergingDictionary<Key, Value> {
private readonly expandedData;
constructor(data: Array<[keys: Array<Key>, value: Value]>);
resolve(key: Key): PossiblyUndefined<Value>;
}
/**
* Converts property keys of an object with CSS property keys from their JS form
* (camelCase) to CSS form (kebab-case). The does not mutate the original object.
* @param styles - The style object.
* @example
* convertStyleObjectPropertyKeys({
* backgroundColor: '#ffffff',
* fontSize: '14pt',
* })
* // Output:
* // {
* // 'background-color': '#ffffff',
* // 'font-size': '14pt',
* // })
* @public
*/
export declare function convertStyleObjectPropertyKeys(styles: ExtendedCSSProperties): StringRecord<ExtendedCSSProperties[keyof ExtendedCSSProperties]>;
/**
* NOTE: This assumes that the values are already sorted.
* @public
*/
export declare function createBinarySearchTree<T>(values: Array<T>): IBinarySearchTreeNode<T>;
/**
* @example
* createCustomCharset(
* Charset.ALPHANUMERIC_LOWER,
* '_-', // add underscore and dash
* )
* @public
*/
export declare function createCustomCharset(...charsets: Array<string>): string;
/**
* Creates a debounced callback.
* @param callback - The callback to be invoked.
* @param timeout - The debounce timeout.
* @returns A debounced callback.
* @example
* // To refresh components upon window resize:
* const debouncedFn = createDebouncedCallback(forceUpdateSomeComponents)
* window.addEventListener('resize', debouncedFn)
* @public
*/
export declare function createDebouncedCallback<C extends TypedFunction>(callback: C, timeout?: number): C;
/**
* Creates a debounced promise.
* @param callback - The callback to be invoked.
* @param timeout - The debounce timeout.
* @returns A promise which the underlying callback is debounced.
* @example
* // To refresh components upon window resize:
* const debouncedFn = createDebouncedPromise(() => { return someValue })
* const value = await debouncedFn()
* @public
*/
export declare function createDebouncedPromise<A extends Array<unknown>, R>(callback: (...args: A) => R, timeout?: number): (...args: A) => Promise<R>;
/**
* Creates a tuple that containing a quotient and a remainder.
* @param q - The quotient.
* @param r - The remainder.
* @returns A tuple containing the quotient and remainder.
* @public
*/
export declare function createDivModData(q: number, r: number): DivModStruct;
/**
* Creates a function that converts a value back to its enum key.
* If the value does not belong to the enum, it will be converted into a string as-is.
* @param enumObject - The enum
* @returns A function that converts a value back to its enum key.
* @public
*/
export declare function createEnumToStringConverter<T>(enumObject: any): ((value: T) => string);
/**
* Creates a linear equation based on a point and a gradient.
* @param x1 - X coordinate of the reference point.
* @param y1 - Y coordinate of the reference point.
* @param m - Gradient of the equation.
* @returns A linear equation function.
* @example
* const f = createLinearEquationFromPointAndGradient(3, 5, 1.5)
* const x = 42
* const y = f(x)
* console.log(y) // 63.5
* @public
*/
export declare function createLinearEquationFromPointAndGradient(x1: number, y1: number, m: number): (x: number) => number;
/**
* Creates a linear equation from two points.
* @param x1 - X coordinate of the first point.
* @param y1 - Y coordinate of the first point.
* @param x2 - X coordinate of the second point.
* @param y2 - Y coordinate of the second point.
* @returns A linear equation function.
* @example
* const f = createLinearEquationFromTwoPoints(3, 6, 7, 9)
* const x = 42
* const y = f(x)
* console.log(y) // 33
* @public
*/
export declare function createLinearEquationFromTwoPoints(x1: number, y1: number, x2: number, y2: number): (x: number) => number;
/**
* Alternative to React's `createRef`, for when a `RefObject` is needed in a non-React project.
* @param value - The value assigned to the ref.
* @returns A new `RefObject`.
* @public
*/
export declare function createRef<T>(value: T): RefObject<T>;
/**
* Alternative to React's `createRef`, for when a `RefObject` is needed in a non-React project.
* @param value - The value assigned to the ref.
* @returns A new `RefObject`.
* @public
*/
export declare function createRef<T>(value: Nullable<T>): RefObject<Nullable<T>>;
/**
* Alternative to React's `createRef`, for when a `RefObject` is needed in a non-React project.
* @param value - The value assigned to the ref.
* @returns A new `RefObject`.
* @public
*/
export declare function createRef<T>(value: PossiblyUndefined<T>): RefObject<PossiblyUndefined<T>>;
/**
* @public
*/
export declare class CSSClassNameFactory extends BaseHashFactory {
minimumLength: number;
readonly bumpThreshold: number;
/**
* Generates a random CSS class name which uniqueness is not guaranteed.
*/
static create(length: number): string;
/**
* A hash factory that generates random hashes while guaranteeing uniqueness.
* If collision occurs above a set threshold, the hash length will be
* increased automatically.
* @param minimumLength - The minimum length of the hash.
* @param bumpThreshold - When value is `1`, each time the number of
* _**non-unique**_ collisions reach the maximum number of combinations
* based on the character set and minimum length, the minimum length of the
* generated hash will be increased by `1`. A lower value will allow the
* minimum length to be increased before all possible combinations are exhausted,
* therefore reducing retry attempts and minimizing computing resources.
* The default value is `0.8`.
*/
constructor(minimumLength: number, bumpThreshold?: number);
/**
* Generates a random CSS class name which uniqueness is guaranteed within
* the scope of this hash factory instance.
*/
create(overwriteMinimumLength?: number): string;
}
/**
* @see https://www.w3.org/wiki/CSS/Properties/color/keywords
* @public
*/
export declare type CSSColor = 'black' | 'silver' | 'gray' | 'white' | 'maroon' | 'red' | 'purple' | 'fuchsia' | 'green' | 'lime' | 'olive' | 'yellow' | 'navy' | 'blue' | 'teal' | 'aqua' | 'aliceblue' | 'antiquewhite' | 'aqua' | 'aquamarine' | 'azure' | 'beige' | 'bisque' | 'black' | 'blanchedalmond' | 'blue' | 'blueviolet' | 'brown' | 'burlywood' | 'cadetblue' | 'chartreuse' | 'chocolate' | 'coral' | 'cornflowerblue' | 'cornsilk' | 'crimson' | 'cyan' | 'darkblue' | 'darkcyan' | 'darkgoldenrod' | 'darkgray' | 'darkgreen' | 'darkgrey' | 'darkkhaki' | 'darkmagenta' | 'darkolivegreen' | 'darkorange' | 'darkorchid' | 'darkred' | 'darksalmon' | 'darkseagreen' | 'darkslateblue' | 'darkslategray' | 'darkslategrey' | 'darkturquoise' | 'darkviolet' | 'deeppink' | 'deepskyblue' | 'dimgray' | 'dimgrey' | 'dodgerblue' | 'firebrick' | 'floralwhite' | 'forestgreen' | 'fuchsia' | 'gainsboro' | 'ghostwhite' | 'gold' | 'goldenrod' | 'gray' | 'green' | 'greenyellow' | 'grey' | 'honeydew' | 'hotpink' | 'indianred' | 'indigo' | 'ivory' | 'khaki' | 'lavender' | 'lavenderblush' | 'lawngreen' | 'lemonchiffon' | 'lightblue' | 'lightcoral' | 'lightcyan' | 'lightgoldenrodyellow' | 'lightgray' | 'lightgreen' | 'lightgrey' | 'lightpink' | 'lightsalmon' | 'lightseagreen' | 'lightskyblue' | 'lightslategray' | 'lightslategrey' | 'lightsteelblue' | 'lightyellow' | 'lime' | 'limegreen' | 'linen' | 'magenta' | 'maroon' | 'mediumaquamarine' | 'mediumblue' | 'mediumorchid' | 'mediumpurple' | 'mediumseagreen' | 'mediumslateblue' | 'mediumspringgreen' | 'mediumturquoise' | 'mediumvioletred' | 'midnightblue' | 'mintcream' | 'mistyrose' | 'moccasin' | 'navajowhite' | 'navy' | 'oldlace' | 'olive' | 'olivedrab' | 'orange' | 'orangered' | 'orchid' | 'palegoldenrod' | 'palegreen' | 'paleturquoise' | 'palevioletred' | 'papayawhip' | 'peachpuff' | 'peru' | 'pink' | 'plum' | 'powderblue' | 'purple' | 'red' | 'rosybrown' | 'royalblue' | 'saddlebrown' | 'salmon' | 'sandybrown' | 'seagreen' | 'seashell' | 'sienna' | 'silver' | 'skyblue' | 'slateblue' | 'slategray' | 'slategrey' | 'snow' | 'springgreen' | 'steelblue' | 'tan' | 'teal' | 'thistle' | 'tomato' | 'turquoise' | 'violet' | 'wheat' | 'white' | 'whitesmoke' | 'yellow' | 'yellowgreen';
/**
* @public
*/
export declare type CSSProperties = Properties<LenientString<number>>;
/**
* @public
*/
export declare type CSSVariableRecord = StringRecord<StringColorValue | number>;
/**
* @public
*/
export declare type CustomCSSVariablesRecord = StringRecord<ExtendedCSSProperties[keyof ExtendedCSSProperties]>;
/**
* @public
*/
export declare class DateTimeConverter {
constructor(config: DateTimeConverterConfig);
DateTimeToHTMLInputString(dateTime: DateTime): string;
DateTimeToSQLString(dateTime: DateTime): Nullable<string>;
DateTimeToTimestamp(dateTime: DateTime): Nullable<ITimestamp>;
HTMLInputStringToDateTime(value: string): DateTime;
SQLStringToDateTime(value: string): Nullable<DateTime>;
TimestampToDateTime(timestamp: ITimestamp): Nullable<DateTime>;
}
/**
* @public
*/
export declare interface DateTimeConverterConfig {
Timestamp?: typeof ITimestamp;
DateTime?: typeof DateTime;
}
/**
* Gets a value from a deeply nested object.
* @param object - The source object
* @param pathSegments - Path to the property in the object
* @returns A tuple containing:
* - `0`: the deeply nested value if it exists, otherwise `undefined`
* - `1`: a boolean indicating whether the value exists at the specified path
* @example
* deepGet({ foo: { bar: 42 } }, 'foo.bar') // [42, true]
* deepGet({ foo: { bar: 42 } }, 'foo.baz') // [undefined, false]
* @public
*/
export declare function deepGet<T = unknown>(object: PossiblyUndefined<unknown>, pathSegments: ObjectPathSegments): [value: PossiblyUndefined<T>, exists: boolean];
/**
* A wrapper around any function that will memoize the results based on the
* arguments passed to the function during invocation. Number of arguments and
* results to memoize can be customized.
* @param callback - The callback to memoize.
* @param cacheSize - Number of sets of arguments and results to memoize.
* (Default value: `2`)
* @returns Either a freshly calculated result or a memoized one.
* @example
* const add = (num1: number, num2: number): number => num1 + num2
* const memoizedAdd = memoize(add)
* memoizedAdd(1, 2) // `add` is invoked
* memoizedAdd(1, 2) // `add` is not invoked
* memoizedAdd(3, 4) // `add` is invoked
* memoizedAdd(1, 2) // `add` is still not invoked
* // ^ Previous results are still cached
* @public
*/
export declare function deepMemoize<A extends Array<unknown>, R>(callback: (...args: A) => R,
/**
* @defaultValue `2`
*/
cacheSize?: number, cacheSpy?: RefObject<Array<[A, R]>>): (...args: A) => R;
/**
* Creates a new object with the deeply nested property removed.
* This does not mutate the original object.
*
* NOTE: For arrays, the element will be removed using the
* [splice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
* method. To preserve the order of elements, consider using {@link deepSet} to
* replace the values with `null` or `undefined` instead.
* @param object - The object to modify.
* @param pathSegments - Path to the property in the object.
* @param options - Additional options to configure the behavior of removal.
* @returns A new object with the deeply nested property removed.
* @example
* const sourceObject = { foo: { bar: { baz: 42 } } }
* const output = deepRemove(sourceObject, 'foo.bar.baz')
* // sourceObject: { foo: { bar: { baz: 42 } } }
* // output: { foo: { bar: {} } }
* @example
* const sourceObject = { foo: { bar: { baz: 42 } } }
* const output = deepRemove(sourceObject, 'foo.bar.baz', { clean: true })
* // sourceObject: { foo: { bar: { baz: 42 } } }
* // output: {}
* @public
*/
export declare function deepRemove<T>(object: T, pathSegments: ObjectPathSegments, options?: DeepRemoveOptions): T;
/**
* @public
*/
export declare interface DeepRemoveOptions {
/**
* Removes the parent property when its last child item is also removed.
* @defaultValue `false`
*/
clean?: boolean;
}
/**
* Creates a new object with the deeply nested property modified.
* This does not mutate the original object.
*
* If in-between properties do not already exist they will be created automatically:
* - if the path segment is a number, an array will be created
* - if the path segment is a string or symbol, an object will be created
*
* If in-between properties already exist, their original types will be respected.
* For example, if a path segment is a number type but the in-between property
* is an object, then it will remain as an object even if the path segment is a number.
*
* Path segments can be specified as a string and they will be automatically split
* into an array containing either strings or numbers. To learn more about
* the splitting behavior, see {@link getObjectPathSegments}.
*
* @param object - The object to modify.
* @param pathSegments - Path to the property in the object.
* @param value - The value to set.
* @returns A new object with the modified property.
* @example
* const sourceObject = { foo: 1 }
* const output = deepSet(sourceObject, 'bar.baz[0]', 42)
* // sourceObject:
* // { foo: 1 }
* //
* // output:
* // {
* // foo: 1,
* // bar: {
* // baz: [42],
* // },
* // }
* @public
*/
export declare function deepSet<T>(object: T, pathSegments: ObjectPathSegments, value: unknown): T;
/**
* Sets a deeply nested value inside an object. This mutates the original object.
*
* If in-between properties do not already exist they will be created automatically:
* - if the path segment is a number, an array will be created
* - if the path segment is a string or symbol, an object will be created
*
* Path segments can be specified as a string and they will be automatically split
* into an array containing either strings or numbers. To learn more about
* the splitting behavior, see {@link getObjectPathSegments}.
*
* @param object - The object to modify.
* @param pathSegments - Path to the property in the object.
* @param value - The value to set.
* @example
* const sourceObject = { foo: 1 }
* deepSet(sourceObject, 'bar.baz[0]', 42)
* // sourceObject:
* // {
* // foo: 1,
* // bar: {
* // baz: [42],
* // },
* // }
* @public
*/
export declare function deepSetMutable(object: unknown, pathSegments: ObjectPathSegments, value: unknown): void;
/**
* @public
*/
export declare const DEFAULT_WINDOW_DIMENSIONS: {
height: number;
width: number;
};
/**
* Converts degrees to radians.
* @param value - The value in degree.
* @returns The value in radians.
* @public
*/
export declare function degToRad(value: number): number;
/**
* Create an empty promise that is resolved after a specified time.
* @param time - The delay time in milliseconds.
* @returns A promise that resolves to `undefined`.
* @public
*/
export declare function delay(time: number): Promise<void>;
/**
* Create an empty promise that is resolved after a set number of frames.
* The delay cannot be cancelled once executed.
* @param count - The number of frames to delay by.
* @returns A promise that resolves to `undefined`.
* @public
*/
export declare function delayByFrame(count: number): Promise<void>;
/**
* Equivalent of `console.error`.
* @public
*/
export declare function devError(...message: unknown[]): void;
/**
* Equivalent of `console.info`.
* It is okay to use `console.log` during development, but remember to remove
* them after debugging is complete.
* @public
*/
export declare function devInfo(...message: unknown[]): void;
/**
* @public
*/
export declare type DevLogType = 'info' | 'warn' | 'error';
/**
* A wrapper around console methods.
* @public
*/
export declare function devPrint(type: DevLogType, ...message: unknown[]): void;
/**
* Equivalent of `console.warn`.
* @public
*/
export declare function devWarn(...message: unknown[]): void;
/**
* @public
*/
export declare interface Dimension2D {
height: number;
width: number;
}
/**
* @param array - The array to concatenate.
* @returns The concatenated array.
* @example
* const output = displayMixedArray(['foo', 42, true, Symbol('meow')])
* console.log(output) // ['foo', 42, true, Symbol(meow)]
* @public
*/
export declare function displayMixedArray(array: ReadonlyOrWritableArray<unknown>): string;
/**
* Express the items of an array as an object notation.
* @param pathStack - The paths pointing to a child in an object.
* @returns The concatenated path.
* @example ['user', 'address', 'street', '1'] -> user.address.street[1]
* @public
*/
export declare function displayObjectPath(pathStack: ReadonlyOrWritableArray<string>): string;
/**
* @param num - The number to format.
* @returns The formatted number.
* @example
* displayOrdinalNumber(1) // 1st
* displayOrdinalNumber(2) // 2nd
* displayOrdinalNumber(3) // 3rd
* displayOrdinalNumber(4) // 4th
* @public
*/
export declare function displayOrdinalNumber(num: number | string): string;
/**
* @param array - The array to concatenate.
* @returns The concatenated array.
* @example
* const output = displayStringArray(['foo', 42, true])
* console.log(output) // ['foo', '42', 'true']
* @public
*/
export declare function displayStringArray(array: unknown[]): string;
/**
* A data structure that store the quotient and remainder of a division. There
* are two methods to use this, pick whichever that is more convenient for your
* use case.
* @example
* // Method 1 - Array destructuring
* const [quotient, remainder] = divModData
* // Method 2 - Object property
* divModData.q // is the quotient
* divModData.r // is the remainder
* @public
*/
export declare type DivModStruct = [quotient: number, remainder: number] & {
/**
* Quotient.
*/
q: number;
/**
* Remainder.
*/
r: number;
};
/**
* @public
*/
export declare const DO_NOT_MODIFY_WARNING = "// DO NOT MODIFY - THIS FILE IS AUTOMATICALLY GENERATED";
/**
* Commonly used animation timing durations in milliseconds.
* @deprecated Please use `ThemeToken.duration` or `useThemeContext().duration.…` instead.
* @public
*/
export declare const Duration: {
readonly VERY_SHORT: 50;
readonly SHORT: 100;
readonly MEDIUM: 200;
readonly LONG: 300;
readonly VERY_LONG: 500;
readonly EXTRA_LONG: 750;
/**
* @deprecated Please use `EXTRA_LONG` instead.
*/
readonly QUARTER_SECOND: 750;
readonly ONE_SECOND: 1000;
};
/**
* @example em(12) // '12em'
* @public
*/
export declare function em(value: number): string;
/**
* @public
*/
export declare namespace Empty {
/**
* @public
*/
const ARRAY: Readonly<Array<any>>;
/**
* @public
*/
const OBJECT: Readonly<Record<PropertyKey, any>>;
/**
* @public
*/
const FUNCTION: () => void;
/**
* @pub