Day 20: Toggling a search box for keyboard users with React
Tags: webdev, react, a11y, search
Published: 2022-12-19 05:10:02

## TL;DR
To toggle the visibility of a search box with React in a _keyboard user_-friendly manner, do the following:
1. Use the `useEffect` hook to trigger a `keydown` event handler for hiding the search box with the Esc key
2. Add the `autoFocus` prop to `<input type="search">` so that the user can immediately start typing in the search box
3. Use the `useEffect` hook to programatically focus the toggle button after the user closes the search box
4. Trap the focus inside the search box popup with `<FocusLock>` from the `react-focus-lock` module.

The entire code described in this article can be found in [the CodeSandbox demo](https://codesandbox.io/s/my-ideal-maps-searchbox-4ui875?file=/src/components/Search.js).

## Introduction

_My Ideal Map_, a web app I’m building to improve the UX of Google Maps, allows the user to search for a place on the map. While Google Maps always displays a search box on the map, _My Ideal Map_ only shows a search button at the top-right corner to minimize the area of the map hidden from the view. I don’t want the user to fail to notice a place of their own interest beneath the search box.
![Menu button at top-left, search button at top-right, the other two buttons at top-bottom over the embedded Google Map](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2rhcdelxga7vfgxhx9yj.png)
**_My Ideal Map_’s user interface with the toggle button for a search box at the top-right corner** (screenshot by the author)

To search for a place on the map, therefore, the user needs to press the search button to see a search box. And, if they change their mind, the user should be allowed to close the search box and go back to the full-screen view of the map.

Implementing this user experience with React is straightforward if we care about touch device users and mouse users only. But there are keyboard users out there, including those screen reader users. Implementation for these users with React turns out to be not trivial at all.

Below I describe what I have learned, by constructing a React component for the search feature step by step.

## 1. HTML

To construct a React component, the first thing I do is to forget about React and focus on what HTML code to write.

### 1.1 Search button
By default, I want the following HTML code:

```html
<form role="search">
  <button
    aria-expanded="false"
    aria-label="Search place"
    type="button"
  >
    <!-- SVG code for the search button (omitted) -->
  </button>
</form>
```
Here are some footnotes on this piece of code:
- Wrapping the button to open a search box with `<form role="search">` allows screen-reader users to notice that the search feature is available on a website ([MDN Contributors 2022a](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/search#search_form_labels_and_accessibility)).

- Screen reader users, when focusing on the `<button>` element, will learn that the search box is currently hidden thanks to `aria-expanded="false"` ([Silver 2019](https://css-tricks.com/why-how-and-when-to-use-semantic-html-and-aria/#aa-using-aria-and-javascript-together)).

- I use `aria-label` to give an accessible name to the button, because the button is an icon button with no text label (see [**Day 16 of this blog series**](https://dev.to/masakudamatsu/day-16-icon-buttons-should-be-labelled-with-aria-label-551g) for detail).

Incidentally, I initially used aria-controls to link the button with `<input type="search">`, to indicate which element the button will open.However, [Pickering (2016)](https://heydonworks.com/article/aria-controls-is-poop/) points out that only the JAWS screen reader supports the `aria-controls` attribute. [ARIA Authoring Practices Guide on menu button](https://www.w3.org/WAI/ARIA/apg/patterns/menubutton/) recommends `aria-controls` only as optional. Apparently, we can forget about `aria-controls` (let me know if I’m wrong).

### 1.2 Search box
Now, when the user clicks the button, I want the HTML code to change as follows:

```html
<form role="search">
  <div class="popup">
    <button
      aria-label="Close searchbox"
      type="button"
    >
      <!-- SVG code for a cross icon (x) (omitted) -->
    </button>
    <div class="searchbox">
      <!-- SVG code for a magnifyiing glass (omitted) -->
      <input
        aria-label="Search for a place on the map"
        autocomplete="off"
        inputmode="search"
        placeholder="Enter place name or address"
        type="search"
      />
    </div>
  </div>
</form>
```
The `<div class="popup">` element is the one created in [**Day 19 of this blog series**](https://dev.to/masakudamatsu/day-19-styling-a-popup-like-clouds-2m04), styling the popup like clouds and positionining the close button at the top right corner.

The `<button>` element will be rendered by the close button component that I have created on [**Day 18 of this blog series**](https://dev.to/masakudamatsu/day-18-building-a-close-button-with-ripple-effect-as-a-react-component-1n62).

The `<div class="searchbox">` and its child elements is the search box that I have created on [**Day 17 of this blog series**](https://dev.to/masakudamatsu/day-17-styling-a-search-box-like-googles-51d2)

### 1.3 Rendering HTML with React
Using the `CloseButton` component created on [**Day 18**](https://dev.to/masakudamatsu/day-18-building-a-close-button-with-ripple-effect-as-a-react-component-1n62), I render the HTML code as described above with the following React component:
```js
import {useState} from 'react';
import {CloseButton} from './components/CloseButton';

export const Search = () => {
  const [searchBoxOpen, setSearchBoxOpen] = useState('false');
  return (
    <form role="search">
      {searchBoxOpen === 'false' ? (
        <button
          aria-expanded="false"
          aria-label="Search place"
          onClick={() => setSearchBoxOpen('true')}
          type="button"
        >
          {/* SVG code for a magnifyiing glass (omitted) */}
        </button>
      ) : (
        <div className="popup">
          <CloseButton
            ariaLabel="Close searchbox"
            handleClick={() => setSearchBoxOpen('false')}
          />
          <div className="searchbox">
            <input
              aria-label="Search for a place on the map"
              autoComplete="off"
              inputMode="search"
              placeholder="Enter place name or address"
              type="search"
            />
          </div>
        </div>
      )}
    </form>
  );
};
```
I create a state variable called `searchBoxOpen` with the `useState` hook. When it is `false`, the toggle button is rendered. When it is `true`, the search box popup is rendered.

Note also that we now need to use the camelCase for `autoComplete` and `inputMode` props in place of `autocomplete` and `inputmode` HTML attributes.

Now let me get to the main point of this article: handling keyboard users.

## 2. Focus management
Keyboard users need to control which interactive element is currently focused. For this purpose, there are three things to implement: (1) focus the search box after opening it; (2) focus the button to open the search box after closing it; (3) trap the focus within the popup showing the search box.

### 2.1 After opening the search box
For good user experience, auto-focusing the search box is critical:
> Don’t make people click twice when once (or not at all) will do. In some cases, the user has to first click the icon to open the search box and then click to move the input focus into the search field. One click on the icon should put the cursor in the field, ready for typing. — [Sherwin (2014)](https://www.nngroup.com/articles/magnifying-glass-icon/)

This feature is actually not just for keyboard users; touch device users and mouse users will also benefit from it.

For implementation, [Johnson (2019)](https://blog.maisie.ink/react-ref-autofocus/) describes three ways of auto-focusing an interactive element in React: the `autoFocus` prop, the combination of `useEffect` and `useRef`, and callback refs. She concludes:
> I would recommend that you use the autoFocus prop, unless you have odd circumstances (like I did) that prevent it from working. — [Johnson (2019)](https://blog.maisie.ink/react-ref-autofocus/)

Following this piece of advice, I add the `autoFocus` prop to the `<input type="search">` element:
```js
export const Search = () => {
  const [searchBoxOpen, setSearchBoxOpen] = useState('false');
  ...
  return (
    <form role="search">
      {searchBoxOpen === 'false' ? (
        <button
          aria-expanded="false"
          aria-label="Search place"
          onClick={() => setSearchBoxOpen('true')}
          type="button"
        >
          {/* SVG code for a magnifyiing glass (omitted) */}
        </button>
      ) : (
        <div className="popup">
          <CloseButton
            ariaLabel="Close searchbox"
            handleClick={() => setSearchBoxOpen('false')}
          />
          <div className="searchbox">
            <input
              aria-label="Search for a place on the map"
              autoComplete="off"
              autoFocus // ADDED
              inputMode="search"
              placeholder="Enter place name or address"
              type="search"
            />
          </div>
        </div>
      )}
    </form>
  );
};
```
This way, whenenver the user presses the magnifying glass button, the popup opens up with the search box focused automatically.

Unfortunately, iOS Safari users cannot immediately type into the auto-focused search box, though. Here is Apple’s take:
> We (Apple) ... do not want programmatic focus to bring up the keyboard when you do not have a hardware keyboard attached and the programmatic focus was not invoked in response to a user gesture. Why you may ask...because auto bringing up the software keyboard can be seen as annoying and a distraction to a user... — [Bates (2019)](https://bugs.webkit.org/show_bug.cgi?id=195884#c4)

We just need to accept this iOS Safari’s behavior. There is no simple way around, it seems.

Incidentally, auto-focusing has an accessibility issue:
> Automatically focusing a form control can confuse visually-impaired people using screen-reading technology and people with cognitive impairments. When autofocus is assigned, screen-readers "teleport" their user to the form control without warning them beforehand. — [MDN Contributors (2022b)](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#autofocus)

Since I have labelled `<input type="search">` with `aria-label="Search for a place on the map"`, screen reader users will learn what kind of interactive element they are now focusing on.

### 2.2 After closing the search box
After the user closes the popup for search, the button that has opened the popup should be auto-focused. That’s the recommendation by [the ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/):
> When a dialog closes, focus returns to the element that invoked the dialog... — [the ARIA Authoring Practices Guide for “Dialog (Modal)”](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/)

This feature is convenient when the keyboard user mistakenly presses the close button. In this case, they want to go back to the search box immediately. With the button to open it automatically focused, they can just hit the Return key to undo their mistake.

For implementation, we cannot use the `autoFocus` prop this time. The button to open the search box is rendered every time the user accesses to the app. We don’t want the search button to be always focused; the user may want to open the menu first or locate themselves on the map by pressing the locator button (see [**Day 12**](https://dev.to/masakudamatsu/day-12-showing-user-location-on-embedded-google-maps-with-geolocation-api-and-react-128j)).

Instead we want to auto-focus the search button only after the search box popup is closed. This happens when the `searchBoxOpen` state changes from `true` to `false`. We can regard the auto-focusing of the seach button as a _side effect_ of state change. That is when we should use the `useEffect` hook.

So we can use what [Johnson (2019)](https://blog.maisie.ink/react-ref-autofocus/) describes as the second approach of auto-focusing an element in React: the combination of `useEffect` and `useRef`.

First, refer to the toggle button with the `useRef` hook:
```js
  ...
  const buttonElement = useRef();
  ...
  return (
    ...
        <button
          aria-expanded="false"
          aria-label="Search place"
          onClick={() => setSearchBoxOpen('true')}
          ref={buttonElement} // ADDED
          type="button"
        >
  )
```
Then, use the `useEffect` hook to run the following code whenever the search box is closed:
```js
  useEffect(() => {
    if (searchBoxOpen === 'false') {
      buttonElement.current.focus();
    }
  }, [searchBoxOpen]);
```
Well, the above `useEffet` code block doesn’t work quite. It will auto-focus the search button when the button is first rendered (that is, when the user first accesses the app). The reason is that the `useEffect` hook only picks the current state, not the previous state as well.

I think there are a few ways around. One solution is to record whether the close button is pressed with the `useRef` hook. So revise the click handler of the close button as follows:
```js
...
  // ADDED FROM HERE
  const closeButtonPressed = useRef();
  const handleClickCloseButton = () => {
    closeButtonPressed.current = true;
    setSearchBoxOpen('false');
  }
  // ADDED UNTIL HERE
...
          <CloseButton
            ariaLabel="Close searchbox"
            handleClick={handleClickCloseButton} // REVISED
          />
...
```
Then, we can check whether `closeButtonPressed.current` is `true` before auto-focusing the search button:
```js
...
  const buttonElement = useRef();
  useEffect(() => {
    if (searchBoxOpen === 'false') {
      // REVISED FROM HERE
      if (closeButtonPressed.current === true) {
        buttonElement.current.focus();
      }
      // REVISED UNTIL HERE
    }
  })
...
```

So the entire code is as follows:

```js
import {useEffect, useRef, useState} from 'react'; // REVISED
import {CloseButton} from './components/CloseButton';

export const Search = () => {
  const [searchBoxOpen, setSearchBoxOpen] = useState('false');

  ...

  // ADDED FROM HERE
  const buttonElement = useRef();
  const closeButtonPressed = useRef();

  const handleClickCloseButton = () => {
    closeButtonPressed.current = true;
    setSearchBoxOpen('false');
  }

  useEffect(() => {
    if (searchBoxOpen === 'false') {
      if (closeButtonPressed.current === true) {
        buttonElement.current.focus();
      }
    }
  }, [searchBoxOpen]);
  // ADDED UNTIL HERE

  return (
    <form role="search">
      {searchBoxOpen === 'false' ? (
        <button
          aria-expanded="false"
          aria-label="Search place"
          onClick={() => setSearchBoxOpen('true')}
          ref={buttonElement} // ADDED
          type="button"
        >
          {/* SVG code for a magnifying glass (omitted) */}
        </button>
      ) : (
        <div className="popup">
          <CloseButton
            ariaLabel="Close searchbox"
            handleClick={handleClickCloseButton} // REVISED
          />
          <div className="searchbox">
            <input
              aria-label="Search for a place on the map"
              autoComplete="off"
              autoFocus
              inputMode="search"
              placeholder="Enter place name or address"
              type="search"
            />
          </div>
        </div>
      )}
    </form>
  );
};
```

This solution can also handle the situation where the searchbox popup closes when the user selects one of the autocomplete suggestions (which will be implemented in one of the next posts of this blog series). In this case, the app will autofocus the popup showing the search result, not the search button. So we can create a click handler for the search result element like so:
```js
 const closeSearchBox = () => {
    closeButtonPressed.current = false;
    setSearchBoxOpen('false');
  };
```
This way, the code block of `useEffect` for auto-focusing will not run.

### 2.3 Trap the focus within the popup
Finally, we want to trap the focus within the search box popup. Otherwise, keyboard users can end up having a focus on one of the place marks in the map beneath the popup. Again, let me cite [ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/):
> If focus is on the last tabbable element inside the dialog, [Tab] moves focus to the first tabbable element inside the dialog.
> If focus is on the first tabbable element inside the dialog, [Shift + Tab] moves focus to the last tabbable element inside the dialog.
> — [ARIA Authoring Practices Guide for “Dialog (Modal)”](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/)

The implementation of focus trap is very complicated to code from scratch. See [Giraudel (2021)](https://www.smashingmagazine.com/2021/07/accessible-dialog-from-scratch/#trapping-focus) for how complex the code can be.

More recently, web developers have been talking about the `inert` attribute to trap the focus (see [Klavenes 2022](https://larsmagnus.co/blog/accessible-modal-dialogs-using-inert), for example). As of November 2022, however, Firefox is yet to support the `inert` attribute (source: [Can I Use?](https://caniuse.com/mdn-api_htmlelement_inert)). We need to wait for a bit more.

The solution I’ve adopted is [the `react-focus-lock` library](https://github.com/theKashey/react-focus-lock#readme), used by Atlassian AtlasKit, ReachUI, SmoothUI, and Storybook among others.

With its FocusLock component, it’s remarkably simple to implement the focus trap:
```js
...
import FocusLock from 'react-focus-lock'; // ADDED

export const Search = () => {
  ...
  return (
    <form role="search">
      {searchBoxOpen === 'false' ? (
        <button
          aria-expanded="false"
          aria-label="Search place"
          onClick={() => setSearchBoxOpen('true')}
          ref={buttonElement}
          type="button"
        >
          {/* SVG code for a magnifying glass (omitted) */}
        </button>
      ) : (
        <FocusLock> {/* ADDED */}
          <div className="popup">
            <CloseButton
              ariaLabel="Close searchbox"
              handleClick={() => setSearchBoxOpen('false')}
            />
            <div className="searchbox">
              <input
                aria-label="Search for a place on the map"
                autoComplete="off"
                autoFocus
                inputMode="search"
                placeholder="Enter place name or address"
                type="search"
              />
            </div>
          </div>
        </FocusLock> {/* ADDED */}
      )}
    </form>
  );
};
```
We just need to wrap the popup with `<FocusLock>`. This way, once the popup is open, pressing the Tab key will cycle the focus within the popup (in our case, the focus moves between the search box and the close button only).

## 3. Close with ESC key
For keyboard users, pressing the ESC key is the standard method for closing a popup. In [the ARIA Authoring Practices Guide for “Dialog (Modal)”](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/), the pressing of the Esc key to close the dialog is listed as one of keyboard interaction requirements.

How can we implement this feature with React?

[Woodson (2020)](https://www.pluralsight.com/guides/event-listeners-in-react-components) gives me a clue. He suggests using the `useEffect` hook like this:
```js
useEffect(() => {
  window.addEventListener('keydown', (event) => {
      // ...
  });
}, []);
```
The code block inside the `useEffect` hook will be run after the HTML code is rendered. Therefore, it allows the `keydown` event handler to be attached to the `window` object that will not be created until the HTML code is rendered.

However, the `keydown` event is fired on the `document` object, not the `window` object, according to [the MDN Web Docs on “Event reference”](https://developer.mozilla.org/en-US/docs/Web/Events). So I’m going to use `document.addEventListener()`.

Let’s first work out the code inside the `useEffect` hook. I define an `keydown` event handler as `closeByEsc`: 
```js
const closeByEsc = event => {
  if (event.key === 'Escape') {
    handleClickCloseButton();
  }
};
```
If the pressed key, available as `event.key`, is the Esc key, this handler runs the `handleClickCloseButton` function defined in the previous section:
```js
  const handleClickCloseButton = () => {
    closeButtonPressed.current = true;
    setSearchBoxOpen('false');
  }
```
This way, after pressing the Esc key to close the popup, the toggle button will be auto-focused, just like after pressing the close button.

Then, when the search box is opened, attach this event handler to `document`:
```js
if (searchBoxOpen === 'true') {
  document.addEventListener('keydown', closeByEsc);
} 
```

When the search box is closed, remove this event handler from `document`:
```js
if (searchBoxOpen === 'true') {
  document.addEventListener('keydown', closeByEsc);

// ADDED FROM HERE
} else {
  document.removeEventListener('keydown', closeByEsc);
// ADDED UNTIL HERE

} 
```

This way, pressing the Esc key will close the search box if and only if the search box is open. When another popup is open, I want them to be closed with the pressing of the Esc key as well. Each time a popup is opened (or closed), I will attach (or remove) the event handler dedicated to closing that particular popup.

Then insert them all into the `useEffect` hook code block:
```js
useEffect(() => { // ADDED
  const closeByEsc = event => {
    if (event.key === 'Escape') {
      handleClickCloseButton();
    }
  };
  if (searchBoxOpen === 'true') {
    document.addEventListener('keydown', closeByEsc);
  } else {
    document.removeEventListener('keydown', closeByEsc);
  }
}, [searchBoxOpen]); // ADDED
```
where `[searchBoxOpen]`, the second argument for the `useEffect` hook, makes the `useEffect` code block run each time the value of `searchBoxOpen` changes. This is critical to attach and remove the event listener each time the search box is opened and closed.

Finally, in case the `Search` component is dismounted while the search box remains open, we want to remove the event listener. To implement this, we use the `return` statement: 
```js
useEffect(() => {
  const closeByEsc = event => {
    if (event.key === 'Escape') {
      handleClickCloseButton();
    }
  };
  if (searchBoxOpen === 'true') {
    document.addEventListener('keydown', closeByEsc);
  } else {
    document.removeEventListener('keydown', closeByEsc);
  }

  // ADDED FROM HERE
  return () => {
    document.removeEventListener('keydown', closeByEsc);
  }
  // ADDED UNTIL HERE

}, [searchBoxOpen]);
```

The complete code for the `Search` component (including the one described in the previous section) is now as follows:
```js
import FocusLock from "react-focus-lock"; // for trapping focus inside popup
import { useEffect, useRef, useState } from "react";
import { ButtonCloud } from "../styled-components/ButtonCloud";
import { CloseButton } from "./CloseButton";

export const Search = () => {
  const [searchBoxOpen, setSearchBoxOpen] = useState("false");

  // Auto-focus the search button after closing search box
  const buttonElement = useRef();
  const closeButtonPressed = useRef();
  const handleClickCloseButton = () => {
    closeButtonPressed.current = true;
    setSearchBoxOpen("false");
  };
  useEffect(() => {
    if (searchBoxOpen === "false") {
      if (closeButtonPressed.current === true) {
        buttonElement.current.focus();
      }
    }
  });

  // Close search box with Esc key
  useEffect(() => {
    const closeByEsc = (event) => {
      if (event.key === "Escape") {
        handleClickCloseButton();
      }
    };
    if (searchBoxOpen === "true") {
      document.addEventListener("keydown", closeByEsc);
    } else {
      document.removeEventListener("keydown", closeByEsc);
    }
    return () => {
      document.removeEventListener("keydown", closeByEsc);
    };
  }, [searchBoxOpen]);

  return (
    <form role="search">
      {searchBoxOpen === "false" ? (
        <button
          aria-expanded="false"
          aria-label="Search place"
          onClick={() => setSearchBoxOpen("true")}
          ref={buttonElement}
          type="button"
        >
          {/* SVG code for a magnifying glass (omitted) */}
        </button>
      ) : (
        <FocusLock> {/* trap focus inside popup */}
          <div className="popup">
            <CloseButton
              ariaLabel="Close searchbox"
              handleClick={handleClickCloseButton}
            />
            <div className="searchbox">
              <input
                aria-label="Search for a place on the map"
                autoComplete="off"
                autoFocus // Auto-focus search box when opened
                inputMode="search"
                placeholder="Enter place name or address"
                type="search"
              />
            </div>
          </div>
        </FocusLock>
      )}
    </form>
  );
};
```

## Demo
Here is [the CodeSandbox demo for the entire code discussed in this article](https://codesandbox.io/s/my-ideal-maps-searchbox-4ui875?file=/src/components/Search.js). With this demo, try the following:
- Press the magnifying glass icon button at the top-right corner. You should be able to enter text in the search box (unless you use iOS Safari).
- Press the Tab key to see the focus ring move between the search box and the close button. 
- Press the Esc key to close the search box.
- After closing the search box, press the Enter key, which should open the search box again.


## References
Bates, Daniel (2019) “[So, I've got some good news 🙂 and some bad news 🙁 for you. Let's do good news first...](https://bugs.webkit.org/show_bug.cgi?id=195884#c4)”, Comment to _WebKit Bugzilla_, Mar 19, 2019.

Giraudel, Kitty (2021) “[Creating An Accessible Dialog From Scratch](https://www.smashingmagazine.com/2021/07/accessible-dialog-from-scratch/)”, _Smashing Magazine_, Jul 28, 2021.

Johnson, Maisie (2019) “[3 ways to autofocus an input in React that ALMOST always work!](https://blog.maisie.ink/react-ref-autofocus/)”, _blog.maisie.ink_, Oct 25, 2019.

Klavenes, Lars Magnus (2022) “[Accessible modal dialogs using inert](https://larsmagnus.co/blog/accessible-modal-dialogs-using-inert)”, _larsmagnus.co_, Jun 11, 2022.

MDN Contributors (2022a) “[<input type="search">](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/search)”, _MDN Web Docs_, last modified on Dec 11, 2022. 

[MDN Contributors (2022b) “<input>: The Input (Form Input) element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)”, _MDN Web Docs_, last modified on Nov 26, 2022. 

Pickering, Heydon (2016) “[Aria-Controls is Poop](https://heydonworks.com/article/aria-controls-is-poop/)”, _Heydonworks_, Aug 21, 2016.

Sherwin, Katie (2014) “[The Magnifying-Glass Icon in Search Design: Pros and Cons](https://www.nngroup.com/articles/magnifying-glass-icon/)”, _Nielsen Norman Group_, Feb 23, 2014.

Silver, Adam (2019) “[Why, How, and When to Use Semantic HTML and ARIA](https://css-tricks.com/why-how-and-when-to-use-semantic-html-and-aria/)”, _CSS-Tricks_, May 7, 2019.

Woodson, Marques (2020) “[Event Listeners in React Components](https://www.pluralsight.com/guides/event-listeners-in-react-components)”, _Pluralsight_, Jun 12, 2020.