Bento

Bento Sidebar

<head>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>bento-sidebar</title>
    <script
      type="module"
      src="https://cdn.ampproject.org/bento.mjs"
      crossorigin="anonymous"
    ></script>
    <script
      nomodule
      src="https://cdn.ampproject.org/bento.js"
      crossorigin="anonymous"
    ></script>
    <script
      type="module"
      src="https://cdn.ampproject.org/v0/bento-sidebar-1.0.mjs"
      crossorigin="anonymous"
    ></script>
    <script
      nomodule
      src="https://cdn.ampproject.org/v0/bento-sidebar-1.0.js"
      crossorigin="anonymous"
    ></script>
    <link
      rel="stylesheet"
      href="https://cdn.ampproject.org/v0/bento-sidebar-1.0.css"
      crossorigin="anonymous"
    />
    <style>
      body {
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
          Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
          'Segoe UI Symbol';
        background: #ecf1f3;
      }
      button {
        -webkit-appearance: none;
        background: transparent;
        border: none;
        box-shadow: none;
        color: #4c5a63;
        cursor: pointer;
        float: right;
        width: 40px;
        height: 35px;
        margin: 0 1rem;
      }
      h2 {
        font-size: 34px;
        font-weight: bold;
        line-height: 1.18;
        letter-spacing: -0.5px;
        color: #002b39;
        margin-block-start: 74px;
      }
      bento-sidebar[open] {
        background: #fff;
        padding-inline: 40px;
        max-width: 320px;
      }
      ul {
        list-style: none;
        padding: 0;
        margin: 0;
      }
      li {
        font-size: 16px;
        font-weight: 650;
        line-height: 2;
        color: #4c5a63;
        padding-block: 8px;
      }
    </style>
</head>

<body>

    <button id="open-sidebar">
      <svg
        xmlns="http://www.w3.org/2000/svg"
        height="48px"
        viewBox="0 0 24 24"
        width="48px"
        fill="#000000"
      >
        <path d="M0 0h24v24H0V0z" fill="none" />
        <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z" />
      </svg>
    </button>
    <bento-sidebar id="sidebar1" side="left" hidden>
      <button id="close-sidebar">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="53.7"
          height="53.7"
          viewBox="0 0 53.7 53.7"
          stroke="#4c5a63"
        >
          <path
            opacity=".6"
            fill="%234c5a63"
            d="M35.6 34.4L28 26.8l7.6-7.6c.2-.2.2-.5
                  0-.7l-.5-.5c-.2-.2-.5-.2-.7 0l-7.6
                  7.6-7.5-7.6c-.2-.2-.5-.2-.7 0l-.6.6c-.2.2-.2.5 0
                  .7l7.6 7.6-7.6 7.5c-.2.2-.2.5 0 .7l.5.5c.2.2.5.2.7
                  0l7.6-7.6 7.6 7.6c.2.2.5.2.7 0l.5-.5c.2-.2.2-.5 0-.7z"
          />
        </svg>
      </button>
      <h2>Navigation Sidebar</h2>
      <ul>
        <li>Nav item A</li>
        <li>Nav item B</li>
        <li>Nav item C</li>
        <li>Nav item D</li>
      </ul>
    </bento-sidebar>
    <script>
      (async () => {
        const sidebar = document.querySelector('#sidebar1');
        await customElements.whenDefined('bento-sidebar');
        const api = await sidebar.getApi();
        // set up button actions
        document.querySelector('#open-sidebar').onclick = () => api.open();
        document.querySelector('#close-sidebar').onclick = () => api.close();
      })();
    </script>
</body>

Provides a way to display meta content intended for temporary access such as navigation, links, buttons, menus. The sidebar can be revealed by a button tap while the main content remains visually underneath.

Use bento-sidebar as a web component or a React functional component:

↓ Web Component ↓ React / Preact

Web Component

You must include each Bento component's required CSS library to guarantee proper loading and before adding custom styles. Or use the light-weight pre-upgrade styles available inline. See Layout and style.

Import via npm

npm install @bentoproject/sidebar
import {defineElement as defineBentoSidebar} from '@bentoproject/sidebar';
defineBentoSidebar();

