From 040881df3f584036570f7e07ee3fee7002e5e81f Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 16 Jun 2023 01:02:00 -0400 Subject: [PATCH] Update toggle --- styles/src/element/toggle.ts | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 styles/src/element/toggle.ts diff --git a/styles/src/element/toggle.ts b/styles/src/element/toggle.ts new file mode 100644 index 0000000000..2b6858e15b --- /dev/null +++ b/styles/src/element/toggle.ts @@ -0,0 +1,47 @@ +import merge from "ts-deepmerge" + +type ToggleState = "inactive" | "active" + +type Toggleable = Record + +const NO_INACTIVE_OR_BASE_ERROR = + "A toggleable object must have an inactive state, or a base property." +const NO_ACTIVE_ERROR = "A toggleable object must have an active state." + +interface ToggleableProps { + base?: T + state: Partial> +} + +/** + * Helper function for creating Toggleable objects. + * @template T The type of the object being toggled. + * @param props Object containing the base (inactive) state and state modifications to create the active state. + * @returns A Toggleable object containing both the inactive and active states. + * @example + * ``` + * toggleable({ + * base: { background: "#000000", text: "#CCCCCC" }, + * state: { active: { text: "#CCCCCC" } }, + * }) + * ``` + */ +export function toggleable( + props: ToggleableProps +): Toggleable { + const { base, state } = props + + if (!base && !state.inactive) throw new Error(NO_INACTIVE_OR_BASE_ERROR) + if (!state.active) throw new Error(NO_ACTIVE_ERROR) + + const inactiveState = base + ? ((state.inactive ? merge(base, state.inactive) : base) as T) + : (state.inactive as T) + + const toggleObj: Toggleable = { + inactive: inactiveState, + active: merge(base ?? {}, state.active) as T, + } + + return toggleObj +}