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');
}