From 7c959877276eb7af8c28f076b7b981d67b0d763d Mon Sep 17 00:00:00 2001 From: Joshua Amaju <127889846+joshamaju@users.noreply.github.com> Date: Tue, 6 May 2025 14:42:16 +0000 Subject: [PATCH 1/2] feat: get JSX element DOM node reference --- src/enact.tsx | 31 +++++++++++++++++++++++++++++-- src/examples/Counter.tsx | 25 ++++++++++++++++++------- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/enact.tsx b/src/enact.tsx index e5d2653..1e94e78 100644 --- a/src/enact.tsx +++ b/src/enact.tsx @@ -9,9 +9,11 @@ import { resource, spawn, Stream, + withResolvers, + WithResolvers, } from "effection"; -import type { ReactNode } from "react"; -import { useEffect, useState } from "react"; +import type { ReactElement, ReactNode } from "react"; +import { cloneElement, useEffect, useState } from "react"; export interface EnactComponent { (props: T): Operation; @@ -28,6 +30,31 @@ export function* render(node: ReactNode): Operation { export const $ = render; +function HOC({ + children, + resolver, +}: { + children: ReactElement; + resolver: WithResolvers; +}) { + const [ref, set_ref] = useState(null); + + useEffect(() => { + if (ref) resolver.resolve(ref); + }, [ref]); + + // @ts-expect-error + return cloneElement(children, { ref: set_ref }); +} + +export function* ref( + current: ReactElement +) { + const resolver = withResolvers(); + yield* render({current}); + return resolver.operation; +} + const RenderContext = createContext<(node: ReactNode) => void>("enact.render"); export function enact(component: EnactComponent): ReactComponent { diff --git a/src/examples/Counter.tsx b/src/examples/Counter.tsx index da57bdc..2ae0ccb 100644 --- a/src/examples/Counter.tsx +++ b/src/examples/Counter.tsx @@ -1,4 +1,5 @@ -import { enact, useValue } from "../enact.tsx"; +import { sleep } from "effection"; +import { ref, enact, useValue } from "../enact.tsx"; /** * ```ts @@ -13,12 +14,22 @@ import { enact, useValue } from "../enact.tsx"; } ``` */ -export const Counter = enact(function*() { - let count = useValue(0); - - return ( - - ); + ); + + const dom = yield* node; + + yield* sleep(2000); + + dom.style.backgroundColor = 'red'; + + yield* sleep(2000); + + dom.style.backgroundColor = 'blue'; }) \ No newline at end of file From d2e8ce9677babcaa7b6109456fdbf682af9144bd Mon Sep 17 00:00:00 2001 From: Joshua Amaju <127889846+joshamaju@users.noreply.github.com> Date: Tue, 6 May 2025 18:04:23 +0000 Subject: [PATCH 2/2] feat: add ref hook helper --- src/enact.tsx | 20 ++++++++++++++++++++ src/examples/Counter.tsx | 8 +++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/enact.tsx b/src/enact.tsx index 1e94e78..91de2ff 100644 --- a/src/enact.tsx +++ b/src/enact.tsx @@ -55,6 +55,26 @@ export function* ref( return resolver.operation; } +export function useRef() { + const ref = {current: null}; + const resolver = withResolvers(); + + const fn = resource(function*(provide) { + yield* provide(yield* resolver.operation) + }) + + return { + [Symbol.iterator]: fn[Symbol.iterator], + get current() { + return ref.current; + }, + set current(node: any) { + ref.current = node; + resolver.resolve(node) + } + } +} + const RenderContext = createContext<(node: ReactNode) => void>("enact.render"); export function enact(component: EnactComponent): ReactComponent { diff --git a/src/examples/Counter.tsx b/src/examples/Counter.tsx index 2ae0ccb..9a015eb 100644 --- a/src/examples/Counter.tsx +++ b/src/examples/Counter.tsx @@ -1,5 +1,5 @@ import { sleep } from "effection"; -import { ref, enact, useValue } from "../enact.tsx"; +import { $, useRef, enact, useValue } from "../enact.tsx"; /** * ```ts @@ -17,8 +17,10 @@ import { ref, enact, useValue } from "../enact.tsx"; export const Counter = enact(function* () { let count = useValue(0); - const node = yield* ref( - );