From d21daa1fed6f26d61afccb6d546773f866ffcf84 Mon Sep 17 00:00:00 2001 From: Valerii <92913245+krulod@users.noreply.github.com> Date: Fri, 20 Oct 2023 19:16:24 +0300 Subject: [PATCH] fix(jsx): fix $attrs (#681) --- packages/jsx/src/index.ts | 55 +++++++++++++++++++++++---------------- packages/jsx/src/jsx.d.ts | 2 +- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/packages/jsx/src/index.ts b/packages/jsx/src/index.ts index 2ec835393..d9c01a745 100644 --- a/packages/jsx/src/index.ts +++ b/packages/jsx/src/index.ts @@ -43,39 +43,48 @@ export const reatomJsx = (ctx: Ctx) => { }) } - let create = (tag: string, props: Rec) => { + let create = (tag: string, attrs: Rec) => { let element = tag === 'svg' ? document.createElementNS('http://www.w3.org/2000/svg', tag) : document.createElement(tag) - for (let k in props) { - if (k === 'children') continue - bindAttr(element, k, props[k]) - } + bindAttrs(element, attrs) - render(element, props.children ?? []) + render(element, attrs.children ?? []) return element } - const bindAttr = (element: any, key: any, val: any) => { - if (key === '$attrs') { - const recs = Array.isArray(val) ? val : [val] - for (const rec of recs) { - for (const k in rec) bindAttr(element, k, rec[k]) - } - } else if (isAtom(val)) { - if (val.__reatom.isAction) { - element[key] = (...args: any) => (val as Action)(ctx, ...args) - } else { - // TODO handle unsubscribe! - var un: undefined | Unsubscribe = ctx.subscribe(val, (val) => - !un || element.isConnected ? renderAttr(element, key, val) : un(), - ) - unlink(element, un) - } - } else renderAttr(element, key, val) + const bindAttrs = (element: Element, attrs: Rec) => { + for (const key in attrs) { + if (key === 'children') continue + const val = attrs[key] + + if (key === '$attrs') { + for (const attrs of Array.isArray(val) ? val : []) { + if (isAtom(attrs)) { + var u = ctx.subscribe(attrs, (attrs): void => + !u || element.isConnected + ? bindAttrs(element, attrs as Rec) + : u(), + ) + unlink(element, u) + } else bindAttrs(element, attrs) + } + } else if (isAtom(val)) { + if (val.__reatom.isAction) { + ;(element as any)[key] = (...args: any) => + (val as Action)(ctx, ...args) + } else { + // TODO handle unsubscribe! + var un: undefined | Unsubscribe = ctx.subscribe(val, (val) => + !un || element.isConnected ? renderAttr(element, key, val) : un(), + ) + unlink(element, un) + } + } else renderAttr(element, key, val) + } } const renderAttr = (element: any, key: any, val: any) => { diff --git a/packages/jsx/src/jsx.d.ts b/packages/jsx/src/jsx.d.ts index 375660a2f..071fa354d 100644 --- a/packages/jsx/src/jsx.d.ts +++ b/packages/jsx/src/jsx.d.ts @@ -110,7 +110,7 @@ export namespace JSX { OnAttributes, OnCaptureAttributes, */ extends CustomEventHandlers { - $attrs?: Atom + $attrs?: AtomMaybe children?: Element innerHTML?: string innerText?: string | number