Include via <script>

<script type="module" src="https://cdn.ampproject.org/bento.mjs" crossorigin="anonymous"></script>
<script nomodule src="https://cdn.ampproject.org/bento.js" crossorigin="anonymous"></script>
<script type="module" src="https://cdn.ampproject.org/v0/bento-sidebar-1.0.mjs" crossorigin="anonymous"></script>
<script nomodule src="https://cdn.ampproject.org/v0/bento-sidebar-1.0.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.ampproject.org/v0/bento-sidebar-1.0.css" crossorigin="anonymous">

Example

<head>

<script
      type="module"
      async
      src="https://cdn.ampproject.org/bento.mjs"
    ></script>
    <script nomodule src="https://cdn.ampproject.org/bento.js"></script>
    <script
      type="module"
      async
      src="https://cdn.ampproject.org/v0/bento-sidebar-1.0.mjs"
    ></script>
    <script
      nomodule
      async
      src="https://cdn.ampproject.org/v0/bento-sidebar-1.0.js"
    ></script>
    <link
      rel="stylesheet"
      type="text/css"
      href="https://cdn.ampproject.org/v0/bento-sidebar-1.0.css"
    />
</head>

<body>

<bento-sidebar id="sidebar1" side="right" hidden>
      <ul>
        <li>Nav item 1</li>
        <li>Nav item 2</li>
        <li>Nav item 3</li>
        <li>Nav item 4</li>
        <li>Nav item 5</li>
        <li>Nav item 6</li>
      </ul>
    </bento-sidebar>

    <div class="buttons" style="margin-top: 8px">
      <button id="open-sidebar">Open sidebar</button>
    </div>

    <script>
      (async () => {
        const sidebar = document.querySelector('#sidebar1');
        await customElements.whenDefined('bento-sidebar');
        const api = await sidebar.getApi();

        // set up button actions
        document.querySelector('#open-sidebar').onclick = () => api.open();
      })();
    </script>
</body>

Interactivity and API usage

Bento components are highly interactive through their API. The bento-sidebar component API is accessible by including the following script tag in your document:

await customElements.whenDefined('bento-sidebar');
const api = await carousel.getApi();

Actions

The bento-sidebar API allows you to perform the following actions:

open()

Opens the sidebar.

api.open();
close()

Closes the sidebar.

api.close();
toggle()

Toggles the sidebar open state.

api.toggle(0);

Layout and style

Each Bento component has a small CSS library you must include to guarantee proper loading without content shifts. Because of order-based specificity, you must manually ensure that stylesheets are included before any custom styles.

<link
rel="stylesheet"
type="text/css"
href="https://cdn.ampproject.org/v0/bento-sidebar-1.0.css"
/>

Alternatively, you may also make the light-weight pre-upgrade styles available inline:

<style>
bento-sidebar:not([open]) {
display: none !important;
}
</style>

Custom styles

The bento-sidebar component can be styled with standard CSS.

  • The width of the bento-sidebar may be set to adjust the width from the pre-set 45px value.
  • The height of the bento-sidebar may be set to adjust the height of the sidebar, if required. If the height exceeds 100vw, the sidebar will have a vertical scrollbar. The preset height of the sidebar is 100vw and can be overridden in CSS to make it shorter.
  • The current state of the sidebar is exposed via the open attribute that is set on the bento-sidebar tag when the side bar is open on the page.
bento-sidebar[open] {
height: 100%;
width: 50px;
}

UX considerations

When using <bento-sidebar>, keep in mind that your users will often view your page on mobile, which may display a fixed-position header. In addition, browsers often display their own fixed header at the top of the page. Adding another fixed-position element at the top of the screen would take up a large amount of mobile screen space with content that gives the user no new information.

For this reason, we recommend that affordances to open the sidebar are not placed in a fixed, full-width header.

  • The sidebar can only appear on the left or right side of a page.
  • The max-height of the sidebar is 100vh, if the height exceeds 100vh then a vertical scrollbar appears. The default height is set to 100vh in CSS and is overridable in CSS.
  • The width of the sidebar can be set and adjusted using CSS.
  • <bento-sidebar> is recommended to be be a direct child of the <body> to preserve a logical DOM order for accessibility as well as to avoid altering its behavior by a container element. Note that having an ancestor of bento-sidebar with a set z-index may cause the sidebar to appear below other elements (such as headers), breaking its functionality.

