git.fiddlerwoaroof.com
react-demo/main.js
cc733b08
 import React from "react";
 import ReactDOM from "react-dom";
 import "../src/genfun_formatter";
 import { Receipt } from "./render";
 import * as m from "./Model";
d230a7a2
 
cc733b08
 import * as gf from "../src/genfuns";
d230a7a2
 
cc733b08
 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>
   ))
e0c6f36a
   .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}
4a9806cd
             onChange={onChange}
           ></input>
e0c6f36a
         </>
       );
     }
   ).fn;
d230a7a2
 
a00b5a50
 class Field extends React.Component {
   constructor(props) {
     super();
     this.state = { editing: false, val: props.value };
   }
   click() {
cc733b08
     this.setState(() => ({
       editing: !this.state.editing,
       val: this.state.val,
     }));
a00b5a50
   }
   onChange(e) {
     const val = e.target.value;
cc733b08
     this.setState(() => ({ editing: true, val }));
a00b5a50
   }
   render() {
     const editingProps = {};
     if (this.state.editing) {
       editingProps.onChange = this.onChange.bind(this);
     }
cc733b08
     return (
       <div>
         <Editable {...this.props} {...editingProps} value={this.state.val} />
         <button onClick={this.click.bind(this)}>Toggle</button>
       </div>
     );
a00b5a50
   }
 }
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 />
cc733b08
     <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>,
cc733b08
   document.querySelector("main"),
d230a7a2
   () => {
cc733b08
     console.log("rendered");
d230a7a2
   }
cc733b08
 );