From 880961034c81e85e191c6c4b845d96506bbd4ea7 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 12 Dec 2022 10:57:14 -0300 Subject: compose, testing and async into web-util --- packages/web-util/src/components/utils.ts | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 packages/web-util/src/components/utils.ts (limited to 'packages/web-util/src/components/utils.ts') diff --git a/packages/web-util/src/components/utils.ts b/packages/web-util/src/components/utils.ts new file mode 100644 index 000000000..71824e14f --- /dev/null +++ b/packages/web-util/src/components/utils.ts @@ -0,0 +1,36 @@ +import { createElement, VNode } from "preact"; + +export type StateFunc = (p: S) => VNode; + +export type StateViewMap = { + [S in StateType as S["status"]]: StateFunc; +}; + +export type RecursiveState = S | (() => RecursiveState); + +export function compose( + hook: (p: PType) => RecursiveState, + viewMap: StateViewMap, +): (p: PType) => VNode { + function withHook(stateHook: () => RecursiveState): () => VNode { + function ComposedComponent(): VNode { + const state = stateHook(); + + if (typeof state === "function") { + const subComponent = withHook(state); + return createElement(subComponent, {}); + } + + const statusName = state.status as unknown as SType["status"]; + const viewComponent = viewMap[statusName] as unknown as StateFunc; + return createElement(viewComponent, state); + } + + return ComposedComponent; + } + + return (p: PType) => { + const h = withHook(() => hook(p)); + return h(); + }; +} -- cgit v1.2.3