Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there any issues using Arrow Key Stepper to scroll when the rows have tabIndex or contentEditable enabled?

We've implemented React-Vitualized using single column Grid with rows that are enabled for keyboard event (onKeyUp/onKeyDown/onKeyPress). We are using Arrow-Key-Stepper to enable ArrowUp/ArrowDown scrolling of the rows.

All works quite well even with PgUp/PgDn, Home/End, Space and Shift-Space. However, when we add either tabIndex and/or contenteditable attributes to the rows (required for keyboard events), scrolling freezes when the focused rows scrolls out-of-view and removed from the DOM. We can regain control by using Tab key and/or the mouse.

QUESTION: Why is tabIndex/contenteditable attributes causing scrolling failure?

I am not allowed to reproduce the code publicly. Not asking for solution nor code but more an opinion from a more experienced source. This is the last issue for our implementation of this widget library, which has been very good thus far.

Appreciate any suggest/opinion.

like image 392
Richard O'Brien Avatar asked Dec 14 '25 23:12

Richard O'Brien


1 Answers

However, when we add either tabIndex and/or contenteditable attributes to the rows (required for keyboard events), scrolling freezes when the focused rows scrolls out-of-view and removed from the DOM.

I'm curious why the rows themselves need this attribute? The outer container rendered by ArrowKeyStepper has a tab-index, in order to be focusable. This is how ArrowKeyStepper listens to keyboard events.

If the row is focused, then when it goes out of the viewport, ArrowKeyStepper is left listening to ... nothing. The way to fix this is to use a class component to render your cell and conditionally self-focusing:

class Cell extends Component {
  componentDidMount = () => this._maybeFocus();
  componentDidUpdate = () => this._maybeFocus();

  render() {
    const {
      columnIndex,
      rowIndex,
      scrollToColumn,
      scrollToRow,
      style,
    } = this.props;

    return (
      <div
        style={style}
        ref={this._setRef}
        tabIndex={1}
      >
        {/* Your content here... */}
      </div>
    );
  };

  _maybeFocus = () => {
    const {
      columnIndex,
      rowIndex,
      scrollToColumn,
      scrollToRow,
    } = this.props;

    if (
      columnIndex === scrollToColumn &&
      rowIndex === scrollToRow
    ) {
      this._ref.focus();
    }
  }

  _setRef = ref => {
    this._ref = ref;
  };
}
like image 73
bvaughn Avatar answered Dec 16 '25 21:12

bvaughn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!