AI Edit Review React component
An AI text editor that rewrites a selected passage, streams a word-level diff review with accept/reject actions, and morphs a dock through writing, review, and applied states.
About the AI Edit Review component
AI Edit Review is a free inline AI editing surface: a paragraph with one highlighted passage and a dock underneath offering rewrite actions such as Improve, Shorten and Translate. Picking one makes the passage shimmer while a small particle orb works, then shows a word-level diff in place, with removed words struck through and added words streaming in, while the dock shows the added and removed word counts next to Reject and Accept.
The text is split into before, selected and after, and actions is a list of up to five { label, result } pairs; the component computes the diff between selected and each result itself. selectionColor, addColor and removeColor color the highlight and the diff, workColors, reviewColors and doneColors the edge glow, and the dock morphs its width for each state. onStart, onAccept and onReject report the user's choice, a live region reads the state and word counts, and actions started from the keyboard move focus to the next state's main button.
When to use it
Use it to build or demo AI writing features in editors, CMS fields, email composers or docs tools, where people must see exactly what the model changed before it is applied.
For free-form prompting instead of fixed rewrite actions, pair a text area with AI Chat Prompt.
Installation
Add the AI Edit Review component to your project with the shadcn CLI. It lands in components/ai-edit-review.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/ai-edit-reviewOr copy the source by hand and install its dependencies:
npm install clsx tailwind-mergeProps
<AIEditReview /> accepts 41 props, all optional.
| Prop | Type | Default |
|---|---|---|
| status | "auto" | "idle" | "working" | "review" | "applied" | "auto" |
| interactive | boolean | true |
| loop | boolean | true |
| holdSeconds | number | 2.2 |
| workSeconds | number | 2 |
| reviewSeconds | number | 2.6 |
| before | string | DEFAULT_BEFORE |
| selected | string | DEFAULT_SELECTED |
| after | string | DEFAULT_AFTER |
| actions | { label: string; result: string }[] | DEFAULT_ACTIONS |
| workingText | string | "Rewriting" |
| reviewText | string | "Review" |
- status"auto" | "idle" | "working" | "review" | "applied"Default: "auto"
- interactivebooleanDefault: true
- loopbooleanDefault: true
- holdSecondsnumberDefault: 2.2
- workSecondsnumberDefault: 2
- reviewSecondsnumberDefault: 2.6
- beforestringDefault: DEFAULT_BEFORE
- selectedstringDefault: DEFAULT_SELECTED
- afterstringDefault: DEFAULT_AFTER
- actions{ label: string; result: string }[]Default: DEFAULT_ACTIONS
- workingTextstringDefault: "Rewriting"
- reviewTextstringDefault: "Review"
Show all 41 propsShow fewer
| appliedText | string | "Applied" |
| acceptLabel | string | "Accept" |
| rejectLabel | string | "Reject" |
| description | string | DEFAULT_DESCRIPTION |
| font | React.CSSProperties | { fontSize: 17, lineHeight: 1.6 } |
| textColor | string | "#EDEDED" |
| mutedColor | string | "#6B6B6B" |
| selectionColor | string | "#9B7BFF" |
| addColor | string | "#7CFFC4" |
| removeColor | string | "#FF7B8A" |
| workColors | string[] | DEFAULT_WORK |
| reviewColors | string[] | DEFAULT_REVIEW |
| doneColors | string[] | DEFAULT_DONE |
| orbColor | string | "#FFFFFF" |
| particles | number | 520 |
| orbAura | number | 0.5 |
| ringIntensity | number | 0.7 |
| ringSize | number | 10 |
| ringSpeed | number | 40 |
| background | string | "#0E0E10" |
| borderColor | string | "rgba(255,255,255,0.09)" |
| radius | number | 28 |
| padding | number | 28 |
| gap | number | 22 |
| onStart | () => void | — |
| onAccept | () => void | — |
| onReject | () => void | — |
| className | string | — |
| style | React.CSSProperties | — |
- appliedTextstringDefault: "Applied"
- acceptLabelstringDefault: "Accept"
- rejectLabelstringDefault: "Reject"
- descriptionstringDefault: DEFAULT_DESCRIPTION
- fontReact.CSSPropertiesDefault: { fontSize: 17, lineHeight: 1.6 }
- textColorstringDefault: "#EDEDED"
- mutedColorstringDefault: "#6B6B6B"
- selectionColorstringDefault: "#9B7BFF"
- addColorstringDefault: "#7CFFC4"
- removeColorstringDefault: "#FF7B8A"
- workColorsstring[]Default: DEFAULT_WORK
- reviewColorsstring[]Default: DEFAULT_REVIEW
- doneColorsstring[]Default: DEFAULT_DONE
- orbColorstringDefault: "#FFFFFF"
- particlesnumberDefault: 520
- orbAuranumberDefault: 0.5
- ringIntensitynumberDefault: 0.7
- ringSizenumberDefault: 10
- ringSpeednumberDefault: 40
- backgroundstringDefault: "#0E0E10"
- borderColorstringDefault: "rgba(255,255,255,0.09)"
- radiusnumberDefault: 28
- paddingnumberDefault: 28
- gapnumberDefault: 22
- onStart() => void
- onAccept() => void
- onReject() => void
- classNamestring
- styleReact.CSSProperties
Kits
Sets of components designed to be used together on one site, AI Edit Review included.
Collections
Use-case pages that compare AI Edit Review with the other components that do a similar job.
npm dependencies
Installed for you by the shadcn CLI.
AI Edit Review FAQ
- Does it call a model to rewrite the text?
- No. The rewritten text is each action's result. To use a real model, request the rewrite, pass it as the first action's result, and set status="working" while it runs and "review" when it arrives.
- Why did onAccept fire without a click?
- With status="auto" the demo loop accepts the change itself after reviewSeconds and calls onAccept. When a user picks an action, the review waits for Accept or Reject.
- How long can the passage be?
- The diff runs word by word for up to 400 words on each side; beyond that it marks the whole passage as removed and the whole result as added.
- Can I make it read-only?
- Yes, interactive={false} turns off the dock buttons, so it only plays or shows the state you set.