Inline Edit
spectrumui/inline-editFreeBlock
A selection-anchored AI edit: suggestion toolbar, word diff, accept or reject.
Install it
npx shadcn@latest add https://ui.spectrumhq.in/r/inline-edit.jsonSource
1'use client';23import { useState } from 'react';4import { Check, Sparkles, X } from 'lucide-react';5import { cn } from '@/lib/utils';67const KEYFRAMES = `8@keyframes su-msg-in { from { opacity: 0; transform: translateY(4px) } to { opacity: 1; transform: none } }9`;1011export type InlineEditPhase = 'selected' | 'reviewing' | 'accepted';1213export interface InlineEditProps {14 before: string;15 selection: string;16 after: string;17 suggestion: string;18 actionLabel?: string;19 phase?: InlineEditPhase;20 onAccept?: () => void;21 onReject?: () => void;22 className?: string;23}2425export function InlineEdit({26 before,27 selection,28 after,29 suggestion,30 actionLabel = 'Tighten this',31 phase: phaseProp,32 onAccept,33 onReject,34 className,35}: InlineEditProps) {36 const [phaseState, setPhaseState] = useState<InlineEditPhase>('selected');37 const phase = phaseProp !== undefined ? phaseProp : phaseState;3839 function accept() {40 setPhaseState('accepted');41 onAccept?.();42 }43 function reject() {44 setPhaseState('selected');45 onReject?.();46 }4748 return (49 <div className={cn('w-full max-w-[480px] text-[13.5px]', className)}>50 <style dangerouslySetInnerHTML={{ __html: KEYFRAMES }} />5152 <p className="leading-[1.75] text-neutral-700 dark:text-neutral-300">53 {before}54 {phase === 'accepted' ? (55 <span className="rounded bg-emerald-500/10 px-0.5 text-neutral-900 motion-safe:animate-[su-msg-in_240ms_cubic-bezier(0.23,1,0.32,1)_both] dark:text-neutral-100">56 {suggestion}57 </span>58 ) : (59 <span className="group/edit relative inline">60 <span className="rounded bg-sky-500/15 px-0.5 dark:bg-sky-400/20">{selection}</span>61 {phase === 'selected' && (62 <span className="absolute left-1/2 top-full z-10 mt-1.5 -translate-x-1/2 motion-safe:animate-[su-msg-in_200ms_cubic-bezier(0.23,1,0.32,1)_both]">63 <button64 type="button"65 onClick={() => setPhaseState('reviewing')}66 className="flex items-center gap-1.5 whitespace-nowrap rounded-full border border-black/[0.08] bg-white py-1 pl-2 pr-2.5 text-[11.5px] font-medium text-neutral-700 shadow-md transition-transform duration-150 active:scale-[0.96] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-neutral-400 dark:border-white/[0.1] dark:bg-neutral-900 dark:text-neutral-200"67 >68// … truncated
What it pulls in
npm packages
Files it writes
More from spectrumui
All 182 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Agent Planagent-plan | spectrumui | Blocks | Free | 1 dep | |
| Agent Stepsagent-steps | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Approval Cardapproval-card | spectrumui | Blocks | Free | 1 dep | |
| Chat Empty Statechat-empty-state | spectrumui | Blocks | Free | 1 dep · 2 files | |
| Citation Sourcescitation-sources | spectrumui | Blocks | Free | no deps · 2 files | |
| Code Blockcode-block | spectrumui | Blocks | Free | 1 dep | |
| Conversation Listconversation-list | spectrumui | Blocks | Free | 1 dep | |
| Diff Viewdiff-view | spectrumui | Blocks | Free | 1 dep |
