Merge pull request #14763 from overleaf/mj-extend-col-row-selectors

[visual] Allow shift clicking column and row selectors

GitOrigin-RevId: 2e6191741681196e4af462f92dc60268f22d137e
This commit is contained in:
Mathias Jakobsen 2023-09-11 10:59:48 +01:00 committed by Copybot
parent 4b699f1ad4
commit 1e3f305ba3
3 changed files with 86 additions and 14 deletions

View file

@ -30,13 +30,20 @@ export class TableSelection {
)
}
static selectRow(row: number, table: TableData) {
selectRow(row: number, extend: boolean, table: TableData) {
return new TableSelection(
{ row, cell: 0 },
{ row: extend ? this.from.row : row, cell: 0 },
{ row, cell: table.columns.length - 1 }
)
}
selectColumn(column: number, extend: boolean, table: TableData) {
return new TableSelection(
{ row: 0, cell: extend ? this.from.cell : column },
{ row: table.rows.length - 1, cell: column }
)
}
normalized() {
const minX = Math.min(this.from.cell, this.to.cell)
const maxX = Math.max(this.from.cell, this.to.cell)

View file

@ -1,4 +1,4 @@
import { useCallback } from 'react'
import { MouseEventHandler, useCallback } from 'react'
import {
TableSelection,
useSelectionContext,
@ -9,14 +9,22 @@ import { useTableContext } from './contexts/table-context'
export const ColumnSelector = ({ index }: { index: number }) => {
const { selection, setSelection } = useSelectionContext()
const { table } = useTableContext()
const onColumnSelect = useCallback(() => {
setSelection(
new TableSelection(
{ row: 0, cell: index },
{ row: table.rows.length - 1, cell: index }
)
)
}, [table.rows.length, index, setSelection])
const onColumnSelect: MouseEventHandler = useCallback(
event => {
event.preventDefault()
if (!selection) {
setSelection(
new TableSelection(
{ row: 0, cell: index },
{ row: table.rows.length - 1, cell: index }
)
)
return
}
setSelection(selection.selectColumn(index, event.shiftKey, table))
},
[index, setSelection, selection, table]
)
const fullySelected = selection?.isColumnSelected(index, table)
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
@ -32,9 +40,22 @@ export const ColumnSelector = ({ index }: { index: number }) => {
export const RowSelector = ({ index }: { index: number }) => {
const { table } = useTableContext()
const { selection, setSelection } = useSelectionContext()
const onSelect = useCallback(() => {
setSelection(TableSelection.selectRow(index, table))
}, [index, setSelection, table])
const onSelect: MouseEventHandler = useCallback(
event => {
event.preventDefault()
if (!selection) {
setSelection(
new TableSelection(
{ row: index, cell: 0 },
{ row: index, cell: table.columns.length - 1 }
)
)
return
}
setSelection(selection.selectRow(index, event.shiftKey, table))
},
[index, setSelection, table, selection]
)
const fullySelected = selection?.isRowSelected(index, table)
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions

View file

@ -588,5 +588,49 @@ cell 3 & cell 4 \\\\
cy.get('@cell-2').tab({ shift: true })
cy.get('@cell-1').should('have.focus').should('have.class', 'selected')
})
it('Can select rows and columns with selectors', function () {
mountEditor(`
\\begin{tabular}{cc }
cell 1 & cell 2\\\\
cell 3 & cell 4 \\\\
\\end{tabular}`)
cy.get('.table-generator-cell').eq(0).as('cell-1')
cy.get('.table-generator-cell').eq(1).as('cell-2')
cy.get('.table-generator-cell').eq(2).as('cell-3')
cy.get('.table-generator-cell').eq(3).as('cell-4')
cy.get('.column-selector').eq(0).click()
cy.get('@cell-1').should('have.class', 'selected')
cy.get('@cell-2').should('not.have.class', 'selected')
cy.get('@cell-3').should('have.class', 'selected')
cy.get('@cell-4').should('not.have.class', 'selected')
cy.get('.column-selector').eq(1).click()
cy.get('@cell-1').should('not.have.class', 'selected')
cy.get('@cell-2').should('have.class', 'selected')
cy.get('@cell-3').should('not.have.class', 'selected')
cy.get('@cell-4').should('have.class', 'selected')
cy.get('.column-selector').eq(0).click({ shiftKey: true })
cy.get('@cell-1').should('have.class', 'selected')
cy.get('@cell-2').should('have.class', 'selected')
cy.get('@cell-3').should('have.class', 'selected')
cy.get('@cell-4').should('have.class', 'selected')
cy.get('.row-selector').eq(0).click()
cy.get('@cell-1').should('have.class', 'selected')
cy.get('@cell-2').should('have.class', 'selected')
cy.get('@cell-3').should('not.have.class', 'selected')
cy.get('@cell-4').should('not.have.class', 'selected')
cy.get('.row-selector').eq(1).click()
cy.get('@cell-1').should('not.have.class', 'selected')
cy.get('@cell-2').should('not.have.class', 'selected')
cy.get('@cell-3').should('have.class', 'selected')
cy.get('@cell-4').should('have.class', 'selected')
cy.get('.row-selector').eq(0).click({ shiftKey: true })
cy.get('@cell-1').should('have.class', 'selected')
cy.get('@cell-2').should('have.class', 'selected')
cy.get('@cell-3').should('have.class', 'selected')
cy.get('@cell-4').should('have.class', 'selected')
})
})
})