/** * Copied from chakra-ui, license MIT * Accessed 2021-12-26, commit July 22nd, 2021 * See also: https://github.com/chakra-ui/chakra-ui/blob/82e99e2/packages/utils/src/function.ts */ /* eslint-disable no-nested-ternary */ import { __DEV__, isFunction, isNumber } from "./assertion"; import { AnyFunction, FunctionArguments } from "./types"; export function runIfFn( valueOrFn: T | ((...fnArgs: U[]) => T), ...args: U[] ): T { return isFunction(valueOrFn) ? valueOrFn(...args) : valueOrFn; } export function callAllHandlers void>( ...fns: (T | undefined)[] ) { return function func(event: FunctionArguments[0]) { fns.some((fn) => { fn?.(event); return event?.defaultPrevented; }); }; } export function callAll(...fns: (T | undefined)[]) { return function mergedFn(arg: FunctionArguments[0]) { fns.forEach((fn) => { fn?.(arg); }); }; } export const compose = ( fn1: (...args: T[]) => T, ...fns: Array<(...args: T[]) => T> ) => fns.reduce( (f1, f2) => (...args) => f1(f2(...args)), fn1, ); export function once(fn?: T | null) { let result: any; return function func(this: any, ...args: Parameters) { if (fn) { result = fn.apply(this, args); fn = null; } return result; }; } export const noop = () => {}; type MessageOptions = { condition: boolean; message: string; }; export const warn = once((options: MessageOptions) => () => { const { condition, message } = options; if (condition && __DEV__) { console.warn(message); } }); export const error = once((options: MessageOptions) => () => { const { condition, message } = options; if (condition && __DEV__) { console.error(message); } }); export const pipe = (...fns: Array<(a: R) => R>) => (v: R) => fns.reduce((a, b) => b(a), v); const distance1D = (a: number, b: number) => Math.abs(a - b); type Point = { x: number; y: number }; const isPoint = (point: any): point is { x: number; y: number } => "x" in point && "y" in point; export function distance

(a: P, b: P) { if (isNumber(a) && isNumber(b)) { return distance1D(a, b); } if (isPoint(a) && isPoint(b)) { const xDelta = distance1D(a.x, b.x); const yDelta = distance1D(a.y, b.y); return Math.sqrt(xDelta ** 2 + yDelta ** 2); } return 0; }