htmlcssreactjsdrag-and-dropdraggable

Select text in absolute element where parent is draggable table cell


How can I select text on #text element?

If I click mouse down and move on #text to copy it, JS trigger drag event on td element and prevents to select text.

Full code on codesandbox.

const SelTd = ({ children }: PropsWithChildren<any>) => {
    const ref = useRef(null)
    const onDragStart = useCallback((e: any) => {
        e.preventDefault()
        e.stopPropagation();
        ref.current && (ref.current.style.backgroundColor = 'yellow')
        setTimeout(() => {
            ref.current.style.backgroundColor = 'unset'
        }, 5 * 1000)
    }, [])
    return <td
        ref={ref}
        className="Td"
        draggable={true}
        onDragStart={onDragStart}

    >
        {children}
    </td>
}
export default function App() {
  return (
    <table>
      <tbody>
        <tr>
          <SelTd>
            <div className="Container">
              <div className="Abs" id="text">
                text to select
              </div>
            </div>
          </SelTd>
          <td className="Td">2</td>
        </tr>
      </tbody>
    </table>
  );
}


Solution

  • You need to set user-select in the text element.

    Here's a minimal example with all the extraneous stuff stripped away:

    <html lang="en">
    
    <head>
      <meta charset="utf-8">
    
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    
      <title>Test select
      </title>
    
      <style>
        .Td {
          padding: 10px 100px;
          border: 1px solid black;
        }
        
        .Container {
          position: relative;
        }
        
        .Abs {
          position: absolute;
          height: 33.5px;
          z-index: 9999;
          left: -100px;
          top: -10px;
          width: 300px;
          background-color: green;
          cursor: pointer;
          user-select: text;
        }
      </style>
    </head>
    
    
    <body>
      <table>
        <tbody>
          <tr>
            <td class="Td" draggable="true" ondragstart="event.preventDefault(); event.stopPropagation(); this.style.background='yellow'; var el= this; setTimeout(function() {el.style.background='unset';}, 5000);">
              <div class="Container">
                <div class="Abs" id="text">text to select
                </div>
              </div>
            </td>
            <td class="Td">2
            </td>
          </tr>
        </tbody>
      </table>
    </body>
    
    </html>