Blueprint: Table not keeping focused cell visible

Created on 25 Sep 2017  路  5Comments  路  Source: palantir/blueprint

Bug report

  • blueprint.table 1.26.0 & blueprint.core 1.29.0
  • Windows / Chrome

Steps to reproduce

  1. Create table with enableFocus set true. Include enough rows to enable scroll bar
  2. Select first cell and arrow down to observe scroll/visibility behaviour
  3. Use up arrow keys to focus on first cell
  4. Use scroll bar to scroll up

Actual behavior

When using down arrow, focused cell is sometimes not fully visible.

arrow-down-visibility-bug

When using up arrow, top first cell hidden behind heading.

arrow-up-visibility-bug

Top cell becomes visible when scroll bar used to scroll up.

arrow-up-visibility-bug-scroll-fix

Expected behavior

Focused cell always fully visible.

P2 table bug

All 5 comments

@olivergeorge ah yep, this got a little wonky during the frozen-columns/rows refactor. Thanks for filing.

I think this is related to the scroll bars extending over the headers
image

@gscshoyru for SA - to repro locally

Yeah, this actually repros pretty easily, it turns out.

It's also a lot worse with custom headers turned on, which leads me to believe the math isn't properly taking headers and sidebar into account.

This also happens when you manually scroll right, and then use the arrow keys to move left - the sidebar is not taken into account.

Just faced this issue, and solved it with a rather hacky way. Hope it helps anyone:

import { useRef } from 'react'
import { Table } from '@blueprintjs/table'

const isCellVisible = ({ col, row }: { col: number; row: number }) => {
  // Any better way to get the target focusing cell before it focus?
  const element = document.querySelector(
    // eslint-disable-next-line @blueprintjs/classes-constants
    `.bp3-table-cell-row-${row}.bp3-table-cell-col-${col}`
  )

  if (!element) return false

  const boundingRect = element.getBoundingClientRect()

  // adjust coordinates to get more accurate results
  const left = boundingRect.left + 1
  const right = boundingRect.right - 1
  const top = boundingRect.top + 1
  const bottom = boundingRect.bottom - 1

  const frontMostElement = [
    document.elementFromPoint(left, top),
    document.elementFromPoint(right, top),
    document.elementFromPoint(left, bottom),
    document.elementFromPoint(right, bottom),
  ]

  return !frontMostElement.some(
    (compare) => compare && compare !== element && !element.contains(compare)
  )
}

const Component = () => {
  const table = useRef<Table>()

  return (
    <Table
      ref={table}
      onFocusedCell={({ col, row }) =>
        isCellVisible({ col, row }) &&
        table.current.scrollToRegion({ cols: [col, col], rows: [row, row] })
      }
    >
      {/* ... */}
    </Table>
  )
}

Please, keep in mind above code is just a representation. Other necessary configuration, such as Column children, were keept out to focus on the sollution.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tgreenwatts picture tgreenwatts  路  3Comments

adidahiya picture adidahiya  路  3Comments

Goddak picture Goddak  路  3Comments

westrem picture westrem  路  3Comments

ernestofreyreg picture ernestofreyreg  路  3Comments