Reactガイドを読んでいくその27

これは

Reactのガイドを読んでいく記事です。

ガイドのリンク

ja.reactjs.org

アクセシビリティ

何回かに分けてやっていきます。

マウスとポインタのイベント

アプリケーションを作っていく際にマウスとキーボードどちらでも操作できることが必要とありました。
ここでは実際の例を出して、マウスで操作した場合とキーボードで操作した場合でどう意識するか学びます。

・アウトサイドクリックパターン
これはユーザが要素の外側をクリックして開いている要素を閉じられるパターンで
ボタンを押下した際にメニューのような子要素が出て、枠外をカーソルで押すと閉じられるようなケースです。

これは多くの場合ポップアップを閉じる役割をもつ click イベントを window オブジェクトに付与することで実装します。
しかしマウスやタッチデバイスのような場合は問題なく動作するが、キーボードでは子要素を閉じることができず、
操作できなくなってしまいます。

それでは困ってしまうので onBlur と onFocusのようなイベントハンドラを使うことで解決させます。

class BlurExample extends React.Component {
  constructor(props) {
    super(props);

    this.state = { isOpen: false };
    this.timeOutId = null;

    this.onClickHandler = this.onClickHandler.bind(this);
    this.onBlurHandler = this.onBlurHandler.bind(this);
    this.onFocusHandler = this.onFocusHandler.bind(this);
  }

  onClickHandler() {
    this.setState(currentState => ({
      isOpen: !currentState.isOpen
    }));
  }

  // We close the popover on the next tick by using setTimeout.
  // This is necessary because we need to first check if
  // another child of the element has received focus as
  // the blur event fires prior to the new focus event.
  onBlurHandler() {
    this.timeOutId = setTimeout(() => {
      this.setState({
        isOpen: false
      });
    });
  }

  // If a child receives focus, do not close the popover.
  onFocusHandler() {
    clearTimeout(this.timeOutId);
  }

  render() {
    // React assists us by bubbling the blur and
    // focus events to the parent.
    return (
      <div onBlur={this.onBlurHandler}
           onFocus={this.onFocusHandler}>

        <button onClick={this.onClickHandler}
                aria-haspopup="true"
                aria-expanded={this.state.isOpen}>
          Select an option
        </button>
        {this.state.isOpen && (
          <ul>
            <li>Option 1</li>
            <li>Option 2</li>
            <li>Option 3</li>
          </ul>
        )}
      </div>
    );
  }
}

テストをするときはキーボード操作のテストも必要。
アプリケーションを提供する側の前提は全てのユーザーに操作できるようにしておくということを考えればそうなるということか。

今日はここまで。