git.fiddlerwoaroof.com
react-demo/main.js
d230a7a2
 import React from 'react';
 import ReactDOM from 'react-dom';
 import '../src/genfun_formatter';
a00b5a50
 import { Receipt } from './render';
 import * as m from './Model';
d230a7a2
 
a00b5a50
 import * as gf from '../src/genfuns';
d230a7a2
 
a00b5a50
 const Editable =
   gf.defgeneric("Editable", "props")
     .around([Object], function (_) {
       return <div style={{ display: 'inline-block' }}>{this.call_next_method()} </div>
     })
     .primary([gf.Shape("label", "htmlFor")], ({ label, htmlFor }) =>
       <label {...{htmlFor}}>{label}</label>)
     .primary([gf.Shape("label", "htmlFor", "value")], function ({ value, onChange }) {
       return <>
         {this.call_next_method()}
         {onChange ? null : <span> {value}</span>}
       </>
     })
     .primary([gf.Shape("label", "htmlFor", "value", "onChange")], function ({ value, htmlFor, onChange }) {
       return <>
         {this.call_next_method()}
         <input type="text" value={value} id={htmlFor} name={htmlFor} onChange={onChange}></input>
       </>
     })
     .fn;
d230a7a2
 
a00b5a50
 class Field extends React.Component {
   constructor(props) {
     super();
     this.state = { editing: false, val: props.value };
   }
   click() {
     this.setState(() => ({ editing: !this.state.editing, val: this.state.val }));
   }
   onChange(e) {
     const val = e.target.value;
     this.setState(() => ({ editing: true, val }))
   }
   render() {
     const editingProps = {};
     if (this.state.editing) {
       editingProps.onChange = this.onChange.bind(this);
     }
     return <div>
       <Editable {...this.props} {...editingProps} value={this.state.val} />
       <button onClick={this.click.bind(this)}>Toggle</button>
     </div>
   }
 }
d230a7a2
 
 ReactDOM.render(
   <div>
a00b5a50
     <Field label="the field" htmlFor="the-field" value="foo" />
     <Editable label="bazquuxes" htmlFor="bazquux" value="foo" display />
     <Editable label="bazquuxes" htmlFor="bazquux" value="foo" editable />
     <Receipt items={[
       new m.AlcoholicBeverage(11),
       new m.AlcoholicBeverage(12),
       new m.AlcoholicBeverage(13),
       new m.NormalFood(11),
       new m.NonFood(11),
       new m.AlcoholicBeverage(10)
     ]} />
d230a7a2
   </div>,
   document.querySelector('main'),
   () => {
     console.log('rendered');
   }
 );