editable-label.tsx 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import OLFormControl from '@/shared/components/ol/ol-form-control'
  2. import {
  3. ChangeEventHandler,
  4. useCallback,
  5. useEffect,
  6. useRef,
  7. useState,
  8. } from 'react'
  9. type EditableLabelProps = {
  10. initialText: string
  11. className?: string
  12. onChange: (name: string) => void
  13. onCancel: () => void
  14. maxLength?: number
  15. }
  16. const EditableLabel = ({
  17. initialText,
  18. className,
  19. onChange,
  20. onCancel,
  21. maxLength,
  22. }: EditableLabelProps) => {
  23. const [name, setName] = useState(initialText)
  24. const inputRef = useRef<HTMLInputElement | null>(null)
  25. useEffect(() => {
  26. inputRef.current?.select()
  27. }, [])
  28. const onInputChange: ChangeEventHandler<HTMLInputElement> = useCallback(
  29. event => {
  30. setName(event.target.value)
  31. },
  32. []
  33. )
  34. const finishRenaming = useCallback(() => {
  35. onChange(name)
  36. }, [onChange, name])
  37. const onKeyDown = useCallback(
  38. (event: React.KeyboardEvent) => {
  39. if (event.key === 'Enter') {
  40. event.preventDefault()
  41. finishRenaming()
  42. }
  43. if (event.key === 'Escape') {
  44. event.preventDefault()
  45. onCancel()
  46. }
  47. },
  48. [finishRenaming, onCancel]
  49. )
  50. return (
  51. <OLFormControl
  52. className={className}
  53. ref={inputRef}
  54. type="text"
  55. value={name}
  56. onChange={onInputChange}
  57. onKeyDown={onKeyDown}
  58. onBlur={finishRenaming}
  59. maxLength={maxLength}
  60. />
  61. )
  62. }
  63. export default EditableLabel