Files
OverlayScrollbars/packages/overlayscrollbars/src/setups/setups.ts
T
2022-07-27 11:48:34 +02:00

55 lines
1.6 KiB
TypeScript

import { assignDeep, hasOwnProperty } from 'support';
import type { Options, ReadonlyOptions } from 'options';
import type { DeepPartial } from 'typings';
export type SetupElements<T extends Record<string, any>> = [elements: T, destroy: () => void];
export type SetupUpdate<T extends any[]> = (
changedOptions: DeepPartial<Options>,
force: boolean,
...args: T
) => void;
export type SetupUpdateCheckOption = <T>(path: string) => [value: T, changed: boolean];
export type SetupUpdateSegment<Hints extends Record<string, any>> = (
updateHints: Hints,
checkOption: SetupUpdateCheckOption,
force: boolean
) => Partial<Hints> | void;
export type SetupState<T extends Record<string, any>> = [
get: () => T,
set: (newState: Partial<T>) => void
];
export type Setup<
DynamicState,
StaticState extends Record<string, any> = Record<string, any>,
A extends any[] = []
> = [update: SetupUpdate<A>, state: (() => DynamicState) & StaticState, destroy: () => void];
const getPropByPath = <T>(obj: any, path: string): T =>
obj
? path.split('.').reduce((o, prop) => (o && hasOwnProperty(o, prop) ? o[prop] : undefined), obj)
: undefined;
export const createOptionCheck =
(
options: ReadonlyOptions,
changedOptions: DeepPartial<Options>,
force?: boolean
): SetupUpdateCheckOption =>
(path: string) =>
[getPropByPath(options, path), force || getPropByPath(changedOptions, path) !== undefined];
export const createState = <S>(initialState: S): SetupState<S> => {
let state: S = initialState;
return [
() => state,
(newState: Partial<S>) => {
state = assignDeep({}, state, newState);
},
];
};