autoSelectText.tsx 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import {forwardRef, useImperativeHandle, useRef} from 'react';
  2. import classNames from 'classnames';
  3. import {selectText} from 'sentry/utils/selectText';
  4. type Props = {
  5. children: React.ReactNode;
  6. className?: string;
  7. style?: React.CSSProperties;
  8. };
  9. type AutoSelectHandle = {
  10. selectText: () => void;
  11. };
  12. const AutoSelectText: React.ForwardRefRenderFunction<AutoSelectHandle, Props> = (
  13. {children, className, ...props},
  14. forwardedRef
  15. ) => {
  16. const element = useRef<HTMLSpanElement>(null);
  17. // We need to expose a selectText method to parent components
  18. // and need an imperative ref handle.
  19. useImperativeHandle(forwardedRef, () => ({
  20. selectText: () => handleClick(),
  21. }));
  22. function handleClick() {
  23. if (!element.current) {
  24. return;
  25. }
  26. selectText(element.current);
  27. }
  28. // use an inner span here for the selection as otherwise the selectText
  29. // function will create a range that includes the entire part of the
  30. // div (including the div itself) which causes newlines to be selected
  31. // in chrome.
  32. return (
  33. <div
  34. {...props}
  35. onClick={handleClick}
  36. className={classNames('auto-select-text', className)}
  37. >
  38. <span ref={element}>{children}</span>
  39. </div>
  40. );
  41. };
  42. export default forwardRef(AutoSelectText);