ProjectName.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import "./TextInput.scss";
  2. import React, { Component } from "react";
  3. import { selectNode, removeSelection } from "../utils";
  4. type Props = {
  5. value: string;
  6. onChange: (value: string) => void;
  7. label: string;
  8. };
  9. export class ProjectName extends Component<Props> {
  10. private handleFocus = (event: React.FocusEvent<HTMLElement>) => {
  11. selectNode(event.currentTarget);
  12. };
  13. private handleBlur = (event: React.FocusEvent<HTMLElement>) => {
  14. const value = event.currentTarget.innerText.trim();
  15. if (value !== this.props.value) {
  16. this.props.onChange(value);
  17. }
  18. removeSelection();
  19. };
  20. private handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
  21. if (event.key === "Enter") {
  22. event.preventDefault();
  23. if (event.nativeEvent.isComposing || event.keyCode === 229) {
  24. return;
  25. }
  26. event.currentTarget.blur();
  27. }
  28. };
  29. private makeEditable = (editable: HTMLSpanElement | null) => {
  30. if (!editable) {
  31. return;
  32. }
  33. try {
  34. editable.contentEditable = "plaintext-only";
  35. } catch {
  36. editable.contentEditable = "true";
  37. }
  38. };
  39. public render() {
  40. return (
  41. <span
  42. suppressContentEditableWarning
  43. ref={this.makeEditable}
  44. data-type="wysiwyg"
  45. className="TextInput"
  46. role="textbox"
  47. aria-label={this.props.label}
  48. onBlur={this.handleBlur}
  49. onKeyDown={this.handleKeyDown}
  50. onFocus={this.handleFocus}
  51. >
  52. {this.props.value}
  53. </span>
  54. );
  55. }
  56. }