From 5d4e752603947de0eb31742b3f85007cb59470b6 Mon Sep 17 00:00:00 2001 From: krulod Date: Mon, 9 Oct 2023 16:20:13 +0300 Subject: [PATCH] feat(logger): add tag factory --- packages/jsx/src/index.ts | 52 ++++++++++++--------------------------- packages/logger/src/t.ts | 16 ++++++++++++ 2 files changed, 32 insertions(+), 36 deletions(-) create mode 100644 packages/logger/src/t.ts diff --git a/packages/jsx/src/index.ts b/packages/jsx/src/index.ts index d9c01a745..a2e33f5b6 100644 --- a/packages/jsx/src/index.ts +++ b/packages/jsx/src/index.ts @@ -43,54 +43,34 @@ export const reatomJsx = (ctx: Ctx) => { }) } - let create = (tag: string, attrs: Rec) => { + let create = (tag: string, props: Rec) => { let element = tag === 'svg' ? document.createElementNS('http://www.w3.org/2000/svg', tag) : document.createElement(tag) - bindAttrs(element, attrs) - - render(element, attrs.children ?? []) - - return element - } - - 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) + for (let k in props) { + if (k === 'children') continue + let prop = props[k] + if (isAtom(prop)) { + if (prop.__reatom.isAction) { + ;(element as any)[k] = (...a: any[]) => prop(ctx, ...a) } else { // TODO handle unsubscribe! - var un: undefined | Unsubscribe = ctx.subscribe(val, (val) => - !un || element.isConnected ? renderAttr(element, key, val) : un(), + var un: undefined | Unsubscribe = ctx.subscribe(prop, (v) => + !un || element.isConnected ? ((element as any)[k] = v) : un(), ) + unlink(element, un) } - } else renderAttr(element, key, val) + } else { + ;(element as any)[k] = prop + } } - } - const renderAttr = (element: any, key: any, val: any) => { - if (key === 'style') { - for (const style in val) element.style.setProperty(style, val[style]) - } else element[key] = val + render(element, props.children ?? []) + + return element } let render = (parent: Element, children: JSXElement[]) => { diff --git a/packages/logger/src/t.ts b/packages/logger/src/t.ts new file mode 100644 index 000000000..2b121cc2f --- /dev/null +++ b/packages/logger/src/t.ts @@ -0,0 +1,16 @@ +import { ElementTag, InferProps, JSXElement, create } from '@reatom/jsx' + +type TagFactory = { + [T in ElementTag]: (props?: InferProps | JSXElement[]) => Element +} + +const factories = {} as TagFactory + +export const t = new Proxy({} as Readonly, { + get: (_, tag) => + (factories[tag as ElementTag] ??= (props = {} as any) => + create( + tag as ElementTag, + Array.isArray(props) ? { children: props } : props, + )), +})