import * as React from "react" import * as ReactDOM from "react-dom" import * as Immutable from "immutable" import * as Moment from 'moment' import {C, Mode, Cont, CmdCommon, make_C, unit, bind} from './core' function format_int(num:number, length:number) : string { return (num / Math.pow(10, length)).toFixed(length).substr(2); } export type OptionalParameters = { disabled?: boolean, size?: number } export type NumberProps = { kind:"number", value:number, mode:Mode } & CmdCommon export type StringType = "email"|"tel"|"text"|"url"|"password" export type StringProps = { kind:"string", value:string, type:StringType, mode:Mode, optional_parameters: OptionalParameters } & CmdCommon export type BooleanStyle = "checkbox"|"fancy toggle"|"plus/minus"|"radio" export type BoolProps = { kind:"bool", value:boolean, mode:Mode, style:BooleanStyle } & CmdCommon export type DateProps = { kind:"date", value:Moment.Moment, mode:Mode } & CmdCommon export type DateTimeProps = { kind:"date time", value:Moment.Moment, mode:Mode } & CmdCommon export type TimeProps = { kind:"time", value:Moment.Moment, mode:Mode } & CmdCommon type NumberState = { value:number } class Number extends React.Component { constructor(props:NumberProps,context:any) { super(props, context) this.state = { value:props.value } } componentWillReceiveProps(new_props:NumberProps) { if (new_props.value != this.state.value) this.setState({...this.state, value: new_props.value}) //, () => this.call_cont(this.state.value)) } componentWillMount() { this.call_cont(this.state.value) } call_cont(value:number) { this.props.cont(()=>null)(value) } render() { return this.props.mode == "edit" ? { let new_value = isNaN(e.currentTarget.valueAsNumber) ? 0 : e.currentTarget.valueAsNumber if (new_value == this.state.value) return this.props.cont(()=>null)(new_value)} }/> : {this.state.value} } } export let number = (mode:Mode, key?:string, dbg?:() => string) => function(value:number) : C { return make_C(ctxt => cont => React.createElement(Number, { kind:"number", debug_info:dbg, mode:mode, value:value, context:ctxt, cont:cont, key:key })) } type StringState = { value:string } class String extends React.Component { constructor(props:StringProps,context:any) { super(props, context) this.state = { value:props.value } } componentWillReceiveProps(new_props:StringProps) { if (this.props.debug_info != undefined) console.log(`receiving props`, this.props.debug_info()) if (new_props.value != this.state.value) this.setState({...this.state, value: new_props.value}) //, () => this.call_cont(new_props.value)) } componentWillMount() { if (this.props.debug_info != undefined) console.log(`mounting`, this.props.debug_info()) this.call_cont(this.state.value) } call_cont(value:string) { if (this.props.debug_info != undefined) console.log(`calling continuation`, this.props.debug_info()) this.props.cont(()=>null)(value) } render() { if (this.props.debug_info != undefined) console.log(`render`, this.props.debug_info()) return this.props.mode == "edit" ? { if (this.state.value == e.currentTarget.value) return this.call_cont(e.currentTarget.value)} } size={this.props.optional_parameters.size != undefined ? this.props.optional_parameters.size : undefined} disabled={this.props.optional_parameters.disabled != undefined && this.props.optional_parameters.disabled} /> : this.props.type == "text" ? {this.state.value} : this.props.type == "tel" ? {this.state.value} : this.props.type == "email" ? {this.state.value} : this.props.type == "url" ? {this.state.value} : this.props.type == "password" ? {Immutable.Repeat("*", this.state.value.length).join("")} : {this.state.value} } } export let string = (mode:Mode, type?:StringType, key?:string, dbg?:() => string, optional_parameters?: OptionalParameters) => function(value:string) : C { return make_C(ctxt => cont => React.createElement(String, { kind:"string", debug_info:dbg, type:type || "text", mode:mode, value:value, context:ctxt, cont:cont, key:key , optional_parameters: optional_parameters == undefined || optional_parameters == null ? {} : optional_parameters })) } type BoolState = { value:boolean } class Bool extends React.Component { constructor(props:BoolProps,context:any) { super(props, context) this.state = { value:props.value } } componentWillReceiveProps(new_props:BoolProps) { if (new_props.value != this.state.value) this.setState({...this.state, value: new_props.value}) //, () => this.call_cont(this.state.value)) } componentWillMount() { this.call_cont(this.state.value) } call_cont(value:boolean) { this.props.cont(()=>null)(value) } render() { return this.props.style == "fancy toggle" ? this.props.cont(()=>null)(e.currentTarget.checked)} /> : this.props.style == "plus/minus" ? this.props.cont(()=>null)(e.currentTarget.checked)} /> : this.props.cont(()=>null)(e.currentTarget.checked)} /> } } export let bool = (mode:Mode, style:BooleanStyle, key?:string, dbg?:() => string) => function(value:boolean) : C { return make_C(ctxt => cont => React.createElement(Bool, { kind:"bool", debug_info:dbg, style:style, mode:mode, value:value, context:ctxt, cont:cont, key:key })) } type DateTimeState = { value:Moment.Moment } class DateTime extends React.Component { constructor(props:DateTimeProps,context:any) { super(props, context) this.state = { value:props.value } } componentWillReceiveProps(new_props:DateTimeProps) { if (new_props.value != this.state.value) this.setState({...this.state, value: new_props.value}) //, () => this.call_cont(this.state.value)) } componentWillMount() { this.call_cont(this.state.value) } call_cont(value:Moment.Moment) { this.props.cont(()=>null)(value) } render() { let item = this.state.value let default_value = `${format_int(item.year(), 4)}-${format_int(item.month()+1, 2)}-${format_int(item.date(), 2)}T${format_int(item.hours(), 2)}:${format_int(item.minutes(), 2)}` return this.props.mode == "view" ?
{ `${format_int(item.date(), 2)}/${format_int(item.month()+1, 2)}/${format_int(item.year(), 4)} ${format_int(item.hours(), 2)}:${format_int(item.minutes(), 2)}` }
: this.call_cont(Moment.utc(e.currentTarget.value)) } /> } } export let date_time = (mode:Mode, key?:string, dbg?:() => string) => function(value:Moment.Moment) : C { return make_C(ctxt => cont => React.createElement(DateTime, { kind:"date time", debug_info:dbg, mode:mode, value:value, context:ctxt, cont:cont, key:key })) } type DateState = { value:Moment.Moment } class DateOnly extends React.Component { constructor(props:DateProps,context:any) { super(props, context) this.state = { value:props.value } } componentWillReceiveProps(new_props:DateProps) { if (new_props.value != this.state.value) this.setState({...this.state, value: new_props.value}) //, () => this.call_cont(this.state.value)) } componentWillMount() { this.call_cont(this.state.value) } call_cont(value:Moment.Moment) { this.props.cont(()=>null)(value) } render() { let item = this.state.value let default_value = `${format_int(item.year(), 4)}-${format_int(item.month()+1, 2)}-${format_int(item.date(), 2)}` return this.props.mode == "view" ?
{ `${format_int(item.date(), 2)}/${format_int(item.month()+1, 2)}/${format_int(item.year(), 4)}` }
: this.call_cont(Moment.utc(new Date(e.currentTarget.value)).startOf('d').add(12, 'h')) } /> } } export let date = (mode:Mode, key?:string, dbg?:() => string) => function(value:Moment.Moment) : C { return make_C(ctxt => cont => React.createElement(DateOnly, { kind:"date", debug_info:dbg, mode:mode, value:value, context:ctxt, cont:cont, key:key })) } type TimeState = { value:Moment.Moment } class Time extends React.Component { constructor(props:TimeProps,context:any) { super(props, context) this.state = { value:props.value } } componentWillReceiveProps(new_props:TimeProps) { if (new_props.value != this.state.value) this.setState({...this.state, value: new_props.value}) //, () => this.call_cont(this.state.value)) } componentWillMount() { this.call_cont(this.state.value) } call_cont(value:Moment.Moment) { this.props.cont(()=>null)(value) } render() { let item = this.state.value let default_value = `${format_int(item.hours(), 2)}:${format_int(item.minutes(), 2)}` return this.props.mode == "view" ?
{ default_value }
: this.call_cont(Moment.utc(e.currentTarget.valueAsDate)) } /> } } export let time = (mode:Mode, key?:string, dbg?:() => string) => function(value:Moment.Moment) : C { return make_C(ctxt => cont => React.createElement(Time, { kind:"time", debug_info:dbg, mode:mode, value:value, context:ctxt, cont:cont, key:key })) }