Skip to content

v0.2: Field-level conflict merge UI helpers #7

@mayrang

Description

@mayrang

Idea

v0.1 ships multi-tab conflict detection (`multiTab: 'warn'`) and exposes `onConflictData` + `resolveConflict('local' | 'remote' | merged)`. But the actual merge UI — showing per-field diffs, letting the user pick field-by-field which version to keep — is left to the consumer.

This results in every app reinventing the same UI pattern. v0.2 should ship reusable UI helpers.

Proposed

A headless `` component and a `useConflictResolver` hook:

```tsx
import { ConflictResolver } from 'formdraft/ui';

{draft.onConflictData && (
<ConflictResolver
local={draft.values}
remote={draft.onConflictData}
onResolve={draft.resolveConflict}
renderField={(name, localValue, remoteValue, onPickLocal, onPickRemote) => (


{name}
Mine: {String(localValue)}
Theirs: {String(remoteValue)}

)}
/>
)}
```

Or fully styled default `` for "drop in and done":

```tsx
import { ConflictDialog } from 'formdraft/ui';

\`\`\`

Implementation notes

  • Headless variant: just orchestration. Consumer brings their own markup via render props.
  • Styled variant: minimal default CSS. Could ship in `formdraft/ui` subpath to avoid coupling main bundle to UI code.
  • Diff algorithm: shallow object diff for v0.2 (deep diff later). For string fields, optionally do char-level diff for visualization.

Acceptance

  • New subpath export `formdraft/ui` with `ConflictResolver` (headless) and `ConflictDialog` (styled)
  • 5+ unit tests covering: render fields with diff, pick local, pick remote, mixed merge, no conflict
  • Bundle: `formdraft/ui` is separate chunk; main bundle stays ≤ 8 KB
  • README new section "Conflict UI" with both variants demonstrated

Related to v0.1 design

Spec §10 lists "Full field-level conflict merge UI helpers" as v0.2 scope. This issue is the v0.2 implementation of that line.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions