Editable Text
wise-ui/editable-textFreeComponent
Inline editable text with animated border reveal, shimmer effect, and smooth save/cancel controls.
Live preview
live · rendered by the registry
Rendered by wise-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://wise-ui.com/r/editable-text.jsonSource
1"use client"23import * as React from "react"4import { motion } from "motion/react"5import { IconPencil, IconCheck, IconX } from "@tabler/icons-react"6import { cn } from "@/registry/wise-ui/lib/utils"78interface EditableTextProps {9 value: string10 onChange: (value: string) => void11 className?: string12 placeholder?: string13}1415const EditableText = React.forwardRef<HTMLDivElement, EditableTextProps>(16 ({ value, onChange, className, placeholder = "Click to edit..." }, ref) => {17 const [isEditing, setIsEditing] = React.useState(false)18 const [isHovered, setIsHovered] = React.useState(false)19 const [draft, setDraft] = React.useState(value)20 const [shimmerKey, setShimmerKey] = React.useState(0)21 const [textWidth, setTextWidth] = React.useState<number | undefined>(22 undefined23 )24 const inputRef = React.useRef<HTMLInputElement>(null)25 const textRef = React.useRef<HTMLSpanElement>(null)26 const blurTimeoutRef = React.useRef<ReturnType<typeof setTimeout>>(undefined)2728 React.useEffect(() => {29 if (!isEditing) setDraft(value)30 }, [value, isEditing])3132 React.useEffect(() => {33 if (isEditing) {34 const timeout = setTimeout(() => {35 inputRef.current?.focus()36 }, 50)37 return () => clearTimeout(timeout)38 }39 }, [isEditing])4041 React.useEffect(() => {42 return () => clearTimeout(blurTimeoutRef.current)43 }, [])4445 function startEditing() {46 if (textRef.current) {47 setTextWidth(textRef.current.offsetWidth)48 }49 setDraft(value)50 setIsEditing(true)51 setIsHovered(false)52 }5354 function save() {55 clearTimeout(blurTimeoutRef.current)56 onChange(draft)57 setIsEditing(false)58 }5960 function cancel() {61 clearTimeout(blurTimeoutRef.current)62 setDraft(value)63 setIsEditing(false)64 }6566 function handleKeyDown(e: React.KeyboardEvent) {67 if (e.key === "Enter") save()68 if (e.key === "Escape") cancel()69 }7071 function handleBlur() {72 blurTimeoutRef.current = setTimeout(save, 150)73 }7475 return (76 <div77 ref={ref}78 className={cn("relative inline-flex items-center", className)}79 onMouseEnter={() => {80 if (!isEditing) {81 setIsHovered(true)82 setShimmerKey((k) => k + 1)83 }84 }}85 onMouseLeave={() => setIsHovered(false)}86 >87 {isEditing ? (88 <div className="relative inline-flex items-center">89// … truncated
What it pulls in
npm packages
Files it writes
More from wise-ui
All 20 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Tabsanimated-tabs | wise-ui | Components | Free | 3 deps | |
| Border Beamborder-beam | wise-ui | Components | Free | 3 deps | |
| Data Tabledata-table | wise-ui | Components | Free | 3 deps | |
| Dockdock | wise-ui | Components | Free | 3 deps | |
| Dot Matrixdot-matrix | wise-ui | Components | Free | 2 deps | |
| Gradient Sidebargradient-sidebar | wise-ui | Components | Free | 3 deps | |
| Kanban Boardkanban-board | wise-ui | Components | Free | 6 deps | |
| Magnetic Buttonmagnetic-button | wise-ui | Components | Free | 3 deps |
