10000 Keyboard copy event problem · Issue #507 · silevis/reactgrid · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Keyboard copy event problem #507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
arasovic opened this issue Mar 10, 2025 · 4 comments
Open

Keyboard copy event problem #507

arasovic opened this issue Mar 10, 2025 · 4 comments

Comments

@arasovic
Copy link
arasovic commented Mar 10, 2025

Describe the bug
After updating to the latest version of Google Chrome, the ability to multi-select and copy (CMD + C) multiple rows and columns is no longer working. It also occurs in Microsoft Edge on a Windows machine. It seems that keyboard events are not functioning properly in the new Chrome version.

Steps to Reproduce:

  1. Select multiple rows and columns within a table or spreadsheet-like interface.
  2. Attempt to use the CMD + C keyboard shortcut to copy the selected data.
  3. Notice that the copy functionality does not work as expected.
    I’ve attached a GIF below that demonstrates the issue.

Please investigate.

Current behavior
CMD + C is not copying

Expected behavior
CMD + C can can copyable and this used to happen

Screenshots or gifs

Image

Your environment details

  • Device: Desktop / Mac
  • OS: MacOS
  • Browser: Chrome Version 134.0.6998.45 (Official Build) (arm64)
  • "@silevis/reactgrid": "^4.1.15",

maybe instead of “document.execCommand(‘copy’)”
we could use something like “navigator.clipboard.writeText(text_to_copy)”.

@MinnDevelopment
Copy link

There already seems to be a different handling for safari, that likely needs to be done on chrome too now:

if (isBrowserSafari()) {
event.clipboardData.setData('text/html', div.innerHTML);
} else {
document.body.appendChild(div);
div.focus();
document.execCommand('selectAll', false);
document.execCommand('copy');
document.body.removeChild(div);
}

@arasovic
Copy link
Author
arasovic commented Mar 11, 2025

The company I work for uses this component. One morning I was able to copy it, but today I started getting emails saying I can't copy it.
When I checked that I could copy it, I checked my chrome version and it was 133 and there was an update. When I updated to 134 I couldn't copy it.
So I was sure that this problem was caused by my Chrome version.
I also needed to solve this problem, so I wrote a wrapper like the one below. I'm not saying it's absolutely the right solution, but it saved my ass.

import React, { useState, useEffect, useCallback } from 'react'
import { ReactGrid, ReactGridProps, Cell, TextCell, Range } from '@silevis/reactgrid'
import '@silevis/reactgrid/styles.css'

interface CustomReactGridProps extends ReactGridProps {
  onCopy?: (text: string) => void
}

type CustomCellMatrix = Cell[][]

const CustomReactGrid: React.FC<CustomReactGridProps> = props => {
  const [selectedRanges, setSelectedRanges] = useState<Range[]>([])

  const handleSelectionChanged = useCallback((ranges: Range[]) => {
    if (ranges.length > 0) {
      setSelectedRanges([ranges[0]])
    } else {
      setSelectedRanges([])
    }
  }, [])

  const handleCopy = useCallback(
    (e: ClipboardEvent) => {
      if (!selectedRanges.length) return

      const range = selectedRanges[0]

      try {
        // Use the selected range directly
        const selectedCells = getCellsInRange(props.rows, props.columns, range)
        const clipboardText = formatCellsForClipboard(selectedCells)

        if (navigator.clipboard && window.isSecureContext) {
          navigator.clipboard
            .writeText(clipboardText)
            .then(() => {
              if (props.onCopy) props.onCopy(clipboardText)
            })
            .catch(err => console.error('Clipboard error:', err))
        }
      } catch (error) {
        console.error('Error during copy:', error)
      }

      e.preventDefault()
    },
    [props.rows, props.columns, selectedRanges, props.onCopy]
  )

  useEffect(() => {
    document.addEventListener('copy', handleCopy)
    return () => document.removeEventListener('copy', handleCopy)
  }, [handleCopy])

  const getCellsInRange = (rows: any[], columns: any[], range: Range) => {
    const cellMatrix: CustomCellMatrix = []

    // Determine range using first and last
    const firstRow = range.first.row
    const lastRow = range.last.row
    const firstCol = range.first.column
    const lastCol = range.last.column

    // Find indices
    const firstRowIndex = rows.findIndex(r => r.rowId === firstRow.rowId)
    const lastRowIndex = rows.findIndex(r => r.rowId === lastRow.rowId)
    const firstColIndex = columns.findIndex(c => c.columnId === firstCol.columnId)
    const lastColIndex = columns.findIndex(c => c.columnId === lastCol.columnId)

    // Get all cells in the selected range
    for (let r = firstRowIndex; r <= lastRowIndex; r += 1) {
      const cellRow: Cell[] = []
      cellMatrix.push(cellRow)

      for (let c = firstColIndex; c <= lastColIndex; c += 1) {
        const cell = rows[r]?.cells?.[c] || { type: 'text', text: '' }
        cellRow.push(cell)
      }
    }

    return cellMatrix
  }

  const formatCellsForClipboard = (cellMatrix: CustomCellMatrix): string => {
    if (!cellMatrix.length) return ''

    return cellMatrix
      .map(row
8000
 =>
        row
          .map(cell => {
            if ('text' in cell) {
              return (cell as TextCell).text
            }
            return ''
          })
          .join('\t')
      )
      .join('\n')
  }

  return <ReactGrid {...props} onSelectionChanged={handleSelectionChanged} />
}

export default CustomReactGrid

@Luisgustavom1
Copy link
Contributor

I'm open this PR to try fix this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@arasovic @MinnDevelopment @Luisgustavom1 and others
0