UNPKG

chonky

Version:

A File Browser component for React

78 lines (66 loc) 2.79 kB
// Used in React hooks to indicate empty deps are intentional. import { MaybePromise, Nullable, WritableProps } from 'tsdef'; import { FileAction, FileActionEffect } from '../types/action.types'; import { Logger } from './logger'; // Used in contexts that need to provide some default value for a function. // eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars export const NOOP_FUNCTION = (...args: any[]) => { Logger.warn( `The "NOOP_FUNCTION" from the constants module was called. ` + `This can indicate a bug in one of the components. Supplied args:`, args ); }; export const isPromise = <T>(value: MaybePromise<T> | any): value is Promise<T> => { if (typeof value !== 'object' || !value) return false; const then = (value as Promise<T>).then; return then && typeof then === 'function'; }; export const defineFileAction = <Action extends FileAction>( action: Action, effect?: FileActionEffect<FileAction> ): WritableProps<Action> => { if (action.__payloadType !== undefined && (action.hotkeys || action.button)) { const errorMessage = `Invalid definition was provided for file action "${action.id}". Actions ` + `that specify hotkeys or buttons cannot define a payload type. If ` + `your application requires this functionality, define two actions ` + `and chain them using effects.`; Logger.error(errorMessage); throw new Error(errorMessage); } action.effect = effect; return action; }; /** * Recursively check the current element and the parent elements, going bottom-up. * Returns the first element to match the predicate, otherwise returns null if such * element is not found. */ export const findElementAmongAncestors = ( maybeElement: HTMLElement | any, predicate: (maybeElement: HTMLElement | any) => boolean ): Nullable<HTMLElement> => { if (!maybeElement) return maybeElement; if (predicate(maybeElement)) return maybeElement; if (maybeElement.parentElement) { return findElementAmongAncestors(maybeElement.parentElement, predicate); } return null; }; export const elementIsInsideButton = (buttonCandidate: HTMLElement | any): boolean => { return !!findElementAmongAncestors( buttonCandidate, (element: any) => element.tagName && element.tagName.toLowerCase() === 'button' ); }; export const getValueOrFallback = <T extends any>( value: T | undefined, fallback: T, desiredType?: 'boolean' | 'string' | 'number' ): NonNullable<T> => { if (desiredType) { return (typeof value === desiredType ? value : fallback) as NonNullable<T>; } return (value !== undefined ? value : fallback) as NonNullable<T>; };