Skip to content
weftGitHub

SyncedForm

A form whose named fields are shared live with everyone in it.

SourcePackage @weft-js/warp

Preview

tsx
import { state } from '@weft-js/core'import { Button, Input, Row, Select, Stack, Switch, SyncedForm } from '@weft-js/warp'import type { Peer } from '@weft-js/warp'export function Runbook() {  const ops = state<{ seq: number; name: string; value: string | boolean; peer: Peer }[]>([])  const remote = (name: string, value: string | boolean) => (ops.value = [...ops.value, { seq: ops.value.length + 1, name, value, peer: JUN }])  return (    <Stack gap="group">      <SyncedForm ops={ops} label="Runbook details">        <Input label="Title" name="title" defaultValue="Rollback runbook" />        <Select label="Owner" name="owner" options={OWNERS} defaultValue="sam" />        <Switch name="notify" defaultChecked>Tell #incidents</Switch>      </SyncedForm>      <Row gap="tight">        <Button size="sm" emphasis="outline" tone="neutral" onClick={() => remote('title', 'Rollback runbook v2')}>Jun edits the title</Button>        <Button size="sm" emphasis="outline" tone="neutral" onClick={() => remote('notify', false)}>Jun flips the switch</Button>      </Row>    </Stack>  )}const PEOPLE = [  { id: 'mara', name: 'Mara Lindqvist', email: 'mara@weft.dev', role: 'Owner', team: 'Platform', initials: 'ML' },  { id: 'jun', name: 'Jun Tanaka', email: 'jun@weft.dev', role: 'Admin', team: 'Platform', initials: 'JT' },  { id: 'priya', name: 'Priya Raman', email: 'priya@weft.dev', role: 'Member', team: 'Web', initials: 'PR' },  { id: 'tomas', name: 'Tomás Oliveira', email: 'tomas@weft.dev', role: 'Member', team: 'Web', initials: 'TO' },  { id: 'lena', name: 'Lena Fischer', email: 'lena@weft.dev', role: 'Member', team: 'Data', initials: 'LF' },  { id: 'noor', name: 'Noor Haddad', email: 'noor@weft.dev', role: 'Viewer', team: 'Data', initials: 'NH' },  { id: 'sam', name: 'Sam Okafor', email: 'sam@weft.dev', role: 'Member', team: 'Mobile', initials: 'SO' },  { id: 'ines', name: 'Inés Vidal', email: 'ines@weft.dev', role: 'Viewer', team: 'Mobile', initials: 'IV' },]const PEERS: Peer[] = PEOPLE.map((p, i) => ({ id: p.id, name: p.name, color: i + 1 }))const [MARA, JUN, PRIYA, TOMAS, LENA, NOOR, SAM, INES] = PEERS as [Peer, Peer, Peer, Peer, Peer, Peer, Peer, Peer]const OWNERS = [{ value: 'jun', label: 'Jun Tanaka' }, { value: 'sam', label: 'Sam Okafor' }]

Installation

npm install @weft-js/warp

Usage

tsx
import { SyncedForm } from '@weft-js/warp'

Accessibility

  • This has no shortcuts of its own: controls inside it use Tab, Enter and Space as usual, and warp's parts keep their roles and labels.

API Reference

PropTypeDefaultDescription
opsLive<FormOp[]>—Other people's edits, oldest first.
labelstring—Names the form.
childrenunknown—What it contains.
EventTypeDefaultDescription
onSend((name: string, value: string | boolean) => void)—Called with each local edit.

RelatedData integrityConflict alert