import * as React from "react" import * as ReactDOM from "react-dom" import * as Immutable from "immutable" import {C, Cont, CmdCommon, Mode, make_C, unit, bind} from './core' export type H1Props = { kind:"h1", className:string|undefined, text:string, value:A, p:(_:A)=>C } & CmdCommon export type H2Props = { kind:"h2", className:string|undefined, text:string, value:A, p:(_:A)=>C } & CmdCommon export type LabelProps = { kind:"label", className:string|undefined, text:string, span_before_content:boolean, value:A, p:(_:A)=>C } & CmdCommon export type DivProps = { kind:"div", className:string|undefined, value:A, p:(_:A)=>C } & CmdCommon export type FormProps = { kind:"form", className:string|undefined, value:A, p:(_:A)=>C } & CmdCommon export type MultiSelectorType = "list"|"checkbox" export type MultiSelectorProps = { kind:"multi selector", type:MultiSelectorType, to_string:(_:A)=>string, items:Immutable.List, selected_items:undefined|Immutable.List } & CmdCommon> export type ImageProps = { kind:"image", src:string, mode:Mode } & CmdCommon export type SelectorType = "dropdown"|"radio" export type SelectorProps = { kind:"selector", type:SelectorType, to_string:(_:A)=>string, items:Immutable.List, selected_item:undefined|A } & CmdCommon export type ButtonProps = { label:string, x:A, disabled:boolean, className:string } & CmdCommon & ({ kind:"button" } | { kind:"a", href:string, rel?:"nofollow" }) export type LinkProps = { kind:"link", label:string, url:string, disabled:boolean, className:string } & CmdCommon export type FileProps = { kind:"file", label:string, url:string, mode:Mode, disabled:boolean } & CmdCommon type LabelState = { p:"creating"|JSX.Element } class Label extends React.Component,LabelState> { constructor(props:LabelProps,context:any) { super(props, context) this.state = { p:"creating" } } componentWillReceiveProps(new_props:LabelProps) { this.props.debug_info && console.log("New props:", this.props.debug_info()) this.setState({...this.state, p:new_props.p(new_props.value).comp(new_props.context)(callback => x => new_props.cont(callback)(x))}) } componentWillMount() { this.setState({...this.state, p:this.props.p(this.props.value).comp(this.props.context)(callback => x => this.props.cont(callback)(x))}) } render() { let content : JSX.Element = this.state.p == "creating" ? null : this.state.p let span = {this.props.text} return } } export function label(text:string, span_before_content?:boolean, className?:string, key?:string, dbg?:() => string) : (p:(_:A)=>C) => ((_:A) => C) { return p => value => make_C(ctxt => cont => (React.createElement>(Label, { kind:"label", className:className, debug_info:dbg, text:text, span_before_content:span_before_content, value:value, p:p, context:ctxt, cont:cont, key:key }))) } type H1State = { p:"creating"|JSX.Element } class H1 extends React.Component,H1State> { constructor(props:H1Props,context:any) { super(props, context) this.state = { p:"creating" } } componentWillReceiveProps(new_props:H1Props) { this.props.debug_info && console.log("New props:", this.props.debug_info()) this.setState({...this.state, p:new_props.p(new_props.value).comp(new_props.context)(callback => x => new_props.cont(callback)(x))}) } componentWillMount() { this.setState({...this.state, p:this.props.p(this.props.value).comp(this.props.context)(callback => x => this.props.cont(callback)(x))}) } render() { let content : JSX.Element = this.state.p == "creating" ? null : this.state.p let span = {this.props.text} return

{span}

{content}
} } export function h1(text:string, className?:string, key?:string, dbg?:() => string) : (p:(_:A)=>C) => ((_:A) => C) { return p => value => make_C(ctxt => cont => (React.createElement>(H1, { kind:"h1", className:className, debug_info:dbg, text:text, value:value, p:p, context:ctxt, cont:cont, key:key }))) } type H2State = { p:"creating"|JSX.Element } class H2 extends React.Component,H2State> { constructor(props:H2Props,context:any) { super(props, context) this.state = { p:"creating" } } componentWillReceiveProps(new_props:H2Props) { this.props.debug_info && console.log("New props:", this.props.debug_info()) this.setState({...this.state, p:new_props.p(new_props.value).comp(new_props.context)(callback => x => new_props.cont(callback)(x))}) } componentWillMount() { this.setState({...this.state, p:this.props.p(this.props.value).comp(this.props.context)(callback => x => this.props.cont(callback)(x))}) } render() { let content : JSX.Element = this.state.p == "creating" ? null : this.state.p let span = {this.props.text} return

{span}

{content}
} } export function h2(text:string, className?:string, key?:string, dbg?:() => string) : (p:(_:A)=>C) => ((_:A) => C) { return p => value => make_C(ctxt => cont => (React.createElement>(H2, { kind:"h2", className:className, debug_info:dbg, text:text, value:value, p:p, context:ctxt, cont:cont, key:key }))) } type DivState = { p:"creating"|JSX.Element } class Div extends React.Component,DivState> { constructor(props:DivProps,context:any) { super(props, context) this.state = { p:"creating" } } componentWillReceiveProps(new_props:DivProps) { this.props.debug_info && console.log("New props:", this.props.debug_info()) this.setState({...this.state, p:new_props.p(new_props.value).comp(new_props.context)(callback => x => new_props.cont(callback)(x))}) } componentWillMount() { this.setState({...this.state, p:this.props.p(this.props.value).comp(this.props.context)(callback => x => this.props.cont(callback)(x))}) } render() { return
{ this.state.p != "creating" ? this.state.p : [] }
} } export function div(className?:string, key?:string, dbg?:() => string) : (p:(_:A)=>C) => ((_:A) => C) { return p => value => make_C(ctxt => cont => (React.createElement>(Div, { kind:"div", className:className, debug_info:dbg, value:value, p:p, context:ctxt, cont:cont, key:key }))) } export function overlay(key?:string, dbg?:() => string) : (p:(_:A)=>C) => ((_:A) => C) { return p => div(`overlay`)(div(`overlay__item`)(p)) } type FormState = { p:"creating"|JSX.Element } class Form extends React.Component,FormState> { constructor(props:FormProps,context:any) { super(props, context) this.state = { p:"creating" } } componentWillReceiveProps(new_props:FormProps) { this.props.debug_info && console.log("New props:", this.props.debug_info()) this.setState({...this.state, p:new_props.p(new_props.value).comp(new_props.context)(callback => x => new_props.cont(callback)(x))}) } componentWillMount() { this.setState({...this.state, p:this.props.p(this.props.value).comp(this.props.context)(callback => x => this.props.cont(callback)(x))}) } render() { return
{ this.state.p != "creating" ? this.state.p : [] }
} } export function form(className?:string, key?:string, dbg?:() => string) : (p:(_:A)=>C) => ((_:A) => C) { return p => value => make_C(ctxt => cont => (React.createElement>(Form, { kind:"form", className:className, debug_info:dbg, value:value, p:p, context:ctxt, cont:cont, key:key }))) } type SelectorState
= { selected:undefined|number } class Selector extends React.Component,SelectorState> { constructor(props:SelectorProps,context:any) { super(props, context) this.state = { selected:props.selected_item != undefined ? props.items.findIndex(i => props.to_string(i) == props.to_string(props.selected_item)) : undefined } } componentWillMount() { if (this.props.selected_item != undefined) this.props.cont(() => null)(this.props.selected_item) } render() { if (this.props.type == "dropdown") return else if (this.props.type == "radio") { return
{ this.props.items.map((i,i_index) => { let i_s = this.props.to_string(i) return
}) }
} else { return [] } } } export let selector = function
(type:SelectorType, to_string:(_:A)=>string, key?:string, dbg?:() => string) : ((items:Array, selected_item?:A) => C) { return (items, selected_item) => make_C(ctxt => cont => React.createElement>(Selector, { kind:"selector", debug_info:dbg, items:Immutable.List(items), selected_item:selected_item, type:type, to_string:to_string, context:ctxt, cont:cont, key:key })) } type MultiSelectorState = { selected:Immutable.Set } class MultiSelector extends React.Component,MultiSelectorState> { constructor(props:MultiSelectorProps,context:any) { super(props, context) this.state = { selected:Immutable.Set( props.selected_items != undefined ? props.items.map((i,i_index) : [string, number] => [props.to_string(i), i_index]) .filter(x => props.selected_items.some(selected => props.to_string(selected) == x[0])) .map(x => x[1]) .toArray() : []) } } componentWillMount() { if (this.props.selected_items != undefined) this.props.cont(() => null)(this.state.selected.map(index => this.props.items.get(index)).toArray()) } render() { if (this.props.type == "list") { return } else if (this.props.type == "checkbox") { return
{ this.props.items.map((i,i_index) => { let i_s = this.props.to_string(i) return
}) }
} else { return null } } } export let multi_selector = function
(type:MultiSelectorType, to_string:(_:A)=>string, key?:string, dbg?:() => string) : ((items:Array, selected_items?:Array) => C>) { return (items, selected_items) => make_C>(ctxt => (cont:Cont>) => React.createElement>( MultiSelector, { kind:"multi selector", debug_info:dbg, items:Immutable.List(items), selected_items:selected_items ? Immutable.List(selected_items) : Immutable.List(), type:type, to_string:to_string, cont:cont, context:ctxt, key:key })) } type ImageState = { src:string } class Image extends React.Component { constructor(props:ImageProps,context:any) { super(props, context) this.state = { src:props.src } } componentWillReceiveProps(new_props:ImageProps) { if (new_props.src != this.state.src) this.setState({...this.state, src: new_props.src}) } render() { return
{ this.props.mode == "edit" ?
{ if(confirm('Are you sure?')) { let new_value = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAMSURBVBhXY/j//z8ABf4C/qc1gYQAAAAASUVORK5CYII=" this.setState({...this.state, src:new_value }, () => this.props.cont(() => null)(new_value)) } } }> { let files:FileList = (e.target as any).files; let file_reader = new FileReader() file_reader.onload = ((e) => { let new_value = file_reader.result this.setState({...this.state, src:new_value }, () => this.props.cont(() => null)(new_value)) }) file_reader.readAsDataURL(files[0]); } } />
: [] }
} } export let image = (mode:Mode, key?:string, dbg?:() => string) => function(src:string) : C { return make_C(ctxt => cont => React.createElement(Image, { kind:"image", debug_info:dbg, mode:mode, src:src, context:ctxt, cont:cont, key:key })) } type ButtonState = { x:A } class Button extends React.Component, ButtonState> { constructor(props:ButtonProps,context:any) { super(props, context) this.state = { x:props.x } } componentWillReceiveProps(new_props:ButtonProps) { this.setState({...this.state, x:new_props.x}) } render() { return this.props.kind == "a" ? { this.props.cont(() => {})(this.state.x) e.preventDefault() return false } }>{this.props.label} : } } export let a = function(label:string, href?:string, rel?:"nofollow", disabled?:boolean, key?:string, className?:string, dbg?:() => string) : ((x:A) => C) { return x => make_C(ctxt => cont => React.createElement>(Button, { kind:"a", debug_info:dbg, label:label, href:href || "#", rel:rel, disabled:!!disabled, x:x, context:ctxt, cont:cont, key:key, className:className })) } export let button = function(label:string, disabled?:boolean, key?:string, className?:string, dbg?:() => string) : ((x:A) => C) { return x => make_C(ctxt => cont => React.createElement>(Button, { kind:"button", debug_info:dbg, label:label, disabled:!!disabled, x:x, context:ctxt, cont:cont, key:key, className:className })) } type LinkState = { } class Link extends React.Component { constructor(props:LinkProps, context:any) { super(props, context) this.state = {} } render() { return {this.props.label} } } export let link = function(label:string, url:string, disabled?:boolean, key?:string, className?:string, dbg?:() => string) : C { return make_C(ctxt => cont => React.createElement(Link, { kind:"link", debug_info:dbg, label:label, url:url, disabled:!!disabled, context:ctxt, cont:cont, key:key, className:className })) } type FileState = {} class FileComponent extends React.Component { constructor(props:FileProps, context:any) { super(props, context) this.state = {} } render() { return
{this.props.label} {this.props.mode == "view" ? [] : { let files:FileList = (e.target as any).files let f = files[0] this.props.cont(() => {})(f) } } /> }
} } export let file = function(mode:Mode, label:string, url:string, disabled?:boolean, key?:string, dbg?:() => string) : C { return make_C(ctxt => cont => React.createElement(FileComponent, { kind:"file", mode:mode, debug_info:dbg, label:label, url:url, disabled:!!disabled, context:ctxt, cont:cont, key:key })) }