Data sources & loading

Declare the data outside the form. Reference it by key inside any field. JavaScript handles requests; core consumes the results.

Define a source

JSON
{
  "apis": {
    "backend": {
      "baseUrl": "https://api.example.com/",
      "timeoutMs": 30000
    }
  }
}
JSON
{
  "countries": {
    "api": "backend",
    "endpoint": "countries",
    "resultPath": "/data",
    "schema": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string"
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "value",
          "label"
        ]
      }
    }
  }
}

Pass the first object as config and the second as dataSources. resultPath is a JSON Pointer: /data extracts that property; /data/0/value extracts the first item’s value. The optional response schema checks the extracted/mapped result. Supported types are string, number, integer, boolean, null, object, and array with an items schema.

Bind a field

JSON
{
  "type": "select",
  "key": "country",
  "bindings": {
    "options": {
      "source": "countries"
    }
  }
}
JSON
{
  "type": "select",
  "key": "region",
  "bindings": {
    "options": {
      "source": "regions",
      "params": {
        "country": {
          "ref": "country"
        }
      }
    }
  }
}

Use an options binding for select/radio options and a value binding for field values. Bindings name a source; params use { value: scalar } for literals or { ref: fieldKey } for field references. Value bindings support apply: initial (default) or live; options bindings always track their source. Referenced fields drive dependent requests after core accepts the schema. Select options are value/label objects, while radio values are booleans.

Loading and retry

Loading disables the affected field. Selects show a spinner and failed sources show an error with a retry control. New generations cancel or ignore stale responses. Rules and validation run after the result is integrated.

Dependent select options clear invalid selections. selectFirstOption: true chooses the first option when an empty selection needs a default; it defaults to false. Valid values from a reopened draft take priority over automatic defaults.

Own the transport

TSX
const config = {
  apis: { backend: { baseUrl: 'https://api.example.com/',
    headers: () => ({ Authorization: 'Bearer ' + getToken() }) } },
  request: async (request) => {
    // Use request.url, method, headers, body, credentials and signal.
    // Context identifies source/upload/submit/save/i18n requests.
    return { data: await yourClient(request) }
  },
}
<Tungsten schema={schema} config={config} dataSources={sources} onSubmit={save} />

Credentials belong in application configuration rather than exported schemas. Endpoints are relative to the configured base URL. Timeouts default to 30 seconds. An override receives cancellation signals and must return a data envelope. Non-idempotent operations are not blindly retried.

Try a failed request and retry →