interactive.ts

 1import { DeepPartial } from "utility-types";
 2import merge from "ts-deepmerge"
 3interface Interactive<T> {
 4    default: T,
 5    hover?: T,
 6    clicked?: T,
 7    disabled?: T,
 8}
 9
10/**
11 * Helper function for creating Interactive<T> objects that works pretty much like Toggle<T>.
12 * It takes a object to be used as a value for `default` field and then fills out other fields
13 * with fields from either `base` or `modifications`.
14 * Notably, it does not touch `hover`, `clicked` and `disabled` if there are no modifications for it.
15 *
16 * @param defaultObj Object to be used as the value for `default` field.
17 * @param base Object containing base fields to be included in the resulting object.
18 * @param modifications Object containing modified fields to be included in the resulting object.
19 * @returns Interactive<T> object with fields from `base` and `modifications`.
20 */
21export function interactive<T extends Object>(base: T, modifications: DeepPartial<Interactive<T>>): Interactive<T> {
22    let interactiveObj: Interactive<T> = {
23        default: base,
24    };
25    if (modifications.default !== undefined) {
26        interactiveObj.default = merge(interactiveObj.default, modifications.default) as T;
27    }
28    if (modifications.hover !== undefined) {
29        interactiveObj.hover = merge(interactiveObj.default, modifications.hover) as T;
30    }
31
32    if (modifications.clicked !== undefined) {
33        interactiveObj.clicked = merge(interactiveObj.default, modifications.clicked) as T;
34    }
35
36    if (modifications.disabled !== undefined) {
37        interactiveObj.disabled = merge(interactiveObj.default, modifications.disabled) as T;
38    }
39
40    return interactiveObj;
41}