1- import { Text } from "@radix-ui/themes" ;
1+ import { Box , Text } from "@radix-ui/themes" ;
22import { useCallback , useEffect } from "react" ;
33
44interface InlineEditableTextProps {
@@ -24,7 +24,7 @@ export function InlineEditableText({
2424} : InlineEditableTextProps ) {
2525 useEffect ( ( ) => {
2626 if ( inputRef . current ) {
27- inputRef . current . textContent = value || placeholder ;
27+ inputRef . current . textContent = value || "" ;
2828 inputRef . current . focus ( ) ;
2929 if ( value ) {
3030 const range = document . createRange ( ) ;
@@ -41,17 +41,8 @@ export function InlineEditableText({
4141 ( e : React . FormEvent < HTMLSpanElement > ) => {
4242 const text = e . currentTarget . textContent ?? "" ;
4343 onChange ( text ) ;
44- if ( ! text && inputRef . current ) {
45- inputRef . current . textContent = placeholder ;
46- const range = document . createRange ( ) ;
47- range . setStart ( inputRef . current , 0 ) ;
48- range . collapse ( true ) ;
49- const sel = window . getSelection ( ) ;
50- sel ?. removeAllRanges ( ) ;
51- sel ?. addRange ( range ) ;
52- }
5344 } ,
54- [ onChange , placeholder , inputRef ] ,
45+ [ onChange ] ,
5546 ) ;
5647
5748 const handleKeyDown = useCallback (
@@ -68,46 +59,60 @@ export function InlineEditableText({
6859 } else if ( e . key === "Enter" && ! e . shiftKey ) {
6960 e . preventDefault ( ) ;
7061 onSubmit ( ) ;
71- } else if ( ! value && e . key . length === 1 && ! e . ctrlKey && ! e . metaKey ) {
72- e . preventDefault ( ) ;
73- e . currentTarget . textContent = e . key ;
74- onChange ( e . key ) ;
75- const range = document . createRange ( ) ;
76- range . selectNodeContents ( e . currentTarget ) ;
77- range . collapse ( false ) ;
78- const sel = window . getSelection ( ) ;
79- sel ?. removeAllRanges ( ) ;
80- sel ?. addRange ( range ) ;
8162 }
8263 } ,
83- [ value , onChange , onNavigateUp , onNavigateDown , onEscape , onSubmit ] ,
64+ [ onNavigateUp , onNavigateDown , onEscape , onSubmit ] ,
8465 ) ;
8566
8667 return (
87- < Text
88- asChild
89- size = "1"
90- weight = "medium"
91- className = { value ? "text-gray-12" : "text-gray-10" }
68+ < Box
69+ style = { {
70+ display : "inline-grid" ,
71+ minWidth : "200px" ,
72+ } }
9273 >
93- { /* biome-ignore lint/a11y/useSemanticElements: contentEditable span needed for inline editing UX */ }
94- < span
95- ref = { inputRef }
96- role = "textbox"
97- tabIndex = { 0 }
98- contentEditable
99- suppressContentEditableWarning
100- onClick = { ( e ) => e . stopPropagation ( ) }
101- onInput = { handleInput }
102- onKeyDown = { handleKeyDown }
103- style = { {
104- outline : "none" ,
105- minWidth : "200px" ,
106- display : "inline-block" ,
107- whiteSpace : "pre-wrap" ,
108- wordBreak : "break-word" ,
109- } }
110- />
111- </ Text >
74+ { ! value && (
75+ < Text
76+ size = "1"
77+ weight = "medium"
78+ className = "text-gray-10"
79+ style = { {
80+ gridRow : 1 ,
81+ gridColumn : 1 ,
82+ pointerEvents : "none" ,
83+ userSelect : "none" ,
84+ whiteSpace : "pre-wrap" ,
85+ wordBreak : "break-word" ,
86+ } }
87+ >
88+ { placeholder }
89+ </ Text >
90+ ) }
91+ < Text
92+ asChild
93+ size = "1"
94+ weight = "medium"
95+ className = { value ? "text-gray-12" : "" }
96+ >
97+ { /* biome-ignore lint/a11y/useSemanticElements: contentEditable span needed for inline editing UX */ }
98+ < span
99+ ref = { inputRef }
100+ role = "textbox"
101+ tabIndex = { 0 }
102+ contentEditable
103+ suppressContentEditableWarning
104+ onClick = { ( e ) => e . stopPropagation ( ) }
105+ onInput = { handleInput }
106+ onKeyDown = { handleKeyDown }
107+ style = { {
108+ gridRow : 1 ,
109+ gridColumn : 1 ,
110+ outline : "none" ,
111+ whiteSpace : "pre-wrap" ,
112+ wordBreak : "break-word" ,
113+ } }
114+ />
115+ </ Text >
116+ </ Box >
112117 ) ;
113118}
0 commit comments