diff --git a/demos/justact-test/src/index.jsx b/demos/justact-test/src/index.jsx index 0613576..c8eb622 100644 --- a/demos/justact-test/src/index.jsx +++ b/demos/justact-test/src/index.jsx @@ -1,9 +1,10 @@ // const justact = require('justact'); import * as justact from 'justact'; +import { ForEach } from 'justact'; + class InputMultiplex extends justact.Component { render () { - console.log('InputMultiplex', this); return this.swap ? ( ) : ( @@ -18,6 +19,9 @@ class App extends justact.Component {
+ ( + + )} />
) } diff --git a/src/construct/ForEach.ts b/src/construct/ForEach.ts new file mode 100644 index 0000000..76c8c6e --- /dev/null +++ b/src/construct/ForEach.ts @@ -0,0 +1,51 @@ +import { Renderable } from '../component/componentdefs.js'; +import { Component } from '../component/Component.js'; +import { ArrayVAO } from '../vao/ArrayVAO.js'; +import { ScalarVAO } from '../vao/ScalarVAO.js'; +import { TAttributes } from '../html/htmldefs.js'; + +// === TODO === +// [A] Naive implementation - should be optimzied + +export type TForEachRender = (item: any) => Renderable | Renderable[] + +export class ForEach extends Component { + static properties = { + array: { + $: ArrayVAO + }, + render: { + $: ScalarVAO + } + } + constructor ({ attributes, children }: { + attributes: TAttributes | undefined, + children: Renderable[] | undefined + }) { + super({ attributes, children }); + + const array$ = this.vaos_['array'] as ArrayVAO; + + // TODO: [A] + ((events) => { + for ( const event of events ) { + array$.sub(event, this.rerenderSelf.bind(this)); + } + })(['change', 'item.insert', 'item.remove', 'item.replace']); + } + render () { + const array$ = this.vaos_['array'] as ArrayVAO; + const render$ = this.vaos_['render']; + + const render = render$.get() as TForEachRender; + + const outputRenderables = []; + for ( const item of array$.get() ) { + outputRenderables.push(...(result => Array.isArray(result) + ? result : [result])(render(item))); + } + + return outputRenderables; + } +} + diff --git a/src/index.ts b/src/index.ts index 7827183..7758a0b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,6 +5,7 @@ import { Component as ExportableComponent } from './component/Component.js'; import { ScalarVAO as ExportableScalarVAO } from './vao/ScalarVAO.js'; import { ArrayVAO as ExportableArrayVAO } from './vao/ArrayVAO.js'; import { AbstractVAO as ExportableAbstractVAO } from './vao/VAO.js'; +import { ForEach as ForEachExportable } from './construct/ForEach.js'; export function createElement( tag: string | RenderableConstructor, @@ -34,3 +35,4 @@ export const Component = ExportableComponent; export const AbstractVAO = ExportableAbstractVAO; export const ScalarVAO = ExportableScalarVAO; export const ArrayVAO = ExportableArrayVAO; +export const ForEach = ForEachExportable; diff --git a/src/vao/ArrayVAO.ts b/src/vao/ArrayVAO.ts index 6733dcb..c5e2527 100644 --- a/src/vao/ArrayVAO.ts +++ b/src/vao/ArrayVAO.ts @@ -24,6 +24,7 @@ export class ArrayVAO extends AbstractVAO { constructor (initialValue: any[]) { super(); + if ( initialValue == null ) initialValue = []; if ( ! Array.isArray(initialValue) ) { throw new Error('ArrayVAO expects an array'); }