import * as b from "bobril"; import * as f from "fun-model"; import * as c from "./common"; export interface IComponentState extends f.IState { } export interface IContext extends b.IBobrilCtx { state: TState; cursor: f.ICursor; forceShouldChange: boolean; } export interface IComponentFactory { (children?: b.ChildrenType): b.IBobrilNode; } export function createComponent(component: b.IBobrilComponent) : (cursor: f.ICursor | c.CursorFieldsMap) => IComponentFactory { return (innerCursor: f.ICursor | c.CursorFieldsMap) => (children?: b.IBobrilChildren) => b.createDerivedComponent( b.createVirtualComponent({ init(ctx: IContext) { ctx.forceShouldChange = false; if (c.isCursor(innerCursor)) { ctx.cursor = innerCursor; ctx.state = f.getState(ctx.cursor); } else { Object.keys(innerCursor).forEach(ck => { (ctx)[c.unifyCursorName(ck)] = (>innerCursor)[ck]; (ctx)[c.unifyStateName(ck)] = f.getState((>innerCursor)[ck]); }); } }, shouldChange(ctx: IContext): boolean { if (c.isCursor(innerCursor)) { const previousState = ctx.state; ctx.state = f.getState(ctx.cursor); return ctx.forceShouldChange || ctx.state !== previousState; } else { let shouldChange = ctx.forceShouldChange; Object.keys(innerCursor).forEach(ck => { const stateName = c.unifyStateName(ck); const previousState = (ctx)[stateName]; (ctx)[stateName] = f.getState((>innerCursor)[ck]); shouldChange = shouldChange || (ctx)[stateName] !== previousState; }); return shouldChange; } } }), component)({ children }) }