diff --git a/packages/html2/src/index.ts b/packages/html2/src/index.ts index 3b42199..4c19e4f 100644 --- a/packages/html2/src/index.ts +++ b/packages/html2/src/index.ts @@ -20,6 +20,7 @@ type Wrapped = { export type NodeGenerator = (t: HtmlTemplater) => ReturnType; export class Widget implements EventTarget { + readonly nodeGenerator: NodeGenerator; readonly facet: Facet; private _node: ChildNode | null = null; parentField: Dataflow.Field; @@ -29,7 +30,15 @@ export class Widget implements EventTarget { return this._node!; } - constructor (private nodeGenerator: NodeGenerator) { + constructor (nodeGenerator: NodeGenerator); + constructor (template: string | HTMLTemplateElement, data: object); + constructor (arg0: NodeGenerator | string | HTMLTemplateElement, data?: object) { + if (data === void 0) { + this.nodeGenerator = arg0 as NodeGenerator; + } else { + this.nodeGenerator = templateGenerator(arg0 as (string | HTMLTemplateElement), data); + } + this.facet = Turn.activeFacet; const cancelAtExit = this.facet.actor.atExit(() => this.node.remove()); @@ -151,8 +160,11 @@ export class ValueWidget extends Widget { _value: Dataflow.Field; _valueAsNumber: Dataflow.Field; - constructor (nodeGenerator: NodeGenerator, triggerEvent: 'change' | 'input' = 'change') { - super(nodeGenerator); + constructor (nodeGenerator: NodeGenerator, triggerEvent?: 'change' | 'input'); + constructor (template: string | HTMLTemplateElement, data: object, triggerEvent?: 'change' | 'input'); + constructor (arg0: NodeGenerator | string | HTMLTemplateElement, arg1?: object | 'change' | 'input', arg2?: 'change' | 'input') { + super(arg0 as any, arg1 as any); + const triggerEvent = typeof arg1 === 'string' ? arg1 : typeof arg2 === 'string' ? arg2 : 'change'; field value: string = ''; this._value = value; @@ -226,3 +238,17 @@ function spawnLocationHashTracker(ds: Ref) { } } } + +export function templateGenerator( + template0: string | HTMLTemplateElement, + data: object, +): NodeGenerator { + const template = typeof template0 === 'string' ? document.querySelector(template0) : template0; + if (template === null) throw new Error('Cannot find template: ' + template0); + const body = `return t => t\`${template.innerHTML.trim().split('`').join('\\`')}\``; + const kvs = Object.entries(data); + const keys = kvs.map(e => e[0]); + const values = kvs.map(e => e[1]); + const factory = new Function(... keys, body); + return factory(... values); +}