Back to all examples

Filter a list using a push drawer

const [open, setOpen] = useState(false);
<div style={{ display: "flex", minHeight: "480px" }}>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div
          style={{
            display: "flex",
            alignItems: "center",
            gap: "1rem",
            marginBottom: "1rem",
          }}
        >
          <h3 style={{ flex: 1, margin: 0 }}>All cases</h3>
          {!open && (
            <GoabxButton
              type="secondary"
              size="compact"
              leadingIcon="filter"
              onClick={() => setOpen(true)}
            >
              Filters
            </GoabxButton>
          )}
        </div>

        <GoabxTable width="100%">
          <table width="100%">
            <thead>
              <tr>
                <th>Status</th>
                <th>Name</th>
                <th>File number</th>
                <th>Act</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>
                  <GoabxBadge type="success" content="Completed" />
                </td>
                <td>Gilbert Barton</td>
                <td>24567-9876</td>
                <td>Traffic safety act</td>
              </tr>
              <tr>
                <td>
                  <GoabxBadge type="information" content="New" />
                </td>
                <td>Brynn Hurley</td>
                <td>98765-3456</td>
                <td>Trespass to premises act</td>
              </tr>
              <tr>
                <td>
                  <GoabxBadge type="midtone" content="In review" />
                </td>
                <td>Marco Silva</td>
                <td>34521-7890</td>
                <td>Gaming, liquor, and cannabis act</td>
              </tr>
              <tr>
                <td>
                  <GoabxBadge type="success" content="Completed" />
                </td>
                <td>Dana Chen</td>
                <td>55123-4567</td>
                <td>Traffic safety act</td>
              </tr>
              <tr>
                <td>
                  <GoabxBadge type="information" content="New" />
                </td>
                <td>Amira Hassan</td>
                <td>67890-1234</td>
                <td>Trespass to premises act</td>
              </tr>
            </tbody>
          </table>
        </GoabxTable>
      </div>

      <GoabPushDrawer
        heading="Filters"
        width="260px"
        open={open}
        onClose={() => setOpen(false)}
      >
        <GoabxFormItem label="Act">
          <GoabxCheckboxList name="act" onChange={() => {}}>
            <GoabxCheckbox name="traffic" text="Traffic safety act" size="compact" />
            <GoabxCheckbox
              name="gaming"
              text="Gaming, liquor, and cannabis act"
              size="compact"
            />
            <GoabxCheckbox
              name="trespass"
              text="Trespass to premises act"
              size="compact"
            />
          </GoabxCheckboxList>
        </GoabxFormItem>
        <GoabxFormItem label="Status" mt="l">
          <GoabxDropdown name="status" onChange={() => {}} value="" size="compact">
            <GoabxDropdownItem value="" label="All statuses" />
            <GoabxDropdownItem value="new" label="New" />
            <GoabxDropdownItem value="in-review" label="In review" />
            <GoabxDropdownItem value="completed" label="Completed" />
          </GoabxDropdown>
        </GoabxFormItem>
      </GoabPushDrawer>
    </div>
const filtersDrawer = document.getElementById("filters-drawer");
const openFiltersBtn = document.getElementById("open-filters-btn");

openFiltersBtn.addEventListener("_click", () => {
  filtersDrawer.setAttribute("open", "true");
  openFiltersBtn.style.display = "none";
});

filtersDrawer.addEventListener("_close", () => {
  filtersDrawer.removeAttribute("open");
  openFiltersBtn.style.display = "";
});
<div style="display: flex; min-height: 480px">
  <div style="flex: 1; min-width: 0">
    <div style="display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem">
      <h3 style="flex: 1; margin: 0">All cases</h3>
      <goa-button
        version="2"
        id="open-filters-btn"
        type="secondary"
        size="compact"
        leadingicon="filter"
        >Filters</goa-button
      >
    </div>

    <goa-table version="2" width="100%">
      <table width="100%">
        <thead>
          <tr>
            <th>Status</th>
            <th>Name</th>
            <th>File number</th>
            <th>Act</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>
              <goa-badge version="2" type="success" content="Completed"></goa-badge>
            </td>
            <td>Gilbert Barton</td>
            <td>24567-9876</td>
            <td>Traffic safety act</td>
          </tr>
          <tr>
            <td><goa-badge version="2" type="information" content="New"></goa-badge></td>
            <td>Brynn Hurley</td>
            <td>98765-3456</td>
            <td>Trespass to premises act</td>
          </tr>
          <tr>
            <td>
              <goa-badge version="2" type="midtone" content="In review"></goa-badge>
            </td>
            <td>Marco Silva</td>
            <td>34521-7890</td>
            <td>Gaming, liquor, and cannabis act</td>
          </tr>
          <tr>
            <td>
              <goa-badge version="2" type="success" content="Completed"></goa-badge>
            </td>
            <td>Dana Chen</td>
            <td>55123-4567</td>
            <td>Traffic safety act</td>
          </tr>
          <tr>
            <td><goa-badge version="2" type="information" content="New"></goa-badge></td>
            <td>Amira Hassan</td>
            <td>67890-1234</td>
            <td>Trespass to premises act</td>
          </tr>
        </tbody>
      </table>
    </goa-table>
  </div>

  <goa-push-drawer id="filters-drawer" heading="Filters" width="260px">
    <goa-form-item version="2" label="Act">
      <goa-checkbox-list name="act">
        <goa-checkbox
          version="2"
          name="traffic"
          text="Traffic safety act"
          size="compact"
        ></goa-checkbox>
        <goa-checkbox
          version="2"
          name="gaming"
          text="Gaming, liquor, and cannabis act"
          size="compact"
        ></goa-checkbox>
        <goa-checkbox
          version="2"
          name="trespass"
          text="Trespass to premises act"
          size="compact"
        ></goa-checkbox>
      </goa-checkbox-list>
    </goa-form-item>
    <goa-form-item version="2" label="Status" mt="l">
      <goa-dropdown version="2" name="status" size="compact">
        <goa-dropdown-item value="" label="All statuses"></goa-dropdown-item>
        <goa-dropdown-item value="new" label="New"></goa-dropdown-item>
        <goa-dropdown-item value="in-review" label="In review"></goa-dropdown-item>
        <goa-dropdown-item value="completed" label="Completed"></goa-dropdown-item>
      </goa-dropdown>
    </goa-form-item>
  </goa-push-drawer>
</div>

Use a push drawer to house filters alongside a list of records. The push drawer keeps the filter controls accessible while users can still see and interact with the filtered results.

When to use

Use this pattern when:

  • Users need to filter a list or table and see results update alongside the filters
  • The filter panel should be dismissible to reclaim screen space
  • Users go back and forth between adjusting filters and reviewing results

Considerations

  • On smaller screens, the push drawer falls back to an overlay drawer automatically
  • Consider whether filters should apply immediately or require a Save action
  • Consider hiding the trigger button while the drawer is open to reduce visual clutter