diff --git a/.jsbeautifyrc b/.jsbeautifyrc new file mode 100644 index 00000000..17449aef --- /dev/null +++ b/.jsbeautifyrc @@ -0,0 +1,24 @@ +{ + "brace_style": "collapse-preserve-inline", + "break_chained_methods": false, + "comma_first": false, + "end_with_newline": true, + "eol": "\n", + "eval_code": false, + "indent_char": " ", + "indent_level": 0, + "indent_size": 2, + "indent_with_tabs": false, + "jslint_happy": false, + "keep_array_indentation": false, + "keep_function_indentation": false, + "max_preserve_newlines": 10, + "preserve_newlines": true, + "space_after_anon_function": false, + "space_before_conditional": true, + "space_in_paren": false, + "unescape_strings": false, + "wrap_attributes": "auto", + "wrap_attributes_indent_size": 4, + "wrap_line_length": 0 +} diff --git a/labeled-sliders/labeledSlider/update.js b/labeled-sliders/labeledSlider/update.js index b46cc73a..3f7bb608 100644 --- a/labeled-sliders/labeledSlider/update.js +++ b/labeled-sliders/labeledSlider/update.js @@ -1,10 +1,10 @@ import { assoc } from "ramda"; import { Action } from "./action"; -// handler : Model -> [ model, Maybe (Task Action) ] +// handler : Model -> Model const handler = model => ({ - NoOp: () => [model], - Update: value => [assoc("value", value, model)] + NoOp: () => model, + Update: value => assoc("value", value, model) }); // update : Action -> Model -> [ model, Maybe (Task Action) ] diff --git a/labeled-sliders/labeledSlider/widget.js b/labeled-sliders/labeledSlider/widget.js index 1844ecb9..c674ddc6 100644 --- a/labeled-sliders/labeledSlider/widget.js +++ b/labeled-sliders/labeledSlider/widget.js @@ -2,12 +2,12 @@ import { initialModel } from "./model"; import { update } from "./update"; import { view } from "./view.jsx"; -const createLabeledSliderWidget = id => { +const createLabeledSliderWidget = (id, actions, model) => { const widget = { id: id, - initialModel: [initialModel], + model: model || initialModel, update: update, - view: view + view: view(actions) }; return widget; diff --git a/labeled-sliders/sliderContainer/action.js b/labeled-sliders/sliderContainer/action.js index fa78407b..ea906446 100644 --- a/labeled-sliders/sliderContainer/action.js +++ b/labeled-sliders/sliderContainer/action.js @@ -2,9 +2,9 @@ import Type from "union-type"; const Action = Type({ NoOp: [], - AddMeasurement: [], + AddMeasurement: [Function], RemoveMeasurement: [Number], - ModifyMeasurement: [Object] + UpdateMeasurement: [Object] // {id: N, action: labeledSlider.Action} }); export { Action }; diff --git a/labeled-sliders/sliderContainer/update.js b/labeled-sliders/sliderContainer/update.js index d71f469f..1f43c01a 100644 --- a/labeled-sliders/sliderContainer/update.js +++ b/labeled-sliders/sliderContainer/update.js @@ -2,16 +2,42 @@ import { append, assoc } from "ramda"; import { Action } from "./action"; import { createLabeledSliderWidget } from "../labeledSlider/widget"; +const updateMeasurement = update => measurement => + update.id === measurement.id + ? assoc("model", measurement.update(update.action)(measurement.model), measurement) + : measurement; + +const rnd = (min, max) => Math.round(Math.random() * min) + (max || 0); + // handler : Model -> [ model, Maybe (Task Action) ] const handler = model => ({ NoOp: () => [model], - AddMeasurement: () => [ - assoc("nextId", model.nextId + 1, - assoc("measurements", append(createLabeledSliderWidget(model.nextId), model.measurements), model) + AddMeasurement: subaction => [ + assoc("nextId", + model.nextId + 1, + assoc("measurements", + append( + createLabeledSliderWidget( + model.nextId, + subaction(model.nextId), + { + label: "Measurement", + value: rnd(50), + max: rnd(50,100), + units: rnd(10) % 2 === 0 ? "cm" : "mm" + } + ), + model.measurements + ), + model + ) ) ], RemoveMeasurement: id => [ assoc("measurements", model.measurements.filter(m => m.id !== id), model) + ], + UpdateMeasurement: update => [ + assoc("measurements", model.measurements.map(updateMeasurement(update)), model) ] }); diff --git a/labeled-sliders/sliderContainer/view.jsx b/labeled-sliders/sliderContainer/view.jsx index 2e41f6d5..81a6993e 100644 --- a/labeled-sliders/sliderContainer/view.jsx +++ b/labeled-sliders/sliderContainer/view.jsx @@ -4,24 +4,31 @@ import { Action } from "./action"; const view = actions => model => { - const onAddMeasurement = _evt => actions.onNext(Action.AddMeasurement()); + const onAddMeasurement = _evt => { + const subaction = id => ({ + onNext: labeledSliderAction => actions.onNext(Action.UpdateMeasurement({id, action: labeledSliderAction})) + }); + actions.onNext(Action.AddMeasurement(subaction)); + }; + const onRemoveMeasurement = id => _evt => actions.onNext(Action.RemoveMeasurement(id)); const renderMeasurement = measurement => { - const view = measurement.view(actions); - return ( -
- {measurement.id} - {view(model)} - +
+ id: {measurement.id} + {measurement.view(measurement.model)} +
); }; return (
- +
+ Measurements: {model.measurements.map(m => JSON.stringify(m.model))} +
+
{model.measurements.map(renderMeasurement)}
); diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 00000000..a8cca1ca Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/images/meiosis.png b/public/images/meiosis.png new file mode 100644 index 00000000..a8cca1ca Binary files /dev/null and b/public/images/meiosis.png differ diff --git a/public/index.html b/public/index.html index 8563b7d9..15870aed 100644 --- a/public/index.html +++ b/public/index.html @@ -1,11 +1,17 @@ + + + + + + Meiosis Example - +
-

Meiosis Example

+

Meiosis Example

diff --git a/public/style.css b/public/style.css new file mode 100644 index 00000000..486535f6 --- /dev/null +++ b/public/style.css @@ -0,0 +1,5 @@ +div { + margin-top: 8px; + margin-bottom: 8px; + padding: 4px; +}