Bindings

A function argument can also modify the value that is passed in. Use Reactive.Binding or Reactive.Output for that. A binding is readable and writable. An output is writable and not readable. The caller passes a state for either one.

Reactive.Function("Save", () => {
  const name = Reactive.Binding(Text.Plain);
  const saved = Reactive.Output(Text.Plain);

  Button.Setter(saved, name, () => {
    Content.Text("Save");
  });
});
The button writes name through saved. Both are values the caller passed in.

Binding

Reactive.Binding(Type) is readable and writable. The caller passes a state, or a reverse that has a source. Inside the function, a field reads the binding and writes it.

Reactive.Function("NameField", () => {
  const name = Reactive.Binding(Text.Plain);

  Input.Text(name);    // write the binding
  Content.Text(name);  // read the binding
});

const name = Reactive.State(Text.Plain)("Ada");
NameField(name);  // pass a state
The field writes name and the text reads it. The caller passes a state.

Output

Reactive.Output(Type) is writable and not readable. The caller passes a reverse with no source, a binding, or a state. A button sets that output to another value. The function does not read the output.

Reactive.Function("Save", () => {
  const settableValue = Reactive.Output(Text.Plain);  // the output we set
  const next = Reactive.Input(Text.Plain);             // the value we set it to

  Button.Setter(settableValue, next, () => {
    Content.Text("Save");
  });
});

const label = Reactive.State(Text.Plain)("");
Save(label, "saved");
Pressing the button sets label to "saved".

A function cannot return a reverse. It may return a binding or a state, and only the forward value comes out. That result is not writable. A function writes through an output or a reverse argument.

Composition

The same field write can sit inside a function. Each function takes an output. One shows a text input. The other shows a number input. The function does not know the output is a field. The caller passes one field of the state into each. Writing the output writes that field, and the state stores the new person.

Reactive.Function("NameField", () => {
  const name = Reactive.Output(Text.Plain);

  Input.Text(name);  // the name
});

Reactive.Function("AgeField", () => {
  const age = Reactive.Output(Maths.Integer.Number);

  Input.Number(age);  // the age
});

const ada = People.Person("Ada Lovelace", 36);
const person = Reactive.State(People.Person)(ada);
NameField(person.name);
AgeField(person.age);
Each function writes one field. The state stores the person.