Spaces:
Sleeping
Sleeping
| import { useEffect, useRef, useState } from 'react'; | |
| function toDraftValue(value, fallback = '') { | |
| if (value === undefined || value === null) { | |
| return fallback; | |
| } | |
| return String(value); | |
| } | |
| function useDraftValue(value, fallback, onCommit) { | |
| const [draft, setDraft] = useState(() => toDraftValue(value, fallback)); | |
| const isEditingRef = useRef(false); | |
| const externalValue = toDraftValue(value, fallback); | |
| useEffect(() => { | |
| if (!isEditingRef.current && draft !== externalValue) { | |
| setDraft(externalValue); | |
| } | |
| }, [draft, externalValue]); | |
| const change = (nextValue) => { | |
| setDraft(nextValue); | |
| onCommit(nextValue); | |
| }; | |
| return { | |
| value: draft, | |
| onFocus: () => { | |
| isEditingRef.current = true; | |
| }, | |
| onBlur: () => { | |
| isEditingRef.current = false; | |
| onCommit(draft); | |
| }, | |
| onChange: (event) => change(event.target.value), | |
| }; | |
| } | |
| export function NodeDraftInput({ value, fallback = '', onCommit, ...props }) { | |
| const draftProps = useDraftValue(value, fallback, onCommit); | |
| return <input {...props} {...draftProps} />; | |
| } | |
| export function NodeDraftTextarea({ value, fallback = '', onCommit, ...props }) { | |
| const draftProps = useDraftValue(value, fallback, onCommit); | |
| return <textarea {...props} {...draftProps} />; | |
| } | |