Attributes

side

Indicates what side of the page the sidebar should open from, either left or right. If a side is not specified, the side value will be inherited from the body tag's dir attribute (ltr => left , rtl => right); if no dir exists, the side defaults to left.

open

This attribute is present when the sidebar is open.


Preact/React Component

Import via npm

npm install @bentoproject/sidebar
import React from 'react';
import {BentoSidebar} from '@bentoproject/sidebar/react';
import '@bentoproject/sidebar/styles.css';

function App() {
return (
<BentoSidebar>
<ul>
<li>Nav item 1</li>
<li>Nav item 2</li>
<li>Nav item 3</li>
<li>Nav item 4</li>
<li>Nav item 5</li>
<li>Nav item 6</li>
</ul>
</BentoSidebar>
);
}

Interactivity and API usage

Bento components are highly interactive through their API. The BentoSidebar component API is accessible by passing a ref:

import React, {createRef} from 'react';
const ref = createRef();

function App() {
return (
<BentoSidebar ref={ref}>
<ul>
<li>Nav item 1</li>
<li>Nav item 2</li>
<li>Nav item 3</li>
<li>Nav item 4</li>
<li>Nav item 5</li>
<li>Nav item 6</li>
</ul>
</BentoSidebar>
);
}

Actions

The BentoSidebar API allows you to perform the following actions:

open()

Opens the sidebar.

ref.current.open();
close()

Closes the sidebar.

ref.current.close();
toggle()

Toggles the sidebar open state.

ref.current.toggle(0);

Layout and style

The BentoSidebar component can be styled with standard CSS.

  • The width of the bento-sidebar may be set to adjust the width from the preset 45px value.
  • The height of the bento-sidebar may be set to adjust the height of the sidebar, if required. If the height exceeds 100vw, the sidebar will have a vertical scrollbar. The preset height of the sidebar is 100vw and can be overridden in CSS to make it shorter.

To ensure the component renders how you want it to, be sure to apply a size to the component. These can be applied inline:

<BentoSidebar style={{width: 300, height: '100%'}}>
<ul>
<li>Nav item 1</li>
<li>Nav item 2</li>
<li>Nav item 3</li>
<li>Nav item 4</li>
<li>Nav item 5</li>
<li>Nav item 6</li>
</ul>
</BentoSidebar>

Or via className:

<BentoSidebar className="custom-styles">
<ul>
<li>Nav item 1</li>
<li>Nav item 2</li>
<li>Nav item 3</li>
<li>Nav item 4</li>
<li>Nav item 5</li>
<li>Nav item 6</li>
</ul>
</BentoSidebar>
.custom-styles {
height: 100%;
width: 300px;
}

UX considerations

When using <BentoSidebar>, keep in mind that your users will often view your page on mobile, which may display a fixed-position header. In addition, browsers often display their own fixed header at the top of the page. Adding another fixed-position element at the top of the screen would take up a large amount of mobile screen space with content that gives the user no new information.

For this reason, we recommend that affordances to open the sidebar are not placed in a fixed, full-width header.

  • The sidebar can only appear on the left or right side of a page.
  • The max-height of the sidebar is 100vh, if the height exceeds 100vh then a vertical scrollbar appears. The default height is set to 100vh in CSS and is overridable in CSS.
  • The width of the sidebar can be set and adjusted using CSS.
  • <BentoSidebar> is recommended to be be a direct child of the <body> to preserve a logical DOM order for accessibility as well as to avoid altering its behavior by a container element. Note that having an ancestor of BentoSidebar with a set z-index may cause the sidebar to appear below other elements (such as headers), breaking its functionality.

Props

side

Indicates what side of the page the sidebar should open from, either left or right. If a side is not specified, the side value will be inherited from the body tag's dir attribute (ltr => left , rtl => right); if no dir exists, the side defaults to left.

More details