project-name-editable-label.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import React, { useEffect, useState, useRef } from 'react'
  2. import PropTypes from 'prop-types'
  3. import classNames from 'classnames'
  4. import Icon from '../../../shared/components/icon'
  5. function ProjectNameEditableLabel({
  6. projectName,
  7. userIsAdmin,
  8. onChange,
  9. className
  10. }) {
  11. const [isRenaming, setIsRenaming] = useState(false)
  12. const canRename = userIsAdmin && !isRenaming
  13. const [inputContent, setInputContent] = useState(projectName)
  14. const inputRef = useRef(null)
  15. useEffect(() => {
  16. if (isRenaming) {
  17. inputRef.current.select()
  18. }
  19. }, [isRenaming])
  20. function startRenaming() {
  21. setInputContent(projectName)
  22. setIsRenaming(true)
  23. }
  24. function handleKeyDown(event) {
  25. if (event.key === 'Enter') {
  26. event.preventDefault()
  27. setIsRenaming(false)
  28. onChange(event.target.value)
  29. }
  30. }
  31. function handleOnChange(event) {
  32. setInputContent(event.target.value)
  33. }
  34. function handleBlur() {
  35. setIsRenaming(false)
  36. }
  37. return (
  38. <div className={classNames('project-name', className)}>
  39. {!isRenaming && (
  40. <span className="name" onDoubleClick={startRenaming}>
  41. {projectName}
  42. </span>
  43. )}
  44. {isRenaming && (
  45. <input
  46. ref={inputRef}
  47. type="text"
  48. className="form-control"
  49. onKeyDown={handleKeyDown}
  50. onChange={handleOnChange}
  51. onBlur={handleBlur}
  52. value={inputContent}
  53. />
  54. )}
  55. {canRename && (
  56. // eslint-disable-next-line jsx-a11y/anchor-is-valid, jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus
  57. <a className="rename" role="button" onClick={startRenaming}>
  58. <Icon type="pencil" modifier="fw" />
  59. </a>
  60. )}
  61. </div>
  62. )
  63. }
  64. ProjectNameEditableLabel.propTypes = {
  65. projectName: PropTypes.string.isRequired,
  66. userIsAdmin: PropTypes.bool,
  67. onChange: PropTypes.func.isRequired,
  68. className: PropTypes.string
  69. }
  70. export default ProjectNameEditableLabel