Skip to content

Sheet

The h-sheet webcomponent provides a solid foundation for creating overlays, side panels, or sheets that slide into the viewport. It uses the <h-portal> webcomponent to render its content in a different location, typically targeting <h-portal-target name="sheets"> to avoid z-index and nesting issues.

Note: h- stands for headless. This is naming convention used for every webcomponent as they must have a two-part name.

Features:

  • Keyboard support: Enables closing via the Escape key and manages focus trapping.
  • Allows to close the sheet by clicking somewhere else on a page
  • Disables scrolling of the page when the sheet is open
  • Manages focus, keeps it within sheet until closed
  • Automatically adds appropriate ARIA roles and accessibility attributes
  • Provides additional webcomponents to facilitate use
  • Provides default styles (which may be customized)

Attributes

Attribute name Type Default Description
opened boolean false Decides if sheet is opened on render.
class string '' Class to customize sheet look or position.
transition string scale Transition class name to change how sheet open and closes.

Note: hidden attribute should always be a part of h-sheet component to avoid layout shifts.

Inner h-sheet components

To facilitate sheet creation, several specialized components are provided:

h-sheet-opener

Clicking this element opens the sheet with the matching name attribute. The h-sheet webcomponent with associated id is the actual sheet that will open. You may have several h-sheet-opener's with same name attribute.

h-sheet-header

Wraps the header content. It is automatically assigned to the header slot and receives the sheet__header class.

h-sheet-body

Wraps the main content. It is assigned to the body slot and receives the sheet__body class.

Wraps the footer content. It is automatically assigned to the footer slot and receives the sheet__footer class.

h-sheet-close

A utility component that closes the parent sheet when clicked.

DOM events

This webcomponent listens to the following DOM events:

This webcomponent also dispatches the following DOM events:

Examples

Here are some examples of sheet usage:

Basic sheet

This is a markup for a basic sheet with header, body, and footer sections.

HTML
<h-sheet-opener name="example-sheet">Open Sheet</h-sheet-opener>

<h-sheet id="example-sheet" hidden>
    <h-sheet-header>
        <header><strong class="h6 font_semibold">Sheet Title</strong></header>

        <h-sheet-close class="btn btn_icon">
            <span class="sr-only">Close</span>
            <svg class="btn__icon icon icon_l" aria-hidden="true">
                <use xlink:href="/assets/img/icons/symbol-defs.svg#icon-x"></use>
            </svg>
        </h-sheet-close>
    </h-sheet-header>

    <h-sheet-body>
        <p class="size_s">This is the main content of the sheet. It behaves exactly like a modal but uses the "sheet" naming convention.</p>
    </h-sheet-body>

    <h-sheet-footer>
        <h-sheet-close class="sheet__btn btn btn_outline">Cancel</h-sheet-close>
        <button class="sheet__btn btn btn_primary">Confirm Action</button>
    </h-sheet-footer>
</h-sheet>

Opened sheet

This is a markup for an opened sheet.

HTML
<h-sheet hidden opened>
    <h-sheet-header>
        Simple header
    </h-sheet-header>

    <h-sheet-body>
        Im opened at start
    </h-sheet-body>
</h-sheet>

Changing default transition

The default transition is scale. Custom transitions can be implemented using the transition attribute and corresponding CSS classes. Here is an example of using a slide-from-top transition:

Slide-from-top HTML example
<h-sheet hidden transition="slide-from-top">
    <h-sheet-header>
        Simple header
    </h-sheet-header>

    <h-sheet-body>
        Im opened at start
    </h-sheet-body>
</h-sheet>
Slide-from-top CSS example
.sheet_show-slide-from-top-start,
.sheet_hide-slide-from-top-end {
    opacity: 0;
    transform: translate3d(0, -5rem, 0);
}

.sheet_show-slide-from-top-end,
.sheet_hide-slide-from-top-start {
    opacity: 1;
    transform: translate3d(0, 0, 0);
}

JavaScript API

You can control the sheet programmatically using its public methods:

open(): void

Opens sheet

const sheet = document.querySelector('h-sheet#my-sheet');
sheet.open();

close(): void

Closes sheet

const sheet = document.querySelector('h-sheet#my-sheet');
sheet.close();

Customization with Slots

You can provide raw HTML elements to the slots for full control:

HTML
<h-sheet id="custom-sheet" hidden>
    <div slot="header" class="my-custom-header">
        Custom Header Content
    </div>

    <div slot="body">
        Custom Body Content
    </div>

    <div slot="footer">
        <h-sheet-close>Close</h-sheet-close>
    </div>
</h-sheet>

Adding CSS classes

You can provide CSS classes to your sheet elements simply add them to the webcomponents. It works with custom slots as well:

HTML
<h-sheet-opener name="sheet">Click me!</h-sheet-opener>

<h-sheet id="sheet" class="my-custom-sheet-container" hidden>
    <h-sheet-header class="sheet-custom-header">
        Simple header
    </h-sheet-header>

    <h-sheet-body class="sheet-custom-body">
        Simple body
    </h-sheet-body>

    <div slot="footer" class="sheet-custom-footer">
        My own super footer
        <h-sheet-close class="sheet__btn btn btn_outline">Cancel</h-sheet-close>
    </div>
</h-sheet>

Webcomponents reference