ns-ui

Optimistic Stitch

Optimistic-write feedback for a single row rendered as a tailor's basting stitch along its left seam — dashed hand-stitch while pending, pulled tight into a solid hairline on ack, or unraveled to muted and dimmed on failure with an inline retry.

Use when Per-row pending/committed/failed feedback for an optimistic write (a list item, a comment, a form field) where the row's own left seam encodes the write's lifecycle — dashed while unacked, solid the instant the server confirms, muted-and-frayed with a real Retry button on failure — and every one of those three rests must read correctly from a single still frame. Reach for streaming-ink-dry instead when the thing that's unsettled is a live token *stream* (chat/generation text) whose 'not yet dry' state keeps animating for as long as tokens keep arriving — optimistic-stitch's states are terminal snapshots of one write's outcome, never a continuously running effect.

Install

npx shadcn add https://design.helpmarq.com/r/optimistic-stitch.json
  • optimistic-ui
  • list
  • form
  • comments
  • svg
  • accessibility
  • aria-live
  • retry
  • state

ns-ui / optimistic-stitch

sprint backlog3 items

Add "Ship dark-mode audit"

just now

Saving

"Looks good, merging tonight."

2m ago

Saved

Renamed to "Q3 roadmap review"

couldn't save — connection dropped

Failed to save. Retry available.

dashed = provisional, solid = acked, muted + dimmed = rolled back — press Retry

Props

PropTypeDefaultDescription
statusBasteStatusWhere this row's write currently sits in its lifecycle.
onRetry?() => voidCalled when the user activates the Retry control after a failed write.
childrenReactNodeThe row's real content — list text, a comment body, a form field.
itemLabel?stringNoun for what this row is, used only in the Retry button's own label ("Retry {itemLabel}") so multiple failed rows read as distinct controls to a screen reader. Default "change".
className?string