-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement missing on methods (#265)
- Loading branch information
1 parent
0b247ca
commit 5ace5ad
Showing
11 changed files
with
142 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,63 @@ | ||
import { assertDefined } from '../assert/assert'; | ||
import type { RenderContext } from '../render/cursor'; | ||
import { visitJsxNode } from '../render/render'; | ||
import { ComponentScopedStyles, OnRenderProp } from '../util/markers'; | ||
import { ComponentScopedStyles, OnRenderProp, QHostAttr } from '../util/markers'; | ||
import { then } from '../util/promises'; | ||
import { styleContent, styleHost } from './qrl-styles'; | ||
import { newInvokeContext, useInvoke } from '../use/use-core'; | ||
import { getContext, getEvent, QContext } from '../props/props'; | ||
import type { JSXNode, ValueOrPromise } from '..'; | ||
import { getEvent, QContext } from '../props/props'; | ||
import type { JSXNode } from '..'; | ||
import { processNode } from '../render/jsx/jsx-runtime'; | ||
|
||
// TODO(misko): Can we get rid of this whole file, and instead teach getProps to know how to render | ||
// the advantage will be that the render capability would then be exposed to the outside world as well. | ||
|
||
export class QComponentCtx { | ||
__brand__!: 'QComponentCtx'; | ||
ctx: QContext; | ||
hostElement: HTMLElement; | ||
|
||
styleId: string | undefined | null = undefined; | ||
styleClass: string | null = null; | ||
styleHostClass: string | null = null; | ||
|
||
slots: JSXNode[] = []; | ||
|
||
constructor(hostElement: HTMLElement) { | ||
this.hostElement = hostElement; | ||
this.ctx = getContext(hostElement); | ||
} | ||
|
||
render(ctx: RenderContext): ValueOrPromise<void> { | ||
const hostElement = this.hostElement; | ||
const onRender = getEvent(this.ctx, OnRenderProp) as any as () => JSXNode; | ||
assertDefined(onRender); | ||
const event = 'qRender'; | ||
this.ctx.dirty = false; | ||
ctx.globalState.hostsStaging.delete(hostElement); | ||
|
||
const promise = useInvoke(newInvokeContext(hostElement, hostElement, event), onRender); | ||
return then(promise, (jsxNode) => { | ||
// Types are wrong here | ||
jsxNode = (jsxNode as any)[0]; | ||
|
||
if (this.styleId === undefined) { | ||
const scopedStyleId = (this.styleId = hostElement.getAttribute(ComponentScopedStyles)); | ||
if (scopedStyleId) { | ||
this.styleHostClass = styleHost(scopedStyleId); | ||
this.styleClass = styleContent(scopedStyleId); | ||
} | ||
} | ||
ctx.hostElements.add(hostElement); | ||
this.slots = []; | ||
const newCtx: RenderContext = { | ||
...ctx, | ||
component: this, | ||
export const firstRenderComponent = (rctx: RenderContext, ctx: QContext) => { | ||
ctx.element.setAttribute(QHostAttr, ''); | ||
const result = renderComponent(rctx, ctx); | ||
// if (ctx.component?.styleHostClass) { | ||
// classlistAdd(rctx, ctx.element, ctx.component.styleHostClass); | ||
// } | ||
return result; | ||
}; | ||
|
||
export const renderComponent = (rctx: RenderContext, ctx: QContext) => { | ||
const hostElement = ctx.element as HTMLElement; | ||
const onRender = getEvent(ctx, OnRenderProp) as any as () => JSXNode; | ||
const event = 'qRender'; | ||
assertDefined(onRender); | ||
|
||
// Component is not dirty any more | ||
ctx.dirty = false; | ||
rctx.globalState.hostsStaging.delete(hostElement); | ||
|
||
// Invoke render hook | ||
const promise = useInvoke(newInvokeContext(hostElement, hostElement, event), onRender); | ||
|
||
return then(promise, (jsxNode) => { | ||
// Types are wrong here | ||
jsxNode = (jsxNode as any)[0]; | ||
rctx.hostElements.add(hostElement); | ||
let componentCtx = ctx.component; | ||
if (!componentCtx) { | ||
componentCtx = ctx.component = { | ||
hostElement, | ||
slots: [], | ||
styleHostClass: undefined, | ||
styleClass: undefined, | ||
styleId: undefined, | ||
}; | ||
return visitJsxNode(newCtx, hostElement, processNode(jsxNode), false); | ||
}); | ||
} | ||
} | ||
|
||
const COMPONENT_PROP = '__qComponent__'; | ||
|
||
export function getQComponent(hostElement: Element): QComponentCtx | undefined { | ||
const element = hostElement as { [COMPONENT_PROP]?: QComponentCtx }; | ||
let component = element[COMPONENT_PROP]; | ||
if (!component) | ||
component = element[COMPONENT_PROP] = new QComponentCtx(hostElement as HTMLElement) as any; | ||
return component; | ||
} | ||
const scopedStyleId = hostElement.getAttribute(ComponentScopedStyles) ?? undefined; | ||
if (scopedStyleId) { | ||
componentCtx.styleId = scopedStyleId; | ||
componentCtx.styleHostClass = styleHost(scopedStyleId); | ||
componentCtx.styleClass = styleContent(scopedStyleId); | ||
hostElement.classList.add(componentCtx.styleHostClass); | ||
} | ||
} | ||
componentCtx.slots = []; | ||
|
||
const newCtx: RenderContext = { | ||
...rctx, | ||
component: componentCtx, | ||
}; | ||
return visitJsxNode(newCtx, hostElement, processNode(jsxNode), false); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.